##// END OF EJS Templates
pager: move more behavior into core...
Augie Fackler -
r30993:9c2977ce default
parent child Browse files
Show More
@@ -1,121 +1,107 b''
1 # pager.py - display output using a pager
1 # pager.py - display output using a pager
2 #
2 #
3 # Copyright 2008 David Soria Parra <dsp@php.net>
3 # Copyright 2008 David Soria Parra <dsp@php.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7 #
7 #
8 # To load the extension, add it to your configuration file:
8 # To load the extension, add it to your configuration file:
9 #
9 #
10 # [extension]
10 # [extension]
11 # pager =
11 # pager =
12 #
12 #
13 # Run 'hg help pager' to get info on configuration.
13 # Run 'hg help pager' to get info on configuration.
14
14
15 '''browse command output with an external pager
15 '''browse command output with an external pager
16
16
17 To set the pager that should be used, set the application variable::
17 To set the pager that should be used, set the application variable::
18
18
19 [pager]
19 [pager]
20 pager = less -FRX
20 pager = less -FRX
21
21
22 If no pager is set, the pager extensions uses the environment variable
22 If no pager is set, the pager extensions uses the environment variable
23 $PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.
23 $PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.
24
24
25 You can disable the pager for certain commands by adding them to the
25 You can disable the pager for certain commands by adding them to the
26 pager.ignore list::
26 pager.ignore list::
27
27
28 [pager]
28 [pager]
29 ignore = version, help, update
29 ignore = version, help, update
30
30
31 You can also enable the pager only for certain commands using
31 You can also enable the pager only for certain commands using
32 pager.attend. Below is the default list of commands to be paged::
32 pager.attend. Below is the default list of commands to be paged::
33
33
34 [pager]
34 [pager]
35 attend = annotate, cat, diff, export, glog, log, qdiff
35 attend = annotate, cat, diff, export, glog, log, qdiff
36
36
37 Setting pager.attend to an empty value will cause all commands to be
37 Setting pager.attend to an empty value will cause all commands to be
38 paged.
38 paged.
39
39
40 If pager.attend is present, pager.ignore will be ignored.
40 If pager.attend is present, pager.ignore will be ignored.
41
41
42 Lastly, you can enable and disable paging for individual commands with
42 Lastly, you can enable and disable paging for individual commands with
43 the attend-<command> option. This setting takes precedence over
43 the attend-<command> option. This setting takes precedence over
44 existing attend and ignore options and defaults::
44 existing attend and ignore options and defaults::
45
45
46 [pager]
46 [pager]
47 attend-cat = false
47 attend-cat = false
48
48
49 To ignore global commands like :hg:`version` or :hg:`help`, you have
49 To ignore global commands like :hg:`version` or :hg:`help`, you have
50 to specify them in your user configuration file.
50 to specify them in your user configuration file.
51
51
52 To control whether the pager is used at all for an individual command,
52 To control whether the pager is used at all for an individual command,
53 you can use --pager=<value>::
53 you can use --pager=<value>::
54
54
55 - use as needed: `auto`.
55 - use as needed: `auto`.
56 - require the pager: `yes` or `on`.
56 - require the pager: `yes` or `on`.
57 - suppress the pager: `no` or `off` (any unrecognized value
57 - suppress the pager: `no` or `off` (any unrecognized value
58 will also work).
58 will also work).
59
59
60 '''
60 '''
61 from __future__ import absolute_import
61 from __future__ import absolute_import
62
62
63 from mercurial.i18n import _
64 from mercurial import (
63 from mercurial import (
65 cmdutil,
64 cmdutil,
66 commands,
65 commands,
67 dispatch,
66 dispatch,
68 extensions,
67 extensions,
69 util,
70 )
68 )
71
69
72 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
70 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
73 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
71 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
74 # be specifying the version(s) of Mercurial they are tested with, or
72 # be specifying the version(s) of Mercurial they are tested with, or
75 # leave the attribute unspecified.
73 # leave the attribute unspecified.
76 testedwith = 'ships-with-hg-core'
74 testedwith = 'ships-with-hg-core'
77
75
78 def uisetup(ui):
76 def uisetup(ui):
79
77
80 def pagecmd(orig, ui, options, cmd, cmdfunc):
78 def pagecmd(orig, ui, options, cmd, cmdfunc):
81 usepager = False
82 always = util.parsebool(options['pager'])
83 auto = options['pager'] == 'auto'
79 auto = options['pager'] == 'auto'
84
80 if auto and not ui.pageractive:
85 if always:
86 usepager = True
87 elif not auto:
88 usepager = False
81 usepager = False
89 else:
90 attend = ui.configlist('pager', 'attend', attended)
82 attend = ui.configlist('pager', 'attend', attended)
91 ignore = ui.configlist('pager', 'ignore')
83 ignore = ui.configlist('pager', 'ignore')
92 cmds, _ = cmdutil.findcmd(cmd, commands.table)
84 cmds, _ = cmdutil.findcmd(cmd, commands.table)
93
85
94 for cmd in cmds:
86 for cmd in cmds:
95 var = 'attend-%s' % cmd
87 var = 'attend-%s' % cmd
96 if ui.config('pager', var):
88 if ui.config('pager', var):
97 usepager = ui.configbool('pager', var)
89 usepager = ui.configbool('pager', var)
98 break
90 break
99 if (cmd in attend or
91 if (cmd in attend or
100 (cmd not in ignore and not attend)):
92 (cmd not in ignore and not attend)):
101 usepager = True
93 usepager = True
102 break
94 break
103
95
104 if usepager:
96 if usepager:
105 ui.pager('extension-via-attend-' + cmd)
97 ui.pager('extension-via-attend-' + cmd)
106 return orig(ui, options, cmd, cmdfunc)
98 return orig(ui, options, cmd, cmdfunc)
107
99
108 # Wrap dispatch._runcommand after color is loaded so color can see
100 # Wrap dispatch._runcommand after color is loaded so color can see
109 # ui.pageractive. Otherwise, if we loaded first, color's wrapped
101 # ui.pageractive. Otherwise, if we loaded first, color's wrapped
110 # dispatch._runcommand would run without having access to ui.pageractive.
102 # dispatch._runcommand would run without having access to ui.pageractive.
111 def afterloaded(loaded):
103 def afterloaded(loaded):
112 extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
104 extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
113 extensions.afterloaded('color', afterloaded)
105 extensions.afterloaded('color', afterloaded)
114
106
115 def extsetup(ui):
116 commands.globalopts.append(
117 ('', 'pager', 'auto',
118 _("when to paginate (boolean, always, auto, or never)"),
119 _('TYPE')))
120
121 attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff']
107 attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff']
@@ -1,5440 +1,5442 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import difflib
10 import difflib
11 import errno
11 import errno
12 import os
12 import os
13 import re
13 import re
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import (
16 from .node import (
17 hex,
17 hex,
18 nullid,
18 nullid,
19 nullrev,
19 nullrev,
20 short,
20 short,
21 )
21 )
22 from . import (
22 from . import (
23 archival,
23 archival,
24 bookmarks,
24 bookmarks,
25 bundle2,
25 bundle2,
26 changegroup,
26 changegroup,
27 cmdutil,
27 cmdutil,
28 copies,
28 copies,
29 destutil,
29 destutil,
30 dirstateguard,
30 dirstateguard,
31 discovery,
31 discovery,
32 encoding,
32 encoding,
33 error,
33 error,
34 exchange,
34 exchange,
35 extensions,
35 extensions,
36 graphmod,
36 graphmod,
37 hbisect,
37 hbisect,
38 help,
38 help,
39 hg,
39 hg,
40 lock as lockmod,
40 lock as lockmod,
41 merge as mergemod,
41 merge as mergemod,
42 minirst,
42 minirst,
43 obsolete,
43 obsolete,
44 patch,
44 patch,
45 phases,
45 phases,
46 pycompat,
46 pycompat,
47 revset,
47 revset,
48 scmutil,
48 scmutil,
49 server,
49 server,
50 sshserver,
50 sshserver,
51 streamclone,
51 streamclone,
52 templatekw,
52 templatekw,
53 ui as uimod,
53 ui as uimod,
54 util,
54 util,
55 )
55 )
56
56
57 release = lockmod.release
57 release = lockmod.release
58
58
59 table = {}
59 table = {}
60
60
61 command = cmdutil.command(table)
61 command = cmdutil.command(table)
62
62
63 # label constants
63 # label constants
64 # until 3.5, bookmarks.current was the advertised name, not
64 # until 3.5, bookmarks.current was the advertised name, not
65 # bookmarks.active, so we must use both to avoid breaking old
65 # bookmarks.active, so we must use both to avoid breaking old
66 # custom styles
66 # custom styles
67 activebookmarklabel = 'bookmarks.active bookmarks.current'
67 activebookmarklabel = 'bookmarks.active bookmarks.current'
68
68
69 # common command options
69 # common command options
70
70
71 globalopts = [
71 globalopts = [
72 ('R', 'repository', '',
72 ('R', 'repository', '',
73 _('repository root directory or name of overlay bundle file'),
73 _('repository root directory or name of overlay bundle file'),
74 _('REPO')),
74 _('REPO')),
75 ('', 'cwd', '',
75 ('', 'cwd', '',
76 _('change working directory'), _('DIR')),
76 _('change working directory'), _('DIR')),
77 ('y', 'noninteractive', None,
77 ('y', 'noninteractive', None,
78 _('do not prompt, automatically pick the first choice for all prompts')),
78 _('do not prompt, automatically pick the first choice for all prompts')),
79 ('q', 'quiet', None, _('suppress output')),
79 ('q', 'quiet', None, _('suppress output')),
80 ('v', 'verbose', None, _('enable additional output')),
80 ('v', 'verbose', None, _('enable additional output')),
81 ('', 'config', [],
81 ('', 'config', [],
82 _('set/override config option (use \'section.name=value\')'),
82 _('set/override config option (use \'section.name=value\')'),
83 _('CONFIG')),
83 _('CONFIG')),
84 ('', 'debug', None, _('enable debugging output')),
84 ('', 'debug', None, _('enable debugging output')),
85 ('', 'debugger', None, _('start debugger')),
85 ('', 'debugger', None, _('start debugger')),
86 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
86 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
87 _('ENCODE')),
87 _('ENCODE')),
88 ('', 'encodingmode', encoding.encodingmode,
88 ('', 'encodingmode', encoding.encodingmode,
89 _('set the charset encoding mode'), _('MODE')),
89 _('set the charset encoding mode'), _('MODE')),
90 ('', 'traceback', None, _('always print a traceback on exception')),
90 ('', 'traceback', None, _('always print a traceback on exception')),
91 ('', 'time', None, _('time how long the command takes')),
91 ('', 'time', None, _('time how long the command takes')),
92 ('', 'profile', None, _('print command execution profile')),
92 ('', 'profile', None, _('print command execution profile')),
93 ('', 'version', None, _('output version information and exit')),
93 ('', 'version', None, _('output version information and exit')),
94 ('h', 'help', None, _('display help and exit')),
94 ('h', 'help', None, _('display help and exit')),
95 ('', 'hidden', False, _('consider hidden changesets')),
95 ('', 'hidden', False, _('consider hidden changesets')),
96 ('', 'pager', 'auto',
97 _("when to paginate (boolean, always, auto, or never)"), _('TYPE')),
96 ]
98 ]
97
99
98 dryrunopts = [('n', 'dry-run', None,
100 dryrunopts = [('n', 'dry-run', None,
99 _('do not perform actions, just print output'))]
101 _('do not perform actions, just print output'))]
100
102
101 remoteopts = [
103 remoteopts = [
102 ('e', 'ssh', '',
104 ('e', 'ssh', '',
103 _('specify ssh command to use'), _('CMD')),
105 _('specify ssh command to use'), _('CMD')),
104 ('', 'remotecmd', '',
106 ('', 'remotecmd', '',
105 _('specify hg command to run on the remote side'), _('CMD')),
107 _('specify hg command to run on the remote side'), _('CMD')),
106 ('', 'insecure', None,
108 ('', 'insecure', None,
107 _('do not verify server certificate (ignoring web.cacerts config)')),
109 _('do not verify server certificate (ignoring web.cacerts config)')),
108 ]
110 ]
109
111
110 walkopts = [
112 walkopts = [
111 ('I', 'include', [],
113 ('I', 'include', [],
112 _('include names matching the given patterns'), _('PATTERN')),
114 _('include names matching the given patterns'), _('PATTERN')),
113 ('X', 'exclude', [],
115 ('X', 'exclude', [],
114 _('exclude names matching the given patterns'), _('PATTERN')),
116 _('exclude names matching the given patterns'), _('PATTERN')),
115 ]
117 ]
116
118
117 commitopts = [
119 commitopts = [
118 ('m', 'message', '',
120 ('m', 'message', '',
119 _('use text as commit message'), _('TEXT')),
121 _('use text as commit message'), _('TEXT')),
120 ('l', 'logfile', '',
122 ('l', 'logfile', '',
121 _('read commit message from file'), _('FILE')),
123 _('read commit message from file'), _('FILE')),
122 ]
124 ]
123
125
124 commitopts2 = [
126 commitopts2 = [
125 ('d', 'date', '',
127 ('d', 'date', '',
126 _('record the specified date as commit date'), _('DATE')),
128 _('record the specified date as commit date'), _('DATE')),
127 ('u', 'user', '',
129 ('u', 'user', '',
128 _('record the specified user as committer'), _('USER')),
130 _('record the specified user as committer'), _('USER')),
129 ]
131 ]
130
132
131 # hidden for now
133 # hidden for now
132 formatteropts = [
134 formatteropts = [
133 ('T', 'template', '',
135 ('T', 'template', '',
134 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
136 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
135 ]
137 ]
136
138
137 templateopts = [
139 templateopts = [
138 ('', 'style', '',
140 ('', 'style', '',
139 _('display using template map file (DEPRECATED)'), _('STYLE')),
141 _('display using template map file (DEPRECATED)'), _('STYLE')),
140 ('T', 'template', '',
142 ('T', 'template', '',
141 _('display with template'), _('TEMPLATE')),
143 _('display with template'), _('TEMPLATE')),
142 ]
144 ]
143
145
144 logopts = [
146 logopts = [
145 ('p', 'patch', None, _('show patch')),
147 ('p', 'patch', None, _('show patch')),
146 ('g', 'git', None, _('use git extended diff format')),
148 ('g', 'git', None, _('use git extended diff format')),
147 ('l', 'limit', '',
149 ('l', 'limit', '',
148 _('limit number of changes displayed'), _('NUM')),
150 _('limit number of changes displayed'), _('NUM')),
149 ('M', 'no-merges', None, _('do not show merges')),
151 ('M', 'no-merges', None, _('do not show merges')),
150 ('', 'stat', None, _('output diffstat-style summary of changes')),
152 ('', 'stat', None, _('output diffstat-style summary of changes')),
151 ('G', 'graph', None, _("show the revision DAG")),
153 ('G', 'graph', None, _("show the revision DAG")),
152 ] + templateopts
154 ] + templateopts
153
155
154 diffopts = [
156 diffopts = [
155 ('a', 'text', None, _('treat all files as text')),
157 ('a', 'text', None, _('treat all files as text')),
156 ('g', 'git', None, _('use git extended diff format')),
158 ('g', 'git', None, _('use git extended diff format')),
157 ('', 'nodates', None, _('omit dates from diff headers'))
159 ('', 'nodates', None, _('omit dates from diff headers'))
158 ]
160 ]
159
161
160 diffwsopts = [
162 diffwsopts = [
161 ('w', 'ignore-all-space', None,
163 ('w', 'ignore-all-space', None,
162 _('ignore white space when comparing lines')),
164 _('ignore white space when comparing lines')),
163 ('b', 'ignore-space-change', None,
165 ('b', 'ignore-space-change', None,
164 _('ignore changes in the amount of white space')),
166 _('ignore changes in the amount of white space')),
165 ('B', 'ignore-blank-lines', None,
167 ('B', 'ignore-blank-lines', None,
166 _('ignore changes whose lines are all blank')),
168 _('ignore changes whose lines are all blank')),
167 ]
169 ]
168
170
169 diffopts2 = [
171 diffopts2 = [
170 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
172 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
171 ('p', 'show-function', None, _('show which function each change is in')),
173 ('p', 'show-function', None, _('show which function each change is in')),
172 ('', 'reverse', None, _('produce a diff that undoes the changes')),
174 ('', 'reverse', None, _('produce a diff that undoes the changes')),
173 ] + diffwsopts + [
175 ] + diffwsopts + [
174 ('U', 'unified', '',
176 ('U', 'unified', '',
175 _('number of lines of context to show'), _('NUM')),
177 _('number of lines of context to show'), _('NUM')),
176 ('', 'stat', None, _('output diffstat-style summary of changes')),
178 ('', 'stat', None, _('output diffstat-style summary of changes')),
177 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
179 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
178 ]
180 ]
179
181
180 mergetoolopts = [
182 mergetoolopts = [
181 ('t', 'tool', '', _('specify merge tool')),
183 ('t', 'tool', '', _('specify merge tool')),
182 ]
184 ]
183
185
184 similarityopts = [
186 similarityopts = [
185 ('s', 'similarity', '',
187 ('s', 'similarity', '',
186 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
188 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
187 ]
189 ]
188
190
189 subrepoopts = [
191 subrepoopts = [
190 ('S', 'subrepos', None,
192 ('S', 'subrepos', None,
191 _('recurse into subrepositories'))
193 _('recurse into subrepositories'))
192 ]
194 ]
193
195
194 debugrevlogopts = [
196 debugrevlogopts = [
195 ('c', 'changelog', False, _('open changelog')),
197 ('c', 'changelog', False, _('open changelog')),
196 ('m', 'manifest', False, _('open manifest')),
198 ('m', 'manifest', False, _('open manifest')),
197 ('', 'dir', '', _('open directory manifest')),
199 ('', 'dir', '', _('open directory manifest')),
198 ]
200 ]
199
201
200 # Commands start here, listed alphabetically
202 # Commands start here, listed alphabetically
201
203
202 @command('^add',
204 @command('^add',
203 walkopts + subrepoopts + dryrunopts,
205 walkopts + subrepoopts + dryrunopts,
204 _('[OPTION]... [FILE]...'),
206 _('[OPTION]... [FILE]...'),
205 inferrepo=True)
207 inferrepo=True)
206 def add(ui, repo, *pats, **opts):
208 def add(ui, repo, *pats, **opts):
207 """add the specified files on the next commit
209 """add the specified files on the next commit
208
210
209 Schedule files to be version controlled and added to the
211 Schedule files to be version controlled and added to the
210 repository.
212 repository.
211
213
212 The files will be added to the repository at the next commit. To
214 The files will be added to the repository at the next commit. To
213 undo an add before that, see :hg:`forget`.
215 undo an add before that, see :hg:`forget`.
214
216
215 If no names are given, add all files to the repository (except
217 If no names are given, add all files to the repository (except
216 files matching ``.hgignore``).
218 files matching ``.hgignore``).
217
219
218 .. container:: verbose
220 .. container:: verbose
219
221
220 Examples:
222 Examples:
221
223
222 - New (unknown) files are added
224 - New (unknown) files are added
223 automatically by :hg:`add`::
225 automatically by :hg:`add`::
224
226
225 $ ls
227 $ ls
226 foo.c
228 foo.c
227 $ hg status
229 $ hg status
228 ? foo.c
230 ? foo.c
229 $ hg add
231 $ hg add
230 adding foo.c
232 adding foo.c
231 $ hg status
233 $ hg status
232 A foo.c
234 A foo.c
233
235
234 - Specific files to be added can be specified::
236 - Specific files to be added can be specified::
235
237
236 $ ls
238 $ ls
237 bar.c foo.c
239 bar.c foo.c
238 $ hg status
240 $ hg status
239 ? bar.c
241 ? bar.c
240 ? foo.c
242 ? foo.c
241 $ hg add bar.c
243 $ hg add bar.c
242 $ hg status
244 $ hg status
243 A bar.c
245 A bar.c
244 ? foo.c
246 ? foo.c
245
247
246 Returns 0 if all files are successfully added.
248 Returns 0 if all files are successfully added.
247 """
249 """
248
250
249 m = scmutil.match(repo[None], pats, opts)
251 m = scmutil.match(repo[None], pats, opts)
250 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
252 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
251 return rejected and 1 or 0
253 return rejected and 1 or 0
252
254
253 @command('addremove',
255 @command('addremove',
254 similarityopts + subrepoopts + walkopts + dryrunopts,
256 similarityopts + subrepoopts + walkopts + dryrunopts,
255 _('[OPTION]... [FILE]...'),
257 _('[OPTION]... [FILE]...'),
256 inferrepo=True)
258 inferrepo=True)
257 def addremove(ui, repo, *pats, **opts):
259 def addremove(ui, repo, *pats, **opts):
258 """add all new files, delete all missing files
260 """add all new files, delete all missing files
259
261
260 Add all new files and remove all missing files from the
262 Add all new files and remove all missing files from the
261 repository.
263 repository.
262
264
263 Unless names are given, new files are ignored if they match any of
265 Unless names are given, new files are ignored if they match any of
264 the patterns in ``.hgignore``. As with add, these changes take
266 the patterns in ``.hgignore``. As with add, these changes take
265 effect at the next commit.
267 effect at the next commit.
266
268
267 Use the -s/--similarity option to detect renamed files. This
269 Use the -s/--similarity option to detect renamed files. This
268 option takes a percentage between 0 (disabled) and 100 (files must
270 option takes a percentage between 0 (disabled) and 100 (files must
269 be identical) as its parameter. With a parameter greater than 0,
271 be identical) as its parameter. With a parameter greater than 0,
270 this compares every removed file with every added file and records
272 this compares every removed file with every added file and records
271 those similar enough as renames. Detecting renamed files this way
273 those similar enough as renames. Detecting renamed files this way
272 can be expensive. After using this option, :hg:`status -C` can be
274 can be expensive. After using this option, :hg:`status -C` can be
273 used to check which files were identified as moved or renamed. If
275 used to check which files were identified as moved or renamed. If
274 not specified, -s/--similarity defaults to 100 and only renames of
276 not specified, -s/--similarity defaults to 100 and only renames of
275 identical files are detected.
277 identical files are detected.
276
278
277 .. container:: verbose
279 .. container:: verbose
278
280
279 Examples:
281 Examples:
280
282
281 - A number of files (bar.c and foo.c) are new,
283 - A number of files (bar.c and foo.c) are new,
282 while foobar.c has been removed (without using :hg:`remove`)
284 while foobar.c has been removed (without using :hg:`remove`)
283 from the repository::
285 from the repository::
284
286
285 $ ls
287 $ ls
286 bar.c foo.c
288 bar.c foo.c
287 $ hg status
289 $ hg status
288 ! foobar.c
290 ! foobar.c
289 ? bar.c
291 ? bar.c
290 ? foo.c
292 ? foo.c
291 $ hg addremove
293 $ hg addremove
292 adding bar.c
294 adding bar.c
293 adding foo.c
295 adding foo.c
294 removing foobar.c
296 removing foobar.c
295 $ hg status
297 $ hg status
296 A bar.c
298 A bar.c
297 A foo.c
299 A foo.c
298 R foobar.c
300 R foobar.c
299
301
300 - A file foobar.c was moved to foo.c without using :hg:`rename`.
302 - A file foobar.c was moved to foo.c without using :hg:`rename`.
301 Afterwards, it was edited slightly::
303 Afterwards, it was edited slightly::
302
304
303 $ ls
305 $ ls
304 foo.c
306 foo.c
305 $ hg status
307 $ hg status
306 ! foobar.c
308 ! foobar.c
307 ? foo.c
309 ? foo.c
308 $ hg addremove --similarity 90
310 $ hg addremove --similarity 90
309 removing foobar.c
311 removing foobar.c
310 adding foo.c
312 adding foo.c
311 recording removal of foobar.c as rename to foo.c (94% similar)
313 recording removal of foobar.c as rename to foo.c (94% similar)
312 $ hg status -C
314 $ hg status -C
313 A foo.c
315 A foo.c
314 foobar.c
316 foobar.c
315 R foobar.c
317 R foobar.c
316
318
317 Returns 0 if all files are successfully added.
319 Returns 0 if all files are successfully added.
318 """
320 """
319 try:
321 try:
320 sim = float(opts.get('similarity') or 100)
322 sim = float(opts.get('similarity') or 100)
321 except ValueError:
323 except ValueError:
322 raise error.Abort(_('similarity must be a number'))
324 raise error.Abort(_('similarity must be a number'))
323 if sim < 0 or sim > 100:
325 if sim < 0 or sim > 100:
324 raise error.Abort(_('similarity must be between 0 and 100'))
326 raise error.Abort(_('similarity must be between 0 and 100'))
325 matcher = scmutil.match(repo[None], pats, opts)
327 matcher = scmutil.match(repo[None], pats, opts)
326 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
328 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
327
329
328 @command('^annotate|blame',
330 @command('^annotate|blame',
329 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
331 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
330 ('', 'follow', None,
332 ('', 'follow', None,
331 _('follow copies/renames and list the filename (DEPRECATED)')),
333 _('follow copies/renames and list the filename (DEPRECATED)')),
332 ('', 'no-follow', None, _("don't follow copies and renames")),
334 ('', 'no-follow', None, _("don't follow copies and renames")),
333 ('a', 'text', None, _('treat all files as text')),
335 ('a', 'text', None, _('treat all files as text')),
334 ('u', 'user', None, _('list the author (long with -v)')),
336 ('u', 'user', None, _('list the author (long with -v)')),
335 ('f', 'file', None, _('list the filename')),
337 ('f', 'file', None, _('list the filename')),
336 ('d', 'date', None, _('list the date (short with -q)')),
338 ('d', 'date', None, _('list the date (short with -q)')),
337 ('n', 'number', None, _('list the revision number (default)')),
339 ('n', 'number', None, _('list the revision number (default)')),
338 ('c', 'changeset', None, _('list the changeset')),
340 ('c', 'changeset', None, _('list the changeset')),
339 ('l', 'line-number', None, _('show line number at the first appearance'))
341 ('l', 'line-number', None, _('show line number at the first appearance'))
340 ] + diffwsopts + walkopts + formatteropts,
342 ] + diffwsopts + walkopts + formatteropts,
341 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
343 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
342 inferrepo=True)
344 inferrepo=True)
343 def annotate(ui, repo, *pats, **opts):
345 def annotate(ui, repo, *pats, **opts):
344 """show changeset information by line for each file
346 """show changeset information by line for each file
345
347
346 List changes in files, showing the revision id responsible for
348 List changes in files, showing the revision id responsible for
347 each line.
349 each line.
348
350
349 This command is useful for discovering when a change was made and
351 This command is useful for discovering when a change was made and
350 by whom.
352 by whom.
351
353
352 If you include --file, --user, or --date, the revision number is
354 If you include --file, --user, or --date, the revision number is
353 suppressed unless you also include --number.
355 suppressed unless you also include --number.
354
356
355 Without the -a/--text option, annotate will avoid processing files
357 Without the -a/--text option, annotate will avoid processing files
356 it detects as binary. With -a, annotate will annotate the file
358 it detects as binary. With -a, annotate will annotate the file
357 anyway, although the results will probably be neither useful
359 anyway, although the results will probably be neither useful
358 nor desirable.
360 nor desirable.
359
361
360 Returns 0 on success.
362 Returns 0 on success.
361 """
363 """
362 if not pats:
364 if not pats:
363 raise error.Abort(_('at least one filename or pattern is required'))
365 raise error.Abort(_('at least one filename or pattern is required'))
364
366
365 if opts.get('follow'):
367 if opts.get('follow'):
366 # --follow is deprecated and now just an alias for -f/--file
368 # --follow is deprecated and now just an alias for -f/--file
367 # to mimic the behavior of Mercurial before version 1.5
369 # to mimic the behavior of Mercurial before version 1.5
368 opts['file'] = True
370 opts['file'] = True
369
371
370 ctx = scmutil.revsingle(repo, opts.get('rev'))
372 ctx = scmutil.revsingle(repo, opts.get('rev'))
371
373
372 fm = ui.formatter('annotate', opts)
374 fm = ui.formatter('annotate', opts)
373 if ui.quiet:
375 if ui.quiet:
374 datefunc = util.shortdate
376 datefunc = util.shortdate
375 else:
377 else:
376 datefunc = util.datestr
378 datefunc = util.datestr
377 if ctx.rev() is None:
379 if ctx.rev() is None:
378 def hexfn(node):
380 def hexfn(node):
379 if node is None:
381 if node is None:
380 return None
382 return None
381 else:
383 else:
382 return fm.hexfunc(node)
384 return fm.hexfunc(node)
383 if opts.get('changeset'):
385 if opts.get('changeset'):
384 # omit "+" suffix which is appended to node hex
386 # omit "+" suffix which is appended to node hex
385 def formatrev(rev):
387 def formatrev(rev):
386 if rev is None:
388 if rev is None:
387 return '%d' % ctx.p1().rev()
389 return '%d' % ctx.p1().rev()
388 else:
390 else:
389 return '%d' % rev
391 return '%d' % rev
390 else:
392 else:
391 def formatrev(rev):
393 def formatrev(rev):
392 if rev is None:
394 if rev is None:
393 return '%d+' % ctx.p1().rev()
395 return '%d+' % ctx.p1().rev()
394 else:
396 else:
395 return '%d ' % rev
397 return '%d ' % rev
396 def formathex(hex):
398 def formathex(hex):
397 if hex is None:
399 if hex is None:
398 return '%s+' % fm.hexfunc(ctx.p1().node())
400 return '%s+' % fm.hexfunc(ctx.p1().node())
399 else:
401 else:
400 return '%s ' % hex
402 return '%s ' % hex
401 else:
403 else:
402 hexfn = fm.hexfunc
404 hexfn = fm.hexfunc
403 formatrev = formathex = str
405 formatrev = formathex = str
404
406
405 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
407 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
406 ('number', ' ', lambda x: x[0].rev(), formatrev),
408 ('number', ' ', lambda x: x[0].rev(), formatrev),
407 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
409 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
408 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
410 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
409 ('file', ' ', lambda x: x[0].path(), str),
411 ('file', ' ', lambda x: x[0].path(), str),
410 ('line_number', ':', lambda x: x[1], str),
412 ('line_number', ':', lambda x: x[1], str),
411 ]
413 ]
412 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
414 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
413
415
414 if (not opts.get('user') and not opts.get('changeset')
416 if (not opts.get('user') and not opts.get('changeset')
415 and not opts.get('date') and not opts.get('file')):
417 and not opts.get('date') and not opts.get('file')):
416 opts['number'] = True
418 opts['number'] = True
417
419
418 linenumber = opts.get('line_number') is not None
420 linenumber = opts.get('line_number') is not None
419 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
421 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
420 raise error.Abort(_('at least one of -n/-c is required for -l'))
422 raise error.Abort(_('at least one of -n/-c is required for -l'))
421
423
422 if fm.isplain():
424 if fm.isplain():
423 def makefunc(get, fmt):
425 def makefunc(get, fmt):
424 return lambda x: fmt(get(x))
426 return lambda x: fmt(get(x))
425 else:
427 else:
426 def makefunc(get, fmt):
428 def makefunc(get, fmt):
427 return get
429 return get
428 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
430 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
429 if opts.get(op)]
431 if opts.get(op)]
430 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
432 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
431 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
433 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
432 if opts.get(op))
434 if opts.get(op))
433
435
434 def bad(x, y):
436 def bad(x, y):
435 raise error.Abort("%s: %s" % (x, y))
437 raise error.Abort("%s: %s" % (x, y))
436
438
437 m = scmutil.match(ctx, pats, opts, badfn=bad)
439 m = scmutil.match(ctx, pats, opts, badfn=bad)
438
440
439 follow = not opts.get('no_follow')
441 follow = not opts.get('no_follow')
440 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
442 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
441 whitespace=True)
443 whitespace=True)
442 for abs in ctx.walk(m):
444 for abs in ctx.walk(m):
443 fctx = ctx[abs]
445 fctx = ctx[abs]
444 if not opts.get('text') and util.binary(fctx.data()):
446 if not opts.get('text') and util.binary(fctx.data()):
445 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
447 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
446 continue
448 continue
447
449
448 lines = fctx.annotate(follow=follow, linenumber=linenumber,
450 lines = fctx.annotate(follow=follow, linenumber=linenumber,
449 diffopts=diffopts)
451 diffopts=diffopts)
450 if not lines:
452 if not lines:
451 continue
453 continue
452 formats = []
454 formats = []
453 pieces = []
455 pieces = []
454
456
455 for f, sep in funcmap:
457 for f, sep in funcmap:
456 l = [f(n) for n, dummy in lines]
458 l = [f(n) for n, dummy in lines]
457 if fm.isplain():
459 if fm.isplain():
458 sizes = [encoding.colwidth(x) for x in l]
460 sizes = [encoding.colwidth(x) for x in l]
459 ml = max(sizes)
461 ml = max(sizes)
460 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
462 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
461 else:
463 else:
462 formats.append(['%s' for x in l])
464 formats.append(['%s' for x in l])
463 pieces.append(l)
465 pieces.append(l)
464
466
465 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
467 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
466 fm.startitem()
468 fm.startitem()
467 fm.write(fields, "".join(f), *p)
469 fm.write(fields, "".join(f), *p)
468 fm.write('line', ": %s", l[1])
470 fm.write('line', ": %s", l[1])
469
471
470 if not lines[-1][1].endswith('\n'):
472 if not lines[-1][1].endswith('\n'):
471 fm.plain('\n')
473 fm.plain('\n')
472
474
473 fm.end()
475 fm.end()
474
476
475 @command('archive',
477 @command('archive',
476 [('', 'no-decode', None, _('do not pass files through decoders')),
478 [('', 'no-decode', None, _('do not pass files through decoders')),
477 ('p', 'prefix', '', _('directory prefix for files in archive'),
479 ('p', 'prefix', '', _('directory prefix for files in archive'),
478 _('PREFIX')),
480 _('PREFIX')),
479 ('r', 'rev', '', _('revision to distribute'), _('REV')),
481 ('r', 'rev', '', _('revision to distribute'), _('REV')),
480 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
482 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
481 ] + subrepoopts + walkopts,
483 ] + subrepoopts + walkopts,
482 _('[OPTION]... DEST'))
484 _('[OPTION]... DEST'))
483 def archive(ui, repo, dest, **opts):
485 def archive(ui, repo, dest, **opts):
484 '''create an unversioned archive of a repository revision
486 '''create an unversioned archive of a repository revision
485
487
486 By default, the revision used is the parent of the working
488 By default, the revision used is the parent of the working
487 directory; use -r/--rev to specify a different revision.
489 directory; use -r/--rev to specify a different revision.
488
490
489 The archive type is automatically detected based on file
491 The archive type is automatically detected based on file
490 extension (to override, use -t/--type).
492 extension (to override, use -t/--type).
491
493
492 .. container:: verbose
494 .. container:: verbose
493
495
494 Examples:
496 Examples:
495
497
496 - create a zip file containing the 1.0 release::
498 - create a zip file containing the 1.0 release::
497
499
498 hg archive -r 1.0 project-1.0.zip
500 hg archive -r 1.0 project-1.0.zip
499
501
500 - create a tarball excluding .hg files::
502 - create a tarball excluding .hg files::
501
503
502 hg archive project.tar.gz -X ".hg*"
504 hg archive project.tar.gz -X ".hg*"
503
505
504 Valid types are:
506 Valid types are:
505
507
506 :``files``: a directory full of files (default)
508 :``files``: a directory full of files (default)
507 :``tar``: tar archive, uncompressed
509 :``tar``: tar archive, uncompressed
508 :``tbz2``: tar archive, compressed using bzip2
510 :``tbz2``: tar archive, compressed using bzip2
509 :``tgz``: tar archive, compressed using gzip
511 :``tgz``: tar archive, compressed using gzip
510 :``uzip``: zip archive, uncompressed
512 :``uzip``: zip archive, uncompressed
511 :``zip``: zip archive, compressed using deflate
513 :``zip``: zip archive, compressed using deflate
512
514
513 The exact name of the destination archive or directory is given
515 The exact name of the destination archive or directory is given
514 using a format string; see :hg:`help export` for details.
516 using a format string; see :hg:`help export` for details.
515
517
516 Each member added to an archive file has a directory prefix
518 Each member added to an archive file has a directory prefix
517 prepended. Use -p/--prefix to specify a format string for the
519 prepended. Use -p/--prefix to specify a format string for the
518 prefix. The default is the basename of the archive, with suffixes
520 prefix. The default is the basename of the archive, with suffixes
519 removed.
521 removed.
520
522
521 Returns 0 on success.
523 Returns 0 on success.
522 '''
524 '''
523
525
524 ctx = scmutil.revsingle(repo, opts.get('rev'))
526 ctx = scmutil.revsingle(repo, opts.get('rev'))
525 if not ctx:
527 if not ctx:
526 raise error.Abort(_('no working directory: please specify a revision'))
528 raise error.Abort(_('no working directory: please specify a revision'))
527 node = ctx.node()
529 node = ctx.node()
528 dest = cmdutil.makefilename(repo, dest, node)
530 dest = cmdutil.makefilename(repo, dest, node)
529 if os.path.realpath(dest) == repo.root:
531 if os.path.realpath(dest) == repo.root:
530 raise error.Abort(_('repository root cannot be destination'))
532 raise error.Abort(_('repository root cannot be destination'))
531
533
532 kind = opts.get('type') or archival.guesskind(dest) or 'files'
534 kind = opts.get('type') or archival.guesskind(dest) or 'files'
533 prefix = opts.get('prefix')
535 prefix = opts.get('prefix')
534
536
535 if dest == '-':
537 if dest == '-':
536 if kind == 'files':
538 if kind == 'files':
537 raise error.Abort(_('cannot archive plain files to stdout'))
539 raise error.Abort(_('cannot archive plain files to stdout'))
538 dest = cmdutil.makefileobj(repo, dest)
540 dest = cmdutil.makefileobj(repo, dest)
539 if not prefix:
541 if not prefix:
540 prefix = os.path.basename(repo.root) + '-%h'
542 prefix = os.path.basename(repo.root) + '-%h'
541
543
542 prefix = cmdutil.makefilename(repo, prefix, node)
544 prefix = cmdutil.makefilename(repo, prefix, node)
543 matchfn = scmutil.match(ctx, [], opts)
545 matchfn = scmutil.match(ctx, [], opts)
544 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
546 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
545 matchfn, prefix, subrepos=opts.get('subrepos'))
547 matchfn, prefix, subrepos=opts.get('subrepos'))
546
548
547 @command('backout',
549 @command('backout',
548 [('', 'merge', None, _('merge with old dirstate parent after backout')),
550 [('', 'merge', None, _('merge with old dirstate parent after backout')),
549 ('', 'commit', None,
551 ('', 'commit', None,
550 _('commit if no conflicts were encountered (DEPRECATED)')),
552 _('commit if no conflicts were encountered (DEPRECATED)')),
551 ('', 'no-commit', None, _('do not commit')),
553 ('', 'no-commit', None, _('do not commit')),
552 ('', 'parent', '',
554 ('', 'parent', '',
553 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
555 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
554 ('r', 'rev', '', _('revision to backout'), _('REV')),
556 ('r', 'rev', '', _('revision to backout'), _('REV')),
555 ('e', 'edit', False, _('invoke editor on commit messages')),
557 ('e', 'edit', False, _('invoke editor on commit messages')),
556 ] + mergetoolopts + walkopts + commitopts + commitopts2,
558 ] + mergetoolopts + walkopts + commitopts + commitopts2,
557 _('[OPTION]... [-r] REV'))
559 _('[OPTION]... [-r] REV'))
558 def backout(ui, repo, node=None, rev=None, **opts):
560 def backout(ui, repo, node=None, rev=None, **opts):
559 '''reverse effect of earlier changeset
561 '''reverse effect of earlier changeset
560
562
561 Prepare a new changeset with the effect of REV undone in the
563 Prepare a new changeset with the effect of REV undone in the
562 current working directory. If no conflicts were encountered,
564 current working directory. If no conflicts were encountered,
563 it will be committed immediately.
565 it will be committed immediately.
564
566
565 If REV is the parent of the working directory, then this new changeset
567 If REV is the parent of the working directory, then this new changeset
566 is committed automatically (unless --no-commit is specified).
568 is committed automatically (unless --no-commit is specified).
567
569
568 .. note::
570 .. note::
569
571
570 :hg:`backout` cannot be used to fix either an unwanted or
572 :hg:`backout` cannot be used to fix either an unwanted or
571 incorrect merge.
573 incorrect merge.
572
574
573 .. container:: verbose
575 .. container:: verbose
574
576
575 Examples:
577 Examples:
576
578
577 - Reverse the effect of the parent of the working directory.
579 - Reverse the effect of the parent of the working directory.
578 This backout will be committed immediately::
580 This backout will be committed immediately::
579
581
580 hg backout -r .
582 hg backout -r .
581
583
582 - Reverse the effect of previous bad revision 23::
584 - Reverse the effect of previous bad revision 23::
583
585
584 hg backout -r 23
586 hg backout -r 23
585
587
586 - Reverse the effect of previous bad revision 23 and
588 - Reverse the effect of previous bad revision 23 and
587 leave changes uncommitted::
589 leave changes uncommitted::
588
590
589 hg backout -r 23 --no-commit
591 hg backout -r 23 --no-commit
590 hg commit -m "Backout revision 23"
592 hg commit -m "Backout revision 23"
591
593
592 By default, the pending changeset will have one parent,
594 By default, the pending changeset will have one parent,
593 maintaining a linear history. With --merge, the pending
595 maintaining a linear history. With --merge, the pending
594 changeset will instead have two parents: the old parent of the
596 changeset will instead have two parents: the old parent of the
595 working directory and a new child of REV that simply undoes REV.
597 working directory and a new child of REV that simply undoes REV.
596
598
597 Before version 1.7, the behavior without --merge was equivalent
599 Before version 1.7, the behavior without --merge was equivalent
598 to specifying --merge followed by :hg:`update --clean .` to
600 to specifying --merge followed by :hg:`update --clean .` to
599 cancel the merge and leave the child of REV as a head to be
601 cancel the merge and leave the child of REV as a head to be
600 merged separately.
602 merged separately.
601
603
602 See :hg:`help dates` for a list of formats valid for -d/--date.
604 See :hg:`help dates` for a list of formats valid for -d/--date.
603
605
604 See :hg:`help revert` for a way to restore files to the state
606 See :hg:`help revert` for a way to restore files to the state
605 of another revision.
607 of another revision.
606
608
607 Returns 0 on success, 1 if nothing to backout or there are unresolved
609 Returns 0 on success, 1 if nothing to backout or there are unresolved
608 files.
610 files.
609 '''
611 '''
610 wlock = lock = None
612 wlock = lock = None
611 try:
613 try:
612 wlock = repo.wlock()
614 wlock = repo.wlock()
613 lock = repo.lock()
615 lock = repo.lock()
614 return _dobackout(ui, repo, node, rev, **opts)
616 return _dobackout(ui, repo, node, rev, **opts)
615 finally:
617 finally:
616 release(lock, wlock)
618 release(lock, wlock)
617
619
618 def _dobackout(ui, repo, node=None, rev=None, **opts):
620 def _dobackout(ui, repo, node=None, rev=None, **opts):
619 if opts.get('commit') and opts.get('no_commit'):
621 if opts.get('commit') and opts.get('no_commit'):
620 raise error.Abort(_("cannot use --commit with --no-commit"))
622 raise error.Abort(_("cannot use --commit with --no-commit"))
621 if opts.get('merge') and opts.get('no_commit'):
623 if opts.get('merge') and opts.get('no_commit'):
622 raise error.Abort(_("cannot use --merge with --no-commit"))
624 raise error.Abort(_("cannot use --merge with --no-commit"))
623
625
624 if rev and node:
626 if rev and node:
625 raise error.Abort(_("please specify just one revision"))
627 raise error.Abort(_("please specify just one revision"))
626
628
627 if not rev:
629 if not rev:
628 rev = node
630 rev = node
629
631
630 if not rev:
632 if not rev:
631 raise error.Abort(_("please specify a revision to backout"))
633 raise error.Abort(_("please specify a revision to backout"))
632
634
633 date = opts.get('date')
635 date = opts.get('date')
634 if date:
636 if date:
635 opts['date'] = util.parsedate(date)
637 opts['date'] = util.parsedate(date)
636
638
637 cmdutil.checkunfinished(repo)
639 cmdutil.checkunfinished(repo)
638 cmdutil.bailifchanged(repo)
640 cmdutil.bailifchanged(repo)
639 node = scmutil.revsingle(repo, rev).node()
641 node = scmutil.revsingle(repo, rev).node()
640
642
641 op1, op2 = repo.dirstate.parents()
643 op1, op2 = repo.dirstate.parents()
642 if not repo.changelog.isancestor(node, op1):
644 if not repo.changelog.isancestor(node, op1):
643 raise error.Abort(_('cannot backout change that is not an ancestor'))
645 raise error.Abort(_('cannot backout change that is not an ancestor'))
644
646
645 p1, p2 = repo.changelog.parents(node)
647 p1, p2 = repo.changelog.parents(node)
646 if p1 == nullid:
648 if p1 == nullid:
647 raise error.Abort(_('cannot backout a change with no parents'))
649 raise error.Abort(_('cannot backout a change with no parents'))
648 if p2 != nullid:
650 if p2 != nullid:
649 if not opts.get('parent'):
651 if not opts.get('parent'):
650 raise error.Abort(_('cannot backout a merge changeset'))
652 raise error.Abort(_('cannot backout a merge changeset'))
651 p = repo.lookup(opts['parent'])
653 p = repo.lookup(opts['parent'])
652 if p not in (p1, p2):
654 if p not in (p1, p2):
653 raise error.Abort(_('%s is not a parent of %s') %
655 raise error.Abort(_('%s is not a parent of %s') %
654 (short(p), short(node)))
656 (short(p), short(node)))
655 parent = p
657 parent = p
656 else:
658 else:
657 if opts.get('parent'):
659 if opts.get('parent'):
658 raise error.Abort(_('cannot use --parent on non-merge changeset'))
660 raise error.Abort(_('cannot use --parent on non-merge changeset'))
659 parent = p1
661 parent = p1
660
662
661 # the backout should appear on the same branch
663 # the backout should appear on the same branch
662 branch = repo.dirstate.branch()
664 branch = repo.dirstate.branch()
663 bheads = repo.branchheads(branch)
665 bheads = repo.branchheads(branch)
664 rctx = scmutil.revsingle(repo, hex(parent))
666 rctx = scmutil.revsingle(repo, hex(parent))
665 if not opts.get('merge') and op1 != node:
667 if not opts.get('merge') and op1 != node:
666 dsguard = dirstateguard.dirstateguard(repo, 'backout')
668 dsguard = dirstateguard.dirstateguard(repo, 'backout')
667 try:
669 try:
668 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
670 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
669 'backout')
671 'backout')
670 stats = mergemod.update(repo, parent, True, True, node, False)
672 stats = mergemod.update(repo, parent, True, True, node, False)
671 repo.setparents(op1, op2)
673 repo.setparents(op1, op2)
672 dsguard.close()
674 dsguard.close()
673 hg._showstats(repo, stats)
675 hg._showstats(repo, stats)
674 if stats[3]:
676 if stats[3]:
675 repo.ui.status(_("use 'hg resolve' to retry unresolved "
677 repo.ui.status(_("use 'hg resolve' to retry unresolved "
676 "file merges\n"))
678 "file merges\n"))
677 return 1
679 return 1
678 finally:
680 finally:
679 ui.setconfig('ui', 'forcemerge', '', '')
681 ui.setconfig('ui', 'forcemerge', '', '')
680 lockmod.release(dsguard)
682 lockmod.release(dsguard)
681 else:
683 else:
682 hg.clean(repo, node, show_stats=False)
684 hg.clean(repo, node, show_stats=False)
683 repo.dirstate.setbranch(branch)
685 repo.dirstate.setbranch(branch)
684 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
686 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
685
687
686 if opts.get('no_commit'):
688 if opts.get('no_commit'):
687 msg = _("changeset %s backed out, "
689 msg = _("changeset %s backed out, "
688 "don't forget to commit.\n")
690 "don't forget to commit.\n")
689 ui.status(msg % short(node))
691 ui.status(msg % short(node))
690 return 0
692 return 0
691
693
692 def commitfunc(ui, repo, message, match, opts):
694 def commitfunc(ui, repo, message, match, opts):
693 editform = 'backout'
695 editform = 'backout'
694 e = cmdutil.getcommiteditor(editform=editform, **opts)
696 e = cmdutil.getcommiteditor(editform=editform, **opts)
695 if not message:
697 if not message:
696 # we don't translate commit messages
698 # we don't translate commit messages
697 message = "Backed out changeset %s" % short(node)
699 message = "Backed out changeset %s" % short(node)
698 e = cmdutil.getcommiteditor(edit=True, editform=editform)
700 e = cmdutil.getcommiteditor(edit=True, editform=editform)
699 return repo.commit(message, opts.get('user'), opts.get('date'),
701 return repo.commit(message, opts.get('user'), opts.get('date'),
700 match, editor=e)
702 match, editor=e)
701 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
703 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
702 if not newnode:
704 if not newnode:
703 ui.status(_("nothing changed\n"))
705 ui.status(_("nothing changed\n"))
704 return 1
706 return 1
705 cmdutil.commitstatus(repo, newnode, branch, bheads)
707 cmdutil.commitstatus(repo, newnode, branch, bheads)
706
708
707 def nice(node):
709 def nice(node):
708 return '%d:%s' % (repo.changelog.rev(node), short(node))
710 return '%d:%s' % (repo.changelog.rev(node), short(node))
709 ui.status(_('changeset %s backs out changeset %s\n') %
711 ui.status(_('changeset %s backs out changeset %s\n') %
710 (nice(repo.changelog.tip()), nice(node)))
712 (nice(repo.changelog.tip()), nice(node)))
711 if opts.get('merge') and op1 != node:
713 if opts.get('merge') and op1 != node:
712 hg.clean(repo, op1, show_stats=False)
714 hg.clean(repo, op1, show_stats=False)
713 ui.status(_('merging with changeset %s\n')
715 ui.status(_('merging with changeset %s\n')
714 % nice(repo.changelog.tip()))
716 % nice(repo.changelog.tip()))
715 try:
717 try:
716 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
718 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
717 'backout')
719 'backout')
718 return hg.merge(repo, hex(repo.changelog.tip()))
720 return hg.merge(repo, hex(repo.changelog.tip()))
719 finally:
721 finally:
720 ui.setconfig('ui', 'forcemerge', '', '')
722 ui.setconfig('ui', 'forcemerge', '', '')
721 return 0
723 return 0
722
724
723 @command('bisect',
725 @command('bisect',
724 [('r', 'reset', False, _('reset bisect state')),
726 [('r', 'reset', False, _('reset bisect state')),
725 ('g', 'good', False, _('mark changeset good')),
727 ('g', 'good', False, _('mark changeset good')),
726 ('b', 'bad', False, _('mark changeset bad')),
728 ('b', 'bad', False, _('mark changeset bad')),
727 ('s', 'skip', False, _('skip testing changeset')),
729 ('s', 'skip', False, _('skip testing changeset')),
728 ('e', 'extend', False, _('extend the bisect range')),
730 ('e', 'extend', False, _('extend the bisect range')),
729 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
731 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
730 ('U', 'noupdate', False, _('do not update to target'))],
732 ('U', 'noupdate', False, _('do not update to target'))],
731 _("[-gbsr] [-U] [-c CMD] [REV]"))
733 _("[-gbsr] [-U] [-c CMD] [REV]"))
732 def bisect(ui, repo, rev=None, extra=None, command=None,
734 def bisect(ui, repo, rev=None, extra=None, command=None,
733 reset=None, good=None, bad=None, skip=None, extend=None,
735 reset=None, good=None, bad=None, skip=None, extend=None,
734 noupdate=None):
736 noupdate=None):
735 """subdivision search of changesets
737 """subdivision search of changesets
736
738
737 This command helps to find changesets which introduce problems. To
739 This command helps to find changesets which introduce problems. To
738 use, mark the earliest changeset you know exhibits the problem as
740 use, mark the earliest changeset you know exhibits the problem as
739 bad, then mark the latest changeset which is free from the problem
741 bad, then mark the latest changeset which is free from the problem
740 as good. Bisect will update your working directory to a revision
742 as good. Bisect will update your working directory to a revision
741 for testing (unless the -U/--noupdate option is specified). Once
743 for testing (unless the -U/--noupdate option is specified). Once
742 you have performed tests, mark the working directory as good or
744 you have performed tests, mark the working directory as good or
743 bad, and bisect will either update to another candidate changeset
745 bad, and bisect will either update to another candidate changeset
744 or announce that it has found the bad revision.
746 or announce that it has found the bad revision.
745
747
746 As a shortcut, you can also use the revision argument to mark a
748 As a shortcut, you can also use the revision argument to mark a
747 revision as good or bad without checking it out first.
749 revision as good or bad without checking it out first.
748
750
749 If you supply a command, it will be used for automatic bisection.
751 If you supply a command, it will be used for automatic bisection.
750 The environment variable HG_NODE will contain the ID of the
752 The environment variable HG_NODE will contain the ID of the
751 changeset being tested. The exit status of the command will be
753 changeset being tested. The exit status of the command will be
752 used to mark revisions as good or bad: status 0 means good, 125
754 used to mark revisions as good or bad: status 0 means good, 125
753 means to skip the revision, 127 (command not found) will abort the
755 means to skip the revision, 127 (command not found) will abort the
754 bisection, and any other non-zero exit status means the revision
756 bisection, and any other non-zero exit status means the revision
755 is bad.
757 is bad.
756
758
757 .. container:: verbose
759 .. container:: verbose
758
760
759 Some examples:
761 Some examples:
760
762
761 - start a bisection with known bad revision 34, and good revision 12::
763 - start a bisection with known bad revision 34, and good revision 12::
762
764
763 hg bisect --bad 34
765 hg bisect --bad 34
764 hg bisect --good 12
766 hg bisect --good 12
765
767
766 - advance the current bisection by marking current revision as good or
768 - advance the current bisection by marking current revision as good or
767 bad::
769 bad::
768
770
769 hg bisect --good
771 hg bisect --good
770 hg bisect --bad
772 hg bisect --bad
771
773
772 - mark the current revision, or a known revision, to be skipped (e.g. if
774 - mark the current revision, or a known revision, to be skipped (e.g. if
773 that revision is not usable because of another issue)::
775 that revision is not usable because of another issue)::
774
776
775 hg bisect --skip
777 hg bisect --skip
776 hg bisect --skip 23
778 hg bisect --skip 23
777
779
778 - skip all revisions that do not touch directories ``foo`` or ``bar``::
780 - skip all revisions that do not touch directories ``foo`` or ``bar``::
779
781
780 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
782 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
781
783
782 - forget the current bisection::
784 - forget the current bisection::
783
785
784 hg bisect --reset
786 hg bisect --reset
785
787
786 - use 'make && make tests' to automatically find the first broken
788 - use 'make && make tests' to automatically find the first broken
787 revision::
789 revision::
788
790
789 hg bisect --reset
791 hg bisect --reset
790 hg bisect --bad 34
792 hg bisect --bad 34
791 hg bisect --good 12
793 hg bisect --good 12
792 hg bisect --command "make && make tests"
794 hg bisect --command "make && make tests"
793
795
794 - see all changesets whose states are already known in the current
796 - see all changesets whose states are already known in the current
795 bisection::
797 bisection::
796
798
797 hg log -r "bisect(pruned)"
799 hg log -r "bisect(pruned)"
798
800
799 - see the changeset currently being bisected (especially useful
801 - see the changeset currently being bisected (especially useful
800 if running with -U/--noupdate)::
802 if running with -U/--noupdate)::
801
803
802 hg log -r "bisect(current)"
804 hg log -r "bisect(current)"
803
805
804 - see all changesets that took part in the current bisection::
806 - see all changesets that took part in the current bisection::
805
807
806 hg log -r "bisect(range)"
808 hg log -r "bisect(range)"
807
809
808 - you can even get a nice graph::
810 - you can even get a nice graph::
809
811
810 hg log --graph -r "bisect(range)"
812 hg log --graph -r "bisect(range)"
811
813
812 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
814 See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
813
815
814 Returns 0 on success.
816 Returns 0 on success.
815 """
817 """
816 # backward compatibility
818 # backward compatibility
817 if rev in "good bad reset init".split():
819 if rev in "good bad reset init".split():
818 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
820 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
819 cmd, rev, extra = rev, extra, None
821 cmd, rev, extra = rev, extra, None
820 if cmd == "good":
822 if cmd == "good":
821 good = True
823 good = True
822 elif cmd == "bad":
824 elif cmd == "bad":
823 bad = True
825 bad = True
824 else:
826 else:
825 reset = True
827 reset = True
826 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
828 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
827 raise error.Abort(_('incompatible arguments'))
829 raise error.Abort(_('incompatible arguments'))
828
830
829 cmdutil.checkunfinished(repo)
831 cmdutil.checkunfinished(repo)
830
832
831 if reset:
833 if reset:
832 hbisect.resetstate(repo)
834 hbisect.resetstate(repo)
833 return
835 return
834
836
835 state = hbisect.load_state(repo)
837 state = hbisect.load_state(repo)
836
838
837 # update state
839 # update state
838 if good or bad or skip:
840 if good or bad or skip:
839 if rev:
841 if rev:
840 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
842 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
841 else:
843 else:
842 nodes = [repo.lookup('.')]
844 nodes = [repo.lookup('.')]
843 if good:
845 if good:
844 state['good'] += nodes
846 state['good'] += nodes
845 elif bad:
847 elif bad:
846 state['bad'] += nodes
848 state['bad'] += nodes
847 elif skip:
849 elif skip:
848 state['skip'] += nodes
850 state['skip'] += nodes
849 hbisect.save_state(repo, state)
851 hbisect.save_state(repo, state)
850 if not (state['good'] and state['bad']):
852 if not (state['good'] and state['bad']):
851 return
853 return
852
854
853 def mayupdate(repo, node, show_stats=True):
855 def mayupdate(repo, node, show_stats=True):
854 """common used update sequence"""
856 """common used update sequence"""
855 if noupdate:
857 if noupdate:
856 return
858 return
857 cmdutil.bailifchanged(repo)
859 cmdutil.bailifchanged(repo)
858 return hg.clean(repo, node, show_stats=show_stats)
860 return hg.clean(repo, node, show_stats=show_stats)
859
861
860 displayer = cmdutil.show_changeset(ui, repo, {})
862 displayer = cmdutil.show_changeset(ui, repo, {})
861
863
862 if command:
864 if command:
863 changesets = 1
865 changesets = 1
864 if noupdate:
866 if noupdate:
865 try:
867 try:
866 node = state['current'][0]
868 node = state['current'][0]
867 except LookupError:
869 except LookupError:
868 raise error.Abort(_('current bisect revision is unknown - '
870 raise error.Abort(_('current bisect revision is unknown - '
869 'start a new bisect to fix'))
871 'start a new bisect to fix'))
870 else:
872 else:
871 node, p2 = repo.dirstate.parents()
873 node, p2 = repo.dirstate.parents()
872 if p2 != nullid:
874 if p2 != nullid:
873 raise error.Abort(_('current bisect revision is a merge'))
875 raise error.Abort(_('current bisect revision is a merge'))
874 if rev:
876 if rev:
875 node = repo[scmutil.revsingle(repo, rev, node)].node()
877 node = repo[scmutil.revsingle(repo, rev, node)].node()
876 try:
878 try:
877 while changesets:
879 while changesets:
878 # update state
880 # update state
879 state['current'] = [node]
881 state['current'] = [node]
880 hbisect.save_state(repo, state)
882 hbisect.save_state(repo, state)
881 status = ui.system(command, environ={'HG_NODE': hex(node)})
883 status = ui.system(command, environ={'HG_NODE': hex(node)})
882 if status == 125:
884 if status == 125:
883 transition = "skip"
885 transition = "skip"
884 elif status == 0:
886 elif status == 0:
885 transition = "good"
887 transition = "good"
886 # status < 0 means process was killed
888 # status < 0 means process was killed
887 elif status == 127:
889 elif status == 127:
888 raise error.Abort(_("failed to execute %s") % command)
890 raise error.Abort(_("failed to execute %s") % command)
889 elif status < 0:
891 elif status < 0:
890 raise error.Abort(_("%s killed") % command)
892 raise error.Abort(_("%s killed") % command)
891 else:
893 else:
892 transition = "bad"
894 transition = "bad"
893 state[transition].append(node)
895 state[transition].append(node)
894 ctx = repo[node]
896 ctx = repo[node]
895 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
897 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
896 hbisect.checkstate(state)
898 hbisect.checkstate(state)
897 # bisect
899 # bisect
898 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
900 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
899 # update to next check
901 # update to next check
900 node = nodes[0]
902 node = nodes[0]
901 mayupdate(repo, node, show_stats=False)
903 mayupdate(repo, node, show_stats=False)
902 finally:
904 finally:
903 state['current'] = [node]
905 state['current'] = [node]
904 hbisect.save_state(repo, state)
906 hbisect.save_state(repo, state)
905 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
907 hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
906 return
908 return
907
909
908 hbisect.checkstate(state)
910 hbisect.checkstate(state)
909
911
910 # actually bisect
912 # actually bisect
911 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
913 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
912 if extend:
914 if extend:
913 if not changesets:
915 if not changesets:
914 extendnode = hbisect.extendrange(repo, state, nodes, good)
916 extendnode = hbisect.extendrange(repo, state, nodes, good)
915 if extendnode is not None:
917 if extendnode is not None:
916 ui.write(_("Extending search to changeset %d:%s\n")
918 ui.write(_("Extending search to changeset %d:%s\n")
917 % (extendnode.rev(), extendnode))
919 % (extendnode.rev(), extendnode))
918 state['current'] = [extendnode.node()]
920 state['current'] = [extendnode.node()]
919 hbisect.save_state(repo, state)
921 hbisect.save_state(repo, state)
920 return mayupdate(repo, extendnode.node())
922 return mayupdate(repo, extendnode.node())
921 raise error.Abort(_("nothing to extend"))
923 raise error.Abort(_("nothing to extend"))
922
924
923 if changesets == 0:
925 if changesets == 0:
924 hbisect.printresult(ui, repo, state, displayer, nodes, good)
926 hbisect.printresult(ui, repo, state, displayer, nodes, good)
925 else:
927 else:
926 assert len(nodes) == 1 # only a single node can be tested next
928 assert len(nodes) == 1 # only a single node can be tested next
927 node = nodes[0]
929 node = nodes[0]
928 # compute the approximate number of remaining tests
930 # compute the approximate number of remaining tests
929 tests, size = 0, 2
931 tests, size = 0, 2
930 while size <= changesets:
932 while size <= changesets:
931 tests, size = tests + 1, size * 2
933 tests, size = tests + 1, size * 2
932 rev = repo.changelog.rev(node)
934 rev = repo.changelog.rev(node)
933 ui.write(_("Testing changeset %d:%s "
935 ui.write(_("Testing changeset %d:%s "
934 "(%d changesets remaining, ~%d tests)\n")
936 "(%d changesets remaining, ~%d tests)\n")
935 % (rev, short(node), changesets, tests))
937 % (rev, short(node), changesets, tests))
936 state['current'] = [node]
938 state['current'] = [node]
937 hbisect.save_state(repo, state)
939 hbisect.save_state(repo, state)
938 return mayupdate(repo, node)
940 return mayupdate(repo, node)
939
941
940 @command('bookmarks|bookmark',
942 @command('bookmarks|bookmark',
941 [('f', 'force', False, _('force')),
943 [('f', 'force', False, _('force')),
942 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
944 ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
943 ('d', 'delete', False, _('delete a given bookmark')),
945 ('d', 'delete', False, _('delete a given bookmark')),
944 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
946 ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
945 ('i', 'inactive', False, _('mark a bookmark inactive')),
947 ('i', 'inactive', False, _('mark a bookmark inactive')),
946 ] + formatteropts,
948 ] + formatteropts,
947 _('hg bookmarks [OPTIONS]... [NAME]...'))
949 _('hg bookmarks [OPTIONS]... [NAME]...'))
948 def bookmark(ui, repo, *names, **opts):
950 def bookmark(ui, repo, *names, **opts):
949 '''create a new bookmark or list existing bookmarks
951 '''create a new bookmark or list existing bookmarks
950
952
951 Bookmarks are labels on changesets to help track lines of development.
953 Bookmarks are labels on changesets to help track lines of development.
952 Bookmarks are unversioned and can be moved, renamed and deleted.
954 Bookmarks are unversioned and can be moved, renamed and deleted.
953 Deleting or moving a bookmark has no effect on the associated changesets.
955 Deleting or moving a bookmark has no effect on the associated changesets.
954
956
955 Creating or updating to a bookmark causes it to be marked as 'active'.
957 Creating or updating to a bookmark causes it to be marked as 'active'.
956 The active bookmark is indicated with a '*'.
958 The active bookmark is indicated with a '*'.
957 When a commit is made, the active bookmark will advance to the new commit.
959 When a commit is made, the active bookmark will advance to the new commit.
958 A plain :hg:`update` will also advance an active bookmark, if possible.
960 A plain :hg:`update` will also advance an active bookmark, if possible.
959 Updating away from a bookmark will cause it to be deactivated.
961 Updating away from a bookmark will cause it to be deactivated.
960
962
961 Bookmarks can be pushed and pulled between repositories (see
963 Bookmarks can be pushed and pulled between repositories (see
962 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
964 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
963 diverged, a new 'divergent bookmark' of the form 'name@path' will
965 diverged, a new 'divergent bookmark' of the form 'name@path' will
964 be created. Using :hg:`merge` will resolve the divergence.
966 be created. Using :hg:`merge` will resolve the divergence.
965
967
966 A bookmark named '@' has the special property that :hg:`clone` will
968 A bookmark named '@' has the special property that :hg:`clone` will
967 check it out by default if it exists.
969 check it out by default if it exists.
968
970
969 .. container:: verbose
971 .. container:: verbose
970
972
971 Examples:
973 Examples:
972
974
973 - create an active bookmark for a new line of development::
975 - create an active bookmark for a new line of development::
974
976
975 hg book new-feature
977 hg book new-feature
976
978
977 - create an inactive bookmark as a place marker::
979 - create an inactive bookmark as a place marker::
978
980
979 hg book -i reviewed
981 hg book -i reviewed
980
982
981 - create an inactive bookmark on another changeset::
983 - create an inactive bookmark on another changeset::
982
984
983 hg book -r .^ tested
985 hg book -r .^ tested
984
986
985 - rename bookmark turkey to dinner::
987 - rename bookmark turkey to dinner::
986
988
987 hg book -m turkey dinner
989 hg book -m turkey dinner
988
990
989 - move the '@' bookmark from another branch::
991 - move the '@' bookmark from another branch::
990
992
991 hg book -f @
993 hg book -f @
992 '''
994 '''
993 force = opts.get('force')
995 force = opts.get('force')
994 rev = opts.get('rev')
996 rev = opts.get('rev')
995 delete = opts.get('delete')
997 delete = opts.get('delete')
996 rename = opts.get('rename')
998 rename = opts.get('rename')
997 inactive = opts.get('inactive')
999 inactive = opts.get('inactive')
998
1000
999 def checkformat(mark):
1001 def checkformat(mark):
1000 mark = mark.strip()
1002 mark = mark.strip()
1001 if not mark:
1003 if not mark:
1002 raise error.Abort(_("bookmark names cannot consist entirely of "
1004 raise error.Abort(_("bookmark names cannot consist entirely of "
1003 "whitespace"))
1005 "whitespace"))
1004 scmutil.checknewlabel(repo, mark, 'bookmark')
1006 scmutil.checknewlabel(repo, mark, 'bookmark')
1005 return mark
1007 return mark
1006
1008
1007 def checkconflict(repo, mark, cur, force=False, target=None):
1009 def checkconflict(repo, mark, cur, force=False, target=None):
1008 if mark in marks and not force:
1010 if mark in marks and not force:
1009 if target:
1011 if target:
1010 if marks[mark] == target and target == cur:
1012 if marks[mark] == target and target == cur:
1011 # re-activating a bookmark
1013 # re-activating a bookmark
1012 return
1014 return
1013 anc = repo.changelog.ancestors([repo[target].rev()])
1015 anc = repo.changelog.ancestors([repo[target].rev()])
1014 bmctx = repo[marks[mark]]
1016 bmctx = repo[marks[mark]]
1015 divs = [repo[b].node() for b in marks
1017 divs = [repo[b].node() for b in marks
1016 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
1018 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
1017
1019
1018 # allow resolving a single divergent bookmark even if moving
1020 # allow resolving a single divergent bookmark even if moving
1019 # the bookmark across branches when a revision is specified
1021 # the bookmark across branches when a revision is specified
1020 # that contains a divergent bookmark
1022 # that contains a divergent bookmark
1021 if bmctx.rev() not in anc and target in divs:
1023 if bmctx.rev() not in anc and target in divs:
1022 bookmarks.deletedivergent(repo, [target], mark)
1024 bookmarks.deletedivergent(repo, [target], mark)
1023 return
1025 return
1024
1026
1025 deletefrom = [b for b in divs
1027 deletefrom = [b for b in divs
1026 if repo[b].rev() in anc or b == target]
1028 if repo[b].rev() in anc or b == target]
1027 bookmarks.deletedivergent(repo, deletefrom, mark)
1029 bookmarks.deletedivergent(repo, deletefrom, mark)
1028 if bookmarks.validdest(repo, bmctx, repo[target]):
1030 if bookmarks.validdest(repo, bmctx, repo[target]):
1029 ui.status(_("moving bookmark '%s' forward from %s\n") %
1031 ui.status(_("moving bookmark '%s' forward from %s\n") %
1030 (mark, short(bmctx.node())))
1032 (mark, short(bmctx.node())))
1031 return
1033 return
1032 raise error.Abort(_("bookmark '%s' already exists "
1034 raise error.Abort(_("bookmark '%s' already exists "
1033 "(use -f to force)") % mark)
1035 "(use -f to force)") % mark)
1034 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
1036 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
1035 and not force):
1037 and not force):
1036 raise error.Abort(
1038 raise error.Abort(
1037 _("a bookmark cannot have the name of an existing branch"))
1039 _("a bookmark cannot have the name of an existing branch"))
1038
1040
1039 if delete and rename:
1041 if delete and rename:
1040 raise error.Abort(_("--delete and --rename are incompatible"))
1042 raise error.Abort(_("--delete and --rename are incompatible"))
1041 if delete and rev:
1043 if delete and rev:
1042 raise error.Abort(_("--rev is incompatible with --delete"))
1044 raise error.Abort(_("--rev is incompatible with --delete"))
1043 if rename and rev:
1045 if rename and rev:
1044 raise error.Abort(_("--rev is incompatible with --rename"))
1046 raise error.Abort(_("--rev is incompatible with --rename"))
1045 if not names and (delete or rev):
1047 if not names and (delete or rev):
1046 raise error.Abort(_("bookmark name required"))
1048 raise error.Abort(_("bookmark name required"))
1047
1049
1048 if delete or rename or names or inactive:
1050 if delete or rename or names or inactive:
1049 wlock = lock = tr = None
1051 wlock = lock = tr = None
1050 try:
1052 try:
1051 wlock = repo.wlock()
1053 wlock = repo.wlock()
1052 lock = repo.lock()
1054 lock = repo.lock()
1053 cur = repo.changectx('.').node()
1055 cur = repo.changectx('.').node()
1054 marks = repo._bookmarks
1056 marks = repo._bookmarks
1055 if delete:
1057 if delete:
1056 tr = repo.transaction('bookmark')
1058 tr = repo.transaction('bookmark')
1057 for mark in names:
1059 for mark in names:
1058 if mark not in marks:
1060 if mark not in marks:
1059 raise error.Abort(_("bookmark '%s' does not exist") %
1061 raise error.Abort(_("bookmark '%s' does not exist") %
1060 mark)
1062 mark)
1061 if mark == repo._activebookmark:
1063 if mark == repo._activebookmark:
1062 bookmarks.deactivate(repo)
1064 bookmarks.deactivate(repo)
1063 del marks[mark]
1065 del marks[mark]
1064
1066
1065 elif rename:
1067 elif rename:
1066 tr = repo.transaction('bookmark')
1068 tr = repo.transaction('bookmark')
1067 if not names:
1069 if not names:
1068 raise error.Abort(_("new bookmark name required"))
1070 raise error.Abort(_("new bookmark name required"))
1069 elif len(names) > 1:
1071 elif len(names) > 1:
1070 raise error.Abort(_("only one new bookmark name allowed"))
1072 raise error.Abort(_("only one new bookmark name allowed"))
1071 mark = checkformat(names[0])
1073 mark = checkformat(names[0])
1072 if rename not in marks:
1074 if rename not in marks:
1073 raise error.Abort(_("bookmark '%s' does not exist")
1075 raise error.Abort(_("bookmark '%s' does not exist")
1074 % rename)
1076 % rename)
1075 checkconflict(repo, mark, cur, force)
1077 checkconflict(repo, mark, cur, force)
1076 marks[mark] = marks[rename]
1078 marks[mark] = marks[rename]
1077 if repo._activebookmark == rename and not inactive:
1079 if repo._activebookmark == rename and not inactive:
1078 bookmarks.activate(repo, mark)
1080 bookmarks.activate(repo, mark)
1079 del marks[rename]
1081 del marks[rename]
1080 elif names:
1082 elif names:
1081 tr = repo.transaction('bookmark')
1083 tr = repo.transaction('bookmark')
1082 newact = None
1084 newact = None
1083 for mark in names:
1085 for mark in names:
1084 mark = checkformat(mark)
1086 mark = checkformat(mark)
1085 if newact is None:
1087 if newact is None:
1086 newact = mark
1088 newact = mark
1087 if inactive and mark == repo._activebookmark:
1089 if inactive and mark == repo._activebookmark:
1088 bookmarks.deactivate(repo)
1090 bookmarks.deactivate(repo)
1089 return
1091 return
1090 tgt = cur
1092 tgt = cur
1091 if rev:
1093 if rev:
1092 tgt = scmutil.revsingle(repo, rev).node()
1094 tgt = scmutil.revsingle(repo, rev).node()
1093 checkconflict(repo, mark, cur, force, tgt)
1095 checkconflict(repo, mark, cur, force, tgt)
1094 marks[mark] = tgt
1096 marks[mark] = tgt
1095 if not inactive and cur == marks[newact] and not rev:
1097 if not inactive and cur == marks[newact] and not rev:
1096 bookmarks.activate(repo, newact)
1098 bookmarks.activate(repo, newact)
1097 elif cur != tgt and newact == repo._activebookmark:
1099 elif cur != tgt and newact == repo._activebookmark:
1098 bookmarks.deactivate(repo)
1100 bookmarks.deactivate(repo)
1099 elif inactive:
1101 elif inactive:
1100 if len(marks) == 0:
1102 if len(marks) == 0:
1101 ui.status(_("no bookmarks set\n"))
1103 ui.status(_("no bookmarks set\n"))
1102 elif not repo._activebookmark:
1104 elif not repo._activebookmark:
1103 ui.status(_("no active bookmark\n"))
1105 ui.status(_("no active bookmark\n"))
1104 else:
1106 else:
1105 bookmarks.deactivate(repo)
1107 bookmarks.deactivate(repo)
1106 if tr is not None:
1108 if tr is not None:
1107 marks.recordchange(tr)
1109 marks.recordchange(tr)
1108 tr.close()
1110 tr.close()
1109 finally:
1111 finally:
1110 lockmod.release(tr, lock, wlock)
1112 lockmod.release(tr, lock, wlock)
1111 else: # show bookmarks
1113 else: # show bookmarks
1112 fm = ui.formatter('bookmarks', opts)
1114 fm = ui.formatter('bookmarks', opts)
1113 hexfn = fm.hexfunc
1115 hexfn = fm.hexfunc
1114 marks = repo._bookmarks
1116 marks = repo._bookmarks
1115 if len(marks) == 0 and fm.isplain():
1117 if len(marks) == 0 and fm.isplain():
1116 ui.status(_("no bookmarks set\n"))
1118 ui.status(_("no bookmarks set\n"))
1117 for bmark, n in sorted(marks.iteritems()):
1119 for bmark, n in sorted(marks.iteritems()):
1118 active = repo._activebookmark
1120 active = repo._activebookmark
1119 if bmark == active:
1121 if bmark == active:
1120 prefix, label = '*', activebookmarklabel
1122 prefix, label = '*', activebookmarklabel
1121 else:
1123 else:
1122 prefix, label = ' ', ''
1124 prefix, label = ' ', ''
1123
1125
1124 fm.startitem()
1126 fm.startitem()
1125 if not ui.quiet:
1127 if not ui.quiet:
1126 fm.plain(' %s ' % prefix, label=label)
1128 fm.plain(' %s ' % prefix, label=label)
1127 fm.write('bookmark', '%s', bmark, label=label)
1129 fm.write('bookmark', '%s', bmark, label=label)
1128 pad = " " * (25 - encoding.colwidth(bmark))
1130 pad = " " * (25 - encoding.colwidth(bmark))
1129 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1131 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1130 repo.changelog.rev(n), hexfn(n), label=label)
1132 repo.changelog.rev(n), hexfn(n), label=label)
1131 fm.data(active=(bmark == active))
1133 fm.data(active=(bmark == active))
1132 fm.plain('\n')
1134 fm.plain('\n')
1133 fm.end()
1135 fm.end()
1134
1136
1135 @command('branch',
1137 @command('branch',
1136 [('f', 'force', None,
1138 [('f', 'force', None,
1137 _('set branch name even if it shadows an existing branch')),
1139 _('set branch name even if it shadows an existing branch')),
1138 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1140 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1139 _('[-fC] [NAME]'))
1141 _('[-fC] [NAME]'))
1140 def branch(ui, repo, label=None, **opts):
1142 def branch(ui, repo, label=None, **opts):
1141 """set or show the current branch name
1143 """set or show the current branch name
1142
1144
1143 .. note::
1145 .. note::
1144
1146
1145 Branch names are permanent and global. Use :hg:`bookmark` to create a
1147 Branch names are permanent and global. Use :hg:`bookmark` to create a
1146 light-weight bookmark instead. See :hg:`help glossary` for more
1148 light-weight bookmark instead. See :hg:`help glossary` for more
1147 information about named branches and bookmarks.
1149 information about named branches and bookmarks.
1148
1150
1149 With no argument, show the current branch name. With one argument,
1151 With no argument, show the current branch name. With one argument,
1150 set the working directory branch name (the branch will not exist
1152 set the working directory branch name (the branch will not exist
1151 in the repository until the next commit). Standard practice
1153 in the repository until the next commit). Standard practice
1152 recommends that primary development take place on the 'default'
1154 recommends that primary development take place on the 'default'
1153 branch.
1155 branch.
1154
1156
1155 Unless -f/--force is specified, branch will not let you set a
1157 Unless -f/--force is specified, branch will not let you set a
1156 branch name that already exists.
1158 branch name that already exists.
1157
1159
1158 Use -C/--clean to reset the working directory branch to that of
1160 Use -C/--clean to reset the working directory branch to that of
1159 the parent of the working directory, negating a previous branch
1161 the parent of the working directory, negating a previous branch
1160 change.
1162 change.
1161
1163
1162 Use the command :hg:`update` to switch to an existing branch. Use
1164 Use the command :hg:`update` to switch to an existing branch. Use
1163 :hg:`commit --close-branch` to mark this branch head as closed.
1165 :hg:`commit --close-branch` to mark this branch head as closed.
1164 When all heads of a branch are closed, the branch will be
1166 When all heads of a branch are closed, the branch will be
1165 considered closed.
1167 considered closed.
1166
1168
1167 Returns 0 on success.
1169 Returns 0 on success.
1168 """
1170 """
1169 if label:
1171 if label:
1170 label = label.strip()
1172 label = label.strip()
1171
1173
1172 if not opts.get('clean') and not label:
1174 if not opts.get('clean') and not label:
1173 ui.write("%s\n" % repo.dirstate.branch())
1175 ui.write("%s\n" % repo.dirstate.branch())
1174 return
1176 return
1175
1177
1176 with repo.wlock():
1178 with repo.wlock():
1177 if opts.get('clean'):
1179 if opts.get('clean'):
1178 label = repo[None].p1().branch()
1180 label = repo[None].p1().branch()
1179 repo.dirstate.setbranch(label)
1181 repo.dirstate.setbranch(label)
1180 ui.status(_('reset working directory to branch %s\n') % label)
1182 ui.status(_('reset working directory to branch %s\n') % label)
1181 elif label:
1183 elif label:
1182 if not opts.get('force') and label in repo.branchmap():
1184 if not opts.get('force') and label in repo.branchmap():
1183 if label not in [p.branch() for p in repo[None].parents()]:
1185 if label not in [p.branch() for p in repo[None].parents()]:
1184 raise error.Abort(_('a branch of the same name already'
1186 raise error.Abort(_('a branch of the same name already'
1185 ' exists'),
1187 ' exists'),
1186 # i18n: "it" refers to an existing branch
1188 # i18n: "it" refers to an existing branch
1187 hint=_("use 'hg update' to switch to it"))
1189 hint=_("use 'hg update' to switch to it"))
1188 scmutil.checknewlabel(repo, label, 'branch')
1190 scmutil.checknewlabel(repo, label, 'branch')
1189 repo.dirstate.setbranch(label)
1191 repo.dirstate.setbranch(label)
1190 ui.status(_('marked working directory as branch %s\n') % label)
1192 ui.status(_('marked working directory as branch %s\n') % label)
1191
1193
1192 # find any open named branches aside from default
1194 # find any open named branches aside from default
1193 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1195 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1194 if n != "default" and not c]
1196 if n != "default" and not c]
1195 if not others:
1197 if not others:
1196 ui.status(_('(branches are permanent and global, '
1198 ui.status(_('(branches are permanent and global, '
1197 'did you want a bookmark?)\n'))
1199 'did you want a bookmark?)\n'))
1198
1200
1199 @command('branches',
1201 @command('branches',
1200 [('a', 'active', False,
1202 [('a', 'active', False,
1201 _('show only branches that have unmerged heads (DEPRECATED)')),
1203 _('show only branches that have unmerged heads (DEPRECATED)')),
1202 ('c', 'closed', False, _('show normal and closed branches')),
1204 ('c', 'closed', False, _('show normal and closed branches')),
1203 ] + formatteropts,
1205 ] + formatteropts,
1204 _('[-c]'))
1206 _('[-c]'))
1205 def branches(ui, repo, active=False, closed=False, **opts):
1207 def branches(ui, repo, active=False, closed=False, **opts):
1206 """list repository named branches
1208 """list repository named branches
1207
1209
1208 List the repository's named branches, indicating which ones are
1210 List the repository's named branches, indicating which ones are
1209 inactive. If -c/--closed is specified, also list branches which have
1211 inactive. If -c/--closed is specified, also list branches which have
1210 been marked closed (see :hg:`commit --close-branch`).
1212 been marked closed (see :hg:`commit --close-branch`).
1211
1213
1212 Use the command :hg:`update` to switch to an existing branch.
1214 Use the command :hg:`update` to switch to an existing branch.
1213
1215
1214 Returns 0.
1216 Returns 0.
1215 """
1217 """
1216
1218
1217 fm = ui.formatter('branches', opts)
1219 fm = ui.formatter('branches', opts)
1218 hexfunc = fm.hexfunc
1220 hexfunc = fm.hexfunc
1219
1221
1220 allheads = set(repo.heads())
1222 allheads = set(repo.heads())
1221 branches = []
1223 branches = []
1222 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1224 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1223 isactive = not isclosed and bool(set(heads) & allheads)
1225 isactive = not isclosed and bool(set(heads) & allheads)
1224 branches.append((tag, repo[tip], isactive, not isclosed))
1226 branches.append((tag, repo[tip], isactive, not isclosed))
1225 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1227 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1226 reverse=True)
1228 reverse=True)
1227
1229
1228 for tag, ctx, isactive, isopen in branches:
1230 for tag, ctx, isactive, isopen in branches:
1229 if active and not isactive:
1231 if active and not isactive:
1230 continue
1232 continue
1231 if isactive:
1233 if isactive:
1232 label = 'branches.active'
1234 label = 'branches.active'
1233 notice = ''
1235 notice = ''
1234 elif not isopen:
1236 elif not isopen:
1235 if not closed:
1237 if not closed:
1236 continue
1238 continue
1237 label = 'branches.closed'
1239 label = 'branches.closed'
1238 notice = _(' (closed)')
1240 notice = _(' (closed)')
1239 else:
1241 else:
1240 label = 'branches.inactive'
1242 label = 'branches.inactive'
1241 notice = _(' (inactive)')
1243 notice = _(' (inactive)')
1242 current = (tag == repo.dirstate.branch())
1244 current = (tag == repo.dirstate.branch())
1243 if current:
1245 if current:
1244 label = 'branches.current'
1246 label = 'branches.current'
1245
1247
1246 fm.startitem()
1248 fm.startitem()
1247 fm.write('branch', '%s', tag, label=label)
1249 fm.write('branch', '%s', tag, label=label)
1248 rev = ctx.rev()
1250 rev = ctx.rev()
1249 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1251 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1250 fmt = ' ' * padsize + ' %d:%s'
1252 fmt = ' ' * padsize + ' %d:%s'
1251 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1253 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1252 label='log.changeset changeset.%s' % ctx.phasestr())
1254 label='log.changeset changeset.%s' % ctx.phasestr())
1253 fm.data(active=isactive, closed=not isopen, current=current)
1255 fm.data(active=isactive, closed=not isopen, current=current)
1254 if not ui.quiet:
1256 if not ui.quiet:
1255 fm.plain(notice)
1257 fm.plain(notice)
1256 fm.plain('\n')
1258 fm.plain('\n')
1257 fm.end()
1259 fm.end()
1258
1260
1259 @command('bundle',
1261 @command('bundle',
1260 [('f', 'force', None, _('run even when the destination is unrelated')),
1262 [('f', 'force', None, _('run even when the destination is unrelated')),
1261 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1263 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1262 _('REV')),
1264 _('REV')),
1263 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1265 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1264 _('BRANCH')),
1266 _('BRANCH')),
1265 ('', 'base', [],
1267 ('', 'base', [],
1266 _('a base changeset assumed to be available at the destination'),
1268 _('a base changeset assumed to be available at the destination'),
1267 _('REV')),
1269 _('REV')),
1268 ('a', 'all', None, _('bundle all changesets in the repository')),
1270 ('a', 'all', None, _('bundle all changesets in the repository')),
1269 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1271 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1270 ] + remoteopts,
1272 ] + remoteopts,
1271 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1273 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1272 def bundle(ui, repo, fname, dest=None, **opts):
1274 def bundle(ui, repo, fname, dest=None, **opts):
1273 """create a changegroup file
1275 """create a changegroup file
1274
1276
1275 Generate a changegroup file collecting changesets to be added
1277 Generate a changegroup file collecting changesets to be added
1276 to a repository.
1278 to a repository.
1277
1279
1278 To create a bundle containing all changesets, use -a/--all
1280 To create a bundle containing all changesets, use -a/--all
1279 (or --base null). Otherwise, hg assumes the destination will have
1281 (or --base null). Otherwise, hg assumes the destination will have
1280 all the nodes you specify with --base parameters. Otherwise, hg
1282 all the nodes you specify with --base parameters. Otherwise, hg
1281 will assume the repository has all the nodes in destination, or
1283 will assume the repository has all the nodes in destination, or
1282 default-push/default if no destination is specified.
1284 default-push/default if no destination is specified.
1283
1285
1284 You can change bundle format with the -t/--type option. You can
1286 You can change bundle format with the -t/--type option. You can
1285 specify a compression, a bundle version or both using a dash
1287 specify a compression, a bundle version or both using a dash
1286 (comp-version). The available compression methods are: none, bzip2,
1288 (comp-version). The available compression methods are: none, bzip2,
1287 and gzip (by default, bundles are compressed using bzip2). The
1289 and gzip (by default, bundles are compressed using bzip2). The
1288 available formats are: v1, v2 (default to most suitable).
1290 available formats are: v1, v2 (default to most suitable).
1289
1291
1290 The bundle file can then be transferred using conventional means
1292 The bundle file can then be transferred using conventional means
1291 and applied to another repository with the unbundle or pull
1293 and applied to another repository with the unbundle or pull
1292 command. This is useful when direct push and pull are not
1294 command. This is useful when direct push and pull are not
1293 available or when exporting an entire repository is undesirable.
1295 available or when exporting an entire repository is undesirable.
1294
1296
1295 Applying bundles preserves all changeset contents including
1297 Applying bundles preserves all changeset contents including
1296 permissions, copy/rename information, and revision history.
1298 permissions, copy/rename information, and revision history.
1297
1299
1298 Returns 0 on success, 1 if no changes found.
1300 Returns 0 on success, 1 if no changes found.
1299 """
1301 """
1300 revs = None
1302 revs = None
1301 if 'rev' in opts:
1303 if 'rev' in opts:
1302 revstrings = opts['rev']
1304 revstrings = opts['rev']
1303 revs = scmutil.revrange(repo, revstrings)
1305 revs = scmutil.revrange(repo, revstrings)
1304 if revstrings and not revs:
1306 if revstrings and not revs:
1305 raise error.Abort(_('no commits to bundle'))
1307 raise error.Abort(_('no commits to bundle'))
1306
1308
1307 bundletype = opts.get('type', 'bzip2').lower()
1309 bundletype = opts.get('type', 'bzip2').lower()
1308 try:
1310 try:
1309 bcompression, cgversion, params = exchange.parsebundlespec(
1311 bcompression, cgversion, params = exchange.parsebundlespec(
1310 repo, bundletype, strict=False)
1312 repo, bundletype, strict=False)
1311 except error.UnsupportedBundleSpecification as e:
1313 except error.UnsupportedBundleSpecification as e:
1312 raise error.Abort(str(e),
1314 raise error.Abort(str(e),
1313 hint=_("see 'hg help bundle' for supported "
1315 hint=_("see 'hg help bundle' for supported "
1314 "values for --type"))
1316 "values for --type"))
1315
1317
1316 # Packed bundles are a pseudo bundle format for now.
1318 # Packed bundles are a pseudo bundle format for now.
1317 if cgversion == 's1':
1319 if cgversion == 's1':
1318 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1320 raise error.Abort(_('packed bundles cannot be produced by "hg bundle"'),
1319 hint=_("use 'hg debugcreatestreamclonebundle'"))
1321 hint=_("use 'hg debugcreatestreamclonebundle'"))
1320
1322
1321 if opts.get('all'):
1323 if opts.get('all'):
1322 if dest:
1324 if dest:
1323 raise error.Abort(_("--all is incompatible with specifying "
1325 raise error.Abort(_("--all is incompatible with specifying "
1324 "a destination"))
1326 "a destination"))
1325 if opts.get('base'):
1327 if opts.get('base'):
1326 ui.warn(_("ignoring --base because --all was specified\n"))
1328 ui.warn(_("ignoring --base because --all was specified\n"))
1327 base = ['null']
1329 base = ['null']
1328 else:
1330 else:
1329 base = scmutil.revrange(repo, opts.get('base'))
1331 base = scmutil.revrange(repo, opts.get('base'))
1330 # TODO: get desired bundlecaps from command line.
1332 # TODO: get desired bundlecaps from command line.
1331 bundlecaps = None
1333 bundlecaps = None
1332 if cgversion not in changegroup.supportedoutgoingversions(repo):
1334 if cgversion not in changegroup.supportedoutgoingversions(repo):
1333 raise error.Abort(_("repository does not support bundle version %s") %
1335 raise error.Abort(_("repository does not support bundle version %s") %
1334 cgversion)
1336 cgversion)
1335
1337
1336 if base:
1338 if base:
1337 if dest:
1339 if dest:
1338 raise error.Abort(_("--base is incompatible with specifying "
1340 raise error.Abort(_("--base is incompatible with specifying "
1339 "a destination"))
1341 "a destination"))
1340 common = [repo.lookup(rev) for rev in base]
1342 common = [repo.lookup(rev) for rev in base]
1341 heads = revs and map(repo.lookup, revs) or None
1343 heads = revs and map(repo.lookup, revs) or None
1342 outgoing = discovery.outgoing(repo, common, heads)
1344 outgoing = discovery.outgoing(repo, common, heads)
1343 cg = changegroup.getchangegroup(repo, 'bundle', outgoing,
1345 cg = changegroup.getchangegroup(repo, 'bundle', outgoing,
1344 bundlecaps=bundlecaps,
1346 bundlecaps=bundlecaps,
1345 version=cgversion)
1347 version=cgversion)
1346 outgoing = None
1348 outgoing = None
1347 else:
1349 else:
1348 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1350 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1349 dest, branches = hg.parseurl(dest, opts.get('branch'))
1351 dest, branches = hg.parseurl(dest, opts.get('branch'))
1350 other = hg.peer(repo, opts, dest)
1352 other = hg.peer(repo, opts, dest)
1351 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1353 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1352 heads = revs and map(repo.lookup, revs) or revs
1354 heads = revs and map(repo.lookup, revs) or revs
1353 outgoing = discovery.findcommonoutgoing(repo, other,
1355 outgoing = discovery.findcommonoutgoing(repo, other,
1354 onlyheads=heads,
1356 onlyheads=heads,
1355 force=opts.get('force'),
1357 force=opts.get('force'),
1356 portable=True)
1358 portable=True)
1357 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1359 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1358 bundlecaps, version=cgversion)
1360 bundlecaps, version=cgversion)
1359 if not cg:
1361 if not cg:
1360 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1362 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1361 return 1
1363 return 1
1362
1364
1363 if cgversion == '01': #bundle1
1365 if cgversion == '01': #bundle1
1364 if bcompression is None:
1366 if bcompression is None:
1365 bcompression = 'UN'
1367 bcompression = 'UN'
1366 bversion = 'HG10' + bcompression
1368 bversion = 'HG10' + bcompression
1367 bcompression = None
1369 bcompression = None
1368 else:
1370 else:
1369 assert cgversion == '02'
1371 assert cgversion == '02'
1370 bversion = 'HG20'
1372 bversion = 'HG20'
1371
1373
1372 # TODO compression options should be derived from bundlespec parsing.
1374 # TODO compression options should be derived from bundlespec parsing.
1373 # This is a temporary hack to allow adjusting bundle compression
1375 # This is a temporary hack to allow adjusting bundle compression
1374 # level without a) formalizing the bundlespec changes to declare it
1376 # level without a) formalizing the bundlespec changes to declare it
1375 # b) introducing a command flag.
1377 # b) introducing a command flag.
1376 compopts = {}
1378 compopts = {}
1377 complevel = ui.configint('experimental', 'bundlecomplevel')
1379 complevel = ui.configint('experimental', 'bundlecomplevel')
1378 if complevel is not None:
1380 if complevel is not None:
1379 compopts['level'] = complevel
1381 compopts['level'] = complevel
1380
1382
1381 bundle2.writebundle(ui, cg, fname, bversion, compression=bcompression,
1383 bundle2.writebundle(ui, cg, fname, bversion, compression=bcompression,
1382 compopts=compopts)
1384 compopts=compopts)
1383
1385
1384 @command('cat',
1386 @command('cat',
1385 [('o', 'output', '',
1387 [('o', 'output', '',
1386 _('print output to file with formatted name'), _('FORMAT')),
1388 _('print output to file with formatted name'), _('FORMAT')),
1387 ('r', 'rev', '', _('print the given revision'), _('REV')),
1389 ('r', 'rev', '', _('print the given revision'), _('REV')),
1388 ('', 'decode', None, _('apply any matching decode filter')),
1390 ('', 'decode', None, _('apply any matching decode filter')),
1389 ] + walkopts,
1391 ] + walkopts,
1390 _('[OPTION]... FILE...'),
1392 _('[OPTION]... FILE...'),
1391 inferrepo=True)
1393 inferrepo=True)
1392 def cat(ui, repo, file1, *pats, **opts):
1394 def cat(ui, repo, file1, *pats, **opts):
1393 """output the current or given revision of files
1395 """output the current or given revision of files
1394
1396
1395 Print the specified files as they were at the given revision. If
1397 Print the specified files as they were at the given revision. If
1396 no revision is given, the parent of the working directory is used.
1398 no revision is given, the parent of the working directory is used.
1397
1399
1398 Output may be to a file, in which case the name of the file is
1400 Output may be to a file, in which case the name of the file is
1399 given using a format string. The formatting rules as follows:
1401 given using a format string. The formatting rules as follows:
1400
1402
1401 :``%%``: literal "%" character
1403 :``%%``: literal "%" character
1402 :``%s``: basename of file being printed
1404 :``%s``: basename of file being printed
1403 :``%d``: dirname of file being printed, or '.' if in repository root
1405 :``%d``: dirname of file being printed, or '.' if in repository root
1404 :``%p``: root-relative path name of file being printed
1406 :``%p``: root-relative path name of file being printed
1405 :``%H``: changeset hash (40 hexadecimal digits)
1407 :``%H``: changeset hash (40 hexadecimal digits)
1406 :``%R``: changeset revision number
1408 :``%R``: changeset revision number
1407 :``%h``: short-form changeset hash (12 hexadecimal digits)
1409 :``%h``: short-form changeset hash (12 hexadecimal digits)
1408 :``%r``: zero-padded changeset revision number
1410 :``%r``: zero-padded changeset revision number
1409 :``%b``: basename of the exporting repository
1411 :``%b``: basename of the exporting repository
1410
1412
1411 Returns 0 on success.
1413 Returns 0 on success.
1412 """
1414 """
1413 ctx = scmutil.revsingle(repo, opts.get('rev'))
1415 ctx = scmutil.revsingle(repo, opts.get('rev'))
1414 m = scmutil.match(ctx, (file1,) + pats, opts)
1416 m = scmutil.match(ctx, (file1,) + pats, opts)
1415
1417
1416 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1418 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1417
1419
1418 @command('^clone',
1420 @command('^clone',
1419 [('U', 'noupdate', None, _('the clone will include an empty working '
1421 [('U', 'noupdate', None, _('the clone will include an empty working '
1420 'directory (only a repository)')),
1422 'directory (only a repository)')),
1421 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1423 ('u', 'updaterev', '', _('revision, tag, or branch to check out'),
1422 _('REV')),
1424 _('REV')),
1423 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1425 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1424 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1426 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1425 ('', 'pull', None, _('use pull protocol to copy metadata')),
1427 ('', 'pull', None, _('use pull protocol to copy metadata')),
1426 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1428 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1427 ] + remoteopts,
1429 ] + remoteopts,
1428 _('[OPTION]... SOURCE [DEST]'),
1430 _('[OPTION]... SOURCE [DEST]'),
1429 norepo=True)
1431 norepo=True)
1430 def clone(ui, source, dest=None, **opts):
1432 def clone(ui, source, dest=None, **opts):
1431 """make a copy of an existing repository
1433 """make a copy of an existing repository
1432
1434
1433 Create a copy of an existing repository in a new directory.
1435 Create a copy of an existing repository in a new directory.
1434
1436
1435 If no destination directory name is specified, it defaults to the
1437 If no destination directory name is specified, it defaults to the
1436 basename of the source.
1438 basename of the source.
1437
1439
1438 The location of the source is added to the new repository's
1440 The location of the source is added to the new repository's
1439 ``.hg/hgrc`` file, as the default to be used for future pulls.
1441 ``.hg/hgrc`` file, as the default to be used for future pulls.
1440
1442
1441 Only local paths and ``ssh://`` URLs are supported as
1443 Only local paths and ``ssh://`` URLs are supported as
1442 destinations. For ``ssh://`` destinations, no working directory or
1444 destinations. For ``ssh://`` destinations, no working directory or
1443 ``.hg/hgrc`` will be created on the remote side.
1445 ``.hg/hgrc`` will be created on the remote side.
1444
1446
1445 If the source repository has a bookmark called '@' set, that
1447 If the source repository has a bookmark called '@' set, that
1446 revision will be checked out in the new repository by default.
1448 revision will be checked out in the new repository by default.
1447
1449
1448 To check out a particular version, use -u/--update, or
1450 To check out a particular version, use -u/--update, or
1449 -U/--noupdate to create a clone with no working directory.
1451 -U/--noupdate to create a clone with no working directory.
1450
1452
1451 To pull only a subset of changesets, specify one or more revisions
1453 To pull only a subset of changesets, specify one or more revisions
1452 identifiers with -r/--rev or branches with -b/--branch. The
1454 identifiers with -r/--rev or branches with -b/--branch. The
1453 resulting clone will contain only the specified changesets and
1455 resulting clone will contain only the specified changesets and
1454 their ancestors. These options (or 'clone src#rev dest') imply
1456 their ancestors. These options (or 'clone src#rev dest') imply
1455 --pull, even for local source repositories.
1457 --pull, even for local source repositories.
1456
1458
1457 .. note::
1459 .. note::
1458
1460
1459 Specifying a tag will include the tagged changeset but not the
1461 Specifying a tag will include the tagged changeset but not the
1460 changeset containing the tag.
1462 changeset containing the tag.
1461
1463
1462 .. container:: verbose
1464 .. container:: verbose
1463
1465
1464 For efficiency, hardlinks are used for cloning whenever the
1466 For efficiency, hardlinks are used for cloning whenever the
1465 source and destination are on the same filesystem (note this
1467 source and destination are on the same filesystem (note this
1466 applies only to the repository data, not to the working
1468 applies only to the repository data, not to the working
1467 directory). Some filesystems, such as AFS, implement hardlinking
1469 directory). Some filesystems, such as AFS, implement hardlinking
1468 incorrectly, but do not report errors. In these cases, use the
1470 incorrectly, but do not report errors. In these cases, use the
1469 --pull option to avoid hardlinking.
1471 --pull option to avoid hardlinking.
1470
1472
1471 In some cases, you can clone repositories and the working
1473 In some cases, you can clone repositories and the working
1472 directory using full hardlinks with ::
1474 directory using full hardlinks with ::
1473
1475
1474 $ cp -al REPO REPOCLONE
1476 $ cp -al REPO REPOCLONE
1475
1477
1476 This is the fastest way to clone, but it is not always safe. The
1478 This is the fastest way to clone, but it is not always safe. The
1477 operation is not atomic (making sure REPO is not modified during
1479 operation is not atomic (making sure REPO is not modified during
1478 the operation is up to you) and you have to make sure your
1480 the operation is up to you) and you have to make sure your
1479 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1481 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1480 so). Also, this is not compatible with certain extensions that
1482 so). Also, this is not compatible with certain extensions that
1481 place their metadata under the .hg directory, such as mq.
1483 place their metadata under the .hg directory, such as mq.
1482
1484
1483 Mercurial will update the working directory to the first applicable
1485 Mercurial will update the working directory to the first applicable
1484 revision from this list:
1486 revision from this list:
1485
1487
1486 a) null if -U or the source repository has no changesets
1488 a) null if -U or the source repository has no changesets
1487 b) if -u . and the source repository is local, the first parent of
1489 b) if -u . and the source repository is local, the first parent of
1488 the source repository's working directory
1490 the source repository's working directory
1489 c) the changeset specified with -u (if a branch name, this means the
1491 c) the changeset specified with -u (if a branch name, this means the
1490 latest head of that branch)
1492 latest head of that branch)
1491 d) the changeset specified with -r
1493 d) the changeset specified with -r
1492 e) the tipmost head specified with -b
1494 e) the tipmost head specified with -b
1493 f) the tipmost head specified with the url#branch source syntax
1495 f) the tipmost head specified with the url#branch source syntax
1494 g) the revision marked with the '@' bookmark, if present
1496 g) the revision marked with the '@' bookmark, if present
1495 h) the tipmost head of the default branch
1497 h) the tipmost head of the default branch
1496 i) tip
1498 i) tip
1497
1499
1498 When cloning from servers that support it, Mercurial may fetch
1500 When cloning from servers that support it, Mercurial may fetch
1499 pre-generated data from a server-advertised URL. When this is done,
1501 pre-generated data from a server-advertised URL. When this is done,
1500 hooks operating on incoming changesets and changegroups may fire twice,
1502 hooks operating on incoming changesets and changegroups may fire twice,
1501 once for the bundle fetched from the URL and another for any additional
1503 once for the bundle fetched from the URL and another for any additional
1502 data not fetched from this URL. In addition, if an error occurs, the
1504 data not fetched from this URL. In addition, if an error occurs, the
1503 repository may be rolled back to a partial clone. This behavior may
1505 repository may be rolled back to a partial clone. This behavior may
1504 change in future releases. See :hg:`help -e clonebundles` for more.
1506 change in future releases. See :hg:`help -e clonebundles` for more.
1505
1507
1506 Examples:
1508 Examples:
1507
1509
1508 - clone a remote repository to a new directory named hg/::
1510 - clone a remote repository to a new directory named hg/::
1509
1511
1510 hg clone https://www.mercurial-scm.org/repo/hg/
1512 hg clone https://www.mercurial-scm.org/repo/hg/
1511
1513
1512 - create a lightweight local clone::
1514 - create a lightweight local clone::
1513
1515
1514 hg clone project/ project-feature/
1516 hg clone project/ project-feature/
1515
1517
1516 - clone from an absolute path on an ssh server (note double-slash)::
1518 - clone from an absolute path on an ssh server (note double-slash)::
1517
1519
1518 hg clone ssh://user@server//home/projects/alpha/
1520 hg clone ssh://user@server//home/projects/alpha/
1519
1521
1520 - do a high-speed clone over a LAN while checking out a
1522 - do a high-speed clone over a LAN while checking out a
1521 specified version::
1523 specified version::
1522
1524
1523 hg clone --uncompressed http://server/repo -u 1.5
1525 hg clone --uncompressed http://server/repo -u 1.5
1524
1526
1525 - create a repository without changesets after a particular revision::
1527 - create a repository without changesets after a particular revision::
1526
1528
1527 hg clone -r 04e544 experimental/ good/
1529 hg clone -r 04e544 experimental/ good/
1528
1530
1529 - clone (and track) a particular named branch::
1531 - clone (and track) a particular named branch::
1530
1532
1531 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1533 hg clone https://www.mercurial-scm.org/repo/hg/#stable
1532
1534
1533 See :hg:`help urls` for details on specifying URLs.
1535 See :hg:`help urls` for details on specifying URLs.
1534
1536
1535 Returns 0 on success.
1537 Returns 0 on success.
1536 """
1538 """
1537 if opts.get('noupdate') and opts.get('updaterev'):
1539 if opts.get('noupdate') and opts.get('updaterev'):
1538 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1540 raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
1539
1541
1540 r = hg.clone(ui, opts, source, dest,
1542 r = hg.clone(ui, opts, source, dest,
1541 pull=opts.get('pull'),
1543 pull=opts.get('pull'),
1542 stream=opts.get('uncompressed'),
1544 stream=opts.get('uncompressed'),
1543 rev=opts.get('rev'),
1545 rev=opts.get('rev'),
1544 update=opts.get('updaterev') or not opts.get('noupdate'),
1546 update=opts.get('updaterev') or not opts.get('noupdate'),
1545 branch=opts.get('branch'),
1547 branch=opts.get('branch'),
1546 shareopts=opts.get('shareopts'))
1548 shareopts=opts.get('shareopts'))
1547
1549
1548 return r is None
1550 return r is None
1549
1551
1550 @command('^commit|ci',
1552 @command('^commit|ci',
1551 [('A', 'addremove', None,
1553 [('A', 'addremove', None,
1552 _('mark new/missing files as added/removed before committing')),
1554 _('mark new/missing files as added/removed before committing')),
1553 ('', 'close-branch', None,
1555 ('', 'close-branch', None,
1554 _('mark a branch head as closed')),
1556 _('mark a branch head as closed')),
1555 ('', 'amend', None, _('amend the parent of the working directory')),
1557 ('', 'amend', None, _('amend the parent of the working directory')),
1556 ('s', 'secret', None, _('use the secret phase for committing')),
1558 ('s', 'secret', None, _('use the secret phase for committing')),
1557 ('e', 'edit', None, _('invoke editor on commit messages')),
1559 ('e', 'edit', None, _('invoke editor on commit messages')),
1558 ('i', 'interactive', None, _('use interactive mode')),
1560 ('i', 'interactive', None, _('use interactive mode')),
1559 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1561 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1560 _('[OPTION]... [FILE]...'),
1562 _('[OPTION]... [FILE]...'),
1561 inferrepo=True)
1563 inferrepo=True)
1562 def commit(ui, repo, *pats, **opts):
1564 def commit(ui, repo, *pats, **opts):
1563 """commit the specified files or all outstanding changes
1565 """commit the specified files or all outstanding changes
1564
1566
1565 Commit changes to the given files into the repository. Unlike a
1567 Commit changes to the given files into the repository. Unlike a
1566 centralized SCM, this operation is a local operation. See
1568 centralized SCM, this operation is a local operation. See
1567 :hg:`push` for a way to actively distribute your changes.
1569 :hg:`push` for a way to actively distribute your changes.
1568
1570
1569 If a list of files is omitted, all changes reported by :hg:`status`
1571 If a list of files is omitted, all changes reported by :hg:`status`
1570 will be committed.
1572 will be committed.
1571
1573
1572 If you are committing the result of a merge, do not provide any
1574 If you are committing the result of a merge, do not provide any
1573 filenames or -I/-X filters.
1575 filenames or -I/-X filters.
1574
1576
1575 If no commit message is specified, Mercurial starts your
1577 If no commit message is specified, Mercurial starts your
1576 configured editor where you can enter a message. In case your
1578 configured editor where you can enter a message. In case your
1577 commit fails, you will find a backup of your message in
1579 commit fails, you will find a backup of your message in
1578 ``.hg/last-message.txt``.
1580 ``.hg/last-message.txt``.
1579
1581
1580 The --close-branch flag can be used to mark the current branch
1582 The --close-branch flag can be used to mark the current branch
1581 head closed. When all heads of a branch are closed, the branch
1583 head closed. When all heads of a branch are closed, the branch
1582 will be considered closed and no longer listed.
1584 will be considered closed and no longer listed.
1583
1585
1584 The --amend flag can be used to amend the parent of the
1586 The --amend flag can be used to amend the parent of the
1585 working directory with a new commit that contains the changes
1587 working directory with a new commit that contains the changes
1586 in the parent in addition to those currently reported by :hg:`status`,
1588 in the parent in addition to those currently reported by :hg:`status`,
1587 if there are any. The old commit is stored in a backup bundle in
1589 if there are any. The old commit is stored in a backup bundle in
1588 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1590 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1589 on how to restore it).
1591 on how to restore it).
1590
1592
1591 Message, user and date are taken from the amended commit unless
1593 Message, user and date are taken from the amended commit unless
1592 specified. When a message isn't specified on the command line,
1594 specified. When a message isn't specified on the command line,
1593 the editor will open with the message of the amended commit.
1595 the editor will open with the message of the amended commit.
1594
1596
1595 It is not possible to amend public changesets (see :hg:`help phases`)
1597 It is not possible to amend public changesets (see :hg:`help phases`)
1596 or changesets that have children.
1598 or changesets that have children.
1597
1599
1598 See :hg:`help dates` for a list of formats valid for -d/--date.
1600 See :hg:`help dates` for a list of formats valid for -d/--date.
1599
1601
1600 Returns 0 on success, 1 if nothing changed.
1602 Returns 0 on success, 1 if nothing changed.
1601
1603
1602 .. container:: verbose
1604 .. container:: verbose
1603
1605
1604 Examples:
1606 Examples:
1605
1607
1606 - commit all files ending in .py::
1608 - commit all files ending in .py::
1607
1609
1608 hg commit --include "set:**.py"
1610 hg commit --include "set:**.py"
1609
1611
1610 - commit all non-binary files::
1612 - commit all non-binary files::
1611
1613
1612 hg commit --exclude "set:binary()"
1614 hg commit --exclude "set:binary()"
1613
1615
1614 - amend the current commit and set the date to now::
1616 - amend the current commit and set the date to now::
1615
1617
1616 hg commit --amend --date now
1618 hg commit --amend --date now
1617 """
1619 """
1618 wlock = lock = None
1620 wlock = lock = None
1619 try:
1621 try:
1620 wlock = repo.wlock()
1622 wlock = repo.wlock()
1621 lock = repo.lock()
1623 lock = repo.lock()
1622 return _docommit(ui, repo, *pats, **opts)
1624 return _docommit(ui, repo, *pats, **opts)
1623 finally:
1625 finally:
1624 release(lock, wlock)
1626 release(lock, wlock)
1625
1627
1626 def _docommit(ui, repo, *pats, **opts):
1628 def _docommit(ui, repo, *pats, **opts):
1627 if opts.get('interactive'):
1629 if opts.get('interactive'):
1628 opts.pop('interactive')
1630 opts.pop('interactive')
1629 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1631 ret = cmdutil.dorecord(ui, repo, commit, None, False,
1630 cmdutil.recordfilter, *pats, **opts)
1632 cmdutil.recordfilter, *pats, **opts)
1631 # ret can be 0 (no changes to record) or the value returned by
1633 # ret can be 0 (no changes to record) or the value returned by
1632 # commit(), 1 if nothing changed or None on success.
1634 # commit(), 1 if nothing changed or None on success.
1633 return 1 if ret == 0 else ret
1635 return 1 if ret == 0 else ret
1634
1636
1635 if opts.get('subrepos'):
1637 if opts.get('subrepos'):
1636 if opts.get('amend'):
1638 if opts.get('amend'):
1637 raise error.Abort(_('cannot amend with --subrepos'))
1639 raise error.Abort(_('cannot amend with --subrepos'))
1638 # Let --subrepos on the command line override config setting.
1640 # Let --subrepos on the command line override config setting.
1639 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1641 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1640
1642
1641 cmdutil.checkunfinished(repo, commit=True)
1643 cmdutil.checkunfinished(repo, commit=True)
1642
1644
1643 branch = repo[None].branch()
1645 branch = repo[None].branch()
1644 bheads = repo.branchheads(branch)
1646 bheads = repo.branchheads(branch)
1645
1647
1646 extra = {}
1648 extra = {}
1647 if opts.get('close_branch'):
1649 if opts.get('close_branch'):
1648 extra['close'] = 1
1650 extra['close'] = 1
1649
1651
1650 if not bheads:
1652 if not bheads:
1651 raise error.Abort(_('can only close branch heads'))
1653 raise error.Abort(_('can only close branch heads'))
1652 elif opts.get('amend'):
1654 elif opts.get('amend'):
1653 if repo[None].parents()[0].p1().branch() != branch and \
1655 if repo[None].parents()[0].p1().branch() != branch and \
1654 repo[None].parents()[0].p2().branch() != branch:
1656 repo[None].parents()[0].p2().branch() != branch:
1655 raise error.Abort(_('can only close branch heads'))
1657 raise error.Abort(_('can only close branch heads'))
1656
1658
1657 if opts.get('amend'):
1659 if opts.get('amend'):
1658 if ui.configbool('ui', 'commitsubrepos'):
1660 if ui.configbool('ui', 'commitsubrepos'):
1659 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1661 raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1660
1662
1661 old = repo['.']
1663 old = repo['.']
1662 if not old.mutable():
1664 if not old.mutable():
1663 raise error.Abort(_('cannot amend public changesets'))
1665 raise error.Abort(_('cannot amend public changesets'))
1664 if len(repo[None].parents()) > 1:
1666 if len(repo[None].parents()) > 1:
1665 raise error.Abort(_('cannot amend while merging'))
1667 raise error.Abort(_('cannot amend while merging'))
1666 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1668 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1667 if not allowunstable and old.children():
1669 if not allowunstable and old.children():
1668 raise error.Abort(_('cannot amend changeset with children'))
1670 raise error.Abort(_('cannot amend changeset with children'))
1669
1671
1670 # Currently histedit gets confused if an amend happens while histedit
1672 # Currently histedit gets confused if an amend happens while histedit
1671 # is in progress. Since we have a checkunfinished command, we are
1673 # is in progress. Since we have a checkunfinished command, we are
1672 # temporarily honoring it.
1674 # temporarily honoring it.
1673 #
1675 #
1674 # Note: eventually this guard will be removed. Please do not expect
1676 # Note: eventually this guard will be removed. Please do not expect
1675 # this behavior to remain.
1677 # this behavior to remain.
1676 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1678 if not obsolete.isenabled(repo, obsolete.createmarkersopt):
1677 cmdutil.checkunfinished(repo)
1679 cmdutil.checkunfinished(repo)
1678
1680
1679 # commitfunc is used only for temporary amend commit by cmdutil.amend
1681 # commitfunc is used only for temporary amend commit by cmdutil.amend
1680 def commitfunc(ui, repo, message, match, opts):
1682 def commitfunc(ui, repo, message, match, opts):
1681 return repo.commit(message,
1683 return repo.commit(message,
1682 opts.get('user') or old.user(),
1684 opts.get('user') or old.user(),
1683 opts.get('date') or old.date(),
1685 opts.get('date') or old.date(),
1684 match,
1686 match,
1685 extra=extra)
1687 extra=extra)
1686
1688
1687 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1689 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1688 if node == old.node():
1690 if node == old.node():
1689 ui.status(_("nothing changed\n"))
1691 ui.status(_("nothing changed\n"))
1690 return 1
1692 return 1
1691 else:
1693 else:
1692 def commitfunc(ui, repo, message, match, opts):
1694 def commitfunc(ui, repo, message, match, opts):
1693 backup = ui.backupconfig('phases', 'new-commit')
1695 backup = ui.backupconfig('phases', 'new-commit')
1694 baseui = repo.baseui
1696 baseui = repo.baseui
1695 basebackup = baseui.backupconfig('phases', 'new-commit')
1697 basebackup = baseui.backupconfig('phases', 'new-commit')
1696 try:
1698 try:
1697 if opts.get('secret'):
1699 if opts.get('secret'):
1698 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1700 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1699 # Propagate to subrepos
1701 # Propagate to subrepos
1700 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1702 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1701
1703
1702 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1704 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1703 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1705 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1704 return repo.commit(message, opts.get('user'), opts.get('date'),
1706 return repo.commit(message, opts.get('user'), opts.get('date'),
1705 match,
1707 match,
1706 editor=editor,
1708 editor=editor,
1707 extra=extra)
1709 extra=extra)
1708 finally:
1710 finally:
1709 ui.restoreconfig(backup)
1711 ui.restoreconfig(backup)
1710 repo.baseui.restoreconfig(basebackup)
1712 repo.baseui.restoreconfig(basebackup)
1711
1713
1712
1714
1713 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1715 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1714
1716
1715 if not node:
1717 if not node:
1716 stat = cmdutil.postcommitstatus(repo, pats, opts)
1718 stat = cmdutil.postcommitstatus(repo, pats, opts)
1717 if stat[3]:
1719 if stat[3]:
1718 ui.status(_("nothing changed (%d missing files, see "
1720 ui.status(_("nothing changed (%d missing files, see "
1719 "'hg status')\n") % len(stat[3]))
1721 "'hg status')\n") % len(stat[3]))
1720 else:
1722 else:
1721 ui.status(_("nothing changed\n"))
1723 ui.status(_("nothing changed\n"))
1722 return 1
1724 return 1
1723
1725
1724 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1726 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1725
1727
1726 @command('config|showconfig|debugconfig',
1728 @command('config|showconfig|debugconfig',
1727 [('u', 'untrusted', None, _('show untrusted configuration options')),
1729 [('u', 'untrusted', None, _('show untrusted configuration options')),
1728 ('e', 'edit', None, _('edit user config')),
1730 ('e', 'edit', None, _('edit user config')),
1729 ('l', 'local', None, _('edit repository config')),
1731 ('l', 'local', None, _('edit repository config')),
1730 ('g', 'global', None, _('edit global config'))] + formatteropts,
1732 ('g', 'global', None, _('edit global config'))] + formatteropts,
1731 _('[-u] [NAME]...'),
1733 _('[-u] [NAME]...'),
1732 optionalrepo=True)
1734 optionalrepo=True)
1733 def config(ui, repo, *values, **opts):
1735 def config(ui, repo, *values, **opts):
1734 """show combined config settings from all hgrc files
1736 """show combined config settings from all hgrc files
1735
1737
1736 With no arguments, print names and values of all config items.
1738 With no arguments, print names and values of all config items.
1737
1739
1738 With one argument of the form section.name, print just the value
1740 With one argument of the form section.name, print just the value
1739 of that config item.
1741 of that config item.
1740
1742
1741 With multiple arguments, print names and values of all config
1743 With multiple arguments, print names and values of all config
1742 items with matching section names.
1744 items with matching section names.
1743
1745
1744 With --edit, start an editor on the user-level config file. With
1746 With --edit, start an editor on the user-level config file. With
1745 --global, edit the system-wide config file. With --local, edit the
1747 --global, edit the system-wide config file. With --local, edit the
1746 repository-level config file.
1748 repository-level config file.
1747
1749
1748 With --debug, the source (filename and line number) is printed
1750 With --debug, the source (filename and line number) is printed
1749 for each config item.
1751 for each config item.
1750
1752
1751 See :hg:`help config` for more information about config files.
1753 See :hg:`help config` for more information about config files.
1752
1754
1753 Returns 0 on success, 1 if NAME does not exist.
1755 Returns 0 on success, 1 if NAME does not exist.
1754
1756
1755 """
1757 """
1756
1758
1757 if opts.get('edit') or opts.get('local') or opts.get('global'):
1759 if opts.get('edit') or opts.get('local') or opts.get('global'):
1758 if opts.get('local') and opts.get('global'):
1760 if opts.get('local') and opts.get('global'):
1759 raise error.Abort(_("can't use --local and --global together"))
1761 raise error.Abort(_("can't use --local and --global together"))
1760
1762
1761 if opts.get('local'):
1763 if opts.get('local'):
1762 if not repo:
1764 if not repo:
1763 raise error.Abort(_("can't use --local outside a repository"))
1765 raise error.Abort(_("can't use --local outside a repository"))
1764 paths = [repo.join('hgrc')]
1766 paths = [repo.join('hgrc')]
1765 elif opts.get('global'):
1767 elif opts.get('global'):
1766 paths = scmutil.systemrcpath()
1768 paths = scmutil.systemrcpath()
1767 else:
1769 else:
1768 paths = scmutil.userrcpath()
1770 paths = scmutil.userrcpath()
1769
1771
1770 for f in paths:
1772 for f in paths:
1771 if os.path.exists(f):
1773 if os.path.exists(f):
1772 break
1774 break
1773 else:
1775 else:
1774 if opts.get('global'):
1776 if opts.get('global'):
1775 samplehgrc = uimod.samplehgrcs['global']
1777 samplehgrc = uimod.samplehgrcs['global']
1776 elif opts.get('local'):
1778 elif opts.get('local'):
1777 samplehgrc = uimod.samplehgrcs['local']
1779 samplehgrc = uimod.samplehgrcs['local']
1778 else:
1780 else:
1779 samplehgrc = uimod.samplehgrcs['user']
1781 samplehgrc = uimod.samplehgrcs['user']
1780
1782
1781 f = paths[0]
1783 f = paths[0]
1782 fp = open(f, "w")
1784 fp = open(f, "w")
1783 fp.write(samplehgrc)
1785 fp.write(samplehgrc)
1784 fp.close()
1786 fp.close()
1785
1787
1786 editor = ui.geteditor()
1788 editor = ui.geteditor()
1787 ui.system("%s \"%s\"" % (editor, f),
1789 ui.system("%s \"%s\"" % (editor, f),
1788 onerr=error.Abort, errprefix=_("edit failed"))
1790 onerr=error.Abort, errprefix=_("edit failed"))
1789 return
1791 return
1790
1792
1791 fm = ui.formatter('config', opts)
1793 fm = ui.formatter('config', opts)
1792 for f in scmutil.rcpath():
1794 for f in scmutil.rcpath():
1793 ui.debug('read config from: %s\n' % f)
1795 ui.debug('read config from: %s\n' % f)
1794 untrusted = bool(opts.get('untrusted'))
1796 untrusted = bool(opts.get('untrusted'))
1795 if values:
1797 if values:
1796 sections = [v for v in values if '.' not in v]
1798 sections = [v for v in values if '.' not in v]
1797 items = [v for v in values if '.' in v]
1799 items = [v for v in values if '.' in v]
1798 if len(items) > 1 or items and sections:
1800 if len(items) > 1 or items and sections:
1799 raise error.Abort(_('only one config item permitted'))
1801 raise error.Abort(_('only one config item permitted'))
1800 matched = False
1802 matched = False
1801 for section, name, value in ui.walkconfig(untrusted=untrusted):
1803 for section, name, value in ui.walkconfig(untrusted=untrusted):
1802 source = ui.configsource(section, name, untrusted)
1804 source = ui.configsource(section, name, untrusted)
1803 value = str(value)
1805 value = str(value)
1804 if fm.isplain():
1806 if fm.isplain():
1805 source = source or 'none'
1807 source = source or 'none'
1806 value = value.replace('\n', '\\n')
1808 value = value.replace('\n', '\\n')
1807 entryname = section + '.' + name
1809 entryname = section + '.' + name
1808 if values:
1810 if values:
1809 for v in values:
1811 for v in values:
1810 if v == section:
1812 if v == section:
1811 fm.startitem()
1813 fm.startitem()
1812 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1814 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1813 fm.write('name value', '%s=%s\n', entryname, value)
1815 fm.write('name value', '%s=%s\n', entryname, value)
1814 matched = True
1816 matched = True
1815 elif v == entryname:
1817 elif v == entryname:
1816 fm.startitem()
1818 fm.startitem()
1817 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1819 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1818 fm.write('value', '%s\n', value)
1820 fm.write('value', '%s\n', value)
1819 fm.data(name=entryname)
1821 fm.data(name=entryname)
1820 matched = True
1822 matched = True
1821 else:
1823 else:
1822 fm.startitem()
1824 fm.startitem()
1823 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1825 fm.condwrite(ui.debugflag, 'source', '%s: ', source)
1824 fm.write('name value', '%s=%s\n', entryname, value)
1826 fm.write('name value', '%s=%s\n', entryname, value)
1825 matched = True
1827 matched = True
1826 fm.end()
1828 fm.end()
1827 if matched:
1829 if matched:
1828 return 0
1830 return 0
1829 return 1
1831 return 1
1830
1832
1831 @command('copy|cp',
1833 @command('copy|cp',
1832 [('A', 'after', None, _('record a copy that has already occurred')),
1834 [('A', 'after', None, _('record a copy that has already occurred')),
1833 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1835 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1834 ] + walkopts + dryrunopts,
1836 ] + walkopts + dryrunopts,
1835 _('[OPTION]... [SOURCE]... DEST'))
1837 _('[OPTION]... [SOURCE]... DEST'))
1836 def copy(ui, repo, *pats, **opts):
1838 def copy(ui, repo, *pats, **opts):
1837 """mark files as copied for the next commit
1839 """mark files as copied for the next commit
1838
1840
1839 Mark dest as having copies of source files. If dest is a
1841 Mark dest as having copies of source files. If dest is a
1840 directory, copies are put in that directory. If dest is a file,
1842 directory, copies are put in that directory. If dest is a file,
1841 the source must be a single file.
1843 the source must be a single file.
1842
1844
1843 By default, this command copies the contents of files as they
1845 By default, this command copies the contents of files as they
1844 exist in the working directory. If invoked with -A/--after, the
1846 exist in the working directory. If invoked with -A/--after, the
1845 operation is recorded, but no copying is performed.
1847 operation is recorded, but no copying is performed.
1846
1848
1847 This command takes effect with the next commit. To undo a copy
1849 This command takes effect with the next commit. To undo a copy
1848 before that, see :hg:`revert`.
1850 before that, see :hg:`revert`.
1849
1851
1850 Returns 0 on success, 1 if errors are encountered.
1852 Returns 0 on success, 1 if errors are encountered.
1851 """
1853 """
1852 with repo.wlock(False):
1854 with repo.wlock(False):
1853 return cmdutil.copy(ui, repo, pats, opts)
1855 return cmdutil.copy(ui, repo, pats, opts)
1854
1856
1855 @command('^diff',
1857 @command('^diff',
1856 [('r', 'rev', [], _('revision'), _('REV')),
1858 [('r', 'rev', [], _('revision'), _('REV')),
1857 ('c', 'change', '', _('change made by revision'), _('REV'))
1859 ('c', 'change', '', _('change made by revision'), _('REV'))
1858 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1860 ] + diffopts + diffopts2 + walkopts + subrepoopts,
1859 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1861 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
1860 inferrepo=True)
1862 inferrepo=True)
1861 def diff(ui, repo, *pats, **opts):
1863 def diff(ui, repo, *pats, **opts):
1862 """diff repository (or selected files)
1864 """diff repository (or selected files)
1863
1865
1864 Show differences between revisions for the specified files.
1866 Show differences between revisions for the specified files.
1865
1867
1866 Differences between files are shown using the unified diff format.
1868 Differences between files are shown using the unified diff format.
1867
1869
1868 .. note::
1870 .. note::
1869
1871
1870 :hg:`diff` may generate unexpected results for merges, as it will
1872 :hg:`diff` may generate unexpected results for merges, as it will
1871 default to comparing against the working directory's first
1873 default to comparing against the working directory's first
1872 parent changeset if no revisions are specified.
1874 parent changeset if no revisions are specified.
1873
1875
1874 When two revision arguments are given, then changes are shown
1876 When two revision arguments are given, then changes are shown
1875 between those revisions. If only one revision is specified then
1877 between those revisions. If only one revision is specified then
1876 that revision is compared to the working directory, and, when no
1878 that revision is compared to the working directory, and, when no
1877 revisions are specified, the working directory files are compared
1879 revisions are specified, the working directory files are compared
1878 to its first parent.
1880 to its first parent.
1879
1881
1880 Alternatively you can specify -c/--change with a revision to see
1882 Alternatively you can specify -c/--change with a revision to see
1881 the changes in that changeset relative to its first parent.
1883 the changes in that changeset relative to its first parent.
1882
1884
1883 Without the -a/--text option, diff will avoid generating diffs of
1885 Without the -a/--text option, diff will avoid generating diffs of
1884 files it detects as binary. With -a, diff will generate a diff
1886 files it detects as binary. With -a, diff will generate a diff
1885 anyway, probably with undesirable results.
1887 anyway, probably with undesirable results.
1886
1888
1887 Use the -g/--git option to generate diffs in the git extended diff
1889 Use the -g/--git option to generate diffs in the git extended diff
1888 format. For more information, read :hg:`help diffs`.
1890 format. For more information, read :hg:`help diffs`.
1889
1891
1890 .. container:: verbose
1892 .. container:: verbose
1891
1893
1892 Examples:
1894 Examples:
1893
1895
1894 - compare a file in the current working directory to its parent::
1896 - compare a file in the current working directory to its parent::
1895
1897
1896 hg diff foo.c
1898 hg diff foo.c
1897
1899
1898 - compare two historical versions of a directory, with rename info::
1900 - compare two historical versions of a directory, with rename info::
1899
1901
1900 hg diff --git -r 1.0:1.2 lib/
1902 hg diff --git -r 1.0:1.2 lib/
1901
1903
1902 - get change stats relative to the last change on some date::
1904 - get change stats relative to the last change on some date::
1903
1905
1904 hg diff --stat -r "date('may 2')"
1906 hg diff --stat -r "date('may 2')"
1905
1907
1906 - diff all newly-added files that contain a keyword::
1908 - diff all newly-added files that contain a keyword::
1907
1909
1908 hg diff "set:added() and grep(GNU)"
1910 hg diff "set:added() and grep(GNU)"
1909
1911
1910 - compare a revision and its parents::
1912 - compare a revision and its parents::
1911
1913
1912 hg diff -c 9353 # compare against first parent
1914 hg diff -c 9353 # compare against first parent
1913 hg diff -r 9353^:9353 # same using revset syntax
1915 hg diff -r 9353^:9353 # same using revset syntax
1914 hg diff -r 9353^2:9353 # compare against the second parent
1916 hg diff -r 9353^2:9353 # compare against the second parent
1915
1917
1916 Returns 0 on success.
1918 Returns 0 on success.
1917 """
1919 """
1918
1920
1919 revs = opts.get('rev')
1921 revs = opts.get('rev')
1920 change = opts.get('change')
1922 change = opts.get('change')
1921 stat = opts.get('stat')
1923 stat = opts.get('stat')
1922 reverse = opts.get('reverse')
1924 reverse = opts.get('reverse')
1923
1925
1924 if revs and change:
1926 if revs and change:
1925 msg = _('cannot specify --rev and --change at the same time')
1927 msg = _('cannot specify --rev and --change at the same time')
1926 raise error.Abort(msg)
1928 raise error.Abort(msg)
1927 elif change:
1929 elif change:
1928 node2 = scmutil.revsingle(repo, change, None).node()
1930 node2 = scmutil.revsingle(repo, change, None).node()
1929 node1 = repo[node2].p1().node()
1931 node1 = repo[node2].p1().node()
1930 else:
1932 else:
1931 node1, node2 = scmutil.revpair(repo, revs)
1933 node1, node2 = scmutil.revpair(repo, revs)
1932
1934
1933 if reverse:
1935 if reverse:
1934 node1, node2 = node2, node1
1936 node1, node2 = node2, node1
1935
1937
1936 diffopts = patch.diffallopts(ui, opts)
1938 diffopts = patch.diffallopts(ui, opts)
1937 m = scmutil.match(repo[node2], pats, opts)
1939 m = scmutil.match(repo[node2], pats, opts)
1938 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1940 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1939 listsubrepos=opts.get('subrepos'),
1941 listsubrepos=opts.get('subrepos'),
1940 root=opts.get('root'))
1942 root=opts.get('root'))
1941
1943
1942 @command('^export',
1944 @command('^export',
1943 [('o', 'output', '',
1945 [('o', 'output', '',
1944 _('print output to file with formatted name'), _('FORMAT')),
1946 _('print output to file with formatted name'), _('FORMAT')),
1945 ('', 'switch-parent', None, _('diff against the second parent')),
1947 ('', 'switch-parent', None, _('diff against the second parent')),
1946 ('r', 'rev', [], _('revisions to export'), _('REV')),
1948 ('r', 'rev', [], _('revisions to export'), _('REV')),
1947 ] + diffopts,
1949 ] + diffopts,
1948 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
1950 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
1949 def export(ui, repo, *changesets, **opts):
1951 def export(ui, repo, *changesets, **opts):
1950 """dump the header and diffs for one or more changesets
1952 """dump the header and diffs for one or more changesets
1951
1953
1952 Print the changeset header and diffs for one or more revisions.
1954 Print the changeset header and diffs for one or more revisions.
1953 If no revision is given, the parent of the working directory is used.
1955 If no revision is given, the parent of the working directory is used.
1954
1956
1955 The information shown in the changeset header is: author, date,
1957 The information shown in the changeset header is: author, date,
1956 branch name (if non-default), changeset hash, parent(s) and commit
1958 branch name (if non-default), changeset hash, parent(s) and commit
1957 comment.
1959 comment.
1958
1960
1959 .. note::
1961 .. note::
1960
1962
1961 :hg:`export` may generate unexpected diff output for merge
1963 :hg:`export` may generate unexpected diff output for merge
1962 changesets, as it will compare the merge changeset against its
1964 changesets, as it will compare the merge changeset against its
1963 first parent only.
1965 first parent only.
1964
1966
1965 Output may be to a file, in which case the name of the file is
1967 Output may be to a file, in which case the name of the file is
1966 given using a format string. The formatting rules are as follows:
1968 given using a format string. The formatting rules are as follows:
1967
1969
1968 :``%%``: literal "%" character
1970 :``%%``: literal "%" character
1969 :``%H``: changeset hash (40 hexadecimal digits)
1971 :``%H``: changeset hash (40 hexadecimal digits)
1970 :``%N``: number of patches being generated
1972 :``%N``: number of patches being generated
1971 :``%R``: changeset revision number
1973 :``%R``: changeset revision number
1972 :``%b``: basename of the exporting repository
1974 :``%b``: basename of the exporting repository
1973 :``%h``: short-form changeset hash (12 hexadecimal digits)
1975 :``%h``: short-form changeset hash (12 hexadecimal digits)
1974 :``%m``: first line of the commit message (only alphanumeric characters)
1976 :``%m``: first line of the commit message (only alphanumeric characters)
1975 :``%n``: zero-padded sequence number, starting at 1
1977 :``%n``: zero-padded sequence number, starting at 1
1976 :``%r``: zero-padded changeset revision number
1978 :``%r``: zero-padded changeset revision number
1977
1979
1978 Without the -a/--text option, export will avoid generating diffs
1980 Without the -a/--text option, export will avoid generating diffs
1979 of files it detects as binary. With -a, export will generate a
1981 of files it detects as binary. With -a, export will generate a
1980 diff anyway, probably with undesirable results.
1982 diff anyway, probably with undesirable results.
1981
1983
1982 Use the -g/--git option to generate diffs in the git extended diff
1984 Use the -g/--git option to generate diffs in the git extended diff
1983 format. See :hg:`help diffs` for more information.
1985 format. See :hg:`help diffs` for more information.
1984
1986
1985 With the --switch-parent option, the diff will be against the
1987 With the --switch-parent option, the diff will be against the
1986 second parent. It can be useful to review a merge.
1988 second parent. It can be useful to review a merge.
1987
1989
1988 .. container:: verbose
1990 .. container:: verbose
1989
1991
1990 Examples:
1992 Examples:
1991
1993
1992 - use export and import to transplant a bugfix to the current
1994 - use export and import to transplant a bugfix to the current
1993 branch::
1995 branch::
1994
1996
1995 hg export -r 9353 | hg import -
1997 hg export -r 9353 | hg import -
1996
1998
1997 - export all the changesets between two revisions to a file with
1999 - export all the changesets between two revisions to a file with
1998 rename information::
2000 rename information::
1999
2001
2000 hg export --git -r 123:150 > changes.txt
2002 hg export --git -r 123:150 > changes.txt
2001
2003
2002 - split outgoing changes into a series of patches with
2004 - split outgoing changes into a series of patches with
2003 descriptive names::
2005 descriptive names::
2004
2006
2005 hg export -r "outgoing()" -o "%n-%m.patch"
2007 hg export -r "outgoing()" -o "%n-%m.patch"
2006
2008
2007 Returns 0 on success.
2009 Returns 0 on success.
2008 """
2010 """
2009 changesets += tuple(opts.get('rev', []))
2011 changesets += tuple(opts.get('rev', []))
2010 if not changesets:
2012 if not changesets:
2011 changesets = ['.']
2013 changesets = ['.']
2012 revs = scmutil.revrange(repo, changesets)
2014 revs = scmutil.revrange(repo, changesets)
2013 if not revs:
2015 if not revs:
2014 raise error.Abort(_("export requires at least one changeset"))
2016 raise error.Abort(_("export requires at least one changeset"))
2015 if len(revs) > 1:
2017 if len(revs) > 1:
2016 ui.note(_('exporting patches:\n'))
2018 ui.note(_('exporting patches:\n'))
2017 else:
2019 else:
2018 ui.note(_('exporting patch:\n'))
2020 ui.note(_('exporting patch:\n'))
2019 cmdutil.export(repo, revs, template=opts.get('output'),
2021 cmdutil.export(repo, revs, template=opts.get('output'),
2020 switch_parent=opts.get('switch_parent'),
2022 switch_parent=opts.get('switch_parent'),
2021 opts=patch.diffallopts(ui, opts))
2023 opts=patch.diffallopts(ui, opts))
2022
2024
2023 @command('files',
2025 @command('files',
2024 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2026 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
2025 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2027 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
2026 ] + walkopts + formatteropts + subrepoopts,
2028 ] + walkopts + formatteropts + subrepoopts,
2027 _('[OPTION]... [FILE]...'))
2029 _('[OPTION]... [FILE]...'))
2028 def files(ui, repo, *pats, **opts):
2030 def files(ui, repo, *pats, **opts):
2029 """list tracked files
2031 """list tracked files
2030
2032
2031 Print files under Mercurial control in the working directory or
2033 Print files under Mercurial control in the working directory or
2032 specified revision for given files (excluding removed files).
2034 specified revision for given files (excluding removed files).
2033 Files can be specified as filenames or filesets.
2035 Files can be specified as filenames or filesets.
2034
2036
2035 If no files are given to match, this command prints the names
2037 If no files are given to match, this command prints the names
2036 of all files under Mercurial control.
2038 of all files under Mercurial control.
2037
2039
2038 .. container:: verbose
2040 .. container:: verbose
2039
2041
2040 Examples:
2042 Examples:
2041
2043
2042 - list all files under the current directory::
2044 - list all files under the current directory::
2043
2045
2044 hg files .
2046 hg files .
2045
2047
2046 - shows sizes and flags for current revision::
2048 - shows sizes and flags for current revision::
2047
2049
2048 hg files -vr .
2050 hg files -vr .
2049
2051
2050 - list all files named README::
2052 - list all files named README::
2051
2053
2052 hg files -I "**/README"
2054 hg files -I "**/README"
2053
2055
2054 - list all binary files::
2056 - list all binary files::
2055
2057
2056 hg files "set:binary()"
2058 hg files "set:binary()"
2057
2059
2058 - find files containing a regular expression::
2060 - find files containing a regular expression::
2059
2061
2060 hg files "set:grep('bob')"
2062 hg files "set:grep('bob')"
2061
2063
2062 - search tracked file contents with xargs and grep::
2064 - search tracked file contents with xargs and grep::
2063
2065
2064 hg files -0 | xargs -0 grep foo
2066 hg files -0 | xargs -0 grep foo
2065
2067
2066 See :hg:`help patterns` and :hg:`help filesets` for more information
2068 See :hg:`help patterns` and :hg:`help filesets` for more information
2067 on specifying file patterns.
2069 on specifying file patterns.
2068
2070
2069 Returns 0 if a match is found, 1 otherwise.
2071 Returns 0 if a match is found, 1 otherwise.
2070
2072
2071 """
2073 """
2072 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2074 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2073
2075
2074 end = '\n'
2076 end = '\n'
2075 if opts.get('print0'):
2077 if opts.get('print0'):
2076 end = '\0'
2078 end = '\0'
2077 fmt = '%s' + end
2079 fmt = '%s' + end
2078
2080
2079 m = scmutil.match(ctx, pats, opts)
2081 m = scmutil.match(ctx, pats, opts)
2080 with ui.formatter('files', opts) as fm:
2082 with ui.formatter('files', opts) as fm:
2081 return cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
2083 return cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
2082
2084
2083 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
2085 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
2084 def forget(ui, repo, *pats, **opts):
2086 def forget(ui, repo, *pats, **opts):
2085 """forget the specified files on the next commit
2087 """forget the specified files on the next commit
2086
2088
2087 Mark the specified files so they will no longer be tracked
2089 Mark the specified files so they will no longer be tracked
2088 after the next commit.
2090 after the next commit.
2089
2091
2090 This only removes files from the current branch, not from the
2092 This only removes files from the current branch, not from the
2091 entire project history, and it does not delete them from the
2093 entire project history, and it does not delete them from the
2092 working directory.
2094 working directory.
2093
2095
2094 To delete the file from the working directory, see :hg:`remove`.
2096 To delete the file from the working directory, see :hg:`remove`.
2095
2097
2096 To undo a forget before the next commit, see :hg:`add`.
2098 To undo a forget before the next commit, see :hg:`add`.
2097
2099
2098 .. container:: verbose
2100 .. container:: verbose
2099
2101
2100 Examples:
2102 Examples:
2101
2103
2102 - forget newly-added binary files::
2104 - forget newly-added binary files::
2103
2105
2104 hg forget "set:added() and binary()"
2106 hg forget "set:added() and binary()"
2105
2107
2106 - forget files that would be excluded by .hgignore::
2108 - forget files that would be excluded by .hgignore::
2107
2109
2108 hg forget "set:hgignore()"
2110 hg forget "set:hgignore()"
2109
2111
2110 Returns 0 on success.
2112 Returns 0 on success.
2111 """
2113 """
2112
2114
2113 if not pats:
2115 if not pats:
2114 raise error.Abort(_('no files specified'))
2116 raise error.Abort(_('no files specified'))
2115
2117
2116 m = scmutil.match(repo[None], pats, opts)
2118 m = scmutil.match(repo[None], pats, opts)
2117 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
2119 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
2118 return rejected and 1 or 0
2120 return rejected and 1 or 0
2119
2121
2120 @command(
2122 @command(
2121 'graft',
2123 'graft',
2122 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2124 [('r', 'rev', [], _('revisions to graft'), _('REV')),
2123 ('c', 'continue', False, _('resume interrupted graft')),
2125 ('c', 'continue', False, _('resume interrupted graft')),
2124 ('e', 'edit', False, _('invoke editor on commit messages')),
2126 ('e', 'edit', False, _('invoke editor on commit messages')),
2125 ('', 'log', None, _('append graft info to log message')),
2127 ('', 'log', None, _('append graft info to log message')),
2126 ('f', 'force', False, _('force graft')),
2128 ('f', 'force', False, _('force graft')),
2127 ('D', 'currentdate', False,
2129 ('D', 'currentdate', False,
2128 _('record the current date as commit date')),
2130 _('record the current date as commit date')),
2129 ('U', 'currentuser', False,
2131 ('U', 'currentuser', False,
2130 _('record the current user as committer'), _('DATE'))]
2132 _('record the current user as committer'), _('DATE'))]
2131 + commitopts2 + mergetoolopts + dryrunopts,
2133 + commitopts2 + mergetoolopts + dryrunopts,
2132 _('[OPTION]... [-r REV]... REV...'))
2134 _('[OPTION]... [-r REV]... REV...'))
2133 def graft(ui, repo, *revs, **opts):
2135 def graft(ui, repo, *revs, **opts):
2134 '''copy changes from other branches onto the current branch
2136 '''copy changes from other branches onto the current branch
2135
2137
2136 This command uses Mercurial's merge logic to copy individual
2138 This command uses Mercurial's merge logic to copy individual
2137 changes from other branches without merging branches in the
2139 changes from other branches without merging branches in the
2138 history graph. This is sometimes known as 'backporting' or
2140 history graph. This is sometimes known as 'backporting' or
2139 'cherry-picking'. By default, graft will copy user, date, and
2141 'cherry-picking'. By default, graft will copy user, date, and
2140 description from the source changesets.
2142 description from the source changesets.
2141
2143
2142 Changesets that are ancestors of the current revision, that have
2144 Changesets that are ancestors of the current revision, that have
2143 already been grafted, or that are merges will be skipped.
2145 already been grafted, or that are merges will be skipped.
2144
2146
2145 If --log is specified, log messages will have a comment appended
2147 If --log is specified, log messages will have a comment appended
2146 of the form::
2148 of the form::
2147
2149
2148 (grafted from CHANGESETHASH)
2150 (grafted from CHANGESETHASH)
2149
2151
2150 If --force is specified, revisions will be grafted even if they
2152 If --force is specified, revisions will be grafted even if they
2151 are already ancestors of or have been grafted to the destination.
2153 are already ancestors of or have been grafted to the destination.
2152 This is useful when the revisions have since been backed out.
2154 This is useful when the revisions have since been backed out.
2153
2155
2154 If a graft merge results in conflicts, the graft process is
2156 If a graft merge results in conflicts, the graft process is
2155 interrupted so that the current merge can be manually resolved.
2157 interrupted so that the current merge can be manually resolved.
2156 Once all conflicts are addressed, the graft process can be
2158 Once all conflicts are addressed, the graft process can be
2157 continued with the -c/--continue option.
2159 continued with the -c/--continue option.
2158
2160
2159 .. note::
2161 .. note::
2160
2162
2161 The -c/--continue option does not reapply earlier options, except
2163 The -c/--continue option does not reapply earlier options, except
2162 for --force.
2164 for --force.
2163
2165
2164 .. container:: verbose
2166 .. container:: verbose
2165
2167
2166 Examples:
2168 Examples:
2167
2169
2168 - copy a single change to the stable branch and edit its description::
2170 - copy a single change to the stable branch and edit its description::
2169
2171
2170 hg update stable
2172 hg update stable
2171 hg graft --edit 9393
2173 hg graft --edit 9393
2172
2174
2173 - graft a range of changesets with one exception, updating dates::
2175 - graft a range of changesets with one exception, updating dates::
2174
2176
2175 hg graft -D "2085::2093 and not 2091"
2177 hg graft -D "2085::2093 and not 2091"
2176
2178
2177 - continue a graft after resolving conflicts::
2179 - continue a graft after resolving conflicts::
2178
2180
2179 hg graft -c
2181 hg graft -c
2180
2182
2181 - show the source of a grafted changeset::
2183 - show the source of a grafted changeset::
2182
2184
2183 hg log --debug -r .
2185 hg log --debug -r .
2184
2186
2185 - show revisions sorted by date::
2187 - show revisions sorted by date::
2186
2188
2187 hg log -r "sort(all(), date)"
2189 hg log -r "sort(all(), date)"
2188
2190
2189 See :hg:`help revisions` for more about specifying revisions.
2191 See :hg:`help revisions` for more about specifying revisions.
2190
2192
2191 Returns 0 on successful completion.
2193 Returns 0 on successful completion.
2192 '''
2194 '''
2193 with repo.wlock():
2195 with repo.wlock():
2194 return _dograft(ui, repo, *revs, **opts)
2196 return _dograft(ui, repo, *revs, **opts)
2195
2197
2196 def _dograft(ui, repo, *revs, **opts):
2198 def _dograft(ui, repo, *revs, **opts):
2197 if revs and opts.get('rev'):
2199 if revs and opts.get('rev'):
2198 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2200 ui.warn(_('warning: inconsistent use of --rev might give unexpected '
2199 'revision ordering!\n'))
2201 'revision ordering!\n'))
2200
2202
2201 revs = list(revs)
2203 revs = list(revs)
2202 revs.extend(opts.get('rev'))
2204 revs.extend(opts.get('rev'))
2203
2205
2204 if not opts.get('user') and opts.get('currentuser'):
2206 if not opts.get('user') and opts.get('currentuser'):
2205 opts['user'] = ui.username()
2207 opts['user'] = ui.username()
2206 if not opts.get('date') and opts.get('currentdate'):
2208 if not opts.get('date') and opts.get('currentdate'):
2207 opts['date'] = "%d %d" % util.makedate()
2209 opts['date'] = "%d %d" % util.makedate()
2208
2210
2209 editor = cmdutil.getcommiteditor(editform='graft', **opts)
2211 editor = cmdutil.getcommiteditor(editform='graft', **opts)
2210
2212
2211 cont = False
2213 cont = False
2212 if opts.get('continue'):
2214 if opts.get('continue'):
2213 cont = True
2215 cont = True
2214 if revs:
2216 if revs:
2215 raise error.Abort(_("can't specify --continue and revisions"))
2217 raise error.Abort(_("can't specify --continue and revisions"))
2216 # read in unfinished revisions
2218 # read in unfinished revisions
2217 try:
2219 try:
2218 nodes = repo.vfs.read('graftstate').splitlines()
2220 nodes = repo.vfs.read('graftstate').splitlines()
2219 revs = [repo[node].rev() for node in nodes]
2221 revs = [repo[node].rev() for node in nodes]
2220 except IOError as inst:
2222 except IOError as inst:
2221 if inst.errno != errno.ENOENT:
2223 if inst.errno != errno.ENOENT:
2222 raise
2224 raise
2223 cmdutil.wrongtooltocontinue(repo, _('graft'))
2225 cmdutil.wrongtooltocontinue(repo, _('graft'))
2224 else:
2226 else:
2225 cmdutil.checkunfinished(repo)
2227 cmdutil.checkunfinished(repo)
2226 cmdutil.bailifchanged(repo)
2228 cmdutil.bailifchanged(repo)
2227 if not revs:
2229 if not revs:
2228 raise error.Abort(_('no revisions specified'))
2230 raise error.Abort(_('no revisions specified'))
2229 revs = scmutil.revrange(repo, revs)
2231 revs = scmutil.revrange(repo, revs)
2230
2232
2231 skipped = set()
2233 skipped = set()
2232 # check for merges
2234 # check for merges
2233 for rev in repo.revs('%ld and merge()', revs):
2235 for rev in repo.revs('%ld and merge()', revs):
2234 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
2236 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
2235 skipped.add(rev)
2237 skipped.add(rev)
2236 revs = [r for r in revs if r not in skipped]
2238 revs = [r for r in revs if r not in skipped]
2237 if not revs:
2239 if not revs:
2238 return -1
2240 return -1
2239
2241
2240 # Don't check in the --continue case, in effect retaining --force across
2242 # Don't check in the --continue case, in effect retaining --force across
2241 # --continues. That's because without --force, any revisions we decided to
2243 # --continues. That's because without --force, any revisions we decided to
2242 # skip would have been filtered out here, so they wouldn't have made their
2244 # skip would have been filtered out here, so they wouldn't have made their
2243 # way to the graftstate. With --force, any revisions we would have otherwise
2245 # way to the graftstate. With --force, any revisions we would have otherwise
2244 # skipped would not have been filtered out, and if they hadn't been applied
2246 # skipped would not have been filtered out, and if they hadn't been applied
2245 # already, they'd have been in the graftstate.
2247 # already, they'd have been in the graftstate.
2246 if not (cont or opts.get('force')):
2248 if not (cont or opts.get('force')):
2247 # check for ancestors of dest branch
2249 # check for ancestors of dest branch
2248 crev = repo['.'].rev()
2250 crev = repo['.'].rev()
2249 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2251 ancestors = repo.changelog.ancestors([crev], inclusive=True)
2250 # XXX make this lazy in the future
2252 # XXX make this lazy in the future
2251 # don't mutate while iterating, create a copy
2253 # don't mutate while iterating, create a copy
2252 for rev in list(revs):
2254 for rev in list(revs):
2253 if rev in ancestors:
2255 if rev in ancestors:
2254 ui.warn(_('skipping ancestor revision %d:%s\n') %
2256 ui.warn(_('skipping ancestor revision %d:%s\n') %
2255 (rev, repo[rev]))
2257 (rev, repo[rev]))
2256 # XXX remove on list is slow
2258 # XXX remove on list is slow
2257 revs.remove(rev)
2259 revs.remove(rev)
2258 if not revs:
2260 if not revs:
2259 return -1
2261 return -1
2260
2262
2261 # analyze revs for earlier grafts
2263 # analyze revs for earlier grafts
2262 ids = {}
2264 ids = {}
2263 for ctx in repo.set("%ld", revs):
2265 for ctx in repo.set("%ld", revs):
2264 ids[ctx.hex()] = ctx.rev()
2266 ids[ctx.hex()] = ctx.rev()
2265 n = ctx.extra().get('source')
2267 n = ctx.extra().get('source')
2266 if n:
2268 if n:
2267 ids[n] = ctx.rev()
2269 ids[n] = ctx.rev()
2268
2270
2269 # check ancestors for earlier grafts
2271 # check ancestors for earlier grafts
2270 ui.debug('scanning for duplicate grafts\n')
2272 ui.debug('scanning for duplicate grafts\n')
2271
2273
2272 for rev in repo.changelog.findmissingrevs(revs, [crev]):
2274 for rev in repo.changelog.findmissingrevs(revs, [crev]):
2273 ctx = repo[rev]
2275 ctx = repo[rev]
2274 n = ctx.extra().get('source')
2276 n = ctx.extra().get('source')
2275 if n in ids:
2277 if n in ids:
2276 try:
2278 try:
2277 r = repo[n].rev()
2279 r = repo[n].rev()
2278 except error.RepoLookupError:
2280 except error.RepoLookupError:
2279 r = None
2281 r = None
2280 if r in revs:
2282 if r in revs:
2281 ui.warn(_('skipping revision %d:%s '
2283 ui.warn(_('skipping revision %d:%s '
2282 '(already grafted to %d:%s)\n')
2284 '(already grafted to %d:%s)\n')
2283 % (r, repo[r], rev, ctx))
2285 % (r, repo[r], rev, ctx))
2284 revs.remove(r)
2286 revs.remove(r)
2285 elif ids[n] in revs:
2287 elif ids[n] in revs:
2286 if r is None:
2288 if r is None:
2287 ui.warn(_('skipping already grafted revision %d:%s '
2289 ui.warn(_('skipping already grafted revision %d:%s '
2288 '(%d:%s also has unknown origin %s)\n')
2290 '(%d:%s also has unknown origin %s)\n')
2289 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2291 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
2290 else:
2292 else:
2291 ui.warn(_('skipping already grafted revision %d:%s '
2293 ui.warn(_('skipping already grafted revision %d:%s '
2292 '(%d:%s also has origin %d:%s)\n')
2294 '(%d:%s also has origin %d:%s)\n')
2293 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2295 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
2294 revs.remove(ids[n])
2296 revs.remove(ids[n])
2295 elif ctx.hex() in ids:
2297 elif ctx.hex() in ids:
2296 r = ids[ctx.hex()]
2298 r = ids[ctx.hex()]
2297 ui.warn(_('skipping already grafted revision %d:%s '
2299 ui.warn(_('skipping already grafted revision %d:%s '
2298 '(was grafted from %d:%s)\n') %
2300 '(was grafted from %d:%s)\n') %
2299 (r, repo[r], rev, ctx))
2301 (r, repo[r], rev, ctx))
2300 revs.remove(r)
2302 revs.remove(r)
2301 if not revs:
2303 if not revs:
2302 return -1
2304 return -1
2303
2305
2304 for pos, ctx in enumerate(repo.set("%ld", revs)):
2306 for pos, ctx in enumerate(repo.set("%ld", revs)):
2305 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2307 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
2306 ctx.description().split('\n', 1)[0])
2308 ctx.description().split('\n', 1)[0])
2307 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2309 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
2308 if names:
2310 if names:
2309 desc += ' (%s)' % ' '.join(names)
2311 desc += ' (%s)' % ' '.join(names)
2310 ui.status(_('grafting %s\n') % desc)
2312 ui.status(_('grafting %s\n') % desc)
2311 if opts.get('dry_run'):
2313 if opts.get('dry_run'):
2312 continue
2314 continue
2313
2315
2314 source = ctx.extra().get('source')
2316 source = ctx.extra().get('source')
2315 extra = {}
2317 extra = {}
2316 if source:
2318 if source:
2317 extra['source'] = source
2319 extra['source'] = source
2318 extra['intermediate-source'] = ctx.hex()
2320 extra['intermediate-source'] = ctx.hex()
2319 else:
2321 else:
2320 extra['source'] = ctx.hex()
2322 extra['source'] = ctx.hex()
2321 user = ctx.user()
2323 user = ctx.user()
2322 if opts.get('user'):
2324 if opts.get('user'):
2323 user = opts['user']
2325 user = opts['user']
2324 date = ctx.date()
2326 date = ctx.date()
2325 if opts.get('date'):
2327 if opts.get('date'):
2326 date = opts['date']
2328 date = opts['date']
2327 message = ctx.description()
2329 message = ctx.description()
2328 if opts.get('log'):
2330 if opts.get('log'):
2329 message += '\n(grafted from %s)' % ctx.hex()
2331 message += '\n(grafted from %s)' % ctx.hex()
2330
2332
2331 # we don't merge the first commit when continuing
2333 # we don't merge the first commit when continuing
2332 if not cont:
2334 if not cont:
2333 # perform the graft merge with p1(rev) as 'ancestor'
2335 # perform the graft merge with p1(rev) as 'ancestor'
2334 try:
2336 try:
2335 # ui.forcemerge is an internal variable, do not document
2337 # ui.forcemerge is an internal variable, do not document
2336 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
2338 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
2337 'graft')
2339 'graft')
2338 stats = mergemod.graft(repo, ctx, ctx.p1(),
2340 stats = mergemod.graft(repo, ctx, ctx.p1(),
2339 ['local', 'graft'])
2341 ['local', 'graft'])
2340 finally:
2342 finally:
2341 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
2343 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
2342 # report any conflicts
2344 # report any conflicts
2343 if stats and stats[3] > 0:
2345 if stats and stats[3] > 0:
2344 # write out state for --continue
2346 # write out state for --continue
2345 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
2347 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
2346 repo.vfs.write('graftstate', ''.join(nodelines))
2348 repo.vfs.write('graftstate', ''.join(nodelines))
2347 extra = ''
2349 extra = ''
2348 if opts.get('user'):
2350 if opts.get('user'):
2349 extra += ' --user %s' % util.shellquote(opts['user'])
2351 extra += ' --user %s' % util.shellquote(opts['user'])
2350 if opts.get('date'):
2352 if opts.get('date'):
2351 extra += ' --date %s' % util.shellquote(opts['date'])
2353 extra += ' --date %s' % util.shellquote(opts['date'])
2352 if opts.get('log'):
2354 if opts.get('log'):
2353 extra += ' --log'
2355 extra += ' --log'
2354 hint=_("use 'hg resolve' and 'hg graft --continue%s'") % extra
2356 hint=_("use 'hg resolve' and 'hg graft --continue%s'") % extra
2355 raise error.Abort(
2357 raise error.Abort(
2356 _("unresolved conflicts, can't continue"),
2358 _("unresolved conflicts, can't continue"),
2357 hint=hint)
2359 hint=hint)
2358 else:
2360 else:
2359 cont = False
2361 cont = False
2360
2362
2361 # commit
2363 # commit
2362 node = repo.commit(text=message, user=user,
2364 node = repo.commit(text=message, user=user,
2363 date=date, extra=extra, editor=editor)
2365 date=date, extra=extra, editor=editor)
2364 if node is None:
2366 if node is None:
2365 ui.warn(
2367 ui.warn(
2366 _('note: graft of %d:%s created no changes to commit\n') %
2368 _('note: graft of %d:%s created no changes to commit\n') %
2367 (ctx.rev(), ctx))
2369 (ctx.rev(), ctx))
2368
2370
2369 # remove state when we complete successfully
2371 # remove state when we complete successfully
2370 if not opts.get('dry_run'):
2372 if not opts.get('dry_run'):
2371 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
2373 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
2372
2374
2373 return 0
2375 return 0
2374
2376
2375 @command('grep',
2377 @command('grep',
2376 [('0', 'print0', None, _('end fields with NUL')),
2378 [('0', 'print0', None, _('end fields with NUL')),
2377 ('', 'all', None, _('print all revisions that match')),
2379 ('', 'all', None, _('print all revisions that match')),
2378 ('a', 'text', None, _('treat all files as text')),
2380 ('a', 'text', None, _('treat all files as text')),
2379 ('f', 'follow', None,
2381 ('f', 'follow', None,
2380 _('follow changeset history,'
2382 _('follow changeset history,'
2381 ' or file history across copies and renames')),
2383 ' or file history across copies and renames')),
2382 ('i', 'ignore-case', None, _('ignore case when matching')),
2384 ('i', 'ignore-case', None, _('ignore case when matching')),
2383 ('l', 'files-with-matches', None,
2385 ('l', 'files-with-matches', None,
2384 _('print only filenames and revisions that match')),
2386 _('print only filenames and revisions that match')),
2385 ('n', 'line-number', None, _('print matching line numbers')),
2387 ('n', 'line-number', None, _('print matching line numbers')),
2386 ('r', 'rev', [],
2388 ('r', 'rev', [],
2387 _('only search files changed within revision range'), _('REV')),
2389 _('only search files changed within revision range'), _('REV')),
2388 ('u', 'user', None, _('list the author (long with -v)')),
2390 ('u', 'user', None, _('list the author (long with -v)')),
2389 ('d', 'date', None, _('list the date (short with -q)')),
2391 ('d', 'date', None, _('list the date (short with -q)')),
2390 ] + formatteropts + walkopts,
2392 ] + formatteropts + walkopts,
2391 _('[OPTION]... PATTERN [FILE]...'),
2393 _('[OPTION]... PATTERN [FILE]...'),
2392 inferrepo=True)
2394 inferrepo=True)
2393 def grep(ui, repo, pattern, *pats, **opts):
2395 def grep(ui, repo, pattern, *pats, **opts):
2394 """search revision history for a pattern in specified files
2396 """search revision history for a pattern in specified files
2395
2397
2396 Search revision history for a regular expression in the specified
2398 Search revision history for a regular expression in the specified
2397 files or the entire project.
2399 files or the entire project.
2398
2400
2399 By default, grep prints the most recent revision number for each
2401 By default, grep prints the most recent revision number for each
2400 file in which it finds a match. To get it to print every revision
2402 file in which it finds a match. To get it to print every revision
2401 that contains a change in match status ("-" for a match that becomes
2403 that contains a change in match status ("-" for a match that becomes
2402 a non-match, or "+" for a non-match that becomes a match), use the
2404 a non-match, or "+" for a non-match that becomes a match), use the
2403 --all flag.
2405 --all flag.
2404
2406
2405 PATTERN can be any Python (roughly Perl-compatible) regular
2407 PATTERN can be any Python (roughly Perl-compatible) regular
2406 expression.
2408 expression.
2407
2409
2408 If no FILEs are specified (and -f/--follow isn't set), all files in
2410 If no FILEs are specified (and -f/--follow isn't set), all files in
2409 the repository are searched, including those that don't exist in the
2411 the repository are searched, including those that don't exist in the
2410 current branch or have been deleted in a prior changeset.
2412 current branch or have been deleted in a prior changeset.
2411
2413
2412 Returns 0 if a match is found, 1 otherwise.
2414 Returns 0 if a match is found, 1 otherwise.
2413 """
2415 """
2414 reflags = re.M
2416 reflags = re.M
2415 if opts.get('ignore_case'):
2417 if opts.get('ignore_case'):
2416 reflags |= re.I
2418 reflags |= re.I
2417 try:
2419 try:
2418 regexp = util.re.compile(pattern, reflags)
2420 regexp = util.re.compile(pattern, reflags)
2419 except re.error as inst:
2421 except re.error as inst:
2420 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
2422 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
2421 return 1
2423 return 1
2422 sep, eol = ':', '\n'
2424 sep, eol = ':', '\n'
2423 if opts.get('print0'):
2425 if opts.get('print0'):
2424 sep = eol = '\0'
2426 sep = eol = '\0'
2425
2427
2426 getfile = util.lrucachefunc(repo.file)
2428 getfile = util.lrucachefunc(repo.file)
2427
2429
2428 def matchlines(body):
2430 def matchlines(body):
2429 begin = 0
2431 begin = 0
2430 linenum = 0
2432 linenum = 0
2431 while begin < len(body):
2433 while begin < len(body):
2432 match = regexp.search(body, begin)
2434 match = regexp.search(body, begin)
2433 if not match:
2435 if not match:
2434 break
2436 break
2435 mstart, mend = match.span()
2437 mstart, mend = match.span()
2436 linenum += body.count('\n', begin, mstart) + 1
2438 linenum += body.count('\n', begin, mstart) + 1
2437 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2439 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2438 begin = body.find('\n', mend) + 1 or len(body) + 1
2440 begin = body.find('\n', mend) + 1 or len(body) + 1
2439 lend = begin - 1
2441 lend = begin - 1
2440 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2442 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2441
2443
2442 class linestate(object):
2444 class linestate(object):
2443 def __init__(self, line, linenum, colstart, colend):
2445 def __init__(self, line, linenum, colstart, colend):
2444 self.line = line
2446 self.line = line
2445 self.linenum = linenum
2447 self.linenum = linenum
2446 self.colstart = colstart
2448 self.colstart = colstart
2447 self.colend = colend
2449 self.colend = colend
2448
2450
2449 def __hash__(self):
2451 def __hash__(self):
2450 return hash((self.linenum, self.line))
2452 return hash((self.linenum, self.line))
2451
2453
2452 def __eq__(self, other):
2454 def __eq__(self, other):
2453 return self.line == other.line
2455 return self.line == other.line
2454
2456
2455 def findpos(self):
2457 def findpos(self):
2456 """Iterate all (start, end) indices of matches"""
2458 """Iterate all (start, end) indices of matches"""
2457 yield self.colstart, self.colend
2459 yield self.colstart, self.colend
2458 p = self.colend
2460 p = self.colend
2459 while p < len(self.line):
2461 while p < len(self.line):
2460 m = regexp.search(self.line, p)
2462 m = regexp.search(self.line, p)
2461 if not m:
2463 if not m:
2462 break
2464 break
2463 yield m.span()
2465 yield m.span()
2464 p = m.end()
2466 p = m.end()
2465
2467
2466 matches = {}
2468 matches = {}
2467 copies = {}
2469 copies = {}
2468 def grepbody(fn, rev, body):
2470 def grepbody(fn, rev, body):
2469 matches[rev].setdefault(fn, [])
2471 matches[rev].setdefault(fn, [])
2470 m = matches[rev][fn]
2472 m = matches[rev][fn]
2471 for lnum, cstart, cend, line in matchlines(body):
2473 for lnum, cstart, cend, line in matchlines(body):
2472 s = linestate(line, lnum, cstart, cend)
2474 s = linestate(line, lnum, cstart, cend)
2473 m.append(s)
2475 m.append(s)
2474
2476
2475 def difflinestates(a, b):
2477 def difflinestates(a, b):
2476 sm = difflib.SequenceMatcher(None, a, b)
2478 sm = difflib.SequenceMatcher(None, a, b)
2477 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2479 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2478 if tag == 'insert':
2480 if tag == 'insert':
2479 for i in xrange(blo, bhi):
2481 for i in xrange(blo, bhi):
2480 yield ('+', b[i])
2482 yield ('+', b[i])
2481 elif tag == 'delete':
2483 elif tag == 'delete':
2482 for i in xrange(alo, ahi):
2484 for i in xrange(alo, ahi):
2483 yield ('-', a[i])
2485 yield ('-', a[i])
2484 elif tag == 'replace':
2486 elif tag == 'replace':
2485 for i in xrange(alo, ahi):
2487 for i in xrange(alo, ahi):
2486 yield ('-', a[i])
2488 yield ('-', a[i])
2487 for i in xrange(blo, bhi):
2489 for i in xrange(blo, bhi):
2488 yield ('+', b[i])
2490 yield ('+', b[i])
2489
2491
2490 def display(fm, fn, ctx, pstates, states):
2492 def display(fm, fn, ctx, pstates, states):
2491 rev = ctx.rev()
2493 rev = ctx.rev()
2492 if fm.isplain():
2494 if fm.isplain():
2493 formatuser = ui.shortuser
2495 formatuser = ui.shortuser
2494 else:
2496 else:
2495 formatuser = str
2497 formatuser = str
2496 if ui.quiet:
2498 if ui.quiet:
2497 datefmt = '%Y-%m-%d'
2499 datefmt = '%Y-%m-%d'
2498 else:
2500 else:
2499 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2501 datefmt = '%a %b %d %H:%M:%S %Y %1%2'
2500 found = False
2502 found = False
2501 @util.cachefunc
2503 @util.cachefunc
2502 def binary():
2504 def binary():
2503 flog = getfile(fn)
2505 flog = getfile(fn)
2504 return util.binary(flog.read(ctx.filenode(fn)))
2506 return util.binary(flog.read(ctx.filenode(fn)))
2505
2507
2506 fieldnamemap = {'filename': 'file', 'linenumber': 'line_number'}
2508 fieldnamemap = {'filename': 'file', 'linenumber': 'line_number'}
2507 if opts.get('all'):
2509 if opts.get('all'):
2508 iter = difflinestates(pstates, states)
2510 iter = difflinestates(pstates, states)
2509 else:
2511 else:
2510 iter = [('', l) for l in states]
2512 iter = [('', l) for l in states]
2511 for change, l in iter:
2513 for change, l in iter:
2512 fm.startitem()
2514 fm.startitem()
2513 fm.data(node=fm.hexfunc(ctx.node()))
2515 fm.data(node=fm.hexfunc(ctx.node()))
2514 cols = [
2516 cols = [
2515 ('filename', fn, True),
2517 ('filename', fn, True),
2516 ('rev', rev, True),
2518 ('rev', rev, True),
2517 ('linenumber', l.linenum, opts.get('line_number')),
2519 ('linenumber', l.linenum, opts.get('line_number')),
2518 ]
2520 ]
2519 if opts.get('all'):
2521 if opts.get('all'):
2520 cols.append(('change', change, True))
2522 cols.append(('change', change, True))
2521 cols.extend([
2523 cols.extend([
2522 ('user', formatuser(ctx.user()), opts.get('user')),
2524 ('user', formatuser(ctx.user()), opts.get('user')),
2523 ('date', fm.formatdate(ctx.date(), datefmt), opts.get('date')),
2525 ('date', fm.formatdate(ctx.date(), datefmt), opts.get('date')),
2524 ])
2526 ])
2525 lastcol = next(name for name, data, cond in reversed(cols) if cond)
2527 lastcol = next(name for name, data, cond in reversed(cols) if cond)
2526 for name, data, cond in cols:
2528 for name, data, cond in cols:
2527 field = fieldnamemap.get(name, name)
2529 field = fieldnamemap.get(name, name)
2528 fm.condwrite(cond, field, '%s', data, label='grep.%s' % name)
2530 fm.condwrite(cond, field, '%s', data, label='grep.%s' % name)
2529 if cond and name != lastcol:
2531 if cond and name != lastcol:
2530 fm.plain(sep, label='grep.sep')
2532 fm.plain(sep, label='grep.sep')
2531 if not opts.get('files_with_matches'):
2533 if not opts.get('files_with_matches'):
2532 fm.plain(sep, label='grep.sep')
2534 fm.plain(sep, label='grep.sep')
2533 if not opts.get('text') and binary():
2535 if not opts.get('text') and binary():
2534 fm.plain(_(" Binary file matches"))
2536 fm.plain(_(" Binary file matches"))
2535 else:
2537 else:
2536 displaymatches(fm.nested('texts'), l)
2538 displaymatches(fm.nested('texts'), l)
2537 fm.plain(eol)
2539 fm.plain(eol)
2538 found = True
2540 found = True
2539 if opts.get('files_with_matches'):
2541 if opts.get('files_with_matches'):
2540 break
2542 break
2541 return found
2543 return found
2542
2544
2543 def displaymatches(fm, l):
2545 def displaymatches(fm, l):
2544 p = 0
2546 p = 0
2545 for s, e in l.findpos():
2547 for s, e in l.findpos():
2546 if p < s:
2548 if p < s:
2547 fm.startitem()
2549 fm.startitem()
2548 fm.write('text', '%s', l.line[p:s])
2550 fm.write('text', '%s', l.line[p:s])
2549 fm.data(matched=False)
2551 fm.data(matched=False)
2550 fm.startitem()
2552 fm.startitem()
2551 fm.write('text', '%s', l.line[s:e], label='grep.match')
2553 fm.write('text', '%s', l.line[s:e], label='grep.match')
2552 fm.data(matched=True)
2554 fm.data(matched=True)
2553 p = e
2555 p = e
2554 if p < len(l.line):
2556 if p < len(l.line):
2555 fm.startitem()
2557 fm.startitem()
2556 fm.write('text', '%s', l.line[p:])
2558 fm.write('text', '%s', l.line[p:])
2557 fm.data(matched=False)
2559 fm.data(matched=False)
2558 fm.end()
2560 fm.end()
2559
2561
2560 skip = {}
2562 skip = {}
2561 revfiles = {}
2563 revfiles = {}
2562 matchfn = scmutil.match(repo[None], pats, opts)
2564 matchfn = scmutil.match(repo[None], pats, opts)
2563 found = False
2565 found = False
2564 follow = opts.get('follow')
2566 follow = opts.get('follow')
2565
2567
2566 def prep(ctx, fns):
2568 def prep(ctx, fns):
2567 rev = ctx.rev()
2569 rev = ctx.rev()
2568 pctx = ctx.p1()
2570 pctx = ctx.p1()
2569 parent = pctx.rev()
2571 parent = pctx.rev()
2570 matches.setdefault(rev, {})
2572 matches.setdefault(rev, {})
2571 matches.setdefault(parent, {})
2573 matches.setdefault(parent, {})
2572 files = revfiles.setdefault(rev, [])
2574 files = revfiles.setdefault(rev, [])
2573 for fn in fns:
2575 for fn in fns:
2574 flog = getfile(fn)
2576 flog = getfile(fn)
2575 try:
2577 try:
2576 fnode = ctx.filenode(fn)
2578 fnode = ctx.filenode(fn)
2577 except error.LookupError:
2579 except error.LookupError:
2578 continue
2580 continue
2579
2581
2580 copied = flog.renamed(fnode)
2582 copied = flog.renamed(fnode)
2581 copy = follow and copied and copied[0]
2583 copy = follow and copied and copied[0]
2582 if copy:
2584 if copy:
2583 copies.setdefault(rev, {})[fn] = copy
2585 copies.setdefault(rev, {})[fn] = copy
2584 if fn in skip:
2586 if fn in skip:
2585 if copy:
2587 if copy:
2586 skip[copy] = True
2588 skip[copy] = True
2587 continue
2589 continue
2588 files.append(fn)
2590 files.append(fn)
2589
2591
2590 if fn not in matches[rev]:
2592 if fn not in matches[rev]:
2591 grepbody(fn, rev, flog.read(fnode))
2593 grepbody(fn, rev, flog.read(fnode))
2592
2594
2593 pfn = copy or fn
2595 pfn = copy or fn
2594 if pfn not in matches[parent]:
2596 if pfn not in matches[parent]:
2595 try:
2597 try:
2596 fnode = pctx.filenode(pfn)
2598 fnode = pctx.filenode(pfn)
2597 grepbody(pfn, parent, flog.read(fnode))
2599 grepbody(pfn, parent, flog.read(fnode))
2598 except error.LookupError:
2600 except error.LookupError:
2599 pass
2601 pass
2600
2602
2601 fm = ui.formatter('grep', opts)
2603 fm = ui.formatter('grep', opts)
2602 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2604 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2603 rev = ctx.rev()
2605 rev = ctx.rev()
2604 parent = ctx.p1().rev()
2606 parent = ctx.p1().rev()
2605 for fn in sorted(revfiles.get(rev, [])):
2607 for fn in sorted(revfiles.get(rev, [])):
2606 states = matches[rev][fn]
2608 states = matches[rev][fn]
2607 copy = copies.get(rev, {}).get(fn)
2609 copy = copies.get(rev, {}).get(fn)
2608 if fn in skip:
2610 if fn in skip:
2609 if copy:
2611 if copy:
2610 skip[copy] = True
2612 skip[copy] = True
2611 continue
2613 continue
2612 pstates = matches.get(parent, {}).get(copy or fn, [])
2614 pstates = matches.get(parent, {}).get(copy or fn, [])
2613 if pstates or states:
2615 if pstates or states:
2614 r = display(fm, fn, ctx, pstates, states)
2616 r = display(fm, fn, ctx, pstates, states)
2615 found = found or r
2617 found = found or r
2616 if r and not opts.get('all'):
2618 if r and not opts.get('all'):
2617 skip[fn] = True
2619 skip[fn] = True
2618 if copy:
2620 if copy:
2619 skip[copy] = True
2621 skip[copy] = True
2620 del matches[rev]
2622 del matches[rev]
2621 del revfiles[rev]
2623 del revfiles[rev]
2622 fm.end()
2624 fm.end()
2623
2625
2624 return not found
2626 return not found
2625
2627
2626 @command('heads',
2628 @command('heads',
2627 [('r', 'rev', '',
2629 [('r', 'rev', '',
2628 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2630 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2629 ('t', 'topo', False, _('show topological heads only')),
2631 ('t', 'topo', False, _('show topological heads only')),
2630 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2632 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2631 ('c', 'closed', False, _('show normal and closed branch heads')),
2633 ('c', 'closed', False, _('show normal and closed branch heads')),
2632 ] + templateopts,
2634 ] + templateopts,
2633 _('[-ct] [-r STARTREV] [REV]...'))
2635 _('[-ct] [-r STARTREV] [REV]...'))
2634 def heads(ui, repo, *branchrevs, **opts):
2636 def heads(ui, repo, *branchrevs, **opts):
2635 """show branch heads
2637 """show branch heads
2636
2638
2637 With no arguments, show all open branch heads in the repository.
2639 With no arguments, show all open branch heads in the repository.
2638 Branch heads are changesets that have no descendants on the
2640 Branch heads are changesets that have no descendants on the
2639 same branch. They are where development generally takes place and
2641 same branch. They are where development generally takes place and
2640 are the usual targets for update and merge operations.
2642 are the usual targets for update and merge operations.
2641
2643
2642 If one or more REVs are given, only open branch heads on the
2644 If one or more REVs are given, only open branch heads on the
2643 branches associated with the specified changesets are shown. This
2645 branches associated with the specified changesets are shown. This
2644 means that you can use :hg:`heads .` to see the heads on the
2646 means that you can use :hg:`heads .` to see the heads on the
2645 currently checked-out branch.
2647 currently checked-out branch.
2646
2648
2647 If -c/--closed is specified, also show branch heads marked closed
2649 If -c/--closed is specified, also show branch heads marked closed
2648 (see :hg:`commit --close-branch`).
2650 (see :hg:`commit --close-branch`).
2649
2651
2650 If STARTREV is specified, only those heads that are descendants of
2652 If STARTREV is specified, only those heads that are descendants of
2651 STARTREV will be displayed.
2653 STARTREV will be displayed.
2652
2654
2653 If -t/--topo is specified, named branch mechanics will be ignored and only
2655 If -t/--topo is specified, named branch mechanics will be ignored and only
2654 topological heads (changesets with no children) will be shown.
2656 topological heads (changesets with no children) will be shown.
2655
2657
2656 Returns 0 if matching heads are found, 1 if not.
2658 Returns 0 if matching heads are found, 1 if not.
2657 """
2659 """
2658
2660
2659 start = None
2661 start = None
2660 if 'rev' in opts:
2662 if 'rev' in opts:
2661 start = scmutil.revsingle(repo, opts['rev'], None).node()
2663 start = scmutil.revsingle(repo, opts['rev'], None).node()
2662
2664
2663 if opts.get('topo'):
2665 if opts.get('topo'):
2664 heads = [repo[h] for h in repo.heads(start)]
2666 heads = [repo[h] for h in repo.heads(start)]
2665 else:
2667 else:
2666 heads = []
2668 heads = []
2667 for branch in repo.branchmap():
2669 for branch in repo.branchmap():
2668 heads += repo.branchheads(branch, start, opts.get('closed'))
2670 heads += repo.branchheads(branch, start, opts.get('closed'))
2669 heads = [repo[h] for h in heads]
2671 heads = [repo[h] for h in heads]
2670
2672
2671 if branchrevs:
2673 if branchrevs:
2672 branches = set(repo[br].branch() for br in branchrevs)
2674 branches = set(repo[br].branch() for br in branchrevs)
2673 heads = [h for h in heads if h.branch() in branches]
2675 heads = [h for h in heads if h.branch() in branches]
2674
2676
2675 if opts.get('active') and branchrevs:
2677 if opts.get('active') and branchrevs:
2676 dagheads = repo.heads(start)
2678 dagheads = repo.heads(start)
2677 heads = [h for h in heads if h.node() in dagheads]
2679 heads = [h for h in heads if h.node() in dagheads]
2678
2680
2679 if branchrevs:
2681 if branchrevs:
2680 haveheads = set(h.branch() for h in heads)
2682 haveheads = set(h.branch() for h in heads)
2681 if branches - haveheads:
2683 if branches - haveheads:
2682 headless = ', '.join(b for b in branches - haveheads)
2684 headless = ', '.join(b for b in branches - haveheads)
2683 msg = _('no open branch heads found on branches %s')
2685 msg = _('no open branch heads found on branches %s')
2684 if opts.get('rev'):
2686 if opts.get('rev'):
2685 msg += _(' (started at %s)') % opts['rev']
2687 msg += _(' (started at %s)') % opts['rev']
2686 ui.warn((msg + '\n') % headless)
2688 ui.warn((msg + '\n') % headless)
2687
2689
2688 if not heads:
2690 if not heads:
2689 return 1
2691 return 1
2690
2692
2691 heads = sorted(heads, key=lambda x: -x.rev())
2693 heads = sorted(heads, key=lambda x: -x.rev())
2692 displayer = cmdutil.show_changeset(ui, repo, opts)
2694 displayer = cmdutil.show_changeset(ui, repo, opts)
2693 for ctx in heads:
2695 for ctx in heads:
2694 displayer.show(ctx)
2696 displayer.show(ctx)
2695 displayer.close()
2697 displayer.close()
2696
2698
2697 @command('help',
2699 @command('help',
2698 [('e', 'extension', None, _('show only help for extensions')),
2700 [('e', 'extension', None, _('show only help for extensions')),
2699 ('c', 'command', None, _('show only help for commands')),
2701 ('c', 'command', None, _('show only help for commands')),
2700 ('k', 'keyword', None, _('show topics matching keyword')),
2702 ('k', 'keyword', None, _('show topics matching keyword')),
2701 ('s', 'system', [], _('show help for specific platform(s)')),
2703 ('s', 'system', [], _('show help for specific platform(s)')),
2702 ],
2704 ],
2703 _('[-ecks] [TOPIC]'),
2705 _('[-ecks] [TOPIC]'),
2704 norepo=True)
2706 norepo=True)
2705 def help_(ui, name=None, **opts):
2707 def help_(ui, name=None, **opts):
2706 """show help for a given topic or a help overview
2708 """show help for a given topic or a help overview
2707
2709
2708 With no arguments, print a list of commands with short help messages.
2710 With no arguments, print a list of commands with short help messages.
2709
2711
2710 Given a topic, extension, or command name, print help for that
2712 Given a topic, extension, or command name, print help for that
2711 topic.
2713 topic.
2712
2714
2713 Returns 0 if successful.
2715 Returns 0 if successful.
2714 """
2716 """
2715
2717
2716 textwidth = ui.configint('ui', 'textwidth', 78)
2718 textwidth = ui.configint('ui', 'textwidth', 78)
2717 termwidth = ui.termwidth() - 2
2719 termwidth = ui.termwidth() - 2
2718 if textwidth <= 0 or termwidth < textwidth:
2720 if textwidth <= 0 or termwidth < textwidth:
2719 textwidth = termwidth
2721 textwidth = termwidth
2720
2722
2721 keep = opts.get('system') or []
2723 keep = opts.get('system') or []
2722 if len(keep) == 0:
2724 if len(keep) == 0:
2723 if pycompat.sysplatform.startswith('win'):
2725 if pycompat.sysplatform.startswith('win'):
2724 keep.append('windows')
2726 keep.append('windows')
2725 elif pycompat.sysplatform == 'OpenVMS':
2727 elif pycompat.sysplatform == 'OpenVMS':
2726 keep.append('vms')
2728 keep.append('vms')
2727 elif pycompat.sysplatform == 'plan9':
2729 elif pycompat.sysplatform == 'plan9':
2728 keep.append('plan9')
2730 keep.append('plan9')
2729 else:
2731 else:
2730 keep.append('unix')
2732 keep.append('unix')
2731 keep.append(pycompat.sysplatform.lower())
2733 keep.append(pycompat.sysplatform.lower())
2732 if ui.verbose:
2734 if ui.verbose:
2733 keep.append('verbose')
2735 keep.append('verbose')
2734
2736
2735 fullname = name
2737 fullname = name
2736 section = None
2738 section = None
2737 subtopic = None
2739 subtopic = None
2738 if name and '.' in name:
2740 if name and '.' in name:
2739 name, remaining = name.split('.', 1)
2741 name, remaining = name.split('.', 1)
2740 remaining = encoding.lower(remaining)
2742 remaining = encoding.lower(remaining)
2741 if '.' in remaining:
2743 if '.' in remaining:
2742 subtopic, section = remaining.split('.', 1)
2744 subtopic, section = remaining.split('.', 1)
2743 else:
2745 else:
2744 if name in help.subtopics:
2746 if name in help.subtopics:
2745 subtopic = remaining
2747 subtopic = remaining
2746 else:
2748 else:
2747 section = remaining
2749 section = remaining
2748
2750
2749 text = help.help_(ui, name, subtopic=subtopic, **opts)
2751 text = help.help_(ui, name, subtopic=subtopic, **opts)
2750
2752
2751 formatted, pruned = minirst.format(text, textwidth, keep=keep,
2753 formatted, pruned = minirst.format(text, textwidth, keep=keep,
2752 section=section)
2754 section=section)
2753
2755
2754 # We could have been given a weird ".foo" section without a name
2756 # We could have been given a weird ".foo" section without a name
2755 # to look for, or we could have simply failed to found "foo.bar"
2757 # to look for, or we could have simply failed to found "foo.bar"
2756 # because bar isn't a section of foo
2758 # because bar isn't a section of foo
2757 if section and not (formatted and name):
2759 if section and not (formatted and name):
2758 raise error.Abort(_("help section not found: %s") % fullname)
2760 raise error.Abort(_("help section not found: %s") % fullname)
2759
2761
2760 if 'verbose' in pruned:
2762 if 'verbose' in pruned:
2761 keep.append('omitted')
2763 keep.append('omitted')
2762 else:
2764 else:
2763 keep.append('notomitted')
2765 keep.append('notomitted')
2764 formatted, pruned = minirst.format(text, textwidth, keep=keep,
2766 formatted, pruned = minirst.format(text, textwidth, keep=keep,
2765 section=section)
2767 section=section)
2766 ui.write(formatted)
2768 ui.write(formatted)
2767
2769
2768
2770
2769 @command('identify|id',
2771 @command('identify|id',
2770 [('r', 'rev', '',
2772 [('r', 'rev', '',
2771 _('identify the specified revision'), _('REV')),
2773 _('identify the specified revision'), _('REV')),
2772 ('n', 'num', None, _('show local revision number')),
2774 ('n', 'num', None, _('show local revision number')),
2773 ('i', 'id', None, _('show global revision id')),
2775 ('i', 'id', None, _('show global revision id')),
2774 ('b', 'branch', None, _('show branch')),
2776 ('b', 'branch', None, _('show branch')),
2775 ('t', 'tags', None, _('show tags')),
2777 ('t', 'tags', None, _('show tags')),
2776 ('B', 'bookmarks', None, _('show bookmarks')),
2778 ('B', 'bookmarks', None, _('show bookmarks')),
2777 ] + remoteopts,
2779 ] + remoteopts,
2778 _('[-nibtB] [-r REV] [SOURCE]'),
2780 _('[-nibtB] [-r REV] [SOURCE]'),
2779 optionalrepo=True)
2781 optionalrepo=True)
2780 def identify(ui, repo, source=None, rev=None,
2782 def identify(ui, repo, source=None, rev=None,
2781 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
2783 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
2782 """identify the working directory or specified revision
2784 """identify the working directory or specified revision
2783
2785
2784 Print a summary identifying the repository state at REV using one or
2786 Print a summary identifying the repository state at REV using one or
2785 two parent hash identifiers, followed by a "+" if the working
2787 two parent hash identifiers, followed by a "+" if the working
2786 directory has uncommitted changes, the branch name (if not default),
2788 directory has uncommitted changes, the branch name (if not default),
2787 a list of tags, and a list of bookmarks.
2789 a list of tags, and a list of bookmarks.
2788
2790
2789 When REV is not given, print a summary of the current state of the
2791 When REV is not given, print a summary of the current state of the
2790 repository.
2792 repository.
2791
2793
2792 Specifying a path to a repository root or Mercurial bundle will
2794 Specifying a path to a repository root or Mercurial bundle will
2793 cause lookup to operate on that repository/bundle.
2795 cause lookup to operate on that repository/bundle.
2794
2796
2795 .. container:: verbose
2797 .. container:: verbose
2796
2798
2797 Examples:
2799 Examples:
2798
2800
2799 - generate a build identifier for the working directory::
2801 - generate a build identifier for the working directory::
2800
2802
2801 hg id --id > build-id.dat
2803 hg id --id > build-id.dat
2802
2804
2803 - find the revision corresponding to a tag::
2805 - find the revision corresponding to a tag::
2804
2806
2805 hg id -n -r 1.3
2807 hg id -n -r 1.3
2806
2808
2807 - check the most recent revision of a remote repository::
2809 - check the most recent revision of a remote repository::
2808
2810
2809 hg id -r tip https://www.mercurial-scm.org/repo/hg/
2811 hg id -r tip https://www.mercurial-scm.org/repo/hg/
2810
2812
2811 See :hg:`log` for generating more information about specific revisions,
2813 See :hg:`log` for generating more information about specific revisions,
2812 including full hash identifiers.
2814 including full hash identifiers.
2813
2815
2814 Returns 0 if successful.
2816 Returns 0 if successful.
2815 """
2817 """
2816
2818
2817 if not repo and not source:
2819 if not repo and not source:
2818 raise error.Abort(_("there is no Mercurial repository here "
2820 raise error.Abort(_("there is no Mercurial repository here "
2819 "(.hg not found)"))
2821 "(.hg not found)"))
2820
2822
2821 if ui.debugflag:
2823 if ui.debugflag:
2822 hexfunc = hex
2824 hexfunc = hex
2823 else:
2825 else:
2824 hexfunc = short
2826 hexfunc = short
2825 default = not (num or id or branch or tags or bookmarks)
2827 default = not (num or id or branch or tags or bookmarks)
2826 output = []
2828 output = []
2827 revs = []
2829 revs = []
2828
2830
2829 if source:
2831 if source:
2830 source, branches = hg.parseurl(ui.expandpath(source))
2832 source, branches = hg.parseurl(ui.expandpath(source))
2831 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
2833 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
2832 repo = peer.local()
2834 repo = peer.local()
2833 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
2835 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
2834
2836
2835 if not repo:
2837 if not repo:
2836 if num or branch or tags:
2838 if num or branch or tags:
2837 raise error.Abort(
2839 raise error.Abort(
2838 _("can't query remote revision number, branch, or tags"))
2840 _("can't query remote revision number, branch, or tags"))
2839 if not rev and revs:
2841 if not rev and revs:
2840 rev = revs[0]
2842 rev = revs[0]
2841 if not rev:
2843 if not rev:
2842 rev = "tip"
2844 rev = "tip"
2843
2845
2844 remoterev = peer.lookup(rev)
2846 remoterev = peer.lookup(rev)
2845 if default or id:
2847 if default or id:
2846 output = [hexfunc(remoterev)]
2848 output = [hexfunc(remoterev)]
2847
2849
2848 def getbms():
2850 def getbms():
2849 bms = []
2851 bms = []
2850
2852
2851 if 'bookmarks' in peer.listkeys('namespaces'):
2853 if 'bookmarks' in peer.listkeys('namespaces'):
2852 hexremoterev = hex(remoterev)
2854 hexremoterev = hex(remoterev)
2853 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
2855 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
2854 if bmr == hexremoterev]
2856 if bmr == hexremoterev]
2855
2857
2856 return sorted(bms)
2858 return sorted(bms)
2857
2859
2858 if bookmarks:
2860 if bookmarks:
2859 output.extend(getbms())
2861 output.extend(getbms())
2860 elif default and not ui.quiet:
2862 elif default and not ui.quiet:
2861 # multiple bookmarks for a single parent separated by '/'
2863 # multiple bookmarks for a single parent separated by '/'
2862 bm = '/'.join(getbms())
2864 bm = '/'.join(getbms())
2863 if bm:
2865 if bm:
2864 output.append(bm)
2866 output.append(bm)
2865 else:
2867 else:
2866 ctx = scmutil.revsingle(repo, rev, None)
2868 ctx = scmutil.revsingle(repo, rev, None)
2867
2869
2868 if ctx.rev() is None:
2870 if ctx.rev() is None:
2869 ctx = repo[None]
2871 ctx = repo[None]
2870 parents = ctx.parents()
2872 parents = ctx.parents()
2871 taglist = []
2873 taglist = []
2872 for p in parents:
2874 for p in parents:
2873 taglist.extend(p.tags())
2875 taglist.extend(p.tags())
2874
2876
2875 changed = ""
2877 changed = ""
2876 if default or id or num:
2878 if default or id or num:
2877 if (any(repo.status())
2879 if (any(repo.status())
2878 or any(ctx.sub(s).dirty() for s in ctx.substate)):
2880 or any(ctx.sub(s).dirty() for s in ctx.substate)):
2879 changed = '+'
2881 changed = '+'
2880 if default or id:
2882 if default or id:
2881 output = ["%s%s" %
2883 output = ["%s%s" %
2882 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
2884 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
2883 if num:
2885 if num:
2884 output.append("%s%s" %
2886 output.append("%s%s" %
2885 ('+'.join([str(p.rev()) for p in parents]), changed))
2887 ('+'.join([str(p.rev()) for p in parents]), changed))
2886 else:
2888 else:
2887 if default or id:
2889 if default or id:
2888 output = [hexfunc(ctx.node())]
2890 output = [hexfunc(ctx.node())]
2889 if num:
2891 if num:
2890 output.append(str(ctx.rev()))
2892 output.append(str(ctx.rev()))
2891 taglist = ctx.tags()
2893 taglist = ctx.tags()
2892
2894
2893 if default and not ui.quiet:
2895 if default and not ui.quiet:
2894 b = ctx.branch()
2896 b = ctx.branch()
2895 if b != 'default':
2897 if b != 'default':
2896 output.append("(%s)" % b)
2898 output.append("(%s)" % b)
2897
2899
2898 # multiple tags for a single parent separated by '/'
2900 # multiple tags for a single parent separated by '/'
2899 t = '/'.join(taglist)
2901 t = '/'.join(taglist)
2900 if t:
2902 if t:
2901 output.append(t)
2903 output.append(t)
2902
2904
2903 # multiple bookmarks for a single parent separated by '/'
2905 # multiple bookmarks for a single parent separated by '/'
2904 bm = '/'.join(ctx.bookmarks())
2906 bm = '/'.join(ctx.bookmarks())
2905 if bm:
2907 if bm:
2906 output.append(bm)
2908 output.append(bm)
2907 else:
2909 else:
2908 if branch:
2910 if branch:
2909 output.append(ctx.branch())
2911 output.append(ctx.branch())
2910
2912
2911 if tags:
2913 if tags:
2912 output.extend(taglist)
2914 output.extend(taglist)
2913
2915
2914 if bookmarks:
2916 if bookmarks:
2915 output.extend(ctx.bookmarks())
2917 output.extend(ctx.bookmarks())
2916
2918
2917 ui.write("%s\n" % ' '.join(output))
2919 ui.write("%s\n" % ' '.join(output))
2918
2920
2919 @command('import|patch',
2921 @command('import|patch',
2920 [('p', 'strip', 1,
2922 [('p', 'strip', 1,
2921 _('directory strip option for patch. This has the same '
2923 _('directory strip option for patch. This has the same '
2922 'meaning as the corresponding patch option'), _('NUM')),
2924 'meaning as the corresponding patch option'), _('NUM')),
2923 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
2925 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
2924 ('e', 'edit', False, _('invoke editor on commit messages')),
2926 ('e', 'edit', False, _('invoke editor on commit messages')),
2925 ('f', 'force', None,
2927 ('f', 'force', None,
2926 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
2928 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
2927 ('', 'no-commit', None,
2929 ('', 'no-commit', None,
2928 _("don't commit, just update the working directory")),
2930 _("don't commit, just update the working directory")),
2929 ('', 'bypass', None,
2931 ('', 'bypass', None,
2930 _("apply patch without touching the working directory")),
2932 _("apply patch without touching the working directory")),
2931 ('', 'partial', None,
2933 ('', 'partial', None,
2932 _('commit even if some hunks fail')),
2934 _('commit even if some hunks fail')),
2933 ('', 'exact', None,
2935 ('', 'exact', None,
2934 _('abort if patch would apply lossily')),
2936 _('abort if patch would apply lossily')),
2935 ('', 'prefix', '',
2937 ('', 'prefix', '',
2936 _('apply patch to subdirectory'), _('DIR')),
2938 _('apply patch to subdirectory'), _('DIR')),
2937 ('', 'import-branch', None,
2939 ('', 'import-branch', None,
2938 _('use any branch information in patch (implied by --exact)'))] +
2940 _('use any branch information in patch (implied by --exact)'))] +
2939 commitopts + commitopts2 + similarityopts,
2941 commitopts + commitopts2 + similarityopts,
2940 _('[OPTION]... PATCH...'))
2942 _('[OPTION]... PATCH...'))
2941 def import_(ui, repo, patch1=None, *patches, **opts):
2943 def import_(ui, repo, patch1=None, *patches, **opts):
2942 """import an ordered set of patches
2944 """import an ordered set of patches
2943
2945
2944 Import a list of patches and commit them individually (unless
2946 Import a list of patches and commit them individually (unless
2945 --no-commit is specified).
2947 --no-commit is specified).
2946
2948
2947 To read a patch from standard input (stdin), use "-" as the patch
2949 To read a patch from standard input (stdin), use "-" as the patch
2948 name. If a URL is specified, the patch will be downloaded from
2950 name. If a URL is specified, the patch will be downloaded from
2949 there.
2951 there.
2950
2952
2951 Import first applies changes to the working directory (unless
2953 Import first applies changes to the working directory (unless
2952 --bypass is specified), import will abort if there are outstanding
2954 --bypass is specified), import will abort if there are outstanding
2953 changes.
2955 changes.
2954
2956
2955 Use --bypass to apply and commit patches directly to the
2957 Use --bypass to apply and commit patches directly to the
2956 repository, without affecting the working directory. Without
2958 repository, without affecting the working directory. Without
2957 --exact, patches will be applied on top of the working directory
2959 --exact, patches will be applied on top of the working directory
2958 parent revision.
2960 parent revision.
2959
2961
2960 You can import a patch straight from a mail message. Even patches
2962 You can import a patch straight from a mail message. Even patches
2961 as attachments work (to use the body part, it must have type
2963 as attachments work (to use the body part, it must have type
2962 text/plain or text/x-patch). From and Subject headers of email
2964 text/plain or text/x-patch). From and Subject headers of email
2963 message are used as default committer and commit message. All
2965 message are used as default committer and commit message. All
2964 text/plain body parts before first diff are added to the commit
2966 text/plain body parts before first diff are added to the commit
2965 message.
2967 message.
2966
2968
2967 If the imported patch was generated by :hg:`export`, user and
2969 If the imported patch was generated by :hg:`export`, user and
2968 description from patch override values from message headers and
2970 description from patch override values from message headers and
2969 body. Values given on command line with -m/--message and -u/--user
2971 body. Values given on command line with -m/--message and -u/--user
2970 override these.
2972 override these.
2971
2973
2972 If --exact is specified, import will set the working directory to
2974 If --exact is specified, import will set the working directory to
2973 the parent of each patch before applying it, and will abort if the
2975 the parent of each patch before applying it, and will abort if the
2974 resulting changeset has a different ID than the one recorded in
2976 resulting changeset has a different ID than the one recorded in
2975 the patch. This will guard against various ways that portable
2977 the patch. This will guard against various ways that portable
2976 patch formats and mail systems might fail to transfer Mercurial
2978 patch formats and mail systems might fail to transfer Mercurial
2977 data or metadata. See :hg:`bundle` for lossless transmission.
2979 data or metadata. See :hg:`bundle` for lossless transmission.
2978
2980
2979 Use --partial to ensure a changeset will be created from the patch
2981 Use --partial to ensure a changeset will be created from the patch
2980 even if some hunks fail to apply. Hunks that fail to apply will be
2982 even if some hunks fail to apply. Hunks that fail to apply will be
2981 written to a <target-file>.rej file. Conflicts can then be resolved
2983 written to a <target-file>.rej file. Conflicts can then be resolved
2982 by hand before :hg:`commit --amend` is run to update the created
2984 by hand before :hg:`commit --amend` is run to update the created
2983 changeset. This flag exists to let people import patches that
2985 changeset. This flag exists to let people import patches that
2984 partially apply without losing the associated metadata (author,
2986 partially apply without losing the associated metadata (author,
2985 date, description, ...).
2987 date, description, ...).
2986
2988
2987 .. note::
2989 .. note::
2988
2990
2989 When no hunks apply cleanly, :hg:`import --partial` will create
2991 When no hunks apply cleanly, :hg:`import --partial` will create
2990 an empty changeset, importing only the patch metadata.
2992 an empty changeset, importing only the patch metadata.
2991
2993
2992 With -s/--similarity, hg will attempt to discover renames and
2994 With -s/--similarity, hg will attempt to discover renames and
2993 copies in the patch in the same way as :hg:`addremove`.
2995 copies in the patch in the same way as :hg:`addremove`.
2994
2996
2995 It is possible to use external patch programs to perform the patch
2997 It is possible to use external patch programs to perform the patch
2996 by setting the ``ui.patch`` configuration option. For the default
2998 by setting the ``ui.patch`` configuration option. For the default
2997 internal tool, the fuzz can also be configured via ``patch.fuzz``.
2999 internal tool, the fuzz can also be configured via ``patch.fuzz``.
2998 See :hg:`help config` for more information about configuration
3000 See :hg:`help config` for more information about configuration
2999 files and how to use these options.
3001 files and how to use these options.
3000
3002
3001 See :hg:`help dates` for a list of formats valid for -d/--date.
3003 See :hg:`help dates` for a list of formats valid for -d/--date.
3002
3004
3003 .. container:: verbose
3005 .. container:: verbose
3004
3006
3005 Examples:
3007 Examples:
3006
3008
3007 - import a traditional patch from a website and detect renames::
3009 - import a traditional patch from a website and detect renames::
3008
3010
3009 hg import -s 80 http://example.com/bugfix.patch
3011 hg import -s 80 http://example.com/bugfix.patch
3010
3012
3011 - import a changeset from an hgweb server::
3013 - import a changeset from an hgweb server::
3012
3014
3013 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
3015 hg import https://www.mercurial-scm.org/repo/hg/rev/5ca8c111e9aa
3014
3016
3015 - import all the patches in an Unix-style mbox::
3017 - import all the patches in an Unix-style mbox::
3016
3018
3017 hg import incoming-patches.mbox
3019 hg import incoming-patches.mbox
3018
3020
3019 - import patches from stdin::
3021 - import patches from stdin::
3020
3022
3021 hg import -
3023 hg import -
3022
3024
3023 - attempt to exactly restore an exported changeset (not always
3025 - attempt to exactly restore an exported changeset (not always
3024 possible)::
3026 possible)::
3025
3027
3026 hg import --exact proposed-fix.patch
3028 hg import --exact proposed-fix.patch
3027
3029
3028 - use an external tool to apply a patch which is too fuzzy for
3030 - use an external tool to apply a patch which is too fuzzy for
3029 the default internal tool.
3031 the default internal tool.
3030
3032
3031 hg import --config ui.patch="patch --merge" fuzzy.patch
3033 hg import --config ui.patch="patch --merge" fuzzy.patch
3032
3034
3033 - change the default fuzzing from 2 to a less strict 7
3035 - change the default fuzzing from 2 to a less strict 7
3034
3036
3035 hg import --config ui.fuzz=7 fuzz.patch
3037 hg import --config ui.fuzz=7 fuzz.patch
3036
3038
3037 Returns 0 on success, 1 on partial success (see --partial).
3039 Returns 0 on success, 1 on partial success (see --partial).
3038 """
3040 """
3039
3041
3040 if not patch1:
3042 if not patch1:
3041 raise error.Abort(_('need at least one patch to import'))
3043 raise error.Abort(_('need at least one patch to import'))
3042
3044
3043 patches = (patch1,) + patches
3045 patches = (patch1,) + patches
3044
3046
3045 date = opts.get('date')
3047 date = opts.get('date')
3046 if date:
3048 if date:
3047 opts['date'] = util.parsedate(date)
3049 opts['date'] = util.parsedate(date)
3048
3050
3049 exact = opts.get('exact')
3051 exact = opts.get('exact')
3050 update = not opts.get('bypass')
3052 update = not opts.get('bypass')
3051 if not update and opts.get('no_commit'):
3053 if not update and opts.get('no_commit'):
3052 raise error.Abort(_('cannot use --no-commit with --bypass'))
3054 raise error.Abort(_('cannot use --no-commit with --bypass'))
3053 try:
3055 try:
3054 sim = float(opts.get('similarity') or 0)
3056 sim = float(opts.get('similarity') or 0)
3055 except ValueError:
3057 except ValueError:
3056 raise error.Abort(_('similarity must be a number'))
3058 raise error.Abort(_('similarity must be a number'))
3057 if sim < 0 or sim > 100:
3059 if sim < 0 or sim > 100:
3058 raise error.Abort(_('similarity must be between 0 and 100'))
3060 raise error.Abort(_('similarity must be between 0 and 100'))
3059 if sim and not update:
3061 if sim and not update:
3060 raise error.Abort(_('cannot use --similarity with --bypass'))
3062 raise error.Abort(_('cannot use --similarity with --bypass'))
3061 if exact:
3063 if exact:
3062 if opts.get('edit'):
3064 if opts.get('edit'):
3063 raise error.Abort(_('cannot use --exact with --edit'))
3065 raise error.Abort(_('cannot use --exact with --edit'))
3064 if opts.get('prefix'):
3066 if opts.get('prefix'):
3065 raise error.Abort(_('cannot use --exact with --prefix'))
3067 raise error.Abort(_('cannot use --exact with --prefix'))
3066
3068
3067 base = opts["base"]
3069 base = opts["base"]
3068 wlock = dsguard = lock = tr = None
3070 wlock = dsguard = lock = tr = None
3069 msgs = []
3071 msgs = []
3070 ret = 0
3072 ret = 0
3071
3073
3072
3074
3073 try:
3075 try:
3074 wlock = repo.wlock()
3076 wlock = repo.wlock()
3075
3077
3076 if update:
3078 if update:
3077 cmdutil.checkunfinished(repo)
3079 cmdutil.checkunfinished(repo)
3078 if (exact or not opts.get('force')):
3080 if (exact or not opts.get('force')):
3079 cmdutil.bailifchanged(repo)
3081 cmdutil.bailifchanged(repo)
3080
3082
3081 if not opts.get('no_commit'):
3083 if not opts.get('no_commit'):
3082 lock = repo.lock()
3084 lock = repo.lock()
3083 tr = repo.transaction('import')
3085 tr = repo.transaction('import')
3084 else:
3086 else:
3085 dsguard = dirstateguard.dirstateguard(repo, 'import')
3087 dsguard = dirstateguard.dirstateguard(repo, 'import')
3086 parents = repo[None].parents()
3088 parents = repo[None].parents()
3087 for patchurl in patches:
3089 for patchurl in patches:
3088 if patchurl == '-':
3090 if patchurl == '-':
3089 ui.status(_('applying patch from stdin\n'))
3091 ui.status(_('applying patch from stdin\n'))
3090 patchfile = ui.fin
3092 patchfile = ui.fin
3091 patchurl = 'stdin' # for error message
3093 patchurl = 'stdin' # for error message
3092 else:
3094 else:
3093 patchurl = os.path.join(base, patchurl)
3095 patchurl = os.path.join(base, patchurl)
3094 ui.status(_('applying %s\n') % patchurl)
3096 ui.status(_('applying %s\n') % patchurl)
3095 patchfile = hg.openpath(ui, patchurl)
3097 patchfile = hg.openpath(ui, patchurl)
3096
3098
3097 haspatch = False
3099 haspatch = False
3098 for hunk in patch.split(patchfile):
3100 for hunk in patch.split(patchfile):
3099 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
3101 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
3100 parents, opts,
3102 parents, opts,
3101 msgs, hg.clean)
3103 msgs, hg.clean)
3102 if msg:
3104 if msg:
3103 haspatch = True
3105 haspatch = True
3104 ui.note(msg + '\n')
3106 ui.note(msg + '\n')
3105 if update or exact:
3107 if update or exact:
3106 parents = repo[None].parents()
3108 parents = repo[None].parents()
3107 else:
3109 else:
3108 parents = [repo[node]]
3110 parents = [repo[node]]
3109 if rej:
3111 if rej:
3110 ui.write_err(_("patch applied partially\n"))
3112 ui.write_err(_("patch applied partially\n"))
3111 ui.write_err(_("(fix the .rej files and run "
3113 ui.write_err(_("(fix the .rej files and run "
3112 "`hg commit --amend`)\n"))
3114 "`hg commit --amend`)\n"))
3113 ret = 1
3115 ret = 1
3114 break
3116 break
3115
3117
3116 if not haspatch:
3118 if not haspatch:
3117 raise error.Abort(_('%s: no diffs found') % patchurl)
3119 raise error.Abort(_('%s: no diffs found') % patchurl)
3118
3120
3119 if tr:
3121 if tr:
3120 tr.close()
3122 tr.close()
3121 if msgs:
3123 if msgs:
3122 repo.savecommitmessage('\n* * *\n'.join(msgs))
3124 repo.savecommitmessage('\n* * *\n'.join(msgs))
3123 if dsguard:
3125 if dsguard:
3124 dsguard.close()
3126 dsguard.close()
3125 return ret
3127 return ret
3126 finally:
3128 finally:
3127 if tr:
3129 if tr:
3128 tr.release()
3130 tr.release()
3129 release(lock, dsguard, wlock)
3131 release(lock, dsguard, wlock)
3130
3132
3131 @command('incoming|in',
3133 @command('incoming|in',
3132 [('f', 'force', None,
3134 [('f', 'force', None,
3133 _('run even if remote repository is unrelated')),
3135 _('run even if remote repository is unrelated')),
3134 ('n', 'newest-first', None, _('show newest record first')),
3136 ('n', 'newest-first', None, _('show newest record first')),
3135 ('', 'bundle', '',
3137 ('', 'bundle', '',
3136 _('file to store the bundles into'), _('FILE')),
3138 _('file to store the bundles into'), _('FILE')),
3137 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3139 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3138 ('B', 'bookmarks', False, _("compare bookmarks")),
3140 ('B', 'bookmarks', False, _("compare bookmarks")),
3139 ('b', 'branch', [],
3141 ('b', 'branch', [],
3140 _('a specific branch you would like to pull'), _('BRANCH')),
3142 _('a specific branch you would like to pull'), _('BRANCH')),
3141 ] + logopts + remoteopts + subrepoopts,
3143 ] + logopts + remoteopts + subrepoopts,
3142 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3144 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3143 def incoming(ui, repo, source="default", **opts):
3145 def incoming(ui, repo, source="default", **opts):
3144 """show new changesets found in source
3146 """show new changesets found in source
3145
3147
3146 Show new changesets found in the specified path/URL or the default
3148 Show new changesets found in the specified path/URL or the default
3147 pull location. These are the changesets that would have been pulled
3149 pull location. These are the changesets that would have been pulled
3148 if a pull at the time you issued this command.
3150 if a pull at the time you issued this command.
3149
3151
3150 See pull for valid source format details.
3152 See pull for valid source format details.
3151
3153
3152 .. container:: verbose
3154 .. container:: verbose
3153
3155
3154 With -B/--bookmarks, the result of bookmark comparison between
3156 With -B/--bookmarks, the result of bookmark comparison between
3155 local and remote repositories is displayed. With -v/--verbose,
3157 local and remote repositories is displayed. With -v/--verbose,
3156 status is also displayed for each bookmark like below::
3158 status is also displayed for each bookmark like below::
3157
3159
3158 BM1 01234567890a added
3160 BM1 01234567890a added
3159 BM2 1234567890ab advanced
3161 BM2 1234567890ab advanced
3160 BM3 234567890abc diverged
3162 BM3 234567890abc diverged
3161 BM4 34567890abcd changed
3163 BM4 34567890abcd changed
3162
3164
3163 The action taken locally when pulling depends on the
3165 The action taken locally when pulling depends on the
3164 status of each bookmark:
3166 status of each bookmark:
3165
3167
3166 :``added``: pull will create it
3168 :``added``: pull will create it
3167 :``advanced``: pull will update it
3169 :``advanced``: pull will update it
3168 :``diverged``: pull will create a divergent bookmark
3170 :``diverged``: pull will create a divergent bookmark
3169 :``changed``: result depends on remote changesets
3171 :``changed``: result depends on remote changesets
3170
3172
3171 From the point of view of pulling behavior, bookmark
3173 From the point of view of pulling behavior, bookmark
3172 existing only in the remote repository are treated as ``added``,
3174 existing only in the remote repository are treated as ``added``,
3173 even if it is in fact locally deleted.
3175 even if it is in fact locally deleted.
3174
3176
3175 .. container:: verbose
3177 .. container:: verbose
3176
3178
3177 For remote repository, using --bundle avoids downloading the
3179 For remote repository, using --bundle avoids downloading the
3178 changesets twice if the incoming is followed by a pull.
3180 changesets twice if the incoming is followed by a pull.
3179
3181
3180 Examples:
3182 Examples:
3181
3183
3182 - show incoming changes with patches and full description::
3184 - show incoming changes with patches and full description::
3183
3185
3184 hg incoming -vp
3186 hg incoming -vp
3185
3187
3186 - show incoming changes excluding merges, store a bundle::
3188 - show incoming changes excluding merges, store a bundle::
3187
3189
3188 hg in -vpM --bundle incoming.hg
3190 hg in -vpM --bundle incoming.hg
3189 hg pull incoming.hg
3191 hg pull incoming.hg
3190
3192
3191 - briefly list changes inside a bundle::
3193 - briefly list changes inside a bundle::
3192
3194
3193 hg in changes.hg -T "{desc|firstline}\\n"
3195 hg in changes.hg -T "{desc|firstline}\\n"
3194
3196
3195 Returns 0 if there are incoming changes, 1 otherwise.
3197 Returns 0 if there are incoming changes, 1 otherwise.
3196 """
3198 """
3197 if opts.get('graph'):
3199 if opts.get('graph'):
3198 cmdutil.checkunsupportedgraphflags([], opts)
3200 cmdutil.checkunsupportedgraphflags([], opts)
3199 def display(other, chlist, displayer):
3201 def display(other, chlist, displayer):
3200 revdag = cmdutil.graphrevs(other, chlist, opts)
3202 revdag = cmdutil.graphrevs(other, chlist, opts)
3201 cmdutil.displaygraph(ui, repo, revdag, displayer,
3203 cmdutil.displaygraph(ui, repo, revdag, displayer,
3202 graphmod.asciiedges)
3204 graphmod.asciiedges)
3203
3205
3204 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3206 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3205 return 0
3207 return 0
3206
3208
3207 if opts.get('bundle') and opts.get('subrepos'):
3209 if opts.get('bundle') and opts.get('subrepos'):
3208 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3210 raise error.Abort(_('cannot combine --bundle and --subrepos'))
3209
3211
3210 if opts.get('bookmarks'):
3212 if opts.get('bookmarks'):
3211 source, branches = hg.parseurl(ui.expandpath(source),
3213 source, branches = hg.parseurl(ui.expandpath(source),
3212 opts.get('branch'))
3214 opts.get('branch'))
3213 other = hg.peer(repo, opts, source)
3215 other = hg.peer(repo, opts, source)
3214 if 'bookmarks' not in other.listkeys('namespaces'):
3216 if 'bookmarks' not in other.listkeys('namespaces'):
3215 ui.warn(_("remote doesn't support bookmarks\n"))
3217 ui.warn(_("remote doesn't support bookmarks\n"))
3216 return 0
3218 return 0
3217 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3219 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3218 return bookmarks.incoming(ui, repo, other)
3220 return bookmarks.incoming(ui, repo, other)
3219
3221
3220 repo._subtoppath = ui.expandpath(source)
3222 repo._subtoppath = ui.expandpath(source)
3221 try:
3223 try:
3222 return hg.incoming(ui, repo, source, opts)
3224 return hg.incoming(ui, repo, source, opts)
3223 finally:
3225 finally:
3224 del repo._subtoppath
3226 del repo._subtoppath
3225
3227
3226
3228
3227 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3229 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
3228 norepo=True)
3230 norepo=True)
3229 def init(ui, dest=".", **opts):
3231 def init(ui, dest=".", **opts):
3230 """create a new repository in the given directory
3232 """create a new repository in the given directory
3231
3233
3232 Initialize a new repository in the given directory. If the given
3234 Initialize a new repository in the given directory. If the given
3233 directory does not exist, it will be created.
3235 directory does not exist, it will be created.
3234
3236
3235 If no directory is given, the current directory is used.
3237 If no directory is given, the current directory is used.
3236
3238
3237 It is possible to specify an ``ssh://`` URL as the destination.
3239 It is possible to specify an ``ssh://`` URL as the destination.
3238 See :hg:`help urls` for more information.
3240 See :hg:`help urls` for more information.
3239
3241
3240 Returns 0 on success.
3242 Returns 0 on success.
3241 """
3243 """
3242 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3244 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3243
3245
3244 @command('locate',
3246 @command('locate',
3245 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3247 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3246 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3248 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3247 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3249 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3248 ] + walkopts,
3250 ] + walkopts,
3249 _('[OPTION]... [PATTERN]...'))
3251 _('[OPTION]... [PATTERN]...'))
3250 def locate(ui, repo, *pats, **opts):
3252 def locate(ui, repo, *pats, **opts):
3251 """locate files matching specific patterns (DEPRECATED)
3253 """locate files matching specific patterns (DEPRECATED)
3252
3254
3253 Print files under Mercurial control in the working directory whose
3255 Print files under Mercurial control in the working directory whose
3254 names match the given patterns.
3256 names match the given patterns.
3255
3257
3256 By default, this command searches all directories in the working
3258 By default, this command searches all directories in the working
3257 directory. To search just the current directory and its
3259 directory. To search just the current directory and its
3258 subdirectories, use "--include .".
3260 subdirectories, use "--include .".
3259
3261
3260 If no patterns are given to match, this command prints the names
3262 If no patterns are given to match, this command prints the names
3261 of all files under Mercurial control in the working directory.
3263 of all files under Mercurial control in the working directory.
3262
3264
3263 If you want to feed the output of this command into the "xargs"
3265 If you want to feed the output of this command into the "xargs"
3264 command, use the -0 option to both this command and "xargs". This
3266 command, use the -0 option to both this command and "xargs". This
3265 will avoid the problem of "xargs" treating single filenames that
3267 will avoid the problem of "xargs" treating single filenames that
3266 contain whitespace as multiple filenames.
3268 contain whitespace as multiple filenames.
3267
3269
3268 See :hg:`help files` for a more versatile command.
3270 See :hg:`help files` for a more versatile command.
3269
3271
3270 Returns 0 if a match is found, 1 otherwise.
3272 Returns 0 if a match is found, 1 otherwise.
3271 """
3273 """
3272 if opts.get('print0'):
3274 if opts.get('print0'):
3273 end = '\0'
3275 end = '\0'
3274 else:
3276 else:
3275 end = '\n'
3277 end = '\n'
3276 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3278 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3277
3279
3278 ret = 1
3280 ret = 1
3279 ctx = repo[rev]
3281 ctx = repo[rev]
3280 m = scmutil.match(ctx, pats, opts, default='relglob',
3282 m = scmutil.match(ctx, pats, opts, default='relglob',
3281 badfn=lambda x, y: False)
3283 badfn=lambda x, y: False)
3282
3284
3283 for abs in ctx.matches(m):
3285 for abs in ctx.matches(m):
3284 if opts.get('fullpath'):
3286 if opts.get('fullpath'):
3285 ui.write(repo.wjoin(abs), end)
3287 ui.write(repo.wjoin(abs), end)
3286 else:
3288 else:
3287 ui.write(((pats and m.rel(abs)) or abs), end)
3289 ui.write(((pats and m.rel(abs)) or abs), end)
3288 ret = 0
3290 ret = 0
3289
3291
3290 return ret
3292 return ret
3291
3293
3292 @command('^log|history',
3294 @command('^log|history',
3293 [('f', 'follow', None,
3295 [('f', 'follow', None,
3294 _('follow changeset history, or file history across copies and renames')),
3296 _('follow changeset history, or file history across copies and renames')),
3295 ('', 'follow-first', None,
3297 ('', 'follow-first', None,
3296 _('only follow the first parent of merge changesets (DEPRECATED)')),
3298 _('only follow the first parent of merge changesets (DEPRECATED)')),
3297 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3299 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3298 ('C', 'copies', None, _('show copied files')),
3300 ('C', 'copies', None, _('show copied files')),
3299 ('k', 'keyword', [],
3301 ('k', 'keyword', [],
3300 _('do case-insensitive search for a given text'), _('TEXT')),
3302 _('do case-insensitive search for a given text'), _('TEXT')),
3301 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3303 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
3302 ('', 'removed', None, _('include revisions where files were removed')),
3304 ('', 'removed', None, _('include revisions where files were removed')),
3303 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3305 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3304 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3306 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3305 ('', 'only-branch', [],
3307 ('', 'only-branch', [],
3306 _('show only changesets within the given named branch (DEPRECATED)'),
3308 _('show only changesets within the given named branch (DEPRECATED)'),
3307 _('BRANCH')),
3309 _('BRANCH')),
3308 ('b', 'branch', [],
3310 ('b', 'branch', [],
3309 _('show changesets within the given named branch'), _('BRANCH')),
3311 _('show changesets within the given named branch'), _('BRANCH')),
3310 ('P', 'prune', [],
3312 ('P', 'prune', [],
3311 _('do not display revision or any of its ancestors'), _('REV')),
3313 _('do not display revision or any of its ancestors'), _('REV')),
3312 ] + logopts + walkopts,
3314 ] + logopts + walkopts,
3313 _('[OPTION]... [FILE]'),
3315 _('[OPTION]... [FILE]'),
3314 inferrepo=True)
3316 inferrepo=True)
3315 def log(ui, repo, *pats, **opts):
3317 def log(ui, repo, *pats, **opts):
3316 """show revision history of entire repository or files
3318 """show revision history of entire repository or files
3317
3319
3318 Print the revision history of the specified files or the entire
3320 Print the revision history of the specified files or the entire
3319 project.
3321 project.
3320
3322
3321 If no revision range is specified, the default is ``tip:0`` unless
3323 If no revision range is specified, the default is ``tip:0`` unless
3322 --follow is set, in which case the working directory parent is
3324 --follow is set, in which case the working directory parent is
3323 used as the starting revision.
3325 used as the starting revision.
3324
3326
3325 File history is shown without following rename or copy history of
3327 File history is shown without following rename or copy history of
3326 files. Use -f/--follow with a filename to follow history across
3328 files. Use -f/--follow with a filename to follow history across
3327 renames and copies. --follow without a filename will only show
3329 renames and copies. --follow without a filename will only show
3328 ancestors or descendants of the starting revision.
3330 ancestors or descendants of the starting revision.
3329
3331
3330 By default this command prints revision number and changeset id,
3332 By default this command prints revision number and changeset id,
3331 tags, non-trivial parents, user, date and time, and a summary for
3333 tags, non-trivial parents, user, date and time, and a summary for
3332 each commit. When the -v/--verbose switch is used, the list of
3334 each commit. When the -v/--verbose switch is used, the list of
3333 changed files and full commit message are shown.
3335 changed files and full commit message are shown.
3334
3336
3335 With --graph the revisions are shown as an ASCII art DAG with the most
3337 With --graph the revisions are shown as an ASCII art DAG with the most
3336 recent changeset at the top.
3338 recent changeset at the top.
3337 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
3339 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
3338 and '+' represents a fork where the changeset from the lines below is a
3340 and '+' represents a fork where the changeset from the lines below is a
3339 parent of the 'o' merge on the same line.
3341 parent of the 'o' merge on the same line.
3340
3342
3341 .. note::
3343 .. note::
3342
3344
3343 :hg:`log --patch` may generate unexpected diff output for merge
3345 :hg:`log --patch` may generate unexpected diff output for merge
3344 changesets, as it will only compare the merge changeset against
3346 changesets, as it will only compare the merge changeset against
3345 its first parent. Also, only files different from BOTH parents
3347 its first parent. Also, only files different from BOTH parents
3346 will appear in files:.
3348 will appear in files:.
3347
3349
3348 .. note::
3350 .. note::
3349
3351
3350 For performance reasons, :hg:`log FILE` may omit duplicate changes
3352 For performance reasons, :hg:`log FILE` may omit duplicate changes
3351 made on branches and will not show removals or mode changes. To
3353 made on branches and will not show removals or mode changes. To
3352 see all such changes, use the --removed switch.
3354 see all such changes, use the --removed switch.
3353
3355
3354 .. container:: verbose
3356 .. container:: verbose
3355
3357
3356 Some examples:
3358 Some examples:
3357
3359
3358 - changesets with full descriptions and file lists::
3360 - changesets with full descriptions and file lists::
3359
3361
3360 hg log -v
3362 hg log -v
3361
3363
3362 - changesets ancestral to the working directory::
3364 - changesets ancestral to the working directory::
3363
3365
3364 hg log -f
3366 hg log -f
3365
3367
3366 - last 10 commits on the current branch::
3368 - last 10 commits on the current branch::
3367
3369
3368 hg log -l 10 -b .
3370 hg log -l 10 -b .
3369
3371
3370 - changesets showing all modifications of a file, including removals::
3372 - changesets showing all modifications of a file, including removals::
3371
3373
3372 hg log --removed file.c
3374 hg log --removed file.c
3373
3375
3374 - all changesets that touch a directory, with diffs, excluding merges::
3376 - all changesets that touch a directory, with diffs, excluding merges::
3375
3377
3376 hg log -Mp lib/
3378 hg log -Mp lib/
3377
3379
3378 - all revision numbers that match a keyword::
3380 - all revision numbers that match a keyword::
3379
3381
3380 hg log -k bug --template "{rev}\\n"
3382 hg log -k bug --template "{rev}\\n"
3381
3383
3382 - the full hash identifier of the working directory parent::
3384 - the full hash identifier of the working directory parent::
3383
3385
3384 hg log -r . --template "{node}\\n"
3386 hg log -r . --template "{node}\\n"
3385
3387
3386 - list available log templates::
3388 - list available log templates::
3387
3389
3388 hg log -T list
3390 hg log -T list
3389
3391
3390 - check if a given changeset is included in a tagged release::
3392 - check if a given changeset is included in a tagged release::
3391
3393
3392 hg log -r "a21ccf and ancestor(1.9)"
3394 hg log -r "a21ccf and ancestor(1.9)"
3393
3395
3394 - find all changesets by some user in a date range::
3396 - find all changesets by some user in a date range::
3395
3397
3396 hg log -k alice -d "may 2008 to jul 2008"
3398 hg log -k alice -d "may 2008 to jul 2008"
3397
3399
3398 - summary of all changesets after the last tag::
3400 - summary of all changesets after the last tag::
3399
3401
3400 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3402 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3401
3403
3402 See :hg:`help dates` for a list of formats valid for -d/--date.
3404 See :hg:`help dates` for a list of formats valid for -d/--date.
3403
3405
3404 See :hg:`help revisions` for more about specifying and ordering
3406 See :hg:`help revisions` for more about specifying and ordering
3405 revisions.
3407 revisions.
3406
3408
3407 See :hg:`help templates` for more about pre-packaged styles and
3409 See :hg:`help templates` for more about pre-packaged styles and
3408 specifying custom templates.
3410 specifying custom templates.
3409
3411
3410 Returns 0 on success.
3412 Returns 0 on success.
3411
3413
3412 """
3414 """
3413 if opts.get('follow') and opts.get('rev'):
3415 if opts.get('follow') and opts.get('rev'):
3414 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
3416 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
3415 del opts['follow']
3417 del opts['follow']
3416
3418
3417 if opts.get('graph'):
3419 if opts.get('graph'):
3418 return cmdutil.graphlog(ui, repo, *pats, **opts)
3420 return cmdutil.graphlog(ui, repo, *pats, **opts)
3419
3421
3420 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
3422 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
3421 limit = cmdutil.loglimit(opts)
3423 limit = cmdutil.loglimit(opts)
3422 count = 0
3424 count = 0
3423
3425
3424 getrenamed = None
3426 getrenamed = None
3425 if opts.get('copies'):
3427 if opts.get('copies'):
3426 endrev = None
3428 endrev = None
3427 if opts.get('rev'):
3429 if opts.get('rev'):
3428 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
3430 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
3429 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3431 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3430
3432
3431 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
3433 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
3432 for rev in revs:
3434 for rev in revs:
3433 if count == limit:
3435 if count == limit:
3434 break
3436 break
3435 ctx = repo[rev]
3437 ctx = repo[rev]
3436 copies = None
3438 copies = None
3437 if getrenamed is not None and rev:
3439 if getrenamed is not None and rev:
3438 copies = []
3440 copies = []
3439 for fn in ctx.files():
3441 for fn in ctx.files():
3440 rename = getrenamed(fn, rev)
3442 rename = getrenamed(fn, rev)
3441 if rename:
3443 if rename:
3442 copies.append((fn, rename[0]))
3444 copies.append((fn, rename[0]))
3443 if filematcher:
3445 if filematcher:
3444 revmatchfn = filematcher(ctx.rev())
3446 revmatchfn = filematcher(ctx.rev())
3445 else:
3447 else:
3446 revmatchfn = None
3448 revmatchfn = None
3447 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3449 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3448 if displayer.flush(ctx):
3450 if displayer.flush(ctx):
3449 count += 1
3451 count += 1
3450
3452
3451 displayer.close()
3453 displayer.close()
3452
3454
3453 @command('manifest',
3455 @command('manifest',
3454 [('r', 'rev', '', _('revision to display'), _('REV')),
3456 [('r', 'rev', '', _('revision to display'), _('REV')),
3455 ('', 'all', False, _("list files from all revisions"))]
3457 ('', 'all', False, _("list files from all revisions"))]
3456 + formatteropts,
3458 + formatteropts,
3457 _('[-r REV]'))
3459 _('[-r REV]'))
3458 def manifest(ui, repo, node=None, rev=None, **opts):
3460 def manifest(ui, repo, node=None, rev=None, **opts):
3459 """output the current or given revision of the project manifest
3461 """output the current or given revision of the project manifest
3460
3462
3461 Print a list of version controlled files for the given revision.
3463 Print a list of version controlled files for the given revision.
3462 If no revision is given, the first parent of the working directory
3464 If no revision is given, the first parent of the working directory
3463 is used, or the null revision if no revision is checked out.
3465 is used, or the null revision if no revision is checked out.
3464
3466
3465 With -v, print file permissions, symlink and executable bits.
3467 With -v, print file permissions, symlink and executable bits.
3466 With --debug, print file revision hashes.
3468 With --debug, print file revision hashes.
3467
3469
3468 If option --all is specified, the list of all files from all revisions
3470 If option --all is specified, the list of all files from all revisions
3469 is printed. This includes deleted and renamed files.
3471 is printed. This includes deleted and renamed files.
3470
3472
3471 Returns 0 on success.
3473 Returns 0 on success.
3472 """
3474 """
3473
3475
3474 fm = ui.formatter('manifest', opts)
3476 fm = ui.formatter('manifest', opts)
3475
3477
3476 if opts.get('all'):
3478 if opts.get('all'):
3477 if rev or node:
3479 if rev or node:
3478 raise error.Abort(_("can't specify a revision with --all"))
3480 raise error.Abort(_("can't specify a revision with --all"))
3479
3481
3480 res = []
3482 res = []
3481 prefix = "data/"
3483 prefix = "data/"
3482 suffix = ".i"
3484 suffix = ".i"
3483 plen = len(prefix)
3485 plen = len(prefix)
3484 slen = len(suffix)
3486 slen = len(suffix)
3485 with repo.lock():
3487 with repo.lock():
3486 for fn, b, size in repo.store.datafiles():
3488 for fn, b, size in repo.store.datafiles():
3487 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
3489 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
3488 res.append(fn[plen:-slen])
3490 res.append(fn[plen:-slen])
3489 for f in res:
3491 for f in res:
3490 fm.startitem()
3492 fm.startitem()
3491 fm.write("path", '%s\n', f)
3493 fm.write("path", '%s\n', f)
3492 fm.end()
3494 fm.end()
3493 return
3495 return
3494
3496
3495 if rev and node:
3497 if rev and node:
3496 raise error.Abort(_("please specify just one revision"))
3498 raise error.Abort(_("please specify just one revision"))
3497
3499
3498 if not node:
3500 if not node:
3499 node = rev
3501 node = rev
3500
3502
3501 char = {'l': '@', 'x': '*', '': ''}
3503 char = {'l': '@', 'x': '*', '': ''}
3502 mode = {'l': '644', 'x': '755', '': '644'}
3504 mode = {'l': '644', 'x': '755', '': '644'}
3503 ctx = scmutil.revsingle(repo, node)
3505 ctx = scmutil.revsingle(repo, node)
3504 mf = ctx.manifest()
3506 mf = ctx.manifest()
3505 for f in ctx:
3507 for f in ctx:
3506 fm.startitem()
3508 fm.startitem()
3507 fl = ctx[f].flags()
3509 fl = ctx[f].flags()
3508 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3510 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
3509 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3511 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
3510 fm.write('path', '%s\n', f)
3512 fm.write('path', '%s\n', f)
3511 fm.end()
3513 fm.end()
3512
3514
3513 @command('^merge',
3515 @command('^merge',
3514 [('f', 'force', None,
3516 [('f', 'force', None,
3515 _('force a merge including outstanding changes (DEPRECATED)')),
3517 _('force a merge including outstanding changes (DEPRECATED)')),
3516 ('r', 'rev', '', _('revision to merge'), _('REV')),
3518 ('r', 'rev', '', _('revision to merge'), _('REV')),
3517 ('P', 'preview', None,
3519 ('P', 'preview', None,
3518 _('review revisions to merge (no merge is performed)'))
3520 _('review revisions to merge (no merge is performed)'))
3519 ] + mergetoolopts,
3521 ] + mergetoolopts,
3520 _('[-P] [[-r] REV]'))
3522 _('[-P] [[-r] REV]'))
3521 def merge(ui, repo, node=None, **opts):
3523 def merge(ui, repo, node=None, **opts):
3522 """merge another revision into working directory
3524 """merge another revision into working directory
3523
3525
3524 The current working directory is updated with all changes made in
3526 The current working directory is updated with all changes made in
3525 the requested revision since the last common predecessor revision.
3527 the requested revision since the last common predecessor revision.
3526
3528
3527 Files that changed between either parent are marked as changed for
3529 Files that changed between either parent are marked as changed for
3528 the next commit and a commit must be performed before any further
3530 the next commit and a commit must be performed before any further
3529 updates to the repository are allowed. The next commit will have
3531 updates to the repository are allowed. The next commit will have
3530 two parents.
3532 two parents.
3531
3533
3532 ``--tool`` can be used to specify the merge tool used for file
3534 ``--tool`` can be used to specify the merge tool used for file
3533 merges. It overrides the HGMERGE environment variable and your
3535 merges. It overrides the HGMERGE environment variable and your
3534 configuration files. See :hg:`help merge-tools` for options.
3536 configuration files. See :hg:`help merge-tools` for options.
3535
3537
3536 If no revision is specified, the working directory's parent is a
3538 If no revision is specified, the working directory's parent is a
3537 head revision, and the current branch contains exactly one other
3539 head revision, and the current branch contains exactly one other
3538 head, the other head is merged with by default. Otherwise, an
3540 head, the other head is merged with by default. Otherwise, an
3539 explicit revision with which to merge with must be provided.
3541 explicit revision with which to merge with must be provided.
3540
3542
3541 See :hg:`help resolve` for information on handling file conflicts.
3543 See :hg:`help resolve` for information on handling file conflicts.
3542
3544
3543 To undo an uncommitted merge, use :hg:`update --clean .` which
3545 To undo an uncommitted merge, use :hg:`update --clean .` which
3544 will check out a clean copy of the original merge parent, losing
3546 will check out a clean copy of the original merge parent, losing
3545 all changes.
3547 all changes.
3546
3548
3547 Returns 0 on success, 1 if there are unresolved files.
3549 Returns 0 on success, 1 if there are unresolved files.
3548 """
3550 """
3549
3551
3550 if opts.get('rev') and node:
3552 if opts.get('rev') and node:
3551 raise error.Abort(_("please specify just one revision"))
3553 raise error.Abort(_("please specify just one revision"))
3552 if not node:
3554 if not node:
3553 node = opts.get('rev')
3555 node = opts.get('rev')
3554
3556
3555 if node:
3557 if node:
3556 node = scmutil.revsingle(repo, node).node()
3558 node = scmutil.revsingle(repo, node).node()
3557
3559
3558 if not node:
3560 if not node:
3559 node = repo[destutil.destmerge(repo)].node()
3561 node = repo[destutil.destmerge(repo)].node()
3560
3562
3561 if opts.get('preview'):
3563 if opts.get('preview'):
3562 # find nodes that are ancestors of p2 but not of p1
3564 # find nodes that are ancestors of p2 but not of p1
3563 p1 = repo.lookup('.')
3565 p1 = repo.lookup('.')
3564 p2 = repo.lookup(node)
3566 p2 = repo.lookup(node)
3565 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
3567 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
3566
3568
3567 displayer = cmdutil.show_changeset(ui, repo, opts)
3569 displayer = cmdutil.show_changeset(ui, repo, opts)
3568 for node in nodes:
3570 for node in nodes:
3569 displayer.show(repo[node])
3571 displayer.show(repo[node])
3570 displayer.close()
3572 displayer.close()
3571 return 0
3573 return 0
3572
3574
3573 try:
3575 try:
3574 # ui.forcemerge is an internal variable, do not document
3576 # ui.forcemerge is an internal variable, do not document
3575 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
3577 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
3576 force = opts.get('force')
3578 force = opts.get('force')
3577 labels = ['working copy', 'merge rev']
3579 labels = ['working copy', 'merge rev']
3578 return hg.merge(repo, node, force=force, mergeforce=force,
3580 return hg.merge(repo, node, force=force, mergeforce=force,
3579 labels=labels)
3581 labels=labels)
3580 finally:
3582 finally:
3581 ui.setconfig('ui', 'forcemerge', '', 'merge')
3583 ui.setconfig('ui', 'forcemerge', '', 'merge')
3582
3584
3583 @command('outgoing|out',
3585 @command('outgoing|out',
3584 [('f', 'force', None, _('run even when the destination is unrelated')),
3586 [('f', 'force', None, _('run even when the destination is unrelated')),
3585 ('r', 'rev', [],
3587 ('r', 'rev', [],
3586 _('a changeset intended to be included in the destination'), _('REV')),
3588 _('a changeset intended to be included in the destination'), _('REV')),
3587 ('n', 'newest-first', None, _('show newest record first')),
3589 ('n', 'newest-first', None, _('show newest record first')),
3588 ('B', 'bookmarks', False, _('compare bookmarks')),
3590 ('B', 'bookmarks', False, _('compare bookmarks')),
3589 ('b', 'branch', [], _('a specific branch you would like to push'),
3591 ('b', 'branch', [], _('a specific branch you would like to push'),
3590 _('BRANCH')),
3592 _('BRANCH')),
3591 ] + logopts + remoteopts + subrepoopts,
3593 ] + logopts + remoteopts + subrepoopts,
3592 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
3594 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
3593 def outgoing(ui, repo, dest=None, **opts):
3595 def outgoing(ui, repo, dest=None, **opts):
3594 """show changesets not found in the destination
3596 """show changesets not found in the destination
3595
3597
3596 Show changesets not found in the specified destination repository
3598 Show changesets not found in the specified destination repository
3597 or the default push location. These are the changesets that would
3599 or the default push location. These are the changesets that would
3598 be pushed if a push was requested.
3600 be pushed if a push was requested.
3599
3601
3600 See pull for details of valid destination formats.
3602 See pull for details of valid destination formats.
3601
3603
3602 .. container:: verbose
3604 .. container:: verbose
3603
3605
3604 With -B/--bookmarks, the result of bookmark comparison between
3606 With -B/--bookmarks, the result of bookmark comparison between
3605 local and remote repositories is displayed. With -v/--verbose,
3607 local and remote repositories is displayed. With -v/--verbose,
3606 status is also displayed for each bookmark like below::
3608 status is also displayed for each bookmark like below::
3607
3609
3608 BM1 01234567890a added
3610 BM1 01234567890a added
3609 BM2 deleted
3611 BM2 deleted
3610 BM3 234567890abc advanced
3612 BM3 234567890abc advanced
3611 BM4 34567890abcd diverged
3613 BM4 34567890abcd diverged
3612 BM5 4567890abcde changed
3614 BM5 4567890abcde changed
3613
3615
3614 The action taken when pushing depends on the
3616 The action taken when pushing depends on the
3615 status of each bookmark:
3617 status of each bookmark:
3616
3618
3617 :``added``: push with ``-B`` will create it
3619 :``added``: push with ``-B`` will create it
3618 :``deleted``: push with ``-B`` will delete it
3620 :``deleted``: push with ``-B`` will delete it
3619 :``advanced``: push will update it
3621 :``advanced``: push will update it
3620 :``diverged``: push with ``-B`` will update it
3622 :``diverged``: push with ``-B`` will update it
3621 :``changed``: push with ``-B`` will update it
3623 :``changed``: push with ``-B`` will update it
3622
3624
3623 From the point of view of pushing behavior, bookmarks
3625 From the point of view of pushing behavior, bookmarks
3624 existing only in the remote repository are treated as
3626 existing only in the remote repository are treated as
3625 ``deleted``, even if it is in fact added remotely.
3627 ``deleted``, even if it is in fact added remotely.
3626
3628
3627 Returns 0 if there are outgoing changes, 1 otherwise.
3629 Returns 0 if there are outgoing changes, 1 otherwise.
3628 """
3630 """
3629 if opts.get('graph'):
3631 if opts.get('graph'):
3630 cmdutil.checkunsupportedgraphflags([], opts)
3632 cmdutil.checkunsupportedgraphflags([], opts)
3631 o, other = hg._outgoing(ui, repo, dest, opts)
3633 o, other = hg._outgoing(ui, repo, dest, opts)
3632 if not o:
3634 if not o:
3633 cmdutil.outgoinghooks(ui, repo, other, opts, o)
3635 cmdutil.outgoinghooks(ui, repo, other, opts, o)
3634 return
3636 return
3635
3637
3636 revdag = cmdutil.graphrevs(repo, o, opts)
3638 revdag = cmdutil.graphrevs(repo, o, opts)
3637 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
3639 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
3638 cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
3640 cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges)
3639 cmdutil.outgoinghooks(ui, repo, other, opts, o)
3641 cmdutil.outgoinghooks(ui, repo, other, opts, o)
3640 return 0
3642 return 0
3641
3643
3642 if opts.get('bookmarks'):
3644 if opts.get('bookmarks'):
3643 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3645 dest = ui.expandpath(dest or 'default-push', dest or 'default')
3644 dest, branches = hg.parseurl(dest, opts.get('branch'))
3646 dest, branches = hg.parseurl(dest, opts.get('branch'))
3645 other = hg.peer(repo, opts, dest)
3647 other = hg.peer(repo, opts, dest)
3646 if 'bookmarks' not in other.listkeys('namespaces'):
3648 if 'bookmarks' not in other.listkeys('namespaces'):
3647 ui.warn(_("remote doesn't support bookmarks\n"))
3649 ui.warn(_("remote doesn't support bookmarks\n"))
3648 return 0
3650 return 0
3649 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
3651 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
3650 return bookmarks.outgoing(ui, repo, other)
3652 return bookmarks.outgoing(ui, repo, other)
3651
3653
3652 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
3654 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
3653 try:
3655 try:
3654 return hg.outgoing(ui, repo, dest, opts)
3656 return hg.outgoing(ui, repo, dest, opts)
3655 finally:
3657 finally:
3656 del repo._subtoppath
3658 del repo._subtoppath
3657
3659
3658 @command('parents',
3660 @command('parents',
3659 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
3661 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
3660 ] + templateopts,
3662 ] + templateopts,
3661 _('[-r REV] [FILE]'),
3663 _('[-r REV] [FILE]'),
3662 inferrepo=True)
3664 inferrepo=True)
3663 def parents(ui, repo, file_=None, **opts):
3665 def parents(ui, repo, file_=None, **opts):
3664 """show the parents of the working directory or revision (DEPRECATED)
3666 """show the parents of the working directory or revision (DEPRECATED)
3665
3667
3666 Print the working directory's parent revisions. If a revision is
3668 Print the working directory's parent revisions. If a revision is
3667 given via -r/--rev, the parent of that revision will be printed.
3669 given via -r/--rev, the parent of that revision will be printed.
3668 If a file argument is given, the revision in which the file was
3670 If a file argument is given, the revision in which the file was
3669 last changed (before the working directory revision or the
3671 last changed (before the working directory revision or the
3670 argument to --rev if given) is printed.
3672 argument to --rev if given) is printed.
3671
3673
3672 This command is equivalent to::
3674 This command is equivalent to::
3673
3675
3674 hg log -r "p1()+p2()" or
3676 hg log -r "p1()+p2()" or
3675 hg log -r "p1(REV)+p2(REV)" or
3677 hg log -r "p1(REV)+p2(REV)" or
3676 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
3678 hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
3677 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
3679 hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
3678
3680
3679 See :hg:`summary` and :hg:`help revsets` for related information.
3681 See :hg:`summary` and :hg:`help revsets` for related information.
3680
3682
3681 Returns 0 on success.
3683 Returns 0 on success.
3682 """
3684 """
3683
3685
3684 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3686 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3685
3687
3686 if file_:
3688 if file_:
3687 m = scmutil.match(ctx, (file_,), opts)
3689 m = scmutil.match(ctx, (file_,), opts)
3688 if m.anypats() or len(m.files()) != 1:
3690 if m.anypats() or len(m.files()) != 1:
3689 raise error.Abort(_('can only specify an explicit filename'))
3691 raise error.Abort(_('can only specify an explicit filename'))
3690 file_ = m.files()[0]
3692 file_ = m.files()[0]
3691 filenodes = []
3693 filenodes = []
3692 for cp in ctx.parents():
3694 for cp in ctx.parents():
3693 if not cp:
3695 if not cp:
3694 continue
3696 continue
3695 try:
3697 try:
3696 filenodes.append(cp.filenode(file_))
3698 filenodes.append(cp.filenode(file_))
3697 except error.LookupError:
3699 except error.LookupError:
3698 pass
3700 pass
3699 if not filenodes:
3701 if not filenodes:
3700 raise error.Abort(_("'%s' not found in manifest!") % file_)
3702 raise error.Abort(_("'%s' not found in manifest!") % file_)
3701 p = []
3703 p = []
3702 for fn in filenodes:
3704 for fn in filenodes:
3703 fctx = repo.filectx(file_, fileid=fn)
3705 fctx = repo.filectx(file_, fileid=fn)
3704 p.append(fctx.node())
3706 p.append(fctx.node())
3705 else:
3707 else:
3706 p = [cp.node() for cp in ctx.parents()]
3708 p = [cp.node() for cp in ctx.parents()]
3707
3709
3708 displayer = cmdutil.show_changeset(ui, repo, opts)
3710 displayer = cmdutil.show_changeset(ui, repo, opts)
3709 for n in p:
3711 for n in p:
3710 if n != nullid:
3712 if n != nullid:
3711 displayer.show(repo[n])
3713 displayer.show(repo[n])
3712 displayer.close()
3714 displayer.close()
3713
3715
3714 @command('paths', formatteropts, _('[NAME]'), optionalrepo=True)
3716 @command('paths', formatteropts, _('[NAME]'), optionalrepo=True)
3715 def paths(ui, repo, search=None, **opts):
3717 def paths(ui, repo, search=None, **opts):
3716 """show aliases for remote repositories
3718 """show aliases for remote repositories
3717
3719
3718 Show definition of symbolic path name NAME. If no name is given,
3720 Show definition of symbolic path name NAME. If no name is given,
3719 show definition of all available names.
3721 show definition of all available names.
3720
3722
3721 Option -q/--quiet suppresses all output when searching for NAME
3723 Option -q/--quiet suppresses all output when searching for NAME
3722 and shows only the path names when listing all definitions.
3724 and shows only the path names when listing all definitions.
3723
3725
3724 Path names are defined in the [paths] section of your
3726 Path names are defined in the [paths] section of your
3725 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
3727 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
3726 repository, ``.hg/hgrc`` is used, too.
3728 repository, ``.hg/hgrc`` is used, too.
3727
3729
3728 The path names ``default`` and ``default-push`` have a special
3730 The path names ``default`` and ``default-push`` have a special
3729 meaning. When performing a push or pull operation, they are used
3731 meaning. When performing a push or pull operation, they are used
3730 as fallbacks if no location is specified on the command-line.
3732 as fallbacks if no location is specified on the command-line.
3731 When ``default-push`` is set, it will be used for push and
3733 When ``default-push`` is set, it will be used for push and
3732 ``default`` will be used for pull; otherwise ``default`` is used
3734 ``default`` will be used for pull; otherwise ``default`` is used
3733 as the fallback for both. When cloning a repository, the clone
3735 as the fallback for both. When cloning a repository, the clone
3734 source is written as ``default`` in ``.hg/hgrc``.
3736 source is written as ``default`` in ``.hg/hgrc``.
3735
3737
3736 .. note::
3738 .. note::
3737
3739
3738 ``default`` and ``default-push`` apply to all inbound (e.g.
3740 ``default`` and ``default-push`` apply to all inbound (e.g.
3739 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
3741 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email`
3740 and :hg:`bundle`) operations.
3742 and :hg:`bundle`) operations.
3741
3743
3742 See :hg:`help urls` for more information.
3744 See :hg:`help urls` for more information.
3743
3745
3744 Returns 0 on success.
3746 Returns 0 on success.
3745 """
3747 """
3746 if search:
3748 if search:
3747 pathitems = [(name, path) for name, path in ui.paths.iteritems()
3749 pathitems = [(name, path) for name, path in ui.paths.iteritems()
3748 if name == search]
3750 if name == search]
3749 else:
3751 else:
3750 pathitems = sorted(ui.paths.iteritems())
3752 pathitems = sorted(ui.paths.iteritems())
3751
3753
3752 fm = ui.formatter('paths', opts)
3754 fm = ui.formatter('paths', opts)
3753 if fm.isplain():
3755 if fm.isplain():
3754 hidepassword = util.hidepassword
3756 hidepassword = util.hidepassword
3755 else:
3757 else:
3756 hidepassword = str
3758 hidepassword = str
3757 if ui.quiet:
3759 if ui.quiet:
3758 namefmt = '%s\n'
3760 namefmt = '%s\n'
3759 else:
3761 else:
3760 namefmt = '%s = '
3762 namefmt = '%s = '
3761 showsubopts = not search and not ui.quiet
3763 showsubopts = not search and not ui.quiet
3762
3764
3763 for name, path in pathitems:
3765 for name, path in pathitems:
3764 fm.startitem()
3766 fm.startitem()
3765 fm.condwrite(not search, 'name', namefmt, name)
3767 fm.condwrite(not search, 'name', namefmt, name)
3766 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
3768 fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
3767 for subopt, value in sorted(path.suboptions.items()):
3769 for subopt, value in sorted(path.suboptions.items()):
3768 assert subopt not in ('name', 'url')
3770 assert subopt not in ('name', 'url')
3769 if showsubopts:
3771 if showsubopts:
3770 fm.plain('%s:%s = ' % (name, subopt))
3772 fm.plain('%s:%s = ' % (name, subopt))
3771 fm.condwrite(showsubopts, subopt, '%s\n', value)
3773 fm.condwrite(showsubopts, subopt, '%s\n', value)
3772
3774
3773 fm.end()
3775 fm.end()
3774
3776
3775 if search and not pathitems:
3777 if search and not pathitems:
3776 if not ui.quiet:
3778 if not ui.quiet:
3777 ui.warn(_("not found!\n"))
3779 ui.warn(_("not found!\n"))
3778 return 1
3780 return 1
3779 else:
3781 else:
3780 return 0
3782 return 0
3781
3783
3782 @command('phase',
3784 @command('phase',
3783 [('p', 'public', False, _('set changeset phase to public')),
3785 [('p', 'public', False, _('set changeset phase to public')),
3784 ('d', 'draft', False, _('set changeset phase to draft')),
3786 ('d', 'draft', False, _('set changeset phase to draft')),
3785 ('s', 'secret', False, _('set changeset phase to secret')),
3787 ('s', 'secret', False, _('set changeset phase to secret')),
3786 ('f', 'force', False, _('allow to move boundary backward')),
3788 ('f', 'force', False, _('allow to move boundary backward')),
3787 ('r', 'rev', [], _('target revision'), _('REV')),
3789 ('r', 'rev', [], _('target revision'), _('REV')),
3788 ],
3790 ],
3789 _('[-p|-d|-s] [-f] [-r] [REV...]'))
3791 _('[-p|-d|-s] [-f] [-r] [REV...]'))
3790 def phase(ui, repo, *revs, **opts):
3792 def phase(ui, repo, *revs, **opts):
3791 """set or show the current phase name
3793 """set or show the current phase name
3792
3794
3793 With no argument, show the phase name of the current revision(s).
3795 With no argument, show the phase name of the current revision(s).
3794
3796
3795 With one of -p/--public, -d/--draft or -s/--secret, change the
3797 With one of -p/--public, -d/--draft or -s/--secret, change the
3796 phase value of the specified revisions.
3798 phase value of the specified revisions.
3797
3799
3798 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
3800 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
3799 lower phase to an higher phase. Phases are ordered as follows::
3801 lower phase to an higher phase. Phases are ordered as follows::
3800
3802
3801 public < draft < secret
3803 public < draft < secret
3802
3804
3803 Returns 0 on success, 1 if some phases could not be changed.
3805 Returns 0 on success, 1 if some phases could not be changed.
3804
3806
3805 (For more information about the phases concept, see :hg:`help phases`.)
3807 (For more information about the phases concept, see :hg:`help phases`.)
3806 """
3808 """
3807 # search for a unique phase argument
3809 # search for a unique phase argument
3808 targetphase = None
3810 targetphase = None
3809 for idx, name in enumerate(phases.phasenames):
3811 for idx, name in enumerate(phases.phasenames):
3810 if opts[name]:
3812 if opts[name]:
3811 if targetphase is not None:
3813 if targetphase is not None:
3812 raise error.Abort(_('only one phase can be specified'))
3814 raise error.Abort(_('only one phase can be specified'))
3813 targetphase = idx
3815 targetphase = idx
3814
3816
3815 # look for specified revision
3817 # look for specified revision
3816 revs = list(revs)
3818 revs = list(revs)
3817 revs.extend(opts['rev'])
3819 revs.extend(opts['rev'])
3818 if not revs:
3820 if not revs:
3819 # display both parents as the second parent phase can influence
3821 # display both parents as the second parent phase can influence
3820 # the phase of a merge commit
3822 # the phase of a merge commit
3821 revs = [c.rev() for c in repo[None].parents()]
3823 revs = [c.rev() for c in repo[None].parents()]
3822
3824
3823 revs = scmutil.revrange(repo, revs)
3825 revs = scmutil.revrange(repo, revs)
3824
3826
3825 lock = None
3827 lock = None
3826 ret = 0
3828 ret = 0
3827 if targetphase is None:
3829 if targetphase is None:
3828 # display
3830 # display
3829 for r in revs:
3831 for r in revs:
3830 ctx = repo[r]
3832 ctx = repo[r]
3831 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
3833 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
3832 else:
3834 else:
3833 tr = None
3835 tr = None
3834 lock = repo.lock()
3836 lock = repo.lock()
3835 try:
3837 try:
3836 tr = repo.transaction("phase")
3838 tr = repo.transaction("phase")
3837 # set phase
3839 # set phase
3838 if not revs:
3840 if not revs:
3839 raise error.Abort(_('empty revision set'))
3841 raise error.Abort(_('empty revision set'))
3840 nodes = [repo[r].node() for r in revs]
3842 nodes = [repo[r].node() for r in revs]
3841 # moving revision from public to draft may hide them
3843 # moving revision from public to draft may hide them
3842 # We have to check result on an unfiltered repository
3844 # We have to check result on an unfiltered repository
3843 unfi = repo.unfiltered()
3845 unfi = repo.unfiltered()
3844 getphase = unfi._phasecache.phase
3846 getphase = unfi._phasecache.phase
3845 olddata = [getphase(unfi, r) for r in unfi]
3847 olddata = [getphase(unfi, r) for r in unfi]
3846 phases.advanceboundary(repo, tr, targetphase, nodes)
3848 phases.advanceboundary(repo, tr, targetphase, nodes)
3847 if opts['force']:
3849 if opts['force']:
3848 phases.retractboundary(repo, tr, targetphase, nodes)
3850 phases.retractboundary(repo, tr, targetphase, nodes)
3849 tr.close()
3851 tr.close()
3850 finally:
3852 finally:
3851 if tr is not None:
3853 if tr is not None:
3852 tr.release()
3854 tr.release()
3853 lock.release()
3855 lock.release()
3854 getphase = unfi._phasecache.phase
3856 getphase = unfi._phasecache.phase
3855 newdata = [getphase(unfi, r) for r in unfi]
3857 newdata = [getphase(unfi, r) for r in unfi]
3856 changes = sum(newdata[r] != olddata[r] for r in unfi)
3858 changes = sum(newdata[r] != olddata[r] for r in unfi)
3857 cl = unfi.changelog
3859 cl = unfi.changelog
3858 rejected = [n for n in nodes
3860 rejected = [n for n in nodes
3859 if newdata[cl.rev(n)] < targetphase]
3861 if newdata[cl.rev(n)] < targetphase]
3860 if rejected:
3862 if rejected:
3861 ui.warn(_('cannot move %i changesets to a higher '
3863 ui.warn(_('cannot move %i changesets to a higher '
3862 'phase, use --force\n') % len(rejected))
3864 'phase, use --force\n') % len(rejected))
3863 ret = 1
3865 ret = 1
3864 if changes:
3866 if changes:
3865 msg = _('phase changed for %i changesets\n') % changes
3867 msg = _('phase changed for %i changesets\n') % changes
3866 if ret:
3868 if ret:
3867 ui.status(msg)
3869 ui.status(msg)
3868 else:
3870 else:
3869 ui.note(msg)
3871 ui.note(msg)
3870 else:
3872 else:
3871 ui.warn(_('no phases changed\n'))
3873 ui.warn(_('no phases changed\n'))
3872 return ret
3874 return ret
3873
3875
3874 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
3876 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
3875 """Run after a changegroup has been added via pull/unbundle
3877 """Run after a changegroup has been added via pull/unbundle
3876
3878
3877 This takes arguments below:
3879 This takes arguments below:
3878
3880
3879 :modheads: change of heads by pull/unbundle
3881 :modheads: change of heads by pull/unbundle
3880 :optupdate: updating working directory is needed or not
3882 :optupdate: updating working directory is needed or not
3881 :checkout: update destination revision (or None to default destination)
3883 :checkout: update destination revision (or None to default destination)
3882 :brev: a name, which might be a bookmark to be activated after updating
3884 :brev: a name, which might be a bookmark to be activated after updating
3883 """
3885 """
3884 if modheads == 0:
3886 if modheads == 0:
3885 return
3887 return
3886 if optupdate:
3888 if optupdate:
3887 try:
3889 try:
3888 return hg.updatetotally(ui, repo, checkout, brev)
3890 return hg.updatetotally(ui, repo, checkout, brev)
3889 except error.UpdateAbort as inst:
3891 except error.UpdateAbort as inst:
3890 msg = _("not updating: %s") % str(inst)
3892 msg = _("not updating: %s") % str(inst)
3891 hint = inst.hint
3893 hint = inst.hint
3892 raise error.UpdateAbort(msg, hint=hint)
3894 raise error.UpdateAbort(msg, hint=hint)
3893 if modheads > 1:
3895 if modheads > 1:
3894 currentbranchheads = len(repo.branchheads())
3896 currentbranchheads = len(repo.branchheads())
3895 if currentbranchheads == modheads:
3897 if currentbranchheads == modheads:
3896 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
3898 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
3897 elif currentbranchheads > 1:
3899 elif currentbranchheads > 1:
3898 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
3900 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
3899 "merge)\n"))
3901 "merge)\n"))
3900 else:
3902 else:
3901 ui.status(_("(run 'hg heads' to see heads)\n"))
3903 ui.status(_("(run 'hg heads' to see heads)\n"))
3902 else:
3904 else:
3903 ui.status(_("(run 'hg update' to get a working copy)\n"))
3905 ui.status(_("(run 'hg update' to get a working copy)\n"))
3904
3906
3905 @command('^pull',
3907 @command('^pull',
3906 [('u', 'update', None,
3908 [('u', 'update', None,
3907 _('update to new branch head if changesets were pulled')),
3909 _('update to new branch head if changesets were pulled')),
3908 ('f', 'force', None, _('run even when remote repository is unrelated')),
3910 ('f', 'force', None, _('run even when remote repository is unrelated')),
3909 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3911 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3910 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
3912 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
3911 ('b', 'branch', [], _('a specific branch you would like to pull'),
3913 ('b', 'branch', [], _('a specific branch you would like to pull'),
3912 _('BRANCH')),
3914 _('BRANCH')),
3913 ] + remoteopts,
3915 ] + remoteopts,
3914 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
3916 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
3915 def pull(ui, repo, source="default", **opts):
3917 def pull(ui, repo, source="default", **opts):
3916 """pull changes from the specified source
3918 """pull changes from the specified source
3917
3919
3918 Pull changes from a remote repository to a local one.
3920 Pull changes from a remote repository to a local one.
3919
3921
3920 This finds all changes from the repository at the specified path
3922 This finds all changes from the repository at the specified path
3921 or URL and adds them to a local repository (the current one unless
3923 or URL and adds them to a local repository (the current one unless
3922 -R is specified). By default, this does not update the copy of the
3924 -R is specified). By default, this does not update the copy of the
3923 project in the working directory.
3925 project in the working directory.
3924
3926
3925 Use :hg:`incoming` if you want to see what would have been added
3927 Use :hg:`incoming` if you want to see what would have been added
3926 by a pull at the time you issued this command. If you then decide
3928 by a pull at the time you issued this command. If you then decide
3927 to add those changes to the repository, you should use :hg:`pull
3929 to add those changes to the repository, you should use :hg:`pull
3928 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
3930 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
3929
3931
3930 If SOURCE is omitted, the 'default' path will be used.
3932 If SOURCE is omitted, the 'default' path will be used.
3931 See :hg:`help urls` for more information.
3933 See :hg:`help urls` for more information.
3932
3934
3933 Specifying bookmark as ``.`` is equivalent to specifying the active
3935 Specifying bookmark as ``.`` is equivalent to specifying the active
3934 bookmark's name.
3936 bookmark's name.
3935
3937
3936 Returns 0 on success, 1 if an update had unresolved files.
3938 Returns 0 on success, 1 if an update had unresolved files.
3937 """
3939 """
3938 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
3940 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
3939 ui.status(_('pulling from %s\n') % util.hidepassword(source))
3941 ui.status(_('pulling from %s\n') % util.hidepassword(source))
3940 other = hg.peer(repo, opts, source)
3942 other = hg.peer(repo, opts, source)
3941 try:
3943 try:
3942 revs, checkout = hg.addbranchrevs(repo, other, branches,
3944 revs, checkout = hg.addbranchrevs(repo, other, branches,
3943 opts.get('rev'))
3945 opts.get('rev'))
3944
3946
3945
3947
3946 pullopargs = {}
3948 pullopargs = {}
3947 if opts.get('bookmark'):
3949 if opts.get('bookmark'):
3948 if not revs:
3950 if not revs:
3949 revs = []
3951 revs = []
3950 # The list of bookmark used here is not the one used to actually
3952 # The list of bookmark used here is not the one used to actually
3951 # update the bookmark name. This can result in the revision pulled
3953 # update the bookmark name. This can result in the revision pulled
3952 # not ending up with the name of the bookmark because of a race
3954 # not ending up with the name of the bookmark because of a race
3953 # condition on the server. (See issue 4689 for details)
3955 # condition on the server. (See issue 4689 for details)
3954 remotebookmarks = other.listkeys('bookmarks')
3956 remotebookmarks = other.listkeys('bookmarks')
3955 pullopargs['remotebookmarks'] = remotebookmarks
3957 pullopargs['remotebookmarks'] = remotebookmarks
3956 for b in opts['bookmark']:
3958 for b in opts['bookmark']:
3957 b = repo._bookmarks.expandname(b)
3959 b = repo._bookmarks.expandname(b)
3958 if b not in remotebookmarks:
3960 if b not in remotebookmarks:
3959 raise error.Abort(_('remote bookmark %s not found!') % b)
3961 raise error.Abort(_('remote bookmark %s not found!') % b)
3960 revs.append(remotebookmarks[b])
3962 revs.append(remotebookmarks[b])
3961
3963
3962 if revs:
3964 if revs:
3963 try:
3965 try:
3964 # When 'rev' is a bookmark name, we cannot guarantee that it
3966 # When 'rev' is a bookmark name, we cannot guarantee that it
3965 # will be updated with that name because of a race condition
3967 # will be updated with that name because of a race condition
3966 # server side. (See issue 4689 for details)
3968 # server side. (See issue 4689 for details)
3967 oldrevs = revs
3969 oldrevs = revs
3968 revs = [] # actually, nodes
3970 revs = [] # actually, nodes
3969 for r in oldrevs:
3971 for r in oldrevs:
3970 node = other.lookup(r)
3972 node = other.lookup(r)
3971 revs.append(node)
3973 revs.append(node)
3972 if r == checkout:
3974 if r == checkout:
3973 checkout = node
3975 checkout = node
3974 except error.CapabilityError:
3976 except error.CapabilityError:
3975 err = _("other repository doesn't support revision lookup, "
3977 err = _("other repository doesn't support revision lookup, "
3976 "so a rev cannot be specified.")
3978 "so a rev cannot be specified.")
3977 raise error.Abort(err)
3979 raise error.Abort(err)
3978
3980
3979 pullopargs.update(opts.get('opargs', {}))
3981 pullopargs.update(opts.get('opargs', {}))
3980 modheads = exchange.pull(repo, other, heads=revs,
3982 modheads = exchange.pull(repo, other, heads=revs,
3981 force=opts.get('force'),
3983 force=opts.get('force'),
3982 bookmarks=opts.get('bookmark', ()),
3984 bookmarks=opts.get('bookmark', ()),
3983 opargs=pullopargs).cgresult
3985 opargs=pullopargs).cgresult
3984
3986
3985 # brev is a name, which might be a bookmark to be activated at
3987 # brev is a name, which might be a bookmark to be activated at
3986 # the end of the update. In other words, it is an explicit
3988 # the end of the update. In other words, it is an explicit
3987 # destination of the update
3989 # destination of the update
3988 brev = None
3990 brev = None
3989
3991
3990 if checkout:
3992 if checkout:
3991 checkout = str(repo.changelog.rev(checkout))
3993 checkout = str(repo.changelog.rev(checkout))
3992
3994
3993 # order below depends on implementation of
3995 # order below depends on implementation of
3994 # hg.addbranchrevs(). opts['bookmark'] is ignored,
3996 # hg.addbranchrevs(). opts['bookmark'] is ignored,
3995 # because 'checkout' is determined without it.
3997 # because 'checkout' is determined without it.
3996 if opts.get('rev'):
3998 if opts.get('rev'):
3997 brev = opts['rev'][0]
3999 brev = opts['rev'][0]
3998 elif opts.get('branch'):
4000 elif opts.get('branch'):
3999 brev = opts['branch'][0]
4001 brev = opts['branch'][0]
4000 else:
4002 else:
4001 brev = branches[0]
4003 brev = branches[0]
4002 repo._subtoppath = source
4004 repo._subtoppath = source
4003 try:
4005 try:
4004 ret = postincoming(ui, repo, modheads, opts.get('update'),
4006 ret = postincoming(ui, repo, modheads, opts.get('update'),
4005 checkout, brev)
4007 checkout, brev)
4006
4008
4007 finally:
4009 finally:
4008 del repo._subtoppath
4010 del repo._subtoppath
4009
4011
4010 finally:
4012 finally:
4011 other.close()
4013 other.close()
4012 return ret
4014 return ret
4013
4015
4014 @command('^push',
4016 @command('^push',
4015 [('f', 'force', None, _('force push')),
4017 [('f', 'force', None, _('force push')),
4016 ('r', 'rev', [],
4018 ('r', 'rev', [],
4017 _('a changeset intended to be included in the destination'),
4019 _('a changeset intended to be included in the destination'),
4018 _('REV')),
4020 _('REV')),
4019 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4021 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4020 ('b', 'branch', [],
4022 ('b', 'branch', [],
4021 _('a specific branch you would like to push'), _('BRANCH')),
4023 _('a specific branch you would like to push'), _('BRANCH')),
4022 ('', 'new-branch', False, _('allow pushing a new branch')),
4024 ('', 'new-branch', False, _('allow pushing a new branch')),
4023 ] + remoteopts,
4025 ] + remoteopts,
4024 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4026 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4025 def push(ui, repo, dest=None, **opts):
4027 def push(ui, repo, dest=None, **opts):
4026 """push changes to the specified destination
4028 """push changes to the specified destination
4027
4029
4028 Push changesets from the local repository to the specified
4030 Push changesets from the local repository to the specified
4029 destination.
4031 destination.
4030
4032
4031 This operation is symmetrical to pull: it is identical to a pull
4033 This operation is symmetrical to pull: it is identical to a pull
4032 in the destination repository from the current one.
4034 in the destination repository from the current one.
4033
4035
4034 By default, push will not allow creation of new heads at the
4036 By default, push will not allow creation of new heads at the
4035 destination, since multiple heads would make it unclear which head
4037 destination, since multiple heads would make it unclear which head
4036 to use. In this situation, it is recommended to pull and merge
4038 to use. In this situation, it is recommended to pull and merge
4037 before pushing.
4039 before pushing.
4038
4040
4039 Use --new-branch if you want to allow push to create a new named
4041 Use --new-branch if you want to allow push to create a new named
4040 branch that is not present at the destination. This allows you to
4042 branch that is not present at the destination. This allows you to
4041 only create a new branch without forcing other changes.
4043 only create a new branch without forcing other changes.
4042
4044
4043 .. note::
4045 .. note::
4044
4046
4045 Extra care should be taken with the -f/--force option,
4047 Extra care should be taken with the -f/--force option,
4046 which will push all new heads on all branches, an action which will
4048 which will push all new heads on all branches, an action which will
4047 almost always cause confusion for collaborators.
4049 almost always cause confusion for collaborators.
4048
4050
4049 If -r/--rev is used, the specified revision and all its ancestors
4051 If -r/--rev is used, the specified revision and all its ancestors
4050 will be pushed to the remote repository.
4052 will be pushed to the remote repository.
4051
4053
4052 If -B/--bookmark is used, the specified bookmarked revision, its
4054 If -B/--bookmark is used, the specified bookmarked revision, its
4053 ancestors, and the bookmark will be pushed to the remote
4055 ancestors, and the bookmark will be pushed to the remote
4054 repository. Specifying ``.`` is equivalent to specifying the active
4056 repository. Specifying ``.`` is equivalent to specifying the active
4055 bookmark's name.
4057 bookmark's name.
4056
4058
4057 Please see :hg:`help urls` for important details about ``ssh://``
4059 Please see :hg:`help urls` for important details about ``ssh://``
4058 URLs. If DESTINATION is omitted, a default path will be used.
4060 URLs. If DESTINATION is omitted, a default path will be used.
4059
4061
4060 Returns 0 if push was successful, 1 if nothing to push.
4062 Returns 0 if push was successful, 1 if nothing to push.
4061 """
4063 """
4062
4064
4063 if opts.get('bookmark'):
4065 if opts.get('bookmark'):
4064 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4066 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4065 for b in opts['bookmark']:
4067 for b in opts['bookmark']:
4066 # translate -B options to -r so changesets get pushed
4068 # translate -B options to -r so changesets get pushed
4067 b = repo._bookmarks.expandname(b)
4069 b = repo._bookmarks.expandname(b)
4068 if b in repo._bookmarks:
4070 if b in repo._bookmarks:
4069 opts.setdefault('rev', []).append(b)
4071 opts.setdefault('rev', []).append(b)
4070 else:
4072 else:
4071 # if we try to push a deleted bookmark, translate it to null
4073 # if we try to push a deleted bookmark, translate it to null
4072 # this lets simultaneous -r, -b options continue working
4074 # this lets simultaneous -r, -b options continue working
4073 opts.setdefault('rev', []).append("null")
4075 opts.setdefault('rev', []).append("null")
4074
4076
4075 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4077 path = ui.paths.getpath(dest, default=('default-push', 'default'))
4076 if not path:
4078 if not path:
4077 raise error.Abort(_('default repository not configured!'),
4079 raise error.Abort(_('default repository not configured!'),
4078 hint=_("see 'hg help config.paths'"))
4080 hint=_("see 'hg help config.paths'"))
4079 dest = path.pushloc or path.loc
4081 dest = path.pushloc or path.loc
4080 branches = (path.branch, opts.get('branch') or [])
4082 branches = (path.branch, opts.get('branch') or [])
4081 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4083 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4082 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4084 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4083 other = hg.peer(repo, opts, dest)
4085 other = hg.peer(repo, opts, dest)
4084
4086
4085 if revs:
4087 if revs:
4086 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
4088 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
4087 if not revs:
4089 if not revs:
4088 raise error.Abort(_("specified revisions evaluate to an empty set"),
4090 raise error.Abort(_("specified revisions evaluate to an empty set"),
4089 hint=_("use different revision arguments"))
4091 hint=_("use different revision arguments"))
4090 elif path.pushrev:
4092 elif path.pushrev:
4091 # It doesn't make any sense to specify ancestor revisions. So limit
4093 # It doesn't make any sense to specify ancestor revisions. So limit
4092 # to DAG heads to make discovery simpler.
4094 # to DAG heads to make discovery simpler.
4093 expr = revset.formatspec('heads(%r)', path.pushrev)
4095 expr = revset.formatspec('heads(%r)', path.pushrev)
4094 revs = scmutil.revrange(repo, [expr])
4096 revs = scmutil.revrange(repo, [expr])
4095 revs = [repo[rev].node() for rev in revs]
4097 revs = [repo[rev].node() for rev in revs]
4096 if not revs:
4098 if not revs:
4097 raise error.Abort(_('default push revset for path evaluates to an '
4099 raise error.Abort(_('default push revset for path evaluates to an '
4098 'empty set'))
4100 'empty set'))
4099
4101
4100 repo._subtoppath = dest
4102 repo._subtoppath = dest
4101 try:
4103 try:
4102 # push subrepos depth-first for coherent ordering
4104 # push subrepos depth-first for coherent ordering
4103 c = repo['']
4105 c = repo['']
4104 subs = c.substate # only repos that are committed
4106 subs = c.substate # only repos that are committed
4105 for s in sorted(subs):
4107 for s in sorted(subs):
4106 result = c.sub(s).push(opts)
4108 result = c.sub(s).push(opts)
4107 if result == 0:
4109 if result == 0:
4108 return not result
4110 return not result
4109 finally:
4111 finally:
4110 del repo._subtoppath
4112 del repo._subtoppath
4111 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4113 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
4112 newbranch=opts.get('new_branch'),
4114 newbranch=opts.get('new_branch'),
4113 bookmarks=opts.get('bookmark', ()),
4115 bookmarks=opts.get('bookmark', ()),
4114 opargs=opts.get('opargs'))
4116 opargs=opts.get('opargs'))
4115
4117
4116 result = not pushop.cgresult
4118 result = not pushop.cgresult
4117
4119
4118 if pushop.bkresult is not None:
4120 if pushop.bkresult is not None:
4119 if pushop.bkresult == 2:
4121 if pushop.bkresult == 2:
4120 result = 2
4122 result = 2
4121 elif not result and pushop.bkresult:
4123 elif not result and pushop.bkresult:
4122 result = 2
4124 result = 2
4123
4125
4124 return result
4126 return result
4125
4127
4126 @command('recover', [])
4128 @command('recover', [])
4127 def recover(ui, repo):
4129 def recover(ui, repo):
4128 """roll back an interrupted transaction
4130 """roll back an interrupted transaction
4129
4131
4130 Recover from an interrupted commit or pull.
4132 Recover from an interrupted commit or pull.
4131
4133
4132 This command tries to fix the repository status after an
4134 This command tries to fix the repository status after an
4133 interrupted operation. It should only be necessary when Mercurial
4135 interrupted operation. It should only be necessary when Mercurial
4134 suggests it.
4136 suggests it.
4135
4137
4136 Returns 0 if successful, 1 if nothing to recover or verify fails.
4138 Returns 0 if successful, 1 if nothing to recover or verify fails.
4137 """
4139 """
4138 if repo.recover():
4140 if repo.recover():
4139 return hg.verify(repo)
4141 return hg.verify(repo)
4140 return 1
4142 return 1
4141
4143
4142 @command('^remove|rm',
4144 @command('^remove|rm',
4143 [('A', 'after', None, _('record delete for missing files')),
4145 [('A', 'after', None, _('record delete for missing files')),
4144 ('f', 'force', None,
4146 ('f', 'force', None,
4145 _('forget added files, delete modified files')),
4147 _('forget added files, delete modified files')),
4146 ] + subrepoopts + walkopts,
4148 ] + subrepoopts + walkopts,
4147 _('[OPTION]... FILE...'),
4149 _('[OPTION]... FILE...'),
4148 inferrepo=True)
4150 inferrepo=True)
4149 def remove(ui, repo, *pats, **opts):
4151 def remove(ui, repo, *pats, **opts):
4150 """remove the specified files on the next commit
4152 """remove the specified files on the next commit
4151
4153
4152 Schedule the indicated files for removal from the current branch.
4154 Schedule the indicated files for removal from the current branch.
4153
4155
4154 This command schedules the files to be removed at the next commit.
4156 This command schedules the files to be removed at the next commit.
4155 To undo a remove before that, see :hg:`revert`. To undo added
4157 To undo a remove before that, see :hg:`revert`. To undo added
4156 files, see :hg:`forget`.
4158 files, see :hg:`forget`.
4157
4159
4158 .. container:: verbose
4160 .. container:: verbose
4159
4161
4160 -A/--after can be used to remove only files that have already
4162 -A/--after can be used to remove only files that have already
4161 been deleted, -f/--force can be used to force deletion, and -Af
4163 been deleted, -f/--force can be used to force deletion, and -Af
4162 can be used to remove files from the next revision without
4164 can be used to remove files from the next revision without
4163 deleting them from the working directory.
4165 deleting them from the working directory.
4164
4166
4165 The following table details the behavior of remove for different
4167 The following table details the behavior of remove for different
4166 file states (columns) and option combinations (rows). The file
4168 file states (columns) and option combinations (rows). The file
4167 states are Added [A], Clean [C], Modified [M] and Missing [!]
4169 states are Added [A], Clean [C], Modified [M] and Missing [!]
4168 (as reported by :hg:`status`). The actions are Warn, Remove
4170 (as reported by :hg:`status`). The actions are Warn, Remove
4169 (from branch) and Delete (from disk):
4171 (from branch) and Delete (from disk):
4170
4172
4171 ========= == == == ==
4173 ========= == == == ==
4172 opt/state A C M !
4174 opt/state A C M !
4173 ========= == == == ==
4175 ========= == == == ==
4174 none W RD W R
4176 none W RD W R
4175 -f R RD RD R
4177 -f R RD RD R
4176 -A W W W R
4178 -A W W W R
4177 -Af R R R R
4179 -Af R R R R
4178 ========= == == == ==
4180 ========= == == == ==
4179
4181
4180 .. note::
4182 .. note::
4181
4183
4182 :hg:`remove` never deletes files in Added [A] state from the
4184 :hg:`remove` never deletes files in Added [A] state from the
4183 working directory, not even if ``--force`` is specified.
4185 working directory, not even if ``--force`` is specified.
4184
4186
4185 Returns 0 on success, 1 if any warnings encountered.
4187 Returns 0 on success, 1 if any warnings encountered.
4186 """
4188 """
4187
4189
4188 after, force = opts.get('after'), opts.get('force')
4190 after, force = opts.get('after'), opts.get('force')
4189 if not pats and not after:
4191 if not pats and not after:
4190 raise error.Abort(_('no files specified'))
4192 raise error.Abort(_('no files specified'))
4191
4193
4192 m = scmutil.match(repo[None], pats, opts)
4194 m = scmutil.match(repo[None], pats, opts)
4193 subrepos = opts.get('subrepos')
4195 subrepos = opts.get('subrepos')
4194 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
4196 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
4195
4197
4196 @command('rename|move|mv',
4198 @command('rename|move|mv',
4197 [('A', 'after', None, _('record a rename that has already occurred')),
4199 [('A', 'after', None, _('record a rename that has already occurred')),
4198 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4200 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4199 ] + walkopts + dryrunopts,
4201 ] + walkopts + dryrunopts,
4200 _('[OPTION]... SOURCE... DEST'))
4202 _('[OPTION]... SOURCE... DEST'))
4201 def rename(ui, repo, *pats, **opts):
4203 def rename(ui, repo, *pats, **opts):
4202 """rename files; equivalent of copy + remove
4204 """rename files; equivalent of copy + remove
4203
4205
4204 Mark dest as copies of sources; mark sources for deletion. If dest
4206 Mark dest as copies of sources; mark sources for deletion. If dest
4205 is a directory, copies are put in that directory. If dest is a
4207 is a directory, copies are put in that directory. If dest is a
4206 file, there can only be one source.
4208 file, there can only be one source.
4207
4209
4208 By default, this command copies the contents of files as they
4210 By default, this command copies the contents of files as they
4209 exist in the working directory. If invoked with -A/--after, the
4211 exist in the working directory. If invoked with -A/--after, the
4210 operation is recorded, but no copying is performed.
4212 operation is recorded, but no copying is performed.
4211
4213
4212 This command takes effect at the next commit. To undo a rename
4214 This command takes effect at the next commit. To undo a rename
4213 before that, see :hg:`revert`.
4215 before that, see :hg:`revert`.
4214
4216
4215 Returns 0 on success, 1 if errors are encountered.
4217 Returns 0 on success, 1 if errors are encountered.
4216 """
4218 """
4217 with repo.wlock(False):
4219 with repo.wlock(False):
4218 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4220 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4219
4221
4220 @command('resolve',
4222 @command('resolve',
4221 [('a', 'all', None, _('select all unresolved files')),
4223 [('a', 'all', None, _('select all unresolved files')),
4222 ('l', 'list', None, _('list state of files needing merge')),
4224 ('l', 'list', None, _('list state of files needing merge')),
4223 ('m', 'mark', None, _('mark files as resolved')),
4225 ('m', 'mark', None, _('mark files as resolved')),
4224 ('u', 'unmark', None, _('mark files as unresolved')),
4226 ('u', 'unmark', None, _('mark files as unresolved')),
4225 ('n', 'no-status', None, _('hide status prefix'))]
4227 ('n', 'no-status', None, _('hide status prefix'))]
4226 + mergetoolopts + walkopts + formatteropts,
4228 + mergetoolopts + walkopts + formatteropts,
4227 _('[OPTION]... [FILE]...'),
4229 _('[OPTION]... [FILE]...'),
4228 inferrepo=True)
4230 inferrepo=True)
4229 def resolve(ui, repo, *pats, **opts):
4231 def resolve(ui, repo, *pats, **opts):
4230 """redo merges or set/view the merge status of files
4232 """redo merges or set/view the merge status of files
4231
4233
4232 Merges with unresolved conflicts are often the result of
4234 Merges with unresolved conflicts are often the result of
4233 non-interactive merging using the ``internal:merge`` configuration
4235 non-interactive merging using the ``internal:merge`` configuration
4234 setting, or a command-line merge tool like ``diff3``. The resolve
4236 setting, or a command-line merge tool like ``diff3``. The resolve
4235 command is used to manage the files involved in a merge, after
4237 command is used to manage the files involved in a merge, after
4236 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4238 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4237 working directory must have two parents). See :hg:`help
4239 working directory must have two parents). See :hg:`help
4238 merge-tools` for information on configuring merge tools.
4240 merge-tools` for information on configuring merge tools.
4239
4241
4240 The resolve command can be used in the following ways:
4242 The resolve command can be used in the following ways:
4241
4243
4242 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4244 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4243 files, discarding any previous merge attempts. Re-merging is not
4245 files, discarding any previous merge attempts. Re-merging is not
4244 performed for files already marked as resolved. Use ``--all/-a``
4246 performed for files already marked as resolved. Use ``--all/-a``
4245 to select all unresolved files. ``--tool`` can be used to specify
4247 to select all unresolved files. ``--tool`` can be used to specify
4246 the merge tool used for the given files. It overrides the HGMERGE
4248 the merge tool used for the given files. It overrides the HGMERGE
4247 environment variable and your configuration files. Previous file
4249 environment variable and your configuration files. Previous file
4248 contents are saved with a ``.orig`` suffix.
4250 contents are saved with a ``.orig`` suffix.
4249
4251
4250 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4252 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4251 (e.g. after having manually fixed-up the files). The default is
4253 (e.g. after having manually fixed-up the files). The default is
4252 to mark all unresolved files.
4254 to mark all unresolved files.
4253
4255
4254 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4256 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4255 default is to mark all resolved files.
4257 default is to mark all resolved files.
4256
4258
4257 - :hg:`resolve -l`: list files which had or still have conflicts.
4259 - :hg:`resolve -l`: list files which had or still have conflicts.
4258 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4260 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4259
4261
4260 .. note::
4262 .. note::
4261
4263
4262 Mercurial will not let you commit files with unresolved merge
4264 Mercurial will not let you commit files with unresolved merge
4263 conflicts. You must use :hg:`resolve -m ...` before you can
4265 conflicts. You must use :hg:`resolve -m ...` before you can
4264 commit after a conflicting merge.
4266 commit after a conflicting merge.
4265
4267
4266 Returns 0 on success, 1 if any files fail a resolve attempt.
4268 Returns 0 on success, 1 if any files fail a resolve attempt.
4267 """
4269 """
4268
4270
4269 flaglist = 'all mark unmark list no_status'.split()
4271 flaglist = 'all mark unmark list no_status'.split()
4270 all, mark, unmark, show, nostatus = \
4272 all, mark, unmark, show, nostatus = \
4271 [opts.get(o) for o in flaglist]
4273 [opts.get(o) for o in flaglist]
4272
4274
4273 if (show and (mark or unmark)) or (mark and unmark):
4275 if (show and (mark or unmark)) or (mark and unmark):
4274 raise error.Abort(_("too many options specified"))
4276 raise error.Abort(_("too many options specified"))
4275 if pats and all:
4277 if pats and all:
4276 raise error.Abort(_("can't specify --all and patterns"))
4278 raise error.Abort(_("can't specify --all and patterns"))
4277 if not (all or pats or show or mark or unmark):
4279 if not (all or pats or show or mark or unmark):
4278 raise error.Abort(_('no files or directories specified'),
4280 raise error.Abort(_('no files or directories specified'),
4279 hint=('use --all to re-merge all unresolved files'))
4281 hint=('use --all to re-merge all unresolved files'))
4280
4282
4281 if show:
4283 if show:
4282 fm = ui.formatter('resolve', opts)
4284 fm = ui.formatter('resolve', opts)
4283 ms = mergemod.mergestate.read(repo)
4285 ms = mergemod.mergestate.read(repo)
4284 m = scmutil.match(repo[None], pats, opts)
4286 m = scmutil.match(repo[None], pats, opts)
4285 for f in ms:
4287 for f in ms:
4286 if not m(f):
4288 if not m(f):
4287 continue
4289 continue
4288 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved',
4290 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved',
4289 'd': 'driverresolved'}[ms[f]]
4291 'd': 'driverresolved'}[ms[f]]
4290 fm.startitem()
4292 fm.startitem()
4291 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
4293 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
4292 fm.write('path', '%s\n', f, label=l)
4294 fm.write('path', '%s\n', f, label=l)
4293 fm.end()
4295 fm.end()
4294 return 0
4296 return 0
4295
4297
4296 with repo.wlock():
4298 with repo.wlock():
4297 ms = mergemod.mergestate.read(repo)
4299 ms = mergemod.mergestate.read(repo)
4298
4300
4299 if not (ms.active() or repo.dirstate.p2() != nullid):
4301 if not (ms.active() or repo.dirstate.p2() != nullid):
4300 raise error.Abort(
4302 raise error.Abort(
4301 _('resolve command not applicable when not merging'))
4303 _('resolve command not applicable when not merging'))
4302
4304
4303 wctx = repo[None]
4305 wctx = repo[None]
4304
4306
4305 if ms.mergedriver and ms.mdstate() == 'u':
4307 if ms.mergedriver and ms.mdstate() == 'u':
4306 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4308 proceed = mergemod.driverpreprocess(repo, ms, wctx)
4307 ms.commit()
4309 ms.commit()
4308 # allow mark and unmark to go through
4310 # allow mark and unmark to go through
4309 if not mark and not unmark and not proceed:
4311 if not mark and not unmark and not proceed:
4310 return 1
4312 return 1
4311
4313
4312 m = scmutil.match(wctx, pats, opts)
4314 m = scmutil.match(wctx, pats, opts)
4313 ret = 0
4315 ret = 0
4314 didwork = False
4316 didwork = False
4315 runconclude = False
4317 runconclude = False
4316
4318
4317 tocomplete = []
4319 tocomplete = []
4318 for f in ms:
4320 for f in ms:
4319 if not m(f):
4321 if not m(f):
4320 continue
4322 continue
4321
4323
4322 didwork = True
4324 didwork = True
4323
4325
4324 # don't let driver-resolved files be marked, and run the conclude
4326 # don't let driver-resolved files be marked, and run the conclude
4325 # step if asked to resolve
4327 # step if asked to resolve
4326 if ms[f] == "d":
4328 if ms[f] == "d":
4327 exact = m.exact(f)
4329 exact = m.exact(f)
4328 if mark:
4330 if mark:
4329 if exact:
4331 if exact:
4330 ui.warn(_('not marking %s as it is driver-resolved\n')
4332 ui.warn(_('not marking %s as it is driver-resolved\n')
4331 % f)
4333 % f)
4332 elif unmark:
4334 elif unmark:
4333 if exact:
4335 if exact:
4334 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4336 ui.warn(_('not unmarking %s as it is driver-resolved\n')
4335 % f)
4337 % f)
4336 else:
4338 else:
4337 runconclude = True
4339 runconclude = True
4338 continue
4340 continue
4339
4341
4340 if mark:
4342 if mark:
4341 ms.mark(f, "r")
4343 ms.mark(f, "r")
4342 elif unmark:
4344 elif unmark:
4343 ms.mark(f, "u")
4345 ms.mark(f, "u")
4344 else:
4346 else:
4345 # backup pre-resolve (merge uses .orig for its own purposes)
4347 # backup pre-resolve (merge uses .orig for its own purposes)
4346 a = repo.wjoin(f)
4348 a = repo.wjoin(f)
4347 try:
4349 try:
4348 util.copyfile(a, a + ".resolve")
4350 util.copyfile(a, a + ".resolve")
4349 except (IOError, OSError) as inst:
4351 except (IOError, OSError) as inst:
4350 if inst.errno != errno.ENOENT:
4352 if inst.errno != errno.ENOENT:
4351 raise
4353 raise
4352
4354
4353 try:
4355 try:
4354 # preresolve file
4356 # preresolve file
4355 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4357 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4356 'resolve')
4358 'resolve')
4357 complete, r = ms.preresolve(f, wctx)
4359 complete, r = ms.preresolve(f, wctx)
4358 if not complete:
4360 if not complete:
4359 tocomplete.append(f)
4361 tocomplete.append(f)
4360 elif r:
4362 elif r:
4361 ret = 1
4363 ret = 1
4362 finally:
4364 finally:
4363 ui.setconfig('ui', 'forcemerge', '', 'resolve')
4365 ui.setconfig('ui', 'forcemerge', '', 'resolve')
4364 ms.commit()
4366 ms.commit()
4365
4367
4366 # replace filemerge's .orig file with our resolve file, but only
4368 # replace filemerge's .orig file with our resolve file, but only
4367 # for merges that are complete
4369 # for merges that are complete
4368 if complete:
4370 if complete:
4369 try:
4371 try:
4370 util.rename(a + ".resolve",
4372 util.rename(a + ".resolve",
4371 scmutil.origpath(ui, repo, a))
4373 scmutil.origpath(ui, repo, a))
4372 except OSError as inst:
4374 except OSError as inst:
4373 if inst.errno != errno.ENOENT:
4375 if inst.errno != errno.ENOENT:
4374 raise
4376 raise
4375
4377
4376 for f in tocomplete:
4378 for f in tocomplete:
4377 try:
4379 try:
4378 # resolve file
4380 # resolve file
4379 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4381 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4380 'resolve')
4382 'resolve')
4381 r = ms.resolve(f, wctx)
4383 r = ms.resolve(f, wctx)
4382 if r:
4384 if r:
4383 ret = 1
4385 ret = 1
4384 finally:
4386 finally:
4385 ui.setconfig('ui', 'forcemerge', '', 'resolve')
4387 ui.setconfig('ui', 'forcemerge', '', 'resolve')
4386 ms.commit()
4388 ms.commit()
4387
4389
4388 # replace filemerge's .orig file with our resolve file
4390 # replace filemerge's .orig file with our resolve file
4389 a = repo.wjoin(f)
4391 a = repo.wjoin(f)
4390 try:
4392 try:
4391 util.rename(a + ".resolve", scmutil.origpath(ui, repo, a))
4393 util.rename(a + ".resolve", scmutil.origpath(ui, repo, a))
4392 except OSError as inst:
4394 except OSError as inst:
4393 if inst.errno != errno.ENOENT:
4395 if inst.errno != errno.ENOENT:
4394 raise
4396 raise
4395
4397
4396 ms.commit()
4398 ms.commit()
4397 ms.recordactions()
4399 ms.recordactions()
4398
4400
4399 if not didwork and pats:
4401 if not didwork and pats:
4400 hint = None
4402 hint = None
4401 if not any([p for p in pats if p.find(':') >= 0]):
4403 if not any([p for p in pats if p.find(':') >= 0]):
4402 pats = ['path:%s' % p for p in pats]
4404 pats = ['path:%s' % p for p in pats]
4403 m = scmutil.match(wctx, pats, opts)
4405 m = scmutil.match(wctx, pats, opts)
4404 for f in ms:
4406 for f in ms:
4405 if not m(f):
4407 if not m(f):
4406 continue
4408 continue
4407 flags = ''.join(['-%s ' % o[0] for o in flaglist
4409 flags = ''.join(['-%s ' % o[0] for o in flaglist
4408 if opts.get(o)])
4410 if opts.get(o)])
4409 hint = _("(try: hg resolve %s%s)\n") % (
4411 hint = _("(try: hg resolve %s%s)\n") % (
4410 flags,
4412 flags,
4411 ' '.join(pats))
4413 ' '.join(pats))
4412 break
4414 break
4413 ui.warn(_("arguments do not match paths that need resolving\n"))
4415 ui.warn(_("arguments do not match paths that need resolving\n"))
4414 if hint:
4416 if hint:
4415 ui.warn(hint)
4417 ui.warn(hint)
4416 elif ms.mergedriver and ms.mdstate() != 's':
4418 elif ms.mergedriver and ms.mdstate() != 's':
4417 # run conclude step when either a driver-resolved file is requested
4419 # run conclude step when either a driver-resolved file is requested
4418 # or there are no driver-resolved files
4420 # or there are no driver-resolved files
4419 # we can't use 'ret' to determine whether any files are unresolved
4421 # we can't use 'ret' to determine whether any files are unresolved
4420 # because we might not have tried to resolve some
4422 # because we might not have tried to resolve some
4421 if ((runconclude or not list(ms.driverresolved()))
4423 if ((runconclude or not list(ms.driverresolved()))
4422 and not list(ms.unresolved())):
4424 and not list(ms.unresolved())):
4423 proceed = mergemod.driverconclude(repo, ms, wctx)
4425 proceed = mergemod.driverconclude(repo, ms, wctx)
4424 ms.commit()
4426 ms.commit()
4425 if not proceed:
4427 if not proceed:
4426 return 1
4428 return 1
4427
4429
4428 # Nudge users into finishing an unfinished operation
4430 # Nudge users into finishing an unfinished operation
4429 unresolvedf = list(ms.unresolved())
4431 unresolvedf = list(ms.unresolved())
4430 driverresolvedf = list(ms.driverresolved())
4432 driverresolvedf = list(ms.driverresolved())
4431 if not unresolvedf and not driverresolvedf:
4433 if not unresolvedf and not driverresolvedf:
4432 ui.status(_('(no more unresolved files)\n'))
4434 ui.status(_('(no more unresolved files)\n'))
4433 cmdutil.checkafterresolved(repo)
4435 cmdutil.checkafterresolved(repo)
4434 elif not unresolvedf:
4436 elif not unresolvedf:
4435 ui.status(_('(no more unresolved files -- '
4437 ui.status(_('(no more unresolved files -- '
4436 'run "hg resolve --all" to conclude)\n'))
4438 'run "hg resolve --all" to conclude)\n'))
4437
4439
4438 return ret
4440 return ret
4439
4441
4440 @command('revert',
4442 @command('revert',
4441 [('a', 'all', None, _('revert all changes when no arguments given')),
4443 [('a', 'all', None, _('revert all changes when no arguments given')),
4442 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4444 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4443 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4445 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4444 ('C', 'no-backup', None, _('do not save backup copies of files')),
4446 ('C', 'no-backup', None, _('do not save backup copies of files')),
4445 ('i', 'interactive', None,
4447 ('i', 'interactive', None,
4446 _('interactively select the changes (EXPERIMENTAL)')),
4448 _('interactively select the changes (EXPERIMENTAL)')),
4447 ] + walkopts + dryrunopts,
4449 ] + walkopts + dryrunopts,
4448 _('[OPTION]... [-r REV] [NAME]...'))
4450 _('[OPTION]... [-r REV] [NAME]...'))
4449 def revert(ui, repo, *pats, **opts):
4451 def revert(ui, repo, *pats, **opts):
4450 """restore files to their checkout state
4452 """restore files to their checkout state
4451
4453
4452 .. note::
4454 .. note::
4453
4455
4454 To check out earlier revisions, you should use :hg:`update REV`.
4456 To check out earlier revisions, you should use :hg:`update REV`.
4455 To cancel an uncommitted merge (and lose your changes),
4457 To cancel an uncommitted merge (and lose your changes),
4456 use :hg:`update --clean .`.
4458 use :hg:`update --clean .`.
4457
4459
4458 With no revision specified, revert the specified files or directories
4460 With no revision specified, revert the specified files or directories
4459 to the contents they had in the parent of the working directory.
4461 to the contents they had in the parent of the working directory.
4460 This restores the contents of files to an unmodified
4462 This restores the contents of files to an unmodified
4461 state and unschedules adds, removes, copies, and renames. If the
4463 state and unschedules adds, removes, copies, and renames. If the
4462 working directory has two parents, you must explicitly specify a
4464 working directory has two parents, you must explicitly specify a
4463 revision.
4465 revision.
4464
4466
4465 Using the -r/--rev or -d/--date options, revert the given files or
4467 Using the -r/--rev or -d/--date options, revert the given files or
4466 directories to their states as of a specific revision. Because
4468 directories to their states as of a specific revision. Because
4467 revert does not change the working directory parents, this will
4469 revert does not change the working directory parents, this will
4468 cause these files to appear modified. This can be helpful to "back
4470 cause these files to appear modified. This can be helpful to "back
4469 out" some or all of an earlier change. See :hg:`backout` for a
4471 out" some or all of an earlier change. See :hg:`backout` for a
4470 related method.
4472 related method.
4471
4473
4472 Modified files are saved with a .orig suffix before reverting.
4474 Modified files are saved with a .orig suffix before reverting.
4473 To disable these backups, use --no-backup. It is possible to store
4475 To disable these backups, use --no-backup. It is possible to store
4474 the backup files in a custom directory relative to the root of the
4476 the backup files in a custom directory relative to the root of the
4475 repository by setting the ``ui.origbackuppath`` configuration
4477 repository by setting the ``ui.origbackuppath`` configuration
4476 option.
4478 option.
4477
4479
4478 See :hg:`help dates` for a list of formats valid for -d/--date.
4480 See :hg:`help dates` for a list of formats valid for -d/--date.
4479
4481
4480 See :hg:`help backout` for a way to reverse the effect of an
4482 See :hg:`help backout` for a way to reverse the effect of an
4481 earlier changeset.
4483 earlier changeset.
4482
4484
4483 Returns 0 on success.
4485 Returns 0 on success.
4484 """
4486 """
4485
4487
4486 if opts.get("date"):
4488 if opts.get("date"):
4487 if opts.get("rev"):
4489 if opts.get("rev"):
4488 raise error.Abort(_("you can't specify a revision and a date"))
4490 raise error.Abort(_("you can't specify a revision and a date"))
4489 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
4491 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
4490
4492
4491 parent, p2 = repo.dirstate.parents()
4493 parent, p2 = repo.dirstate.parents()
4492 if not opts.get('rev') and p2 != nullid:
4494 if not opts.get('rev') and p2 != nullid:
4493 # revert after merge is a trap for new users (issue2915)
4495 # revert after merge is a trap for new users (issue2915)
4494 raise error.Abort(_('uncommitted merge with no revision specified'),
4496 raise error.Abort(_('uncommitted merge with no revision specified'),
4495 hint=_("use 'hg update' or see 'hg help revert'"))
4497 hint=_("use 'hg update' or see 'hg help revert'"))
4496
4498
4497 ctx = scmutil.revsingle(repo, opts.get('rev'))
4499 ctx = scmutil.revsingle(repo, opts.get('rev'))
4498
4500
4499 if (not (pats or opts.get('include') or opts.get('exclude') or
4501 if (not (pats or opts.get('include') or opts.get('exclude') or
4500 opts.get('all') or opts.get('interactive'))):
4502 opts.get('all') or opts.get('interactive'))):
4501 msg = _("no files or directories specified")
4503 msg = _("no files or directories specified")
4502 if p2 != nullid:
4504 if p2 != nullid:
4503 hint = _("uncommitted merge, use --all to discard all changes,"
4505 hint = _("uncommitted merge, use --all to discard all changes,"
4504 " or 'hg update -C .' to abort the merge")
4506 " or 'hg update -C .' to abort the merge")
4505 raise error.Abort(msg, hint=hint)
4507 raise error.Abort(msg, hint=hint)
4506 dirty = any(repo.status())
4508 dirty = any(repo.status())
4507 node = ctx.node()
4509 node = ctx.node()
4508 if node != parent:
4510 if node != parent:
4509 if dirty:
4511 if dirty:
4510 hint = _("uncommitted changes, use --all to discard all"
4512 hint = _("uncommitted changes, use --all to discard all"
4511 " changes, or 'hg update %s' to update") % ctx.rev()
4513 " changes, or 'hg update %s' to update") % ctx.rev()
4512 else:
4514 else:
4513 hint = _("use --all to revert all files,"
4515 hint = _("use --all to revert all files,"
4514 " or 'hg update %s' to update") % ctx.rev()
4516 " or 'hg update %s' to update") % ctx.rev()
4515 elif dirty:
4517 elif dirty:
4516 hint = _("uncommitted changes, use --all to discard all changes")
4518 hint = _("uncommitted changes, use --all to discard all changes")
4517 else:
4519 else:
4518 hint = _("use --all to revert all files")
4520 hint = _("use --all to revert all files")
4519 raise error.Abort(msg, hint=hint)
4521 raise error.Abort(msg, hint=hint)
4520
4522
4521 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
4523 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
4522
4524
4523 @command('rollback', dryrunopts +
4525 @command('rollback', dryrunopts +
4524 [('f', 'force', False, _('ignore safety measures'))])
4526 [('f', 'force', False, _('ignore safety measures'))])
4525 def rollback(ui, repo, **opts):
4527 def rollback(ui, repo, **opts):
4526 """roll back the last transaction (DANGEROUS) (DEPRECATED)
4528 """roll back the last transaction (DANGEROUS) (DEPRECATED)
4527
4529
4528 Please use :hg:`commit --amend` instead of rollback to correct
4530 Please use :hg:`commit --amend` instead of rollback to correct
4529 mistakes in the last commit.
4531 mistakes in the last commit.
4530
4532
4531 This command should be used with care. There is only one level of
4533 This command should be used with care. There is only one level of
4532 rollback, and there is no way to undo a rollback. It will also
4534 rollback, and there is no way to undo a rollback. It will also
4533 restore the dirstate at the time of the last transaction, losing
4535 restore the dirstate at the time of the last transaction, losing
4534 any dirstate changes since that time. This command does not alter
4536 any dirstate changes since that time. This command does not alter
4535 the working directory.
4537 the working directory.
4536
4538
4537 Transactions are used to encapsulate the effects of all commands
4539 Transactions are used to encapsulate the effects of all commands
4538 that create new changesets or propagate existing changesets into a
4540 that create new changesets or propagate existing changesets into a
4539 repository.
4541 repository.
4540
4542
4541 .. container:: verbose
4543 .. container:: verbose
4542
4544
4543 For example, the following commands are transactional, and their
4545 For example, the following commands are transactional, and their
4544 effects can be rolled back:
4546 effects can be rolled back:
4545
4547
4546 - commit
4548 - commit
4547 - import
4549 - import
4548 - pull
4550 - pull
4549 - push (with this repository as the destination)
4551 - push (with this repository as the destination)
4550 - unbundle
4552 - unbundle
4551
4553
4552 To avoid permanent data loss, rollback will refuse to rollback a
4554 To avoid permanent data loss, rollback will refuse to rollback a
4553 commit transaction if it isn't checked out. Use --force to
4555 commit transaction if it isn't checked out. Use --force to
4554 override this protection.
4556 override this protection.
4555
4557
4556 The rollback command can be entirely disabled by setting the
4558 The rollback command can be entirely disabled by setting the
4557 ``ui.rollback`` configuration setting to false. If you're here
4559 ``ui.rollback`` configuration setting to false. If you're here
4558 because you want to use rollback and it's disabled, you can
4560 because you want to use rollback and it's disabled, you can
4559 re-enable the command by setting ``ui.rollback`` to true.
4561 re-enable the command by setting ``ui.rollback`` to true.
4560
4562
4561 This command is not intended for use on public repositories. Once
4563 This command is not intended for use on public repositories. Once
4562 changes are visible for pull by other users, rolling a transaction
4564 changes are visible for pull by other users, rolling a transaction
4563 back locally is ineffective (someone else may already have pulled
4565 back locally is ineffective (someone else may already have pulled
4564 the changes). Furthermore, a race is possible with readers of the
4566 the changes). Furthermore, a race is possible with readers of the
4565 repository; for example an in-progress pull from the repository
4567 repository; for example an in-progress pull from the repository
4566 may fail if a rollback is performed.
4568 may fail if a rollback is performed.
4567
4569
4568 Returns 0 on success, 1 if no rollback data is available.
4570 Returns 0 on success, 1 if no rollback data is available.
4569 """
4571 """
4570 if not ui.configbool('ui', 'rollback', True):
4572 if not ui.configbool('ui', 'rollback', True):
4571 raise error.Abort(_('rollback is disabled because it is unsafe'),
4573 raise error.Abort(_('rollback is disabled because it is unsafe'),
4572 hint=('see `hg help -v rollback` for information'))
4574 hint=('see `hg help -v rollback` for information'))
4573 return repo.rollback(dryrun=opts.get('dry_run'),
4575 return repo.rollback(dryrun=opts.get('dry_run'),
4574 force=opts.get('force'))
4576 force=opts.get('force'))
4575
4577
4576 @command('root', [])
4578 @command('root', [])
4577 def root(ui, repo):
4579 def root(ui, repo):
4578 """print the root (top) of the current working directory
4580 """print the root (top) of the current working directory
4579
4581
4580 Print the root directory of the current repository.
4582 Print the root directory of the current repository.
4581
4583
4582 Returns 0 on success.
4584 Returns 0 on success.
4583 """
4585 """
4584 ui.write(repo.root + "\n")
4586 ui.write(repo.root + "\n")
4585
4587
4586 @command('^serve',
4588 @command('^serve',
4587 [('A', 'accesslog', '', _('name of access log file to write to'),
4589 [('A', 'accesslog', '', _('name of access log file to write to'),
4588 _('FILE')),
4590 _('FILE')),
4589 ('d', 'daemon', None, _('run server in background')),
4591 ('d', 'daemon', None, _('run server in background')),
4590 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
4592 ('', 'daemon-postexec', [], _('used internally by daemon mode')),
4591 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
4593 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
4592 # use string type, then we can check if something was passed
4594 # use string type, then we can check if something was passed
4593 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
4595 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
4594 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
4596 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
4595 _('ADDR')),
4597 _('ADDR')),
4596 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
4598 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
4597 _('PREFIX')),
4599 _('PREFIX')),
4598 ('n', 'name', '',
4600 ('n', 'name', '',
4599 _('name to show in web pages (default: working directory)'), _('NAME')),
4601 _('name to show in web pages (default: working directory)'), _('NAME')),
4600 ('', 'web-conf', '',
4602 ('', 'web-conf', '',
4601 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
4603 _("name of the hgweb config file (see 'hg help hgweb')"), _('FILE')),
4602 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
4604 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
4603 _('FILE')),
4605 _('FILE')),
4604 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
4606 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
4605 ('', 'stdio', None, _('for remote clients')),
4607 ('', 'stdio', None, _('for remote clients')),
4606 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
4608 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
4607 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
4609 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
4608 ('', 'style', '', _('template style to use'), _('STYLE')),
4610 ('', 'style', '', _('template style to use'), _('STYLE')),
4609 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4611 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4610 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
4612 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
4611 _('[OPTION]...'),
4613 _('[OPTION]...'),
4612 optionalrepo=True)
4614 optionalrepo=True)
4613 def serve(ui, repo, **opts):
4615 def serve(ui, repo, **opts):
4614 """start stand-alone webserver
4616 """start stand-alone webserver
4615
4617
4616 Start a local HTTP repository browser and pull server. You can use
4618 Start a local HTTP repository browser and pull server. You can use
4617 this for ad-hoc sharing and browsing of repositories. It is
4619 this for ad-hoc sharing and browsing of repositories. It is
4618 recommended to use a real web server to serve a repository for
4620 recommended to use a real web server to serve a repository for
4619 longer periods of time.
4621 longer periods of time.
4620
4622
4621 Please note that the server does not implement access control.
4623 Please note that the server does not implement access control.
4622 This means that, by default, anybody can read from the server and
4624 This means that, by default, anybody can read from the server and
4623 nobody can write to it by default. Set the ``web.allow_push``
4625 nobody can write to it by default. Set the ``web.allow_push``
4624 option to ``*`` to allow everybody to push to the server. You
4626 option to ``*`` to allow everybody to push to the server. You
4625 should use a real web server if you need to authenticate users.
4627 should use a real web server if you need to authenticate users.
4626
4628
4627 By default, the server logs accesses to stdout and errors to
4629 By default, the server logs accesses to stdout and errors to
4628 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
4630 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
4629 files.
4631 files.
4630
4632
4631 To have the server choose a free port number to listen on, specify
4633 To have the server choose a free port number to listen on, specify
4632 a port number of 0; in this case, the server will print the port
4634 a port number of 0; in this case, the server will print the port
4633 number it uses.
4635 number it uses.
4634
4636
4635 Returns 0 on success.
4637 Returns 0 on success.
4636 """
4638 """
4637
4639
4638 if opts["stdio"] and opts["cmdserver"]:
4640 if opts["stdio"] and opts["cmdserver"]:
4639 raise error.Abort(_("cannot use --stdio with --cmdserver"))
4641 raise error.Abort(_("cannot use --stdio with --cmdserver"))
4640
4642
4641 if opts["stdio"]:
4643 if opts["stdio"]:
4642 if repo is None:
4644 if repo is None:
4643 raise error.RepoError(_("there is no Mercurial repository here"
4645 raise error.RepoError(_("there is no Mercurial repository here"
4644 " (.hg not found)"))
4646 " (.hg not found)"))
4645 s = sshserver.sshserver(ui, repo)
4647 s = sshserver.sshserver(ui, repo)
4646 s.serve_forever()
4648 s.serve_forever()
4647
4649
4648 service = server.createservice(ui, repo, opts)
4650 service = server.createservice(ui, repo, opts)
4649 return server.runservice(opts, initfn=service.init, runfn=service.run)
4651 return server.runservice(opts, initfn=service.init, runfn=service.run)
4650
4652
4651 @command('^status|st',
4653 @command('^status|st',
4652 [('A', 'all', None, _('show status of all files')),
4654 [('A', 'all', None, _('show status of all files')),
4653 ('m', 'modified', None, _('show only modified files')),
4655 ('m', 'modified', None, _('show only modified files')),
4654 ('a', 'added', None, _('show only added files')),
4656 ('a', 'added', None, _('show only added files')),
4655 ('r', 'removed', None, _('show only removed files')),
4657 ('r', 'removed', None, _('show only removed files')),
4656 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4658 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4657 ('c', 'clean', None, _('show only files without changes')),
4659 ('c', 'clean', None, _('show only files without changes')),
4658 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4660 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4659 ('i', 'ignored', None, _('show only ignored files')),
4661 ('i', 'ignored', None, _('show only ignored files')),
4660 ('n', 'no-status', None, _('hide status prefix')),
4662 ('n', 'no-status', None, _('hide status prefix')),
4661 ('C', 'copies', None, _('show source of copied files')),
4663 ('C', 'copies', None, _('show source of copied files')),
4662 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4664 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4663 ('', 'rev', [], _('show difference from revision'), _('REV')),
4665 ('', 'rev', [], _('show difference from revision'), _('REV')),
4664 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
4666 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
4665 ] + walkopts + subrepoopts + formatteropts,
4667 ] + walkopts + subrepoopts + formatteropts,
4666 _('[OPTION]... [FILE]...'),
4668 _('[OPTION]... [FILE]...'),
4667 inferrepo=True)
4669 inferrepo=True)
4668 def status(ui, repo, *pats, **opts):
4670 def status(ui, repo, *pats, **opts):
4669 """show changed files in the working directory
4671 """show changed files in the working directory
4670
4672
4671 Show status of files in the repository. If names are given, only
4673 Show status of files in the repository. If names are given, only
4672 files that match are shown. Files that are clean or ignored or
4674 files that match are shown. Files that are clean or ignored or
4673 the source of a copy/move operation, are not listed unless
4675 the source of a copy/move operation, are not listed unless
4674 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
4676 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
4675 Unless options described with "show only ..." are given, the
4677 Unless options described with "show only ..." are given, the
4676 options -mardu are used.
4678 options -mardu are used.
4677
4679
4678 Option -q/--quiet hides untracked (unknown and ignored) files
4680 Option -q/--quiet hides untracked (unknown and ignored) files
4679 unless explicitly requested with -u/--unknown or -i/--ignored.
4681 unless explicitly requested with -u/--unknown or -i/--ignored.
4680
4682
4681 .. note::
4683 .. note::
4682
4684
4683 :hg:`status` may appear to disagree with diff if permissions have
4685 :hg:`status` may appear to disagree with diff if permissions have
4684 changed or a merge has occurred. The standard diff format does
4686 changed or a merge has occurred. The standard diff format does
4685 not report permission changes and diff only reports changes
4687 not report permission changes and diff only reports changes
4686 relative to one merge parent.
4688 relative to one merge parent.
4687
4689
4688 If one revision is given, it is used as the base revision.
4690 If one revision is given, it is used as the base revision.
4689 If two revisions are given, the differences between them are
4691 If two revisions are given, the differences between them are
4690 shown. The --change option can also be used as a shortcut to list
4692 shown. The --change option can also be used as a shortcut to list
4691 the changed files of a revision from its first parent.
4693 the changed files of a revision from its first parent.
4692
4694
4693 The codes used to show the status of files are::
4695 The codes used to show the status of files are::
4694
4696
4695 M = modified
4697 M = modified
4696 A = added
4698 A = added
4697 R = removed
4699 R = removed
4698 C = clean
4700 C = clean
4699 ! = missing (deleted by non-hg command, but still tracked)
4701 ! = missing (deleted by non-hg command, but still tracked)
4700 ? = not tracked
4702 ? = not tracked
4701 I = ignored
4703 I = ignored
4702 = origin of the previous file (with --copies)
4704 = origin of the previous file (with --copies)
4703
4705
4704 .. container:: verbose
4706 .. container:: verbose
4705
4707
4706 Examples:
4708 Examples:
4707
4709
4708 - show changes in the working directory relative to a
4710 - show changes in the working directory relative to a
4709 changeset::
4711 changeset::
4710
4712
4711 hg status --rev 9353
4713 hg status --rev 9353
4712
4714
4713 - show changes in the working directory relative to the
4715 - show changes in the working directory relative to the
4714 current directory (see :hg:`help patterns` for more information)::
4716 current directory (see :hg:`help patterns` for more information)::
4715
4717
4716 hg status re:
4718 hg status re:
4717
4719
4718 - show all changes including copies in an existing changeset::
4720 - show all changes including copies in an existing changeset::
4719
4721
4720 hg status --copies --change 9353
4722 hg status --copies --change 9353
4721
4723
4722 - get a NUL separated list of added files, suitable for xargs::
4724 - get a NUL separated list of added files, suitable for xargs::
4723
4725
4724 hg status -an0
4726 hg status -an0
4725
4727
4726 Returns 0 on success.
4728 Returns 0 on success.
4727 """
4729 """
4728
4730
4729 revs = opts.get('rev')
4731 revs = opts.get('rev')
4730 change = opts.get('change')
4732 change = opts.get('change')
4731
4733
4732 if revs and change:
4734 if revs and change:
4733 msg = _('cannot specify --rev and --change at the same time')
4735 msg = _('cannot specify --rev and --change at the same time')
4734 raise error.Abort(msg)
4736 raise error.Abort(msg)
4735 elif change:
4737 elif change:
4736 node2 = scmutil.revsingle(repo, change, None).node()
4738 node2 = scmutil.revsingle(repo, change, None).node()
4737 node1 = repo[node2].p1().node()
4739 node1 = repo[node2].p1().node()
4738 else:
4740 else:
4739 node1, node2 = scmutil.revpair(repo, revs)
4741 node1, node2 = scmutil.revpair(repo, revs)
4740
4742
4741 if pats:
4743 if pats:
4742 cwd = repo.getcwd()
4744 cwd = repo.getcwd()
4743 else:
4745 else:
4744 cwd = ''
4746 cwd = ''
4745
4747
4746 if opts.get('print0'):
4748 if opts.get('print0'):
4747 end = '\0'
4749 end = '\0'
4748 else:
4750 else:
4749 end = '\n'
4751 end = '\n'
4750 copy = {}
4752 copy = {}
4751 states = 'modified added removed deleted unknown ignored clean'.split()
4753 states = 'modified added removed deleted unknown ignored clean'.split()
4752 show = [k for k in states if opts.get(k)]
4754 show = [k for k in states if opts.get(k)]
4753 if opts.get('all'):
4755 if opts.get('all'):
4754 show += ui.quiet and (states[:4] + ['clean']) or states
4756 show += ui.quiet and (states[:4] + ['clean']) or states
4755 if not show:
4757 if not show:
4756 if ui.quiet:
4758 if ui.quiet:
4757 show = states[:4]
4759 show = states[:4]
4758 else:
4760 else:
4759 show = states[:5]
4761 show = states[:5]
4760
4762
4761 m = scmutil.match(repo[node2], pats, opts)
4763 m = scmutil.match(repo[node2], pats, opts)
4762 stat = repo.status(node1, node2, m,
4764 stat = repo.status(node1, node2, m,
4763 'ignored' in show, 'clean' in show, 'unknown' in show,
4765 'ignored' in show, 'clean' in show, 'unknown' in show,
4764 opts.get('subrepos'))
4766 opts.get('subrepos'))
4765 changestates = zip(states, 'MAR!?IC', stat)
4767 changestates = zip(states, 'MAR!?IC', stat)
4766
4768
4767 if (opts.get('all') or opts.get('copies')
4769 if (opts.get('all') or opts.get('copies')
4768 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
4770 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
4769 copy = copies.pathcopies(repo[node1], repo[node2], m)
4771 copy = copies.pathcopies(repo[node1], repo[node2], m)
4770
4772
4771 fm = ui.formatter('status', opts)
4773 fm = ui.formatter('status', opts)
4772 fmt = '%s' + end
4774 fmt = '%s' + end
4773 showchar = not opts.get('no_status')
4775 showchar = not opts.get('no_status')
4774
4776
4775 for state, char, files in changestates:
4777 for state, char, files in changestates:
4776 if state in show:
4778 if state in show:
4777 label = 'status.' + state
4779 label = 'status.' + state
4778 for f in files:
4780 for f in files:
4779 fm.startitem()
4781 fm.startitem()
4780 fm.condwrite(showchar, 'status', '%s ', char, label=label)
4782 fm.condwrite(showchar, 'status', '%s ', char, label=label)
4781 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
4783 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
4782 if f in copy:
4784 if f in copy:
4783 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
4785 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
4784 label='status.copied')
4786 label='status.copied')
4785 fm.end()
4787 fm.end()
4786
4788
4787 @command('^summary|sum',
4789 @command('^summary|sum',
4788 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
4790 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
4789 def summary(ui, repo, **opts):
4791 def summary(ui, repo, **opts):
4790 """summarize working directory state
4792 """summarize working directory state
4791
4793
4792 This generates a brief summary of the working directory state,
4794 This generates a brief summary of the working directory state,
4793 including parents, branch, commit status, phase and available updates.
4795 including parents, branch, commit status, phase and available updates.
4794
4796
4795 With the --remote option, this will check the default paths for
4797 With the --remote option, this will check the default paths for
4796 incoming and outgoing changes. This can be time-consuming.
4798 incoming and outgoing changes. This can be time-consuming.
4797
4799
4798 Returns 0 on success.
4800 Returns 0 on success.
4799 """
4801 """
4800
4802
4801 ctx = repo[None]
4803 ctx = repo[None]
4802 parents = ctx.parents()
4804 parents = ctx.parents()
4803 pnode = parents[0].node()
4805 pnode = parents[0].node()
4804 marks = []
4806 marks = []
4805
4807
4806 ms = None
4808 ms = None
4807 try:
4809 try:
4808 ms = mergemod.mergestate.read(repo)
4810 ms = mergemod.mergestate.read(repo)
4809 except error.UnsupportedMergeRecords as e:
4811 except error.UnsupportedMergeRecords as e:
4810 s = ' '.join(e.recordtypes)
4812 s = ' '.join(e.recordtypes)
4811 ui.warn(
4813 ui.warn(
4812 _('warning: merge state has unsupported record types: %s\n') % s)
4814 _('warning: merge state has unsupported record types: %s\n') % s)
4813 unresolved = 0
4815 unresolved = 0
4814 else:
4816 else:
4815 unresolved = [f for f in ms if ms[f] == 'u']
4817 unresolved = [f for f in ms if ms[f] == 'u']
4816
4818
4817 for p in parents:
4819 for p in parents:
4818 # label with log.changeset (instead of log.parent) since this
4820 # label with log.changeset (instead of log.parent) since this
4819 # shows a working directory parent *changeset*:
4821 # shows a working directory parent *changeset*:
4820 # i18n: column positioning for "hg summary"
4822 # i18n: column positioning for "hg summary"
4821 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
4823 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
4822 label=cmdutil._changesetlabels(p))
4824 label=cmdutil._changesetlabels(p))
4823 ui.write(' '.join(p.tags()), label='log.tag')
4825 ui.write(' '.join(p.tags()), label='log.tag')
4824 if p.bookmarks():
4826 if p.bookmarks():
4825 marks.extend(p.bookmarks())
4827 marks.extend(p.bookmarks())
4826 if p.rev() == -1:
4828 if p.rev() == -1:
4827 if not len(repo):
4829 if not len(repo):
4828 ui.write(_(' (empty repository)'))
4830 ui.write(_(' (empty repository)'))
4829 else:
4831 else:
4830 ui.write(_(' (no revision checked out)'))
4832 ui.write(_(' (no revision checked out)'))
4831 if p.troubled():
4833 if p.troubled():
4832 ui.write(' ('
4834 ui.write(' ('
4833 + ', '.join(ui.label(trouble, 'trouble.%s' % trouble)
4835 + ', '.join(ui.label(trouble, 'trouble.%s' % trouble)
4834 for trouble in p.troubles())
4836 for trouble in p.troubles())
4835 + ')')
4837 + ')')
4836 ui.write('\n')
4838 ui.write('\n')
4837 if p.description():
4839 if p.description():
4838 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
4840 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
4839 label='log.summary')
4841 label='log.summary')
4840
4842
4841 branch = ctx.branch()
4843 branch = ctx.branch()
4842 bheads = repo.branchheads(branch)
4844 bheads = repo.branchheads(branch)
4843 # i18n: column positioning for "hg summary"
4845 # i18n: column positioning for "hg summary"
4844 m = _('branch: %s\n') % branch
4846 m = _('branch: %s\n') % branch
4845 if branch != 'default':
4847 if branch != 'default':
4846 ui.write(m, label='log.branch')
4848 ui.write(m, label='log.branch')
4847 else:
4849 else:
4848 ui.status(m, label='log.branch')
4850 ui.status(m, label='log.branch')
4849
4851
4850 if marks:
4852 if marks:
4851 active = repo._activebookmark
4853 active = repo._activebookmark
4852 # i18n: column positioning for "hg summary"
4854 # i18n: column positioning for "hg summary"
4853 ui.write(_('bookmarks:'), label='log.bookmark')
4855 ui.write(_('bookmarks:'), label='log.bookmark')
4854 if active is not None:
4856 if active is not None:
4855 if active in marks:
4857 if active in marks:
4856 ui.write(' *' + active, label=activebookmarklabel)
4858 ui.write(' *' + active, label=activebookmarklabel)
4857 marks.remove(active)
4859 marks.remove(active)
4858 else:
4860 else:
4859 ui.write(' [%s]' % active, label=activebookmarklabel)
4861 ui.write(' [%s]' % active, label=activebookmarklabel)
4860 for m in marks:
4862 for m in marks:
4861 ui.write(' ' + m, label='log.bookmark')
4863 ui.write(' ' + m, label='log.bookmark')
4862 ui.write('\n', label='log.bookmark')
4864 ui.write('\n', label='log.bookmark')
4863
4865
4864 status = repo.status(unknown=True)
4866 status = repo.status(unknown=True)
4865
4867
4866 c = repo.dirstate.copies()
4868 c = repo.dirstate.copies()
4867 copied, renamed = [], []
4869 copied, renamed = [], []
4868 for d, s in c.iteritems():
4870 for d, s in c.iteritems():
4869 if s in status.removed:
4871 if s in status.removed:
4870 status.removed.remove(s)
4872 status.removed.remove(s)
4871 renamed.append(d)
4873 renamed.append(d)
4872 else:
4874 else:
4873 copied.append(d)
4875 copied.append(d)
4874 if d in status.added:
4876 if d in status.added:
4875 status.added.remove(d)
4877 status.added.remove(d)
4876
4878
4877 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
4879 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
4878
4880
4879 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
4881 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
4880 (ui.label(_('%d added'), 'status.added'), status.added),
4882 (ui.label(_('%d added'), 'status.added'), status.added),
4881 (ui.label(_('%d removed'), 'status.removed'), status.removed),
4883 (ui.label(_('%d removed'), 'status.removed'), status.removed),
4882 (ui.label(_('%d renamed'), 'status.copied'), renamed),
4884 (ui.label(_('%d renamed'), 'status.copied'), renamed),
4883 (ui.label(_('%d copied'), 'status.copied'), copied),
4885 (ui.label(_('%d copied'), 'status.copied'), copied),
4884 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
4886 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
4885 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
4887 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
4886 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
4888 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
4887 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
4889 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
4888 t = []
4890 t = []
4889 for l, s in labels:
4891 for l, s in labels:
4890 if s:
4892 if s:
4891 t.append(l % len(s))
4893 t.append(l % len(s))
4892
4894
4893 t = ', '.join(t)
4895 t = ', '.join(t)
4894 cleanworkdir = False
4896 cleanworkdir = False
4895
4897
4896 if repo.vfs.exists('graftstate'):
4898 if repo.vfs.exists('graftstate'):
4897 t += _(' (graft in progress)')
4899 t += _(' (graft in progress)')
4898 if repo.vfs.exists('updatestate'):
4900 if repo.vfs.exists('updatestate'):
4899 t += _(' (interrupted update)')
4901 t += _(' (interrupted update)')
4900 elif len(parents) > 1:
4902 elif len(parents) > 1:
4901 t += _(' (merge)')
4903 t += _(' (merge)')
4902 elif branch != parents[0].branch():
4904 elif branch != parents[0].branch():
4903 t += _(' (new branch)')
4905 t += _(' (new branch)')
4904 elif (parents[0].closesbranch() and
4906 elif (parents[0].closesbranch() and
4905 pnode in repo.branchheads(branch, closed=True)):
4907 pnode in repo.branchheads(branch, closed=True)):
4906 t += _(' (head closed)')
4908 t += _(' (head closed)')
4907 elif not (status.modified or status.added or status.removed or renamed or
4909 elif not (status.modified or status.added or status.removed or renamed or
4908 copied or subs):
4910 copied or subs):
4909 t += _(' (clean)')
4911 t += _(' (clean)')
4910 cleanworkdir = True
4912 cleanworkdir = True
4911 elif pnode not in bheads:
4913 elif pnode not in bheads:
4912 t += _(' (new branch head)')
4914 t += _(' (new branch head)')
4913
4915
4914 if parents:
4916 if parents:
4915 pendingphase = max(p.phase() for p in parents)
4917 pendingphase = max(p.phase() for p in parents)
4916 else:
4918 else:
4917 pendingphase = phases.public
4919 pendingphase = phases.public
4918
4920
4919 if pendingphase > phases.newcommitphase(ui):
4921 if pendingphase > phases.newcommitphase(ui):
4920 t += ' (%s)' % phases.phasenames[pendingphase]
4922 t += ' (%s)' % phases.phasenames[pendingphase]
4921
4923
4922 if cleanworkdir:
4924 if cleanworkdir:
4923 # i18n: column positioning for "hg summary"
4925 # i18n: column positioning for "hg summary"
4924 ui.status(_('commit: %s\n') % t.strip())
4926 ui.status(_('commit: %s\n') % t.strip())
4925 else:
4927 else:
4926 # i18n: column positioning for "hg summary"
4928 # i18n: column positioning for "hg summary"
4927 ui.write(_('commit: %s\n') % t.strip())
4929 ui.write(_('commit: %s\n') % t.strip())
4928
4930
4929 # all ancestors of branch heads - all ancestors of parent = new csets
4931 # all ancestors of branch heads - all ancestors of parent = new csets
4930 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
4932 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
4931 bheads))
4933 bheads))
4932
4934
4933 if new == 0:
4935 if new == 0:
4934 # i18n: column positioning for "hg summary"
4936 # i18n: column positioning for "hg summary"
4935 ui.status(_('update: (current)\n'))
4937 ui.status(_('update: (current)\n'))
4936 elif pnode not in bheads:
4938 elif pnode not in bheads:
4937 # i18n: column positioning for "hg summary"
4939 # i18n: column positioning for "hg summary"
4938 ui.write(_('update: %d new changesets (update)\n') % new)
4940 ui.write(_('update: %d new changesets (update)\n') % new)
4939 else:
4941 else:
4940 # i18n: column positioning for "hg summary"
4942 # i18n: column positioning for "hg summary"
4941 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
4943 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
4942 (new, len(bheads)))
4944 (new, len(bheads)))
4943
4945
4944 t = []
4946 t = []
4945 draft = len(repo.revs('draft()'))
4947 draft = len(repo.revs('draft()'))
4946 if draft:
4948 if draft:
4947 t.append(_('%d draft') % draft)
4949 t.append(_('%d draft') % draft)
4948 secret = len(repo.revs('secret()'))
4950 secret = len(repo.revs('secret()'))
4949 if secret:
4951 if secret:
4950 t.append(_('%d secret') % secret)
4952 t.append(_('%d secret') % secret)
4951
4953
4952 if draft or secret:
4954 if draft or secret:
4953 ui.status(_('phases: %s\n') % ', '.join(t))
4955 ui.status(_('phases: %s\n') % ', '.join(t))
4954
4956
4955 if obsolete.isenabled(repo, obsolete.createmarkersopt):
4957 if obsolete.isenabled(repo, obsolete.createmarkersopt):
4956 for trouble in ("unstable", "divergent", "bumped"):
4958 for trouble in ("unstable", "divergent", "bumped"):
4957 numtrouble = len(repo.revs(trouble + "()"))
4959 numtrouble = len(repo.revs(trouble + "()"))
4958 # We write all the possibilities to ease translation
4960 # We write all the possibilities to ease translation
4959 troublemsg = {
4961 troublemsg = {
4960 "unstable": _("unstable: %d changesets"),
4962 "unstable": _("unstable: %d changesets"),
4961 "divergent": _("divergent: %d changesets"),
4963 "divergent": _("divergent: %d changesets"),
4962 "bumped": _("bumped: %d changesets"),
4964 "bumped": _("bumped: %d changesets"),
4963 }
4965 }
4964 if numtrouble > 0:
4966 if numtrouble > 0:
4965 ui.status(troublemsg[trouble] % numtrouble + "\n")
4967 ui.status(troublemsg[trouble] % numtrouble + "\n")
4966
4968
4967 cmdutil.summaryhooks(ui, repo)
4969 cmdutil.summaryhooks(ui, repo)
4968
4970
4969 if opts.get('remote'):
4971 if opts.get('remote'):
4970 needsincoming, needsoutgoing = True, True
4972 needsincoming, needsoutgoing = True, True
4971 else:
4973 else:
4972 needsincoming, needsoutgoing = False, False
4974 needsincoming, needsoutgoing = False, False
4973 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
4975 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
4974 if i:
4976 if i:
4975 needsincoming = True
4977 needsincoming = True
4976 if o:
4978 if o:
4977 needsoutgoing = True
4979 needsoutgoing = True
4978 if not needsincoming and not needsoutgoing:
4980 if not needsincoming and not needsoutgoing:
4979 return
4981 return
4980
4982
4981 def getincoming():
4983 def getincoming():
4982 source, branches = hg.parseurl(ui.expandpath('default'))
4984 source, branches = hg.parseurl(ui.expandpath('default'))
4983 sbranch = branches[0]
4985 sbranch = branches[0]
4984 try:
4986 try:
4985 other = hg.peer(repo, {}, source)
4987 other = hg.peer(repo, {}, source)
4986 except error.RepoError:
4988 except error.RepoError:
4987 if opts.get('remote'):
4989 if opts.get('remote'):
4988 raise
4990 raise
4989 return source, sbranch, None, None, None
4991 return source, sbranch, None, None, None
4990 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
4992 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
4991 if revs:
4993 if revs:
4992 revs = [other.lookup(rev) for rev in revs]
4994 revs = [other.lookup(rev) for rev in revs]
4993 ui.debug('comparing with %s\n' % util.hidepassword(source))
4995 ui.debug('comparing with %s\n' % util.hidepassword(source))
4994 repo.ui.pushbuffer()
4996 repo.ui.pushbuffer()
4995 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
4997 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
4996 repo.ui.popbuffer()
4998 repo.ui.popbuffer()
4997 return source, sbranch, other, commoninc, commoninc[1]
4999 return source, sbranch, other, commoninc, commoninc[1]
4998
5000
4999 if needsincoming:
5001 if needsincoming:
5000 source, sbranch, sother, commoninc, incoming = getincoming()
5002 source, sbranch, sother, commoninc, incoming = getincoming()
5001 else:
5003 else:
5002 source = sbranch = sother = commoninc = incoming = None
5004 source = sbranch = sother = commoninc = incoming = None
5003
5005
5004 def getoutgoing():
5006 def getoutgoing():
5005 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5007 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5006 dbranch = branches[0]
5008 dbranch = branches[0]
5007 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5009 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5008 if source != dest:
5010 if source != dest:
5009 try:
5011 try:
5010 dother = hg.peer(repo, {}, dest)
5012 dother = hg.peer(repo, {}, dest)
5011 except error.RepoError:
5013 except error.RepoError:
5012 if opts.get('remote'):
5014 if opts.get('remote'):
5013 raise
5015 raise
5014 return dest, dbranch, None, None
5016 return dest, dbranch, None, None
5015 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5017 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5016 elif sother is None:
5018 elif sother is None:
5017 # there is no explicit destination peer, but source one is invalid
5019 # there is no explicit destination peer, but source one is invalid
5018 return dest, dbranch, None, None
5020 return dest, dbranch, None, None
5019 else:
5021 else:
5020 dother = sother
5022 dother = sother
5021 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5023 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5022 common = None
5024 common = None
5023 else:
5025 else:
5024 common = commoninc
5026 common = commoninc
5025 if revs:
5027 if revs:
5026 revs = [repo.lookup(rev) for rev in revs]
5028 revs = [repo.lookup(rev) for rev in revs]
5027 repo.ui.pushbuffer()
5029 repo.ui.pushbuffer()
5028 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5030 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5029 commoninc=common)
5031 commoninc=common)
5030 repo.ui.popbuffer()
5032 repo.ui.popbuffer()
5031 return dest, dbranch, dother, outgoing
5033 return dest, dbranch, dother, outgoing
5032
5034
5033 if needsoutgoing:
5035 if needsoutgoing:
5034 dest, dbranch, dother, outgoing = getoutgoing()
5036 dest, dbranch, dother, outgoing = getoutgoing()
5035 else:
5037 else:
5036 dest = dbranch = dother = outgoing = None
5038 dest = dbranch = dother = outgoing = None
5037
5039
5038 if opts.get('remote'):
5040 if opts.get('remote'):
5039 t = []
5041 t = []
5040 if incoming:
5042 if incoming:
5041 t.append(_('1 or more incoming'))
5043 t.append(_('1 or more incoming'))
5042 o = outgoing.missing
5044 o = outgoing.missing
5043 if o:
5045 if o:
5044 t.append(_('%d outgoing') % len(o))
5046 t.append(_('%d outgoing') % len(o))
5045 other = dother or sother
5047 other = dother or sother
5046 if 'bookmarks' in other.listkeys('namespaces'):
5048 if 'bookmarks' in other.listkeys('namespaces'):
5047 counts = bookmarks.summary(repo, other)
5049 counts = bookmarks.summary(repo, other)
5048 if counts[0] > 0:
5050 if counts[0] > 0:
5049 t.append(_('%d incoming bookmarks') % counts[0])
5051 t.append(_('%d incoming bookmarks') % counts[0])
5050 if counts[1] > 0:
5052 if counts[1] > 0:
5051 t.append(_('%d outgoing bookmarks') % counts[1])
5053 t.append(_('%d outgoing bookmarks') % counts[1])
5052
5054
5053 if t:
5055 if t:
5054 # i18n: column positioning for "hg summary"
5056 # i18n: column positioning for "hg summary"
5055 ui.write(_('remote: %s\n') % (', '.join(t)))
5057 ui.write(_('remote: %s\n') % (', '.join(t)))
5056 else:
5058 else:
5057 # i18n: column positioning for "hg summary"
5059 # i18n: column positioning for "hg summary"
5058 ui.status(_('remote: (synced)\n'))
5060 ui.status(_('remote: (synced)\n'))
5059
5061
5060 cmdutil.summaryremotehooks(ui, repo, opts,
5062 cmdutil.summaryremotehooks(ui, repo, opts,
5061 ((source, sbranch, sother, commoninc),
5063 ((source, sbranch, sother, commoninc),
5062 (dest, dbranch, dother, outgoing)))
5064 (dest, dbranch, dother, outgoing)))
5063
5065
5064 @command('tag',
5066 @command('tag',
5065 [('f', 'force', None, _('force tag')),
5067 [('f', 'force', None, _('force tag')),
5066 ('l', 'local', None, _('make the tag local')),
5068 ('l', 'local', None, _('make the tag local')),
5067 ('r', 'rev', '', _('revision to tag'), _('REV')),
5069 ('r', 'rev', '', _('revision to tag'), _('REV')),
5068 ('', 'remove', None, _('remove a tag')),
5070 ('', 'remove', None, _('remove a tag')),
5069 # -l/--local is already there, commitopts cannot be used
5071 # -l/--local is already there, commitopts cannot be used
5070 ('e', 'edit', None, _('invoke editor on commit messages')),
5072 ('e', 'edit', None, _('invoke editor on commit messages')),
5071 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5073 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
5072 ] + commitopts2,
5074 ] + commitopts2,
5073 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5075 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5074 def tag(ui, repo, name1, *names, **opts):
5076 def tag(ui, repo, name1, *names, **opts):
5075 """add one or more tags for the current or given revision
5077 """add one or more tags for the current or given revision
5076
5078
5077 Name a particular revision using <name>.
5079 Name a particular revision using <name>.
5078
5080
5079 Tags are used to name particular revisions of the repository and are
5081 Tags are used to name particular revisions of the repository and are
5080 very useful to compare different revisions, to go back to significant
5082 very useful to compare different revisions, to go back to significant
5081 earlier versions or to mark branch points as releases, etc. Changing
5083 earlier versions or to mark branch points as releases, etc. Changing
5082 an existing tag is normally disallowed; use -f/--force to override.
5084 an existing tag is normally disallowed; use -f/--force to override.
5083
5085
5084 If no revision is given, the parent of the working directory is
5086 If no revision is given, the parent of the working directory is
5085 used.
5087 used.
5086
5088
5087 To facilitate version control, distribution, and merging of tags,
5089 To facilitate version control, distribution, and merging of tags,
5088 they are stored as a file named ".hgtags" which is managed similarly
5090 they are stored as a file named ".hgtags" which is managed similarly
5089 to other project files and can be hand-edited if necessary. This
5091 to other project files and can be hand-edited if necessary. This
5090 also means that tagging creates a new commit. The file
5092 also means that tagging creates a new commit. The file
5091 ".hg/localtags" is used for local tags (not shared among
5093 ".hg/localtags" is used for local tags (not shared among
5092 repositories).
5094 repositories).
5093
5095
5094 Tag commits are usually made at the head of a branch. If the parent
5096 Tag commits are usually made at the head of a branch. If the parent
5095 of the working directory is not a branch head, :hg:`tag` aborts; use
5097 of the working directory is not a branch head, :hg:`tag` aborts; use
5096 -f/--force to force the tag commit to be based on a non-head
5098 -f/--force to force the tag commit to be based on a non-head
5097 changeset.
5099 changeset.
5098
5100
5099 See :hg:`help dates` for a list of formats valid for -d/--date.
5101 See :hg:`help dates` for a list of formats valid for -d/--date.
5100
5102
5101 Since tag names have priority over branch names during revision
5103 Since tag names have priority over branch names during revision
5102 lookup, using an existing branch name as a tag name is discouraged.
5104 lookup, using an existing branch name as a tag name is discouraged.
5103
5105
5104 Returns 0 on success.
5106 Returns 0 on success.
5105 """
5107 """
5106 wlock = lock = None
5108 wlock = lock = None
5107 try:
5109 try:
5108 wlock = repo.wlock()
5110 wlock = repo.wlock()
5109 lock = repo.lock()
5111 lock = repo.lock()
5110 rev_ = "."
5112 rev_ = "."
5111 names = [t.strip() for t in (name1,) + names]
5113 names = [t.strip() for t in (name1,) + names]
5112 if len(names) != len(set(names)):
5114 if len(names) != len(set(names)):
5113 raise error.Abort(_('tag names must be unique'))
5115 raise error.Abort(_('tag names must be unique'))
5114 for n in names:
5116 for n in names:
5115 scmutil.checknewlabel(repo, n, 'tag')
5117 scmutil.checknewlabel(repo, n, 'tag')
5116 if not n:
5118 if not n:
5117 raise error.Abort(_('tag names cannot consist entirely of '
5119 raise error.Abort(_('tag names cannot consist entirely of '
5118 'whitespace'))
5120 'whitespace'))
5119 if opts.get('rev') and opts.get('remove'):
5121 if opts.get('rev') and opts.get('remove'):
5120 raise error.Abort(_("--rev and --remove are incompatible"))
5122 raise error.Abort(_("--rev and --remove are incompatible"))
5121 if opts.get('rev'):
5123 if opts.get('rev'):
5122 rev_ = opts['rev']
5124 rev_ = opts['rev']
5123 message = opts.get('message')
5125 message = opts.get('message')
5124 if opts.get('remove'):
5126 if opts.get('remove'):
5125 if opts.get('local'):
5127 if opts.get('local'):
5126 expectedtype = 'local'
5128 expectedtype = 'local'
5127 else:
5129 else:
5128 expectedtype = 'global'
5130 expectedtype = 'global'
5129
5131
5130 for n in names:
5132 for n in names:
5131 if not repo.tagtype(n):
5133 if not repo.tagtype(n):
5132 raise error.Abort(_("tag '%s' does not exist") % n)
5134 raise error.Abort(_("tag '%s' does not exist") % n)
5133 if repo.tagtype(n) != expectedtype:
5135 if repo.tagtype(n) != expectedtype:
5134 if expectedtype == 'global':
5136 if expectedtype == 'global':
5135 raise error.Abort(_("tag '%s' is not a global tag") % n)
5137 raise error.Abort(_("tag '%s' is not a global tag") % n)
5136 else:
5138 else:
5137 raise error.Abort(_("tag '%s' is not a local tag") % n)
5139 raise error.Abort(_("tag '%s' is not a local tag") % n)
5138 rev_ = 'null'
5140 rev_ = 'null'
5139 if not message:
5141 if not message:
5140 # we don't translate commit messages
5142 # we don't translate commit messages
5141 message = 'Removed tag %s' % ', '.join(names)
5143 message = 'Removed tag %s' % ', '.join(names)
5142 elif not opts.get('force'):
5144 elif not opts.get('force'):
5143 for n in names:
5145 for n in names:
5144 if n in repo.tags():
5146 if n in repo.tags():
5145 raise error.Abort(_("tag '%s' already exists "
5147 raise error.Abort(_("tag '%s' already exists "
5146 "(use -f to force)") % n)
5148 "(use -f to force)") % n)
5147 if not opts.get('local'):
5149 if not opts.get('local'):
5148 p1, p2 = repo.dirstate.parents()
5150 p1, p2 = repo.dirstate.parents()
5149 if p2 != nullid:
5151 if p2 != nullid:
5150 raise error.Abort(_('uncommitted merge'))
5152 raise error.Abort(_('uncommitted merge'))
5151 bheads = repo.branchheads()
5153 bheads = repo.branchheads()
5152 if not opts.get('force') and bheads and p1 not in bheads:
5154 if not opts.get('force') and bheads and p1 not in bheads:
5153 raise error.Abort(_('working directory is not at a branch head '
5155 raise error.Abort(_('working directory is not at a branch head '
5154 '(use -f to force)'))
5156 '(use -f to force)'))
5155 r = scmutil.revsingle(repo, rev_).node()
5157 r = scmutil.revsingle(repo, rev_).node()
5156
5158
5157 if not message:
5159 if not message:
5158 # we don't translate commit messages
5160 # we don't translate commit messages
5159 message = ('Added tag %s for changeset %s' %
5161 message = ('Added tag %s for changeset %s' %
5160 (', '.join(names), short(r)))
5162 (', '.join(names), short(r)))
5161
5163
5162 date = opts.get('date')
5164 date = opts.get('date')
5163 if date:
5165 if date:
5164 date = util.parsedate(date)
5166 date = util.parsedate(date)
5165
5167
5166 if opts.get('remove'):
5168 if opts.get('remove'):
5167 editform = 'tag.remove'
5169 editform = 'tag.remove'
5168 else:
5170 else:
5169 editform = 'tag.add'
5171 editform = 'tag.add'
5170 editor = cmdutil.getcommiteditor(editform=editform, **opts)
5172 editor = cmdutil.getcommiteditor(editform=editform, **opts)
5171
5173
5172 # don't allow tagging the null rev
5174 # don't allow tagging the null rev
5173 if (not opts.get('remove') and
5175 if (not opts.get('remove') and
5174 scmutil.revsingle(repo, rev_).rev() == nullrev):
5176 scmutil.revsingle(repo, rev_).rev() == nullrev):
5175 raise error.Abort(_("cannot tag null revision"))
5177 raise error.Abort(_("cannot tag null revision"))
5176
5178
5177 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
5179 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
5178 editor=editor)
5180 editor=editor)
5179 finally:
5181 finally:
5180 release(lock, wlock)
5182 release(lock, wlock)
5181
5183
5182 @command('tags', formatteropts, '')
5184 @command('tags', formatteropts, '')
5183 def tags(ui, repo, **opts):
5185 def tags(ui, repo, **opts):
5184 """list repository tags
5186 """list repository tags
5185
5187
5186 This lists both regular and local tags. When the -v/--verbose
5188 This lists both regular and local tags. When the -v/--verbose
5187 switch is used, a third column "local" is printed for local tags.
5189 switch is used, a third column "local" is printed for local tags.
5188 When the -q/--quiet switch is used, only the tag name is printed.
5190 When the -q/--quiet switch is used, only the tag name is printed.
5189
5191
5190 Returns 0 on success.
5192 Returns 0 on success.
5191 """
5193 """
5192
5194
5193 fm = ui.formatter('tags', opts)
5195 fm = ui.formatter('tags', opts)
5194 hexfunc = fm.hexfunc
5196 hexfunc = fm.hexfunc
5195 tagtype = ""
5197 tagtype = ""
5196
5198
5197 for t, n in reversed(repo.tagslist()):
5199 for t, n in reversed(repo.tagslist()):
5198 hn = hexfunc(n)
5200 hn = hexfunc(n)
5199 label = 'tags.normal'
5201 label = 'tags.normal'
5200 tagtype = ''
5202 tagtype = ''
5201 if repo.tagtype(t) == 'local':
5203 if repo.tagtype(t) == 'local':
5202 label = 'tags.local'
5204 label = 'tags.local'
5203 tagtype = 'local'
5205 tagtype = 'local'
5204
5206
5205 fm.startitem()
5207 fm.startitem()
5206 fm.write('tag', '%s', t, label=label)
5208 fm.write('tag', '%s', t, label=label)
5207 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5209 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5208 fm.condwrite(not ui.quiet, 'rev node', fmt,
5210 fm.condwrite(not ui.quiet, 'rev node', fmt,
5209 repo.changelog.rev(n), hn, label=label)
5211 repo.changelog.rev(n), hn, label=label)
5210 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5212 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5211 tagtype, label=label)
5213 tagtype, label=label)
5212 fm.plain('\n')
5214 fm.plain('\n')
5213 fm.end()
5215 fm.end()
5214
5216
5215 @command('tip',
5217 @command('tip',
5216 [('p', 'patch', None, _('show patch')),
5218 [('p', 'patch', None, _('show patch')),
5217 ('g', 'git', None, _('use git extended diff format')),
5219 ('g', 'git', None, _('use git extended diff format')),
5218 ] + templateopts,
5220 ] + templateopts,
5219 _('[-p] [-g]'))
5221 _('[-p] [-g]'))
5220 def tip(ui, repo, **opts):
5222 def tip(ui, repo, **opts):
5221 """show the tip revision (DEPRECATED)
5223 """show the tip revision (DEPRECATED)
5222
5224
5223 The tip revision (usually just called the tip) is the changeset
5225 The tip revision (usually just called the tip) is the changeset
5224 most recently added to the repository (and therefore the most
5226 most recently added to the repository (and therefore the most
5225 recently changed head).
5227 recently changed head).
5226
5228
5227 If you have just made a commit, that commit will be the tip. If
5229 If you have just made a commit, that commit will be the tip. If
5228 you have just pulled changes from another repository, the tip of
5230 you have just pulled changes from another repository, the tip of
5229 that repository becomes the current tip. The "tip" tag is special
5231 that repository becomes the current tip. The "tip" tag is special
5230 and cannot be renamed or assigned to a different changeset.
5232 and cannot be renamed or assigned to a different changeset.
5231
5233
5232 This command is deprecated, please use :hg:`heads` instead.
5234 This command is deprecated, please use :hg:`heads` instead.
5233
5235
5234 Returns 0 on success.
5236 Returns 0 on success.
5235 """
5237 """
5236 displayer = cmdutil.show_changeset(ui, repo, opts)
5238 displayer = cmdutil.show_changeset(ui, repo, opts)
5237 displayer.show(repo['tip'])
5239 displayer.show(repo['tip'])
5238 displayer.close()
5240 displayer.close()
5239
5241
5240 @command('unbundle',
5242 @command('unbundle',
5241 [('u', 'update', None,
5243 [('u', 'update', None,
5242 _('update to new branch head if changesets were unbundled'))],
5244 _('update to new branch head if changesets were unbundled'))],
5243 _('[-u] FILE...'))
5245 _('[-u] FILE...'))
5244 def unbundle(ui, repo, fname1, *fnames, **opts):
5246 def unbundle(ui, repo, fname1, *fnames, **opts):
5245 """apply one or more changegroup files
5247 """apply one or more changegroup files
5246
5248
5247 Apply one or more compressed changegroup files generated by the
5249 Apply one or more compressed changegroup files generated by the
5248 bundle command.
5250 bundle command.
5249
5251
5250 Returns 0 on success, 1 if an update has unresolved files.
5252 Returns 0 on success, 1 if an update has unresolved files.
5251 """
5253 """
5252 fnames = (fname1,) + fnames
5254 fnames = (fname1,) + fnames
5253
5255
5254 with repo.lock():
5256 with repo.lock():
5255 for fname in fnames:
5257 for fname in fnames:
5256 f = hg.openpath(ui, fname)
5258 f = hg.openpath(ui, fname)
5257 gen = exchange.readbundle(ui, f, fname)
5259 gen = exchange.readbundle(ui, f, fname)
5258 if isinstance(gen, bundle2.unbundle20):
5260 if isinstance(gen, bundle2.unbundle20):
5259 tr = repo.transaction('unbundle')
5261 tr = repo.transaction('unbundle')
5260 try:
5262 try:
5261 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
5263 op = bundle2.applybundle(repo, gen, tr, source='unbundle',
5262 url='bundle:' + fname)
5264 url='bundle:' + fname)
5263 tr.close()
5265 tr.close()
5264 except error.BundleUnknownFeatureError as exc:
5266 except error.BundleUnknownFeatureError as exc:
5265 raise error.Abort(_('%s: unknown bundle feature, %s')
5267 raise error.Abort(_('%s: unknown bundle feature, %s')
5266 % (fname, exc),
5268 % (fname, exc),
5267 hint=_("see https://mercurial-scm.org/"
5269 hint=_("see https://mercurial-scm.org/"
5268 "wiki/BundleFeature for more "
5270 "wiki/BundleFeature for more "
5269 "information"))
5271 "information"))
5270 finally:
5272 finally:
5271 if tr:
5273 if tr:
5272 tr.release()
5274 tr.release()
5273 changes = [r.get('return', 0)
5275 changes = [r.get('return', 0)
5274 for r in op.records['changegroup']]
5276 for r in op.records['changegroup']]
5275 modheads = changegroup.combineresults(changes)
5277 modheads = changegroup.combineresults(changes)
5276 elif isinstance(gen, streamclone.streamcloneapplier):
5278 elif isinstance(gen, streamclone.streamcloneapplier):
5277 raise error.Abort(
5279 raise error.Abort(
5278 _('packed bundles cannot be applied with '
5280 _('packed bundles cannot be applied with '
5279 '"hg unbundle"'),
5281 '"hg unbundle"'),
5280 hint=_('use "hg debugapplystreamclonebundle"'))
5282 hint=_('use "hg debugapplystreamclonebundle"'))
5281 else:
5283 else:
5282 modheads = gen.apply(repo, 'unbundle', 'bundle:' + fname)
5284 modheads = gen.apply(repo, 'unbundle', 'bundle:' + fname)
5283
5285
5284 return postincoming(ui, repo, modheads, opts.get('update'), None, None)
5286 return postincoming(ui, repo, modheads, opts.get('update'), None, None)
5285
5287
5286 @command('^update|up|checkout|co',
5288 @command('^update|up|checkout|co',
5287 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5289 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5288 ('c', 'check', None, _('require clean working directory')),
5290 ('c', 'check', None, _('require clean working directory')),
5289 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5291 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5290 ('r', 'rev', '', _('revision'), _('REV'))
5292 ('r', 'rev', '', _('revision'), _('REV'))
5291 ] + mergetoolopts,
5293 ] + mergetoolopts,
5292 _('[-C|-c] [-d DATE] [[-r] REV]'))
5294 _('[-C|-c] [-d DATE] [[-r] REV]'))
5293 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
5295 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
5294 tool=None):
5296 tool=None):
5295 """update working directory (or switch revisions)
5297 """update working directory (or switch revisions)
5296
5298
5297 Update the repository's working directory to the specified
5299 Update the repository's working directory to the specified
5298 changeset. If no changeset is specified, update to the tip of the
5300 changeset. If no changeset is specified, update to the tip of the
5299 current named branch and move the active bookmark (see :hg:`help
5301 current named branch and move the active bookmark (see :hg:`help
5300 bookmarks`).
5302 bookmarks`).
5301
5303
5302 Update sets the working directory's parent revision to the specified
5304 Update sets the working directory's parent revision to the specified
5303 changeset (see :hg:`help parents`).
5305 changeset (see :hg:`help parents`).
5304
5306
5305 If the changeset is not a descendant or ancestor of the working
5307 If the changeset is not a descendant or ancestor of the working
5306 directory's parent and there are uncommitted changes, the update is
5308 directory's parent and there are uncommitted changes, the update is
5307 aborted. With the -c/--check option, the working directory is checked
5309 aborted. With the -c/--check option, the working directory is checked
5308 for uncommitted changes; if none are found, the working directory is
5310 for uncommitted changes; if none are found, the working directory is
5309 updated to the specified changeset.
5311 updated to the specified changeset.
5310
5312
5311 .. container:: verbose
5313 .. container:: verbose
5312
5314
5313 The -C/--clean and -c/--check options control what happens if the
5315 The -C/--clean and -c/--check options control what happens if the
5314 working directory contains uncommitted changes.
5316 working directory contains uncommitted changes.
5315 At most of one of them can be specified.
5317 At most of one of them can be specified.
5316
5318
5317 1. If no option is specified, and if
5319 1. If no option is specified, and if
5318 the requested changeset is an ancestor or descendant of
5320 the requested changeset is an ancestor or descendant of
5319 the working directory's parent, the uncommitted changes
5321 the working directory's parent, the uncommitted changes
5320 are merged into the requested changeset and the merged
5322 are merged into the requested changeset and the merged
5321 result is left uncommitted. If the requested changeset is
5323 result is left uncommitted. If the requested changeset is
5322 not an ancestor or descendant (that is, it is on another
5324 not an ancestor or descendant (that is, it is on another
5323 branch), the update is aborted and the uncommitted changes
5325 branch), the update is aborted and the uncommitted changes
5324 are preserved.
5326 are preserved.
5325
5327
5326 2. With the -c/--check option, the update is aborted and the
5328 2. With the -c/--check option, the update is aborted and the
5327 uncommitted changes are preserved.
5329 uncommitted changes are preserved.
5328
5330
5329 3. With the -C/--clean option, uncommitted changes are discarded and
5331 3. With the -C/--clean option, uncommitted changes are discarded and
5330 the working directory is updated to the requested changeset.
5332 the working directory is updated to the requested changeset.
5331
5333
5332 To cancel an uncommitted merge (and lose your changes), use
5334 To cancel an uncommitted merge (and lose your changes), use
5333 :hg:`update --clean .`.
5335 :hg:`update --clean .`.
5334
5336
5335 Use null as the changeset to remove the working directory (like
5337 Use null as the changeset to remove the working directory (like
5336 :hg:`clone -U`).
5338 :hg:`clone -U`).
5337
5339
5338 If you want to revert just one file to an older revision, use
5340 If you want to revert just one file to an older revision, use
5339 :hg:`revert [-r REV] NAME`.
5341 :hg:`revert [-r REV] NAME`.
5340
5342
5341 See :hg:`help dates` for a list of formats valid for -d/--date.
5343 See :hg:`help dates` for a list of formats valid for -d/--date.
5342
5344
5343 Returns 0 on success, 1 if there are unresolved files.
5345 Returns 0 on success, 1 if there are unresolved files.
5344 """
5346 """
5345 if rev and node:
5347 if rev and node:
5346 raise error.Abort(_("please specify just one revision"))
5348 raise error.Abort(_("please specify just one revision"))
5347
5349
5348 if rev is None or rev == '':
5350 if rev is None or rev == '':
5349 rev = node
5351 rev = node
5350
5352
5351 if date and rev is not None:
5353 if date and rev is not None:
5352 raise error.Abort(_("you can't specify a revision and a date"))
5354 raise error.Abort(_("you can't specify a revision and a date"))
5353
5355
5354 if check and clean:
5356 if check and clean:
5355 raise error.Abort(_("cannot specify both -c/--check and -C/--clean"))
5357 raise error.Abort(_("cannot specify both -c/--check and -C/--clean"))
5356
5358
5357 with repo.wlock():
5359 with repo.wlock():
5358 cmdutil.clearunfinished(repo)
5360 cmdutil.clearunfinished(repo)
5359
5361
5360 if date:
5362 if date:
5361 rev = cmdutil.finddate(ui, repo, date)
5363 rev = cmdutil.finddate(ui, repo, date)
5362
5364
5363 # if we defined a bookmark, we have to remember the original name
5365 # if we defined a bookmark, we have to remember the original name
5364 brev = rev
5366 brev = rev
5365 rev = scmutil.revsingle(repo, rev, rev).rev()
5367 rev = scmutil.revsingle(repo, rev, rev).rev()
5366
5368
5367 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
5369 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
5368
5370
5369 return hg.updatetotally(ui, repo, rev, brev, clean=clean, check=check)
5371 return hg.updatetotally(ui, repo, rev, brev, clean=clean, check=check)
5370
5372
5371 @command('verify', [])
5373 @command('verify', [])
5372 def verify(ui, repo):
5374 def verify(ui, repo):
5373 """verify the integrity of the repository
5375 """verify the integrity of the repository
5374
5376
5375 Verify the integrity of the current repository.
5377 Verify the integrity of the current repository.
5376
5378
5377 This will perform an extensive check of the repository's
5379 This will perform an extensive check of the repository's
5378 integrity, validating the hashes and checksums of each entry in
5380 integrity, validating the hashes and checksums of each entry in
5379 the changelog, manifest, and tracked files, as well as the
5381 the changelog, manifest, and tracked files, as well as the
5380 integrity of their crosslinks and indices.
5382 integrity of their crosslinks and indices.
5381
5383
5382 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
5384 Please see https://mercurial-scm.org/wiki/RepositoryCorruption
5383 for more information about recovery from corruption of the
5385 for more information about recovery from corruption of the
5384 repository.
5386 repository.
5385
5387
5386 Returns 0 on success, 1 if errors are encountered.
5388 Returns 0 on success, 1 if errors are encountered.
5387 """
5389 """
5388 return hg.verify(repo)
5390 return hg.verify(repo)
5389
5391
5390 @command('version', [] + formatteropts, norepo=True)
5392 @command('version', [] + formatteropts, norepo=True)
5391 def version_(ui, **opts):
5393 def version_(ui, **opts):
5392 """output version and copyright information"""
5394 """output version and copyright information"""
5393 fm = ui.formatter("version", opts)
5395 fm = ui.formatter("version", opts)
5394 fm.startitem()
5396 fm.startitem()
5395 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
5397 fm.write("ver", _("Mercurial Distributed SCM (version %s)\n"),
5396 util.version())
5398 util.version())
5397 license = _(
5399 license = _(
5398 "(see https://mercurial-scm.org for more information)\n"
5400 "(see https://mercurial-scm.org for more information)\n"
5399 "\nCopyright (C) 2005-2017 Matt Mackall and others\n"
5401 "\nCopyright (C) 2005-2017 Matt Mackall and others\n"
5400 "This is free software; see the source for copying conditions. "
5402 "This is free software; see the source for copying conditions. "
5401 "There is NO\nwarranty; "
5403 "There is NO\nwarranty; "
5402 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5404 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5403 )
5405 )
5404 if not ui.quiet:
5406 if not ui.quiet:
5405 fm.plain(license)
5407 fm.plain(license)
5406
5408
5407 if ui.verbose:
5409 if ui.verbose:
5408 fm.plain(_("\nEnabled extensions:\n\n"))
5410 fm.plain(_("\nEnabled extensions:\n\n"))
5409 # format names and versions into columns
5411 # format names and versions into columns
5410 names = []
5412 names = []
5411 vers = []
5413 vers = []
5412 isinternals = []
5414 isinternals = []
5413 for name, module in extensions.extensions():
5415 for name, module in extensions.extensions():
5414 names.append(name)
5416 names.append(name)
5415 vers.append(extensions.moduleversion(module) or None)
5417 vers.append(extensions.moduleversion(module) or None)
5416 isinternals.append(extensions.ismoduleinternal(module))
5418 isinternals.append(extensions.ismoduleinternal(module))
5417 fn = fm.nested("extensions")
5419 fn = fm.nested("extensions")
5418 if names:
5420 if names:
5419 namefmt = " %%-%ds " % max(len(n) for n in names)
5421 namefmt = " %%-%ds " % max(len(n) for n in names)
5420 places = [_("external"), _("internal")]
5422 places = [_("external"), _("internal")]
5421 for n, v, p in zip(names, vers, isinternals):
5423 for n, v, p in zip(names, vers, isinternals):
5422 fn.startitem()
5424 fn.startitem()
5423 fn.condwrite(ui.verbose, "name", namefmt, n)
5425 fn.condwrite(ui.verbose, "name", namefmt, n)
5424 if ui.verbose:
5426 if ui.verbose:
5425 fn.plain("%s " % places[p])
5427 fn.plain("%s " % places[p])
5426 fn.data(bundled=p)
5428 fn.data(bundled=p)
5427 fn.condwrite(ui.verbose and v, "ver", "%s", v)
5429 fn.condwrite(ui.verbose and v, "ver", "%s", v)
5428 if ui.verbose:
5430 if ui.verbose:
5429 fn.plain("\n")
5431 fn.plain("\n")
5430 fn.end()
5432 fn.end()
5431 fm.end()
5433 fm.end()
5432
5434
5433 def loadcmdtable(ui, name, cmdtable):
5435 def loadcmdtable(ui, name, cmdtable):
5434 """Load command functions from specified cmdtable
5436 """Load command functions from specified cmdtable
5435 """
5437 """
5436 overrides = [cmd for cmd in cmdtable if cmd in table]
5438 overrides = [cmd for cmd in cmdtable if cmd in table]
5437 if overrides:
5439 if overrides:
5438 ui.warn(_("extension '%s' overrides commands: %s\n")
5440 ui.warn(_("extension '%s' overrides commands: %s\n")
5439 % (name, " ".join(overrides)))
5441 % (name, " ".join(overrides)))
5440 table.update(cmdtable)
5442 table.update(cmdtable)
@@ -1,892 +1,894 b''
1 # dispatch.py - command dispatching for mercurial
1 # dispatch.py - command dispatching for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import, print_function
8 from __future__ import absolute_import, print_function
9
9
10 import atexit
10 import atexit
11 import difflib
11 import difflib
12 import errno
12 import errno
13 import getopt
13 import getopt
14 import os
14 import os
15 import pdb
15 import pdb
16 import re
16 import re
17 import signal
17 import signal
18 import sys
18 import sys
19 import time
19 import time
20 import traceback
20 import traceback
21
21
22
22
23 from .i18n import _
23 from .i18n import _
24
24
25 from . import (
25 from . import (
26 cmdutil,
26 cmdutil,
27 color,
27 color,
28 commands,
28 commands,
29 debugcommands,
29 debugcommands,
30 demandimport,
30 demandimport,
31 encoding,
31 encoding,
32 error,
32 error,
33 extensions,
33 extensions,
34 fancyopts,
34 fancyopts,
35 fileset,
35 fileset,
36 hg,
36 hg,
37 hook,
37 hook,
38 profiling,
38 profiling,
39 pycompat,
39 pycompat,
40 revset,
40 revset,
41 scmutil,
41 scmutil,
42 templatefilters,
42 templatefilters,
43 templatekw,
43 templatekw,
44 templater,
44 templater,
45 ui as uimod,
45 ui as uimod,
46 util,
46 util,
47 )
47 )
48
48
49 class request(object):
49 class request(object):
50 def __init__(self, args, ui=None, repo=None, fin=None, fout=None,
50 def __init__(self, args, ui=None, repo=None, fin=None, fout=None,
51 ferr=None):
51 ferr=None):
52 self.args = args
52 self.args = args
53 self.ui = ui
53 self.ui = ui
54 self.repo = repo
54 self.repo = repo
55
55
56 # input/output/error streams
56 # input/output/error streams
57 self.fin = fin
57 self.fin = fin
58 self.fout = fout
58 self.fout = fout
59 self.ferr = ferr
59 self.ferr = ferr
60
60
61 def run():
61 def run():
62 "run the command in sys.argv"
62 "run the command in sys.argv"
63 sys.exit((dispatch(request(pycompat.sysargv[1:])) or 0) & 255)
63 sys.exit((dispatch(request(pycompat.sysargv[1:])) or 0) & 255)
64
64
65 def _getsimilar(symbols, value):
65 def _getsimilar(symbols, value):
66 sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio()
66 sim = lambda x: difflib.SequenceMatcher(None, value, x).ratio()
67 # The cutoff for similarity here is pretty arbitrary. It should
67 # The cutoff for similarity here is pretty arbitrary. It should
68 # probably be investigated and tweaked.
68 # probably be investigated and tweaked.
69 return [s for s in symbols if sim(s) > 0.6]
69 return [s for s in symbols if sim(s) > 0.6]
70
70
71 def _reportsimilar(write, similar):
71 def _reportsimilar(write, similar):
72 if len(similar) == 1:
72 if len(similar) == 1:
73 write(_("(did you mean %s?)\n") % similar[0])
73 write(_("(did you mean %s?)\n") % similar[0])
74 elif similar:
74 elif similar:
75 ss = ", ".join(sorted(similar))
75 ss = ", ".join(sorted(similar))
76 write(_("(did you mean one of %s?)\n") % ss)
76 write(_("(did you mean one of %s?)\n") % ss)
77
77
78 def _formatparse(write, inst):
78 def _formatparse(write, inst):
79 similar = []
79 similar = []
80 if isinstance(inst, error.UnknownIdentifier):
80 if isinstance(inst, error.UnknownIdentifier):
81 # make sure to check fileset first, as revset can invoke fileset
81 # make sure to check fileset first, as revset can invoke fileset
82 similar = _getsimilar(inst.symbols, inst.function)
82 similar = _getsimilar(inst.symbols, inst.function)
83 if len(inst.args) > 1:
83 if len(inst.args) > 1:
84 write(_("hg: parse error at %s: %s\n") %
84 write(_("hg: parse error at %s: %s\n") %
85 (inst.args[1], inst.args[0]))
85 (inst.args[1], inst.args[0]))
86 if (inst.args[0][0] == ' '):
86 if (inst.args[0][0] == ' '):
87 write(_("unexpected leading whitespace\n"))
87 write(_("unexpected leading whitespace\n"))
88 else:
88 else:
89 write(_("hg: parse error: %s\n") % inst.args[0])
89 write(_("hg: parse error: %s\n") % inst.args[0])
90 _reportsimilar(write, similar)
90 _reportsimilar(write, similar)
91 if inst.hint:
91 if inst.hint:
92 write(_("(%s)\n") % inst.hint)
92 write(_("(%s)\n") % inst.hint)
93
93
94 def dispatch(req):
94 def dispatch(req):
95 "run the command specified in req.args"
95 "run the command specified in req.args"
96 if req.ferr:
96 if req.ferr:
97 ferr = req.ferr
97 ferr = req.ferr
98 elif req.ui:
98 elif req.ui:
99 ferr = req.ui.ferr
99 ferr = req.ui.ferr
100 else:
100 else:
101 ferr = util.stderr
101 ferr = util.stderr
102
102
103 try:
103 try:
104 if not req.ui:
104 if not req.ui:
105 req.ui = uimod.ui.load()
105 req.ui = uimod.ui.load()
106 if '--traceback' in req.args:
106 if '--traceback' in req.args:
107 req.ui.setconfig('ui', 'traceback', 'on', '--traceback')
107 req.ui.setconfig('ui', 'traceback', 'on', '--traceback')
108
108
109 # set ui streams from the request
109 # set ui streams from the request
110 if req.fin:
110 if req.fin:
111 req.ui.fin = req.fin
111 req.ui.fin = req.fin
112 if req.fout:
112 if req.fout:
113 req.ui.fout = req.fout
113 req.ui.fout = req.fout
114 if req.ferr:
114 if req.ferr:
115 req.ui.ferr = req.ferr
115 req.ui.ferr = req.ferr
116 except error.Abort as inst:
116 except error.Abort as inst:
117 ferr.write(_("abort: %s\n") % inst)
117 ferr.write(_("abort: %s\n") % inst)
118 if inst.hint:
118 if inst.hint:
119 ferr.write(_("(%s)\n") % inst.hint)
119 ferr.write(_("(%s)\n") % inst.hint)
120 return -1
120 return -1
121 except error.ParseError as inst:
121 except error.ParseError as inst:
122 _formatparse(ferr.write, inst)
122 _formatparse(ferr.write, inst)
123 return -1
123 return -1
124
124
125 msg = ' '.join(' ' in a and repr(a) or a for a in req.args)
125 msg = ' '.join(' ' in a and repr(a) or a for a in req.args)
126 starttime = util.timer()
126 starttime = util.timer()
127 ret = None
127 ret = None
128 try:
128 try:
129 ret = _runcatch(req)
129 ret = _runcatch(req)
130 except KeyboardInterrupt:
130 except KeyboardInterrupt:
131 try:
131 try:
132 req.ui.warn(_("interrupted!\n"))
132 req.ui.warn(_("interrupted!\n"))
133 except IOError as inst:
133 except IOError as inst:
134 if inst.errno != errno.EPIPE:
134 if inst.errno != errno.EPIPE:
135 raise
135 raise
136 ret = -1
136 ret = -1
137 finally:
137 finally:
138 duration = util.timer() - starttime
138 duration = util.timer() - starttime
139 req.ui.flush()
139 req.ui.flush()
140 if req.ui.logblockedtimes:
140 if req.ui.logblockedtimes:
141 req.ui._blockedtimes['command_duration'] = duration * 1000
141 req.ui._blockedtimes['command_duration'] = duration * 1000
142 req.ui.log('uiblocked', 'ui blocked ms', **req.ui._blockedtimes)
142 req.ui.log('uiblocked', 'ui blocked ms', **req.ui._blockedtimes)
143 req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n",
143 req.ui.log("commandfinish", "%s exited %s after %0.2f seconds\n",
144 msg, ret or 0, duration)
144 msg, ret or 0, duration)
145 return ret
145 return ret
146
146
147 def _runcatch(req):
147 def _runcatch(req):
148 def catchterm(*args):
148 def catchterm(*args):
149 raise error.SignalInterrupt
149 raise error.SignalInterrupt
150
150
151 ui = req.ui
151 ui = req.ui
152 try:
152 try:
153 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
153 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
154 num = getattr(signal, name, None)
154 num = getattr(signal, name, None)
155 if num:
155 if num:
156 signal.signal(num, catchterm)
156 signal.signal(num, catchterm)
157 except ValueError:
157 except ValueError:
158 pass # happens if called in a thread
158 pass # happens if called in a thread
159
159
160 def _runcatchfunc():
160 def _runcatchfunc():
161 try:
161 try:
162 debugger = 'pdb'
162 debugger = 'pdb'
163 debugtrace = {
163 debugtrace = {
164 'pdb' : pdb.set_trace
164 'pdb' : pdb.set_trace
165 }
165 }
166 debugmortem = {
166 debugmortem = {
167 'pdb' : pdb.post_mortem
167 'pdb' : pdb.post_mortem
168 }
168 }
169
169
170 # read --config before doing anything else
170 # read --config before doing anything else
171 # (e.g. to change trust settings for reading .hg/hgrc)
171 # (e.g. to change trust settings for reading .hg/hgrc)
172 cfgs = _parseconfig(req.ui, _earlygetopt(['--config'], req.args))
172 cfgs = _parseconfig(req.ui, _earlygetopt(['--config'], req.args))
173
173
174 if req.repo:
174 if req.repo:
175 # copy configs that were passed on the cmdline (--config) to
175 # copy configs that were passed on the cmdline (--config) to
176 # the repo ui
176 # the repo ui
177 for sec, name, val in cfgs:
177 for sec, name, val in cfgs:
178 req.repo.ui.setconfig(sec, name, val, source='--config')
178 req.repo.ui.setconfig(sec, name, val, source='--config')
179
179
180 # developer config: ui.debugger
180 # developer config: ui.debugger
181 debugger = ui.config("ui", "debugger")
181 debugger = ui.config("ui", "debugger")
182 debugmod = pdb
182 debugmod = pdb
183 if not debugger or ui.plain():
183 if not debugger or ui.plain():
184 # if we are in HGPLAIN mode, then disable custom debugging
184 # if we are in HGPLAIN mode, then disable custom debugging
185 debugger = 'pdb'
185 debugger = 'pdb'
186 elif '--debugger' in req.args:
186 elif '--debugger' in req.args:
187 # This import can be slow for fancy debuggers, so only
187 # This import can be slow for fancy debuggers, so only
188 # do it when absolutely necessary, i.e. when actual
188 # do it when absolutely necessary, i.e. when actual
189 # debugging has been requested
189 # debugging has been requested
190 with demandimport.deactivated():
190 with demandimport.deactivated():
191 try:
191 try:
192 debugmod = __import__(debugger)
192 debugmod = __import__(debugger)
193 except ImportError:
193 except ImportError:
194 pass # Leave debugmod = pdb
194 pass # Leave debugmod = pdb
195
195
196 debugtrace[debugger] = debugmod.set_trace
196 debugtrace[debugger] = debugmod.set_trace
197 debugmortem[debugger] = debugmod.post_mortem
197 debugmortem[debugger] = debugmod.post_mortem
198
198
199 # enter the debugger before command execution
199 # enter the debugger before command execution
200 if '--debugger' in req.args:
200 if '--debugger' in req.args:
201 ui.warn(_("entering debugger - "
201 ui.warn(_("entering debugger - "
202 "type c to continue starting hg or h for help\n"))
202 "type c to continue starting hg or h for help\n"))
203
203
204 if (debugger != 'pdb' and
204 if (debugger != 'pdb' and
205 debugtrace[debugger] == debugtrace['pdb']):
205 debugtrace[debugger] == debugtrace['pdb']):
206 ui.warn(_("%s debugger specified "
206 ui.warn(_("%s debugger specified "
207 "but its module was not found\n") % debugger)
207 "but its module was not found\n") % debugger)
208 with demandimport.deactivated():
208 with demandimport.deactivated():
209 debugtrace[debugger]()
209 debugtrace[debugger]()
210 try:
210 try:
211 return _dispatch(req)
211 return _dispatch(req)
212 finally:
212 finally:
213 ui.flush()
213 ui.flush()
214 except: # re-raises
214 except: # re-raises
215 # enter the debugger when we hit an exception
215 # enter the debugger when we hit an exception
216 if '--debugger' in req.args:
216 if '--debugger' in req.args:
217 traceback.print_exc()
217 traceback.print_exc()
218 debugmortem[debugger](sys.exc_info()[2])
218 debugmortem[debugger](sys.exc_info()[2])
219 ui.traceback()
219 ui.traceback()
220 raise
220 raise
221
221
222 return callcatch(ui, _runcatchfunc)
222 return callcatch(ui, _runcatchfunc)
223
223
224 def callcatch(ui, func):
224 def callcatch(ui, func):
225 """like scmutil.callcatch but handles more high-level exceptions about
225 """like scmutil.callcatch but handles more high-level exceptions about
226 config parsing and commands. besides, use handlecommandexception to handle
226 config parsing and commands. besides, use handlecommandexception to handle
227 uncaught exceptions.
227 uncaught exceptions.
228 """
228 """
229 try:
229 try:
230 return scmutil.callcatch(ui, func)
230 return scmutil.callcatch(ui, func)
231 except error.AmbiguousCommand as inst:
231 except error.AmbiguousCommand as inst:
232 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
232 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
233 (inst.args[0], " ".join(inst.args[1])))
233 (inst.args[0], " ".join(inst.args[1])))
234 except error.CommandError as inst:
234 except error.CommandError as inst:
235 if inst.args[0]:
235 if inst.args[0]:
236 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
236 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
237 commands.help_(ui, inst.args[0], full=False, command=True)
237 commands.help_(ui, inst.args[0], full=False, command=True)
238 else:
238 else:
239 ui.warn(_("hg: %s\n") % inst.args[1])
239 ui.warn(_("hg: %s\n") % inst.args[1])
240 commands.help_(ui, 'shortlist')
240 commands.help_(ui, 'shortlist')
241 except error.ParseError as inst:
241 except error.ParseError as inst:
242 _formatparse(ui.warn, inst)
242 _formatparse(ui.warn, inst)
243 return -1
243 return -1
244 except error.UnknownCommand as inst:
244 except error.UnknownCommand as inst:
245 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
245 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
246 try:
246 try:
247 # check if the command is in a disabled extension
247 # check if the command is in a disabled extension
248 # (but don't check for extensions themselves)
248 # (but don't check for extensions themselves)
249 commands.help_(ui, inst.args[0], unknowncmd=True)
249 commands.help_(ui, inst.args[0], unknowncmd=True)
250 except (error.UnknownCommand, error.Abort):
250 except (error.UnknownCommand, error.Abort):
251 suggested = False
251 suggested = False
252 if len(inst.args) == 2:
252 if len(inst.args) == 2:
253 sim = _getsimilar(inst.args[1], inst.args[0])
253 sim = _getsimilar(inst.args[1], inst.args[0])
254 if sim:
254 if sim:
255 _reportsimilar(ui.warn, sim)
255 _reportsimilar(ui.warn, sim)
256 suggested = True
256 suggested = True
257 if not suggested:
257 if not suggested:
258 commands.help_(ui, 'shortlist')
258 commands.help_(ui, 'shortlist')
259 except IOError:
259 except IOError:
260 raise
260 raise
261 except KeyboardInterrupt:
261 except KeyboardInterrupt:
262 raise
262 raise
263 except: # probably re-raises
263 except: # probably re-raises
264 if not handlecommandexception(ui):
264 if not handlecommandexception(ui):
265 raise
265 raise
266
266
267 return -1
267 return -1
268
268
269 def aliasargs(fn, givenargs):
269 def aliasargs(fn, givenargs):
270 args = getattr(fn, 'args', [])
270 args = getattr(fn, 'args', [])
271 if args:
271 if args:
272 cmd = ' '.join(map(util.shellquote, args))
272 cmd = ' '.join(map(util.shellquote, args))
273
273
274 nums = []
274 nums = []
275 def replacer(m):
275 def replacer(m):
276 num = int(m.group(1)) - 1
276 num = int(m.group(1)) - 1
277 nums.append(num)
277 nums.append(num)
278 if num < len(givenargs):
278 if num < len(givenargs):
279 return givenargs[num]
279 return givenargs[num]
280 raise error.Abort(_('too few arguments for command alias'))
280 raise error.Abort(_('too few arguments for command alias'))
281 cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
281 cmd = re.sub(r'\$(\d+|\$)', replacer, cmd)
282 givenargs = [x for i, x in enumerate(givenargs)
282 givenargs = [x for i, x in enumerate(givenargs)
283 if i not in nums]
283 if i not in nums]
284 args = pycompat.shlexsplit(cmd)
284 args = pycompat.shlexsplit(cmd)
285 return args + givenargs
285 return args + givenargs
286
286
287 def aliasinterpolate(name, args, cmd):
287 def aliasinterpolate(name, args, cmd):
288 '''interpolate args into cmd for shell aliases
288 '''interpolate args into cmd for shell aliases
289
289
290 This also handles $0, $@ and "$@".
290 This also handles $0, $@ and "$@".
291 '''
291 '''
292 # util.interpolate can't deal with "$@" (with quotes) because it's only
292 # util.interpolate can't deal with "$@" (with quotes) because it's only
293 # built to match prefix + patterns.
293 # built to match prefix + patterns.
294 replacemap = dict(('$%d' % (i + 1), arg) for i, arg in enumerate(args))
294 replacemap = dict(('$%d' % (i + 1), arg) for i, arg in enumerate(args))
295 replacemap['$0'] = name
295 replacemap['$0'] = name
296 replacemap['$$'] = '$'
296 replacemap['$$'] = '$'
297 replacemap['$@'] = ' '.join(args)
297 replacemap['$@'] = ' '.join(args)
298 # Typical Unix shells interpolate "$@" (with quotes) as all the positional
298 # Typical Unix shells interpolate "$@" (with quotes) as all the positional
299 # parameters, separated out into words. Emulate the same behavior here by
299 # parameters, separated out into words. Emulate the same behavior here by
300 # quoting the arguments individually. POSIX shells will then typically
300 # quoting the arguments individually. POSIX shells will then typically
301 # tokenize each argument into exactly one word.
301 # tokenize each argument into exactly one word.
302 replacemap['"$@"'] = ' '.join(util.shellquote(arg) for arg in args)
302 replacemap['"$@"'] = ' '.join(util.shellquote(arg) for arg in args)
303 # escape '\$' for regex
303 # escape '\$' for regex
304 regex = '|'.join(replacemap.keys()).replace('$', r'\$')
304 regex = '|'.join(replacemap.keys()).replace('$', r'\$')
305 r = re.compile(regex)
305 r = re.compile(regex)
306 return r.sub(lambda x: replacemap[x.group()], cmd)
306 return r.sub(lambda x: replacemap[x.group()], cmd)
307
307
308 class cmdalias(object):
308 class cmdalias(object):
309 def __init__(self, name, definition, cmdtable, source):
309 def __init__(self, name, definition, cmdtable, source):
310 self.name = self.cmd = name
310 self.name = self.cmd = name
311 self.cmdname = ''
311 self.cmdname = ''
312 self.definition = definition
312 self.definition = definition
313 self.fn = None
313 self.fn = None
314 self.givenargs = []
314 self.givenargs = []
315 self.opts = []
315 self.opts = []
316 self.help = ''
316 self.help = ''
317 self.badalias = None
317 self.badalias = None
318 self.unknowncmd = False
318 self.unknowncmd = False
319 self.source = source
319 self.source = source
320
320
321 try:
321 try:
322 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
322 aliases, entry = cmdutil.findcmd(self.name, cmdtable)
323 for alias, e in cmdtable.iteritems():
323 for alias, e in cmdtable.iteritems():
324 if e is entry:
324 if e is entry:
325 self.cmd = alias
325 self.cmd = alias
326 break
326 break
327 self.shadows = True
327 self.shadows = True
328 except error.UnknownCommand:
328 except error.UnknownCommand:
329 self.shadows = False
329 self.shadows = False
330
330
331 if not self.definition:
331 if not self.definition:
332 self.badalias = _("no definition for alias '%s'") % self.name
332 self.badalias = _("no definition for alias '%s'") % self.name
333 return
333 return
334
334
335 if self.definition.startswith('!'):
335 if self.definition.startswith('!'):
336 self.shell = True
336 self.shell = True
337 def fn(ui, *args):
337 def fn(ui, *args):
338 env = {'HG_ARGS': ' '.join((self.name,) + args)}
338 env = {'HG_ARGS': ' '.join((self.name,) + args)}
339 def _checkvar(m):
339 def _checkvar(m):
340 if m.groups()[0] == '$':
340 if m.groups()[0] == '$':
341 return m.group()
341 return m.group()
342 elif int(m.groups()[0]) <= len(args):
342 elif int(m.groups()[0]) <= len(args):
343 return m.group()
343 return m.group()
344 else:
344 else:
345 ui.debug("No argument found for substitution "
345 ui.debug("No argument found for substitution "
346 "of %i variable in alias '%s' definition."
346 "of %i variable in alias '%s' definition."
347 % (int(m.groups()[0]), self.name))
347 % (int(m.groups()[0]), self.name))
348 return ''
348 return ''
349 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
349 cmd = re.sub(r'\$(\d+|\$)', _checkvar, self.definition[1:])
350 cmd = aliasinterpolate(self.name, args, cmd)
350 cmd = aliasinterpolate(self.name, args, cmd)
351 return ui.system(cmd, environ=env)
351 return ui.system(cmd, environ=env)
352 self.fn = fn
352 self.fn = fn
353 return
353 return
354
354
355 try:
355 try:
356 args = pycompat.shlexsplit(self.definition)
356 args = pycompat.shlexsplit(self.definition)
357 except ValueError as inst:
357 except ValueError as inst:
358 self.badalias = (_("error in definition for alias '%s': %s")
358 self.badalias = (_("error in definition for alias '%s': %s")
359 % (self.name, inst))
359 % (self.name, inst))
360 return
360 return
361 self.cmdname = cmd = args.pop(0)
361 self.cmdname = cmd = args.pop(0)
362 self.givenargs = args
362 self.givenargs = args
363
363
364 for invalidarg in ("--cwd", "-R", "--repository", "--repo", "--config"):
364 for invalidarg in ("--cwd", "-R", "--repository", "--repo", "--config"):
365 if _earlygetopt([invalidarg], args):
365 if _earlygetopt([invalidarg], args):
366 self.badalias = (_("error in definition for alias '%s': %s may "
366 self.badalias = (_("error in definition for alias '%s': %s may "
367 "only be given on the command line")
367 "only be given on the command line")
368 % (self.name, invalidarg))
368 % (self.name, invalidarg))
369 return
369 return
370
370
371 try:
371 try:
372 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
372 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
373 if len(tableentry) > 2:
373 if len(tableentry) > 2:
374 self.fn, self.opts, self.help = tableentry
374 self.fn, self.opts, self.help = tableentry
375 else:
375 else:
376 self.fn, self.opts = tableentry
376 self.fn, self.opts = tableentry
377
377
378 if self.help.startswith("hg " + cmd):
378 if self.help.startswith("hg " + cmd):
379 # drop prefix in old-style help lines so hg shows the alias
379 # drop prefix in old-style help lines so hg shows the alias
380 self.help = self.help[4 + len(cmd):]
380 self.help = self.help[4 + len(cmd):]
381 self.__doc__ = self.fn.__doc__
381 self.__doc__ = self.fn.__doc__
382
382
383 except error.UnknownCommand:
383 except error.UnknownCommand:
384 self.badalias = (_("alias '%s' resolves to unknown command '%s'")
384 self.badalias = (_("alias '%s' resolves to unknown command '%s'")
385 % (self.name, cmd))
385 % (self.name, cmd))
386 self.unknowncmd = True
386 self.unknowncmd = True
387 except error.AmbiguousCommand:
387 except error.AmbiguousCommand:
388 self.badalias = (_("alias '%s' resolves to ambiguous command '%s'")
388 self.badalias = (_("alias '%s' resolves to ambiguous command '%s'")
389 % (self.name, cmd))
389 % (self.name, cmd))
390
390
391 @property
391 @property
392 def args(self):
392 def args(self):
393 args = map(util.expandpath, self.givenargs)
393 args = map(util.expandpath, self.givenargs)
394 return aliasargs(self.fn, args)
394 return aliasargs(self.fn, args)
395
395
396 def __getattr__(self, name):
396 def __getattr__(self, name):
397 adefaults = {'norepo': True, 'optionalrepo': False, 'inferrepo': False}
397 adefaults = {'norepo': True, 'optionalrepo': False, 'inferrepo': False}
398 if name not in adefaults:
398 if name not in adefaults:
399 raise AttributeError(name)
399 raise AttributeError(name)
400 if self.badalias or util.safehasattr(self, 'shell'):
400 if self.badalias or util.safehasattr(self, 'shell'):
401 return adefaults[name]
401 return adefaults[name]
402 return getattr(self.fn, name)
402 return getattr(self.fn, name)
403
403
404 def __call__(self, ui, *args, **opts):
404 def __call__(self, ui, *args, **opts):
405 if self.badalias:
405 if self.badalias:
406 hint = None
406 hint = None
407 if self.unknowncmd:
407 if self.unknowncmd:
408 try:
408 try:
409 # check if the command is in a disabled extension
409 # check if the command is in a disabled extension
410 cmd, ext = extensions.disabledcmd(ui, self.cmdname)[:2]
410 cmd, ext = extensions.disabledcmd(ui, self.cmdname)[:2]
411 hint = _("'%s' is provided by '%s' extension") % (cmd, ext)
411 hint = _("'%s' is provided by '%s' extension") % (cmd, ext)
412 except error.UnknownCommand:
412 except error.UnknownCommand:
413 pass
413 pass
414 raise error.Abort(self.badalias, hint=hint)
414 raise error.Abort(self.badalias, hint=hint)
415 if self.shadows:
415 if self.shadows:
416 ui.debug("alias '%s' shadows command '%s'\n" %
416 ui.debug("alias '%s' shadows command '%s'\n" %
417 (self.name, self.cmdname))
417 (self.name, self.cmdname))
418
418
419 ui.log('commandalias', "alias '%s' expands to '%s'\n",
419 ui.log('commandalias', "alias '%s' expands to '%s'\n",
420 self.name, self.definition)
420 self.name, self.definition)
421 if util.safehasattr(self, 'shell'):
421 if util.safehasattr(self, 'shell'):
422 return self.fn(ui, *args, **opts)
422 return self.fn(ui, *args, **opts)
423 else:
423 else:
424 try:
424 try:
425 return util.checksignature(self.fn)(ui, *args, **opts)
425 return util.checksignature(self.fn)(ui, *args, **opts)
426 except error.SignatureError:
426 except error.SignatureError:
427 args = ' '.join([self.cmdname] + self.args)
427 args = ' '.join([self.cmdname] + self.args)
428 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
428 ui.debug("alias '%s' expands to '%s'\n" % (self.name, args))
429 raise
429 raise
430
430
431 def addaliases(ui, cmdtable):
431 def addaliases(ui, cmdtable):
432 # aliases are processed after extensions have been loaded, so they
432 # aliases are processed after extensions have been loaded, so they
433 # may use extension commands. Aliases can also use other alias definitions,
433 # may use extension commands. Aliases can also use other alias definitions,
434 # but only if they have been defined prior to the current definition.
434 # but only if they have been defined prior to the current definition.
435 for alias, definition in ui.configitems('alias'):
435 for alias, definition in ui.configitems('alias'):
436 source = ui.configsource('alias', alias)
436 source = ui.configsource('alias', alias)
437 aliasdef = cmdalias(alias, definition, cmdtable, source)
437 aliasdef = cmdalias(alias, definition, cmdtable, source)
438
438
439 try:
439 try:
440 olddef = cmdtable[aliasdef.cmd][0]
440 olddef = cmdtable[aliasdef.cmd][0]
441 if olddef.definition == aliasdef.definition:
441 if olddef.definition == aliasdef.definition:
442 continue
442 continue
443 except (KeyError, AttributeError):
443 except (KeyError, AttributeError):
444 # definition might not exist or it might not be a cmdalias
444 # definition might not exist or it might not be a cmdalias
445 pass
445 pass
446
446
447 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
447 cmdtable[aliasdef.name] = (aliasdef, aliasdef.opts, aliasdef.help)
448
448
449 def _parse(ui, args):
449 def _parse(ui, args):
450 options = {}
450 options = {}
451 cmdoptions = {}
451 cmdoptions = {}
452
452
453 try:
453 try:
454 args = fancyopts.fancyopts(args, commands.globalopts, options)
454 args = fancyopts.fancyopts(args, commands.globalopts, options)
455 except getopt.GetoptError as inst:
455 except getopt.GetoptError as inst:
456 raise error.CommandError(None, inst)
456 raise error.CommandError(None, inst)
457
457
458 if args:
458 if args:
459 cmd, args = args[0], args[1:]
459 cmd, args = args[0], args[1:]
460 aliases, entry = cmdutil.findcmd(cmd, commands.table,
460 aliases, entry = cmdutil.findcmd(cmd, commands.table,
461 ui.configbool("ui", "strict"))
461 ui.configbool("ui", "strict"))
462 cmd = aliases[0]
462 cmd = aliases[0]
463 args = aliasargs(entry[0], args)
463 args = aliasargs(entry[0], args)
464 defaults = ui.config("defaults", cmd)
464 defaults = ui.config("defaults", cmd)
465 if defaults:
465 if defaults:
466 args = map(util.expandpath, pycompat.shlexsplit(defaults)) + args
466 args = map(util.expandpath, pycompat.shlexsplit(defaults)) + args
467 c = list(entry[1])
467 c = list(entry[1])
468 else:
468 else:
469 cmd = None
469 cmd = None
470 c = []
470 c = []
471
471
472 # combine global options into local
472 # combine global options into local
473 for o in commands.globalopts:
473 for o in commands.globalopts:
474 c.append((o[0], o[1], options[o[1]], o[3]))
474 c.append((o[0], o[1], options[o[1]], o[3]))
475
475
476 try:
476 try:
477 args = fancyopts.fancyopts(args, c, cmdoptions, gnu=True)
477 args = fancyopts.fancyopts(args, c, cmdoptions, gnu=True)
478 except getopt.GetoptError as inst:
478 except getopt.GetoptError as inst:
479 raise error.CommandError(cmd, inst)
479 raise error.CommandError(cmd, inst)
480
480
481 # separate global options back out
481 # separate global options back out
482 for o in commands.globalopts:
482 for o in commands.globalopts:
483 n = o[1]
483 n = o[1]
484 options[n] = cmdoptions[n]
484 options[n] = cmdoptions[n]
485 del cmdoptions[n]
485 del cmdoptions[n]
486
486
487 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
487 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
488
488
489 def _parseconfig(ui, config):
489 def _parseconfig(ui, config):
490 """parse the --config options from the command line"""
490 """parse the --config options from the command line"""
491 configs = []
491 configs = []
492
492
493 for cfg in config:
493 for cfg in config:
494 try:
494 try:
495 name, value = [cfgelem.strip()
495 name, value = [cfgelem.strip()
496 for cfgelem in cfg.split('=', 1)]
496 for cfgelem in cfg.split('=', 1)]
497 section, name = name.split('.', 1)
497 section, name = name.split('.', 1)
498 if not section or not name:
498 if not section or not name:
499 raise IndexError
499 raise IndexError
500 ui.setconfig(section, name, value, '--config')
500 ui.setconfig(section, name, value, '--config')
501 configs.append((section, name, value))
501 configs.append((section, name, value))
502 except (IndexError, ValueError):
502 except (IndexError, ValueError):
503 raise error.Abort(_('malformed --config option: %r '
503 raise error.Abort(_('malformed --config option: %r '
504 '(use --config section.name=value)') % cfg)
504 '(use --config section.name=value)') % cfg)
505
505
506 return configs
506 return configs
507
507
508 def _earlygetopt(aliases, args):
508 def _earlygetopt(aliases, args):
509 """Return list of values for an option (or aliases).
509 """Return list of values for an option (or aliases).
510
510
511 The values are listed in the order they appear in args.
511 The values are listed in the order they appear in args.
512 The options and values are removed from args.
512 The options and values are removed from args.
513
513
514 >>> args = ['x', '--cwd', 'foo', 'y']
514 >>> args = ['x', '--cwd', 'foo', 'y']
515 >>> _earlygetopt(['--cwd'], args), args
515 >>> _earlygetopt(['--cwd'], args), args
516 (['foo'], ['x', 'y'])
516 (['foo'], ['x', 'y'])
517
517
518 >>> args = ['x', '--cwd=bar', 'y']
518 >>> args = ['x', '--cwd=bar', 'y']
519 >>> _earlygetopt(['--cwd'], args), args
519 >>> _earlygetopt(['--cwd'], args), args
520 (['bar'], ['x', 'y'])
520 (['bar'], ['x', 'y'])
521
521
522 >>> args = ['x', '-R', 'foo', 'y']
522 >>> args = ['x', '-R', 'foo', 'y']
523 >>> _earlygetopt(['-R'], args), args
523 >>> _earlygetopt(['-R'], args), args
524 (['foo'], ['x', 'y'])
524 (['foo'], ['x', 'y'])
525
525
526 >>> args = ['x', '-Rbar', 'y']
526 >>> args = ['x', '-Rbar', 'y']
527 >>> _earlygetopt(['-R'], args), args
527 >>> _earlygetopt(['-R'], args), args
528 (['bar'], ['x', 'y'])
528 (['bar'], ['x', 'y'])
529 """
529 """
530 try:
530 try:
531 argcount = args.index("--")
531 argcount = args.index("--")
532 except ValueError:
532 except ValueError:
533 argcount = len(args)
533 argcount = len(args)
534 shortopts = [opt for opt in aliases if len(opt) == 2]
534 shortopts = [opt for opt in aliases if len(opt) == 2]
535 values = []
535 values = []
536 pos = 0
536 pos = 0
537 while pos < argcount:
537 while pos < argcount:
538 fullarg = arg = args[pos]
538 fullarg = arg = args[pos]
539 equals = arg.find('=')
539 equals = arg.find('=')
540 if equals > -1:
540 if equals > -1:
541 arg = arg[:equals]
541 arg = arg[:equals]
542 if arg in aliases:
542 if arg in aliases:
543 del args[pos]
543 del args[pos]
544 if equals > -1:
544 if equals > -1:
545 values.append(fullarg[equals + 1:])
545 values.append(fullarg[equals + 1:])
546 argcount -= 1
546 argcount -= 1
547 else:
547 else:
548 if pos + 1 >= argcount:
548 if pos + 1 >= argcount:
549 # ignore and let getopt report an error if there is no value
549 # ignore and let getopt report an error if there is no value
550 break
550 break
551 values.append(args.pop(pos))
551 values.append(args.pop(pos))
552 argcount -= 2
552 argcount -= 2
553 elif arg[:2] in shortopts:
553 elif arg[:2] in shortopts:
554 # short option can have no following space, e.g. hg log -Rfoo
554 # short option can have no following space, e.g. hg log -Rfoo
555 values.append(args.pop(pos)[2:])
555 values.append(args.pop(pos)[2:])
556 argcount -= 1
556 argcount -= 1
557 else:
557 else:
558 pos += 1
558 pos += 1
559 return values
559 return values
560
560
561 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
561 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
562 # run pre-hook, and abort if it fails
562 # run pre-hook, and abort if it fails
563 hook.hook(lui, repo, "pre-%s" % cmd, True, args=" ".join(fullargs),
563 hook.hook(lui, repo, "pre-%s" % cmd, True, args=" ".join(fullargs),
564 pats=cmdpats, opts=cmdoptions)
564 pats=cmdpats, opts=cmdoptions)
565 try:
565 try:
566 ret = _runcommand(ui, options, cmd, d)
566 ret = _runcommand(ui, options, cmd, d)
567 # run post-hook, passing command result
567 # run post-hook, passing command result
568 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
568 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
569 result=ret, pats=cmdpats, opts=cmdoptions)
569 result=ret, pats=cmdpats, opts=cmdoptions)
570 except Exception:
570 except Exception:
571 # run failure hook and re-raise
571 # run failure hook and re-raise
572 hook.hook(lui, repo, "fail-%s" % cmd, False, args=" ".join(fullargs),
572 hook.hook(lui, repo, "fail-%s" % cmd, False, args=" ".join(fullargs),
573 pats=cmdpats, opts=cmdoptions)
573 pats=cmdpats, opts=cmdoptions)
574 raise
574 raise
575 return ret
575 return ret
576
576
577 def _getlocal(ui, rpath, wd=None):
577 def _getlocal(ui, rpath, wd=None):
578 """Return (path, local ui object) for the given target path.
578 """Return (path, local ui object) for the given target path.
579
579
580 Takes paths in [cwd]/.hg/hgrc into account."
580 Takes paths in [cwd]/.hg/hgrc into account."
581 """
581 """
582 if wd is None:
582 if wd is None:
583 try:
583 try:
584 wd = pycompat.getcwd()
584 wd = pycompat.getcwd()
585 except OSError as e:
585 except OSError as e:
586 raise error.Abort(_("error getting current working directory: %s") %
586 raise error.Abort(_("error getting current working directory: %s") %
587 e.strerror)
587 e.strerror)
588 path = cmdutil.findrepo(wd) or ""
588 path = cmdutil.findrepo(wd) or ""
589 if not path:
589 if not path:
590 lui = ui
590 lui = ui
591 else:
591 else:
592 lui = ui.copy()
592 lui = ui.copy()
593 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
593 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
594
594
595 if rpath and rpath[-1]:
595 if rpath and rpath[-1]:
596 path = lui.expandpath(rpath[-1])
596 path = lui.expandpath(rpath[-1])
597 lui = ui.copy()
597 lui = ui.copy()
598 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
598 lui.readconfig(os.path.join(path, ".hg", "hgrc"), path)
599
599
600 return path, lui
600 return path, lui
601
601
602 def _checkshellalias(lui, ui, args):
602 def _checkshellalias(lui, ui, args):
603 """Return the function to run the shell alias, if it is required"""
603 """Return the function to run the shell alias, if it is required"""
604 options = {}
604 options = {}
605
605
606 try:
606 try:
607 args = fancyopts.fancyopts(args, commands.globalopts, options)
607 args = fancyopts.fancyopts(args, commands.globalopts, options)
608 except getopt.GetoptError:
608 except getopt.GetoptError:
609 return
609 return
610
610
611 if not args:
611 if not args:
612 return
612 return
613
613
614 cmdtable = commands.table
614 cmdtable = commands.table
615
615
616 cmd = args[0]
616 cmd = args[0]
617 try:
617 try:
618 strict = ui.configbool("ui", "strict")
618 strict = ui.configbool("ui", "strict")
619 aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
619 aliases, entry = cmdutil.findcmd(cmd, cmdtable, strict)
620 except (error.AmbiguousCommand, error.UnknownCommand):
620 except (error.AmbiguousCommand, error.UnknownCommand):
621 return
621 return
622
622
623 cmd = aliases[0]
623 cmd = aliases[0]
624 fn = entry[0]
624 fn = entry[0]
625
625
626 if cmd and util.safehasattr(fn, 'shell'):
626 if cmd and util.safehasattr(fn, 'shell'):
627 d = lambda: fn(ui, *args[1:])
627 d = lambda: fn(ui, *args[1:])
628 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d,
628 return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d,
629 [], {})
629 [], {})
630
630
631 _loaded = set()
631 _loaded = set()
632
632
633 # list of (objname, loadermod, loadername) tuple:
633 # list of (objname, loadermod, loadername) tuple:
634 # - objname is the name of an object in extension module, from which
634 # - objname is the name of an object in extension module, from which
635 # extra information is loaded
635 # extra information is loaded
636 # - loadermod is the module where loader is placed
636 # - loadermod is the module where loader is placed
637 # - loadername is the name of the function, which takes (ui, extensionname,
637 # - loadername is the name of the function, which takes (ui, extensionname,
638 # extraobj) arguments
638 # extraobj) arguments
639 extraloaders = [
639 extraloaders = [
640 ('cmdtable', commands, 'loadcmdtable'),
640 ('cmdtable', commands, 'loadcmdtable'),
641 ('colortable', color, 'loadcolortable'),
641 ('colortable', color, 'loadcolortable'),
642 ('filesetpredicate', fileset, 'loadpredicate'),
642 ('filesetpredicate', fileset, 'loadpredicate'),
643 ('revsetpredicate', revset, 'loadpredicate'),
643 ('revsetpredicate', revset, 'loadpredicate'),
644 ('templatefilter', templatefilters, 'loadfilter'),
644 ('templatefilter', templatefilters, 'loadfilter'),
645 ('templatefunc', templater, 'loadfunction'),
645 ('templatefunc', templater, 'loadfunction'),
646 ('templatekeyword', templatekw, 'loadkeyword'),
646 ('templatekeyword', templatekw, 'loadkeyword'),
647 ]
647 ]
648
648
649 def _dispatch(req):
649 def _dispatch(req):
650 args = req.args
650 args = req.args
651 ui = req.ui
651 ui = req.ui
652
652
653 # check for cwd
653 # check for cwd
654 cwd = _earlygetopt(['--cwd'], args)
654 cwd = _earlygetopt(['--cwd'], args)
655 if cwd:
655 if cwd:
656 os.chdir(cwd[-1])
656 os.chdir(cwd[-1])
657
657
658 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
658 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
659 path, lui = _getlocal(ui, rpath)
659 path, lui = _getlocal(ui, rpath)
660
660
661 # Side-effect of accessing is debugcommands module is guaranteed to be
661 # Side-effect of accessing is debugcommands module is guaranteed to be
662 # imported and commands.table is populated.
662 # imported and commands.table is populated.
663 debugcommands.command
663 debugcommands.command
664
664
665 uis = set([ui, lui])
665 uis = set([ui, lui])
666
666
667 if req.repo:
667 if req.repo:
668 uis.add(req.repo.ui)
668 uis.add(req.repo.ui)
669
669
670 if '--profile' in args:
670 if '--profile' in args:
671 for ui_ in uis:
671 for ui_ in uis:
672 ui_.setconfig('profiling', 'enabled', 'true', '--profile')
672 ui_.setconfig('profiling', 'enabled', 'true', '--profile')
673
673
674 with profiling.maybeprofile(lui):
674 with profiling.maybeprofile(lui):
675 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
675 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
676 # reposetup. Programs like TortoiseHg will call _dispatch several
676 # reposetup. Programs like TortoiseHg will call _dispatch several
677 # times so we keep track of configured extensions in _loaded.
677 # times so we keep track of configured extensions in _loaded.
678 extensions.loadall(lui)
678 extensions.loadall(lui)
679 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
679 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
680 # Propagate any changes to lui.__class__ by extensions
680 # Propagate any changes to lui.__class__ by extensions
681 ui.__class__ = lui.__class__
681 ui.__class__ = lui.__class__
682
682
683 # (uisetup and extsetup are handled in extensions.loadall)
683 # (uisetup and extsetup are handled in extensions.loadall)
684
684
685 for name, module in exts:
685 for name, module in exts:
686 for objname, loadermod, loadername in extraloaders:
686 for objname, loadermod, loadername in extraloaders:
687 extraobj = getattr(module, objname, None)
687 extraobj = getattr(module, objname, None)
688 if extraobj is not None:
688 if extraobj is not None:
689 getattr(loadermod, loadername)(ui, name, extraobj)
689 getattr(loadermod, loadername)(ui, name, extraobj)
690 _loaded.add(name)
690 _loaded.add(name)
691
691
692 # (reposetup is handled in hg.repository)
692 # (reposetup is handled in hg.repository)
693
693
694 addaliases(lui, commands.table)
694 addaliases(lui, commands.table)
695
695
696 # All aliases and commands are completely defined, now.
696 # All aliases and commands are completely defined, now.
697 # Check abbreviation/ambiguity of shell alias.
697 # Check abbreviation/ambiguity of shell alias.
698 shellaliasfn = _checkshellalias(lui, ui, args)
698 shellaliasfn = _checkshellalias(lui, ui, args)
699 if shellaliasfn:
699 if shellaliasfn:
700 return shellaliasfn()
700 return shellaliasfn()
701
701
702 # check for fallback encoding
702 # check for fallback encoding
703 fallback = lui.config('ui', 'fallbackencoding')
703 fallback = lui.config('ui', 'fallbackencoding')
704 if fallback:
704 if fallback:
705 encoding.fallbackencoding = fallback
705 encoding.fallbackencoding = fallback
706
706
707 fullargs = args
707 fullargs = args
708 cmd, func, args, options, cmdoptions = _parse(lui, args)
708 cmd, func, args, options, cmdoptions = _parse(lui, args)
709
709
710 if options["config"]:
710 if options["config"]:
711 raise error.Abort(_("option --config may not be abbreviated!"))
711 raise error.Abort(_("option --config may not be abbreviated!"))
712 if options["cwd"]:
712 if options["cwd"]:
713 raise error.Abort(_("option --cwd may not be abbreviated!"))
713 raise error.Abort(_("option --cwd may not be abbreviated!"))
714 if options["repository"]:
714 if options["repository"]:
715 raise error.Abort(_(
715 raise error.Abort(_(
716 "option -R has to be separated from other options (e.g. not "
716 "option -R has to be separated from other options (e.g. not "
717 "-qR) and --repository may only be abbreviated as --repo!"))
717 "-qR) and --repository may only be abbreviated as --repo!"))
718
718
719 if options["encoding"]:
719 if options["encoding"]:
720 encoding.encoding = options["encoding"]
720 encoding.encoding = options["encoding"]
721 if options["encodingmode"]:
721 if options["encodingmode"]:
722 encoding.encodingmode = options["encodingmode"]
722 encoding.encodingmode = options["encodingmode"]
723 if options["time"]:
723 if options["time"]:
724 def get_times():
724 def get_times():
725 t = os.times()
725 t = os.times()
726 if t[4] == 0.0:
726 if t[4] == 0.0:
727 # Windows leaves this as zero, so use time.clock()
727 # Windows leaves this as zero, so use time.clock()
728 t = (t[0], t[1], t[2], t[3], time.clock())
728 t = (t[0], t[1], t[2], t[3], time.clock())
729 return t
729 return t
730 s = get_times()
730 s = get_times()
731 def print_time():
731 def print_time():
732 t = get_times()
732 t = get_times()
733 ui.warn(
733 ui.warn(
734 _("time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
734 _("time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
735 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
735 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
736 atexit.register(print_time)
736 atexit.register(print_time)
737
737
738 if options['verbose'] or options['debug'] or options['quiet']:
738 if options['verbose'] or options['debug'] or options['quiet']:
739 for opt in ('verbose', 'debug', 'quiet'):
739 for opt in ('verbose', 'debug', 'quiet'):
740 val = str(bool(options[opt]))
740 val = str(bool(options[opt]))
741 for ui_ in uis:
741 for ui_ in uis:
742 ui_.setconfig('ui', opt, val, '--' + opt)
742 ui_.setconfig('ui', opt, val, '--' + opt)
743
743
744 if options['traceback']:
744 if options['traceback']:
745 for ui_ in uis:
745 for ui_ in uis:
746 ui_.setconfig('ui', 'traceback', 'on', '--traceback')
746 ui_.setconfig('ui', 'traceback', 'on', '--traceback')
747
747
748 if options['noninteractive']:
748 if options['noninteractive']:
749 for ui_ in uis:
749 for ui_ in uis:
750 ui_.setconfig('ui', 'interactive', 'off', '-y')
750 ui_.setconfig('ui', 'interactive', 'off', '-y')
751
751
752 if cmdoptions.get('insecure', False):
752 if cmdoptions.get('insecure', False):
753 for ui_ in uis:
753 for ui_ in uis:
754 ui_.insecureconnections = True
754 ui_.insecureconnections = True
755
755
756 if options['version']:
756 if options['version']:
757 return commands.version_(ui)
757 return commands.version_(ui)
758 if options['help']:
758 if options['help']:
759 return commands.help_(ui, cmd, command=cmd is not None)
759 return commands.help_(ui, cmd, command=cmd is not None)
760 elif not cmd:
760 elif not cmd:
761 return commands.help_(ui, 'shortlist')
761 return commands.help_(ui, 'shortlist')
762
762
763 repo = None
763 repo = None
764 cmdpats = args[:]
764 cmdpats = args[:]
765 if not func.norepo:
765 if not func.norepo:
766 # use the repo from the request only if we don't have -R
766 # use the repo from the request only if we don't have -R
767 if not rpath and not cwd:
767 if not rpath and not cwd:
768 repo = req.repo
768 repo = req.repo
769
769
770 if repo:
770 if repo:
771 # set the descriptors of the repo ui to those of ui
771 # set the descriptors of the repo ui to those of ui
772 repo.ui.fin = ui.fin
772 repo.ui.fin = ui.fin
773 repo.ui.fout = ui.fout
773 repo.ui.fout = ui.fout
774 repo.ui.ferr = ui.ferr
774 repo.ui.ferr = ui.ferr
775 else:
775 else:
776 try:
776 try:
777 repo = hg.repository(ui, path=path)
777 repo = hg.repository(ui, path=path)
778 if not repo.local():
778 if not repo.local():
779 raise error.Abort(_("repository '%s' is not local")
779 raise error.Abort(_("repository '%s' is not local")
780 % path)
780 % path)
781 repo.ui.setconfig("bundle", "mainreporoot", repo.root,
781 repo.ui.setconfig("bundle", "mainreporoot", repo.root,
782 'repo')
782 'repo')
783 except error.RequirementError:
783 except error.RequirementError:
784 raise
784 raise
785 except error.RepoError:
785 except error.RepoError:
786 if rpath and rpath[-1]: # invalid -R path
786 if rpath and rpath[-1]: # invalid -R path
787 raise
787 raise
788 if not func.optionalrepo:
788 if not func.optionalrepo:
789 if func.inferrepo and args and not path:
789 if func.inferrepo and args and not path:
790 # try to infer -R from command args
790 # try to infer -R from command args
791 repos = map(cmdutil.findrepo, args)
791 repos = map(cmdutil.findrepo, args)
792 guess = repos[0]
792 guess = repos[0]
793 if guess and repos.count(guess) == len(repos):
793 if guess and repos.count(guess) == len(repos):
794 req.args = ['--repository', guess] + fullargs
794 req.args = ['--repository', guess] + fullargs
795 return _dispatch(req)
795 return _dispatch(req)
796 if not path:
796 if not path:
797 raise error.RepoError(_("no repository found in"
797 raise error.RepoError(_("no repository found in"
798 " '%s' (.hg not found)")
798 " '%s' (.hg not found)")
799 % pycompat.getcwd())
799 % pycompat.getcwd())
800 raise
800 raise
801 if repo:
801 if repo:
802 ui = repo.ui
802 ui = repo.ui
803 if options['hidden']:
803 if options['hidden']:
804 repo = repo.unfiltered()
804 repo = repo.unfiltered()
805 args.insert(0, repo)
805 args.insert(0, repo)
806 elif rpath:
806 elif rpath:
807 ui.warn(_("warning: --repository ignored\n"))
807 ui.warn(_("warning: --repository ignored\n"))
808
808
809 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
809 msg = ' '.join(' ' in a and repr(a) or a for a in fullargs)
810 ui.log("command", '%s\n', msg)
810 ui.log("command", '%s\n', msg)
811 strcmdopt = pycompat.strkwargs(cmdoptions)
811 strcmdopt = pycompat.strkwargs(cmdoptions)
812 d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
812 d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
813 try:
813 try:
814 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
814 return runcommand(lui, repo, cmd, fullargs, ui, options, d,
815 cmdpats, cmdoptions)
815 cmdpats, cmdoptions)
816 finally:
816 finally:
817 if repo and repo != req.repo:
817 if repo and repo != req.repo:
818 repo.close()
818 repo.close()
819
819
820 def _runcommand(ui, options, cmd, cmdfunc):
820 def _runcommand(ui, options, cmd, cmdfunc):
821 """Run a command function, possibly with profiling enabled."""
821 """Run a command function, possibly with profiling enabled."""
822 if util.parsebool(options['pager']):
823 ui.pager('internal-always-' + cmd)
822 try:
824 try:
823 return cmdfunc()
825 return cmdfunc()
824 except error.SignatureError:
826 except error.SignatureError:
825 raise error.CommandError(cmd, _('invalid arguments'))
827 raise error.CommandError(cmd, _('invalid arguments'))
826
828
827 def _exceptionwarning(ui):
829 def _exceptionwarning(ui):
828 """Produce a warning message for the current active exception"""
830 """Produce a warning message for the current active exception"""
829
831
830 # For compatibility checking, we discard the portion of the hg
832 # For compatibility checking, we discard the portion of the hg
831 # version after the + on the assumption that if a "normal
833 # version after the + on the assumption that if a "normal
832 # user" is running a build with a + in it the packager
834 # user" is running a build with a + in it the packager
833 # probably built from fairly close to a tag and anyone with a
835 # probably built from fairly close to a tag and anyone with a
834 # 'make local' copy of hg (where the version number can be out
836 # 'make local' copy of hg (where the version number can be out
835 # of date) will be clueful enough to notice the implausible
837 # of date) will be clueful enough to notice the implausible
836 # version number and try updating.
838 # version number and try updating.
837 ct = util.versiontuple(n=2)
839 ct = util.versiontuple(n=2)
838 worst = None, ct, ''
840 worst = None, ct, ''
839 if ui.config('ui', 'supportcontact', None) is None:
841 if ui.config('ui', 'supportcontact', None) is None:
840 for name, mod in extensions.extensions():
842 for name, mod in extensions.extensions():
841 testedwith = getattr(mod, 'testedwith', '')
843 testedwith = getattr(mod, 'testedwith', '')
842 report = getattr(mod, 'buglink', _('the extension author.'))
844 report = getattr(mod, 'buglink', _('the extension author.'))
843 if not testedwith.strip():
845 if not testedwith.strip():
844 # We found an untested extension. It's likely the culprit.
846 # We found an untested extension. It's likely the culprit.
845 worst = name, 'unknown', report
847 worst = name, 'unknown', report
846 break
848 break
847
849
848 # Never blame on extensions bundled with Mercurial.
850 # Never blame on extensions bundled with Mercurial.
849 if extensions.ismoduleinternal(mod):
851 if extensions.ismoduleinternal(mod):
850 continue
852 continue
851
853
852 tested = [util.versiontuple(t, 2) for t in testedwith.split()]
854 tested = [util.versiontuple(t, 2) for t in testedwith.split()]
853 if ct in tested:
855 if ct in tested:
854 continue
856 continue
855
857
856 lower = [t for t in tested if t < ct]
858 lower = [t for t in tested if t < ct]
857 nearest = max(lower or tested)
859 nearest = max(lower or tested)
858 if worst[0] is None or nearest < worst[1]:
860 if worst[0] is None or nearest < worst[1]:
859 worst = name, nearest, report
861 worst = name, nearest, report
860 if worst[0] is not None:
862 if worst[0] is not None:
861 name, testedwith, report = worst
863 name, testedwith, report = worst
862 if not isinstance(testedwith, str):
864 if not isinstance(testedwith, str):
863 testedwith = '.'.join([str(c) for c in testedwith])
865 testedwith = '.'.join([str(c) for c in testedwith])
864 warning = (_('** Unknown exception encountered with '
866 warning = (_('** Unknown exception encountered with '
865 'possibly-broken third-party extension %s\n'
867 'possibly-broken third-party extension %s\n'
866 '** which supports versions %s of Mercurial.\n'
868 '** which supports versions %s of Mercurial.\n'
867 '** Please disable %s and try your action again.\n'
869 '** Please disable %s and try your action again.\n'
868 '** If that fixes the bug please report it to %s\n')
870 '** If that fixes the bug please report it to %s\n')
869 % (name, testedwith, name, report))
871 % (name, testedwith, name, report))
870 else:
872 else:
871 bugtracker = ui.config('ui', 'supportcontact', None)
873 bugtracker = ui.config('ui', 'supportcontact', None)
872 if bugtracker is None:
874 if bugtracker is None:
873 bugtracker = _("https://mercurial-scm.org/wiki/BugTracker")
875 bugtracker = _("https://mercurial-scm.org/wiki/BugTracker")
874 warning = (_("** unknown exception encountered, "
876 warning = (_("** unknown exception encountered, "
875 "please report by visiting\n** ") + bugtracker + '\n')
877 "please report by visiting\n** ") + bugtracker + '\n')
876 warning += ((_("** Python %s\n") % sys.version.replace('\n', '')) +
878 warning += ((_("** Python %s\n") % sys.version.replace('\n', '')) +
877 (_("** Mercurial Distributed SCM (version %s)\n") %
879 (_("** Mercurial Distributed SCM (version %s)\n") %
878 util.version()) +
880 util.version()) +
879 (_("** Extensions loaded: %s\n") %
881 (_("** Extensions loaded: %s\n") %
880 ", ".join([x[0] for x in extensions.extensions()])))
882 ", ".join([x[0] for x in extensions.extensions()])))
881 return warning
883 return warning
882
884
883 def handlecommandexception(ui):
885 def handlecommandexception(ui):
884 """Produce a warning message for broken commands
886 """Produce a warning message for broken commands
885
887
886 Called when handling an exception; the exception is reraised if
888 Called when handling an exception; the exception is reraised if
887 this function returns False, ignored otherwise.
889 this function returns False, ignored otherwise.
888 """
890 """
889 warning = _exceptionwarning(ui)
891 warning = _exceptionwarning(ui)
890 ui.log("commandexception", "%s\n%s\n", warning, traceback.format_exc())
892 ui.log("commandexception", "%s\n%s\n", warning, traceback.format_exc())
891 ui.warn(warning)
893 ui.warn(warning)
892 return False # re-raise the exception
894 return False # re-raise the exception
@@ -1,354 +1,356 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 add
3 add
4 addremove
4 addremove
5 annotate
5 annotate
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 bookmarks
10 branch
10 branch
11 branches
11 branches
12 bundle
12 bundle
13 cat
13 cat
14 clone
14 clone
15 commit
15 commit
16 config
16 config
17 copy
17 copy
18 diff
18 diff
19 export
19 export
20 files
20 files
21 forget
21 forget
22 graft
22 graft
23 grep
23 grep
24 heads
24 heads
25 help
25 help
26 identify
26 identify
27 import
27 import
28 incoming
28 incoming
29 init
29 init
30 locate
30 locate
31 log
31 log
32 manifest
32 manifest
33 merge
33 merge
34 outgoing
34 outgoing
35 parents
35 parents
36 paths
36 paths
37 phase
37 phase
38 pull
38 pull
39 push
39 push
40 recover
40 recover
41 remove
41 remove
42 rename
42 rename
43 resolve
43 resolve
44 revert
44 revert
45 rollback
45 rollback
46 root
46 root
47 serve
47 serve
48 status
48 status
49 summary
49 summary
50 tag
50 tag
51 tags
51 tags
52 tip
52 tip
53 unbundle
53 unbundle
54 update
54 update
55 verify
55 verify
56 version
56 version
57
57
58 Show all commands that start with "a"
58 Show all commands that start with "a"
59 $ hg debugcomplete a
59 $ hg debugcomplete a
60 add
60 add
61 addremove
61 addremove
62 annotate
62 annotate
63 archive
63 archive
64
64
65 Do not show debug commands if there are other candidates
65 Do not show debug commands if there are other candidates
66 $ hg debugcomplete d
66 $ hg debugcomplete d
67 diff
67 diff
68
68
69 Show debug commands if there are no other candidates
69 Show debug commands if there are no other candidates
70 $ hg debugcomplete debug
70 $ hg debugcomplete debug
71 debugancestor
71 debugancestor
72 debugapplystreamclonebundle
72 debugapplystreamclonebundle
73 debugbuilddag
73 debugbuilddag
74 debugbundle
74 debugbundle
75 debugcheckstate
75 debugcheckstate
76 debugcommands
76 debugcommands
77 debugcomplete
77 debugcomplete
78 debugconfig
78 debugconfig
79 debugcreatestreamclonebundle
79 debugcreatestreamclonebundle
80 debugdag
80 debugdag
81 debugdata
81 debugdata
82 debugdate
82 debugdate
83 debugdeltachain
83 debugdeltachain
84 debugdirstate
84 debugdirstate
85 debugdiscovery
85 debugdiscovery
86 debugextensions
86 debugextensions
87 debugfileset
87 debugfileset
88 debugfsinfo
88 debugfsinfo
89 debuggetbundle
89 debuggetbundle
90 debugignore
90 debugignore
91 debugindex
91 debugindex
92 debugindexdot
92 debugindexdot
93 debuginstall
93 debuginstall
94 debugknown
94 debugknown
95 debuglabelcomplete
95 debuglabelcomplete
96 debuglocks
96 debuglocks
97 debugmergestate
97 debugmergestate
98 debugnamecomplete
98 debugnamecomplete
99 debugobsolete
99 debugobsolete
100 debugpathcomplete
100 debugpathcomplete
101 debugpushkey
101 debugpushkey
102 debugpvec
102 debugpvec
103 debugrebuilddirstate
103 debugrebuilddirstate
104 debugrebuildfncache
104 debugrebuildfncache
105 debugrename
105 debugrename
106 debugrevlog
106 debugrevlog
107 debugrevspec
107 debugrevspec
108 debugsetparents
108 debugsetparents
109 debugsub
109 debugsub
110 debugsuccessorssets
110 debugsuccessorssets
111 debugtemplate
111 debugtemplate
112 debugupgraderepo
112 debugupgraderepo
113 debugwalk
113 debugwalk
114 debugwireargs
114 debugwireargs
115
115
116 Do not show the alias of a debug command if there are other candidates
116 Do not show the alias of a debug command if there are other candidates
117 (this should hide rawcommit)
117 (this should hide rawcommit)
118 $ hg debugcomplete r
118 $ hg debugcomplete r
119 recover
119 recover
120 remove
120 remove
121 rename
121 rename
122 resolve
122 resolve
123 revert
123 revert
124 rollback
124 rollback
125 root
125 root
126 Show the alias of a debug command if there are no other candidates
126 Show the alias of a debug command if there are no other candidates
127 $ hg debugcomplete rawc
127 $ hg debugcomplete rawc
128
128
129
129
130 Show the global options
130 Show the global options
131 $ hg debugcomplete --options | sort
131 $ hg debugcomplete --options | sort
132 --config
132 --config
133 --cwd
133 --cwd
134 --debug
134 --debug
135 --debugger
135 --debugger
136 --encoding
136 --encoding
137 --encodingmode
137 --encodingmode
138 --help
138 --help
139 --hidden
139 --hidden
140 --noninteractive
140 --noninteractive
141 --pager
141 --profile
142 --profile
142 --quiet
143 --quiet
143 --repository
144 --repository
144 --time
145 --time
145 --traceback
146 --traceback
146 --verbose
147 --verbose
147 --version
148 --version
148 -R
149 -R
149 -h
150 -h
150 -q
151 -q
151 -v
152 -v
152 -y
153 -y
153
154
154 Show the options for the "serve" command
155 Show the options for the "serve" command
155 $ hg debugcomplete --options serve | sort
156 $ hg debugcomplete --options serve | sort
156 --accesslog
157 --accesslog
157 --address
158 --address
158 --certificate
159 --certificate
159 --cmdserver
160 --cmdserver
160 --config
161 --config
161 --cwd
162 --cwd
162 --daemon
163 --daemon
163 --daemon-postexec
164 --daemon-postexec
164 --debug
165 --debug
165 --debugger
166 --debugger
166 --encoding
167 --encoding
167 --encodingmode
168 --encodingmode
168 --errorlog
169 --errorlog
169 --help
170 --help
170 --hidden
171 --hidden
171 --ipv6
172 --ipv6
172 --name
173 --name
173 --noninteractive
174 --noninteractive
175 --pager
174 --pid-file
176 --pid-file
175 --port
177 --port
176 --prefix
178 --prefix
177 --profile
179 --profile
178 --quiet
180 --quiet
179 --repository
181 --repository
180 --stdio
182 --stdio
181 --style
183 --style
182 --templates
184 --templates
183 --time
185 --time
184 --traceback
186 --traceback
185 --verbose
187 --verbose
186 --version
188 --version
187 --web-conf
189 --web-conf
188 -6
190 -6
189 -A
191 -A
190 -E
192 -E
191 -R
193 -R
192 -a
194 -a
193 -d
195 -d
194 -h
196 -h
195 -n
197 -n
196 -p
198 -p
197 -q
199 -q
198 -t
200 -t
199 -v
201 -v
200 -y
202 -y
201
203
202 Show an error if we use --options with an ambiguous abbreviation
204 Show an error if we use --options with an ambiguous abbreviation
203 $ hg debugcomplete --options s
205 $ hg debugcomplete --options s
204 hg: command 's' is ambiguous:
206 hg: command 's' is ambiguous:
205 serve showconfig status summary
207 serve showconfig status summary
206 [255]
208 [255]
207
209
208 Show all commands + options
210 Show all commands + options
209 $ hg debugcommands
211 $ hg debugcommands
210 add: include, exclude, subrepos, dry-run
212 add: include, exclude, subrepos, dry-run
211 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
213 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
212 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
214 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
213 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
215 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
214 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
216 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
215 export: output, switch-parent, rev, text, git, nodates
217 export: output, switch-parent, rev, text, git, nodates
216 forget: include, exclude
218 forget: include, exclude
217 init: ssh, remotecmd, insecure
219 init: ssh, remotecmd, insecure
218 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
220 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
219 merge: force, rev, preview, tool
221 merge: force, rev, preview, tool
220 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
222 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
221 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
223 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
222 remove: after, force, subrepos, include, exclude
224 remove: after, force, subrepos, include, exclude
223 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
225 serve: accesslog, daemon, daemon-postexec, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
224 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
226 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
225 summary: remote
227 summary: remote
226 update: clean, check, date, rev, tool
228 update: clean, check, date, rev, tool
227 addremove: similarity, subrepos, include, exclude, dry-run
229 addremove: similarity, subrepos, include, exclude, dry-run
228 archive: no-decode, prefix, rev, type, subrepos, include, exclude
230 archive: no-decode, prefix, rev, type, subrepos, include, exclude
229 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
231 backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
230 bisect: reset, good, bad, skip, extend, command, noupdate
232 bisect: reset, good, bad, skip, extend, command, noupdate
231 bookmarks: force, rev, delete, rename, inactive, template
233 bookmarks: force, rev, delete, rename, inactive, template
232 branch: force, clean
234 branch: force, clean
233 branches: active, closed, template
235 branches: active, closed, template
234 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
236 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
235 cat: output, rev, decode, include, exclude
237 cat: output, rev, decode, include, exclude
236 config: untrusted, edit, local, global, template
238 config: untrusted, edit, local, global, template
237 copy: after, force, include, exclude, dry-run
239 copy: after, force, include, exclude, dry-run
238 debugancestor:
240 debugancestor:
239 debugapplystreamclonebundle:
241 debugapplystreamclonebundle:
240 debugbuilddag: mergeable-file, overwritten-file, new-file
242 debugbuilddag: mergeable-file, overwritten-file, new-file
241 debugbundle: all, spec
243 debugbundle: all, spec
242 debugcheckstate:
244 debugcheckstate:
243 debugcommands:
245 debugcommands:
244 debugcomplete: options
246 debugcomplete: options
245 debugcreatestreamclonebundle:
247 debugcreatestreamclonebundle:
246 debugdag: tags, branches, dots, spaces
248 debugdag: tags, branches, dots, spaces
247 debugdata: changelog, manifest, dir
249 debugdata: changelog, manifest, dir
248 debugdate: extended
250 debugdate: extended
249 debugdeltachain: changelog, manifest, dir, template
251 debugdeltachain: changelog, manifest, dir, template
250 debugdirstate: nodates, datesort
252 debugdirstate: nodates, datesort
251 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
253 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
252 debugextensions: template
254 debugextensions: template
253 debugfileset: rev
255 debugfileset: rev
254 debugfsinfo:
256 debugfsinfo:
255 debuggetbundle: head, common, type
257 debuggetbundle: head, common, type
256 debugignore:
258 debugignore:
257 debugindex: changelog, manifest, dir, format
259 debugindex: changelog, manifest, dir, format
258 debugindexdot: changelog, manifest, dir
260 debugindexdot: changelog, manifest, dir
259 debuginstall: template
261 debuginstall: template
260 debugknown:
262 debugknown:
261 debuglabelcomplete:
263 debuglabelcomplete:
262 debuglocks: force-lock, force-wlock
264 debuglocks: force-lock, force-wlock
263 debugmergestate:
265 debugmergestate:
264 debugnamecomplete:
266 debugnamecomplete:
265 debugobsolete: flags, record-parents, rev, index, delete, date, user, template
267 debugobsolete: flags, record-parents, rev, index, delete, date, user, template
266 debugpathcomplete: full, normal, added, removed
268 debugpathcomplete: full, normal, added, removed
267 debugpushkey:
269 debugpushkey:
268 debugpvec:
270 debugpvec:
269 debugrebuilddirstate: rev, minimal
271 debugrebuilddirstate: rev, minimal
270 debugrebuildfncache:
272 debugrebuildfncache:
271 debugrename: rev
273 debugrename: rev
272 debugrevlog: changelog, manifest, dir, dump
274 debugrevlog: changelog, manifest, dir, dump
273 debugrevspec: optimize, show-stage, no-optimized, verify-optimized
275 debugrevspec: optimize, show-stage, no-optimized, verify-optimized
274 debugsetparents:
276 debugsetparents:
275 debugsub: rev
277 debugsub: rev
276 debugsuccessorssets:
278 debugsuccessorssets:
277 debugtemplate: rev, define
279 debugtemplate: rev, define
278 debugupgraderepo: optimize, run
280 debugupgraderepo: optimize, run
279 debugwalk: include, exclude
281 debugwalk: include, exclude
280 debugwireargs: three, four, five, ssh, remotecmd, insecure
282 debugwireargs: three, four, five, ssh, remotecmd, insecure
281 files: rev, print0, include, exclude, template, subrepos
283 files: rev, print0, include, exclude, template, subrepos
282 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
284 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
283 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, template, include, exclude
285 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, template, include, exclude
284 heads: rev, topo, active, closed, style, template
286 heads: rev, topo, active, closed, style, template
285 help: extension, command, keyword, system
287 help: extension, command, keyword, system
286 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
288 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
287 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
289 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
288 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
290 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
289 locate: rev, print0, fullpath, include, exclude
291 locate: rev, print0, fullpath, include, exclude
290 manifest: rev, all, template
292 manifest: rev, all, template
291 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
293 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
292 parents: rev, style, template
294 parents: rev, style, template
293 paths: template
295 paths: template
294 phase: public, draft, secret, force, rev
296 phase: public, draft, secret, force, rev
295 recover:
297 recover:
296 rename: after, force, include, exclude, dry-run
298 rename: after, force, include, exclude, dry-run
297 resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
299 resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
298 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
300 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
299 rollback: dry-run, force
301 rollback: dry-run, force
300 root:
302 root:
301 tag: force, local, rev, remove, edit, message, date, user
303 tag: force, local, rev, remove, edit, message, date, user
302 tags: template
304 tags: template
303 tip: patch, git, style, template
305 tip: patch, git, style, template
304 unbundle: update
306 unbundle: update
305 verify:
307 verify:
306 version: template
308 version: template
307
309
308 $ hg init a
310 $ hg init a
309 $ cd a
311 $ cd a
310 $ echo fee > fee
312 $ echo fee > fee
311 $ hg ci -q -Amfee
313 $ hg ci -q -Amfee
312 $ hg tag fee
314 $ hg tag fee
313 $ mkdir fie
315 $ mkdir fie
314 $ echo dead > fie/dead
316 $ echo dead > fie/dead
315 $ echo live > fie/live
317 $ echo live > fie/live
316 $ hg bookmark fo
318 $ hg bookmark fo
317 $ hg branch -q fie
319 $ hg branch -q fie
318 $ hg ci -q -Amfie
320 $ hg ci -q -Amfie
319 $ echo fo > fo
321 $ echo fo > fo
320 $ hg branch -qf default
322 $ hg branch -qf default
321 $ hg ci -q -Amfo
323 $ hg ci -q -Amfo
322 $ echo Fum > Fum
324 $ echo Fum > Fum
323 $ hg ci -q -AmFum
325 $ hg ci -q -AmFum
324 $ hg bookmark Fum
326 $ hg bookmark Fum
325
327
326 Test debugpathcomplete
328 Test debugpathcomplete
327
329
328 $ hg debugpathcomplete f
330 $ hg debugpathcomplete f
329 fee
331 fee
330 fie
332 fie
331 fo
333 fo
332 $ hg debugpathcomplete -f f
334 $ hg debugpathcomplete -f f
333 fee
335 fee
334 fie/dead
336 fie/dead
335 fie/live
337 fie/live
336 fo
338 fo
337
339
338 $ hg rm Fum
340 $ hg rm Fum
339 $ hg debugpathcomplete -r F
341 $ hg debugpathcomplete -r F
340 Fum
342 Fum
341
343
342 Test debugnamecomplete
344 Test debugnamecomplete
343
345
344 $ hg debugnamecomplete
346 $ hg debugnamecomplete
345 Fum
347 Fum
346 default
348 default
347 fee
349 fee
348 fie
350 fie
349 fo
351 fo
350 tip
352 tip
351 $ hg debugnamecomplete f
353 $ hg debugnamecomplete f
352 fee
354 fee
353 fie
355 fie
354 fo
356 fo
@@ -1,1527 +1,1539 b''
1 Test basic extension support
1 Test basic extension support
2
2
3 $ cat > foobar.py <<EOF
3 $ cat > foobar.py <<EOF
4 > import os
4 > import os
5 > from mercurial import cmdutil, commands
5 > from mercurial import cmdutil, commands
6 > cmdtable = {}
6 > cmdtable = {}
7 > command = cmdutil.command(cmdtable)
7 > command = cmdutil.command(cmdtable)
8 > def uisetup(ui):
8 > def uisetup(ui):
9 > ui.write("uisetup called\\n")
9 > ui.write("uisetup called\\n")
10 > ui.flush()
10 > ui.flush()
11 > def reposetup(ui, repo):
11 > def reposetup(ui, repo):
12 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
12 > ui.write("reposetup called for %s\\n" % os.path.basename(repo.root))
13 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
13 > ui.write("ui %s= repo.ui\\n" % (ui == repo.ui and "=" or "!"))
14 > ui.flush()
14 > ui.flush()
15 > @command('foo', [], 'hg foo')
15 > @command('foo', [], 'hg foo')
16 > def foo(ui, *args, **kwargs):
16 > def foo(ui, *args, **kwargs):
17 > ui.write("Foo\\n")
17 > ui.write("Foo\\n")
18 > @command('bar', [], 'hg bar', norepo=True)
18 > @command('bar', [], 'hg bar', norepo=True)
19 > def bar(ui, *args, **kwargs):
19 > def bar(ui, *args, **kwargs):
20 > ui.write("Bar\\n")
20 > ui.write("Bar\\n")
21 > EOF
21 > EOF
22 $ abspath=`pwd`/foobar.py
22 $ abspath=`pwd`/foobar.py
23
23
24 $ mkdir barfoo
24 $ mkdir barfoo
25 $ cp foobar.py barfoo/__init__.py
25 $ cp foobar.py barfoo/__init__.py
26 $ barfoopath=`pwd`/barfoo
26 $ barfoopath=`pwd`/barfoo
27
27
28 $ hg init a
28 $ hg init a
29 $ cd a
29 $ cd a
30 $ echo foo > file
30 $ echo foo > file
31 $ hg add file
31 $ hg add file
32 $ hg commit -m 'add file'
32 $ hg commit -m 'add file'
33
33
34 $ echo '[extensions]' >> $HGRCPATH
34 $ echo '[extensions]' >> $HGRCPATH
35 $ echo "foobar = $abspath" >> $HGRCPATH
35 $ echo "foobar = $abspath" >> $HGRCPATH
36 $ hg foo
36 $ hg foo
37 uisetup called
37 uisetup called
38 reposetup called for a
38 reposetup called for a
39 ui == repo.ui
39 ui == repo.ui
40 Foo
40 Foo
41
41
42 $ cd ..
42 $ cd ..
43 $ hg clone a b
43 $ hg clone a b
44 uisetup called
44 uisetup called
45 reposetup called for a
45 reposetup called for a
46 ui == repo.ui
46 ui == repo.ui
47 reposetup called for b
47 reposetup called for b
48 ui == repo.ui
48 ui == repo.ui
49 updating to branch default
49 updating to branch default
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
51
51
52 $ hg bar
52 $ hg bar
53 uisetup called
53 uisetup called
54 Bar
54 Bar
55 $ echo 'foobar = !' >> $HGRCPATH
55 $ echo 'foobar = !' >> $HGRCPATH
56
56
57 module/__init__.py-style
57 module/__init__.py-style
58
58
59 $ echo "barfoo = $barfoopath" >> $HGRCPATH
59 $ echo "barfoo = $barfoopath" >> $HGRCPATH
60 $ cd a
60 $ cd a
61 $ hg foo
61 $ hg foo
62 uisetup called
62 uisetup called
63 reposetup called for a
63 reposetup called for a
64 ui == repo.ui
64 ui == repo.ui
65 Foo
65 Foo
66 $ echo 'barfoo = !' >> $HGRCPATH
66 $ echo 'barfoo = !' >> $HGRCPATH
67
67
68 Check that extensions are loaded in phases:
68 Check that extensions are loaded in phases:
69
69
70 $ cat > foo.py <<EOF
70 $ cat > foo.py <<EOF
71 > import os
71 > import os
72 > name = os.path.basename(__file__).rsplit('.', 1)[0]
72 > name = os.path.basename(__file__).rsplit('.', 1)[0]
73 > print "1) %s imported" % name
73 > print "1) %s imported" % name
74 > def uisetup(ui):
74 > def uisetup(ui):
75 > print "2) %s uisetup" % name
75 > print "2) %s uisetup" % name
76 > def extsetup():
76 > def extsetup():
77 > print "3) %s extsetup" % name
77 > print "3) %s extsetup" % name
78 > def reposetup(ui, repo):
78 > def reposetup(ui, repo):
79 > print "4) %s reposetup" % name
79 > print "4) %s reposetup" % name
80 > EOF
80 > EOF
81
81
82 $ cp foo.py bar.py
82 $ cp foo.py bar.py
83 $ echo 'foo = foo.py' >> $HGRCPATH
83 $ echo 'foo = foo.py' >> $HGRCPATH
84 $ echo 'bar = bar.py' >> $HGRCPATH
84 $ echo 'bar = bar.py' >> $HGRCPATH
85
85
86 Command with no output, we just want to see the extensions loaded:
86 Command with no output, we just want to see the extensions loaded:
87
87
88 $ hg paths
88 $ hg paths
89 1) foo imported
89 1) foo imported
90 1) bar imported
90 1) bar imported
91 2) foo uisetup
91 2) foo uisetup
92 2) bar uisetup
92 2) bar uisetup
93 3) foo extsetup
93 3) foo extsetup
94 3) bar extsetup
94 3) bar extsetup
95 4) foo reposetup
95 4) foo reposetup
96 4) bar reposetup
96 4) bar reposetup
97
97
98 Check hgweb's load order:
98 Check hgweb's load order:
99
99
100 $ cat > hgweb.cgi <<EOF
100 $ cat > hgweb.cgi <<EOF
101 > #!/usr/bin/env python
101 > #!/usr/bin/env python
102 > from mercurial import demandimport; demandimport.enable()
102 > from mercurial import demandimport; demandimport.enable()
103 > from mercurial.hgweb import hgweb
103 > from mercurial.hgweb import hgweb
104 > from mercurial.hgweb import wsgicgi
104 > from mercurial.hgweb import wsgicgi
105 > application = hgweb('.', 'test repo')
105 > application = hgweb('.', 'test repo')
106 > wsgicgi.launch(application)
106 > wsgicgi.launch(application)
107 > EOF
107 > EOF
108
108
109 $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
109 $ REQUEST_METHOD='GET' PATH_INFO='/' SCRIPT_NAME='' QUERY_STRING='' \
110 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
110 > SERVER_PORT='80' SERVER_NAME='localhost' python hgweb.cgi \
111 > | grep '^[0-9]) ' # ignores HTML output
111 > | grep '^[0-9]) ' # ignores HTML output
112 1) foo imported
112 1) foo imported
113 1) bar imported
113 1) bar imported
114 2) foo uisetup
114 2) foo uisetup
115 2) bar uisetup
115 2) bar uisetup
116 3) foo extsetup
116 3) foo extsetup
117 3) bar extsetup
117 3) bar extsetup
118 4) foo reposetup
118 4) foo reposetup
119 4) bar reposetup
119 4) bar reposetup
120
120
121 $ echo 'foo = !' >> $HGRCPATH
121 $ echo 'foo = !' >> $HGRCPATH
122 $ echo 'bar = !' >> $HGRCPATH
122 $ echo 'bar = !' >> $HGRCPATH
123
123
124 Check "from __future__ import absolute_import" support for external libraries
124 Check "from __future__ import absolute_import" support for external libraries
125
125
126 #if windows
126 #if windows
127 $ PATHSEP=";"
127 $ PATHSEP=";"
128 #else
128 #else
129 $ PATHSEP=":"
129 $ PATHSEP=":"
130 #endif
130 #endif
131 $ export PATHSEP
131 $ export PATHSEP
132
132
133 $ mkdir $TESTTMP/libroot
133 $ mkdir $TESTTMP/libroot
134 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
134 $ echo "s = 'libroot/ambig.py'" > $TESTTMP/libroot/ambig.py
135 $ mkdir $TESTTMP/libroot/mod
135 $ mkdir $TESTTMP/libroot/mod
136 $ touch $TESTTMP/libroot/mod/__init__.py
136 $ touch $TESTTMP/libroot/mod/__init__.py
137 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
137 $ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
138
138
139 #if absimport
139 #if absimport
140 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
140 $ cat > $TESTTMP/libroot/mod/ambigabs.py <<EOF
141 > from __future__ import absolute_import
141 > from __future__ import absolute_import
142 > import ambig # should load "libroot/ambig.py"
142 > import ambig # should load "libroot/ambig.py"
143 > s = ambig.s
143 > s = ambig.s
144 > EOF
144 > EOF
145 $ cat > loadabs.py <<EOF
145 $ cat > loadabs.py <<EOF
146 > import mod.ambigabs as ambigabs
146 > import mod.ambigabs as ambigabs
147 > def extsetup():
147 > def extsetup():
148 > print 'ambigabs.s=%s' % ambigabs.s
148 > print 'ambigabs.s=%s' % ambigabs.s
149 > EOF
149 > EOF
150 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
150 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadabs=loadabs.py root)
151 ambigabs.s=libroot/ambig.py
151 ambigabs.s=libroot/ambig.py
152 $TESTTMP/a (glob)
152 $TESTTMP/a (glob)
153 #endif
153 #endif
154
154
155 #if no-py3k
155 #if no-py3k
156 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
156 $ cat > $TESTTMP/libroot/mod/ambigrel.py <<EOF
157 > import ambig # should load "libroot/mod/ambig.py"
157 > import ambig # should load "libroot/mod/ambig.py"
158 > s = ambig.s
158 > s = ambig.s
159 > EOF
159 > EOF
160 $ cat > loadrel.py <<EOF
160 $ cat > loadrel.py <<EOF
161 > import mod.ambigrel as ambigrel
161 > import mod.ambigrel as ambigrel
162 > def extsetup():
162 > def extsetup():
163 > print 'ambigrel.s=%s' % ambigrel.s
163 > print 'ambigrel.s=%s' % ambigrel.s
164 > EOF
164 > EOF
165 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
165 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
166 ambigrel.s=libroot/mod/ambig.py
166 ambigrel.s=libroot/mod/ambig.py
167 $TESTTMP/a (glob)
167 $TESTTMP/a (glob)
168 #endif
168 #endif
169
169
170 Check absolute/relative import of extension specific modules
170 Check absolute/relative import of extension specific modules
171
171
172 $ mkdir $TESTTMP/extroot
172 $ mkdir $TESTTMP/extroot
173 $ cat > $TESTTMP/extroot/bar.py <<EOF
173 $ cat > $TESTTMP/extroot/bar.py <<EOF
174 > s = 'this is extroot.bar'
174 > s = 'this is extroot.bar'
175 > EOF
175 > EOF
176 $ mkdir $TESTTMP/extroot/sub1
176 $ mkdir $TESTTMP/extroot/sub1
177 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
177 $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
178 > s = 'this is extroot.sub1.__init__'
178 > s = 'this is extroot.sub1.__init__'
179 > EOF
179 > EOF
180 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
180 $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
181 > s = 'this is extroot.sub1.baz'
181 > s = 'this is extroot.sub1.baz'
182 > EOF
182 > EOF
183 $ cat > $TESTTMP/extroot/__init__.py <<EOF
183 $ cat > $TESTTMP/extroot/__init__.py <<EOF
184 > s = 'this is extroot.__init__'
184 > s = 'this is extroot.__init__'
185 > import foo
185 > import foo
186 > def extsetup(ui):
186 > def extsetup(ui):
187 > ui.write('(extroot) ', foo.func(), '\n')
187 > ui.write('(extroot) ', foo.func(), '\n')
188 > ui.flush()
188 > ui.flush()
189 > EOF
189 > EOF
190
190
191 $ cat > $TESTTMP/extroot/foo.py <<EOF
191 $ cat > $TESTTMP/extroot/foo.py <<EOF
192 > # test absolute import
192 > # test absolute import
193 > buf = []
193 > buf = []
194 > def func():
194 > def func():
195 > # "not locals" case
195 > # "not locals" case
196 > import extroot.bar
196 > import extroot.bar
197 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
197 > buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
198 > return '\n(extroot) '.join(buf)
198 > return '\n(extroot) '.join(buf)
199 > # "fromlist == ('*',)" case
199 > # "fromlist == ('*',)" case
200 > from extroot.bar import *
200 > from extroot.bar import *
201 > buf.append('from extroot.bar import *: %s' % s)
201 > buf.append('from extroot.bar import *: %s' % s)
202 > # "not fromlist" and "if '.' in name" case
202 > # "not fromlist" and "if '.' in name" case
203 > import extroot.sub1.baz
203 > import extroot.sub1.baz
204 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
204 > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
205 > # "not fromlist" and NOT "if '.' in name" case
205 > # "not fromlist" and NOT "if '.' in name" case
206 > import extroot
206 > import extroot
207 > buf.append('import extroot: %s' % extroot.s)
207 > buf.append('import extroot: %s' % extroot.s)
208 > # NOT "not fromlist" and NOT "level != -1" case
208 > # NOT "not fromlist" and NOT "level != -1" case
209 > from extroot.bar import s
209 > from extroot.bar import s
210 > buf.append('from extroot.bar import s: %s' % s)
210 > buf.append('from extroot.bar import s: %s' % s)
211 > EOF
211 > EOF
212 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.extroot=$TESTTMP/extroot root)
212 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.extroot=$TESTTMP/extroot root)
213 (extroot) from extroot.bar import *: this is extroot.bar
213 (extroot) from extroot.bar import *: this is extroot.bar
214 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
214 (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
215 (extroot) import extroot: this is extroot.__init__
215 (extroot) import extroot: this is extroot.__init__
216 (extroot) from extroot.bar import s: this is extroot.bar
216 (extroot) from extroot.bar import s: this is extroot.bar
217 (extroot) import extroot.bar in func(): this is extroot.bar
217 (extroot) import extroot.bar in func(): this is extroot.bar
218 $TESTTMP/a (glob)
218 $TESTTMP/a (glob)
219
219
220 #if no-py3k
220 #if no-py3k
221 $ rm "$TESTTMP"/extroot/foo.*
221 $ rm "$TESTTMP"/extroot/foo.*
222 $ cat > $TESTTMP/extroot/foo.py <<EOF
222 $ cat > $TESTTMP/extroot/foo.py <<EOF
223 > # test relative import
223 > # test relative import
224 > buf = []
224 > buf = []
225 > def func():
225 > def func():
226 > # "not locals" case
226 > # "not locals" case
227 > import bar
227 > import bar
228 > buf.append('import bar in func(): %s' % bar.s)
228 > buf.append('import bar in func(): %s' % bar.s)
229 > return '\n(extroot) '.join(buf)
229 > return '\n(extroot) '.join(buf)
230 > # "fromlist == ('*',)" case
230 > # "fromlist == ('*',)" case
231 > from bar import *
231 > from bar import *
232 > buf.append('from bar import *: %s' % s)
232 > buf.append('from bar import *: %s' % s)
233 > # "not fromlist" and "if '.' in name" case
233 > # "not fromlist" and "if '.' in name" case
234 > import sub1.baz
234 > import sub1.baz
235 > buf.append('import sub1.baz: %s' % sub1.baz.s)
235 > buf.append('import sub1.baz: %s' % sub1.baz.s)
236 > # "not fromlist" and NOT "if '.' in name" case
236 > # "not fromlist" and NOT "if '.' in name" case
237 > import sub1
237 > import sub1
238 > buf.append('import sub1: %s' % sub1.s)
238 > buf.append('import sub1: %s' % sub1.s)
239 > # NOT "not fromlist" and NOT "level != -1" case
239 > # NOT "not fromlist" and NOT "level != -1" case
240 > from bar import s
240 > from bar import s
241 > buf.append('from bar import s: %s' % s)
241 > buf.append('from bar import s: %s' % s)
242 > EOF
242 > EOF
243 $ hg --config extensions.extroot=$TESTTMP/extroot root
243 $ hg --config extensions.extroot=$TESTTMP/extroot root
244 (extroot) from bar import *: this is extroot.bar
244 (extroot) from bar import *: this is extroot.bar
245 (extroot) import sub1.baz: this is extroot.sub1.baz
245 (extroot) import sub1.baz: this is extroot.sub1.baz
246 (extroot) import sub1: this is extroot.sub1.__init__
246 (extroot) import sub1: this is extroot.sub1.__init__
247 (extroot) from bar import s: this is extroot.bar
247 (extroot) from bar import s: this is extroot.bar
248 (extroot) import bar in func(): this is extroot.bar
248 (extroot) import bar in func(): this is extroot.bar
249 $TESTTMP/a (glob)
249 $TESTTMP/a (glob)
250 #endif
250 #endif
251
251
252 #if demandimport absimport
252 #if demandimport absimport
253
253
254 Examine whether module loading is delayed until actual referring, even
254 Examine whether module loading is delayed until actual referring, even
255 though module is imported with "absolute_import" feature.
255 though module is imported with "absolute_import" feature.
256
256
257 Files below in each packages are used for described purpose:
257 Files below in each packages are used for described purpose:
258
258
259 - "called": examine whether "from MODULE import ATTR" works correctly
259 - "called": examine whether "from MODULE import ATTR" works correctly
260 - "unused": examine whether loading is delayed correctly
260 - "unused": examine whether loading is delayed correctly
261 - "used": examine whether "from PACKAGE import MODULE" works correctly
261 - "used": examine whether "from PACKAGE import MODULE" works correctly
262
262
263 Package hierarchy is needed to examine whether demand importing works
263 Package hierarchy is needed to examine whether demand importing works
264 as expected for "from SUB.PACK.AGE import MODULE".
264 as expected for "from SUB.PACK.AGE import MODULE".
265
265
266 Setup "external library" to be imported with "absolute_import"
266 Setup "external library" to be imported with "absolute_import"
267 feature.
267 feature.
268
268
269 $ mkdir -p $TESTTMP/extlibroot/lsub1/lsub2
269 $ mkdir -p $TESTTMP/extlibroot/lsub1/lsub2
270 $ touch $TESTTMP/extlibroot/__init__.py
270 $ touch $TESTTMP/extlibroot/__init__.py
271 $ touch $TESTTMP/extlibroot/lsub1/__init__.py
271 $ touch $TESTTMP/extlibroot/lsub1/__init__.py
272 $ touch $TESTTMP/extlibroot/lsub1/lsub2/__init__.py
272 $ touch $TESTTMP/extlibroot/lsub1/lsub2/__init__.py
273
273
274 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/called.py <<EOF
274 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/called.py <<EOF
275 > def func():
275 > def func():
276 > return "this is extlibroot.lsub1.lsub2.called.func()"
276 > return "this is extlibroot.lsub1.lsub2.called.func()"
277 > EOF
277 > EOF
278 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/unused.py <<EOF
278 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/unused.py <<EOF
279 > raise Exception("extlibroot.lsub1.lsub2.unused is loaded unintentionally")
279 > raise Exception("extlibroot.lsub1.lsub2.unused is loaded unintentionally")
280 > EOF
280 > EOF
281 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/used.py <<EOF
281 $ cat > $TESTTMP/extlibroot/lsub1/lsub2/used.py <<EOF
282 > detail = "this is extlibroot.lsub1.lsub2.used"
282 > detail = "this is extlibroot.lsub1.lsub2.used"
283 > EOF
283 > EOF
284
284
285 Setup sub-package of "external library", which causes instantiation of
285 Setup sub-package of "external library", which causes instantiation of
286 demandmod in "recurse down the module chain" code path. Relative
286 demandmod in "recurse down the module chain" code path. Relative
287 importing with "absolute_import" feature isn't tested, because "level
287 importing with "absolute_import" feature isn't tested, because "level
288 >=1 " doesn't cause instantiation of demandmod.
288 >=1 " doesn't cause instantiation of demandmod.
289
289
290 $ mkdir -p $TESTTMP/extlibroot/recursedown/abs
290 $ mkdir -p $TESTTMP/extlibroot/recursedown/abs
291 $ cat > $TESTTMP/extlibroot/recursedown/abs/used.py <<EOF
291 $ cat > $TESTTMP/extlibroot/recursedown/abs/used.py <<EOF
292 > detail = "this is extlibroot.recursedown.abs.used"
292 > detail = "this is extlibroot.recursedown.abs.used"
293 > EOF
293 > EOF
294 $ cat > $TESTTMP/extlibroot/recursedown/abs/__init__.py <<EOF
294 $ cat > $TESTTMP/extlibroot/recursedown/abs/__init__.py <<EOF
295 > from __future__ import absolute_import
295 > from __future__ import absolute_import
296 > from extlibroot.recursedown.abs.used import detail
296 > from extlibroot.recursedown.abs.used import detail
297 > EOF
297 > EOF
298
298
299 $ mkdir -p $TESTTMP/extlibroot/recursedown/legacy
299 $ mkdir -p $TESTTMP/extlibroot/recursedown/legacy
300 $ cat > $TESTTMP/extlibroot/recursedown/legacy/used.py <<EOF
300 $ cat > $TESTTMP/extlibroot/recursedown/legacy/used.py <<EOF
301 > detail = "this is extlibroot.recursedown.legacy.used"
301 > detail = "this is extlibroot.recursedown.legacy.used"
302 > EOF
302 > EOF
303 $ cat > $TESTTMP/extlibroot/recursedown/legacy/__init__.py <<EOF
303 $ cat > $TESTTMP/extlibroot/recursedown/legacy/__init__.py <<EOF
304 > # legacy style (level == -1) import
304 > # legacy style (level == -1) import
305 > from extlibroot.recursedown.legacy.used import detail
305 > from extlibroot.recursedown.legacy.used import detail
306 > EOF
306 > EOF
307
307
308 $ cat > $TESTTMP/extlibroot/recursedown/__init__.py <<EOF
308 $ cat > $TESTTMP/extlibroot/recursedown/__init__.py <<EOF
309 > from __future__ import absolute_import
309 > from __future__ import absolute_import
310 > from extlibroot.recursedown.abs import detail as absdetail
310 > from extlibroot.recursedown.abs import detail as absdetail
311 > from .legacy import detail as legacydetail
311 > from .legacy import detail as legacydetail
312 > EOF
312 > EOF
313
313
314 Setup extension local modules to be imported with "absolute_import"
314 Setup extension local modules to be imported with "absolute_import"
315 feature.
315 feature.
316
316
317 $ mkdir -p $TESTTMP/absextroot/xsub1/xsub2
317 $ mkdir -p $TESTTMP/absextroot/xsub1/xsub2
318 $ touch $TESTTMP/absextroot/xsub1/__init__.py
318 $ touch $TESTTMP/absextroot/xsub1/__init__.py
319 $ touch $TESTTMP/absextroot/xsub1/xsub2/__init__.py
319 $ touch $TESTTMP/absextroot/xsub1/xsub2/__init__.py
320
320
321 $ cat > $TESTTMP/absextroot/xsub1/xsub2/called.py <<EOF
321 $ cat > $TESTTMP/absextroot/xsub1/xsub2/called.py <<EOF
322 > def func():
322 > def func():
323 > return "this is absextroot.xsub1.xsub2.called.func()"
323 > return "this is absextroot.xsub1.xsub2.called.func()"
324 > EOF
324 > EOF
325 $ cat > $TESTTMP/absextroot/xsub1/xsub2/unused.py <<EOF
325 $ cat > $TESTTMP/absextroot/xsub1/xsub2/unused.py <<EOF
326 > raise Exception("absextroot.xsub1.xsub2.unused is loaded unintentionally")
326 > raise Exception("absextroot.xsub1.xsub2.unused is loaded unintentionally")
327 > EOF
327 > EOF
328 $ cat > $TESTTMP/absextroot/xsub1/xsub2/used.py <<EOF
328 $ cat > $TESTTMP/absextroot/xsub1/xsub2/used.py <<EOF
329 > detail = "this is absextroot.xsub1.xsub2.used"
329 > detail = "this is absextroot.xsub1.xsub2.used"
330 > EOF
330 > EOF
331
331
332 Setup extension local modules to examine whether demand importing
332 Setup extension local modules to examine whether demand importing
333 works as expected in "level > 1" case.
333 works as expected in "level > 1" case.
334
334
335 $ cat > $TESTTMP/absextroot/relimportee.py <<EOF
335 $ cat > $TESTTMP/absextroot/relimportee.py <<EOF
336 > detail = "this is absextroot.relimportee"
336 > detail = "this is absextroot.relimportee"
337 > EOF
337 > EOF
338 $ cat > $TESTTMP/absextroot/xsub1/xsub2/relimporter.py <<EOF
338 $ cat > $TESTTMP/absextroot/xsub1/xsub2/relimporter.py <<EOF
339 > from __future__ import absolute_import
339 > from __future__ import absolute_import
340 > from ... import relimportee
340 > from ... import relimportee
341 > detail = "this relimporter imports %r" % (relimportee.detail)
341 > detail = "this relimporter imports %r" % (relimportee.detail)
342 > EOF
342 > EOF
343
343
344 Setup modules, which actually import extension local modules at
344 Setup modules, which actually import extension local modules at
345 runtime.
345 runtime.
346
346
347 $ cat > $TESTTMP/absextroot/absolute.py << EOF
347 $ cat > $TESTTMP/absextroot/absolute.py << EOF
348 > from __future__ import absolute_import
348 > from __future__ import absolute_import
349 >
349 >
350 > # import extension local modules absolutely (level = 0)
350 > # import extension local modules absolutely (level = 0)
351 > from absextroot.xsub1.xsub2 import used, unused
351 > from absextroot.xsub1.xsub2 import used, unused
352 > from absextroot.xsub1.xsub2.called import func
352 > from absextroot.xsub1.xsub2.called import func
353 >
353 >
354 > def getresult():
354 > def getresult():
355 > result = []
355 > result = []
356 > result.append(used.detail)
356 > result.append(used.detail)
357 > result.append(func())
357 > result.append(func())
358 > return result
358 > return result
359 > EOF
359 > EOF
360
360
361 $ cat > $TESTTMP/absextroot/relative.py << EOF
361 $ cat > $TESTTMP/absextroot/relative.py << EOF
362 > from __future__ import absolute_import
362 > from __future__ import absolute_import
363 >
363 >
364 > # import extension local modules relatively (level == 1)
364 > # import extension local modules relatively (level == 1)
365 > from .xsub1.xsub2 import used, unused
365 > from .xsub1.xsub2 import used, unused
366 > from .xsub1.xsub2.called import func
366 > from .xsub1.xsub2.called import func
367 >
367 >
368 > # import a module, which implies "importing with level > 1"
368 > # import a module, which implies "importing with level > 1"
369 > from .xsub1.xsub2 import relimporter
369 > from .xsub1.xsub2 import relimporter
370 >
370 >
371 > def getresult():
371 > def getresult():
372 > result = []
372 > result = []
373 > result.append(used.detail)
373 > result.append(used.detail)
374 > result.append(func())
374 > result.append(func())
375 > result.append(relimporter.detail)
375 > result.append(relimporter.detail)
376 > return result
376 > return result
377 > EOF
377 > EOF
378
378
379 Setup main procedure of extension.
379 Setup main procedure of extension.
380
380
381 $ cat > $TESTTMP/absextroot/__init__.py <<EOF
381 $ cat > $TESTTMP/absextroot/__init__.py <<EOF
382 > from __future__ import absolute_import
382 > from __future__ import absolute_import
383 > from mercurial import cmdutil
383 > from mercurial import cmdutil
384 > cmdtable = {}
384 > cmdtable = {}
385 > command = cmdutil.command(cmdtable)
385 > command = cmdutil.command(cmdtable)
386 >
386 >
387 > # "absolute" and "relative" shouldn't be imported before actual
387 > # "absolute" and "relative" shouldn't be imported before actual
388 > # command execution, because (1) they import same modules, and (2)
388 > # command execution, because (1) they import same modules, and (2)
389 > # preceding import (= instantiate "demandmod" object instead of
389 > # preceding import (= instantiate "demandmod" object instead of
390 > # real "module" object) might hide problem of succeeding import.
390 > # real "module" object) might hide problem of succeeding import.
391 >
391 >
392 > @command('showabsolute', [], norepo=True)
392 > @command('showabsolute', [], norepo=True)
393 > def showabsolute(ui, *args, **opts):
393 > def showabsolute(ui, *args, **opts):
394 > from absextroot import absolute
394 > from absextroot import absolute
395 > ui.write('ABS: %s\n' % '\nABS: '.join(absolute.getresult()))
395 > ui.write('ABS: %s\n' % '\nABS: '.join(absolute.getresult()))
396 >
396 >
397 > @command('showrelative', [], norepo=True)
397 > @command('showrelative', [], norepo=True)
398 > def showrelative(ui, *args, **opts):
398 > def showrelative(ui, *args, **opts):
399 > from . import relative
399 > from . import relative
400 > ui.write('REL: %s\n' % '\nREL: '.join(relative.getresult()))
400 > ui.write('REL: %s\n' % '\nREL: '.join(relative.getresult()))
401 >
401 >
402 > # import modules from external library
402 > # import modules from external library
403 > from extlibroot.lsub1.lsub2 import used as lused, unused as lunused
403 > from extlibroot.lsub1.lsub2 import used as lused, unused as lunused
404 > from extlibroot.lsub1.lsub2.called import func as lfunc
404 > from extlibroot.lsub1.lsub2.called import func as lfunc
405 > from extlibroot.recursedown import absdetail, legacydetail
405 > from extlibroot.recursedown import absdetail, legacydetail
406 >
406 >
407 > def uisetup(ui):
407 > def uisetup(ui):
408 > result = []
408 > result = []
409 > result.append(lused.detail)
409 > result.append(lused.detail)
410 > result.append(lfunc())
410 > result.append(lfunc())
411 > result.append(absdetail)
411 > result.append(absdetail)
412 > result.append(legacydetail)
412 > result.append(legacydetail)
413 > ui.write('LIB: %s\n' % '\nLIB: '.join(result))
413 > ui.write('LIB: %s\n' % '\nLIB: '.join(result))
414 > EOF
414 > EOF
415
415
416 Examine module importing.
416 Examine module importing.
417
417
418 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showabsolute)
418 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showabsolute)
419 LIB: this is extlibroot.lsub1.lsub2.used
419 LIB: this is extlibroot.lsub1.lsub2.used
420 LIB: this is extlibroot.lsub1.lsub2.called.func()
420 LIB: this is extlibroot.lsub1.lsub2.called.func()
421 LIB: this is extlibroot.recursedown.abs.used
421 LIB: this is extlibroot.recursedown.abs.used
422 LIB: this is extlibroot.recursedown.legacy.used
422 LIB: this is extlibroot.recursedown.legacy.used
423 ABS: this is absextroot.xsub1.xsub2.used
423 ABS: this is absextroot.xsub1.xsub2.used
424 ABS: this is absextroot.xsub1.xsub2.called.func()
424 ABS: this is absextroot.xsub1.xsub2.called.func()
425
425
426 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showrelative)
426 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.absextroot=$TESTTMP/absextroot showrelative)
427 LIB: this is extlibroot.lsub1.lsub2.used
427 LIB: this is extlibroot.lsub1.lsub2.used
428 LIB: this is extlibroot.lsub1.lsub2.called.func()
428 LIB: this is extlibroot.lsub1.lsub2.called.func()
429 LIB: this is extlibroot.recursedown.abs.used
429 LIB: this is extlibroot.recursedown.abs.used
430 LIB: this is extlibroot.recursedown.legacy.used
430 LIB: this is extlibroot.recursedown.legacy.used
431 REL: this is absextroot.xsub1.xsub2.used
431 REL: this is absextroot.xsub1.xsub2.used
432 REL: this is absextroot.xsub1.xsub2.called.func()
432 REL: this is absextroot.xsub1.xsub2.called.func()
433 REL: this relimporter imports 'this is absextroot.relimportee'
433 REL: this relimporter imports 'this is absextroot.relimportee'
434
434
435 Examine whether sub-module is imported relatively as expected.
435 Examine whether sub-module is imported relatively as expected.
436
436
437 See also issue5208 for detail about example case on Python 3.x.
437 See also issue5208 for detail about example case on Python 3.x.
438
438
439 $ f -q $TESTTMP/extlibroot/lsub1/lsub2/notexist.py
439 $ f -q $TESTTMP/extlibroot/lsub1/lsub2/notexist.py
440 $TESTTMP/extlibroot/lsub1/lsub2/notexist.py: file not found
440 $TESTTMP/extlibroot/lsub1/lsub2/notexist.py: file not found
441
441
442 $ cat > $TESTTMP/notexist.py <<EOF
442 $ cat > $TESTTMP/notexist.py <<EOF
443 > text = 'notexist.py at root is loaded unintentionally\n'
443 > text = 'notexist.py at root is loaded unintentionally\n'
444 > EOF
444 > EOF
445
445
446 $ cat > $TESTTMP/checkrelativity.py <<EOF
446 $ cat > $TESTTMP/checkrelativity.py <<EOF
447 > from mercurial import cmdutil
447 > from mercurial import cmdutil
448 > cmdtable = {}
448 > cmdtable = {}
449 > command = cmdutil.command(cmdtable)
449 > command = cmdutil.command(cmdtable)
450 >
450 >
451 > # demand import avoids failure of importing notexist here
451 > # demand import avoids failure of importing notexist here
452 > import extlibroot.lsub1.lsub2.notexist
452 > import extlibroot.lsub1.lsub2.notexist
453 >
453 >
454 > @command('checkrelativity', [], norepo=True)
454 > @command('checkrelativity', [], norepo=True)
455 > def checkrelativity(ui, *args, **opts):
455 > def checkrelativity(ui, *args, **opts):
456 > try:
456 > try:
457 > ui.write(extlibroot.lsub1.lsub2.notexist.text)
457 > ui.write(extlibroot.lsub1.lsub2.notexist.text)
458 > return 1 # unintentional success
458 > return 1 # unintentional success
459 > except ImportError:
459 > except ImportError:
460 > pass # intentional failure
460 > pass # intentional failure
461 > EOF
461 > EOF
462
462
463 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.checkrelativity=$TESTTMP/checkrelativity.py checkrelativity)
463 $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}; hg --config extensions.checkrelativity=$TESTTMP/checkrelativity.py checkrelativity)
464
464
465 #endif
465 #endif
466
466
467 $ cd ..
467 $ cd ..
468
468
469 hide outer repo
469 hide outer repo
470 $ hg init
470 $ hg init
471
471
472 $ cat > empty.py <<EOF
472 $ cat > empty.py <<EOF
473 > '''empty cmdtable
473 > '''empty cmdtable
474 > '''
474 > '''
475 > cmdtable = {}
475 > cmdtable = {}
476 > EOF
476 > EOF
477 $ emptypath=`pwd`/empty.py
477 $ emptypath=`pwd`/empty.py
478 $ echo "empty = $emptypath" >> $HGRCPATH
478 $ echo "empty = $emptypath" >> $HGRCPATH
479 $ hg help empty
479 $ hg help empty
480 empty extension - empty cmdtable
480 empty extension - empty cmdtable
481
481
482 no commands defined
482 no commands defined
483
483
484
484
485 $ echo 'empty = !' >> $HGRCPATH
485 $ echo 'empty = !' >> $HGRCPATH
486
486
487 $ cat > debugextension.py <<EOF
487 $ cat > debugextension.py <<EOF
488 > '''only debugcommands
488 > '''only debugcommands
489 > '''
489 > '''
490 > from mercurial import cmdutil
490 > from mercurial import cmdutil
491 > cmdtable = {}
491 > cmdtable = {}
492 > command = cmdutil.command(cmdtable)
492 > command = cmdutil.command(cmdtable)
493 > @command('debugfoobar', [], 'hg debugfoobar')
493 > @command('debugfoobar', [], 'hg debugfoobar')
494 > def debugfoobar(ui, repo, *args, **opts):
494 > def debugfoobar(ui, repo, *args, **opts):
495 > "yet another debug command"
495 > "yet another debug command"
496 > pass
496 > pass
497 > @command('foo', [], 'hg foo')
497 > @command('foo', [], 'hg foo')
498 > def foo(ui, repo, *args, **opts):
498 > def foo(ui, repo, *args, **opts):
499 > """yet another foo command
499 > """yet another foo command
500 > This command has been DEPRECATED since forever.
500 > This command has been DEPRECATED since forever.
501 > """
501 > """
502 > pass
502 > pass
503 > EOF
503 > EOF
504 $ debugpath=`pwd`/debugextension.py
504 $ debugpath=`pwd`/debugextension.py
505 $ echo "debugextension = $debugpath" >> $HGRCPATH
505 $ echo "debugextension = $debugpath" >> $HGRCPATH
506
506
507 $ hg help debugextension
507 $ hg help debugextension
508 hg debugextensions
508 hg debugextensions
509
509
510 show information about active extensions
510 show information about active extensions
511
511
512 options:
512 options:
513
513
514 (some details hidden, use --verbose to show complete help)
514 (some details hidden, use --verbose to show complete help)
515
515
516
516
517 $ hg --verbose help debugextension
517 $ hg --verbose help debugextension
518 hg debugextensions
518 hg debugextensions
519
519
520 show information about active extensions
520 show information about active extensions
521
521
522 options:
522 options:
523
523
524 -T --template TEMPLATE display with template (EXPERIMENTAL)
524 -T --template TEMPLATE display with template (EXPERIMENTAL)
525
525
526 global options ([+] can be repeated):
526 global options ([+] can be repeated):
527
527
528 -R --repository REPO repository root directory or name of overlay bundle
528 -R --repository REPO repository root directory or name of overlay bundle
529 file
529 file
530 --cwd DIR change working directory
530 --cwd DIR change working directory
531 -y --noninteractive do not prompt, automatically pick the first choice for
531 -y --noninteractive do not prompt, automatically pick the first choice for
532 all prompts
532 all prompts
533 -q --quiet suppress output
533 -q --quiet suppress output
534 -v --verbose enable additional output
534 -v --verbose enable additional output
535 --config CONFIG [+] set/override config option (use 'section.name=value')
535 --config CONFIG [+] set/override config option (use 'section.name=value')
536 --debug enable debugging output
536 --debug enable debugging output
537 --debugger start debugger
537 --debugger start debugger
538 --encoding ENCODE set the charset encoding (default: ascii)
538 --encoding ENCODE set the charset encoding (default: ascii)
539 --encodingmode MODE set the charset encoding mode (default: strict)
539 --encodingmode MODE set the charset encoding mode (default: strict)
540 --traceback always print a traceback on exception
540 --traceback always print a traceback on exception
541 --time time how long the command takes
541 --time time how long the command takes
542 --profile print command execution profile
542 --profile print command execution profile
543 --version output version information and exit
543 --version output version information and exit
544 -h --help display help and exit
544 -h --help display help and exit
545 --hidden consider hidden changesets
545 --hidden consider hidden changesets
546 --pager TYPE when to paginate (boolean, always, auto, or never)
547 (default: auto)
546
548
547
549
548
550
549
551
550
552
551
553
552 $ hg --debug help debugextension
554 $ hg --debug help debugextension
553 hg debugextensions
555 hg debugextensions
554
556
555 show information about active extensions
557 show information about active extensions
556
558
557 options:
559 options:
558
560
559 -T --template TEMPLATE display with template (EXPERIMENTAL)
561 -T --template TEMPLATE display with template (EXPERIMENTAL)
560
562
561 global options ([+] can be repeated):
563 global options ([+] can be repeated):
562
564
563 -R --repository REPO repository root directory or name of overlay bundle
565 -R --repository REPO repository root directory or name of overlay bundle
564 file
566 file
565 --cwd DIR change working directory
567 --cwd DIR change working directory
566 -y --noninteractive do not prompt, automatically pick the first choice for
568 -y --noninteractive do not prompt, automatically pick the first choice for
567 all prompts
569 all prompts
568 -q --quiet suppress output
570 -q --quiet suppress output
569 -v --verbose enable additional output
571 -v --verbose enable additional output
570 --config CONFIG [+] set/override config option (use 'section.name=value')
572 --config CONFIG [+] set/override config option (use 'section.name=value')
571 --debug enable debugging output
573 --debug enable debugging output
572 --debugger start debugger
574 --debugger start debugger
573 --encoding ENCODE set the charset encoding (default: ascii)
575 --encoding ENCODE set the charset encoding (default: ascii)
574 --encodingmode MODE set the charset encoding mode (default: strict)
576 --encodingmode MODE set the charset encoding mode (default: strict)
575 --traceback always print a traceback on exception
577 --traceback always print a traceback on exception
576 --time time how long the command takes
578 --time time how long the command takes
577 --profile print command execution profile
579 --profile print command execution profile
578 --version output version information and exit
580 --version output version information and exit
579 -h --help display help and exit
581 -h --help display help and exit
580 --hidden consider hidden changesets
582 --hidden consider hidden changesets
583 --pager TYPE when to paginate (boolean, always, auto, or never)
584 (default: auto)
581
585
582
586
583
587
584
588
585
589
586 $ echo 'debugextension = !' >> $HGRCPATH
590 $ echo 'debugextension = !' >> $HGRCPATH
587
591
588 Asking for help about a deprecated extension should do something useful:
592 Asking for help about a deprecated extension should do something useful:
589
593
590 $ hg help glog
594 $ hg help glog
591 'glog' is provided by the following extension:
595 'glog' is provided by the following extension:
592
596
593 graphlog command to view revision graphs from a shell (DEPRECATED)
597 graphlog command to view revision graphs from a shell (DEPRECATED)
594
598
595 (use 'hg help extensions' for information on enabling extensions)
599 (use 'hg help extensions' for information on enabling extensions)
596
600
597 Extension module help vs command help:
601 Extension module help vs command help:
598
602
599 $ echo 'extdiff =' >> $HGRCPATH
603 $ echo 'extdiff =' >> $HGRCPATH
600 $ hg help extdiff
604 $ hg help extdiff
601 hg extdiff [OPT]... [FILE]...
605 hg extdiff [OPT]... [FILE]...
602
606
603 use external program to diff repository (or selected files)
607 use external program to diff repository (or selected files)
604
608
605 Show differences between revisions for the specified files, using an
609 Show differences between revisions for the specified files, using an
606 external program. The default program used is diff, with default options
610 external program. The default program used is diff, with default options
607 "-Npru".
611 "-Npru".
608
612
609 To select a different program, use the -p/--program option. The program
613 To select a different program, use the -p/--program option. The program
610 will be passed the names of two directories to compare. To pass additional
614 will be passed the names of two directories to compare. To pass additional
611 options to the program, use -o/--option. These will be passed before the
615 options to the program, use -o/--option. These will be passed before the
612 names of the directories to compare.
616 names of the directories to compare.
613
617
614 When two revision arguments are given, then changes are shown between
618 When two revision arguments are given, then changes are shown between
615 those revisions. If only one revision is specified then that revision is
619 those revisions. If only one revision is specified then that revision is
616 compared to the working directory, and, when no revisions are specified,
620 compared to the working directory, and, when no revisions are specified,
617 the working directory files are compared to its parent.
621 the working directory files are compared to its parent.
618
622
619 (use 'hg help -e extdiff' to show help for the extdiff extension)
623 (use 'hg help -e extdiff' to show help for the extdiff extension)
620
624
621 options ([+] can be repeated):
625 options ([+] can be repeated):
622
626
623 -p --program CMD comparison program to run
627 -p --program CMD comparison program to run
624 -o --option OPT [+] pass option to comparison program
628 -o --option OPT [+] pass option to comparison program
625 -r --rev REV [+] revision
629 -r --rev REV [+] revision
626 -c --change REV change made by revision
630 -c --change REV change made by revision
627 --patch compare patches for two revisions
631 --patch compare patches for two revisions
628 -I --include PATTERN [+] include names matching the given patterns
632 -I --include PATTERN [+] include names matching the given patterns
629 -X --exclude PATTERN [+] exclude names matching the given patterns
633 -X --exclude PATTERN [+] exclude names matching the given patterns
630 -S --subrepos recurse into subrepositories
634 -S --subrepos recurse into subrepositories
631
635
632 (some details hidden, use --verbose to show complete help)
636 (some details hidden, use --verbose to show complete help)
633
637
634
638
635
639
636
640
637
641
638
642
639
643
640
644
641
645
642
646
643 $ hg help --extension extdiff
647 $ hg help --extension extdiff
644 extdiff extension - command to allow external programs to compare revisions
648 extdiff extension - command to allow external programs to compare revisions
645
649
646 The extdiff Mercurial extension allows you to use external programs to compare
650 The extdiff Mercurial extension allows you to use external programs to compare
647 revisions, or revision with working directory. The external diff programs are
651 revisions, or revision with working directory. The external diff programs are
648 called with a configurable set of options and two non-option arguments: paths
652 called with a configurable set of options and two non-option arguments: paths
649 to directories containing snapshots of files to compare.
653 to directories containing snapshots of files to compare.
650
654
651 The extdiff extension also allows you to configure new diff commands, so you
655 The extdiff extension also allows you to configure new diff commands, so you
652 do not need to type 'hg extdiff -p kdiff3' always.
656 do not need to type 'hg extdiff -p kdiff3' always.
653
657
654 [extdiff]
658 [extdiff]
655 # add new command that runs GNU diff(1) in 'context diff' mode
659 # add new command that runs GNU diff(1) in 'context diff' mode
656 cdiff = gdiff -Nprc5
660 cdiff = gdiff -Nprc5
657 ## or the old way:
661 ## or the old way:
658 #cmd.cdiff = gdiff
662 #cmd.cdiff = gdiff
659 #opts.cdiff = -Nprc5
663 #opts.cdiff = -Nprc5
660
664
661 # add new command called meld, runs meld (no need to name twice). If
665 # add new command called meld, runs meld (no need to name twice). If
662 # the meld executable is not available, the meld tool in [merge-tools]
666 # the meld executable is not available, the meld tool in [merge-tools]
663 # will be used, if available
667 # will be used, if available
664 meld =
668 meld =
665
669
666 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
670 # add new command called vimdiff, runs gvimdiff with DirDiff plugin
667 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
671 # (see http://www.vim.org/scripts/script.php?script_id=102) Non
668 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
672 # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
669 # your .vimrc
673 # your .vimrc
670 vimdiff = gvim -f "+next" \
674 vimdiff = gvim -f "+next" \
671 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
675 "+execute 'DirDiff' fnameescape(argv(0)) fnameescape(argv(1))"
672
676
673 Tool arguments can include variables that are expanded at runtime:
677 Tool arguments can include variables that are expanded at runtime:
674
678
675 $parent1, $plabel1 - filename, descriptive label of first parent
679 $parent1, $plabel1 - filename, descriptive label of first parent
676 $child, $clabel - filename, descriptive label of child revision
680 $child, $clabel - filename, descriptive label of child revision
677 $parent2, $plabel2 - filename, descriptive label of second parent
681 $parent2, $plabel2 - filename, descriptive label of second parent
678 $root - repository root
682 $root - repository root
679 $parent is an alias for $parent1.
683 $parent is an alias for $parent1.
680
684
681 The extdiff extension will look in your [diff-tools] and [merge-tools]
685 The extdiff extension will look in your [diff-tools] and [merge-tools]
682 sections for diff tool arguments, when none are specified in [extdiff].
686 sections for diff tool arguments, when none are specified in [extdiff].
683
687
684 [extdiff]
688 [extdiff]
685 kdiff3 =
689 kdiff3 =
686
690
687 [diff-tools]
691 [diff-tools]
688 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
692 kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
689
693
690 You can use -I/-X and list of file or directory names like normal 'hg diff'
694 You can use -I/-X and list of file or directory names like normal 'hg diff'
691 command. The extdiff extension makes snapshots of only needed files, so
695 command. The extdiff extension makes snapshots of only needed files, so
692 running the external diff program will actually be pretty fast (at least
696 running the external diff program will actually be pretty fast (at least
693 faster than having to compare the entire tree).
697 faster than having to compare the entire tree).
694
698
695 list of commands:
699 list of commands:
696
700
697 extdiff use external program to diff repository (or selected files)
701 extdiff use external program to diff repository (or selected files)
698
702
699 (use 'hg help -v -e extdiff' to show built-in aliases and global options)
703 (use 'hg help -v -e extdiff' to show built-in aliases and global options)
700
704
701
705
702
706
703
707
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 $ echo 'extdiff = !' >> $HGRCPATH
720 $ echo 'extdiff = !' >> $HGRCPATH
717
721
718 Test help topic with same name as extension
722 Test help topic with same name as extension
719
723
720 $ cat > multirevs.py <<EOF
724 $ cat > multirevs.py <<EOF
721 > from mercurial import cmdutil, commands
725 > from mercurial import cmdutil, commands
722 > cmdtable = {}
726 > cmdtable = {}
723 > command = cmdutil.command(cmdtable)
727 > command = cmdutil.command(cmdtable)
724 > """multirevs extension
728 > """multirevs extension
725 > Big multi-line module docstring."""
729 > Big multi-line module docstring."""
726 > @command('multirevs', [], 'ARG', norepo=True)
730 > @command('multirevs', [], 'ARG', norepo=True)
727 > def multirevs(ui, repo, arg, *args, **opts):
731 > def multirevs(ui, repo, arg, *args, **opts):
728 > """multirevs command"""
732 > """multirevs command"""
729 > pass
733 > pass
730 > EOF
734 > EOF
731 $ echo "multirevs = multirevs.py" >> $HGRCPATH
735 $ echo "multirevs = multirevs.py" >> $HGRCPATH
732
736
733 $ hg help multirevs | tail
737 $ hg help multirevs | tail
734 bookmark (this works because the last revision of the revset is used):
738 bookmark (this works because the last revision of the revset is used):
735
739
736 hg update :@
740 hg update :@
737
741
738 - Show diff between tags 1.3 and 1.5 (this works because the first and the
742 - Show diff between tags 1.3 and 1.5 (this works because the first and the
739 last revisions of the revset are used):
743 last revisions of the revset are used):
740
744
741 hg diff -r 1.3::1.5
745 hg diff -r 1.3::1.5
742
746
743 use 'hg help -c multirevs' to see help for the multirevs command
747 use 'hg help -c multirevs' to see help for the multirevs command
744
748
745
749
746
750
747
751
748
752
749
753
750 $ hg help -c multirevs
754 $ hg help -c multirevs
751 hg multirevs ARG
755 hg multirevs ARG
752
756
753 multirevs command
757 multirevs command
754
758
755 (some details hidden, use --verbose to show complete help)
759 (some details hidden, use --verbose to show complete help)
756
760
757
761
758
762
759 $ hg multirevs
763 $ hg multirevs
760 hg multirevs: invalid arguments
764 hg multirevs: invalid arguments
761 hg multirevs ARG
765 hg multirevs ARG
762
766
763 multirevs command
767 multirevs command
764
768
765 (use 'hg multirevs -h' to show more help)
769 (use 'hg multirevs -h' to show more help)
766 [255]
770 [255]
767
771
768
772
769
773
770 $ echo "multirevs = !" >> $HGRCPATH
774 $ echo "multirevs = !" >> $HGRCPATH
771
775
772 Issue811: Problem loading extensions twice (by site and by user)
776 Issue811: Problem loading extensions twice (by site and by user)
773
777
774 $ cat <<EOF >> $HGRCPATH
778 $ cat <<EOF >> $HGRCPATH
775 > mq =
779 > mq =
776 > strip =
780 > strip =
777 > hgext.mq =
781 > hgext.mq =
778 > hgext/mq =
782 > hgext/mq =
779 > EOF
783 > EOF
780
784
781 Show extensions:
785 Show extensions:
782 (note that mq force load strip, also checking it's not loaded twice)
786 (note that mq force load strip, also checking it's not loaded twice)
783
787
784 $ hg debugextensions
788 $ hg debugextensions
785 mq
789 mq
786 strip
790 strip
787
791
788 For extensions, which name matches one of its commands, help
792 For extensions, which name matches one of its commands, help
789 message should ask '-v -e' to get list of built-in aliases
793 message should ask '-v -e' to get list of built-in aliases
790 along with extension help itself
794 along with extension help itself
791
795
792 $ mkdir $TESTTMP/d
796 $ mkdir $TESTTMP/d
793 $ cat > $TESTTMP/d/dodo.py <<EOF
797 $ cat > $TESTTMP/d/dodo.py <<EOF
794 > """
798 > """
795 > This is an awesome 'dodo' extension. It does nothing and
799 > This is an awesome 'dodo' extension. It does nothing and
796 > writes 'Foo foo'
800 > writes 'Foo foo'
797 > """
801 > """
798 > from mercurial import cmdutil, commands
802 > from mercurial import cmdutil, commands
799 > cmdtable = {}
803 > cmdtable = {}
800 > command = cmdutil.command(cmdtable)
804 > command = cmdutil.command(cmdtable)
801 > @command('dodo', [], 'hg dodo')
805 > @command('dodo', [], 'hg dodo')
802 > def dodo(ui, *args, **kwargs):
806 > def dodo(ui, *args, **kwargs):
803 > """Does nothing"""
807 > """Does nothing"""
804 > ui.write("I do nothing. Yay\\n")
808 > ui.write("I do nothing. Yay\\n")
805 > @command('foofoo', [], 'hg foofoo')
809 > @command('foofoo', [], 'hg foofoo')
806 > def foofoo(ui, *args, **kwargs):
810 > def foofoo(ui, *args, **kwargs):
807 > """Writes 'Foo foo'"""
811 > """Writes 'Foo foo'"""
808 > ui.write("Foo foo\\n")
812 > ui.write("Foo foo\\n")
809 > EOF
813 > EOF
810 $ dodopath=$TESTTMP/d/dodo.py
814 $ dodopath=$TESTTMP/d/dodo.py
811
815
812 $ echo "dodo = $dodopath" >> $HGRCPATH
816 $ echo "dodo = $dodopath" >> $HGRCPATH
813
817
814 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
818 Make sure that user is asked to enter '-v -e' to get list of built-in aliases
815 $ hg help -e dodo
819 $ hg help -e dodo
816 dodo extension -
820 dodo extension -
817
821
818 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
822 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
819
823
820 list of commands:
824 list of commands:
821
825
822 dodo Does nothing
826 dodo Does nothing
823 foofoo Writes 'Foo foo'
827 foofoo Writes 'Foo foo'
824
828
825 (use 'hg help -v -e dodo' to show built-in aliases and global options)
829 (use 'hg help -v -e dodo' to show built-in aliases and global options)
826
830
827 Make sure that '-v -e' prints list of built-in aliases along with
831 Make sure that '-v -e' prints list of built-in aliases along with
828 extension help itself
832 extension help itself
829 $ hg help -v -e dodo
833 $ hg help -v -e dodo
830 dodo extension -
834 dodo extension -
831
835
832 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
836 This is an awesome 'dodo' extension. It does nothing and writes 'Foo foo'
833
837
834 list of commands:
838 list of commands:
835
839
836 dodo Does nothing
840 dodo Does nothing
837 foofoo Writes 'Foo foo'
841 foofoo Writes 'Foo foo'
838
842
839 global options ([+] can be repeated):
843 global options ([+] can be repeated):
840
844
841 -R --repository REPO repository root directory or name of overlay bundle
845 -R --repository REPO repository root directory or name of overlay bundle
842 file
846 file
843 --cwd DIR change working directory
847 --cwd DIR change working directory
844 -y --noninteractive do not prompt, automatically pick the first choice for
848 -y --noninteractive do not prompt, automatically pick the first choice for
845 all prompts
849 all prompts
846 -q --quiet suppress output
850 -q --quiet suppress output
847 -v --verbose enable additional output
851 -v --verbose enable additional output
848 --config CONFIG [+] set/override config option (use 'section.name=value')
852 --config CONFIG [+] set/override config option (use 'section.name=value')
849 --debug enable debugging output
853 --debug enable debugging output
850 --debugger start debugger
854 --debugger start debugger
851 --encoding ENCODE set the charset encoding (default: ascii)
855 --encoding ENCODE set the charset encoding (default: ascii)
852 --encodingmode MODE set the charset encoding mode (default: strict)
856 --encodingmode MODE set the charset encoding mode (default: strict)
853 --traceback always print a traceback on exception
857 --traceback always print a traceback on exception
854 --time time how long the command takes
858 --time time how long the command takes
855 --profile print command execution profile
859 --profile print command execution profile
856 --version output version information and exit
860 --version output version information and exit
857 -h --help display help and exit
861 -h --help display help and exit
858 --hidden consider hidden changesets
862 --hidden consider hidden changesets
863 --pager TYPE when to paginate (boolean, always, auto, or never)
864 (default: auto)
859
865
860 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
866 Make sure that single '-v' option shows help and built-ins only for 'dodo' command
861 $ hg help -v dodo
867 $ hg help -v dodo
862 hg dodo
868 hg dodo
863
869
864 Does nothing
870 Does nothing
865
871
866 (use 'hg help -e dodo' to show help for the dodo extension)
872 (use 'hg help -e dodo' to show help for the dodo extension)
867
873
868 options:
874 options:
869
875
870 --mq operate on patch repository
876 --mq operate on patch repository
871
877
872 global options ([+] can be repeated):
878 global options ([+] can be repeated):
873
879
874 -R --repository REPO repository root directory or name of overlay bundle
880 -R --repository REPO repository root directory or name of overlay bundle
875 file
881 file
876 --cwd DIR change working directory
882 --cwd DIR change working directory
877 -y --noninteractive do not prompt, automatically pick the first choice for
883 -y --noninteractive do not prompt, automatically pick the first choice for
878 all prompts
884 all prompts
879 -q --quiet suppress output
885 -q --quiet suppress output
880 -v --verbose enable additional output
886 -v --verbose enable additional output
881 --config CONFIG [+] set/override config option (use 'section.name=value')
887 --config CONFIG [+] set/override config option (use 'section.name=value')
882 --debug enable debugging output
888 --debug enable debugging output
883 --debugger start debugger
889 --debugger start debugger
884 --encoding ENCODE set the charset encoding (default: ascii)
890 --encoding ENCODE set the charset encoding (default: ascii)
885 --encodingmode MODE set the charset encoding mode (default: strict)
891 --encodingmode MODE set the charset encoding mode (default: strict)
886 --traceback always print a traceback on exception
892 --traceback always print a traceback on exception
887 --time time how long the command takes
893 --time time how long the command takes
888 --profile print command execution profile
894 --profile print command execution profile
889 --version output version information and exit
895 --version output version information and exit
890 -h --help display help and exit
896 -h --help display help and exit
891 --hidden consider hidden changesets
897 --hidden consider hidden changesets
898 --pager TYPE when to paginate (boolean, always, auto, or never)
899 (default: auto)
892
900
893 In case when extension name doesn't match any of its commands,
901 In case when extension name doesn't match any of its commands,
894 help message should ask for '-v' to get list of built-in aliases
902 help message should ask for '-v' to get list of built-in aliases
895 along with extension help
903 along with extension help
896 $ cat > $TESTTMP/d/dudu.py <<EOF
904 $ cat > $TESTTMP/d/dudu.py <<EOF
897 > """
905 > """
898 > This is an awesome 'dudu' extension. It does something and
906 > This is an awesome 'dudu' extension. It does something and
899 > also writes 'Beep beep'
907 > also writes 'Beep beep'
900 > """
908 > """
901 > from mercurial import cmdutil, commands
909 > from mercurial import cmdutil, commands
902 > cmdtable = {}
910 > cmdtable = {}
903 > command = cmdutil.command(cmdtable)
911 > command = cmdutil.command(cmdtable)
904 > @command('something', [], 'hg something')
912 > @command('something', [], 'hg something')
905 > def something(ui, *args, **kwargs):
913 > def something(ui, *args, **kwargs):
906 > """Does something"""
914 > """Does something"""
907 > ui.write("I do something. Yaaay\\n")
915 > ui.write("I do something. Yaaay\\n")
908 > @command('beep', [], 'hg beep')
916 > @command('beep', [], 'hg beep')
909 > def beep(ui, *args, **kwargs):
917 > def beep(ui, *args, **kwargs):
910 > """Writes 'Beep beep'"""
918 > """Writes 'Beep beep'"""
911 > ui.write("Beep beep\\n")
919 > ui.write("Beep beep\\n")
912 > EOF
920 > EOF
913 $ dudupath=$TESTTMP/d/dudu.py
921 $ dudupath=$TESTTMP/d/dudu.py
914
922
915 $ echo "dudu = $dudupath" >> $HGRCPATH
923 $ echo "dudu = $dudupath" >> $HGRCPATH
916
924
917 $ hg help -e dudu
925 $ hg help -e dudu
918 dudu extension -
926 dudu extension -
919
927
920 This is an awesome 'dudu' extension. It does something and also writes 'Beep
928 This is an awesome 'dudu' extension. It does something and also writes 'Beep
921 beep'
929 beep'
922
930
923 list of commands:
931 list of commands:
924
932
925 beep Writes 'Beep beep'
933 beep Writes 'Beep beep'
926 something Does something
934 something Does something
927
935
928 (use 'hg help -v dudu' to show built-in aliases and global options)
936 (use 'hg help -v dudu' to show built-in aliases and global options)
929
937
930 In case when extension name doesn't match any of its commands,
938 In case when extension name doesn't match any of its commands,
931 help options '-v' and '-v -e' should be equivalent
939 help options '-v' and '-v -e' should be equivalent
932 $ hg help -v dudu
940 $ hg help -v dudu
933 dudu extension -
941 dudu extension -
934
942
935 This is an awesome 'dudu' extension. It does something and also writes 'Beep
943 This is an awesome 'dudu' extension. It does something and also writes 'Beep
936 beep'
944 beep'
937
945
938 list of commands:
946 list of commands:
939
947
940 beep Writes 'Beep beep'
948 beep Writes 'Beep beep'
941 something Does something
949 something Does something
942
950
943 global options ([+] can be repeated):
951 global options ([+] can be repeated):
944
952
945 -R --repository REPO repository root directory or name of overlay bundle
953 -R --repository REPO repository root directory or name of overlay bundle
946 file
954 file
947 --cwd DIR change working directory
955 --cwd DIR change working directory
948 -y --noninteractive do not prompt, automatically pick the first choice for
956 -y --noninteractive do not prompt, automatically pick the first choice for
949 all prompts
957 all prompts
950 -q --quiet suppress output
958 -q --quiet suppress output
951 -v --verbose enable additional output
959 -v --verbose enable additional output
952 --config CONFIG [+] set/override config option (use 'section.name=value')
960 --config CONFIG [+] set/override config option (use 'section.name=value')
953 --debug enable debugging output
961 --debug enable debugging output
954 --debugger start debugger
962 --debugger start debugger
955 --encoding ENCODE set the charset encoding (default: ascii)
963 --encoding ENCODE set the charset encoding (default: ascii)
956 --encodingmode MODE set the charset encoding mode (default: strict)
964 --encodingmode MODE set the charset encoding mode (default: strict)
957 --traceback always print a traceback on exception
965 --traceback always print a traceback on exception
958 --time time how long the command takes
966 --time time how long the command takes
959 --profile print command execution profile
967 --profile print command execution profile
960 --version output version information and exit
968 --version output version information and exit
961 -h --help display help and exit
969 -h --help display help and exit
962 --hidden consider hidden changesets
970 --hidden consider hidden changesets
971 --pager TYPE when to paginate (boolean, always, auto, or never)
972 (default: auto)
963
973
964 $ hg help -v -e dudu
974 $ hg help -v -e dudu
965 dudu extension -
975 dudu extension -
966
976
967 This is an awesome 'dudu' extension. It does something and also writes 'Beep
977 This is an awesome 'dudu' extension. It does something and also writes 'Beep
968 beep'
978 beep'
969
979
970 list of commands:
980 list of commands:
971
981
972 beep Writes 'Beep beep'
982 beep Writes 'Beep beep'
973 something Does something
983 something Does something
974
984
975 global options ([+] can be repeated):
985 global options ([+] can be repeated):
976
986
977 -R --repository REPO repository root directory or name of overlay bundle
987 -R --repository REPO repository root directory or name of overlay bundle
978 file
988 file
979 --cwd DIR change working directory
989 --cwd DIR change working directory
980 -y --noninteractive do not prompt, automatically pick the first choice for
990 -y --noninteractive do not prompt, automatically pick the first choice for
981 all prompts
991 all prompts
982 -q --quiet suppress output
992 -q --quiet suppress output
983 -v --verbose enable additional output
993 -v --verbose enable additional output
984 --config CONFIG [+] set/override config option (use 'section.name=value')
994 --config CONFIG [+] set/override config option (use 'section.name=value')
985 --debug enable debugging output
995 --debug enable debugging output
986 --debugger start debugger
996 --debugger start debugger
987 --encoding ENCODE set the charset encoding (default: ascii)
997 --encoding ENCODE set the charset encoding (default: ascii)
988 --encodingmode MODE set the charset encoding mode (default: strict)
998 --encodingmode MODE set the charset encoding mode (default: strict)
989 --traceback always print a traceback on exception
999 --traceback always print a traceback on exception
990 --time time how long the command takes
1000 --time time how long the command takes
991 --profile print command execution profile
1001 --profile print command execution profile
992 --version output version information and exit
1002 --version output version information and exit
993 -h --help display help and exit
1003 -h --help display help and exit
994 --hidden consider hidden changesets
1004 --hidden consider hidden changesets
1005 --pager TYPE when to paginate (boolean, always, auto, or never)
1006 (default: auto)
995
1007
996 Disabled extension commands:
1008 Disabled extension commands:
997
1009
998 $ ORGHGRCPATH=$HGRCPATH
1010 $ ORGHGRCPATH=$HGRCPATH
999 $ HGRCPATH=
1011 $ HGRCPATH=
1000 $ export HGRCPATH
1012 $ export HGRCPATH
1001 $ hg help email
1013 $ hg help email
1002 'email' is provided by the following extension:
1014 'email' is provided by the following extension:
1003
1015
1004 patchbomb command to send changesets as (a series of) patch emails
1016 patchbomb command to send changesets as (a series of) patch emails
1005
1017
1006 (use 'hg help extensions' for information on enabling extensions)
1018 (use 'hg help extensions' for information on enabling extensions)
1007
1019
1008
1020
1009 $ hg qdel
1021 $ hg qdel
1010 hg: unknown command 'qdel'
1022 hg: unknown command 'qdel'
1011 'qdelete' is provided by the following extension:
1023 'qdelete' is provided by the following extension:
1012
1024
1013 mq manage a stack of patches
1025 mq manage a stack of patches
1014
1026
1015 (use 'hg help extensions' for information on enabling extensions)
1027 (use 'hg help extensions' for information on enabling extensions)
1016 [255]
1028 [255]
1017
1029
1018
1030
1019 $ hg churn
1031 $ hg churn
1020 hg: unknown command 'churn'
1032 hg: unknown command 'churn'
1021 'churn' is provided by the following extension:
1033 'churn' is provided by the following extension:
1022
1034
1023 churn command to display statistics about repository history
1035 churn command to display statistics about repository history
1024
1036
1025 (use 'hg help extensions' for information on enabling extensions)
1037 (use 'hg help extensions' for information on enabling extensions)
1026 [255]
1038 [255]
1027
1039
1028
1040
1029
1041
1030 Disabled extensions:
1042 Disabled extensions:
1031
1043
1032 $ hg help churn
1044 $ hg help churn
1033 churn extension - command to display statistics about repository history
1045 churn extension - command to display statistics about repository history
1034
1046
1035 (use 'hg help extensions' for information on enabling extensions)
1047 (use 'hg help extensions' for information on enabling extensions)
1036
1048
1037 $ hg help patchbomb
1049 $ hg help patchbomb
1038 patchbomb extension - command to send changesets as (a series of) patch emails
1050 patchbomb extension - command to send changesets as (a series of) patch emails
1039
1051
1040 The series is started off with a "[PATCH 0 of N]" introduction, which
1052 The series is started off with a "[PATCH 0 of N]" introduction, which
1041 describes the series as a whole.
1053 describes the series as a whole.
1042
1054
1043 Each patch email has a Subject line of "[PATCH M of N] ...", using the first
1055 Each patch email has a Subject line of "[PATCH M of N] ...", using the first
1044 line of the changeset description as the subject text. The message contains
1056 line of the changeset description as the subject text. The message contains
1045 two or three body parts:
1057 two or three body parts:
1046
1058
1047 - The changeset description.
1059 - The changeset description.
1048 - [Optional] The result of running diffstat on the patch.
1060 - [Optional] The result of running diffstat on the patch.
1049 - The patch itself, as generated by 'hg export'.
1061 - The patch itself, as generated by 'hg export'.
1050
1062
1051 Each message refers to the first in the series using the In-Reply-To and
1063 Each message refers to the first in the series using the In-Reply-To and
1052 References headers, so they will show up as a sequence in threaded mail and
1064 References headers, so they will show up as a sequence in threaded mail and
1053 news readers, and in mail archives.
1065 news readers, and in mail archives.
1054
1066
1055 To configure other defaults, add a section like this to your configuration
1067 To configure other defaults, add a section like this to your configuration
1056 file:
1068 file:
1057
1069
1058 [email]
1070 [email]
1059 from = My Name <my@email>
1071 from = My Name <my@email>
1060 to = recipient1, recipient2, ...
1072 to = recipient1, recipient2, ...
1061 cc = cc1, cc2, ...
1073 cc = cc1, cc2, ...
1062 bcc = bcc1, bcc2, ...
1074 bcc = bcc1, bcc2, ...
1063 reply-to = address1, address2, ...
1075 reply-to = address1, address2, ...
1064
1076
1065 Use "[patchbomb]" as configuration section name if you need to override global
1077 Use "[patchbomb]" as configuration section name if you need to override global
1066 "[email]" address settings.
1078 "[email]" address settings.
1067
1079
1068 Then you can use the 'hg email' command to mail a series of changesets as a
1080 Then you can use the 'hg email' command to mail a series of changesets as a
1069 patchbomb.
1081 patchbomb.
1070
1082
1071 You can also either configure the method option in the email section to be a
1083 You can also either configure the method option in the email section to be a
1072 sendmail compatible mailer or fill out the [smtp] section so that the
1084 sendmail compatible mailer or fill out the [smtp] section so that the
1073 patchbomb extension can automatically send patchbombs directly from the
1085 patchbomb extension can automatically send patchbombs directly from the
1074 commandline. See the [email] and [smtp] sections in hgrc(5) for details.
1086 commandline. See the [email] and [smtp] sections in hgrc(5) for details.
1075
1087
1076 By default, 'hg email' will prompt for a "To" or "CC" header if you do not
1088 By default, 'hg email' will prompt for a "To" or "CC" header if you do not
1077 supply one via configuration or the command line. You can override this to
1089 supply one via configuration or the command line. You can override this to
1078 never prompt by configuring an empty value:
1090 never prompt by configuring an empty value:
1079
1091
1080 [email]
1092 [email]
1081 cc =
1093 cc =
1082
1094
1083 You can control the default inclusion of an introduction message with the
1095 You can control the default inclusion of an introduction message with the
1084 "patchbomb.intro" configuration option. The configuration is always
1096 "patchbomb.intro" configuration option. The configuration is always
1085 overwritten by command line flags like --intro and --desc:
1097 overwritten by command line flags like --intro and --desc:
1086
1098
1087 [patchbomb]
1099 [patchbomb]
1088 intro=auto # include introduction message if more than 1 patch (default)
1100 intro=auto # include introduction message if more than 1 patch (default)
1089 intro=never # never include an introduction message
1101 intro=never # never include an introduction message
1090 intro=always # always include an introduction message
1102 intro=always # always include an introduction message
1091
1103
1092 You can set patchbomb to always ask for confirmation by setting
1104 You can set patchbomb to always ask for confirmation by setting
1093 "patchbomb.confirm" to true.
1105 "patchbomb.confirm" to true.
1094
1106
1095 (use 'hg help extensions' for information on enabling extensions)
1107 (use 'hg help extensions' for information on enabling extensions)
1096
1108
1097
1109
1098 Broken disabled extension and command:
1110 Broken disabled extension and command:
1099
1111
1100 $ mkdir hgext
1112 $ mkdir hgext
1101 $ echo > hgext/__init__.py
1113 $ echo > hgext/__init__.py
1102 $ cat > hgext/broken.py <<EOF
1114 $ cat > hgext/broken.py <<EOF
1103 > "broken extension'
1115 > "broken extension'
1104 > EOF
1116 > EOF
1105 $ cat > path.py <<EOF
1117 $ cat > path.py <<EOF
1106 > import os, sys
1118 > import os, sys
1107 > sys.path.insert(0, os.environ['HGEXTPATH'])
1119 > sys.path.insert(0, os.environ['HGEXTPATH'])
1108 > EOF
1120 > EOF
1109 $ HGEXTPATH=`pwd`
1121 $ HGEXTPATH=`pwd`
1110 $ export HGEXTPATH
1122 $ export HGEXTPATH
1111
1123
1112 $ hg --config extensions.path=./path.py help broken
1124 $ hg --config extensions.path=./path.py help broken
1113 broken extension - (no help text available)
1125 broken extension - (no help text available)
1114
1126
1115 (use 'hg help extensions' for information on enabling extensions)
1127 (use 'hg help extensions' for information on enabling extensions)
1116
1128
1117
1129
1118 $ cat > hgext/forest.py <<EOF
1130 $ cat > hgext/forest.py <<EOF
1119 > cmdtable = None
1131 > cmdtable = None
1120 > EOF
1132 > EOF
1121 $ hg --config extensions.path=./path.py help foo > /dev/null
1133 $ hg --config extensions.path=./path.py help foo > /dev/null
1122 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
1134 warning: error finding commands in $TESTTMP/hgext/forest.py (glob)
1123 abort: no such help topic: foo
1135 abort: no such help topic: foo
1124 (try 'hg help --keyword foo')
1136 (try 'hg help --keyword foo')
1125 [255]
1137 [255]
1126
1138
1127 $ cat > throw.py <<EOF
1139 $ cat > throw.py <<EOF
1128 > from mercurial import cmdutil, commands, util
1140 > from mercurial import cmdutil, commands, util
1129 > cmdtable = {}
1141 > cmdtable = {}
1130 > command = cmdutil.command(cmdtable)
1142 > command = cmdutil.command(cmdtable)
1131 > class Bogon(Exception): pass
1143 > class Bogon(Exception): pass
1132 > @command('throw', [], 'hg throw', norepo=True)
1144 > @command('throw', [], 'hg throw', norepo=True)
1133 > def throw(ui, **opts):
1145 > def throw(ui, **opts):
1134 > """throws an exception"""
1146 > """throws an exception"""
1135 > raise Bogon()
1147 > raise Bogon()
1136 > EOF
1148 > EOF
1137
1149
1138 No declared supported version, extension complains:
1150 No declared supported version, extension complains:
1139 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1151 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1140 ** Unknown exception encountered with possibly-broken third-party extension throw
1152 ** Unknown exception encountered with possibly-broken third-party extension throw
1141 ** which supports versions unknown of Mercurial.
1153 ** which supports versions unknown of Mercurial.
1142 ** Please disable throw and try your action again.
1154 ** Please disable throw and try your action again.
1143 ** If that fixes the bug please report it to the extension author.
1155 ** If that fixes the bug please report it to the extension author.
1144 ** Python * (glob)
1156 ** Python * (glob)
1145 ** Mercurial Distributed SCM * (glob)
1157 ** Mercurial Distributed SCM * (glob)
1146 ** Extensions loaded: throw
1158 ** Extensions loaded: throw
1147
1159
1148 empty declaration of supported version, extension complains:
1160 empty declaration of supported version, extension complains:
1149 $ echo "testedwith = ''" >> throw.py
1161 $ echo "testedwith = ''" >> throw.py
1150 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1162 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1151 ** Unknown exception encountered with possibly-broken third-party extension throw
1163 ** Unknown exception encountered with possibly-broken third-party extension throw
1152 ** which supports versions unknown of Mercurial.
1164 ** which supports versions unknown of Mercurial.
1153 ** Please disable throw and try your action again.
1165 ** Please disable throw and try your action again.
1154 ** If that fixes the bug please report it to the extension author.
1166 ** If that fixes the bug please report it to the extension author.
1155 ** Python * (glob)
1167 ** Python * (glob)
1156 ** Mercurial Distributed SCM (*) (glob)
1168 ** Mercurial Distributed SCM (*) (glob)
1157 ** Extensions loaded: throw
1169 ** Extensions loaded: throw
1158
1170
1159 If the extension specifies a buglink, show that:
1171 If the extension specifies a buglink, show that:
1160 $ echo 'buglink = "http://example.com/bts"' >> throw.py
1172 $ echo 'buglink = "http://example.com/bts"' >> throw.py
1161 $ rm -f throw.pyc throw.pyo
1173 $ rm -f throw.pyc throw.pyo
1162 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1174 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1163 ** Unknown exception encountered with possibly-broken third-party extension throw
1175 ** Unknown exception encountered with possibly-broken third-party extension throw
1164 ** which supports versions unknown of Mercurial.
1176 ** which supports versions unknown of Mercurial.
1165 ** Please disable throw and try your action again.
1177 ** Please disable throw and try your action again.
1166 ** If that fixes the bug please report it to http://example.com/bts
1178 ** If that fixes the bug please report it to http://example.com/bts
1167 ** Python * (glob)
1179 ** Python * (glob)
1168 ** Mercurial Distributed SCM (*) (glob)
1180 ** Mercurial Distributed SCM (*) (glob)
1169 ** Extensions loaded: throw
1181 ** Extensions loaded: throw
1170
1182
1171 If the extensions declare outdated versions, accuse the older extension first:
1183 If the extensions declare outdated versions, accuse the older extension first:
1172 $ echo "from mercurial import util" >> older.py
1184 $ echo "from mercurial import util" >> older.py
1173 $ echo "util.version = lambda:'2.2'" >> older.py
1185 $ echo "util.version = lambda:'2.2'" >> older.py
1174 $ echo "testedwith = '1.9.3'" >> older.py
1186 $ echo "testedwith = '1.9.3'" >> older.py
1175 $ echo "testedwith = '2.1.1'" >> throw.py
1187 $ echo "testedwith = '2.1.1'" >> throw.py
1176 $ rm -f throw.pyc throw.pyo
1188 $ rm -f throw.pyc throw.pyo
1177 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1189 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1178 > throw 2>&1 | egrep '^\*\*'
1190 > throw 2>&1 | egrep '^\*\*'
1179 ** Unknown exception encountered with possibly-broken third-party extension older
1191 ** Unknown exception encountered with possibly-broken third-party extension older
1180 ** which supports versions 1.9 of Mercurial.
1192 ** which supports versions 1.9 of Mercurial.
1181 ** Please disable older and try your action again.
1193 ** Please disable older and try your action again.
1182 ** If that fixes the bug please report it to the extension author.
1194 ** If that fixes the bug please report it to the extension author.
1183 ** Python * (glob)
1195 ** Python * (glob)
1184 ** Mercurial Distributed SCM (version 2.2)
1196 ** Mercurial Distributed SCM (version 2.2)
1185 ** Extensions loaded: throw, older
1197 ** Extensions loaded: throw, older
1186
1198
1187 One extension only tested with older, one only with newer versions:
1199 One extension only tested with older, one only with newer versions:
1188 $ echo "util.version = lambda:'2.1'" >> older.py
1200 $ echo "util.version = lambda:'2.1'" >> older.py
1189 $ rm -f older.pyc older.pyo
1201 $ rm -f older.pyc older.pyo
1190 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1202 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1191 > throw 2>&1 | egrep '^\*\*'
1203 > throw 2>&1 | egrep '^\*\*'
1192 ** Unknown exception encountered with possibly-broken third-party extension older
1204 ** Unknown exception encountered with possibly-broken third-party extension older
1193 ** which supports versions 1.9 of Mercurial.
1205 ** which supports versions 1.9 of Mercurial.
1194 ** Please disable older and try your action again.
1206 ** Please disable older and try your action again.
1195 ** If that fixes the bug please report it to the extension author.
1207 ** If that fixes the bug please report it to the extension author.
1196 ** Python * (glob)
1208 ** Python * (glob)
1197 ** Mercurial Distributed SCM (version 2.1)
1209 ** Mercurial Distributed SCM (version 2.1)
1198 ** Extensions loaded: throw, older
1210 ** Extensions loaded: throw, older
1199
1211
1200 Older extension is tested with current version, the other only with newer:
1212 Older extension is tested with current version, the other only with newer:
1201 $ echo "util.version = lambda:'1.9.3'" >> older.py
1213 $ echo "util.version = lambda:'1.9.3'" >> older.py
1202 $ rm -f older.pyc older.pyo
1214 $ rm -f older.pyc older.pyo
1203 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1215 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1204 > throw 2>&1 | egrep '^\*\*'
1216 > throw 2>&1 | egrep '^\*\*'
1205 ** Unknown exception encountered with possibly-broken third-party extension throw
1217 ** Unknown exception encountered with possibly-broken third-party extension throw
1206 ** which supports versions 2.1 of Mercurial.
1218 ** which supports versions 2.1 of Mercurial.
1207 ** Please disable throw and try your action again.
1219 ** Please disable throw and try your action again.
1208 ** If that fixes the bug please report it to http://example.com/bts
1220 ** If that fixes the bug please report it to http://example.com/bts
1209 ** Python * (glob)
1221 ** Python * (glob)
1210 ** Mercurial Distributed SCM (version 1.9.3)
1222 ** Mercurial Distributed SCM (version 1.9.3)
1211 ** Extensions loaded: throw, older
1223 ** Extensions loaded: throw, older
1212
1224
1213 Ability to point to a different point
1225 Ability to point to a different point
1214 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1226 $ hg --config extensions.throw=throw.py --config extensions.older=older.py \
1215 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
1227 > --config ui.supportcontact='Your Local Goat Lenders' throw 2>&1 | egrep '^\*\*'
1216 ** unknown exception encountered, please report by visiting
1228 ** unknown exception encountered, please report by visiting
1217 ** Your Local Goat Lenders
1229 ** Your Local Goat Lenders
1218 ** Python * (glob)
1230 ** Python * (glob)
1219 ** Mercurial Distributed SCM (*) (glob)
1231 ** Mercurial Distributed SCM (*) (glob)
1220 ** Extensions loaded: throw, older
1232 ** Extensions loaded: throw, older
1221
1233
1222 Declare the version as supporting this hg version, show regular bts link:
1234 Declare the version as supporting this hg version, show regular bts link:
1223 $ hgver=`hg debuginstall -T '{hgver}'`
1235 $ hgver=`hg debuginstall -T '{hgver}'`
1224 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
1236 $ echo 'testedwith = """'"$hgver"'"""' >> throw.py
1225 $ if [ -z "$hgver" ]; then
1237 $ if [ -z "$hgver" ]; then
1226 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
1238 > echo "unable to fetch a mercurial version. Make sure __version__ is correct";
1227 > fi
1239 > fi
1228 $ rm -f throw.pyc throw.pyo
1240 $ rm -f throw.pyc throw.pyo
1229 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1241 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1230 ** unknown exception encountered, please report by visiting
1242 ** unknown exception encountered, please report by visiting
1231 ** https://mercurial-scm.org/wiki/BugTracker
1243 ** https://mercurial-scm.org/wiki/BugTracker
1232 ** Python * (glob)
1244 ** Python * (glob)
1233 ** Mercurial Distributed SCM (*) (glob)
1245 ** Mercurial Distributed SCM (*) (glob)
1234 ** Extensions loaded: throw
1246 ** Extensions loaded: throw
1235
1247
1236 Patch version is ignored during compatibility check
1248 Patch version is ignored during compatibility check
1237 $ echo "testedwith = '3.2'" >> throw.py
1249 $ echo "testedwith = '3.2'" >> throw.py
1238 $ echo "util.version = lambda:'3.2.2'" >> throw.py
1250 $ echo "util.version = lambda:'3.2.2'" >> throw.py
1239 $ rm -f throw.pyc throw.pyo
1251 $ rm -f throw.pyc throw.pyo
1240 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1252 $ hg --config extensions.throw=throw.py throw 2>&1 | egrep '^\*\*'
1241 ** unknown exception encountered, please report by visiting
1253 ** unknown exception encountered, please report by visiting
1242 ** https://mercurial-scm.org/wiki/BugTracker
1254 ** https://mercurial-scm.org/wiki/BugTracker
1243 ** Python * (glob)
1255 ** Python * (glob)
1244 ** Mercurial Distributed SCM (*) (glob)
1256 ** Mercurial Distributed SCM (*) (glob)
1245 ** Extensions loaded: throw
1257 ** Extensions loaded: throw
1246
1258
1247 Test version number support in 'hg version':
1259 Test version number support in 'hg version':
1248 $ echo '__version__ = (1, 2, 3)' >> throw.py
1260 $ echo '__version__ = (1, 2, 3)' >> throw.py
1249 $ rm -f throw.pyc throw.pyo
1261 $ rm -f throw.pyc throw.pyo
1250 $ hg version -v
1262 $ hg version -v
1251 Mercurial Distributed SCM (version *) (glob)
1263 Mercurial Distributed SCM (version *) (glob)
1252 (see https://mercurial-scm.org for more information)
1264 (see https://mercurial-scm.org for more information)
1253
1265
1254 Copyright (C) 2005-* Matt Mackall and others (glob)
1266 Copyright (C) 2005-* Matt Mackall and others (glob)
1255 This is free software; see the source for copying conditions. There is NO
1267 This is free software; see the source for copying conditions. There is NO
1256 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1268 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1257
1269
1258 Enabled extensions:
1270 Enabled extensions:
1259
1271
1260
1272
1261 $ hg version -v --config extensions.throw=throw.py
1273 $ hg version -v --config extensions.throw=throw.py
1262 Mercurial Distributed SCM (version *) (glob)
1274 Mercurial Distributed SCM (version *) (glob)
1263 (see https://mercurial-scm.org for more information)
1275 (see https://mercurial-scm.org for more information)
1264
1276
1265 Copyright (C) 2005-* Matt Mackall and others (glob)
1277 Copyright (C) 2005-* Matt Mackall and others (glob)
1266 This is free software; see the source for copying conditions. There is NO
1278 This is free software; see the source for copying conditions. There is NO
1267 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1279 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1268
1280
1269 Enabled extensions:
1281 Enabled extensions:
1270
1282
1271 throw external 1.2.3
1283 throw external 1.2.3
1272 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1284 $ echo 'getversion = lambda: "1.twentythree"' >> throw.py
1273 $ rm -f throw.pyc throw.pyo
1285 $ rm -f throw.pyc throw.pyo
1274 $ hg version -v --config extensions.throw=throw.py --config extensions.strip=
1286 $ hg version -v --config extensions.throw=throw.py --config extensions.strip=
1275 Mercurial Distributed SCM (version *) (glob)
1287 Mercurial Distributed SCM (version *) (glob)
1276 (see https://mercurial-scm.org for more information)
1288 (see https://mercurial-scm.org for more information)
1277
1289
1278 Copyright (C) 2005-* Matt Mackall and others (glob)
1290 Copyright (C) 2005-* Matt Mackall and others (glob)
1279 This is free software; see the source for copying conditions. There is NO
1291 This is free software; see the source for copying conditions. There is NO
1280 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1292 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1281
1293
1282 Enabled extensions:
1294 Enabled extensions:
1283
1295
1284 throw external 1.twentythree
1296 throw external 1.twentythree
1285 strip internal
1297 strip internal
1286
1298
1287 $ hg version -q --config extensions.throw=throw.py
1299 $ hg version -q --config extensions.throw=throw.py
1288 Mercurial Distributed SCM (version *) (glob)
1300 Mercurial Distributed SCM (version *) (glob)
1289
1301
1290 Test JSON output of version:
1302 Test JSON output of version:
1291
1303
1292 $ hg version -Tjson
1304 $ hg version -Tjson
1293 [
1305 [
1294 {
1306 {
1295 "extensions": [],
1307 "extensions": [],
1296 "ver": "*" (glob)
1308 "ver": "*" (glob)
1297 }
1309 }
1298 ]
1310 ]
1299
1311
1300 $ hg version --config extensions.throw=throw.py -Tjson
1312 $ hg version --config extensions.throw=throw.py -Tjson
1301 [
1313 [
1302 {
1314 {
1303 "extensions": [{"bundled": false, "name": "throw", "ver": "1.twentythree"}],
1315 "extensions": [{"bundled": false, "name": "throw", "ver": "1.twentythree"}],
1304 "ver": "3.2.2"
1316 "ver": "3.2.2"
1305 }
1317 }
1306 ]
1318 ]
1307
1319
1308 $ hg version --config extensions.strip= -Tjson
1320 $ hg version --config extensions.strip= -Tjson
1309 [
1321 [
1310 {
1322 {
1311 "extensions": [{"bundled": true, "name": "strip", "ver": null}],
1323 "extensions": [{"bundled": true, "name": "strip", "ver": null}],
1312 "ver": "*" (glob)
1324 "ver": "*" (glob)
1313 }
1325 }
1314 ]
1326 ]
1315
1327
1316 Test template output of version:
1328 Test template output of version:
1317
1329
1318 $ hg version --config extensions.throw=throw.py --config extensions.strip= \
1330 $ hg version --config extensions.throw=throw.py --config extensions.strip= \
1319 > -T'{extensions % "{name} {pad(ver, 16)} ({if(bundled, "internal", "external")})\n"}'
1331 > -T'{extensions % "{name} {pad(ver, 16)} ({if(bundled, "internal", "external")})\n"}'
1320 throw 1.twentythree (external)
1332 throw 1.twentythree (external)
1321 strip (internal)
1333 strip (internal)
1322
1334
1323 Refuse to load extensions with minimum version requirements
1335 Refuse to load extensions with minimum version requirements
1324
1336
1325 $ cat > minversion1.py << EOF
1337 $ cat > minversion1.py << EOF
1326 > from mercurial import util
1338 > from mercurial import util
1327 > util.version = lambda: '3.5.2'
1339 > util.version = lambda: '3.5.2'
1328 > minimumhgversion = '3.6'
1340 > minimumhgversion = '3.6'
1329 > EOF
1341 > EOF
1330 $ hg --config extensions.minversion=minversion1.py version
1342 $ hg --config extensions.minversion=minversion1.py version
1331 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1343 (third party extension minversion requires version 3.6 or newer of Mercurial; disabling)
1332 Mercurial Distributed SCM (version 3.5.2)
1344 Mercurial Distributed SCM (version 3.5.2)
1333 (see https://mercurial-scm.org for more information)
1345 (see https://mercurial-scm.org for more information)
1334
1346
1335 Copyright (C) 2005-* Matt Mackall and others (glob)
1347 Copyright (C) 2005-* Matt Mackall and others (glob)
1336 This is free software; see the source for copying conditions. There is NO
1348 This is free software; see the source for copying conditions. There is NO
1337 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1338
1350
1339 $ cat > minversion2.py << EOF
1351 $ cat > minversion2.py << EOF
1340 > from mercurial import util
1352 > from mercurial import util
1341 > util.version = lambda: '3.6'
1353 > util.version = lambda: '3.6'
1342 > minimumhgversion = '3.7'
1354 > minimumhgversion = '3.7'
1343 > EOF
1355 > EOF
1344 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1356 $ hg --config extensions.minversion=minversion2.py version 2>&1 | egrep '\(third'
1345 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1357 (third party extension minversion requires version 3.7 or newer of Mercurial; disabling)
1346
1358
1347 Can load version that is only off by point release
1359 Can load version that is only off by point release
1348
1360
1349 $ cat > minversion2.py << EOF
1361 $ cat > minversion2.py << EOF
1350 > from mercurial import util
1362 > from mercurial import util
1351 > util.version = lambda: '3.6.1'
1363 > util.version = lambda: '3.6.1'
1352 > minimumhgversion = '3.6'
1364 > minimumhgversion = '3.6'
1353 > EOF
1365 > EOF
1354 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1366 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1355 [1]
1367 [1]
1356
1368
1357 Can load minimum version identical to current
1369 Can load minimum version identical to current
1358
1370
1359 $ cat > minversion3.py << EOF
1371 $ cat > minversion3.py << EOF
1360 > from mercurial import util
1372 > from mercurial import util
1361 > util.version = lambda: '3.5'
1373 > util.version = lambda: '3.5'
1362 > minimumhgversion = '3.5'
1374 > minimumhgversion = '3.5'
1363 > EOF
1375 > EOF
1364 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1376 $ hg --config extensions.minversion=minversion3.py version 2>&1 | egrep '\(third'
1365 [1]
1377 [1]
1366
1378
1367 Restore HGRCPATH
1379 Restore HGRCPATH
1368
1380
1369 $ HGRCPATH=$ORGHGRCPATH
1381 $ HGRCPATH=$ORGHGRCPATH
1370 $ export HGRCPATH
1382 $ export HGRCPATH
1371
1383
1372 Commands handling multiple repositories at a time should invoke only
1384 Commands handling multiple repositories at a time should invoke only
1373 "reposetup()" of extensions enabling in the target repository.
1385 "reposetup()" of extensions enabling in the target repository.
1374
1386
1375 $ mkdir reposetup-test
1387 $ mkdir reposetup-test
1376 $ cd reposetup-test
1388 $ cd reposetup-test
1377
1389
1378 $ cat > $TESTTMP/reposetuptest.py <<EOF
1390 $ cat > $TESTTMP/reposetuptest.py <<EOF
1379 > from mercurial import extensions
1391 > from mercurial import extensions
1380 > def reposetup(ui, repo):
1392 > def reposetup(ui, repo):
1381 > ui.write('reposetup() for %s\n' % (repo.root))
1393 > ui.write('reposetup() for %s\n' % (repo.root))
1382 > ui.flush()
1394 > ui.flush()
1383 > EOF
1395 > EOF
1384 $ hg init src
1396 $ hg init src
1385 $ echo a > src/a
1397 $ echo a > src/a
1386 $ hg -R src commit -Am '#0 at src/a'
1398 $ hg -R src commit -Am '#0 at src/a'
1387 adding a
1399 adding a
1388 $ echo '[extensions]' >> src/.hg/hgrc
1400 $ echo '[extensions]' >> src/.hg/hgrc
1389 $ echo '# enable extension locally' >> src/.hg/hgrc
1401 $ echo '# enable extension locally' >> src/.hg/hgrc
1390 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1402 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
1391 $ hg -R src status
1403 $ hg -R src status
1392 reposetup() for $TESTTMP/reposetup-test/src (glob)
1404 reposetup() for $TESTTMP/reposetup-test/src (glob)
1393
1405
1394 $ hg clone -U src clone-dst1
1406 $ hg clone -U src clone-dst1
1395 reposetup() for $TESTTMP/reposetup-test/src (glob)
1407 reposetup() for $TESTTMP/reposetup-test/src (glob)
1396 $ hg init push-dst1
1408 $ hg init push-dst1
1397 $ hg -q -R src push push-dst1
1409 $ hg -q -R src push push-dst1
1398 reposetup() for $TESTTMP/reposetup-test/src (glob)
1410 reposetup() for $TESTTMP/reposetup-test/src (glob)
1399 $ hg init pull-src1
1411 $ hg init pull-src1
1400 $ hg -q -R pull-src1 pull src
1412 $ hg -q -R pull-src1 pull src
1401 reposetup() for $TESTTMP/reposetup-test/src (glob)
1413 reposetup() for $TESTTMP/reposetup-test/src (glob)
1402
1414
1403 $ cat <<EOF >> $HGRCPATH
1415 $ cat <<EOF >> $HGRCPATH
1404 > [extensions]
1416 > [extensions]
1405 > # disable extension globally and explicitly
1417 > # disable extension globally and explicitly
1406 > reposetuptest = !
1418 > reposetuptest = !
1407 > EOF
1419 > EOF
1408 $ hg clone -U src clone-dst2
1420 $ hg clone -U src clone-dst2
1409 reposetup() for $TESTTMP/reposetup-test/src (glob)
1421 reposetup() for $TESTTMP/reposetup-test/src (glob)
1410 $ hg init push-dst2
1422 $ hg init push-dst2
1411 $ hg -q -R src push push-dst2
1423 $ hg -q -R src push push-dst2
1412 reposetup() for $TESTTMP/reposetup-test/src (glob)
1424 reposetup() for $TESTTMP/reposetup-test/src (glob)
1413 $ hg init pull-src2
1425 $ hg init pull-src2
1414 $ hg -q -R pull-src2 pull src
1426 $ hg -q -R pull-src2 pull src
1415 reposetup() for $TESTTMP/reposetup-test/src (glob)
1427 reposetup() for $TESTTMP/reposetup-test/src (glob)
1416
1428
1417 $ cat <<EOF >> $HGRCPATH
1429 $ cat <<EOF >> $HGRCPATH
1418 > [extensions]
1430 > [extensions]
1419 > # enable extension globally
1431 > # enable extension globally
1420 > reposetuptest = $TESTTMP/reposetuptest.py
1432 > reposetuptest = $TESTTMP/reposetuptest.py
1421 > EOF
1433 > EOF
1422 $ hg clone -U src clone-dst3
1434 $ hg clone -U src clone-dst3
1423 reposetup() for $TESTTMP/reposetup-test/src (glob)
1435 reposetup() for $TESTTMP/reposetup-test/src (glob)
1424 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1436 reposetup() for $TESTTMP/reposetup-test/clone-dst3 (glob)
1425 $ hg init push-dst3
1437 $ hg init push-dst3
1426 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1438 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1427 $ hg -q -R src push push-dst3
1439 $ hg -q -R src push push-dst3
1428 reposetup() for $TESTTMP/reposetup-test/src (glob)
1440 reposetup() for $TESTTMP/reposetup-test/src (glob)
1429 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1441 reposetup() for $TESTTMP/reposetup-test/push-dst3 (glob)
1430 $ hg init pull-src3
1442 $ hg init pull-src3
1431 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1443 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1432 $ hg -q -R pull-src3 pull src
1444 $ hg -q -R pull-src3 pull src
1433 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1445 reposetup() for $TESTTMP/reposetup-test/pull-src3 (glob)
1434 reposetup() for $TESTTMP/reposetup-test/src (glob)
1446 reposetup() for $TESTTMP/reposetup-test/src (glob)
1435
1447
1436 $ echo '[extensions]' >> src/.hg/hgrc
1448 $ echo '[extensions]' >> src/.hg/hgrc
1437 $ echo '# disable extension locally' >> src/.hg/hgrc
1449 $ echo '# disable extension locally' >> src/.hg/hgrc
1438 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1450 $ echo 'reposetuptest = !' >> src/.hg/hgrc
1439 $ hg clone -U src clone-dst4
1451 $ hg clone -U src clone-dst4
1440 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1452 reposetup() for $TESTTMP/reposetup-test/clone-dst4 (glob)
1441 $ hg init push-dst4
1453 $ hg init push-dst4
1442 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1454 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1443 $ hg -q -R src push push-dst4
1455 $ hg -q -R src push push-dst4
1444 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1456 reposetup() for $TESTTMP/reposetup-test/push-dst4 (glob)
1445 $ hg init pull-src4
1457 $ hg init pull-src4
1446 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1458 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1447 $ hg -q -R pull-src4 pull src
1459 $ hg -q -R pull-src4 pull src
1448 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1460 reposetup() for $TESTTMP/reposetup-test/pull-src4 (glob)
1449
1461
1450 disabling in command line overlays with all configuration
1462 disabling in command line overlays with all configuration
1451 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1463 $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
1452 $ hg --config extensions.reposetuptest=! init push-dst5
1464 $ hg --config extensions.reposetuptest=! init push-dst5
1453 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1465 $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
1454 $ hg --config extensions.reposetuptest=! init pull-src5
1466 $ hg --config extensions.reposetuptest=! init pull-src5
1455 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1467 $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
1456
1468
1457 $ cat <<EOF >> $HGRCPATH
1469 $ cat <<EOF >> $HGRCPATH
1458 > [extensions]
1470 > [extensions]
1459 > # disable extension globally and explicitly
1471 > # disable extension globally and explicitly
1460 > reposetuptest = !
1472 > reposetuptest = !
1461 > EOF
1473 > EOF
1462 $ hg init parent
1474 $ hg init parent
1463 $ hg init parent/sub1
1475 $ hg init parent/sub1
1464 $ echo 1 > parent/sub1/1
1476 $ echo 1 > parent/sub1/1
1465 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1477 $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
1466 adding 1
1478 adding 1
1467 $ hg init parent/sub2
1479 $ hg init parent/sub2
1468 $ hg init parent/sub2/sub21
1480 $ hg init parent/sub2/sub21
1469 $ echo 21 > parent/sub2/sub21/21
1481 $ echo 21 > parent/sub2/sub21/21
1470 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1482 $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
1471 adding 21
1483 adding 21
1472 $ cat > parent/sub2/.hgsub <<EOF
1484 $ cat > parent/sub2/.hgsub <<EOF
1473 > sub21 = sub21
1485 > sub21 = sub21
1474 > EOF
1486 > EOF
1475 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1487 $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
1476 adding .hgsub
1488 adding .hgsub
1477 $ hg init parent/sub3
1489 $ hg init parent/sub3
1478 $ echo 3 > parent/sub3/3
1490 $ echo 3 > parent/sub3/3
1479 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1491 $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
1480 adding 3
1492 adding 3
1481 $ cat > parent/.hgsub <<EOF
1493 $ cat > parent/.hgsub <<EOF
1482 > sub1 = sub1
1494 > sub1 = sub1
1483 > sub2 = sub2
1495 > sub2 = sub2
1484 > sub3 = sub3
1496 > sub3 = sub3
1485 > EOF
1497 > EOF
1486 $ hg -R parent commit -Am '#0 at parent'
1498 $ hg -R parent commit -Am '#0 at parent'
1487 adding .hgsub
1499 adding .hgsub
1488 $ echo '[extensions]' >> parent/.hg/hgrc
1500 $ echo '[extensions]' >> parent/.hg/hgrc
1489 $ echo '# enable extension locally' >> parent/.hg/hgrc
1501 $ echo '# enable extension locally' >> parent/.hg/hgrc
1490 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1502 $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
1491 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1503 $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
1492 $ hg -R parent status -S -A
1504 $ hg -R parent status -S -A
1493 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1505 reposetup() for $TESTTMP/reposetup-test/parent (glob)
1494 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1506 reposetup() for $TESTTMP/reposetup-test/parent/sub2 (glob)
1495 C .hgsub
1507 C .hgsub
1496 C .hgsubstate
1508 C .hgsubstate
1497 C sub1/1
1509 C sub1/1
1498 C sub2/.hgsub
1510 C sub2/.hgsub
1499 C sub2/.hgsubstate
1511 C sub2/.hgsubstate
1500 C sub2/sub21/21
1512 C sub2/sub21/21
1501 C sub3/3
1513 C sub3/3
1502
1514
1503 $ cd ..
1515 $ cd ..
1504
1516
1505 Test synopsis and docstring extending
1517 Test synopsis and docstring extending
1506
1518
1507 $ hg init exthelp
1519 $ hg init exthelp
1508 $ cat > exthelp.py <<EOF
1520 $ cat > exthelp.py <<EOF
1509 > from mercurial import commands, extensions
1521 > from mercurial import commands, extensions
1510 > def exbookmarks(orig, *args, **opts):
1522 > def exbookmarks(orig, *args, **opts):
1511 > return orig(*args, **opts)
1523 > return orig(*args, **opts)
1512 > def uisetup(ui):
1524 > def uisetup(ui):
1513 > synopsis = ' GREPME [--foo] [-x]'
1525 > synopsis = ' GREPME [--foo] [-x]'
1514 > docstring = '''
1526 > docstring = '''
1515 > GREPME make sure that this is in the help!
1527 > GREPME make sure that this is in the help!
1516 > '''
1528 > '''
1517 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1529 > extensions.wrapcommand(commands.table, 'bookmarks', exbookmarks,
1518 > synopsis, docstring)
1530 > synopsis, docstring)
1519 > EOF
1531 > EOF
1520 $ abspath=`pwd`/exthelp.py
1532 $ abspath=`pwd`/exthelp.py
1521 $ echo '[extensions]' >> $HGRCPATH
1533 $ echo '[extensions]' >> $HGRCPATH
1522 $ echo "exthelp = $abspath" >> $HGRCPATH
1534 $ echo "exthelp = $abspath" >> $HGRCPATH
1523 $ cd exthelp
1535 $ cd exthelp
1524 $ hg help bookmarks | grep GREPME
1536 $ hg help bookmarks | grep GREPME
1525 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1537 hg bookmarks [OPTIONS]... [NAME]... GREPME [--foo] [-x]
1526 GREPME make sure that this is in the help!
1538 GREPME make sure that this is in the help!
1527
1539
@@ -1,4 +1,9 b''
1 #require docutils gettext
1 #require docutils gettext
2
2
3 Error: the current ro localization has some rst defects exposed by
4 moving pager to core. These two warnings about references are expected
5 until the localization is corrected.
3 $ $TESTDIR/check-gendoc ro
6 $ $TESTDIR/check-gendoc ro
4 checking for parse errors
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.
@@ -1,3174 +1,3184 b''
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge another revision into working directory
17 merge merge another revision into working directory
18 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge another revision into working directory
38 merge merge another revision into working directory
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 $ hg help
47 $ hg help
48 Mercurial Distributed SCM
48 Mercurial Distributed SCM
49
49
50 list of commands:
50 list of commands:
51
51
52 add add the specified files on the next commit
52 add add the specified files on the next commit
53 addremove add all new files, delete all missing files
53 addremove add all new files, delete all missing files
54 annotate show changeset information by line for each file
54 annotate show changeset information by line for each file
55 archive create an unversioned archive of a repository revision
55 archive create an unversioned archive of a repository revision
56 backout reverse effect of earlier changeset
56 backout reverse effect of earlier changeset
57 bisect subdivision search of changesets
57 bisect subdivision search of changesets
58 bookmarks create a new bookmark or list existing bookmarks
58 bookmarks create a new bookmark or list existing bookmarks
59 branch set or show the current branch name
59 branch set or show the current branch name
60 branches list repository named branches
60 branches list repository named branches
61 bundle create a changegroup file
61 bundle create a changegroup file
62 cat output the current or given revision of files
62 cat output the current or given revision of files
63 clone make a copy of an existing repository
63 clone make a copy of an existing repository
64 commit commit the specified files or all outstanding changes
64 commit commit the specified files or all outstanding changes
65 config show combined config settings from all hgrc files
65 config show combined config settings from all hgrc files
66 copy mark files as copied for the next commit
66 copy mark files as copied for the next commit
67 diff diff repository (or selected files)
67 diff diff repository (or selected files)
68 export dump the header and diffs for one or more changesets
68 export dump the header and diffs for one or more changesets
69 files list tracked files
69 files list tracked files
70 forget forget the specified files on the next commit
70 forget forget the specified files on the next commit
71 graft copy changes from other branches onto the current branch
71 graft copy changes from other branches onto the current branch
72 grep search revision history for a pattern in specified files
72 grep search revision history for a pattern in specified files
73 heads show branch heads
73 heads show branch heads
74 help show help for a given topic or a help overview
74 help show help for a given topic or a help overview
75 identify identify the working directory or specified revision
75 identify identify the working directory or specified revision
76 import import an ordered set of patches
76 import import an ordered set of patches
77 incoming show new changesets found in source
77 incoming show new changesets found in source
78 init create a new repository in the given directory
78 init create a new repository in the given directory
79 log show revision history of entire repository or files
79 log show revision history of entire repository or files
80 manifest output the current or given revision of the project manifest
80 manifest output the current or given revision of the project manifest
81 merge merge another revision into working directory
81 merge merge another revision into working directory
82 outgoing show changesets not found in the destination
82 outgoing show changesets not found in the destination
83 paths show aliases for remote repositories
83 paths show aliases for remote repositories
84 phase set or show the current phase name
84 phase set or show the current phase name
85 pull pull changes from the specified source
85 pull pull changes from the specified source
86 push push changes to the specified destination
86 push push changes to the specified destination
87 recover roll back an interrupted transaction
87 recover roll back an interrupted transaction
88 remove remove the specified files on the next commit
88 remove remove the specified files on the next commit
89 rename rename files; equivalent of copy + remove
89 rename rename files; equivalent of copy + remove
90 resolve redo merges or set/view the merge status of files
90 resolve redo merges or set/view the merge status of files
91 revert restore files to their checkout state
91 revert restore files to their checkout state
92 root print the root (top) of the current working directory
92 root print the root (top) of the current working directory
93 serve start stand-alone webserver
93 serve start stand-alone webserver
94 status show changed files in the working directory
94 status show changed files in the working directory
95 summary summarize working directory state
95 summary summarize working directory state
96 tag add one or more tags for the current or given revision
96 tag add one or more tags for the current or given revision
97 tags list repository tags
97 tags list repository tags
98 unbundle apply one or more changegroup files
98 unbundle apply one or more changegroup files
99 update update working directory (or switch revisions)
99 update update working directory (or switch revisions)
100 verify verify the integrity of the repository
100 verify verify the integrity of the repository
101 version output version and copyright information
101 version output version and copyright information
102
102
103 additional help topics:
103 additional help topics:
104
104
105 config Configuration Files
105 config Configuration Files
106 dates Date Formats
106 dates Date Formats
107 diffs Diff Formats
107 diffs Diff Formats
108 environment Environment Variables
108 environment Environment Variables
109 extensions Using Additional Features
109 extensions Using Additional Features
110 filesets Specifying File Sets
110 filesets Specifying File Sets
111 glossary Glossary
111 glossary Glossary
112 hgignore Syntax for Mercurial Ignore Files
112 hgignore Syntax for Mercurial Ignore Files
113 hgweb Configuring hgweb
113 hgweb Configuring hgweb
114 internals Technical implementation topics
114 internals Technical implementation topics
115 merge-tools Merge Tools
115 merge-tools Merge Tools
116 patterns File Name Patterns
116 patterns File Name Patterns
117 phases Working with Phases
117 phases Working with Phases
118 revisions Specifying Revisions
118 revisions Specifying Revisions
119 scripting Using Mercurial from scripts and automation
119 scripting Using Mercurial from scripts and automation
120 subrepos Subrepositories
120 subrepos Subrepositories
121 templating Template Usage
121 templating Template Usage
122 urls URL Paths
122 urls URL Paths
123
123
124 (use 'hg help -v' to show built-in aliases and global options)
124 (use 'hg help -v' to show built-in aliases and global options)
125
125
126 $ hg -q help
126 $ hg -q help
127 add add the specified files on the next commit
127 add add the specified files on the next commit
128 addremove add all new files, delete all missing files
128 addremove add all new files, delete all missing files
129 annotate show changeset information by line for each file
129 annotate show changeset information by line for each file
130 archive create an unversioned archive of a repository revision
130 archive create an unversioned archive of a repository revision
131 backout reverse effect of earlier changeset
131 backout reverse effect of earlier changeset
132 bisect subdivision search of changesets
132 bisect subdivision search of changesets
133 bookmarks create a new bookmark or list existing bookmarks
133 bookmarks create a new bookmark or list existing bookmarks
134 branch set or show the current branch name
134 branch set or show the current branch name
135 branches list repository named branches
135 branches list repository named branches
136 bundle create a changegroup file
136 bundle create a changegroup file
137 cat output the current or given revision of files
137 cat output the current or given revision of files
138 clone make a copy of an existing repository
138 clone make a copy of an existing repository
139 commit commit the specified files or all outstanding changes
139 commit commit the specified files or all outstanding changes
140 config show combined config settings from all hgrc files
140 config show combined config settings from all hgrc files
141 copy mark files as copied for the next commit
141 copy mark files as copied for the next commit
142 diff diff repository (or selected files)
142 diff diff repository (or selected files)
143 export dump the header and diffs for one or more changesets
143 export dump the header and diffs for one or more changesets
144 files list tracked files
144 files list tracked files
145 forget forget the specified files on the next commit
145 forget forget the specified files on the next commit
146 graft copy changes from other branches onto the current branch
146 graft copy changes from other branches onto the current branch
147 grep search revision history for a pattern in specified files
147 grep search revision history for a pattern in specified files
148 heads show branch heads
148 heads show branch heads
149 help show help for a given topic or a help overview
149 help show help for a given topic or a help overview
150 identify identify the working directory or specified revision
150 identify identify the working directory or specified revision
151 import import an ordered set of patches
151 import import an ordered set of patches
152 incoming show new changesets found in source
152 incoming show new changesets found in source
153 init create a new repository in the given directory
153 init create a new repository in the given directory
154 log show revision history of entire repository or files
154 log show revision history of entire repository or files
155 manifest output the current or given revision of the project manifest
155 manifest output the current or given revision of the project manifest
156 merge merge another revision into working directory
156 merge merge another revision into working directory
157 outgoing show changesets not found in the destination
157 outgoing show changesets not found in the destination
158 paths show aliases for remote repositories
158 paths show aliases for remote repositories
159 phase set or show the current phase name
159 phase set or show the current phase name
160 pull pull changes from the specified source
160 pull pull changes from the specified source
161 push push changes to the specified destination
161 push push changes to the specified destination
162 recover roll back an interrupted transaction
162 recover roll back an interrupted transaction
163 remove remove the specified files on the next commit
163 remove remove the specified files on the next commit
164 rename rename files; equivalent of copy + remove
164 rename rename files; equivalent of copy + remove
165 resolve redo merges or set/view the merge status of files
165 resolve redo merges or set/view the merge status of files
166 revert restore files to their checkout state
166 revert restore files to their checkout state
167 root print the root (top) of the current working directory
167 root print the root (top) of the current working directory
168 serve start stand-alone webserver
168 serve start stand-alone webserver
169 status show changed files in the working directory
169 status show changed files in the working directory
170 summary summarize working directory state
170 summary summarize working directory state
171 tag add one or more tags for the current or given revision
171 tag add one or more tags for the current or given revision
172 tags list repository tags
172 tags list repository tags
173 unbundle apply one or more changegroup files
173 unbundle apply one or more changegroup files
174 update update working directory (or switch revisions)
174 update update working directory (or switch revisions)
175 verify verify the integrity of the repository
175 verify verify the integrity of the repository
176 version output version and copyright information
176 version output version and copyright information
177
177
178 additional help topics:
178 additional help topics:
179
179
180 config Configuration Files
180 config Configuration Files
181 dates Date Formats
181 dates Date Formats
182 diffs Diff Formats
182 diffs Diff Formats
183 environment Environment Variables
183 environment Environment Variables
184 extensions Using Additional Features
184 extensions Using Additional Features
185 filesets Specifying File Sets
185 filesets Specifying File Sets
186 glossary Glossary
186 glossary Glossary
187 hgignore Syntax for Mercurial Ignore Files
187 hgignore Syntax for Mercurial Ignore Files
188 hgweb Configuring hgweb
188 hgweb Configuring hgweb
189 internals Technical implementation topics
189 internals Technical implementation topics
190 merge-tools Merge Tools
190 merge-tools Merge Tools
191 patterns File Name Patterns
191 patterns File Name Patterns
192 phases Working with Phases
192 phases Working with Phases
193 revisions Specifying Revisions
193 revisions Specifying Revisions
194 scripting Using Mercurial from scripts and automation
194 scripting Using Mercurial from scripts and automation
195 subrepos Subrepositories
195 subrepos Subrepositories
196 templating Template Usage
196 templating Template Usage
197 urls URL Paths
197 urls URL Paths
198
198
199 Test extension help:
199 Test extension help:
200 $ hg help extensions --config extensions.rebase= --config extensions.children=
200 $ hg help extensions --config extensions.rebase= --config extensions.children=
201 Using Additional Features
201 Using Additional Features
202 """""""""""""""""""""""""
202 """""""""""""""""""""""""
203
203
204 Mercurial has the ability to add new features through the use of
204 Mercurial has the ability to add new features through the use of
205 extensions. Extensions may add new commands, add options to existing
205 extensions. Extensions may add new commands, add options to existing
206 commands, change the default behavior of commands, or implement hooks.
206 commands, change the default behavior of commands, or implement hooks.
207
207
208 To enable the "foo" extension, either shipped with Mercurial or in the
208 To enable the "foo" extension, either shipped with Mercurial or in the
209 Python search path, create an entry for it in your configuration file,
209 Python search path, create an entry for it in your configuration file,
210 like this:
210 like this:
211
211
212 [extensions]
212 [extensions]
213 foo =
213 foo =
214
214
215 You may also specify the full path to an extension:
215 You may also specify the full path to an extension:
216
216
217 [extensions]
217 [extensions]
218 myfeature = ~/.hgext/myfeature.py
218 myfeature = ~/.hgext/myfeature.py
219
219
220 See 'hg help config' for more information on configuration files.
220 See 'hg help config' for more information on configuration files.
221
221
222 Extensions are not loaded by default for a variety of reasons: they can
222 Extensions are not loaded by default for a variety of reasons: they can
223 increase startup overhead; they may be meant for advanced usage only; they
223 increase startup overhead; they may be meant for advanced usage only; they
224 may provide potentially dangerous abilities (such as letting you destroy
224 may provide potentially dangerous abilities (such as letting you destroy
225 or modify history); they might not be ready for prime time; or they may
225 or modify history); they might not be ready for prime time; or they may
226 alter some usual behaviors of stock Mercurial. It is thus up to the user
226 alter some usual behaviors of stock Mercurial. It is thus up to the user
227 to activate extensions as needed.
227 to activate extensions as needed.
228
228
229 To explicitly disable an extension enabled in a configuration file of
229 To explicitly disable an extension enabled in a configuration file of
230 broader scope, prepend its path with !:
230 broader scope, prepend its path with !:
231
231
232 [extensions]
232 [extensions]
233 # disabling extension bar residing in /path/to/extension/bar.py
233 # disabling extension bar residing in /path/to/extension/bar.py
234 bar = !/path/to/extension/bar.py
234 bar = !/path/to/extension/bar.py
235 # ditto, but no path was supplied for extension baz
235 # ditto, but no path was supplied for extension baz
236 baz = !
236 baz = !
237
237
238 enabled extensions:
238 enabled extensions:
239
239
240 children command to display child changesets (DEPRECATED)
240 children command to display child changesets (DEPRECATED)
241 rebase command to move sets of revisions to a different ancestor
241 rebase command to move sets of revisions to a different ancestor
242
242
243 disabled extensions:
243 disabled extensions:
244
244
245 acl hooks for controlling repository access
245 acl hooks for controlling repository access
246 blackbox log repository events to a blackbox for debugging
246 blackbox log repository events to a blackbox for debugging
247 bugzilla hooks for integrating with the Bugzilla bug tracker
247 bugzilla hooks for integrating with the Bugzilla bug tracker
248 censor erase file content at a given revision
248 censor erase file content at a given revision
249 churn command to display statistics about repository history
249 churn command to display statistics about repository history
250 clonebundles advertise pre-generated bundles to seed clones
250 clonebundles advertise pre-generated bundles to seed clones
251 color colorize output from some commands
251 color colorize output from some commands
252 convert import revisions from foreign VCS repositories into
252 convert import revisions from foreign VCS repositories into
253 Mercurial
253 Mercurial
254 eol automatically manage newlines in repository files
254 eol automatically manage newlines in repository files
255 extdiff command to allow external programs to compare revisions
255 extdiff command to allow external programs to compare revisions
256 factotum http authentication with factotum
256 factotum http authentication with factotum
257 gpg commands to sign and verify changesets
257 gpg commands to sign and verify changesets
258 hgk browse the repository in a graphical way
258 hgk browse the repository in a graphical way
259 highlight syntax highlighting for hgweb (requires Pygments)
259 highlight syntax highlighting for hgweb (requires Pygments)
260 histedit interactive history editing
260 histedit interactive history editing
261 keyword expand keywords in tracked files
261 keyword expand keywords in tracked files
262 largefiles track large binary files
262 largefiles track large binary files
263 mq manage a stack of patches
263 mq manage a stack of patches
264 notify hooks for sending email push notifications
264 notify hooks for sending email push notifications
265 pager browse command output with an external pager
265 pager browse command output with an external pager
266 patchbomb command to send changesets as (a series of) patch emails
266 patchbomb command to send changesets as (a series of) patch emails
267 purge command to delete untracked files from the working
267 purge command to delete untracked files from the working
268 directory
268 directory
269 relink recreates hardlinks between repository clones
269 relink recreates hardlinks between repository clones
270 schemes extend schemes with shortcuts to repository swarms
270 schemes extend schemes with shortcuts to repository swarms
271 share share a common history between several working directories
271 share share a common history between several working directories
272 shelve save and restore changes to the working directory
272 shelve save and restore changes to the working directory
273 strip strip changesets and their descendants from history
273 strip strip changesets and their descendants from history
274 transplant command to transplant changesets from another branch
274 transplant command to transplant changesets from another branch
275 win32mbcs allow the use of MBCS paths with problematic encodings
275 win32mbcs allow the use of MBCS paths with problematic encodings
276 zeroconf discover and advertise repositories on the local network
276 zeroconf discover and advertise repositories on the local network
277
277
278 Verify that extension keywords appear in help templates
278 Verify that extension keywords appear in help templates
279
279
280 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
280 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
281
281
282 Test short command list with verbose option
282 Test short command list with verbose option
283
283
284 $ hg -v help shortlist
284 $ hg -v help shortlist
285 Mercurial Distributed SCM
285 Mercurial Distributed SCM
286
286
287 basic commands:
287 basic commands:
288
288
289 add add the specified files on the next commit
289 add add the specified files on the next commit
290 annotate, blame
290 annotate, blame
291 show changeset information by line for each file
291 show changeset information by line for each file
292 clone make a copy of an existing repository
292 clone make a copy of an existing repository
293 commit, ci commit the specified files or all outstanding changes
293 commit, ci commit the specified files or all outstanding changes
294 diff diff repository (or selected files)
294 diff diff repository (or selected files)
295 export dump the header and diffs for one or more changesets
295 export dump the header and diffs for one or more changesets
296 forget forget the specified files on the next commit
296 forget forget the specified files on the next commit
297 init create a new repository in the given directory
297 init create a new repository in the given directory
298 log, history show revision history of entire repository or files
298 log, history show revision history of entire repository or files
299 merge merge another revision into working directory
299 merge merge another revision into working directory
300 pull pull changes from the specified source
300 pull pull changes from the specified source
301 push push changes to the specified destination
301 push push changes to the specified destination
302 remove, rm remove the specified files on the next commit
302 remove, rm remove the specified files on the next commit
303 serve start stand-alone webserver
303 serve start stand-alone webserver
304 status, st show changed files in the working directory
304 status, st show changed files in the working directory
305 summary, sum summarize working directory state
305 summary, sum summarize working directory state
306 update, up, checkout, co
306 update, up, checkout, co
307 update working directory (or switch revisions)
307 update working directory (or switch revisions)
308
308
309 global options ([+] can be repeated):
309 global options ([+] can be repeated):
310
310
311 -R --repository REPO repository root directory or name of overlay bundle
311 -R --repository REPO repository root directory or name of overlay bundle
312 file
312 file
313 --cwd DIR change working directory
313 --cwd DIR change working directory
314 -y --noninteractive do not prompt, automatically pick the first choice for
314 -y --noninteractive do not prompt, automatically pick the first choice for
315 all prompts
315 all prompts
316 -q --quiet suppress output
316 -q --quiet suppress output
317 -v --verbose enable additional output
317 -v --verbose enable additional output
318 --config CONFIG [+] set/override config option (use 'section.name=value')
318 --config CONFIG [+] set/override config option (use 'section.name=value')
319 --debug enable debugging output
319 --debug enable debugging output
320 --debugger start debugger
320 --debugger start debugger
321 --encoding ENCODE set the charset encoding (default: ascii)
321 --encoding ENCODE set the charset encoding (default: ascii)
322 --encodingmode MODE set the charset encoding mode (default: strict)
322 --encodingmode MODE set the charset encoding mode (default: strict)
323 --traceback always print a traceback on exception
323 --traceback always print a traceback on exception
324 --time time how long the command takes
324 --time time how long the command takes
325 --profile print command execution profile
325 --profile print command execution profile
326 --version output version information and exit
326 --version output version information and exit
327 -h --help display help and exit
327 -h --help display help and exit
328 --hidden consider hidden changesets
328 --hidden consider hidden changesets
329 --pager TYPE when to paginate (boolean, always, auto, or never)
330 (default: auto)
329
331
330 (use 'hg help' for the full list of commands)
332 (use 'hg help' for the full list of commands)
331
333
332 $ hg add -h
334 $ hg add -h
333 hg add [OPTION]... [FILE]...
335 hg add [OPTION]... [FILE]...
334
336
335 add the specified files on the next commit
337 add the specified files on the next commit
336
338
337 Schedule files to be version controlled and added to the repository.
339 Schedule files to be version controlled and added to the repository.
338
340
339 The files will be added to the repository at the next commit. To undo an
341 The files will be added to the repository at the next commit. To undo an
340 add before that, see 'hg forget'.
342 add before that, see 'hg forget'.
341
343
342 If no names are given, add all files to the repository (except files
344 If no names are given, add all files to the repository (except files
343 matching ".hgignore").
345 matching ".hgignore").
344
346
345 Returns 0 if all files are successfully added.
347 Returns 0 if all files are successfully added.
346
348
347 options ([+] can be repeated):
349 options ([+] can be repeated):
348
350
349 -I --include PATTERN [+] include names matching the given patterns
351 -I --include PATTERN [+] include names matching the given patterns
350 -X --exclude PATTERN [+] exclude names matching the given patterns
352 -X --exclude PATTERN [+] exclude names matching the given patterns
351 -S --subrepos recurse into subrepositories
353 -S --subrepos recurse into subrepositories
352 -n --dry-run do not perform actions, just print output
354 -n --dry-run do not perform actions, just print output
353
355
354 (some details hidden, use --verbose to show complete help)
356 (some details hidden, use --verbose to show complete help)
355
357
356 Verbose help for add
358 Verbose help for add
357
359
358 $ hg add -hv
360 $ hg add -hv
359 hg add [OPTION]... [FILE]...
361 hg add [OPTION]... [FILE]...
360
362
361 add the specified files on the next commit
363 add the specified files on the next commit
362
364
363 Schedule files to be version controlled and added to the repository.
365 Schedule files to be version controlled and added to the repository.
364
366
365 The files will be added to the repository at the next commit. To undo an
367 The files will be added to the repository at the next commit. To undo an
366 add before that, see 'hg forget'.
368 add before that, see 'hg forget'.
367
369
368 If no names are given, add all files to the repository (except files
370 If no names are given, add all files to the repository (except files
369 matching ".hgignore").
371 matching ".hgignore").
370
372
371 Examples:
373 Examples:
372
374
373 - New (unknown) files are added automatically by 'hg add':
375 - New (unknown) files are added automatically by 'hg add':
374
376
375 $ ls
377 $ ls
376 foo.c
378 foo.c
377 $ hg status
379 $ hg status
378 ? foo.c
380 ? foo.c
379 $ hg add
381 $ hg add
380 adding foo.c
382 adding foo.c
381 $ hg status
383 $ hg status
382 A foo.c
384 A foo.c
383
385
384 - Specific files to be added can be specified:
386 - Specific files to be added can be specified:
385
387
386 $ ls
388 $ ls
387 bar.c foo.c
389 bar.c foo.c
388 $ hg status
390 $ hg status
389 ? bar.c
391 ? bar.c
390 ? foo.c
392 ? foo.c
391 $ hg add bar.c
393 $ hg add bar.c
392 $ hg status
394 $ hg status
393 A bar.c
395 A bar.c
394 ? foo.c
396 ? foo.c
395
397
396 Returns 0 if all files are successfully added.
398 Returns 0 if all files are successfully added.
397
399
398 options ([+] can be repeated):
400 options ([+] can be repeated):
399
401
400 -I --include PATTERN [+] include names matching the given patterns
402 -I --include PATTERN [+] include names matching the given patterns
401 -X --exclude PATTERN [+] exclude names matching the given patterns
403 -X --exclude PATTERN [+] exclude names matching the given patterns
402 -S --subrepos recurse into subrepositories
404 -S --subrepos recurse into subrepositories
403 -n --dry-run do not perform actions, just print output
405 -n --dry-run do not perform actions, just print output
404
406
405 global options ([+] can be repeated):
407 global options ([+] can be repeated):
406
408
407 -R --repository REPO repository root directory or name of overlay bundle
409 -R --repository REPO repository root directory or name of overlay bundle
408 file
410 file
409 --cwd DIR change working directory
411 --cwd DIR change working directory
410 -y --noninteractive do not prompt, automatically pick the first choice for
412 -y --noninteractive do not prompt, automatically pick the first choice for
411 all prompts
413 all prompts
412 -q --quiet suppress output
414 -q --quiet suppress output
413 -v --verbose enable additional output
415 -v --verbose enable additional output
414 --config CONFIG [+] set/override config option (use 'section.name=value')
416 --config CONFIG [+] set/override config option (use 'section.name=value')
415 --debug enable debugging output
417 --debug enable debugging output
416 --debugger start debugger
418 --debugger start debugger
417 --encoding ENCODE set the charset encoding (default: ascii)
419 --encoding ENCODE set the charset encoding (default: ascii)
418 --encodingmode MODE set the charset encoding mode (default: strict)
420 --encodingmode MODE set the charset encoding mode (default: strict)
419 --traceback always print a traceback on exception
421 --traceback always print a traceback on exception
420 --time time how long the command takes
422 --time time how long the command takes
421 --profile print command execution profile
423 --profile print command execution profile
422 --version output version information and exit
424 --version output version information and exit
423 -h --help display help and exit
425 -h --help display help and exit
424 --hidden consider hidden changesets
426 --hidden consider hidden changesets
427 --pager TYPE when to paginate (boolean, always, auto, or never)
428 (default: auto)
425
429
426 Test the textwidth config option
430 Test the textwidth config option
427
431
428 $ hg root -h --config ui.textwidth=50
432 $ hg root -h --config ui.textwidth=50
429 hg root
433 hg root
430
434
431 print the root (top) of the current working
435 print the root (top) of the current working
432 directory
436 directory
433
437
434 Print the root directory of the current
438 Print the root directory of the current
435 repository.
439 repository.
436
440
437 Returns 0 on success.
441 Returns 0 on success.
438
442
439 (some details hidden, use --verbose to show
443 (some details hidden, use --verbose to show
440 complete help)
444 complete help)
441
445
442 Test help option with version option
446 Test help option with version option
443
447
444 $ hg add -h --version
448 $ hg add -h --version
445 Mercurial Distributed SCM (version *) (glob)
449 Mercurial Distributed SCM (version *) (glob)
446 (see https://mercurial-scm.org for more information)
450 (see https://mercurial-scm.org for more information)
447
451
448 Copyright (C) 2005-* Matt Mackall and others (glob)
452 Copyright (C) 2005-* Matt Mackall and others (glob)
449 This is free software; see the source for copying conditions. There is NO
453 This is free software; see the source for copying conditions. There is NO
450 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
454 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
451
455
452 $ hg add --skjdfks
456 $ hg add --skjdfks
453 hg add: option --skjdfks not recognized
457 hg add: option --skjdfks not recognized
454 hg add [OPTION]... [FILE]...
458 hg add [OPTION]... [FILE]...
455
459
456 add the specified files on the next commit
460 add the specified files on the next commit
457
461
458 options ([+] can be repeated):
462 options ([+] can be repeated):
459
463
460 -I --include PATTERN [+] include names matching the given patterns
464 -I --include PATTERN [+] include names matching the given patterns
461 -X --exclude PATTERN [+] exclude names matching the given patterns
465 -X --exclude PATTERN [+] exclude names matching the given patterns
462 -S --subrepos recurse into subrepositories
466 -S --subrepos recurse into subrepositories
463 -n --dry-run do not perform actions, just print output
467 -n --dry-run do not perform actions, just print output
464
468
465 (use 'hg add -h' to show more help)
469 (use 'hg add -h' to show more help)
466 [255]
470 [255]
467
471
468 Test ambiguous command help
472 Test ambiguous command help
469
473
470 $ hg help ad
474 $ hg help ad
471 list of commands:
475 list of commands:
472
476
473 add add the specified files on the next commit
477 add add the specified files on the next commit
474 addremove add all new files, delete all missing files
478 addremove add all new files, delete all missing files
475
479
476 (use 'hg help -v ad' to show built-in aliases and global options)
480 (use 'hg help -v ad' to show built-in aliases and global options)
477
481
478 Test command without options
482 Test command without options
479
483
480 $ hg help verify
484 $ hg help verify
481 hg verify
485 hg verify
482
486
483 verify the integrity of the repository
487 verify the integrity of the repository
484
488
485 Verify the integrity of the current repository.
489 Verify the integrity of the current repository.
486
490
487 This will perform an extensive check of the repository's integrity,
491 This will perform an extensive check of the repository's integrity,
488 validating the hashes and checksums of each entry in the changelog,
492 validating the hashes and checksums of each entry in the changelog,
489 manifest, and tracked files, as well as the integrity of their crosslinks
493 manifest, and tracked files, as well as the integrity of their crosslinks
490 and indices.
494 and indices.
491
495
492 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
496 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
493 information about recovery from corruption of the repository.
497 information about recovery from corruption of the repository.
494
498
495 Returns 0 on success, 1 if errors are encountered.
499 Returns 0 on success, 1 if errors are encountered.
496
500
497 (some details hidden, use --verbose to show complete help)
501 (some details hidden, use --verbose to show complete help)
498
502
499 $ hg help diff
503 $ hg help diff
500 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
504 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
501
505
502 diff repository (or selected files)
506 diff repository (or selected files)
503
507
504 Show differences between revisions for the specified files.
508 Show differences between revisions for the specified files.
505
509
506 Differences between files are shown using the unified diff format.
510 Differences between files are shown using the unified diff format.
507
511
508 Note:
512 Note:
509 'hg diff' may generate unexpected results for merges, as it will
513 'hg diff' may generate unexpected results for merges, as it will
510 default to comparing against the working directory's first parent
514 default to comparing against the working directory's first parent
511 changeset if no revisions are specified.
515 changeset if no revisions are specified.
512
516
513 When two revision arguments are given, then changes are shown between
517 When two revision arguments are given, then changes are shown between
514 those revisions. If only one revision is specified then that revision is
518 those revisions. If only one revision is specified then that revision is
515 compared to the working directory, and, when no revisions are specified,
519 compared to the working directory, and, when no revisions are specified,
516 the working directory files are compared to its first parent.
520 the working directory files are compared to its first parent.
517
521
518 Alternatively you can specify -c/--change with a revision to see the
522 Alternatively you can specify -c/--change with a revision to see the
519 changes in that changeset relative to its first parent.
523 changes in that changeset relative to its first parent.
520
524
521 Without the -a/--text option, diff will avoid generating diffs of files it
525 Without the -a/--text option, diff will avoid generating diffs of files it
522 detects as binary. With -a, diff will generate a diff anyway, probably
526 detects as binary. With -a, diff will generate a diff anyway, probably
523 with undesirable results.
527 with undesirable results.
524
528
525 Use the -g/--git option to generate diffs in the git extended diff format.
529 Use the -g/--git option to generate diffs in the git extended diff format.
526 For more information, read 'hg help diffs'.
530 For more information, read 'hg help diffs'.
527
531
528 Returns 0 on success.
532 Returns 0 on success.
529
533
530 options ([+] can be repeated):
534 options ([+] can be repeated):
531
535
532 -r --rev REV [+] revision
536 -r --rev REV [+] revision
533 -c --change REV change made by revision
537 -c --change REV change made by revision
534 -a --text treat all files as text
538 -a --text treat all files as text
535 -g --git use git extended diff format
539 -g --git use git extended diff format
536 --nodates omit dates from diff headers
540 --nodates omit dates from diff headers
537 --noprefix omit a/ and b/ prefixes from filenames
541 --noprefix omit a/ and b/ prefixes from filenames
538 -p --show-function show which function each change is in
542 -p --show-function show which function each change is in
539 --reverse produce a diff that undoes the changes
543 --reverse produce a diff that undoes the changes
540 -w --ignore-all-space ignore white space when comparing lines
544 -w --ignore-all-space ignore white space when comparing lines
541 -b --ignore-space-change ignore changes in the amount of white space
545 -b --ignore-space-change ignore changes in the amount of white space
542 -B --ignore-blank-lines ignore changes whose lines are all blank
546 -B --ignore-blank-lines ignore changes whose lines are all blank
543 -U --unified NUM number of lines of context to show
547 -U --unified NUM number of lines of context to show
544 --stat output diffstat-style summary of changes
548 --stat output diffstat-style summary of changes
545 --root DIR produce diffs relative to subdirectory
549 --root DIR produce diffs relative to subdirectory
546 -I --include PATTERN [+] include names matching the given patterns
550 -I --include PATTERN [+] include names matching the given patterns
547 -X --exclude PATTERN [+] exclude names matching the given patterns
551 -X --exclude PATTERN [+] exclude names matching the given patterns
548 -S --subrepos recurse into subrepositories
552 -S --subrepos recurse into subrepositories
549
553
550 (some details hidden, use --verbose to show complete help)
554 (some details hidden, use --verbose to show complete help)
551
555
552 $ hg help status
556 $ hg help status
553 hg status [OPTION]... [FILE]...
557 hg status [OPTION]... [FILE]...
554
558
555 aliases: st
559 aliases: st
556
560
557 show changed files in the working directory
561 show changed files in the working directory
558
562
559 Show status of files in the repository. If names are given, only files
563 Show status of files in the repository. If names are given, only files
560 that match are shown. Files that are clean or ignored or the source of a
564 that match are shown. Files that are clean or ignored or the source of a
561 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
565 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
562 -C/--copies or -A/--all are given. Unless options described with "show
566 -C/--copies or -A/--all are given. Unless options described with "show
563 only ..." are given, the options -mardu are used.
567 only ..." are given, the options -mardu are used.
564
568
565 Option -q/--quiet hides untracked (unknown and ignored) files unless
569 Option -q/--quiet hides untracked (unknown and ignored) files unless
566 explicitly requested with -u/--unknown or -i/--ignored.
570 explicitly requested with -u/--unknown or -i/--ignored.
567
571
568 Note:
572 Note:
569 'hg status' may appear to disagree with diff if permissions have
573 'hg status' may appear to disagree with diff if permissions have
570 changed or a merge has occurred. The standard diff format does not
574 changed or a merge has occurred. The standard diff format does not
571 report permission changes and diff only reports changes relative to one
575 report permission changes and diff only reports changes relative to one
572 merge parent.
576 merge parent.
573
577
574 If one revision is given, it is used as the base revision. If two
578 If one revision is given, it is used as the base revision. If two
575 revisions are given, the differences between them are shown. The --change
579 revisions are given, the differences between them are shown. The --change
576 option can also be used as a shortcut to list the changed files of a
580 option can also be used as a shortcut to list the changed files of a
577 revision from its first parent.
581 revision from its first parent.
578
582
579 The codes used to show the status of files are:
583 The codes used to show the status of files are:
580
584
581 M = modified
585 M = modified
582 A = added
586 A = added
583 R = removed
587 R = removed
584 C = clean
588 C = clean
585 ! = missing (deleted by non-hg command, but still tracked)
589 ! = missing (deleted by non-hg command, but still tracked)
586 ? = not tracked
590 ? = not tracked
587 I = ignored
591 I = ignored
588 = origin of the previous file (with --copies)
592 = origin of the previous file (with --copies)
589
593
590 Returns 0 on success.
594 Returns 0 on success.
591
595
592 options ([+] can be repeated):
596 options ([+] can be repeated):
593
597
594 -A --all show status of all files
598 -A --all show status of all files
595 -m --modified show only modified files
599 -m --modified show only modified files
596 -a --added show only added files
600 -a --added show only added files
597 -r --removed show only removed files
601 -r --removed show only removed files
598 -d --deleted show only deleted (but tracked) files
602 -d --deleted show only deleted (but tracked) files
599 -c --clean show only files without changes
603 -c --clean show only files without changes
600 -u --unknown show only unknown (not tracked) files
604 -u --unknown show only unknown (not tracked) files
601 -i --ignored show only ignored files
605 -i --ignored show only ignored files
602 -n --no-status hide status prefix
606 -n --no-status hide status prefix
603 -C --copies show source of copied files
607 -C --copies show source of copied files
604 -0 --print0 end filenames with NUL, for use with xargs
608 -0 --print0 end filenames with NUL, for use with xargs
605 --rev REV [+] show difference from revision
609 --rev REV [+] show difference from revision
606 --change REV list the changed files of a revision
610 --change REV list the changed files of a revision
607 -I --include PATTERN [+] include names matching the given patterns
611 -I --include PATTERN [+] include names matching the given patterns
608 -X --exclude PATTERN [+] exclude names matching the given patterns
612 -X --exclude PATTERN [+] exclude names matching the given patterns
609 -S --subrepos recurse into subrepositories
613 -S --subrepos recurse into subrepositories
610
614
611 (some details hidden, use --verbose to show complete help)
615 (some details hidden, use --verbose to show complete help)
612
616
613 $ hg -q help status
617 $ hg -q help status
614 hg status [OPTION]... [FILE]...
618 hg status [OPTION]... [FILE]...
615
619
616 show changed files in the working directory
620 show changed files in the working directory
617
621
618 $ hg help foo
622 $ hg help foo
619 abort: no such help topic: foo
623 abort: no such help topic: foo
620 (try 'hg help --keyword foo')
624 (try 'hg help --keyword foo')
621 [255]
625 [255]
622
626
623 $ hg skjdfks
627 $ hg skjdfks
624 hg: unknown command 'skjdfks'
628 hg: unknown command 'skjdfks'
625 Mercurial Distributed SCM
629 Mercurial Distributed SCM
626
630
627 basic commands:
631 basic commands:
628
632
629 add add the specified files on the next commit
633 add add the specified files on the next commit
630 annotate show changeset information by line for each file
634 annotate show changeset information by line for each file
631 clone make a copy of an existing repository
635 clone make a copy of an existing repository
632 commit commit the specified files or all outstanding changes
636 commit commit the specified files or all outstanding changes
633 diff diff repository (or selected files)
637 diff diff repository (or selected files)
634 export dump the header and diffs for one or more changesets
638 export dump the header and diffs for one or more changesets
635 forget forget the specified files on the next commit
639 forget forget the specified files on the next commit
636 init create a new repository in the given directory
640 init create a new repository in the given directory
637 log show revision history of entire repository or files
641 log show revision history of entire repository or files
638 merge merge another revision into working directory
642 merge merge another revision into working directory
639 pull pull changes from the specified source
643 pull pull changes from the specified source
640 push push changes to the specified destination
644 push push changes to the specified destination
641 remove remove the specified files on the next commit
645 remove remove the specified files on the next commit
642 serve start stand-alone webserver
646 serve start stand-alone webserver
643 status show changed files in the working directory
647 status show changed files in the working directory
644 summary summarize working directory state
648 summary summarize working directory state
645 update update working directory (or switch revisions)
649 update update working directory (or switch revisions)
646
650
647 (use 'hg help' for the full list of commands or 'hg -v' for details)
651 (use 'hg help' for the full list of commands or 'hg -v' for details)
648 [255]
652 [255]
649
653
650
654
651 Make sure that we don't run afoul of the help system thinking that
655 Make sure that we don't run afoul of the help system thinking that
652 this is a section and erroring out weirdly.
656 this is a section and erroring out weirdly.
653
657
654 $ hg .log
658 $ hg .log
655 hg: unknown command '.log'
659 hg: unknown command '.log'
656 (did you mean log?)
660 (did you mean log?)
657 [255]
661 [255]
658
662
659 $ hg log.
663 $ hg log.
660 hg: unknown command 'log.'
664 hg: unknown command 'log.'
661 (did you mean log?)
665 (did you mean log?)
662 [255]
666 [255]
663 $ hg pu.lh
667 $ hg pu.lh
664 hg: unknown command 'pu.lh'
668 hg: unknown command 'pu.lh'
665 (did you mean one of pull, push?)
669 (did you mean one of pull, push?)
666 [255]
670 [255]
667
671
668 $ cat > helpext.py <<EOF
672 $ cat > helpext.py <<EOF
669 > import os
673 > import os
670 > from mercurial import cmdutil, commands
674 > from mercurial import cmdutil, commands
671 >
675 >
672 > cmdtable = {}
676 > cmdtable = {}
673 > command = cmdutil.command(cmdtable)
677 > command = cmdutil.command(cmdtable)
674 >
678 >
675 > @command('nohelp',
679 > @command('nohelp',
676 > [('', 'longdesc', 3, 'x'*90),
680 > [('', 'longdesc', 3, 'x'*90),
677 > ('n', '', None, 'normal desc'),
681 > ('n', '', None, 'normal desc'),
678 > ('', 'newline', '', 'line1\nline2')],
682 > ('', 'newline', '', 'line1\nline2')],
679 > 'hg nohelp',
683 > 'hg nohelp',
680 > norepo=True)
684 > norepo=True)
681 > @command('debugoptDEP', [('', 'dopt', None, 'option is (DEPRECATED)')])
685 > @command('debugoptDEP', [('', 'dopt', None, 'option is (DEPRECATED)')])
682 > @command('debugoptEXP', [('', 'eopt', None, 'option is (EXPERIMENTAL)')])
686 > @command('debugoptEXP', [('', 'eopt', None, 'option is (EXPERIMENTAL)')])
683 > def nohelp(ui, *args, **kwargs):
687 > def nohelp(ui, *args, **kwargs):
684 > pass
688 > pass
685 >
689 >
686 > def uisetup(ui):
690 > def uisetup(ui):
687 > ui.setconfig('alias', 'shellalias', '!echo hi', 'helpext')
691 > ui.setconfig('alias', 'shellalias', '!echo hi', 'helpext')
688 > ui.setconfig('alias', 'hgalias', 'summary', 'helpext')
692 > ui.setconfig('alias', 'hgalias', 'summary', 'helpext')
689 >
693 >
690 > EOF
694 > EOF
691 $ echo '[extensions]' >> $HGRCPATH
695 $ echo '[extensions]' >> $HGRCPATH
692 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
696 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
693
697
694 Test for aliases
698 Test for aliases
695
699
696 $ hg help hgalias
700 $ hg help hgalias
697 hg hgalias [--remote]
701 hg hgalias [--remote]
698
702
699 alias for: hg summary
703 alias for: hg summary
700
704
701 summarize working directory state
705 summarize working directory state
702
706
703 This generates a brief summary of the working directory state, including
707 This generates a brief summary of the working directory state, including
704 parents, branch, commit status, phase and available updates.
708 parents, branch, commit status, phase and available updates.
705
709
706 With the --remote option, this will check the default paths for incoming
710 With the --remote option, this will check the default paths for incoming
707 and outgoing changes. This can be time-consuming.
711 and outgoing changes. This can be time-consuming.
708
712
709 Returns 0 on success.
713 Returns 0 on success.
710
714
711 defined by: helpext
715 defined by: helpext
712
716
713 options:
717 options:
714
718
715 --remote check for push and pull
719 --remote check for push and pull
716
720
717 (some details hidden, use --verbose to show complete help)
721 (some details hidden, use --verbose to show complete help)
718
722
719 $ hg help shellalias
723 $ hg help shellalias
720 hg shellalias
724 hg shellalias
721
725
722 shell alias for:
726 shell alias for:
723
727
724 echo hi
728 echo hi
725
729
726 defined by: helpext
730 defined by: helpext
727
731
728 (some details hidden, use --verbose to show complete help)
732 (some details hidden, use --verbose to show complete help)
729
733
730 Test command with no help text
734 Test command with no help text
731
735
732 $ hg help nohelp
736 $ hg help nohelp
733 hg nohelp
737 hg nohelp
734
738
735 (no help text available)
739 (no help text available)
736
740
737 options:
741 options:
738
742
739 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
743 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
740 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
744 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
741 -n -- normal desc
745 -n -- normal desc
742 --newline VALUE line1 line2
746 --newline VALUE line1 line2
743
747
744 (some details hidden, use --verbose to show complete help)
748 (some details hidden, use --verbose to show complete help)
745
749
746 $ hg help -k nohelp
750 $ hg help -k nohelp
747 Commands:
751 Commands:
748
752
749 nohelp hg nohelp
753 nohelp hg nohelp
750
754
751 Extension Commands:
755 Extension Commands:
752
756
753 nohelp (no help text available)
757 nohelp (no help text available)
754
758
755 Test that default list of commands omits extension commands
759 Test that default list of commands omits extension commands
756
760
757 $ hg help
761 $ hg help
758 Mercurial Distributed SCM
762 Mercurial Distributed SCM
759
763
760 list of commands:
764 list of commands:
761
765
762 add add the specified files on the next commit
766 add add the specified files on the next commit
763 addremove add all new files, delete all missing files
767 addremove add all new files, delete all missing files
764 annotate show changeset information by line for each file
768 annotate show changeset information by line for each file
765 archive create an unversioned archive of a repository revision
769 archive create an unversioned archive of a repository revision
766 backout reverse effect of earlier changeset
770 backout reverse effect of earlier changeset
767 bisect subdivision search of changesets
771 bisect subdivision search of changesets
768 bookmarks create a new bookmark or list existing bookmarks
772 bookmarks create a new bookmark or list existing bookmarks
769 branch set or show the current branch name
773 branch set or show the current branch name
770 branches list repository named branches
774 branches list repository named branches
771 bundle create a changegroup file
775 bundle create a changegroup file
772 cat output the current or given revision of files
776 cat output the current or given revision of files
773 clone make a copy of an existing repository
777 clone make a copy of an existing repository
774 commit commit the specified files or all outstanding changes
778 commit commit the specified files or all outstanding changes
775 config show combined config settings from all hgrc files
779 config show combined config settings from all hgrc files
776 copy mark files as copied for the next commit
780 copy mark files as copied for the next commit
777 diff diff repository (or selected files)
781 diff diff repository (or selected files)
778 export dump the header and diffs for one or more changesets
782 export dump the header and diffs for one or more changesets
779 files list tracked files
783 files list tracked files
780 forget forget the specified files on the next commit
784 forget forget the specified files on the next commit
781 graft copy changes from other branches onto the current branch
785 graft copy changes from other branches onto the current branch
782 grep search revision history for a pattern in specified files
786 grep search revision history for a pattern in specified files
783 heads show branch heads
787 heads show branch heads
784 help show help for a given topic or a help overview
788 help show help for a given topic or a help overview
785 identify identify the working directory or specified revision
789 identify identify the working directory or specified revision
786 import import an ordered set of patches
790 import import an ordered set of patches
787 incoming show new changesets found in source
791 incoming show new changesets found in source
788 init create a new repository in the given directory
792 init create a new repository in the given directory
789 log show revision history of entire repository or files
793 log show revision history of entire repository or files
790 manifest output the current or given revision of the project manifest
794 manifest output the current or given revision of the project manifest
791 merge merge another revision into working directory
795 merge merge another revision into working directory
792 outgoing show changesets not found in the destination
796 outgoing show changesets not found in the destination
793 paths show aliases for remote repositories
797 paths show aliases for remote repositories
794 phase set or show the current phase name
798 phase set or show the current phase name
795 pull pull changes from the specified source
799 pull pull changes from the specified source
796 push push changes to the specified destination
800 push push changes to the specified destination
797 recover roll back an interrupted transaction
801 recover roll back an interrupted transaction
798 remove remove the specified files on the next commit
802 remove remove the specified files on the next commit
799 rename rename files; equivalent of copy + remove
803 rename rename files; equivalent of copy + remove
800 resolve redo merges or set/view the merge status of files
804 resolve redo merges or set/view the merge status of files
801 revert restore files to their checkout state
805 revert restore files to their checkout state
802 root print the root (top) of the current working directory
806 root print the root (top) of the current working directory
803 serve start stand-alone webserver
807 serve start stand-alone webserver
804 status show changed files in the working directory
808 status show changed files in the working directory
805 summary summarize working directory state
809 summary summarize working directory state
806 tag add one or more tags for the current or given revision
810 tag add one or more tags for the current or given revision
807 tags list repository tags
811 tags list repository tags
808 unbundle apply one or more changegroup files
812 unbundle apply one or more changegroup files
809 update update working directory (or switch revisions)
813 update update working directory (or switch revisions)
810 verify verify the integrity of the repository
814 verify verify the integrity of the repository
811 version output version and copyright information
815 version output version and copyright information
812
816
813 enabled extensions:
817 enabled extensions:
814
818
815 helpext (no help text available)
819 helpext (no help text available)
816
820
817 additional help topics:
821 additional help topics:
818
822
819 config Configuration Files
823 config Configuration Files
820 dates Date Formats
824 dates Date Formats
821 diffs Diff Formats
825 diffs Diff Formats
822 environment Environment Variables
826 environment Environment Variables
823 extensions Using Additional Features
827 extensions Using Additional Features
824 filesets Specifying File Sets
828 filesets Specifying File Sets
825 glossary Glossary
829 glossary Glossary
826 hgignore Syntax for Mercurial Ignore Files
830 hgignore Syntax for Mercurial Ignore Files
827 hgweb Configuring hgweb
831 hgweb Configuring hgweb
828 internals Technical implementation topics
832 internals Technical implementation topics
829 merge-tools Merge Tools
833 merge-tools Merge Tools
830 patterns File Name Patterns
834 patterns File Name Patterns
831 phases Working with Phases
835 phases Working with Phases
832 revisions Specifying Revisions
836 revisions Specifying Revisions
833 scripting Using Mercurial from scripts and automation
837 scripting Using Mercurial from scripts and automation
834 subrepos Subrepositories
838 subrepos Subrepositories
835 templating Template Usage
839 templating Template Usage
836 urls URL Paths
840 urls URL Paths
837
841
838 (use 'hg help -v' to show built-in aliases and global options)
842 (use 'hg help -v' to show built-in aliases and global options)
839
843
840
844
841 Test list of internal help commands
845 Test list of internal help commands
842
846
843 $ hg help debug
847 $ hg help debug
844 debug commands (internal and unsupported):
848 debug commands (internal and unsupported):
845
849
846 debugancestor
850 debugancestor
847 find the ancestor revision of two revisions in a given index
851 find the ancestor revision of two revisions in a given index
848 debugapplystreamclonebundle
852 debugapplystreamclonebundle
849 apply a stream clone bundle file
853 apply a stream clone bundle file
850 debugbuilddag
854 debugbuilddag
851 builds a repo with a given DAG from scratch in the current
855 builds a repo with a given DAG from scratch in the current
852 empty repo
856 empty repo
853 debugbundle lists the contents of a bundle
857 debugbundle lists the contents of a bundle
854 debugcheckstate
858 debugcheckstate
855 validate the correctness of the current dirstate
859 validate the correctness of the current dirstate
856 debugcommands
860 debugcommands
857 list all available commands and options
861 list all available commands and options
858 debugcomplete
862 debugcomplete
859 returns the completion list associated with the given command
863 returns the completion list associated with the given command
860 debugcreatestreamclonebundle
864 debugcreatestreamclonebundle
861 create a stream clone bundle file
865 create a stream clone bundle file
862 debugdag format the changelog or an index DAG as a concise textual
866 debugdag format the changelog or an index DAG as a concise textual
863 description
867 description
864 debugdata dump the contents of a data file revision
868 debugdata dump the contents of a data file revision
865 debugdate parse and display a date
869 debugdate parse and display a date
866 debugdeltachain
870 debugdeltachain
867 dump information about delta chains in a revlog
871 dump information about delta chains in a revlog
868 debugdirstate
872 debugdirstate
869 show the contents of the current dirstate
873 show the contents of the current dirstate
870 debugdiscovery
874 debugdiscovery
871 runs the changeset discovery protocol in isolation
875 runs the changeset discovery protocol in isolation
872 debugextensions
876 debugextensions
873 show information about active extensions
877 show information about active extensions
874 debugfileset parse and apply a fileset specification
878 debugfileset parse and apply a fileset specification
875 debugfsinfo show information detected about current filesystem
879 debugfsinfo show information detected about current filesystem
876 debuggetbundle
880 debuggetbundle
877 retrieves a bundle from a repo
881 retrieves a bundle from a repo
878 debugignore display the combined ignore pattern and information about
882 debugignore display the combined ignore pattern and information about
879 ignored files
883 ignored files
880 debugindex dump the contents of an index file
884 debugindex dump the contents of an index file
881 debugindexdot
885 debugindexdot
882 dump an index DAG as a graphviz dot file
886 dump an index DAG as a graphviz dot file
883 debuginstall test Mercurial installation
887 debuginstall test Mercurial installation
884 debugknown test whether node ids are known to a repo
888 debugknown test whether node ids are known to a repo
885 debuglocks show or modify state of locks
889 debuglocks show or modify state of locks
886 debugmergestate
890 debugmergestate
887 print merge state
891 print merge state
888 debugnamecomplete
892 debugnamecomplete
889 complete "names" - tags, open branch names, bookmark names
893 complete "names" - tags, open branch names, bookmark names
890 debugobsolete
894 debugobsolete
891 create arbitrary obsolete marker
895 create arbitrary obsolete marker
892 debugoptDEP (no help text available)
896 debugoptDEP (no help text available)
893 debugoptEXP (no help text available)
897 debugoptEXP (no help text available)
894 debugpathcomplete
898 debugpathcomplete
895 complete part or all of a tracked path
899 complete part or all of a tracked path
896 debugpushkey access the pushkey key/value protocol
900 debugpushkey access the pushkey key/value protocol
897 debugpvec (no help text available)
901 debugpvec (no help text available)
898 debugrebuilddirstate
902 debugrebuilddirstate
899 rebuild the dirstate as it would look like for the given
903 rebuild the dirstate as it would look like for the given
900 revision
904 revision
901 debugrebuildfncache
905 debugrebuildfncache
902 rebuild the fncache file
906 rebuild the fncache file
903 debugrename dump rename information
907 debugrename dump rename information
904 debugrevlog show data and statistics about a revlog
908 debugrevlog show data and statistics about a revlog
905 debugrevspec parse and apply a revision specification
909 debugrevspec parse and apply a revision specification
906 debugsetparents
910 debugsetparents
907 manually set the parents of the current working directory
911 manually set the parents of the current working directory
908 debugsub (no help text available)
912 debugsub (no help text available)
909 debugsuccessorssets
913 debugsuccessorssets
910 show set of successors for revision
914 show set of successors for revision
911 debugtemplate
915 debugtemplate
912 parse and apply a template
916 parse and apply a template
913 debugupgraderepo
917 debugupgraderepo
914 upgrade a repository to use different features
918 upgrade a repository to use different features
915 debugwalk show how files match on given patterns
919 debugwalk show how files match on given patterns
916 debugwireargs
920 debugwireargs
917 (no help text available)
921 (no help text available)
918
922
919 (use 'hg help -v debug' to show built-in aliases and global options)
923 (use 'hg help -v debug' to show built-in aliases and global options)
920
924
921 internals topic renders index of available sub-topics
925 internals topic renders index of available sub-topics
922
926
923 $ hg help internals
927 $ hg help internals
924 Technical implementation topics
928 Technical implementation topics
925 """""""""""""""""""""""""""""""
929 """""""""""""""""""""""""""""""
926
930
927 bundles Bundles
931 bundles Bundles
928 changegroups Changegroups
932 changegroups Changegroups
929 requirements Repository Requirements
933 requirements Repository Requirements
930 revlogs Revision Logs
934 revlogs Revision Logs
931 wireprotocol Wire Protocol
935 wireprotocol Wire Protocol
932
936
933 sub-topics can be accessed
937 sub-topics can be accessed
934
938
935 $ hg help internals.changegroups
939 $ hg help internals.changegroups
936 Changegroups
940 Changegroups
937 """"""""""""
941 """"""""""""
938
942
939 Changegroups are representations of repository revlog data, specifically
943 Changegroups are representations of repository revlog data, specifically
940 the changelog, manifest, and filelogs.
944 the changelog, manifest, and filelogs.
941
945
942 There are 3 versions of changegroups: "1", "2", and "3". From a high-
946 There are 3 versions of changegroups: "1", "2", and "3". From a high-
943 level, versions "1" and "2" are almost exactly the same, with the only
947 level, versions "1" and "2" are almost exactly the same, with the only
944 difference being a header on entries in the changeset segment. Version "3"
948 difference being a header on entries in the changeset segment. Version "3"
945 adds support for exchanging treemanifests and includes revlog flags in the
949 adds support for exchanging treemanifests and includes revlog flags in the
946 delta header.
950 delta header.
947
951
948 Changegroups consists of 3 logical segments:
952 Changegroups consists of 3 logical segments:
949
953
950 +---------------------------------+
954 +---------------------------------+
951 | | | |
955 | | | |
952 | changeset | manifest | filelogs |
956 | changeset | manifest | filelogs |
953 | | | |
957 | | | |
954 +---------------------------------+
958 +---------------------------------+
955
959
956 The principle building block of each segment is a *chunk*. A *chunk* is a
960 The principle building block of each segment is a *chunk*. A *chunk* is a
957 framed piece of data:
961 framed piece of data:
958
962
959 +---------------------------------------+
963 +---------------------------------------+
960 | | |
964 | | |
961 | length | data |
965 | length | data |
962 | (32 bits) | <length> bytes |
966 | (32 bits) | <length> bytes |
963 | | |
967 | | |
964 +---------------------------------------+
968 +---------------------------------------+
965
969
966 Each chunk starts with a 32-bit big-endian signed integer indicating the
970 Each chunk starts with a 32-bit big-endian signed integer indicating the
967 length of the raw data that follows.
971 length of the raw data that follows.
968
972
969 There is a special case chunk that has 0 length ("0x00000000"). We call
973 There is a special case chunk that has 0 length ("0x00000000"). We call
970 this an *empty chunk*.
974 this an *empty chunk*.
971
975
972 Delta Groups
976 Delta Groups
973 ============
977 ============
974
978
975 A *delta group* expresses the content of a revlog as a series of deltas,
979 A *delta group* expresses the content of a revlog as a series of deltas,
976 or patches against previous revisions.
980 or patches against previous revisions.
977
981
978 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
982 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
979 to signal the end of the delta group:
983 to signal the end of the delta group:
980
984
981 +------------------------------------------------------------------------+
985 +------------------------------------------------------------------------+
982 | | | | | |
986 | | | | | |
983 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
987 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
984 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
988 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
985 | | | | | |
989 | | | | | |
986 +------------------------------------------------------------+-----------+
990 +------------------------------------------------------------+-----------+
987
991
988 Each *chunk*'s data consists of the following:
992 Each *chunk*'s data consists of the following:
989
993
990 +-----------------------------------------+
994 +-----------------------------------------+
991 | | | |
995 | | | |
992 | delta header | mdiff header | delta |
996 | delta header | mdiff header | delta |
993 | (various) | (12 bytes) | (various) |
997 | (various) | (12 bytes) | (various) |
994 | | | |
998 | | | |
995 +-----------------------------------------+
999 +-----------------------------------------+
996
1000
997 The *length* field is the byte length of the remaining 3 logical pieces of
1001 The *length* field is the byte length of the remaining 3 logical pieces of
998 data. The *delta* is a diff from an existing entry in the changelog.
1002 data. The *delta* is a diff from an existing entry in the changelog.
999
1003
1000 The *delta header* is different between versions "1", "2", and "3" of the
1004 The *delta header* is different between versions "1", "2", and "3" of the
1001 changegroup format.
1005 changegroup format.
1002
1006
1003 Version 1:
1007 Version 1:
1004
1008
1005 +------------------------------------------------------+
1009 +------------------------------------------------------+
1006 | | | | |
1010 | | | | |
1007 | node | p1 node | p2 node | link node |
1011 | node | p1 node | p2 node | link node |
1008 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1012 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1009 | | | | |
1013 | | | | |
1010 +------------------------------------------------------+
1014 +------------------------------------------------------+
1011
1015
1012 Version 2:
1016 Version 2:
1013
1017
1014 +------------------------------------------------------------------+
1018 +------------------------------------------------------------------+
1015 | | | | | |
1019 | | | | | |
1016 | node | p1 node | p2 node | base node | link node |
1020 | node | p1 node | p2 node | base node | link node |
1017 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1021 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1018 | | | | | |
1022 | | | | | |
1019 +------------------------------------------------------------------+
1023 +------------------------------------------------------------------+
1020
1024
1021 Version 3:
1025 Version 3:
1022
1026
1023 +------------------------------------------------------------------------------+
1027 +------------------------------------------------------------------------------+
1024 | | | | | | |
1028 | | | | | | |
1025 | node | p1 node | p2 node | base node | link node | flags |
1029 | node | p1 node | p2 node | base node | link node | flags |
1026 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1030 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1027 | | | | | | |
1031 | | | | | | |
1028 +------------------------------------------------------------------------------+
1032 +------------------------------------------------------------------------------+
1029
1033
1030 The *mdiff header* consists of 3 32-bit big-endian signed integers
1034 The *mdiff header* consists of 3 32-bit big-endian signed integers
1031 describing offsets at which to apply the following delta content:
1035 describing offsets at which to apply the following delta content:
1032
1036
1033 +-------------------------------------+
1037 +-------------------------------------+
1034 | | | |
1038 | | | |
1035 | offset | old length | new length |
1039 | offset | old length | new length |
1036 | (32 bits) | (32 bits) | (32 bits) |
1040 | (32 bits) | (32 bits) | (32 bits) |
1037 | | | |
1041 | | | |
1038 +-------------------------------------+
1042 +-------------------------------------+
1039
1043
1040 In version 1, the delta is always applied against the previous node from
1044 In version 1, the delta is always applied against the previous node from
1041 the changegroup or the first parent if this is the first entry in the
1045 the changegroup or the first parent if this is the first entry in the
1042 changegroup.
1046 changegroup.
1043
1047
1044 In version 2, the delta base node is encoded in the entry in the
1048 In version 2, the delta base node is encoded in the entry in the
1045 changegroup. This allows the delta to be expressed against any parent,
1049 changegroup. This allows the delta to be expressed against any parent,
1046 which can result in smaller deltas and more efficient encoding of data.
1050 which can result in smaller deltas and more efficient encoding of data.
1047
1051
1048 Changeset Segment
1052 Changeset Segment
1049 =================
1053 =================
1050
1054
1051 The *changeset segment* consists of a single *delta group* holding
1055 The *changeset segment* consists of a single *delta group* holding
1052 changelog data. It is followed by an *empty chunk* to denote the boundary
1056 changelog data. It is followed by an *empty chunk* to denote the boundary
1053 to the *manifests segment*.
1057 to the *manifests segment*.
1054
1058
1055 Manifest Segment
1059 Manifest Segment
1056 ================
1060 ================
1057
1061
1058 The *manifest segment* consists of a single *delta group* holding manifest
1062 The *manifest segment* consists of a single *delta group* holding manifest
1059 data. It is followed by an *empty chunk* to denote the boundary to the
1063 data. It is followed by an *empty chunk* to denote the boundary to the
1060 *filelogs segment*.
1064 *filelogs segment*.
1061
1065
1062 Filelogs Segment
1066 Filelogs Segment
1063 ================
1067 ================
1064
1068
1065 The *filelogs* segment consists of multiple sub-segments, each
1069 The *filelogs* segment consists of multiple sub-segments, each
1066 corresponding to an individual file whose data is being described:
1070 corresponding to an individual file whose data is being described:
1067
1071
1068 +--------------------------------------+
1072 +--------------------------------------+
1069 | | | | |
1073 | | | | |
1070 | filelog0 | filelog1 | filelog2 | ... |
1074 | filelog0 | filelog1 | filelog2 | ... |
1071 | | | | |
1075 | | | | |
1072 +--------------------------------------+
1076 +--------------------------------------+
1073
1077
1074 In version "3" of the changegroup format, filelogs may include directory
1078 In version "3" of the changegroup format, filelogs may include directory
1075 logs when treemanifests are in use. directory logs are identified by
1079 logs when treemanifests are in use. directory logs are identified by
1076 having a trailing '/' on their filename (see below).
1080 having a trailing '/' on their filename (see below).
1077
1081
1078 The final filelog sub-segment is followed by an *empty chunk* to denote
1082 The final filelog sub-segment is followed by an *empty chunk* to denote
1079 the end of the segment and the overall changegroup.
1083 the end of the segment and the overall changegroup.
1080
1084
1081 Each filelog sub-segment consists of the following:
1085 Each filelog sub-segment consists of the following:
1082
1086
1083 +------------------------------------------+
1087 +------------------------------------------+
1084 | | | |
1088 | | | |
1085 | filename size | filename | delta group |
1089 | filename size | filename | delta group |
1086 | (32 bits) | (various) | (various) |
1090 | (32 bits) | (various) | (various) |
1087 | | | |
1091 | | | |
1088 +------------------------------------------+
1092 +------------------------------------------+
1089
1093
1090 That is, a *chunk* consisting of the filename (not terminated or padded)
1094 That is, a *chunk* consisting of the filename (not terminated or padded)
1091 followed by N chunks constituting the *delta group* for this file.
1095 followed by N chunks constituting the *delta group* for this file.
1092
1096
1093 Test list of commands with command with no help text
1097 Test list of commands with command with no help text
1094
1098
1095 $ hg help helpext
1099 $ hg help helpext
1096 helpext extension - no help text available
1100 helpext extension - no help text available
1097
1101
1098 list of commands:
1102 list of commands:
1099
1103
1100 nohelp (no help text available)
1104 nohelp (no help text available)
1101
1105
1102 (use 'hg help -v helpext' to show built-in aliases and global options)
1106 (use 'hg help -v helpext' to show built-in aliases and global options)
1103
1107
1104
1108
1105 test deprecated and experimental options are hidden in command help
1109 test deprecated and experimental options are hidden in command help
1106 $ hg help debugoptDEP
1110 $ hg help debugoptDEP
1107 hg debugoptDEP
1111 hg debugoptDEP
1108
1112
1109 (no help text available)
1113 (no help text available)
1110
1114
1111 options:
1115 options:
1112
1116
1113 (some details hidden, use --verbose to show complete help)
1117 (some details hidden, use --verbose to show complete help)
1114
1118
1115 $ hg help debugoptEXP
1119 $ hg help debugoptEXP
1116 hg debugoptEXP
1120 hg debugoptEXP
1117
1121
1118 (no help text available)
1122 (no help text available)
1119
1123
1120 options:
1124 options:
1121
1125
1122 (some details hidden, use --verbose to show complete help)
1126 (some details hidden, use --verbose to show complete help)
1123
1127
1124 test deprecated and experimental options is shown with -v
1128 test deprecated and experimental options is shown with -v
1125 $ hg help -v debugoptDEP | grep dopt
1129 $ hg help -v debugoptDEP | grep dopt
1126 --dopt option is (DEPRECATED)
1130 --dopt option is (DEPRECATED)
1127 $ hg help -v debugoptEXP | grep eopt
1131 $ hg help -v debugoptEXP | grep eopt
1128 --eopt option is (EXPERIMENTAL)
1132 --eopt option is (EXPERIMENTAL)
1129
1133
1130 #if gettext
1134 #if gettext
1131 test deprecated option is hidden with translation with untranslated description
1135 test deprecated option is hidden with translation with untranslated description
1132 (use many globy for not failing on changed transaction)
1136 (use many globy for not failing on changed transaction)
1133 $ LANGUAGE=sv hg help debugoptDEP
1137 $ LANGUAGE=sv hg help debugoptDEP
1134 hg debugoptDEP
1138 hg debugoptDEP
1135
1139
1136 (*) (glob)
1140 (*) (glob)
1137
1141
1138 options:
1142 options:
1139
1143
1140 (some details hidden, use --verbose to show complete help)
1144 (some details hidden, use --verbose to show complete help)
1141 #endif
1145 #endif
1142
1146
1143 Test commands that collide with topics (issue4240)
1147 Test commands that collide with topics (issue4240)
1144
1148
1145 $ hg config -hq
1149 $ hg config -hq
1146 hg config [-u] [NAME]...
1150 hg config [-u] [NAME]...
1147
1151
1148 show combined config settings from all hgrc files
1152 show combined config settings from all hgrc files
1149 $ hg showconfig -hq
1153 $ hg showconfig -hq
1150 hg config [-u] [NAME]...
1154 hg config [-u] [NAME]...
1151
1155
1152 show combined config settings from all hgrc files
1156 show combined config settings from all hgrc files
1153
1157
1154 Test a help topic
1158 Test a help topic
1155
1159
1156 $ hg help dates
1160 $ hg help dates
1157 Date Formats
1161 Date Formats
1158 """"""""""""
1162 """"""""""""
1159
1163
1160 Some commands allow the user to specify a date, e.g.:
1164 Some commands allow the user to specify a date, e.g.:
1161
1165
1162 - backout, commit, import, tag: Specify the commit date.
1166 - backout, commit, import, tag: Specify the commit date.
1163 - log, revert, update: Select revision(s) by date.
1167 - log, revert, update: Select revision(s) by date.
1164
1168
1165 Many date formats are valid. Here are some examples:
1169 Many date formats are valid. Here are some examples:
1166
1170
1167 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1171 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1168 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1172 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1169 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1173 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1170 - "Dec 6" (midnight)
1174 - "Dec 6" (midnight)
1171 - "13:18" (today assumed)
1175 - "13:18" (today assumed)
1172 - "3:39" (3:39AM assumed)
1176 - "3:39" (3:39AM assumed)
1173 - "3:39pm" (15:39)
1177 - "3:39pm" (15:39)
1174 - "2006-12-06 13:18:29" (ISO 8601 format)
1178 - "2006-12-06 13:18:29" (ISO 8601 format)
1175 - "2006-12-6 13:18"
1179 - "2006-12-6 13:18"
1176 - "2006-12-6"
1180 - "2006-12-6"
1177 - "12-6"
1181 - "12-6"
1178 - "12/6"
1182 - "12/6"
1179 - "12/6/6" (Dec 6 2006)
1183 - "12/6/6" (Dec 6 2006)
1180 - "today" (midnight)
1184 - "today" (midnight)
1181 - "yesterday" (midnight)
1185 - "yesterday" (midnight)
1182 - "now" - right now
1186 - "now" - right now
1183
1187
1184 Lastly, there is Mercurial's internal format:
1188 Lastly, there is Mercurial's internal format:
1185
1189
1186 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1190 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1187
1191
1188 This is the internal representation format for dates. The first number is
1192 This is the internal representation format for dates. The first number is
1189 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1193 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1190 is the offset of the local timezone, in seconds west of UTC (negative if
1194 is the offset of the local timezone, in seconds west of UTC (negative if
1191 the timezone is east of UTC).
1195 the timezone is east of UTC).
1192
1196
1193 The log command also accepts date ranges:
1197 The log command also accepts date ranges:
1194
1198
1195 - "<DATE" - at or before a given date/time
1199 - "<DATE" - at or before a given date/time
1196 - ">DATE" - on or after a given date/time
1200 - ">DATE" - on or after a given date/time
1197 - "DATE to DATE" - a date range, inclusive
1201 - "DATE to DATE" - a date range, inclusive
1198 - "-DAYS" - within a given number of days of today
1202 - "-DAYS" - within a given number of days of today
1199
1203
1200 Test repeated config section name
1204 Test repeated config section name
1201
1205
1202 $ hg help config.host
1206 $ hg help config.host
1203 "http_proxy.host"
1207 "http_proxy.host"
1204 Host name and (optional) port of the proxy server, for example
1208 Host name and (optional) port of the proxy server, for example
1205 "myproxy:8000".
1209 "myproxy:8000".
1206
1210
1207 "smtp.host"
1211 "smtp.host"
1208 Host name of mail server, e.g. "mail.example.com".
1212 Host name of mail server, e.g. "mail.example.com".
1209
1213
1210 Unrelated trailing paragraphs shouldn't be included
1214 Unrelated trailing paragraphs shouldn't be included
1211
1215
1212 $ hg help config.extramsg | grep '^$'
1216 $ hg help config.extramsg | grep '^$'
1213
1217
1214
1218
1215 Test capitalized section name
1219 Test capitalized section name
1216
1220
1217 $ hg help scripting.HGPLAIN > /dev/null
1221 $ hg help scripting.HGPLAIN > /dev/null
1218
1222
1219 Help subsection:
1223 Help subsection:
1220
1224
1221 $ hg help config.charsets |grep "Email example:" > /dev/null
1225 $ hg help config.charsets |grep "Email example:" > /dev/null
1222 [1]
1226 [1]
1223
1227
1224 Show nested definitions
1228 Show nested definitions
1225 ("profiling.type"[break]"ls"[break]"stat"[break])
1229 ("profiling.type"[break]"ls"[break]"stat"[break])
1226
1230
1227 $ hg help config.type | egrep '^$'|wc -l
1231 $ hg help config.type | egrep '^$'|wc -l
1228 \s*3 (re)
1232 \s*3 (re)
1229
1233
1230 Separate sections from subsections
1234 Separate sections from subsections
1231
1235
1232 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1236 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1233 "format"
1237 "format"
1234 --------
1238 --------
1235
1239
1236 "usegeneraldelta"
1240 "usegeneraldelta"
1237
1241
1238 "dotencode"
1242 "dotencode"
1239
1243
1240 "usefncache"
1244 "usefncache"
1241
1245
1242 "usestore"
1246 "usestore"
1243
1247
1244 "profiling"
1248 "profiling"
1245 -----------
1249 -----------
1246
1250
1247 "format"
1251 "format"
1248
1252
1249 "progress"
1253 "progress"
1250 ----------
1254 ----------
1251
1255
1252 "format"
1256 "format"
1253
1257
1254
1258
1255 Last item in help config.*:
1259 Last item in help config.*:
1256
1260
1257 $ hg help config.`hg help config|grep '^ "'| \
1261 $ hg help config.`hg help config|grep '^ "'| \
1258 > tail -1|sed 's![ "]*!!g'`| \
1262 > tail -1|sed 's![ "]*!!g'`| \
1259 > grep 'hg help -c config' > /dev/null
1263 > grep 'hg help -c config' > /dev/null
1260 [1]
1264 [1]
1261
1265
1262 note to use help -c for general hg help config:
1266 note to use help -c for general hg help config:
1263
1267
1264 $ hg help config |grep 'hg help -c config' > /dev/null
1268 $ hg help config |grep 'hg help -c config' > /dev/null
1265
1269
1266 Test templating help
1270 Test templating help
1267
1271
1268 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1272 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1269 desc String. The text of the changeset description.
1273 desc String. The text of the changeset description.
1270 diffstat String. Statistics of changes with the following format:
1274 diffstat String. Statistics of changes with the following format:
1271 firstline Any text. Returns the first line of text.
1275 firstline Any text. Returns the first line of text.
1272 nonempty Any text. Returns '(none)' if the string is empty.
1276 nonempty Any text. Returns '(none)' if the string is empty.
1273
1277
1274 Test deprecated items
1278 Test deprecated items
1275
1279
1276 $ hg help -v templating | grep currentbookmark
1280 $ hg help -v templating | grep currentbookmark
1277 currentbookmark
1281 currentbookmark
1278 $ hg help templating | (grep currentbookmark || true)
1282 $ hg help templating | (grep currentbookmark || true)
1279
1283
1280 Test help hooks
1284 Test help hooks
1281
1285
1282 $ cat > helphook1.py <<EOF
1286 $ cat > helphook1.py <<EOF
1283 > from mercurial import help
1287 > from mercurial import help
1284 >
1288 >
1285 > def rewrite(ui, topic, doc):
1289 > def rewrite(ui, topic, doc):
1286 > return doc + '\nhelphook1\n'
1290 > return doc + '\nhelphook1\n'
1287 >
1291 >
1288 > def extsetup(ui):
1292 > def extsetup(ui):
1289 > help.addtopichook('revisions', rewrite)
1293 > help.addtopichook('revisions', rewrite)
1290 > EOF
1294 > EOF
1291 $ cat > helphook2.py <<EOF
1295 $ cat > helphook2.py <<EOF
1292 > from mercurial import help
1296 > from mercurial import help
1293 >
1297 >
1294 > def rewrite(ui, topic, doc):
1298 > def rewrite(ui, topic, doc):
1295 > return doc + '\nhelphook2\n'
1299 > return doc + '\nhelphook2\n'
1296 >
1300 >
1297 > def extsetup(ui):
1301 > def extsetup(ui):
1298 > help.addtopichook('revisions', rewrite)
1302 > help.addtopichook('revisions', rewrite)
1299 > EOF
1303 > EOF
1300 $ echo '[extensions]' >> $HGRCPATH
1304 $ echo '[extensions]' >> $HGRCPATH
1301 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1305 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1302 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1306 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1303 $ hg help revsets | grep helphook
1307 $ hg help revsets | grep helphook
1304 helphook1
1308 helphook1
1305 helphook2
1309 helphook2
1306
1310
1307 help -c should only show debug --debug
1311 help -c should only show debug --debug
1308
1312
1309 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1313 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1310 [1]
1314 [1]
1311
1315
1312 help -c should only show deprecated for -v
1316 help -c should only show deprecated for -v
1313
1317
1314 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1318 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1315 [1]
1319 [1]
1316
1320
1317 Test -s / --system
1321 Test -s / --system
1318
1322
1319 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1323 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1320 > wc -l | sed -e 's/ //g'
1324 > wc -l | sed -e 's/ //g'
1321 0
1325 0
1322 $ hg help config.files --system unix | grep 'USER' | \
1326 $ hg help config.files --system unix | grep 'USER' | \
1323 > wc -l | sed -e 's/ //g'
1327 > wc -l | sed -e 's/ //g'
1324 0
1328 0
1325
1329
1326 Test -e / -c / -k combinations
1330 Test -e / -c / -k combinations
1327
1331
1328 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1332 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1329 Commands:
1333 Commands:
1330 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1334 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1331 Extensions:
1335 Extensions:
1332 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1336 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1333 Topics:
1337 Topics:
1334 Commands:
1338 Commands:
1335 Extensions:
1339 Extensions:
1336 Extension Commands:
1340 Extension Commands:
1337 $ hg help -c schemes
1341 $ hg help -c schemes
1338 abort: no such help topic: schemes
1342 abort: no such help topic: schemes
1339 (try 'hg help --keyword schemes')
1343 (try 'hg help --keyword schemes')
1340 [255]
1344 [255]
1341 $ hg help -e schemes |head -1
1345 $ hg help -e schemes |head -1
1342 schemes extension - extend schemes with shortcuts to repository swarms
1346 schemes extension - extend schemes with shortcuts to repository swarms
1343 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1347 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1344 Commands:
1348 Commands:
1345 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1349 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1346 Extensions:
1350 Extensions:
1347 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1351 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1348 Extensions:
1352 Extensions:
1349 Commands:
1353 Commands:
1350 $ hg help -c commit > /dev/null
1354 $ hg help -c commit > /dev/null
1351 $ hg help -e -c commit > /dev/null
1355 $ hg help -e -c commit > /dev/null
1352 $ hg help -e commit > /dev/null
1356 $ hg help -e commit > /dev/null
1353 abort: no such help topic: commit
1357 abort: no such help topic: commit
1354 (try 'hg help --keyword commit')
1358 (try 'hg help --keyword commit')
1355 [255]
1359 [255]
1356
1360
1357 Test keyword search help
1361 Test keyword search help
1358
1362
1359 $ cat > prefixedname.py <<EOF
1363 $ cat > prefixedname.py <<EOF
1360 > '''matched against word "clone"
1364 > '''matched against word "clone"
1361 > '''
1365 > '''
1362 > EOF
1366 > EOF
1363 $ echo '[extensions]' >> $HGRCPATH
1367 $ echo '[extensions]' >> $HGRCPATH
1364 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1368 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1365 $ hg help -k clone
1369 $ hg help -k clone
1366 Topics:
1370 Topics:
1367
1371
1368 config Configuration Files
1372 config Configuration Files
1369 extensions Using Additional Features
1373 extensions Using Additional Features
1370 glossary Glossary
1374 glossary Glossary
1371 phases Working with Phases
1375 phases Working with Phases
1372 subrepos Subrepositories
1376 subrepos Subrepositories
1373 urls URL Paths
1377 urls URL Paths
1374
1378
1375 Commands:
1379 Commands:
1376
1380
1377 bookmarks create a new bookmark or list existing bookmarks
1381 bookmarks create a new bookmark or list existing bookmarks
1378 clone make a copy of an existing repository
1382 clone make a copy of an existing repository
1379 paths show aliases for remote repositories
1383 paths show aliases for remote repositories
1380 update update working directory (or switch revisions)
1384 update update working directory (or switch revisions)
1381
1385
1382 Extensions:
1386 Extensions:
1383
1387
1384 clonebundles advertise pre-generated bundles to seed clones
1388 clonebundles advertise pre-generated bundles to seed clones
1385 prefixedname matched against word "clone"
1389 prefixedname matched against word "clone"
1386 relink recreates hardlinks between repository clones
1390 relink recreates hardlinks between repository clones
1387
1391
1388 Extension Commands:
1392 Extension Commands:
1389
1393
1390 qclone clone main and patch repository at same time
1394 qclone clone main and patch repository at same time
1391
1395
1392 Test unfound topic
1396 Test unfound topic
1393
1397
1394 $ hg help nonexistingtopicthatwillneverexisteverever
1398 $ hg help nonexistingtopicthatwillneverexisteverever
1395 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1399 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1396 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1400 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1397 [255]
1401 [255]
1398
1402
1399 Test unfound keyword
1403 Test unfound keyword
1400
1404
1401 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1405 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1402 abort: no matches
1406 abort: no matches
1403 (try 'hg help' for a list of topics)
1407 (try 'hg help' for a list of topics)
1404 [255]
1408 [255]
1405
1409
1406 Test omit indicating for help
1410 Test omit indicating for help
1407
1411
1408 $ cat > addverboseitems.py <<EOF
1412 $ cat > addverboseitems.py <<EOF
1409 > '''extension to test omit indicating.
1413 > '''extension to test omit indicating.
1410 >
1414 >
1411 > This paragraph is never omitted (for extension)
1415 > This paragraph is never omitted (for extension)
1412 >
1416 >
1413 > .. container:: verbose
1417 > .. container:: verbose
1414 >
1418 >
1415 > This paragraph is omitted,
1419 > This paragraph is omitted,
1416 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1420 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1417 >
1421 >
1418 > This paragraph is never omitted, too (for extension)
1422 > This paragraph is never omitted, too (for extension)
1419 > '''
1423 > '''
1420 >
1424 >
1421 > from mercurial import help, commands
1425 > from mercurial import help, commands
1422 > testtopic = """This paragraph is never omitted (for topic).
1426 > testtopic = """This paragraph is never omitted (for topic).
1423 >
1427 >
1424 > .. container:: verbose
1428 > .. container:: verbose
1425 >
1429 >
1426 > This paragraph is omitted,
1430 > This paragraph is omitted,
1427 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1431 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1428 >
1432 >
1429 > This paragraph is never omitted, too (for topic)
1433 > This paragraph is never omitted, too (for topic)
1430 > """
1434 > """
1431 > def extsetup(ui):
1435 > def extsetup(ui):
1432 > help.helptable.append((["topic-containing-verbose"],
1436 > help.helptable.append((["topic-containing-verbose"],
1433 > "This is the topic to test omit indicating.",
1437 > "This is the topic to test omit indicating.",
1434 > lambda ui: testtopic))
1438 > lambda ui: testtopic))
1435 > EOF
1439 > EOF
1436 $ echo '[extensions]' >> $HGRCPATH
1440 $ echo '[extensions]' >> $HGRCPATH
1437 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1441 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1438 $ hg help addverboseitems
1442 $ hg help addverboseitems
1439 addverboseitems extension - extension to test omit indicating.
1443 addverboseitems extension - extension to test omit indicating.
1440
1444
1441 This paragraph is never omitted (for extension)
1445 This paragraph is never omitted (for extension)
1442
1446
1443 This paragraph is never omitted, too (for extension)
1447 This paragraph is never omitted, too (for extension)
1444
1448
1445 (some details hidden, use --verbose to show complete help)
1449 (some details hidden, use --verbose to show complete help)
1446
1450
1447 no commands defined
1451 no commands defined
1448 $ hg help -v addverboseitems
1452 $ hg help -v addverboseitems
1449 addverboseitems extension - extension to test omit indicating.
1453 addverboseitems extension - extension to test omit indicating.
1450
1454
1451 This paragraph is never omitted (for extension)
1455 This paragraph is never omitted (for extension)
1452
1456
1453 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1457 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1454 extension)
1458 extension)
1455
1459
1456 This paragraph is never omitted, too (for extension)
1460 This paragraph is never omitted, too (for extension)
1457
1461
1458 no commands defined
1462 no commands defined
1459 $ hg help topic-containing-verbose
1463 $ hg help topic-containing-verbose
1460 This is the topic to test omit indicating.
1464 This is the topic to test omit indicating.
1461 """"""""""""""""""""""""""""""""""""""""""
1465 """"""""""""""""""""""""""""""""""""""""""
1462
1466
1463 This paragraph is never omitted (for topic).
1467 This paragraph is never omitted (for topic).
1464
1468
1465 This paragraph is never omitted, too (for topic)
1469 This paragraph is never omitted, too (for topic)
1466
1470
1467 (some details hidden, use --verbose to show complete help)
1471 (some details hidden, use --verbose to show complete help)
1468 $ hg help -v topic-containing-verbose
1472 $ hg help -v topic-containing-verbose
1469 This is the topic to test omit indicating.
1473 This is the topic to test omit indicating.
1470 """"""""""""""""""""""""""""""""""""""""""
1474 """"""""""""""""""""""""""""""""""""""""""
1471
1475
1472 This paragraph is never omitted (for topic).
1476 This paragraph is never omitted (for topic).
1473
1477
1474 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1478 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1475 topic)
1479 topic)
1476
1480
1477 This paragraph is never omitted, too (for topic)
1481 This paragraph is never omitted, too (for topic)
1478
1482
1479 Test section lookup
1483 Test section lookup
1480
1484
1481 $ hg help revset.merge
1485 $ hg help revset.merge
1482 "merge()"
1486 "merge()"
1483 Changeset is a merge changeset.
1487 Changeset is a merge changeset.
1484
1488
1485 $ hg help glossary.dag
1489 $ hg help glossary.dag
1486 DAG
1490 DAG
1487 The repository of changesets of a distributed version control system
1491 The repository of changesets of a distributed version control system
1488 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1492 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1489 of nodes and edges, where nodes correspond to changesets and edges
1493 of nodes and edges, where nodes correspond to changesets and edges
1490 imply a parent -> child relation. This graph can be visualized by
1494 imply a parent -> child relation. This graph can be visualized by
1491 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1495 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1492 limited by the requirement for children to have at most two parents.
1496 limited by the requirement for children to have at most two parents.
1493
1497
1494
1498
1495 $ hg help hgrc.paths
1499 $ hg help hgrc.paths
1496 "paths"
1500 "paths"
1497 -------
1501 -------
1498
1502
1499 Assigns symbolic names and behavior to repositories.
1503 Assigns symbolic names and behavior to repositories.
1500
1504
1501 Options are symbolic names defining the URL or directory that is the
1505 Options are symbolic names defining the URL or directory that is the
1502 location of the repository. Example:
1506 location of the repository. Example:
1503
1507
1504 [paths]
1508 [paths]
1505 my_server = https://example.com/my_repo
1509 my_server = https://example.com/my_repo
1506 local_path = /home/me/repo
1510 local_path = /home/me/repo
1507
1511
1508 These symbolic names can be used from the command line. To pull from
1512 These symbolic names can be used from the command line. To pull from
1509 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1513 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1510 local_path'.
1514 local_path'.
1511
1515
1512 Options containing colons (":") denote sub-options that can influence
1516 Options containing colons (":") denote sub-options that can influence
1513 behavior for that specific path. Example:
1517 behavior for that specific path. Example:
1514
1518
1515 [paths]
1519 [paths]
1516 my_server = https://example.com/my_path
1520 my_server = https://example.com/my_path
1517 my_server:pushurl = ssh://example.com/my_path
1521 my_server:pushurl = ssh://example.com/my_path
1518
1522
1519 The following sub-options can be defined:
1523 The following sub-options can be defined:
1520
1524
1521 "pushurl"
1525 "pushurl"
1522 The URL to use for push operations. If not defined, the location
1526 The URL to use for push operations. If not defined, the location
1523 defined by the path's main entry is used.
1527 defined by the path's main entry is used.
1524
1528
1525 "pushrev"
1529 "pushrev"
1526 A revset defining which revisions to push by default.
1530 A revset defining which revisions to push by default.
1527
1531
1528 When 'hg push' is executed without a "-r" argument, the revset defined
1532 When 'hg push' is executed without a "-r" argument, the revset defined
1529 by this sub-option is evaluated to determine what to push.
1533 by this sub-option is evaluated to determine what to push.
1530
1534
1531 For example, a value of "." will push the working directory's revision
1535 For example, a value of "." will push the working directory's revision
1532 by default.
1536 by default.
1533
1537
1534 Revsets specifying bookmarks will not result in the bookmark being
1538 Revsets specifying bookmarks will not result in the bookmark being
1535 pushed.
1539 pushed.
1536
1540
1537 The following special named paths exist:
1541 The following special named paths exist:
1538
1542
1539 "default"
1543 "default"
1540 The URL or directory to use when no source or remote is specified.
1544 The URL or directory to use when no source or remote is specified.
1541
1545
1542 'hg clone' will automatically define this path to the location the
1546 'hg clone' will automatically define this path to the location the
1543 repository was cloned from.
1547 repository was cloned from.
1544
1548
1545 "default-push"
1549 "default-push"
1546 (deprecated) The URL or directory for the default 'hg push' location.
1550 (deprecated) The URL or directory for the default 'hg push' location.
1547 "default:pushurl" should be used instead.
1551 "default:pushurl" should be used instead.
1548
1552
1549 $ hg help glossary.mcguffin
1553 $ hg help glossary.mcguffin
1550 abort: help section not found: glossary.mcguffin
1554 abort: help section not found: glossary.mcguffin
1551 [255]
1555 [255]
1552
1556
1553 $ hg help glossary.mc.guffin
1557 $ hg help glossary.mc.guffin
1554 abort: help section not found: glossary.mc.guffin
1558 abort: help section not found: glossary.mc.guffin
1555 [255]
1559 [255]
1556
1560
1557 $ hg help template.files
1561 $ hg help template.files
1558 files List of strings. All files modified, added, or removed by
1562 files List of strings. All files modified, added, or removed by
1559 this changeset.
1563 this changeset.
1560 files(pattern)
1564 files(pattern)
1561 All files of the current changeset matching the pattern. See
1565 All files of the current changeset matching the pattern. See
1562 'hg help patterns'.
1566 'hg help patterns'.
1563
1567
1564 Test section lookup by translated message
1568 Test section lookup by translated message
1565
1569
1566 str.lower() instead of encoding.lower(str) on translated message might
1570 str.lower() instead of encoding.lower(str) on translated message might
1567 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1571 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1568 as the second or later byte of multi-byte character.
1572 as the second or later byte of multi-byte character.
1569
1573
1570 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1574 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1571 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1575 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1572 replacement makes message meaningless.
1576 replacement makes message meaningless.
1573
1577
1574 This tests that section lookup by translated string isn't broken by
1578 This tests that section lookup by translated string isn't broken by
1575 such str.lower().
1579 such str.lower().
1576
1580
1577 $ python <<EOF
1581 $ python <<EOF
1578 > def escape(s):
1582 > def escape(s):
1579 > return ''.join('\u%x' % ord(uc) for uc in s.decode('cp932'))
1583 > return ''.join('\u%x' % ord(uc) for uc in s.decode('cp932'))
1580 > # translation of "record" in ja_JP.cp932
1584 > # translation of "record" in ja_JP.cp932
1581 > upper = "\x8bL\x98^"
1585 > upper = "\x8bL\x98^"
1582 > # str.lower()-ed section name should be treated as different one
1586 > # str.lower()-ed section name should be treated as different one
1583 > lower = "\x8bl\x98^"
1587 > lower = "\x8bl\x98^"
1584 > with open('ambiguous.py', 'w') as fp:
1588 > with open('ambiguous.py', 'w') as fp:
1585 > fp.write("""# ambiguous section names in ja_JP.cp932
1589 > fp.write("""# ambiguous section names in ja_JP.cp932
1586 > u'''summary of extension
1590 > u'''summary of extension
1587 >
1591 >
1588 > %s
1592 > %s
1589 > ----
1593 > ----
1590 >
1594 >
1591 > Upper name should show only this message
1595 > Upper name should show only this message
1592 >
1596 >
1593 > %s
1597 > %s
1594 > ----
1598 > ----
1595 >
1599 >
1596 > Lower name should show only this message
1600 > Lower name should show only this message
1597 >
1601 >
1598 > subsequent section
1602 > subsequent section
1599 > ------------------
1603 > ------------------
1600 >
1604 >
1601 > This should be hidden at 'hg help ambiguous' with section name.
1605 > This should be hidden at 'hg help ambiguous' with section name.
1602 > '''
1606 > '''
1603 > """ % (escape(upper), escape(lower)))
1607 > """ % (escape(upper), escape(lower)))
1604 > EOF
1608 > EOF
1605
1609
1606 $ cat >> $HGRCPATH <<EOF
1610 $ cat >> $HGRCPATH <<EOF
1607 > [extensions]
1611 > [extensions]
1608 > ambiguous = ./ambiguous.py
1612 > ambiguous = ./ambiguous.py
1609 > EOF
1613 > EOF
1610
1614
1611 $ python <<EOF | sh
1615 $ python <<EOF | sh
1612 > upper = "\x8bL\x98^"
1616 > upper = "\x8bL\x98^"
1613 > print "hg --encoding cp932 help -e ambiguous.%s" % upper
1617 > print "hg --encoding cp932 help -e ambiguous.%s" % upper
1614 > EOF
1618 > EOF
1615 \x8bL\x98^ (esc)
1619 \x8bL\x98^ (esc)
1616 ----
1620 ----
1617
1621
1618 Upper name should show only this message
1622 Upper name should show only this message
1619
1623
1620
1624
1621 $ python <<EOF | sh
1625 $ python <<EOF | sh
1622 > lower = "\x8bl\x98^"
1626 > lower = "\x8bl\x98^"
1623 > print "hg --encoding cp932 help -e ambiguous.%s" % lower
1627 > print "hg --encoding cp932 help -e ambiguous.%s" % lower
1624 > EOF
1628 > EOF
1625 \x8bl\x98^ (esc)
1629 \x8bl\x98^ (esc)
1626 ----
1630 ----
1627
1631
1628 Lower name should show only this message
1632 Lower name should show only this message
1629
1633
1630
1634
1631 $ cat >> $HGRCPATH <<EOF
1635 $ cat >> $HGRCPATH <<EOF
1632 > [extensions]
1636 > [extensions]
1633 > ambiguous = !
1637 > ambiguous = !
1634 > EOF
1638 > EOF
1635
1639
1636 Show help content of disabled extensions
1640 Show help content of disabled extensions
1637
1641
1638 $ cat >> $HGRCPATH <<EOF
1642 $ cat >> $HGRCPATH <<EOF
1639 > [extensions]
1643 > [extensions]
1640 > ambiguous = !./ambiguous.py
1644 > ambiguous = !./ambiguous.py
1641 > EOF
1645 > EOF
1642 $ hg help -e ambiguous
1646 $ hg help -e ambiguous
1643 ambiguous extension - (no help text available)
1647 ambiguous extension - (no help text available)
1644
1648
1645 (use 'hg help extensions' for information on enabling extensions)
1649 (use 'hg help extensions' for information on enabling extensions)
1646
1650
1647 Test dynamic list of merge tools only shows up once
1651 Test dynamic list of merge tools only shows up once
1648 $ hg help merge-tools
1652 $ hg help merge-tools
1649 Merge Tools
1653 Merge Tools
1650 """""""""""
1654 """""""""""
1651
1655
1652 To merge files Mercurial uses merge tools.
1656 To merge files Mercurial uses merge tools.
1653
1657
1654 A merge tool combines two different versions of a file into a merged file.
1658 A merge tool combines two different versions of a file into a merged file.
1655 Merge tools are given the two files and the greatest common ancestor of
1659 Merge tools are given the two files and the greatest common ancestor of
1656 the two file versions, so they can determine the changes made on both
1660 the two file versions, so they can determine the changes made on both
1657 branches.
1661 branches.
1658
1662
1659 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1663 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1660 backout' and in several extensions.
1664 backout' and in several extensions.
1661
1665
1662 Usually, the merge tool tries to automatically reconcile the files by
1666 Usually, the merge tool tries to automatically reconcile the files by
1663 combining all non-overlapping changes that occurred separately in the two
1667 combining all non-overlapping changes that occurred separately in the two
1664 different evolutions of the same initial base file. Furthermore, some
1668 different evolutions of the same initial base file. Furthermore, some
1665 interactive merge programs make it easier to manually resolve conflicting
1669 interactive merge programs make it easier to manually resolve conflicting
1666 merges, either in a graphical way, or by inserting some conflict markers.
1670 merges, either in a graphical way, or by inserting some conflict markers.
1667 Mercurial does not include any interactive merge programs but relies on
1671 Mercurial does not include any interactive merge programs but relies on
1668 external tools for that.
1672 external tools for that.
1669
1673
1670 Available merge tools
1674 Available merge tools
1671 =====================
1675 =====================
1672
1676
1673 External merge tools and their properties are configured in the merge-
1677 External merge tools and their properties are configured in the merge-
1674 tools configuration section - see hgrc(5) - but they can often just be
1678 tools configuration section - see hgrc(5) - but they can often just be
1675 named by their executable.
1679 named by their executable.
1676
1680
1677 A merge tool is generally usable if its executable can be found on the
1681 A merge tool is generally usable if its executable can be found on the
1678 system and if it can handle the merge. The executable is found if it is an
1682 system and if it can handle the merge. The executable is found if it is an
1679 absolute or relative executable path or the name of an application in the
1683 absolute or relative executable path or the name of an application in the
1680 executable search path. The tool is assumed to be able to handle the merge
1684 executable search path. The tool is assumed to be able to handle the merge
1681 if it can handle symlinks if the file is a symlink, if it can handle
1685 if it can handle symlinks if the file is a symlink, if it can handle
1682 binary files if the file is binary, and if a GUI is available if the tool
1686 binary files if the file is binary, and if a GUI is available if the tool
1683 requires a GUI.
1687 requires a GUI.
1684
1688
1685 There are some internal merge tools which can be used. The internal merge
1689 There are some internal merge tools which can be used. The internal merge
1686 tools are:
1690 tools are:
1687
1691
1688 ":dump"
1692 ":dump"
1689 Creates three versions of the files to merge, containing the contents of
1693 Creates three versions of the files to merge, containing the contents of
1690 local, other and base. These files can then be used to perform a merge
1694 local, other and base. These files can then be used to perform a merge
1691 manually. If the file to be merged is named "a.txt", these files will
1695 manually. If the file to be merged is named "a.txt", these files will
1692 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1696 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1693 they will be placed in the same directory as "a.txt".
1697 they will be placed in the same directory as "a.txt".
1694
1698
1695 ":fail"
1699 ":fail"
1696 Rather than attempting to merge files that were modified on both
1700 Rather than attempting to merge files that were modified on both
1697 branches, it marks them as unresolved. The resolve command must be used
1701 branches, it marks them as unresolved. The resolve command must be used
1698 to resolve these conflicts.
1702 to resolve these conflicts.
1699
1703
1700 ":local"
1704 ":local"
1701 Uses the local 'p1()' version of files as the merged version.
1705 Uses the local 'p1()' version of files as the merged version.
1702
1706
1703 ":merge"
1707 ":merge"
1704 Uses the internal non-interactive simple merge algorithm for merging
1708 Uses the internal non-interactive simple merge algorithm for merging
1705 files. It will fail if there are any conflicts and leave markers in the
1709 files. It will fail if there are any conflicts and leave markers in the
1706 partially merged file. Markers will have two sections, one for each side
1710 partially merged file. Markers will have two sections, one for each side
1707 of merge.
1711 of merge.
1708
1712
1709 ":merge-local"
1713 ":merge-local"
1710 Like :merge, but resolve all conflicts non-interactively in favor of the
1714 Like :merge, but resolve all conflicts non-interactively in favor of the
1711 local 'p1()' changes.
1715 local 'p1()' changes.
1712
1716
1713 ":merge-other"
1717 ":merge-other"
1714 Like :merge, but resolve all conflicts non-interactively in favor of the
1718 Like :merge, but resolve all conflicts non-interactively in favor of the
1715 other 'p2()' changes.
1719 other 'p2()' changes.
1716
1720
1717 ":merge3"
1721 ":merge3"
1718 Uses the internal non-interactive simple merge algorithm for merging
1722 Uses the internal non-interactive simple merge algorithm for merging
1719 files. It will fail if there are any conflicts and leave markers in the
1723 files. It will fail if there are any conflicts and leave markers in the
1720 partially merged file. Marker will have three sections, one from each
1724 partially merged file. Marker will have three sections, one from each
1721 side of the merge and one for the base content.
1725 side of the merge and one for the base content.
1722
1726
1723 ":other"
1727 ":other"
1724 Uses the other 'p2()' version of files as the merged version.
1728 Uses the other 'p2()' version of files as the merged version.
1725
1729
1726 ":prompt"
1730 ":prompt"
1727 Asks the user which of the local 'p1()' or the other 'p2()' version to
1731 Asks the user which of the local 'p1()' or the other 'p2()' version to
1728 keep as the merged version.
1732 keep as the merged version.
1729
1733
1730 ":tagmerge"
1734 ":tagmerge"
1731 Uses the internal tag merge algorithm (experimental).
1735 Uses the internal tag merge algorithm (experimental).
1732
1736
1733 ":union"
1737 ":union"
1734 Uses the internal non-interactive simple merge algorithm for merging
1738 Uses the internal non-interactive simple merge algorithm for merging
1735 files. It will use both left and right sides for conflict regions. No
1739 files. It will use both left and right sides for conflict regions. No
1736 markers are inserted.
1740 markers are inserted.
1737
1741
1738 Internal tools are always available and do not require a GUI but will by
1742 Internal tools are always available and do not require a GUI but will by
1739 default not handle symlinks or binary files.
1743 default not handle symlinks or binary files.
1740
1744
1741 Choosing a merge tool
1745 Choosing a merge tool
1742 =====================
1746 =====================
1743
1747
1744 Mercurial uses these rules when deciding which merge tool to use:
1748 Mercurial uses these rules when deciding which merge tool to use:
1745
1749
1746 1. If a tool has been specified with the --tool option to merge or
1750 1. If a tool has been specified with the --tool option to merge or
1747 resolve, it is used. If it is the name of a tool in the merge-tools
1751 resolve, it is used. If it is the name of a tool in the merge-tools
1748 configuration, its configuration is used. Otherwise the specified tool
1752 configuration, its configuration is used. Otherwise the specified tool
1749 must be executable by the shell.
1753 must be executable by the shell.
1750 2. If the "HGMERGE" environment variable is present, its value is used and
1754 2. If the "HGMERGE" environment variable is present, its value is used and
1751 must be executable by the shell.
1755 must be executable by the shell.
1752 3. If the filename of the file to be merged matches any of the patterns in
1756 3. If the filename of the file to be merged matches any of the patterns in
1753 the merge-patterns configuration section, the first usable merge tool
1757 the merge-patterns configuration section, the first usable merge tool
1754 corresponding to a matching pattern is used. Here, binary capabilities
1758 corresponding to a matching pattern is used. Here, binary capabilities
1755 of the merge tool are not considered.
1759 of the merge tool are not considered.
1756 4. If ui.merge is set it will be considered next. If the value is not the
1760 4. If ui.merge is set it will be considered next. If the value is not the
1757 name of a configured tool, the specified value is used and must be
1761 name of a configured tool, the specified value is used and must be
1758 executable by the shell. Otherwise the named tool is used if it is
1762 executable by the shell. Otherwise the named tool is used if it is
1759 usable.
1763 usable.
1760 5. If any usable merge tools are present in the merge-tools configuration
1764 5. If any usable merge tools are present in the merge-tools configuration
1761 section, the one with the highest priority is used.
1765 section, the one with the highest priority is used.
1762 6. If a program named "hgmerge" can be found on the system, it is used -
1766 6. If a program named "hgmerge" can be found on the system, it is used -
1763 but it will by default not be used for symlinks and binary files.
1767 but it will by default not be used for symlinks and binary files.
1764 7. If the file to be merged is not binary and is not a symlink, then
1768 7. If the file to be merged is not binary and is not a symlink, then
1765 internal ":merge" is used.
1769 internal ":merge" is used.
1766 8. The merge of the file fails and must be resolved before commit.
1770 8. The merge of the file fails and must be resolved before commit.
1767
1771
1768 Note:
1772 Note:
1769 After selecting a merge program, Mercurial will by default attempt to
1773 After selecting a merge program, Mercurial will by default attempt to
1770 merge the files using a simple merge algorithm first. Only if it
1774 merge the files using a simple merge algorithm first. Only if it
1771 doesn't succeed because of conflicting changes Mercurial will actually
1775 doesn't succeed because of conflicting changes Mercurial will actually
1772 execute the merge program. Whether to use the simple merge algorithm
1776 execute the merge program. Whether to use the simple merge algorithm
1773 first can be controlled by the premerge setting of the merge tool.
1777 first can be controlled by the premerge setting of the merge tool.
1774 Premerge is enabled by default unless the file is binary or a symlink.
1778 Premerge is enabled by default unless the file is binary or a symlink.
1775
1779
1776 See the merge-tools and ui sections of hgrc(5) for details on the
1780 See the merge-tools and ui sections of hgrc(5) for details on the
1777 configuration of merge tools.
1781 configuration of merge tools.
1778
1782
1779 Test usage of section marks in help documents
1783 Test usage of section marks in help documents
1780
1784
1781 $ cd "$TESTDIR"/../doc
1785 $ cd "$TESTDIR"/../doc
1782 $ python check-seclevel.py
1786 $ python check-seclevel.py
1783 $ cd $TESTTMP
1787 $ cd $TESTTMP
1784
1788
1785 #if serve
1789 #if serve
1786
1790
1787 Test the help pages in hgweb.
1791 Test the help pages in hgweb.
1788
1792
1789 Dish up an empty repo; serve it cold.
1793 Dish up an empty repo; serve it cold.
1790
1794
1791 $ hg init "$TESTTMP/test"
1795 $ hg init "$TESTTMP/test"
1792 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
1796 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
1793 $ cat hg.pid >> $DAEMON_PIDS
1797 $ cat hg.pid >> $DAEMON_PIDS
1794
1798
1795 $ get-with-headers.py 127.0.0.1:$HGPORT "help"
1799 $ get-with-headers.py 127.0.0.1:$HGPORT "help"
1796 200 Script output follows
1800 200 Script output follows
1797
1801
1798 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1802 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1799 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1803 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1800 <head>
1804 <head>
1801 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1805 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1802 <meta name="robots" content="index, nofollow" />
1806 <meta name="robots" content="index, nofollow" />
1803 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1807 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1804 <script type="text/javascript" src="/static/mercurial.js"></script>
1808 <script type="text/javascript" src="/static/mercurial.js"></script>
1805
1809
1806 <title>Help: Index</title>
1810 <title>Help: Index</title>
1807 </head>
1811 </head>
1808 <body>
1812 <body>
1809
1813
1810 <div class="container">
1814 <div class="container">
1811 <div class="menu">
1815 <div class="menu">
1812 <div class="logo">
1816 <div class="logo">
1813 <a href="https://mercurial-scm.org/">
1817 <a href="https://mercurial-scm.org/">
1814 <img src="/static/hglogo.png" alt="mercurial" /></a>
1818 <img src="/static/hglogo.png" alt="mercurial" /></a>
1815 </div>
1819 </div>
1816 <ul>
1820 <ul>
1817 <li><a href="/shortlog">log</a></li>
1821 <li><a href="/shortlog">log</a></li>
1818 <li><a href="/graph">graph</a></li>
1822 <li><a href="/graph">graph</a></li>
1819 <li><a href="/tags">tags</a></li>
1823 <li><a href="/tags">tags</a></li>
1820 <li><a href="/bookmarks">bookmarks</a></li>
1824 <li><a href="/bookmarks">bookmarks</a></li>
1821 <li><a href="/branches">branches</a></li>
1825 <li><a href="/branches">branches</a></li>
1822 </ul>
1826 </ul>
1823 <ul>
1827 <ul>
1824 <li class="active">help</li>
1828 <li class="active">help</li>
1825 </ul>
1829 </ul>
1826 </div>
1830 </div>
1827
1831
1828 <div class="main">
1832 <div class="main">
1829 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1833 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1830 <form class="search" action="/log">
1834 <form class="search" action="/log">
1831
1835
1832 <p><input name="rev" id="search1" type="text" size="30" /></p>
1836 <p><input name="rev" id="search1" type="text" size="30" /></p>
1833 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1837 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1834 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1838 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1835 </form>
1839 </form>
1836 <table class="bigtable">
1840 <table class="bigtable">
1837 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
1841 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
1838
1842
1839 <tr><td>
1843 <tr><td>
1840 <a href="/help/config">
1844 <a href="/help/config">
1841 config
1845 config
1842 </a>
1846 </a>
1843 </td><td>
1847 </td><td>
1844 Configuration Files
1848 Configuration Files
1845 </td></tr>
1849 </td></tr>
1846 <tr><td>
1850 <tr><td>
1847 <a href="/help/dates">
1851 <a href="/help/dates">
1848 dates
1852 dates
1849 </a>
1853 </a>
1850 </td><td>
1854 </td><td>
1851 Date Formats
1855 Date Formats
1852 </td></tr>
1856 </td></tr>
1853 <tr><td>
1857 <tr><td>
1854 <a href="/help/diffs">
1858 <a href="/help/diffs">
1855 diffs
1859 diffs
1856 </a>
1860 </a>
1857 </td><td>
1861 </td><td>
1858 Diff Formats
1862 Diff Formats
1859 </td></tr>
1863 </td></tr>
1860 <tr><td>
1864 <tr><td>
1861 <a href="/help/environment">
1865 <a href="/help/environment">
1862 environment
1866 environment
1863 </a>
1867 </a>
1864 </td><td>
1868 </td><td>
1865 Environment Variables
1869 Environment Variables
1866 </td></tr>
1870 </td></tr>
1867 <tr><td>
1871 <tr><td>
1868 <a href="/help/extensions">
1872 <a href="/help/extensions">
1869 extensions
1873 extensions
1870 </a>
1874 </a>
1871 </td><td>
1875 </td><td>
1872 Using Additional Features
1876 Using Additional Features
1873 </td></tr>
1877 </td></tr>
1874 <tr><td>
1878 <tr><td>
1875 <a href="/help/filesets">
1879 <a href="/help/filesets">
1876 filesets
1880 filesets
1877 </a>
1881 </a>
1878 </td><td>
1882 </td><td>
1879 Specifying File Sets
1883 Specifying File Sets
1880 </td></tr>
1884 </td></tr>
1881 <tr><td>
1885 <tr><td>
1882 <a href="/help/glossary">
1886 <a href="/help/glossary">
1883 glossary
1887 glossary
1884 </a>
1888 </a>
1885 </td><td>
1889 </td><td>
1886 Glossary
1890 Glossary
1887 </td></tr>
1891 </td></tr>
1888 <tr><td>
1892 <tr><td>
1889 <a href="/help/hgignore">
1893 <a href="/help/hgignore">
1890 hgignore
1894 hgignore
1891 </a>
1895 </a>
1892 </td><td>
1896 </td><td>
1893 Syntax for Mercurial Ignore Files
1897 Syntax for Mercurial Ignore Files
1894 </td></tr>
1898 </td></tr>
1895 <tr><td>
1899 <tr><td>
1896 <a href="/help/hgweb">
1900 <a href="/help/hgweb">
1897 hgweb
1901 hgweb
1898 </a>
1902 </a>
1899 </td><td>
1903 </td><td>
1900 Configuring hgweb
1904 Configuring hgweb
1901 </td></tr>
1905 </td></tr>
1902 <tr><td>
1906 <tr><td>
1903 <a href="/help/internals">
1907 <a href="/help/internals">
1904 internals
1908 internals
1905 </a>
1909 </a>
1906 </td><td>
1910 </td><td>
1907 Technical implementation topics
1911 Technical implementation topics
1908 </td></tr>
1912 </td></tr>
1909 <tr><td>
1913 <tr><td>
1910 <a href="/help/merge-tools">
1914 <a href="/help/merge-tools">
1911 merge-tools
1915 merge-tools
1912 </a>
1916 </a>
1913 </td><td>
1917 </td><td>
1914 Merge Tools
1918 Merge Tools
1915 </td></tr>
1919 </td></tr>
1916 <tr><td>
1920 <tr><td>
1917 <a href="/help/patterns">
1921 <a href="/help/patterns">
1918 patterns
1922 patterns
1919 </a>
1923 </a>
1920 </td><td>
1924 </td><td>
1921 File Name Patterns
1925 File Name Patterns
1922 </td></tr>
1926 </td></tr>
1923 <tr><td>
1927 <tr><td>
1924 <a href="/help/phases">
1928 <a href="/help/phases">
1925 phases
1929 phases
1926 </a>
1930 </a>
1927 </td><td>
1931 </td><td>
1928 Working with Phases
1932 Working with Phases
1929 </td></tr>
1933 </td></tr>
1930 <tr><td>
1934 <tr><td>
1931 <a href="/help/revisions">
1935 <a href="/help/revisions">
1932 revisions
1936 revisions
1933 </a>
1937 </a>
1934 </td><td>
1938 </td><td>
1935 Specifying Revisions
1939 Specifying Revisions
1936 </td></tr>
1940 </td></tr>
1937 <tr><td>
1941 <tr><td>
1938 <a href="/help/scripting">
1942 <a href="/help/scripting">
1939 scripting
1943 scripting
1940 </a>
1944 </a>
1941 </td><td>
1945 </td><td>
1942 Using Mercurial from scripts and automation
1946 Using Mercurial from scripts and automation
1943 </td></tr>
1947 </td></tr>
1944 <tr><td>
1948 <tr><td>
1945 <a href="/help/subrepos">
1949 <a href="/help/subrepos">
1946 subrepos
1950 subrepos
1947 </a>
1951 </a>
1948 </td><td>
1952 </td><td>
1949 Subrepositories
1953 Subrepositories
1950 </td></tr>
1954 </td></tr>
1951 <tr><td>
1955 <tr><td>
1952 <a href="/help/templating">
1956 <a href="/help/templating">
1953 templating
1957 templating
1954 </a>
1958 </a>
1955 </td><td>
1959 </td><td>
1956 Template Usage
1960 Template Usage
1957 </td></tr>
1961 </td></tr>
1958 <tr><td>
1962 <tr><td>
1959 <a href="/help/urls">
1963 <a href="/help/urls">
1960 urls
1964 urls
1961 </a>
1965 </a>
1962 </td><td>
1966 </td><td>
1963 URL Paths
1967 URL Paths
1964 </td></tr>
1968 </td></tr>
1965 <tr><td>
1969 <tr><td>
1966 <a href="/help/topic-containing-verbose">
1970 <a href="/help/topic-containing-verbose">
1967 topic-containing-verbose
1971 topic-containing-verbose
1968 </a>
1972 </a>
1969 </td><td>
1973 </td><td>
1970 This is the topic to test omit indicating.
1974 This is the topic to test omit indicating.
1971 </td></tr>
1975 </td></tr>
1972
1976
1973
1977
1974 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1978 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1975
1979
1976 <tr><td>
1980 <tr><td>
1977 <a href="/help/add">
1981 <a href="/help/add">
1978 add
1982 add
1979 </a>
1983 </a>
1980 </td><td>
1984 </td><td>
1981 add the specified files on the next commit
1985 add the specified files on the next commit
1982 </td></tr>
1986 </td></tr>
1983 <tr><td>
1987 <tr><td>
1984 <a href="/help/annotate">
1988 <a href="/help/annotate">
1985 annotate
1989 annotate
1986 </a>
1990 </a>
1987 </td><td>
1991 </td><td>
1988 show changeset information by line for each file
1992 show changeset information by line for each file
1989 </td></tr>
1993 </td></tr>
1990 <tr><td>
1994 <tr><td>
1991 <a href="/help/clone">
1995 <a href="/help/clone">
1992 clone
1996 clone
1993 </a>
1997 </a>
1994 </td><td>
1998 </td><td>
1995 make a copy of an existing repository
1999 make a copy of an existing repository
1996 </td></tr>
2000 </td></tr>
1997 <tr><td>
2001 <tr><td>
1998 <a href="/help/commit">
2002 <a href="/help/commit">
1999 commit
2003 commit
2000 </a>
2004 </a>
2001 </td><td>
2005 </td><td>
2002 commit the specified files or all outstanding changes
2006 commit the specified files or all outstanding changes
2003 </td></tr>
2007 </td></tr>
2004 <tr><td>
2008 <tr><td>
2005 <a href="/help/diff">
2009 <a href="/help/diff">
2006 diff
2010 diff
2007 </a>
2011 </a>
2008 </td><td>
2012 </td><td>
2009 diff repository (or selected files)
2013 diff repository (or selected files)
2010 </td></tr>
2014 </td></tr>
2011 <tr><td>
2015 <tr><td>
2012 <a href="/help/export">
2016 <a href="/help/export">
2013 export
2017 export
2014 </a>
2018 </a>
2015 </td><td>
2019 </td><td>
2016 dump the header and diffs for one or more changesets
2020 dump the header and diffs for one or more changesets
2017 </td></tr>
2021 </td></tr>
2018 <tr><td>
2022 <tr><td>
2019 <a href="/help/forget">
2023 <a href="/help/forget">
2020 forget
2024 forget
2021 </a>
2025 </a>
2022 </td><td>
2026 </td><td>
2023 forget the specified files on the next commit
2027 forget the specified files on the next commit
2024 </td></tr>
2028 </td></tr>
2025 <tr><td>
2029 <tr><td>
2026 <a href="/help/init">
2030 <a href="/help/init">
2027 init
2031 init
2028 </a>
2032 </a>
2029 </td><td>
2033 </td><td>
2030 create a new repository in the given directory
2034 create a new repository in the given directory
2031 </td></tr>
2035 </td></tr>
2032 <tr><td>
2036 <tr><td>
2033 <a href="/help/log">
2037 <a href="/help/log">
2034 log
2038 log
2035 </a>
2039 </a>
2036 </td><td>
2040 </td><td>
2037 show revision history of entire repository or files
2041 show revision history of entire repository or files
2038 </td></tr>
2042 </td></tr>
2039 <tr><td>
2043 <tr><td>
2040 <a href="/help/merge">
2044 <a href="/help/merge">
2041 merge
2045 merge
2042 </a>
2046 </a>
2043 </td><td>
2047 </td><td>
2044 merge another revision into working directory
2048 merge another revision into working directory
2045 </td></tr>
2049 </td></tr>
2046 <tr><td>
2050 <tr><td>
2047 <a href="/help/pull">
2051 <a href="/help/pull">
2048 pull
2052 pull
2049 </a>
2053 </a>
2050 </td><td>
2054 </td><td>
2051 pull changes from the specified source
2055 pull changes from the specified source
2052 </td></tr>
2056 </td></tr>
2053 <tr><td>
2057 <tr><td>
2054 <a href="/help/push">
2058 <a href="/help/push">
2055 push
2059 push
2056 </a>
2060 </a>
2057 </td><td>
2061 </td><td>
2058 push changes to the specified destination
2062 push changes to the specified destination
2059 </td></tr>
2063 </td></tr>
2060 <tr><td>
2064 <tr><td>
2061 <a href="/help/remove">
2065 <a href="/help/remove">
2062 remove
2066 remove
2063 </a>
2067 </a>
2064 </td><td>
2068 </td><td>
2065 remove the specified files on the next commit
2069 remove the specified files on the next commit
2066 </td></tr>
2070 </td></tr>
2067 <tr><td>
2071 <tr><td>
2068 <a href="/help/serve">
2072 <a href="/help/serve">
2069 serve
2073 serve
2070 </a>
2074 </a>
2071 </td><td>
2075 </td><td>
2072 start stand-alone webserver
2076 start stand-alone webserver
2073 </td></tr>
2077 </td></tr>
2074 <tr><td>
2078 <tr><td>
2075 <a href="/help/status">
2079 <a href="/help/status">
2076 status
2080 status
2077 </a>
2081 </a>
2078 </td><td>
2082 </td><td>
2079 show changed files in the working directory
2083 show changed files in the working directory
2080 </td></tr>
2084 </td></tr>
2081 <tr><td>
2085 <tr><td>
2082 <a href="/help/summary">
2086 <a href="/help/summary">
2083 summary
2087 summary
2084 </a>
2088 </a>
2085 </td><td>
2089 </td><td>
2086 summarize working directory state
2090 summarize working directory state
2087 </td></tr>
2091 </td></tr>
2088 <tr><td>
2092 <tr><td>
2089 <a href="/help/update">
2093 <a href="/help/update">
2090 update
2094 update
2091 </a>
2095 </a>
2092 </td><td>
2096 </td><td>
2093 update working directory (or switch revisions)
2097 update working directory (or switch revisions)
2094 </td></tr>
2098 </td></tr>
2095
2099
2096
2100
2097
2101
2098 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2102 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2099
2103
2100 <tr><td>
2104 <tr><td>
2101 <a href="/help/addremove">
2105 <a href="/help/addremove">
2102 addremove
2106 addremove
2103 </a>
2107 </a>
2104 </td><td>
2108 </td><td>
2105 add all new files, delete all missing files
2109 add all new files, delete all missing files
2106 </td></tr>
2110 </td></tr>
2107 <tr><td>
2111 <tr><td>
2108 <a href="/help/archive">
2112 <a href="/help/archive">
2109 archive
2113 archive
2110 </a>
2114 </a>
2111 </td><td>
2115 </td><td>
2112 create an unversioned archive of a repository revision
2116 create an unversioned archive of a repository revision
2113 </td></tr>
2117 </td></tr>
2114 <tr><td>
2118 <tr><td>
2115 <a href="/help/backout">
2119 <a href="/help/backout">
2116 backout
2120 backout
2117 </a>
2121 </a>
2118 </td><td>
2122 </td><td>
2119 reverse effect of earlier changeset
2123 reverse effect of earlier changeset
2120 </td></tr>
2124 </td></tr>
2121 <tr><td>
2125 <tr><td>
2122 <a href="/help/bisect">
2126 <a href="/help/bisect">
2123 bisect
2127 bisect
2124 </a>
2128 </a>
2125 </td><td>
2129 </td><td>
2126 subdivision search of changesets
2130 subdivision search of changesets
2127 </td></tr>
2131 </td></tr>
2128 <tr><td>
2132 <tr><td>
2129 <a href="/help/bookmarks">
2133 <a href="/help/bookmarks">
2130 bookmarks
2134 bookmarks
2131 </a>
2135 </a>
2132 </td><td>
2136 </td><td>
2133 create a new bookmark or list existing bookmarks
2137 create a new bookmark or list existing bookmarks
2134 </td></tr>
2138 </td></tr>
2135 <tr><td>
2139 <tr><td>
2136 <a href="/help/branch">
2140 <a href="/help/branch">
2137 branch
2141 branch
2138 </a>
2142 </a>
2139 </td><td>
2143 </td><td>
2140 set or show the current branch name
2144 set or show the current branch name
2141 </td></tr>
2145 </td></tr>
2142 <tr><td>
2146 <tr><td>
2143 <a href="/help/branches">
2147 <a href="/help/branches">
2144 branches
2148 branches
2145 </a>
2149 </a>
2146 </td><td>
2150 </td><td>
2147 list repository named branches
2151 list repository named branches
2148 </td></tr>
2152 </td></tr>
2149 <tr><td>
2153 <tr><td>
2150 <a href="/help/bundle">
2154 <a href="/help/bundle">
2151 bundle
2155 bundle
2152 </a>
2156 </a>
2153 </td><td>
2157 </td><td>
2154 create a changegroup file
2158 create a changegroup file
2155 </td></tr>
2159 </td></tr>
2156 <tr><td>
2160 <tr><td>
2157 <a href="/help/cat">
2161 <a href="/help/cat">
2158 cat
2162 cat
2159 </a>
2163 </a>
2160 </td><td>
2164 </td><td>
2161 output the current or given revision of files
2165 output the current or given revision of files
2162 </td></tr>
2166 </td></tr>
2163 <tr><td>
2167 <tr><td>
2164 <a href="/help/config">
2168 <a href="/help/config">
2165 config
2169 config
2166 </a>
2170 </a>
2167 </td><td>
2171 </td><td>
2168 show combined config settings from all hgrc files
2172 show combined config settings from all hgrc files
2169 </td></tr>
2173 </td></tr>
2170 <tr><td>
2174 <tr><td>
2171 <a href="/help/copy">
2175 <a href="/help/copy">
2172 copy
2176 copy
2173 </a>
2177 </a>
2174 </td><td>
2178 </td><td>
2175 mark files as copied for the next commit
2179 mark files as copied for the next commit
2176 </td></tr>
2180 </td></tr>
2177 <tr><td>
2181 <tr><td>
2178 <a href="/help/files">
2182 <a href="/help/files">
2179 files
2183 files
2180 </a>
2184 </a>
2181 </td><td>
2185 </td><td>
2182 list tracked files
2186 list tracked files
2183 </td></tr>
2187 </td></tr>
2184 <tr><td>
2188 <tr><td>
2185 <a href="/help/graft">
2189 <a href="/help/graft">
2186 graft
2190 graft
2187 </a>
2191 </a>
2188 </td><td>
2192 </td><td>
2189 copy changes from other branches onto the current branch
2193 copy changes from other branches onto the current branch
2190 </td></tr>
2194 </td></tr>
2191 <tr><td>
2195 <tr><td>
2192 <a href="/help/grep">
2196 <a href="/help/grep">
2193 grep
2197 grep
2194 </a>
2198 </a>
2195 </td><td>
2199 </td><td>
2196 search revision history for a pattern in specified files
2200 search revision history for a pattern in specified files
2197 </td></tr>
2201 </td></tr>
2198 <tr><td>
2202 <tr><td>
2199 <a href="/help/heads">
2203 <a href="/help/heads">
2200 heads
2204 heads
2201 </a>
2205 </a>
2202 </td><td>
2206 </td><td>
2203 show branch heads
2207 show branch heads
2204 </td></tr>
2208 </td></tr>
2205 <tr><td>
2209 <tr><td>
2206 <a href="/help/help">
2210 <a href="/help/help">
2207 help
2211 help
2208 </a>
2212 </a>
2209 </td><td>
2213 </td><td>
2210 show help for a given topic or a help overview
2214 show help for a given topic or a help overview
2211 </td></tr>
2215 </td></tr>
2212 <tr><td>
2216 <tr><td>
2213 <a href="/help/hgalias">
2217 <a href="/help/hgalias">
2214 hgalias
2218 hgalias
2215 </a>
2219 </a>
2216 </td><td>
2220 </td><td>
2217 summarize working directory state
2221 summarize working directory state
2218 </td></tr>
2222 </td></tr>
2219 <tr><td>
2223 <tr><td>
2220 <a href="/help/identify">
2224 <a href="/help/identify">
2221 identify
2225 identify
2222 </a>
2226 </a>
2223 </td><td>
2227 </td><td>
2224 identify the working directory or specified revision
2228 identify the working directory or specified revision
2225 </td></tr>
2229 </td></tr>
2226 <tr><td>
2230 <tr><td>
2227 <a href="/help/import">
2231 <a href="/help/import">
2228 import
2232 import
2229 </a>
2233 </a>
2230 </td><td>
2234 </td><td>
2231 import an ordered set of patches
2235 import an ordered set of patches
2232 </td></tr>
2236 </td></tr>
2233 <tr><td>
2237 <tr><td>
2234 <a href="/help/incoming">
2238 <a href="/help/incoming">
2235 incoming
2239 incoming
2236 </a>
2240 </a>
2237 </td><td>
2241 </td><td>
2238 show new changesets found in source
2242 show new changesets found in source
2239 </td></tr>
2243 </td></tr>
2240 <tr><td>
2244 <tr><td>
2241 <a href="/help/manifest">
2245 <a href="/help/manifest">
2242 manifest
2246 manifest
2243 </a>
2247 </a>
2244 </td><td>
2248 </td><td>
2245 output the current or given revision of the project manifest
2249 output the current or given revision of the project manifest
2246 </td></tr>
2250 </td></tr>
2247 <tr><td>
2251 <tr><td>
2248 <a href="/help/nohelp">
2252 <a href="/help/nohelp">
2249 nohelp
2253 nohelp
2250 </a>
2254 </a>
2251 </td><td>
2255 </td><td>
2252 (no help text available)
2256 (no help text available)
2253 </td></tr>
2257 </td></tr>
2254 <tr><td>
2258 <tr><td>
2255 <a href="/help/outgoing">
2259 <a href="/help/outgoing">
2256 outgoing
2260 outgoing
2257 </a>
2261 </a>
2258 </td><td>
2262 </td><td>
2259 show changesets not found in the destination
2263 show changesets not found in the destination
2260 </td></tr>
2264 </td></tr>
2261 <tr><td>
2265 <tr><td>
2262 <a href="/help/paths">
2266 <a href="/help/paths">
2263 paths
2267 paths
2264 </a>
2268 </a>
2265 </td><td>
2269 </td><td>
2266 show aliases for remote repositories
2270 show aliases for remote repositories
2267 </td></tr>
2271 </td></tr>
2268 <tr><td>
2272 <tr><td>
2269 <a href="/help/phase">
2273 <a href="/help/phase">
2270 phase
2274 phase
2271 </a>
2275 </a>
2272 </td><td>
2276 </td><td>
2273 set or show the current phase name
2277 set or show the current phase name
2274 </td></tr>
2278 </td></tr>
2275 <tr><td>
2279 <tr><td>
2276 <a href="/help/recover">
2280 <a href="/help/recover">
2277 recover
2281 recover
2278 </a>
2282 </a>
2279 </td><td>
2283 </td><td>
2280 roll back an interrupted transaction
2284 roll back an interrupted transaction
2281 </td></tr>
2285 </td></tr>
2282 <tr><td>
2286 <tr><td>
2283 <a href="/help/rename">
2287 <a href="/help/rename">
2284 rename
2288 rename
2285 </a>
2289 </a>
2286 </td><td>
2290 </td><td>
2287 rename files; equivalent of copy + remove
2291 rename files; equivalent of copy + remove
2288 </td></tr>
2292 </td></tr>
2289 <tr><td>
2293 <tr><td>
2290 <a href="/help/resolve">
2294 <a href="/help/resolve">
2291 resolve
2295 resolve
2292 </a>
2296 </a>
2293 </td><td>
2297 </td><td>
2294 redo merges or set/view the merge status of files
2298 redo merges or set/view the merge status of files
2295 </td></tr>
2299 </td></tr>
2296 <tr><td>
2300 <tr><td>
2297 <a href="/help/revert">
2301 <a href="/help/revert">
2298 revert
2302 revert
2299 </a>
2303 </a>
2300 </td><td>
2304 </td><td>
2301 restore files to their checkout state
2305 restore files to their checkout state
2302 </td></tr>
2306 </td></tr>
2303 <tr><td>
2307 <tr><td>
2304 <a href="/help/root">
2308 <a href="/help/root">
2305 root
2309 root
2306 </a>
2310 </a>
2307 </td><td>
2311 </td><td>
2308 print the root (top) of the current working directory
2312 print the root (top) of the current working directory
2309 </td></tr>
2313 </td></tr>
2310 <tr><td>
2314 <tr><td>
2311 <a href="/help/shellalias">
2315 <a href="/help/shellalias">
2312 shellalias
2316 shellalias
2313 </a>
2317 </a>
2314 </td><td>
2318 </td><td>
2315 (no help text available)
2319 (no help text available)
2316 </td></tr>
2320 </td></tr>
2317 <tr><td>
2321 <tr><td>
2318 <a href="/help/tag">
2322 <a href="/help/tag">
2319 tag
2323 tag
2320 </a>
2324 </a>
2321 </td><td>
2325 </td><td>
2322 add one or more tags for the current or given revision
2326 add one or more tags for the current or given revision
2323 </td></tr>
2327 </td></tr>
2324 <tr><td>
2328 <tr><td>
2325 <a href="/help/tags">
2329 <a href="/help/tags">
2326 tags
2330 tags
2327 </a>
2331 </a>
2328 </td><td>
2332 </td><td>
2329 list repository tags
2333 list repository tags
2330 </td></tr>
2334 </td></tr>
2331 <tr><td>
2335 <tr><td>
2332 <a href="/help/unbundle">
2336 <a href="/help/unbundle">
2333 unbundle
2337 unbundle
2334 </a>
2338 </a>
2335 </td><td>
2339 </td><td>
2336 apply one or more changegroup files
2340 apply one or more changegroup files
2337 </td></tr>
2341 </td></tr>
2338 <tr><td>
2342 <tr><td>
2339 <a href="/help/verify">
2343 <a href="/help/verify">
2340 verify
2344 verify
2341 </a>
2345 </a>
2342 </td><td>
2346 </td><td>
2343 verify the integrity of the repository
2347 verify the integrity of the repository
2344 </td></tr>
2348 </td></tr>
2345 <tr><td>
2349 <tr><td>
2346 <a href="/help/version">
2350 <a href="/help/version">
2347 version
2351 version
2348 </a>
2352 </a>
2349 </td><td>
2353 </td><td>
2350 output version and copyright information
2354 output version and copyright information
2351 </td></tr>
2355 </td></tr>
2352
2356
2353
2357
2354 </table>
2358 </table>
2355 </div>
2359 </div>
2356 </div>
2360 </div>
2357
2361
2358
2362
2359
2363
2360 </body>
2364 </body>
2361 </html>
2365 </html>
2362
2366
2363
2367
2364 $ get-with-headers.py 127.0.0.1:$HGPORT "help/add"
2368 $ get-with-headers.py 127.0.0.1:$HGPORT "help/add"
2365 200 Script output follows
2369 200 Script output follows
2366
2370
2367 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2371 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2368 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2372 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2369 <head>
2373 <head>
2370 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2374 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2371 <meta name="robots" content="index, nofollow" />
2375 <meta name="robots" content="index, nofollow" />
2372 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2376 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2373 <script type="text/javascript" src="/static/mercurial.js"></script>
2377 <script type="text/javascript" src="/static/mercurial.js"></script>
2374
2378
2375 <title>Help: add</title>
2379 <title>Help: add</title>
2376 </head>
2380 </head>
2377 <body>
2381 <body>
2378
2382
2379 <div class="container">
2383 <div class="container">
2380 <div class="menu">
2384 <div class="menu">
2381 <div class="logo">
2385 <div class="logo">
2382 <a href="https://mercurial-scm.org/">
2386 <a href="https://mercurial-scm.org/">
2383 <img src="/static/hglogo.png" alt="mercurial" /></a>
2387 <img src="/static/hglogo.png" alt="mercurial" /></a>
2384 </div>
2388 </div>
2385 <ul>
2389 <ul>
2386 <li><a href="/shortlog">log</a></li>
2390 <li><a href="/shortlog">log</a></li>
2387 <li><a href="/graph">graph</a></li>
2391 <li><a href="/graph">graph</a></li>
2388 <li><a href="/tags">tags</a></li>
2392 <li><a href="/tags">tags</a></li>
2389 <li><a href="/bookmarks">bookmarks</a></li>
2393 <li><a href="/bookmarks">bookmarks</a></li>
2390 <li><a href="/branches">branches</a></li>
2394 <li><a href="/branches">branches</a></li>
2391 </ul>
2395 </ul>
2392 <ul>
2396 <ul>
2393 <li class="active"><a href="/help">help</a></li>
2397 <li class="active"><a href="/help">help</a></li>
2394 </ul>
2398 </ul>
2395 </div>
2399 </div>
2396
2400
2397 <div class="main">
2401 <div class="main">
2398 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2402 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2399 <h3>Help: add</h3>
2403 <h3>Help: add</h3>
2400
2404
2401 <form class="search" action="/log">
2405 <form class="search" action="/log">
2402
2406
2403 <p><input name="rev" id="search1" type="text" size="30" /></p>
2407 <p><input name="rev" id="search1" type="text" size="30" /></p>
2404 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2408 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2405 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2409 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2406 </form>
2410 </form>
2407 <div id="doc">
2411 <div id="doc">
2408 <p>
2412 <p>
2409 hg add [OPTION]... [FILE]...
2413 hg add [OPTION]... [FILE]...
2410 </p>
2414 </p>
2411 <p>
2415 <p>
2412 add the specified files on the next commit
2416 add the specified files on the next commit
2413 </p>
2417 </p>
2414 <p>
2418 <p>
2415 Schedule files to be version controlled and added to the
2419 Schedule files to be version controlled and added to the
2416 repository.
2420 repository.
2417 </p>
2421 </p>
2418 <p>
2422 <p>
2419 The files will be added to the repository at the next commit. To
2423 The files will be added to the repository at the next commit. To
2420 undo an add before that, see 'hg forget'.
2424 undo an add before that, see 'hg forget'.
2421 </p>
2425 </p>
2422 <p>
2426 <p>
2423 If no names are given, add all files to the repository (except
2427 If no names are given, add all files to the repository (except
2424 files matching &quot;.hgignore&quot;).
2428 files matching &quot;.hgignore&quot;).
2425 </p>
2429 </p>
2426 <p>
2430 <p>
2427 Examples:
2431 Examples:
2428 </p>
2432 </p>
2429 <ul>
2433 <ul>
2430 <li> New (unknown) files are added automatically by 'hg add':
2434 <li> New (unknown) files are added automatically by 'hg add':
2431 <pre>
2435 <pre>
2432 \$ ls (re)
2436 \$ ls (re)
2433 foo.c
2437 foo.c
2434 \$ hg status (re)
2438 \$ hg status (re)
2435 ? foo.c
2439 ? foo.c
2436 \$ hg add (re)
2440 \$ hg add (re)
2437 adding foo.c
2441 adding foo.c
2438 \$ hg status (re)
2442 \$ hg status (re)
2439 A foo.c
2443 A foo.c
2440 </pre>
2444 </pre>
2441 <li> Specific files to be added can be specified:
2445 <li> Specific files to be added can be specified:
2442 <pre>
2446 <pre>
2443 \$ ls (re)
2447 \$ ls (re)
2444 bar.c foo.c
2448 bar.c foo.c
2445 \$ hg status (re)
2449 \$ hg status (re)
2446 ? bar.c
2450 ? bar.c
2447 ? foo.c
2451 ? foo.c
2448 \$ hg add bar.c (re)
2452 \$ hg add bar.c (re)
2449 \$ hg status (re)
2453 \$ hg status (re)
2450 A bar.c
2454 A bar.c
2451 ? foo.c
2455 ? foo.c
2452 </pre>
2456 </pre>
2453 </ul>
2457 </ul>
2454 <p>
2458 <p>
2455 Returns 0 if all files are successfully added.
2459 Returns 0 if all files are successfully added.
2456 </p>
2460 </p>
2457 <p>
2461 <p>
2458 options ([+] can be repeated):
2462 options ([+] can be repeated):
2459 </p>
2463 </p>
2460 <table>
2464 <table>
2461 <tr><td>-I</td>
2465 <tr><td>-I</td>
2462 <td>--include PATTERN [+]</td>
2466 <td>--include PATTERN [+]</td>
2463 <td>include names matching the given patterns</td></tr>
2467 <td>include names matching the given patterns</td></tr>
2464 <tr><td>-X</td>
2468 <tr><td>-X</td>
2465 <td>--exclude PATTERN [+]</td>
2469 <td>--exclude PATTERN [+]</td>
2466 <td>exclude names matching the given patterns</td></tr>
2470 <td>exclude names matching the given patterns</td></tr>
2467 <tr><td>-S</td>
2471 <tr><td>-S</td>
2468 <td>--subrepos</td>
2472 <td>--subrepos</td>
2469 <td>recurse into subrepositories</td></tr>
2473 <td>recurse into subrepositories</td></tr>
2470 <tr><td>-n</td>
2474 <tr><td>-n</td>
2471 <td>--dry-run</td>
2475 <td>--dry-run</td>
2472 <td>do not perform actions, just print output</td></tr>
2476 <td>do not perform actions, just print output</td></tr>
2473 </table>
2477 </table>
2474 <p>
2478 <p>
2475 global options ([+] can be repeated):
2479 global options ([+] can be repeated):
2476 </p>
2480 </p>
2477 <table>
2481 <table>
2478 <tr><td>-R</td>
2482 <tr><td>-R</td>
2479 <td>--repository REPO</td>
2483 <td>--repository REPO</td>
2480 <td>repository root directory or name of overlay bundle file</td></tr>
2484 <td>repository root directory or name of overlay bundle file</td></tr>
2481 <tr><td></td>
2485 <tr><td></td>
2482 <td>--cwd DIR</td>
2486 <td>--cwd DIR</td>
2483 <td>change working directory</td></tr>
2487 <td>change working directory</td></tr>
2484 <tr><td>-y</td>
2488 <tr><td>-y</td>
2485 <td>--noninteractive</td>
2489 <td>--noninteractive</td>
2486 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2490 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2487 <tr><td>-q</td>
2491 <tr><td>-q</td>
2488 <td>--quiet</td>
2492 <td>--quiet</td>
2489 <td>suppress output</td></tr>
2493 <td>suppress output</td></tr>
2490 <tr><td>-v</td>
2494 <tr><td>-v</td>
2491 <td>--verbose</td>
2495 <td>--verbose</td>
2492 <td>enable additional output</td></tr>
2496 <td>enable additional output</td></tr>
2493 <tr><td></td>
2497 <tr><td></td>
2494 <td>--config CONFIG [+]</td>
2498 <td>--config CONFIG [+]</td>
2495 <td>set/override config option (use 'section.name=value')</td></tr>
2499 <td>set/override config option (use 'section.name=value')</td></tr>
2496 <tr><td></td>
2500 <tr><td></td>
2497 <td>--debug</td>
2501 <td>--debug</td>
2498 <td>enable debugging output</td></tr>
2502 <td>enable debugging output</td></tr>
2499 <tr><td></td>
2503 <tr><td></td>
2500 <td>--debugger</td>
2504 <td>--debugger</td>
2501 <td>start debugger</td></tr>
2505 <td>start debugger</td></tr>
2502 <tr><td></td>
2506 <tr><td></td>
2503 <td>--encoding ENCODE</td>
2507 <td>--encoding ENCODE</td>
2504 <td>set the charset encoding (default: ascii)</td></tr>
2508 <td>set the charset encoding (default: ascii)</td></tr>
2505 <tr><td></td>
2509 <tr><td></td>
2506 <td>--encodingmode MODE</td>
2510 <td>--encodingmode MODE</td>
2507 <td>set the charset encoding mode (default: strict)</td></tr>
2511 <td>set the charset encoding mode (default: strict)</td></tr>
2508 <tr><td></td>
2512 <tr><td></td>
2509 <td>--traceback</td>
2513 <td>--traceback</td>
2510 <td>always print a traceback on exception</td></tr>
2514 <td>always print a traceback on exception</td></tr>
2511 <tr><td></td>
2515 <tr><td></td>
2512 <td>--time</td>
2516 <td>--time</td>
2513 <td>time how long the command takes</td></tr>
2517 <td>time how long the command takes</td></tr>
2514 <tr><td></td>
2518 <tr><td></td>
2515 <td>--profile</td>
2519 <td>--profile</td>
2516 <td>print command execution profile</td></tr>
2520 <td>print command execution profile</td></tr>
2517 <tr><td></td>
2521 <tr><td></td>
2518 <td>--version</td>
2522 <td>--version</td>
2519 <td>output version information and exit</td></tr>
2523 <td>output version information and exit</td></tr>
2520 <tr><td>-h</td>
2524 <tr><td>-h</td>
2521 <td>--help</td>
2525 <td>--help</td>
2522 <td>display help and exit</td></tr>
2526 <td>display help and exit</td></tr>
2523 <tr><td></td>
2527 <tr><td></td>
2524 <td>--hidden</td>
2528 <td>--hidden</td>
2525 <td>consider hidden changesets</td></tr>
2529 <td>consider hidden changesets</td></tr>
2530 <tr><td></td>
2531 <td>--pager TYPE</td>
2532 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2526 </table>
2533 </table>
2527
2534
2528 </div>
2535 </div>
2529 </div>
2536 </div>
2530 </div>
2537 </div>
2531
2538
2532
2539
2533
2540
2534 </body>
2541 </body>
2535 </html>
2542 </html>
2536
2543
2537
2544
2538 $ get-with-headers.py 127.0.0.1:$HGPORT "help/remove"
2545 $ get-with-headers.py 127.0.0.1:$HGPORT "help/remove"
2539 200 Script output follows
2546 200 Script output follows
2540
2547
2541 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2548 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2542 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2549 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2543 <head>
2550 <head>
2544 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2551 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2545 <meta name="robots" content="index, nofollow" />
2552 <meta name="robots" content="index, nofollow" />
2546 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2553 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2547 <script type="text/javascript" src="/static/mercurial.js"></script>
2554 <script type="text/javascript" src="/static/mercurial.js"></script>
2548
2555
2549 <title>Help: remove</title>
2556 <title>Help: remove</title>
2550 </head>
2557 </head>
2551 <body>
2558 <body>
2552
2559
2553 <div class="container">
2560 <div class="container">
2554 <div class="menu">
2561 <div class="menu">
2555 <div class="logo">
2562 <div class="logo">
2556 <a href="https://mercurial-scm.org/">
2563 <a href="https://mercurial-scm.org/">
2557 <img src="/static/hglogo.png" alt="mercurial" /></a>
2564 <img src="/static/hglogo.png" alt="mercurial" /></a>
2558 </div>
2565 </div>
2559 <ul>
2566 <ul>
2560 <li><a href="/shortlog">log</a></li>
2567 <li><a href="/shortlog">log</a></li>
2561 <li><a href="/graph">graph</a></li>
2568 <li><a href="/graph">graph</a></li>
2562 <li><a href="/tags">tags</a></li>
2569 <li><a href="/tags">tags</a></li>
2563 <li><a href="/bookmarks">bookmarks</a></li>
2570 <li><a href="/bookmarks">bookmarks</a></li>
2564 <li><a href="/branches">branches</a></li>
2571 <li><a href="/branches">branches</a></li>
2565 </ul>
2572 </ul>
2566 <ul>
2573 <ul>
2567 <li class="active"><a href="/help">help</a></li>
2574 <li class="active"><a href="/help">help</a></li>
2568 </ul>
2575 </ul>
2569 </div>
2576 </div>
2570
2577
2571 <div class="main">
2578 <div class="main">
2572 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2579 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2573 <h3>Help: remove</h3>
2580 <h3>Help: remove</h3>
2574
2581
2575 <form class="search" action="/log">
2582 <form class="search" action="/log">
2576
2583
2577 <p><input name="rev" id="search1" type="text" size="30" /></p>
2584 <p><input name="rev" id="search1" type="text" size="30" /></p>
2578 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2585 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2579 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2586 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2580 </form>
2587 </form>
2581 <div id="doc">
2588 <div id="doc">
2582 <p>
2589 <p>
2583 hg remove [OPTION]... FILE...
2590 hg remove [OPTION]... FILE...
2584 </p>
2591 </p>
2585 <p>
2592 <p>
2586 aliases: rm
2593 aliases: rm
2587 </p>
2594 </p>
2588 <p>
2595 <p>
2589 remove the specified files on the next commit
2596 remove the specified files on the next commit
2590 </p>
2597 </p>
2591 <p>
2598 <p>
2592 Schedule the indicated files for removal from the current branch.
2599 Schedule the indicated files for removal from the current branch.
2593 </p>
2600 </p>
2594 <p>
2601 <p>
2595 This command schedules the files to be removed at the next commit.
2602 This command schedules the files to be removed at the next commit.
2596 To undo a remove before that, see 'hg revert'. To undo added
2603 To undo a remove before that, see 'hg revert'. To undo added
2597 files, see 'hg forget'.
2604 files, see 'hg forget'.
2598 </p>
2605 </p>
2599 <p>
2606 <p>
2600 -A/--after can be used to remove only files that have already
2607 -A/--after can be used to remove only files that have already
2601 been deleted, -f/--force can be used to force deletion, and -Af
2608 been deleted, -f/--force can be used to force deletion, and -Af
2602 can be used to remove files from the next revision without
2609 can be used to remove files from the next revision without
2603 deleting them from the working directory.
2610 deleting them from the working directory.
2604 </p>
2611 </p>
2605 <p>
2612 <p>
2606 The following table details the behavior of remove for different
2613 The following table details the behavior of remove for different
2607 file states (columns) and option combinations (rows). The file
2614 file states (columns) and option combinations (rows). The file
2608 states are Added [A], Clean [C], Modified [M] and Missing [!]
2615 states are Added [A], Clean [C], Modified [M] and Missing [!]
2609 (as reported by 'hg status'). The actions are Warn, Remove
2616 (as reported by 'hg status'). The actions are Warn, Remove
2610 (from branch) and Delete (from disk):
2617 (from branch) and Delete (from disk):
2611 </p>
2618 </p>
2612 <table>
2619 <table>
2613 <tr><td>opt/state</td>
2620 <tr><td>opt/state</td>
2614 <td>A</td>
2621 <td>A</td>
2615 <td>C</td>
2622 <td>C</td>
2616 <td>M</td>
2623 <td>M</td>
2617 <td>!</td></tr>
2624 <td>!</td></tr>
2618 <tr><td>none</td>
2625 <tr><td>none</td>
2619 <td>W</td>
2626 <td>W</td>
2620 <td>RD</td>
2627 <td>RD</td>
2621 <td>W</td>
2628 <td>W</td>
2622 <td>R</td></tr>
2629 <td>R</td></tr>
2623 <tr><td>-f</td>
2630 <tr><td>-f</td>
2624 <td>R</td>
2631 <td>R</td>
2625 <td>RD</td>
2632 <td>RD</td>
2626 <td>RD</td>
2633 <td>RD</td>
2627 <td>R</td></tr>
2634 <td>R</td></tr>
2628 <tr><td>-A</td>
2635 <tr><td>-A</td>
2629 <td>W</td>
2636 <td>W</td>
2630 <td>W</td>
2637 <td>W</td>
2631 <td>W</td>
2638 <td>W</td>
2632 <td>R</td></tr>
2639 <td>R</td></tr>
2633 <tr><td>-Af</td>
2640 <tr><td>-Af</td>
2634 <td>R</td>
2641 <td>R</td>
2635 <td>R</td>
2642 <td>R</td>
2636 <td>R</td>
2643 <td>R</td>
2637 <td>R</td></tr>
2644 <td>R</td></tr>
2638 </table>
2645 </table>
2639 <p>
2646 <p>
2640 <b>Note:</b>
2647 <b>Note:</b>
2641 </p>
2648 </p>
2642 <p>
2649 <p>
2643 'hg remove' never deletes files in Added [A] state from the
2650 'hg remove' never deletes files in Added [A] state from the
2644 working directory, not even if &quot;--force&quot; is specified.
2651 working directory, not even if &quot;--force&quot; is specified.
2645 </p>
2652 </p>
2646 <p>
2653 <p>
2647 Returns 0 on success, 1 if any warnings encountered.
2654 Returns 0 on success, 1 if any warnings encountered.
2648 </p>
2655 </p>
2649 <p>
2656 <p>
2650 options ([+] can be repeated):
2657 options ([+] can be repeated):
2651 </p>
2658 </p>
2652 <table>
2659 <table>
2653 <tr><td>-A</td>
2660 <tr><td>-A</td>
2654 <td>--after</td>
2661 <td>--after</td>
2655 <td>record delete for missing files</td></tr>
2662 <td>record delete for missing files</td></tr>
2656 <tr><td>-f</td>
2663 <tr><td>-f</td>
2657 <td>--force</td>
2664 <td>--force</td>
2658 <td>forget added files, delete modified files</td></tr>
2665 <td>forget added files, delete modified files</td></tr>
2659 <tr><td>-S</td>
2666 <tr><td>-S</td>
2660 <td>--subrepos</td>
2667 <td>--subrepos</td>
2661 <td>recurse into subrepositories</td></tr>
2668 <td>recurse into subrepositories</td></tr>
2662 <tr><td>-I</td>
2669 <tr><td>-I</td>
2663 <td>--include PATTERN [+]</td>
2670 <td>--include PATTERN [+]</td>
2664 <td>include names matching the given patterns</td></tr>
2671 <td>include names matching the given patterns</td></tr>
2665 <tr><td>-X</td>
2672 <tr><td>-X</td>
2666 <td>--exclude PATTERN [+]</td>
2673 <td>--exclude PATTERN [+]</td>
2667 <td>exclude names matching the given patterns</td></tr>
2674 <td>exclude names matching the given patterns</td></tr>
2668 </table>
2675 </table>
2669 <p>
2676 <p>
2670 global options ([+] can be repeated):
2677 global options ([+] can be repeated):
2671 </p>
2678 </p>
2672 <table>
2679 <table>
2673 <tr><td>-R</td>
2680 <tr><td>-R</td>
2674 <td>--repository REPO</td>
2681 <td>--repository REPO</td>
2675 <td>repository root directory or name of overlay bundle file</td></tr>
2682 <td>repository root directory or name of overlay bundle file</td></tr>
2676 <tr><td></td>
2683 <tr><td></td>
2677 <td>--cwd DIR</td>
2684 <td>--cwd DIR</td>
2678 <td>change working directory</td></tr>
2685 <td>change working directory</td></tr>
2679 <tr><td>-y</td>
2686 <tr><td>-y</td>
2680 <td>--noninteractive</td>
2687 <td>--noninteractive</td>
2681 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2688 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2682 <tr><td>-q</td>
2689 <tr><td>-q</td>
2683 <td>--quiet</td>
2690 <td>--quiet</td>
2684 <td>suppress output</td></tr>
2691 <td>suppress output</td></tr>
2685 <tr><td>-v</td>
2692 <tr><td>-v</td>
2686 <td>--verbose</td>
2693 <td>--verbose</td>
2687 <td>enable additional output</td></tr>
2694 <td>enable additional output</td></tr>
2688 <tr><td></td>
2695 <tr><td></td>
2689 <td>--config CONFIG [+]</td>
2696 <td>--config CONFIG [+]</td>
2690 <td>set/override config option (use 'section.name=value')</td></tr>
2697 <td>set/override config option (use 'section.name=value')</td></tr>
2691 <tr><td></td>
2698 <tr><td></td>
2692 <td>--debug</td>
2699 <td>--debug</td>
2693 <td>enable debugging output</td></tr>
2700 <td>enable debugging output</td></tr>
2694 <tr><td></td>
2701 <tr><td></td>
2695 <td>--debugger</td>
2702 <td>--debugger</td>
2696 <td>start debugger</td></tr>
2703 <td>start debugger</td></tr>
2697 <tr><td></td>
2704 <tr><td></td>
2698 <td>--encoding ENCODE</td>
2705 <td>--encoding ENCODE</td>
2699 <td>set the charset encoding (default: ascii)</td></tr>
2706 <td>set the charset encoding (default: ascii)</td></tr>
2700 <tr><td></td>
2707 <tr><td></td>
2701 <td>--encodingmode MODE</td>
2708 <td>--encodingmode MODE</td>
2702 <td>set the charset encoding mode (default: strict)</td></tr>
2709 <td>set the charset encoding mode (default: strict)</td></tr>
2703 <tr><td></td>
2710 <tr><td></td>
2704 <td>--traceback</td>
2711 <td>--traceback</td>
2705 <td>always print a traceback on exception</td></tr>
2712 <td>always print a traceback on exception</td></tr>
2706 <tr><td></td>
2713 <tr><td></td>
2707 <td>--time</td>
2714 <td>--time</td>
2708 <td>time how long the command takes</td></tr>
2715 <td>time how long the command takes</td></tr>
2709 <tr><td></td>
2716 <tr><td></td>
2710 <td>--profile</td>
2717 <td>--profile</td>
2711 <td>print command execution profile</td></tr>
2718 <td>print command execution profile</td></tr>
2712 <tr><td></td>
2719 <tr><td></td>
2713 <td>--version</td>
2720 <td>--version</td>
2714 <td>output version information and exit</td></tr>
2721 <td>output version information and exit</td></tr>
2715 <tr><td>-h</td>
2722 <tr><td>-h</td>
2716 <td>--help</td>
2723 <td>--help</td>
2717 <td>display help and exit</td></tr>
2724 <td>display help and exit</td></tr>
2718 <tr><td></td>
2725 <tr><td></td>
2719 <td>--hidden</td>
2726 <td>--hidden</td>
2720 <td>consider hidden changesets</td></tr>
2727 <td>consider hidden changesets</td></tr>
2728 <tr><td></td>
2729 <td>--pager TYPE</td>
2730 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2721 </table>
2731 </table>
2722
2732
2723 </div>
2733 </div>
2724 </div>
2734 </div>
2725 </div>
2735 </div>
2726
2736
2727
2737
2728
2738
2729 </body>
2739 </body>
2730 </html>
2740 </html>
2731
2741
2732
2742
2733 $ get-with-headers.py 127.0.0.1:$HGPORT "help/dates"
2743 $ get-with-headers.py 127.0.0.1:$HGPORT "help/dates"
2734 200 Script output follows
2744 200 Script output follows
2735
2745
2736 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2746 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2737 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2747 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2738 <head>
2748 <head>
2739 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2749 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2740 <meta name="robots" content="index, nofollow" />
2750 <meta name="robots" content="index, nofollow" />
2741 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2751 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2742 <script type="text/javascript" src="/static/mercurial.js"></script>
2752 <script type="text/javascript" src="/static/mercurial.js"></script>
2743
2753
2744 <title>Help: dates</title>
2754 <title>Help: dates</title>
2745 </head>
2755 </head>
2746 <body>
2756 <body>
2747
2757
2748 <div class="container">
2758 <div class="container">
2749 <div class="menu">
2759 <div class="menu">
2750 <div class="logo">
2760 <div class="logo">
2751 <a href="https://mercurial-scm.org/">
2761 <a href="https://mercurial-scm.org/">
2752 <img src="/static/hglogo.png" alt="mercurial" /></a>
2762 <img src="/static/hglogo.png" alt="mercurial" /></a>
2753 </div>
2763 </div>
2754 <ul>
2764 <ul>
2755 <li><a href="/shortlog">log</a></li>
2765 <li><a href="/shortlog">log</a></li>
2756 <li><a href="/graph">graph</a></li>
2766 <li><a href="/graph">graph</a></li>
2757 <li><a href="/tags">tags</a></li>
2767 <li><a href="/tags">tags</a></li>
2758 <li><a href="/bookmarks">bookmarks</a></li>
2768 <li><a href="/bookmarks">bookmarks</a></li>
2759 <li><a href="/branches">branches</a></li>
2769 <li><a href="/branches">branches</a></li>
2760 </ul>
2770 </ul>
2761 <ul>
2771 <ul>
2762 <li class="active"><a href="/help">help</a></li>
2772 <li class="active"><a href="/help">help</a></li>
2763 </ul>
2773 </ul>
2764 </div>
2774 </div>
2765
2775
2766 <div class="main">
2776 <div class="main">
2767 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2777 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2768 <h3>Help: dates</h3>
2778 <h3>Help: dates</h3>
2769
2779
2770 <form class="search" action="/log">
2780 <form class="search" action="/log">
2771
2781
2772 <p><input name="rev" id="search1" type="text" size="30" /></p>
2782 <p><input name="rev" id="search1" type="text" size="30" /></p>
2773 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2783 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2774 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2784 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2775 </form>
2785 </form>
2776 <div id="doc">
2786 <div id="doc">
2777 <h1>Date Formats</h1>
2787 <h1>Date Formats</h1>
2778 <p>
2788 <p>
2779 Some commands allow the user to specify a date, e.g.:
2789 Some commands allow the user to specify a date, e.g.:
2780 </p>
2790 </p>
2781 <ul>
2791 <ul>
2782 <li> backout, commit, import, tag: Specify the commit date.
2792 <li> backout, commit, import, tag: Specify the commit date.
2783 <li> log, revert, update: Select revision(s) by date.
2793 <li> log, revert, update: Select revision(s) by date.
2784 </ul>
2794 </ul>
2785 <p>
2795 <p>
2786 Many date formats are valid. Here are some examples:
2796 Many date formats are valid. Here are some examples:
2787 </p>
2797 </p>
2788 <ul>
2798 <ul>
2789 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
2799 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
2790 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
2800 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
2791 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
2801 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
2792 <li> &quot;Dec 6&quot; (midnight)
2802 <li> &quot;Dec 6&quot; (midnight)
2793 <li> &quot;13:18&quot; (today assumed)
2803 <li> &quot;13:18&quot; (today assumed)
2794 <li> &quot;3:39&quot; (3:39AM assumed)
2804 <li> &quot;3:39&quot; (3:39AM assumed)
2795 <li> &quot;3:39pm&quot; (15:39)
2805 <li> &quot;3:39pm&quot; (15:39)
2796 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
2806 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
2797 <li> &quot;2006-12-6 13:18&quot;
2807 <li> &quot;2006-12-6 13:18&quot;
2798 <li> &quot;2006-12-6&quot;
2808 <li> &quot;2006-12-6&quot;
2799 <li> &quot;12-6&quot;
2809 <li> &quot;12-6&quot;
2800 <li> &quot;12/6&quot;
2810 <li> &quot;12/6&quot;
2801 <li> &quot;12/6/6&quot; (Dec 6 2006)
2811 <li> &quot;12/6/6&quot; (Dec 6 2006)
2802 <li> &quot;today&quot; (midnight)
2812 <li> &quot;today&quot; (midnight)
2803 <li> &quot;yesterday&quot; (midnight)
2813 <li> &quot;yesterday&quot; (midnight)
2804 <li> &quot;now&quot; - right now
2814 <li> &quot;now&quot; - right now
2805 </ul>
2815 </ul>
2806 <p>
2816 <p>
2807 Lastly, there is Mercurial's internal format:
2817 Lastly, there is Mercurial's internal format:
2808 </p>
2818 </p>
2809 <ul>
2819 <ul>
2810 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
2820 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
2811 </ul>
2821 </ul>
2812 <p>
2822 <p>
2813 This is the internal representation format for dates. The first number
2823 This is the internal representation format for dates. The first number
2814 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
2824 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
2815 second is the offset of the local timezone, in seconds west of UTC
2825 second is the offset of the local timezone, in seconds west of UTC
2816 (negative if the timezone is east of UTC).
2826 (negative if the timezone is east of UTC).
2817 </p>
2827 </p>
2818 <p>
2828 <p>
2819 The log command also accepts date ranges:
2829 The log command also accepts date ranges:
2820 </p>
2830 </p>
2821 <ul>
2831 <ul>
2822 <li> &quot;&lt;DATE&quot; - at or before a given date/time
2832 <li> &quot;&lt;DATE&quot; - at or before a given date/time
2823 <li> &quot;&gt;DATE&quot; - on or after a given date/time
2833 <li> &quot;&gt;DATE&quot; - on or after a given date/time
2824 <li> &quot;DATE to DATE&quot; - a date range, inclusive
2834 <li> &quot;DATE to DATE&quot; - a date range, inclusive
2825 <li> &quot;-DAYS&quot; - within a given number of days of today
2835 <li> &quot;-DAYS&quot; - within a given number of days of today
2826 </ul>
2836 </ul>
2827
2837
2828 </div>
2838 </div>
2829 </div>
2839 </div>
2830 </div>
2840 </div>
2831
2841
2832
2842
2833
2843
2834 </body>
2844 </body>
2835 </html>
2845 </html>
2836
2846
2837
2847
2838 Sub-topic indexes rendered properly
2848 Sub-topic indexes rendered properly
2839
2849
2840 $ get-with-headers.py 127.0.0.1:$HGPORT "help/internals"
2850 $ get-with-headers.py 127.0.0.1:$HGPORT "help/internals"
2841 200 Script output follows
2851 200 Script output follows
2842
2852
2843 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2853 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2844 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2854 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2845 <head>
2855 <head>
2846 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2856 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2847 <meta name="robots" content="index, nofollow" />
2857 <meta name="robots" content="index, nofollow" />
2848 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2858 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2849 <script type="text/javascript" src="/static/mercurial.js"></script>
2859 <script type="text/javascript" src="/static/mercurial.js"></script>
2850
2860
2851 <title>Help: internals</title>
2861 <title>Help: internals</title>
2852 </head>
2862 </head>
2853 <body>
2863 <body>
2854
2864
2855 <div class="container">
2865 <div class="container">
2856 <div class="menu">
2866 <div class="menu">
2857 <div class="logo">
2867 <div class="logo">
2858 <a href="https://mercurial-scm.org/">
2868 <a href="https://mercurial-scm.org/">
2859 <img src="/static/hglogo.png" alt="mercurial" /></a>
2869 <img src="/static/hglogo.png" alt="mercurial" /></a>
2860 </div>
2870 </div>
2861 <ul>
2871 <ul>
2862 <li><a href="/shortlog">log</a></li>
2872 <li><a href="/shortlog">log</a></li>
2863 <li><a href="/graph">graph</a></li>
2873 <li><a href="/graph">graph</a></li>
2864 <li><a href="/tags">tags</a></li>
2874 <li><a href="/tags">tags</a></li>
2865 <li><a href="/bookmarks">bookmarks</a></li>
2875 <li><a href="/bookmarks">bookmarks</a></li>
2866 <li><a href="/branches">branches</a></li>
2876 <li><a href="/branches">branches</a></li>
2867 </ul>
2877 </ul>
2868 <ul>
2878 <ul>
2869 <li><a href="/help">help</a></li>
2879 <li><a href="/help">help</a></li>
2870 </ul>
2880 </ul>
2871 </div>
2881 </div>
2872
2882
2873 <div class="main">
2883 <div class="main">
2874 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2884 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2875 <form class="search" action="/log">
2885 <form class="search" action="/log">
2876
2886
2877 <p><input name="rev" id="search1" type="text" size="30" /></p>
2887 <p><input name="rev" id="search1" type="text" size="30" /></p>
2878 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2888 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2879 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2889 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2880 </form>
2890 </form>
2881 <table class="bigtable">
2891 <table class="bigtable">
2882 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2892 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2883
2893
2884 <tr><td>
2894 <tr><td>
2885 <a href="/help/internals.bundles">
2895 <a href="/help/internals.bundles">
2886 bundles
2896 bundles
2887 </a>
2897 </a>
2888 </td><td>
2898 </td><td>
2889 Bundles
2899 Bundles
2890 </td></tr>
2900 </td></tr>
2891 <tr><td>
2901 <tr><td>
2892 <a href="/help/internals.changegroups">
2902 <a href="/help/internals.changegroups">
2893 changegroups
2903 changegroups
2894 </a>
2904 </a>
2895 </td><td>
2905 </td><td>
2896 Changegroups
2906 Changegroups
2897 </td></tr>
2907 </td></tr>
2898 <tr><td>
2908 <tr><td>
2899 <a href="/help/internals.requirements">
2909 <a href="/help/internals.requirements">
2900 requirements
2910 requirements
2901 </a>
2911 </a>
2902 </td><td>
2912 </td><td>
2903 Repository Requirements
2913 Repository Requirements
2904 </td></tr>
2914 </td></tr>
2905 <tr><td>
2915 <tr><td>
2906 <a href="/help/internals.revlogs">
2916 <a href="/help/internals.revlogs">
2907 revlogs
2917 revlogs
2908 </a>
2918 </a>
2909 </td><td>
2919 </td><td>
2910 Revision Logs
2920 Revision Logs
2911 </td></tr>
2921 </td></tr>
2912 <tr><td>
2922 <tr><td>
2913 <a href="/help/internals.wireprotocol">
2923 <a href="/help/internals.wireprotocol">
2914 wireprotocol
2924 wireprotocol
2915 </a>
2925 </a>
2916 </td><td>
2926 </td><td>
2917 Wire Protocol
2927 Wire Protocol
2918 </td></tr>
2928 </td></tr>
2919
2929
2920
2930
2921
2931
2922
2932
2923
2933
2924 </table>
2934 </table>
2925 </div>
2935 </div>
2926 </div>
2936 </div>
2927
2937
2928
2938
2929
2939
2930 </body>
2940 </body>
2931 </html>
2941 </html>
2932
2942
2933
2943
2934 Sub-topic topics rendered properly
2944 Sub-topic topics rendered properly
2935
2945
2936 $ get-with-headers.py 127.0.0.1:$HGPORT "help/internals.changegroups"
2946 $ get-with-headers.py 127.0.0.1:$HGPORT "help/internals.changegroups"
2937 200 Script output follows
2947 200 Script output follows
2938
2948
2939 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2949 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2940 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2950 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2941 <head>
2951 <head>
2942 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2952 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2943 <meta name="robots" content="index, nofollow" />
2953 <meta name="robots" content="index, nofollow" />
2944 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2954 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2945 <script type="text/javascript" src="/static/mercurial.js"></script>
2955 <script type="text/javascript" src="/static/mercurial.js"></script>
2946
2956
2947 <title>Help: internals.changegroups</title>
2957 <title>Help: internals.changegroups</title>
2948 </head>
2958 </head>
2949 <body>
2959 <body>
2950
2960
2951 <div class="container">
2961 <div class="container">
2952 <div class="menu">
2962 <div class="menu">
2953 <div class="logo">
2963 <div class="logo">
2954 <a href="https://mercurial-scm.org/">
2964 <a href="https://mercurial-scm.org/">
2955 <img src="/static/hglogo.png" alt="mercurial" /></a>
2965 <img src="/static/hglogo.png" alt="mercurial" /></a>
2956 </div>
2966 </div>
2957 <ul>
2967 <ul>
2958 <li><a href="/shortlog">log</a></li>
2968 <li><a href="/shortlog">log</a></li>
2959 <li><a href="/graph">graph</a></li>
2969 <li><a href="/graph">graph</a></li>
2960 <li><a href="/tags">tags</a></li>
2970 <li><a href="/tags">tags</a></li>
2961 <li><a href="/bookmarks">bookmarks</a></li>
2971 <li><a href="/bookmarks">bookmarks</a></li>
2962 <li><a href="/branches">branches</a></li>
2972 <li><a href="/branches">branches</a></li>
2963 </ul>
2973 </ul>
2964 <ul>
2974 <ul>
2965 <li class="active"><a href="/help">help</a></li>
2975 <li class="active"><a href="/help">help</a></li>
2966 </ul>
2976 </ul>
2967 </div>
2977 </div>
2968
2978
2969 <div class="main">
2979 <div class="main">
2970 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2980 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2971 <h3>Help: internals.changegroups</h3>
2981 <h3>Help: internals.changegroups</h3>
2972
2982
2973 <form class="search" action="/log">
2983 <form class="search" action="/log">
2974
2984
2975 <p><input name="rev" id="search1" type="text" size="30" /></p>
2985 <p><input name="rev" id="search1" type="text" size="30" /></p>
2976 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2986 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2977 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2987 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2978 </form>
2988 </form>
2979 <div id="doc">
2989 <div id="doc">
2980 <h1>Changegroups</h1>
2990 <h1>Changegroups</h1>
2981 <p>
2991 <p>
2982 Changegroups are representations of repository revlog data, specifically
2992 Changegroups are representations of repository revlog data, specifically
2983 the changelog, manifest, and filelogs.
2993 the changelog, manifest, and filelogs.
2984 </p>
2994 </p>
2985 <p>
2995 <p>
2986 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
2996 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
2987 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with
2997 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with
2988 the only difference being a header on entries in the changeset
2998 the only difference being a header on entries in the changeset
2989 segment. Version &quot;3&quot; adds support for exchanging treemanifests and
2999 segment. Version &quot;3&quot; adds support for exchanging treemanifests and
2990 includes revlog flags in the delta header.
3000 includes revlog flags in the delta header.
2991 </p>
3001 </p>
2992 <p>
3002 <p>
2993 Changegroups consists of 3 logical segments:
3003 Changegroups consists of 3 logical segments:
2994 </p>
3004 </p>
2995 <pre>
3005 <pre>
2996 +---------------------------------+
3006 +---------------------------------+
2997 | | | |
3007 | | | |
2998 | changeset | manifest | filelogs |
3008 | changeset | manifest | filelogs |
2999 | | | |
3009 | | | |
3000 +---------------------------------+
3010 +---------------------------------+
3001 </pre>
3011 </pre>
3002 <p>
3012 <p>
3003 The principle building block of each segment is a *chunk*. A *chunk*
3013 The principle building block of each segment is a *chunk*. A *chunk*
3004 is a framed piece of data:
3014 is a framed piece of data:
3005 </p>
3015 </p>
3006 <pre>
3016 <pre>
3007 +---------------------------------------+
3017 +---------------------------------------+
3008 | | |
3018 | | |
3009 | length | data |
3019 | length | data |
3010 | (32 bits) | &lt;length&gt; bytes |
3020 | (32 bits) | &lt;length&gt; bytes |
3011 | | |
3021 | | |
3012 +---------------------------------------+
3022 +---------------------------------------+
3013 </pre>
3023 </pre>
3014 <p>
3024 <p>
3015 Each chunk starts with a 32-bit big-endian signed integer indicating
3025 Each chunk starts with a 32-bit big-endian signed integer indicating
3016 the length of the raw data that follows.
3026 the length of the raw data that follows.
3017 </p>
3027 </p>
3018 <p>
3028 <p>
3019 There is a special case chunk that has 0 length (&quot;0x00000000&quot;). We
3029 There is a special case chunk that has 0 length (&quot;0x00000000&quot;). We
3020 call this an *empty chunk*.
3030 call this an *empty chunk*.
3021 </p>
3031 </p>
3022 <h2>Delta Groups</h2>
3032 <h2>Delta Groups</h2>
3023 <p>
3033 <p>
3024 A *delta group* expresses the content of a revlog as a series of deltas,
3034 A *delta group* expresses the content of a revlog as a series of deltas,
3025 or patches against previous revisions.
3035 or patches against previous revisions.
3026 </p>
3036 </p>
3027 <p>
3037 <p>
3028 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3038 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3029 to signal the end of the delta group:
3039 to signal the end of the delta group:
3030 </p>
3040 </p>
3031 <pre>
3041 <pre>
3032 +------------------------------------------------------------------------+
3042 +------------------------------------------------------------------------+
3033 | | | | | |
3043 | | | | | |
3034 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3044 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3035 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
3045 | (32 bits) | (various) | (32 bits) | (various) | (32 bits) |
3036 | | | | | |
3046 | | | | | |
3037 +------------------------------------------------------------+-----------+
3047 +------------------------------------------------------------+-----------+
3038 </pre>
3048 </pre>
3039 <p>
3049 <p>
3040 Each *chunk*'s data consists of the following:
3050 Each *chunk*'s data consists of the following:
3041 </p>
3051 </p>
3042 <pre>
3052 <pre>
3043 +-----------------------------------------+
3053 +-----------------------------------------+
3044 | | | |
3054 | | | |
3045 | delta header | mdiff header | delta |
3055 | delta header | mdiff header | delta |
3046 | (various) | (12 bytes) | (various) |
3056 | (various) | (12 bytes) | (various) |
3047 | | | |
3057 | | | |
3048 +-----------------------------------------+
3058 +-----------------------------------------+
3049 </pre>
3059 </pre>
3050 <p>
3060 <p>
3051 The *length* field is the byte length of the remaining 3 logical pieces
3061 The *length* field is the byte length of the remaining 3 logical pieces
3052 of data. The *delta* is a diff from an existing entry in the changelog.
3062 of data. The *delta* is a diff from an existing entry in the changelog.
3053 </p>
3063 </p>
3054 <p>
3064 <p>
3055 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3065 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3056 &quot;3&quot; of the changegroup format.
3066 &quot;3&quot; of the changegroup format.
3057 </p>
3067 </p>
3058 <p>
3068 <p>
3059 Version 1:
3069 Version 1:
3060 </p>
3070 </p>
3061 <pre>
3071 <pre>
3062 +------------------------------------------------------+
3072 +------------------------------------------------------+
3063 | | | | |
3073 | | | | |
3064 | node | p1 node | p2 node | link node |
3074 | node | p1 node | p2 node | link node |
3065 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3075 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3066 | | | | |
3076 | | | | |
3067 +------------------------------------------------------+
3077 +------------------------------------------------------+
3068 </pre>
3078 </pre>
3069 <p>
3079 <p>
3070 Version 2:
3080 Version 2:
3071 </p>
3081 </p>
3072 <pre>
3082 <pre>
3073 +------------------------------------------------------------------+
3083 +------------------------------------------------------------------+
3074 | | | | | |
3084 | | | | | |
3075 | node | p1 node | p2 node | base node | link node |
3085 | node | p1 node | p2 node | base node | link node |
3076 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3086 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3077 | | | | | |
3087 | | | | | |
3078 +------------------------------------------------------------------+
3088 +------------------------------------------------------------------+
3079 </pre>
3089 </pre>
3080 <p>
3090 <p>
3081 Version 3:
3091 Version 3:
3082 </p>
3092 </p>
3083 <pre>
3093 <pre>
3084 +------------------------------------------------------------------------------+
3094 +------------------------------------------------------------------------------+
3085 | | | | | | |
3095 | | | | | | |
3086 | node | p1 node | p2 node | base node | link node | flags |
3096 | node | p1 node | p2 node | base node | link node | flags |
3087 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3097 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3088 | | | | | | |
3098 | | | | | | |
3089 +------------------------------------------------------------------------------+
3099 +------------------------------------------------------------------------------+
3090 </pre>
3100 </pre>
3091 <p>
3101 <p>
3092 The *mdiff header* consists of 3 32-bit big-endian signed integers
3102 The *mdiff header* consists of 3 32-bit big-endian signed integers
3093 describing offsets at which to apply the following delta content:
3103 describing offsets at which to apply the following delta content:
3094 </p>
3104 </p>
3095 <pre>
3105 <pre>
3096 +-------------------------------------+
3106 +-------------------------------------+
3097 | | | |
3107 | | | |
3098 | offset | old length | new length |
3108 | offset | old length | new length |
3099 | (32 bits) | (32 bits) | (32 bits) |
3109 | (32 bits) | (32 bits) | (32 bits) |
3100 | | | |
3110 | | | |
3101 +-------------------------------------+
3111 +-------------------------------------+
3102 </pre>
3112 </pre>
3103 <p>
3113 <p>
3104 In version 1, the delta is always applied against the previous node from
3114 In version 1, the delta is always applied against the previous node from
3105 the changegroup or the first parent if this is the first entry in the
3115 the changegroup or the first parent if this is the first entry in the
3106 changegroup.
3116 changegroup.
3107 </p>
3117 </p>
3108 <p>
3118 <p>
3109 In version 2, the delta base node is encoded in the entry in the
3119 In version 2, the delta base node is encoded in the entry in the
3110 changegroup. This allows the delta to be expressed against any parent,
3120 changegroup. This allows the delta to be expressed against any parent,
3111 which can result in smaller deltas and more efficient encoding of data.
3121 which can result in smaller deltas and more efficient encoding of data.
3112 </p>
3122 </p>
3113 <h2>Changeset Segment</h2>
3123 <h2>Changeset Segment</h2>
3114 <p>
3124 <p>
3115 The *changeset segment* consists of a single *delta group* holding
3125 The *changeset segment* consists of a single *delta group* holding
3116 changelog data. It is followed by an *empty chunk* to denote the
3126 changelog data. It is followed by an *empty chunk* to denote the
3117 boundary to the *manifests segment*.
3127 boundary to the *manifests segment*.
3118 </p>
3128 </p>
3119 <h2>Manifest Segment</h2>
3129 <h2>Manifest Segment</h2>
3120 <p>
3130 <p>
3121 The *manifest segment* consists of a single *delta group* holding
3131 The *manifest segment* consists of a single *delta group* holding
3122 manifest data. It is followed by an *empty chunk* to denote the boundary
3132 manifest data. It is followed by an *empty chunk* to denote the boundary
3123 to the *filelogs segment*.
3133 to the *filelogs segment*.
3124 </p>
3134 </p>
3125 <h2>Filelogs Segment</h2>
3135 <h2>Filelogs Segment</h2>
3126 <p>
3136 <p>
3127 The *filelogs* segment consists of multiple sub-segments, each
3137 The *filelogs* segment consists of multiple sub-segments, each
3128 corresponding to an individual file whose data is being described:
3138 corresponding to an individual file whose data is being described:
3129 </p>
3139 </p>
3130 <pre>
3140 <pre>
3131 +--------------------------------------+
3141 +--------------------------------------+
3132 | | | | |
3142 | | | | |
3133 | filelog0 | filelog1 | filelog2 | ... |
3143 | filelog0 | filelog1 | filelog2 | ... |
3134 | | | | |
3144 | | | | |
3135 +--------------------------------------+
3145 +--------------------------------------+
3136 </pre>
3146 </pre>
3137 <p>
3147 <p>
3138 In version &quot;3&quot; of the changegroup format, filelogs may include
3148 In version &quot;3&quot; of the changegroup format, filelogs may include
3139 directory logs when treemanifests are in use. directory logs are
3149 directory logs when treemanifests are in use. directory logs are
3140 identified by having a trailing '/' on their filename (see below).
3150 identified by having a trailing '/' on their filename (see below).
3141 </p>
3151 </p>
3142 <p>
3152 <p>
3143 The final filelog sub-segment is followed by an *empty chunk* to denote
3153 The final filelog sub-segment is followed by an *empty chunk* to denote
3144 the end of the segment and the overall changegroup.
3154 the end of the segment and the overall changegroup.
3145 </p>
3155 </p>
3146 <p>
3156 <p>
3147 Each filelog sub-segment consists of the following:
3157 Each filelog sub-segment consists of the following:
3148 </p>
3158 </p>
3149 <pre>
3159 <pre>
3150 +------------------------------------------+
3160 +------------------------------------------+
3151 | | | |
3161 | | | |
3152 | filename size | filename | delta group |
3162 | filename size | filename | delta group |
3153 | (32 bits) | (various) | (various) |
3163 | (32 bits) | (various) | (various) |
3154 | | | |
3164 | | | |
3155 +------------------------------------------+
3165 +------------------------------------------+
3156 </pre>
3166 </pre>
3157 <p>
3167 <p>
3158 That is, a *chunk* consisting of the filename (not terminated or padded)
3168 That is, a *chunk* consisting of the filename (not terminated or padded)
3159 followed by N chunks constituting the *delta group* for this file.
3169 followed by N chunks constituting the *delta group* for this file.
3160 </p>
3170 </p>
3161
3171
3162 </div>
3172 </div>
3163 </div>
3173 </div>
3164 </div>
3174 </div>
3165
3175
3166
3176
3167
3177
3168 </body>
3178 </body>
3169 </html>
3179 </html>
3170
3180
3171
3181
3172 $ killdaemons.py
3182 $ killdaemons.py
3173
3183
3174 #endif
3184 #endif
General Comments 0
You need to be logged in to leave comments. Login now