##// END OF EJS Templates
dirstate: add --minimal flag to debugrebuilddirstate...
Durham Goode -
r26024:84c00f03 default
parent child Browse files
Show More
@@ -1,6546 +1,6569 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 node import hex, bin, nullid, nullrev, short
8 from node import hex, bin, nullid, nullrev, short
9 from lock import release
9 from lock import release
10 from i18n import _
10 from i18n import _
11 import os, re, difflib, time, tempfile, errno, shlex
11 import os, re, difflib, time, tempfile, errno, shlex
12 import sys, socket
12 import sys, socket
13 import hg, scmutil, util, revlog, copies, error, bookmarks
13 import hg, scmutil, util, revlog, copies, error, bookmarks
14 import patch, help, encoding, templatekw, discovery
14 import patch, help, encoding, templatekw, discovery
15 import archival, changegroup, cmdutil, hbisect
15 import archival, changegroup, cmdutil, hbisect
16 import sshserver, hgweb
16 import sshserver, hgweb
17 import extensions
17 import extensions
18 from hgweb import server as hgweb_server
18 from hgweb import server as hgweb_server
19 import merge as mergemod
19 import merge as mergemod
20 import minirst, revset, fileset
20 import minirst, revset, fileset
21 import dagparser, context, simplemerge, graphmod, copies
21 import dagparser, context, simplemerge, graphmod, copies
22 import random
22 import random
23 import setdiscovery, treediscovery, dagutil, pvec, localrepo
23 import setdiscovery, treediscovery, dagutil, pvec, localrepo
24 import phases, obsolete, exchange, bundle2, repair, lock as lockmod
24 import phases, obsolete, exchange, bundle2, repair, lock as lockmod
25 import ui as uimod
25 import ui as uimod
26
26
27 table = {}
27 table = {}
28
28
29 command = cmdutil.command(table)
29 command = cmdutil.command(table)
30
30
31 # Space delimited list of commands that don't require local repositories.
31 # Space delimited list of commands that don't require local repositories.
32 # This should be populated by passing norepo=True into the @command decorator.
32 # This should be populated by passing norepo=True into the @command decorator.
33 norepo = ''
33 norepo = ''
34 # Space delimited list of commands that optionally require local repositories.
34 # Space delimited list of commands that optionally require local repositories.
35 # This should be populated by passing optionalrepo=True into the @command
35 # This should be populated by passing optionalrepo=True into the @command
36 # decorator.
36 # decorator.
37 optionalrepo = ''
37 optionalrepo = ''
38 # Space delimited list of commands that will examine arguments looking for
38 # Space delimited list of commands that will examine arguments looking for
39 # a repository. This should be populated by passing inferrepo=True into the
39 # a repository. This should be populated by passing inferrepo=True into the
40 # @command decorator.
40 # @command decorator.
41 inferrepo = ''
41 inferrepo = ''
42
42
43 # label constants
43 # label constants
44 # until 3.5, bookmarks.current was the advertised name, not
44 # until 3.5, bookmarks.current was the advertised name, not
45 # bookmarks.active, so we must use both to avoid breaking old
45 # bookmarks.active, so we must use both to avoid breaking old
46 # custom styles
46 # custom styles
47 activebookmarklabel = 'bookmarks.active bookmarks.current'
47 activebookmarklabel = 'bookmarks.active bookmarks.current'
48
48
49 # common command options
49 # common command options
50
50
51 globalopts = [
51 globalopts = [
52 ('R', 'repository', '',
52 ('R', 'repository', '',
53 _('repository root directory or name of overlay bundle file'),
53 _('repository root directory or name of overlay bundle file'),
54 _('REPO')),
54 _('REPO')),
55 ('', 'cwd', '',
55 ('', 'cwd', '',
56 _('change working directory'), _('DIR')),
56 _('change working directory'), _('DIR')),
57 ('y', 'noninteractive', None,
57 ('y', 'noninteractive', None,
58 _('do not prompt, automatically pick the first choice for all prompts')),
58 _('do not prompt, automatically pick the first choice for all prompts')),
59 ('q', 'quiet', None, _('suppress output')),
59 ('q', 'quiet', None, _('suppress output')),
60 ('v', 'verbose', None, _('enable additional output')),
60 ('v', 'verbose', None, _('enable additional output')),
61 ('', 'config', [],
61 ('', 'config', [],
62 _('set/override config option (use \'section.name=value\')'),
62 _('set/override config option (use \'section.name=value\')'),
63 _('CONFIG')),
63 _('CONFIG')),
64 ('', 'debug', None, _('enable debugging output')),
64 ('', 'debug', None, _('enable debugging output')),
65 ('', 'debugger', None, _('start debugger')),
65 ('', 'debugger', None, _('start debugger')),
66 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
66 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
67 _('ENCODE')),
67 _('ENCODE')),
68 ('', 'encodingmode', encoding.encodingmode,
68 ('', 'encodingmode', encoding.encodingmode,
69 _('set the charset encoding mode'), _('MODE')),
69 _('set the charset encoding mode'), _('MODE')),
70 ('', 'traceback', None, _('always print a traceback on exception')),
70 ('', 'traceback', None, _('always print a traceback on exception')),
71 ('', 'time', None, _('time how long the command takes')),
71 ('', 'time', None, _('time how long the command takes')),
72 ('', 'profile', None, _('print command execution profile')),
72 ('', 'profile', None, _('print command execution profile')),
73 ('', 'version', None, _('output version information and exit')),
73 ('', 'version', None, _('output version information and exit')),
74 ('h', 'help', None, _('display help and exit')),
74 ('h', 'help', None, _('display help and exit')),
75 ('', 'hidden', False, _('consider hidden changesets')),
75 ('', 'hidden', False, _('consider hidden changesets')),
76 ]
76 ]
77
77
78 dryrunopts = [('n', 'dry-run', None,
78 dryrunopts = [('n', 'dry-run', None,
79 _('do not perform actions, just print output'))]
79 _('do not perform actions, just print output'))]
80
80
81 remoteopts = [
81 remoteopts = [
82 ('e', 'ssh', '',
82 ('e', 'ssh', '',
83 _('specify ssh command to use'), _('CMD')),
83 _('specify ssh command to use'), _('CMD')),
84 ('', 'remotecmd', '',
84 ('', 'remotecmd', '',
85 _('specify hg command to run on the remote side'), _('CMD')),
85 _('specify hg command to run on the remote side'), _('CMD')),
86 ('', 'insecure', None,
86 ('', 'insecure', None,
87 _('do not verify server certificate (ignoring web.cacerts config)')),
87 _('do not verify server certificate (ignoring web.cacerts config)')),
88 ]
88 ]
89
89
90 walkopts = [
90 walkopts = [
91 ('I', 'include', [],
91 ('I', 'include', [],
92 _('include names matching the given patterns'), _('PATTERN')),
92 _('include names matching the given patterns'), _('PATTERN')),
93 ('X', 'exclude', [],
93 ('X', 'exclude', [],
94 _('exclude names matching the given patterns'), _('PATTERN')),
94 _('exclude names matching the given patterns'), _('PATTERN')),
95 ]
95 ]
96
96
97 commitopts = [
97 commitopts = [
98 ('m', 'message', '',
98 ('m', 'message', '',
99 _('use text as commit message'), _('TEXT')),
99 _('use text as commit message'), _('TEXT')),
100 ('l', 'logfile', '',
100 ('l', 'logfile', '',
101 _('read commit message from file'), _('FILE')),
101 _('read commit message from file'), _('FILE')),
102 ]
102 ]
103
103
104 commitopts2 = [
104 commitopts2 = [
105 ('d', 'date', '',
105 ('d', 'date', '',
106 _('record the specified date as commit date'), _('DATE')),
106 _('record the specified date as commit date'), _('DATE')),
107 ('u', 'user', '',
107 ('u', 'user', '',
108 _('record the specified user as committer'), _('USER')),
108 _('record the specified user as committer'), _('USER')),
109 ]
109 ]
110
110
111 # hidden for now
111 # hidden for now
112 formatteropts = [
112 formatteropts = [
113 ('T', 'template', '',
113 ('T', 'template', '',
114 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
114 _('display with template (EXPERIMENTAL)'), _('TEMPLATE')),
115 ]
115 ]
116
116
117 templateopts = [
117 templateopts = [
118 ('', 'style', '',
118 ('', 'style', '',
119 _('display using template map file (DEPRECATED)'), _('STYLE')),
119 _('display using template map file (DEPRECATED)'), _('STYLE')),
120 ('T', 'template', '',
120 ('T', 'template', '',
121 _('display with template'), _('TEMPLATE')),
121 _('display with template'), _('TEMPLATE')),
122 ]
122 ]
123
123
124 logopts = [
124 logopts = [
125 ('p', 'patch', None, _('show patch')),
125 ('p', 'patch', None, _('show patch')),
126 ('g', 'git', None, _('use git extended diff format')),
126 ('g', 'git', None, _('use git extended diff format')),
127 ('l', 'limit', '',
127 ('l', 'limit', '',
128 _('limit number of changes displayed'), _('NUM')),
128 _('limit number of changes displayed'), _('NUM')),
129 ('M', 'no-merges', None, _('do not show merges')),
129 ('M', 'no-merges', None, _('do not show merges')),
130 ('', 'stat', None, _('output diffstat-style summary of changes')),
130 ('', 'stat', None, _('output diffstat-style summary of changes')),
131 ('G', 'graph', None, _("show the revision DAG")),
131 ('G', 'graph', None, _("show the revision DAG")),
132 ] + templateopts
132 ] + templateopts
133
133
134 diffopts = [
134 diffopts = [
135 ('a', 'text', None, _('treat all files as text')),
135 ('a', 'text', None, _('treat all files as text')),
136 ('g', 'git', None, _('use git extended diff format')),
136 ('g', 'git', None, _('use git extended diff format')),
137 ('', 'nodates', None, _('omit dates from diff headers'))
137 ('', 'nodates', None, _('omit dates from diff headers'))
138 ]
138 ]
139
139
140 diffwsopts = [
140 diffwsopts = [
141 ('w', 'ignore-all-space', None,
141 ('w', 'ignore-all-space', None,
142 _('ignore white space when comparing lines')),
142 _('ignore white space when comparing lines')),
143 ('b', 'ignore-space-change', None,
143 ('b', 'ignore-space-change', None,
144 _('ignore changes in the amount of white space')),
144 _('ignore changes in the amount of white space')),
145 ('B', 'ignore-blank-lines', None,
145 ('B', 'ignore-blank-lines', None,
146 _('ignore changes whose lines are all blank')),
146 _('ignore changes whose lines are all blank')),
147 ]
147 ]
148
148
149 diffopts2 = [
149 diffopts2 = [
150 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
150 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
151 ('p', 'show-function', None, _('show which function each change is in')),
151 ('p', 'show-function', None, _('show which function each change is in')),
152 ('', 'reverse', None, _('produce a diff that undoes the changes')),
152 ('', 'reverse', None, _('produce a diff that undoes the changes')),
153 ] + diffwsopts + [
153 ] + diffwsopts + [
154 ('U', 'unified', '',
154 ('U', 'unified', '',
155 _('number of lines of context to show'), _('NUM')),
155 _('number of lines of context to show'), _('NUM')),
156 ('', 'stat', None, _('output diffstat-style summary of changes')),
156 ('', 'stat', None, _('output diffstat-style summary of changes')),
157 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
157 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
158 ]
158 ]
159
159
160 mergetoolopts = [
160 mergetoolopts = [
161 ('t', 'tool', '', _('specify merge tool')),
161 ('t', 'tool', '', _('specify merge tool')),
162 ]
162 ]
163
163
164 similarityopts = [
164 similarityopts = [
165 ('s', 'similarity', '',
165 ('s', 'similarity', '',
166 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
166 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
167 ]
167 ]
168
168
169 subrepoopts = [
169 subrepoopts = [
170 ('S', 'subrepos', None,
170 ('S', 'subrepos', None,
171 _('recurse into subrepositories'))
171 _('recurse into subrepositories'))
172 ]
172 ]
173
173
174 # Commands start here, listed alphabetically
174 # Commands start here, listed alphabetically
175
175
176 @command('^add',
176 @command('^add',
177 walkopts + subrepoopts + dryrunopts,
177 walkopts + subrepoopts + dryrunopts,
178 _('[OPTION]... [FILE]...'),
178 _('[OPTION]... [FILE]...'),
179 inferrepo=True)
179 inferrepo=True)
180 def add(ui, repo, *pats, **opts):
180 def add(ui, repo, *pats, **opts):
181 """add the specified files on the next commit
181 """add the specified files on the next commit
182
182
183 Schedule files to be version controlled and added to the
183 Schedule files to be version controlled and added to the
184 repository.
184 repository.
185
185
186 The files will be added to the repository at the next commit. To
186 The files will be added to the repository at the next commit. To
187 undo an add before that, see :hg:`forget`.
187 undo an add before that, see :hg:`forget`.
188
188
189 If no names are given, add all files to the repository.
189 If no names are given, add all files to the repository.
190
190
191 .. container:: verbose
191 .. container:: verbose
192
192
193 An example showing how new (unknown) files are added
193 An example showing how new (unknown) files are added
194 automatically by :hg:`add`::
194 automatically by :hg:`add`::
195
195
196 $ ls
196 $ ls
197 foo.c
197 foo.c
198 $ hg status
198 $ hg status
199 ? foo.c
199 ? foo.c
200 $ hg add
200 $ hg add
201 adding foo.c
201 adding foo.c
202 $ hg status
202 $ hg status
203 A foo.c
203 A foo.c
204
204
205 Returns 0 if all files are successfully added.
205 Returns 0 if all files are successfully added.
206 """
206 """
207
207
208 m = scmutil.match(repo[None], pats, opts)
208 m = scmutil.match(repo[None], pats, opts)
209 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
209 rejected = cmdutil.add(ui, repo, m, "", False, **opts)
210 return rejected and 1 or 0
210 return rejected and 1 or 0
211
211
212 @command('addremove',
212 @command('addremove',
213 similarityopts + subrepoopts + walkopts + dryrunopts,
213 similarityopts + subrepoopts + walkopts + dryrunopts,
214 _('[OPTION]... [FILE]...'),
214 _('[OPTION]... [FILE]...'),
215 inferrepo=True)
215 inferrepo=True)
216 def addremove(ui, repo, *pats, **opts):
216 def addremove(ui, repo, *pats, **opts):
217 """add all new files, delete all missing files
217 """add all new files, delete all missing files
218
218
219 Add all new files and remove all missing files from the
219 Add all new files and remove all missing files from the
220 repository.
220 repository.
221
221
222 New files are ignored if they match any of the patterns in
222 New files are ignored if they match any of the patterns in
223 ``.hgignore``. As with add, these changes take effect at the next
223 ``.hgignore``. As with add, these changes take effect at the next
224 commit.
224 commit.
225
225
226 Use the -s/--similarity option to detect renamed files. This
226 Use the -s/--similarity option to detect renamed files. This
227 option takes a percentage between 0 (disabled) and 100 (files must
227 option takes a percentage between 0 (disabled) and 100 (files must
228 be identical) as its parameter. With a parameter greater than 0,
228 be identical) as its parameter. With a parameter greater than 0,
229 this compares every removed file with every added file and records
229 this compares every removed file with every added file and records
230 those similar enough as renames. Detecting renamed files this way
230 those similar enough as renames. Detecting renamed files this way
231 can be expensive. After using this option, :hg:`status -C` can be
231 can be expensive. After using this option, :hg:`status -C` can be
232 used to check which files were identified as moved or renamed. If
232 used to check which files were identified as moved or renamed. If
233 not specified, -s/--similarity defaults to 100 and only renames of
233 not specified, -s/--similarity defaults to 100 and only renames of
234 identical files are detected.
234 identical files are detected.
235
235
236 Returns 0 if all files are successfully added.
236 Returns 0 if all files are successfully added.
237 """
237 """
238 try:
238 try:
239 sim = float(opts.get('similarity') or 100)
239 sim = float(opts.get('similarity') or 100)
240 except ValueError:
240 except ValueError:
241 raise util.Abort(_('similarity must be a number'))
241 raise util.Abort(_('similarity must be a number'))
242 if sim < 0 or sim > 100:
242 if sim < 0 or sim > 100:
243 raise util.Abort(_('similarity must be between 0 and 100'))
243 raise util.Abort(_('similarity must be between 0 and 100'))
244 matcher = scmutil.match(repo[None], pats, opts)
244 matcher = scmutil.match(repo[None], pats, opts)
245 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
245 return scmutil.addremove(repo, matcher, "", opts, similarity=sim / 100.0)
246
246
247 @command('^annotate|blame',
247 @command('^annotate|blame',
248 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
248 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
249 ('', 'follow', None,
249 ('', 'follow', None,
250 _('follow copies/renames and list the filename (DEPRECATED)')),
250 _('follow copies/renames and list the filename (DEPRECATED)')),
251 ('', 'no-follow', None, _("don't follow copies and renames")),
251 ('', 'no-follow', None, _("don't follow copies and renames")),
252 ('a', 'text', None, _('treat all files as text')),
252 ('a', 'text', None, _('treat all files as text')),
253 ('u', 'user', None, _('list the author (long with -v)')),
253 ('u', 'user', None, _('list the author (long with -v)')),
254 ('f', 'file', None, _('list the filename')),
254 ('f', 'file', None, _('list the filename')),
255 ('d', 'date', None, _('list the date (short with -q)')),
255 ('d', 'date', None, _('list the date (short with -q)')),
256 ('n', 'number', None, _('list the revision number (default)')),
256 ('n', 'number', None, _('list the revision number (default)')),
257 ('c', 'changeset', None, _('list the changeset')),
257 ('c', 'changeset', None, _('list the changeset')),
258 ('l', 'line-number', None, _('show line number at the first appearance'))
258 ('l', 'line-number', None, _('show line number at the first appearance'))
259 ] + diffwsopts + walkopts + formatteropts,
259 ] + diffwsopts + walkopts + formatteropts,
260 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
260 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
261 inferrepo=True)
261 inferrepo=True)
262 def annotate(ui, repo, *pats, **opts):
262 def annotate(ui, repo, *pats, **opts):
263 """show changeset information by line for each file
263 """show changeset information by line for each file
264
264
265 List changes in files, showing the revision id responsible for
265 List changes in files, showing the revision id responsible for
266 each line
266 each line
267
267
268 This command is useful for discovering when a change was made and
268 This command is useful for discovering when a change was made and
269 by whom.
269 by whom.
270
270
271 Without the -a/--text option, annotate will avoid processing files
271 Without the -a/--text option, annotate will avoid processing files
272 it detects as binary. With -a, annotate will annotate the file
272 it detects as binary. With -a, annotate will annotate the file
273 anyway, although the results will probably be neither useful
273 anyway, although the results will probably be neither useful
274 nor desirable.
274 nor desirable.
275
275
276 Returns 0 on success.
276 Returns 0 on success.
277 """
277 """
278 if not pats:
278 if not pats:
279 raise util.Abort(_('at least one filename or pattern is required'))
279 raise util.Abort(_('at least one filename or pattern is required'))
280
280
281 if opts.get('follow'):
281 if opts.get('follow'):
282 # --follow is deprecated and now just an alias for -f/--file
282 # --follow is deprecated and now just an alias for -f/--file
283 # to mimic the behavior of Mercurial before version 1.5
283 # to mimic the behavior of Mercurial before version 1.5
284 opts['file'] = True
284 opts['file'] = True
285
285
286 ctx = scmutil.revsingle(repo, opts.get('rev'))
286 ctx = scmutil.revsingle(repo, opts.get('rev'))
287
287
288 fm = ui.formatter('annotate', opts)
288 fm = ui.formatter('annotate', opts)
289 if ui.quiet:
289 if ui.quiet:
290 datefunc = util.shortdate
290 datefunc = util.shortdate
291 else:
291 else:
292 datefunc = util.datestr
292 datefunc = util.datestr
293 if ctx.rev() is None:
293 if ctx.rev() is None:
294 def hexfn(node):
294 def hexfn(node):
295 if node is None:
295 if node is None:
296 return None
296 return None
297 else:
297 else:
298 return fm.hexfunc(node)
298 return fm.hexfunc(node)
299 if opts.get('changeset'):
299 if opts.get('changeset'):
300 # omit "+" suffix which is appended to node hex
300 # omit "+" suffix which is appended to node hex
301 def formatrev(rev):
301 def formatrev(rev):
302 if rev is None:
302 if rev is None:
303 return '%d' % ctx.p1().rev()
303 return '%d' % ctx.p1().rev()
304 else:
304 else:
305 return '%d' % rev
305 return '%d' % rev
306 else:
306 else:
307 def formatrev(rev):
307 def formatrev(rev):
308 if rev is None:
308 if rev is None:
309 return '%d+' % ctx.p1().rev()
309 return '%d+' % ctx.p1().rev()
310 else:
310 else:
311 return '%d ' % rev
311 return '%d ' % rev
312 def formathex(hex):
312 def formathex(hex):
313 if hex is None:
313 if hex is None:
314 return '%s+' % fm.hexfunc(ctx.p1().node())
314 return '%s+' % fm.hexfunc(ctx.p1().node())
315 else:
315 else:
316 return '%s ' % hex
316 return '%s ' % hex
317 else:
317 else:
318 hexfn = fm.hexfunc
318 hexfn = fm.hexfunc
319 formatrev = formathex = str
319 formatrev = formathex = str
320
320
321 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
321 opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
322 ('number', ' ', lambda x: x[0].rev(), formatrev),
322 ('number', ' ', lambda x: x[0].rev(), formatrev),
323 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
323 ('changeset', ' ', lambda x: hexfn(x[0].node()), formathex),
324 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
324 ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
325 ('file', ' ', lambda x: x[0].path(), str),
325 ('file', ' ', lambda x: x[0].path(), str),
326 ('line_number', ':', lambda x: x[1], str),
326 ('line_number', ':', lambda x: x[1], str),
327 ]
327 ]
328 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
328 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
329
329
330 if (not opts.get('user') and not opts.get('changeset')
330 if (not opts.get('user') and not opts.get('changeset')
331 and not opts.get('date') and not opts.get('file')):
331 and not opts.get('date') and not opts.get('file')):
332 opts['number'] = True
332 opts['number'] = True
333
333
334 linenumber = opts.get('line_number') is not None
334 linenumber = opts.get('line_number') is not None
335 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
335 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
336 raise util.Abort(_('at least one of -n/-c is required for -l'))
336 raise util.Abort(_('at least one of -n/-c is required for -l'))
337
337
338 if fm:
338 if fm:
339 def makefunc(get, fmt):
339 def makefunc(get, fmt):
340 return get
340 return get
341 else:
341 else:
342 def makefunc(get, fmt):
342 def makefunc(get, fmt):
343 return lambda x: fmt(get(x))
343 return lambda x: fmt(get(x))
344 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
344 funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
345 if opts.get(op)]
345 if opts.get(op)]
346 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
346 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
347 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
347 fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
348 if opts.get(op))
348 if opts.get(op))
349
349
350 def bad(x, y):
350 def bad(x, y):
351 raise util.Abort("%s: %s" % (x, y))
351 raise util.Abort("%s: %s" % (x, y))
352
352
353 m = scmutil.match(ctx, pats, opts, badfn=bad)
353 m = scmutil.match(ctx, pats, opts, badfn=bad)
354
354
355 follow = not opts.get('no_follow')
355 follow = not opts.get('no_follow')
356 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
356 diffopts = patch.difffeatureopts(ui, opts, section='annotate',
357 whitespace=True)
357 whitespace=True)
358 for abs in ctx.walk(m):
358 for abs in ctx.walk(m):
359 fctx = ctx[abs]
359 fctx = ctx[abs]
360 if not opts.get('text') and util.binary(fctx.data()):
360 if not opts.get('text') and util.binary(fctx.data()):
361 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
361 fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
362 continue
362 continue
363
363
364 lines = fctx.annotate(follow=follow, linenumber=linenumber,
364 lines = fctx.annotate(follow=follow, linenumber=linenumber,
365 diffopts=diffopts)
365 diffopts=diffopts)
366 formats = []
366 formats = []
367 pieces = []
367 pieces = []
368
368
369 for f, sep in funcmap:
369 for f, sep in funcmap:
370 l = [f(n) for n, dummy in lines]
370 l = [f(n) for n, dummy in lines]
371 if l:
371 if l:
372 if fm:
372 if fm:
373 formats.append(['%s' for x in l])
373 formats.append(['%s' for x in l])
374 else:
374 else:
375 sizes = [encoding.colwidth(x) for x in l]
375 sizes = [encoding.colwidth(x) for x in l]
376 ml = max(sizes)
376 ml = max(sizes)
377 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
377 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
378 pieces.append(l)
378 pieces.append(l)
379
379
380 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
380 for f, p, l in zip(zip(*formats), zip(*pieces), lines):
381 fm.startitem()
381 fm.startitem()
382 fm.write(fields, "".join(f), *p)
382 fm.write(fields, "".join(f), *p)
383 fm.write('line', ": %s", l[1])
383 fm.write('line', ": %s", l[1])
384
384
385 if lines and not lines[-1][1].endswith('\n'):
385 if lines and not lines[-1][1].endswith('\n'):
386 fm.plain('\n')
386 fm.plain('\n')
387
387
388 fm.end()
388 fm.end()
389
389
390 @command('archive',
390 @command('archive',
391 [('', 'no-decode', None, _('do not pass files through decoders')),
391 [('', 'no-decode', None, _('do not pass files through decoders')),
392 ('p', 'prefix', '', _('directory prefix for files in archive'),
392 ('p', 'prefix', '', _('directory prefix for files in archive'),
393 _('PREFIX')),
393 _('PREFIX')),
394 ('r', 'rev', '', _('revision to distribute'), _('REV')),
394 ('r', 'rev', '', _('revision to distribute'), _('REV')),
395 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
395 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
396 ] + subrepoopts + walkopts,
396 ] + subrepoopts + walkopts,
397 _('[OPTION]... DEST'))
397 _('[OPTION]... DEST'))
398 def archive(ui, repo, dest, **opts):
398 def archive(ui, repo, dest, **opts):
399 '''create an unversioned archive of a repository revision
399 '''create an unversioned archive of a repository revision
400
400
401 By default, the revision used is the parent of the working
401 By default, the revision used is the parent of the working
402 directory; use -r/--rev to specify a different revision.
402 directory; use -r/--rev to specify a different revision.
403
403
404 The archive type is automatically detected based on file
404 The archive type is automatically detected based on file
405 extension (or override using -t/--type).
405 extension (or override using -t/--type).
406
406
407 .. container:: verbose
407 .. container:: verbose
408
408
409 Examples:
409 Examples:
410
410
411 - create a zip file containing the 1.0 release::
411 - create a zip file containing the 1.0 release::
412
412
413 hg archive -r 1.0 project-1.0.zip
413 hg archive -r 1.0 project-1.0.zip
414
414
415 - create a tarball excluding .hg files::
415 - create a tarball excluding .hg files::
416
416
417 hg archive project.tar.gz -X ".hg*"
417 hg archive project.tar.gz -X ".hg*"
418
418
419 Valid types are:
419 Valid types are:
420
420
421 :``files``: a directory full of files (default)
421 :``files``: a directory full of files (default)
422 :``tar``: tar archive, uncompressed
422 :``tar``: tar archive, uncompressed
423 :``tbz2``: tar archive, compressed using bzip2
423 :``tbz2``: tar archive, compressed using bzip2
424 :``tgz``: tar archive, compressed using gzip
424 :``tgz``: tar archive, compressed using gzip
425 :``uzip``: zip archive, uncompressed
425 :``uzip``: zip archive, uncompressed
426 :``zip``: zip archive, compressed using deflate
426 :``zip``: zip archive, compressed using deflate
427
427
428 The exact name of the destination archive or directory is given
428 The exact name of the destination archive or directory is given
429 using a format string; see :hg:`help export` for details.
429 using a format string; see :hg:`help export` for details.
430
430
431 Each member added to an archive file has a directory prefix
431 Each member added to an archive file has a directory prefix
432 prepended. Use -p/--prefix to specify a format string for the
432 prepended. Use -p/--prefix to specify a format string for the
433 prefix. The default is the basename of the archive, with suffixes
433 prefix. The default is the basename of the archive, with suffixes
434 removed.
434 removed.
435
435
436 Returns 0 on success.
436 Returns 0 on success.
437 '''
437 '''
438
438
439 ctx = scmutil.revsingle(repo, opts.get('rev'))
439 ctx = scmutil.revsingle(repo, opts.get('rev'))
440 if not ctx:
440 if not ctx:
441 raise util.Abort(_('no working directory: please specify a revision'))
441 raise util.Abort(_('no working directory: please specify a revision'))
442 node = ctx.node()
442 node = ctx.node()
443 dest = cmdutil.makefilename(repo, dest, node)
443 dest = cmdutil.makefilename(repo, dest, node)
444 if os.path.realpath(dest) == repo.root:
444 if os.path.realpath(dest) == repo.root:
445 raise util.Abort(_('repository root cannot be destination'))
445 raise util.Abort(_('repository root cannot be destination'))
446
446
447 kind = opts.get('type') or archival.guesskind(dest) or 'files'
447 kind = opts.get('type') or archival.guesskind(dest) or 'files'
448 prefix = opts.get('prefix')
448 prefix = opts.get('prefix')
449
449
450 if dest == '-':
450 if dest == '-':
451 if kind == 'files':
451 if kind == 'files':
452 raise util.Abort(_('cannot archive plain files to stdout'))
452 raise util.Abort(_('cannot archive plain files to stdout'))
453 dest = cmdutil.makefileobj(repo, dest)
453 dest = cmdutil.makefileobj(repo, dest)
454 if not prefix:
454 if not prefix:
455 prefix = os.path.basename(repo.root) + '-%h'
455 prefix = os.path.basename(repo.root) + '-%h'
456
456
457 prefix = cmdutil.makefilename(repo, prefix, node)
457 prefix = cmdutil.makefilename(repo, prefix, node)
458 matchfn = scmutil.match(ctx, [], opts)
458 matchfn = scmutil.match(ctx, [], opts)
459 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
459 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
460 matchfn, prefix, subrepos=opts.get('subrepos'))
460 matchfn, prefix, subrepos=opts.get('subrepos'))
461
461
462 @command('backout',
462 @command('backout',
463 [('', 'merge', None, _('merge with old dirstate parent after backout')),
463 [('', 'merge', None, _('merge with old dirstate parent after backout')),
464 ('', 'commit', None, _('commit if no conflicts were encountered')),
464 ('', 'commit', None, _('commit if no conflicts were encountered')),
465 ('', 'parent', '',
465 ('', 'parent', '',
466 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
466 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
467 ('r', 'rev', '', _('revision to backout'), _('REV')),
467 ('r', 'rev', '', _('revision to backout'), _('REV')),
468 ('e', 'edit', False, _('invoke editor on commit messages')),
468 ('e', 'edit', False, _('invoke editor on commit messages')),
469 ] + mergetoolopts + walkopts + commitopts + commitopts2,
469 ] + mergetoolopts + walkopts + commitopts + commitopts2,
470 _('[OPTION]... [-r] REV'))
470 _('[OPTION]... [-r] REV'))
471 def backout(ui, repo, node=None, rev=None, commit=False, **opts):
471 def backout(ui, repo, node=None, rev=None, commit=False, **opts):
472 '''reverse effect of earlier changeset
472 '''reverse effect of earlier changeset
473
473
474 Prepare a new changeset with the effect of REV undone in the
474 Prepare a new changeset with the effect of REV undone in the
475 current working directory.
475 current working directory.
476
476
477 If REV is the parent of the working directory, then this new changeset
477 If REV is the parent of the working directory, then this new changeset
478 is committed automatically. Otherwise, hg needs to merge the
478 is committed automatically. Otherwise, hg needs to merge the
479 changes and the merged result is left uncommitted.
479 changes and the merged result is left uncommitted.
480
480
481 .. note::
481 .. note::
482
482
483 backout cannot be used to fix either an unwanted or
483 backout cannot be used to fix either an unwanted or
484 incorrect merge.
484 incorrect merge.
485
485
486 .. container:: verbose
486 .. container:: verbose
487
487
488 By default, the pending changeset will have one parent,
488 By default, the pending changeset will have one parent,
489 maintaining a linear history. With --merge, the pending
489 maintaining a linear history. With --merge, the pending
490 changeset will instead have two parents: the old parent of the
490 changeset will instead have two parents: the old parent of the
491 working directory and a new child of REV that simply undoes REV.
491 working directory and a new child of REV that simply undoes REV.
492
492
493 Before version 1.7, the behavior without --merge was equivalent
493 Before version 1.7, the behavior without --merge was equivalent
494 to specifying --merge followed by :hg:`update --clean .` to
494 to specifying --merge followed by :hg:`update --clean .` to
495 cancel the merge and leave the child of REV as a head to be
495 cancel the merge and leave the child of REV as a head to be
496 merged separately.
496 merged separately.
497
497
498 See :hg:`help dates` for a list of formats valid for -d/--date.
498 See :hg:`help dates` for a list of formats valid for -d/--date.
499
499
500 Returns 0 on success, 1 if nothing to backout or there are unresolved
500 Returns 0 on success, 1 if nothing to backout or there are unresolved
501 files.
501 files.
502 '''
502 '''
503 if rev and node:
503 if rev and node:
504 raise util.Abort(_("please specify just one revision"))
504 raise util.Abort(_("please specify just one revision"))
505
505
506 if not rev:
506 if not rev:
507 rev = node
507 rev = node
508
508
509 if not rev:
509 if not rev:
510 raise util.Abort(_("please specify a revision to backout"))
510 raise util.Abort(_("please specify a revision to backout"))
511
511
512 date = opts.get('date')
512 date = opts.get('date')
513 if date:
513 if date:
514 opts['date'] = util.parsedate(date)
514 opts['date'] = util.parsedate(date)
515
515
516 cmdutil.checkunfinished(repo)
516 cmdutil.checkunfinished(repo)
517 cmdutil.bailifchanged(repo)
517 cmdutil.bailifchanged(repo)
518 node = scmutil.revsingle(repo, rev).node()
518 node = scmutil.revsingle(repo, rev).node()
519
519
520 op1, op2 = repo.dirstate.parents()
520 op1, op2 = repo.dirstate.parents()
521 if not repo.changelog.isancestor(node, op1):
521 if not repo.changelog.isancestor(node, op1):
522 raise util.Abort(_('cannot backout change that is not an ancestor'))
522 raise util.Abort(_('cannot backout change that is not an ancestor'))
523
523
524 p1, p2 = repo.changelog.parents(node)
524 p1, p2 = repo.changelog.parents(node)
525 if p1 == nullid:
525 if p1 == nullid:
526 raise util.Abort(_('cannot backout a change with no parents'))
526 raise util.Abort(_('cannot backout a change with no parents'))
527 if p2 != nullid:
527 if p2 != nullid:
528 if not opts.get('parent'):
528 if not opts.get('parent'):
529 raise util.Abort(_('cannot backout a merge changeset'))
529 raise util.Abort(_('cannot backout a merge changeset'))
530 p = repo.lookup(opts['parent'])
530 p = repo.lookup(opts['parent'])
531 if p not in (p1, p2):
531 if p not in (p1, p2):
532 raise util.Abort(_('%s is not a parent of %s') %
532 raise util.Abort(_('%s is not a parent of %s') %
533 (short(p), short(node)))
533 (short(p), short(node)))
534 parent = p
534 parent = p
535 else:
535 else:
536 if opts.get('parent'):
536 if opts.get('parent'):
537 raise util.Abort(_('cannot use --parent on non-merge changeset'))
537 raise util.Abort(_('cannot use --parent on non-merge changeset'))
538 parent = p1
538 parent = p1
539
539
540 # the backout should appear on the same branch
540 # the backout should appear on the same branch
541 wlock = repo.wlock()
541 wlock = repo.wlock()
542 try:
542 try:
543 branch = repo.dirstate.branch()
543 branch = repo.dirstate.branch()
544 bheads = repo.branchheads(branch)
544 bheads = repo.branchheads(branch)
545 rctx = scmutil.revsingle(repo, hex(parent))
545 rctx = scmutil.revsingle(repo, hex(parent))
546 if not opts.get('merge') and op1 != node:
546 if not opts.get('merge') and op1 != node:
547 try:
547 try:
548 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
548 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
549 'backout')
549 'backout')
550 repo.dirstate.beginparentchange()
550 repo.dirstate.beginparentchange()
551 stats = mergemod.update(repo, parent, True, True, False,
551 stats = mergemod.update(repo, parent, True, True, False,
552 node, False)
552 node, False)
553 repo.setparents(op1, op2)
553 repo.setparents(op1, op2)
554 repo.dirstate.endparentchange()
554 repo.dirstate.endparentchange()
555 hg._showstats(repo, stats)
555 hg._showstats(repo, stats)
556 if stats[3]:
556 if stats[3]:
557 repo.ui.status(_("use 'hg resolve' to retry unresolved "
557 repo.ui.status(_("use 'hg resolve' to retry unresolved "
558 "file merges\n"))
558 "file merges\n"))
559 return 1
559 return 1
560 elif not commit:
560 elif not commit:
561 msg = _("changeset %s backed out, "
561 msg = _("changeset %s backed out, "
562 "don't forget to commit.\n")
562 "don't forget to commit.\n")
563 ui.status(msg % short(node))
563 ui.status(msg % short(node))
564 return 0
564 return 0
565 finally:
565 finally:
566 ui.setconfig('ui', 'forcemerge', '', '')
566 ui.setconfig('ui', 'forcemerge', '', '')
567 else:
567 else:
568 hg.clean(repo, node, show_stats=False)
568 hg.clean(repo, node, show_stats=False)
569 repo.dirstate.setbranch(branch)
569 repo.dirstate.setbranch(branch)
570 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
570 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
571
571
572
572
573 def commitfunc(ui, repo, message, match, opts):
573 def commitfunc(ui, repo, message, match, opts):
574 editform = 'backout'
574 editform = 'backout'
575 e = cmdutil.getcommiteditor(editform=editform, **opts)
575 e = cmdutil.getcommiteditor(editform=editform, **opts)
576 if not message:
576 if not message:
577 # we don't translate commit messages
577 # we don't translate commit messages
578 message = "Backed out changeset %s" % short(node)
578 message = "Backed out changeset %s" % short(node)
579 e = cmdutil.getcommiteditor(edit=True, editform=editform)
579 e = cmdutil.getcommiteditor(edit=True, editform=editform)
580 return repo.commit(message, opts.get('user'), opts.get('date'),
580 return repo.commit(message, opts.get('user'), opts.get('date'),
581 match, editor=e)
581 match, editor=e)
582 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
582 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
583 if not newnode:
583 if not newnode:
584 ui.status(_("nothing changed\n"))
584 ui.status(_("nothing changed\n"))
585 return 1
585 return 1
586 cmdutil.commitstatus(repo, newnode, branch, bheads)
586 cmdutil.commitstatus(repo, newnode, branch, bheads)
587
587
588 def nice(node):
588 def nice(node):
589 return '%d:%s' % (repo.changelog.rev(node), short(node))
589 return '%d:%s' % (repo.changelog.rev(node), short(node))
590 ui.status(_('changeset %s backs out changeset %s\n') %
590 ui.status(_('changeset %s backs out changeset %s\n') %
591 (nice(repo.changelog.tip()), nice(node)))
591 (nice(repo.changelog.tip()), nice(node)))
592 if opts.get('merge') and op1 != node:
592 if opts.get('merge') and op1 != node:
593 hg.clean(repo, op1, show_stats=False)
593 hg.clean(repo, op1, show_stats=False)
594 ui.status(_('merging with changeset %s\n')
594 ui.status(_('merging with changeset %s\n')
595 % nice(repo.changelog.tip()))
595 % nice(repo.changelog.tip()))
596 try:
596 try:
597 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
597 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
598 'backout')
598 'backout')
599 return hg.merge(repo, hex(repo.changelog.tip()))
599 return hg.merge(repo, hex(repo.changelog.tip()))
600 finally:
600 finally:
601 ui.setconfig('ui', 'forcemerge', '', '')
601 ui.setconfig('ui', 'forcemerge', '', '')
602 finally:
602 finally:
603 wlock.release()
603 wlock.release()
604 return 0
604 return 0
605
605
606 @command('bisect',
606 @command('bisect',
607 [('r', 'reset', False, _('reset bisect state')),
607 [('r', 'reset', False, _('reset bisect state')),
608 ('g', 'good', False, _('mark changeset good')),
608 ('g', 'good', False, _('mark changeset good')),
609 ('b', 'bad', False, _('mark changeset bad')),
609 ('b', 'bad', False, _('mark changeset bad')),
610 ('s', 'skip', False, _('skip testing changeset')),
610 ('s', 'skip', False, _('skip testing changeset')),
611 ('e', 'extend', False, _('extend the bisect range')),
611 ('e', 'extend', False, _('extend the bisect range')),
612 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
612 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
613 ('U', 'noupdate', False, _('do not update to target'))],
613 ('U', 'noupdate', False, _('do not update to target'))],
614 _("[-gbsr] [-U] [-c CMD] [REV]"))
614 _("[-gbsr] [-U] [-c CMD] [REV]"))
615 def bisect(ui, repo, rev=None, extra=None, command=None,
615 def bisect(ui, repo, rev=None, extra=None, command=None,
616 reset=None, good=None, bad=None, skip=None, extend=None,
616 reset=None, good=None, bad=None, skip=None, extend=None,
617 noupdate=None):
617 noupdate=None):
618 """subdivision search of changesets
618 """subdivision search of changesets
619
619
620 This command helps to find changesets which introduce problems. To
620 This command helps to find changesets which introduce problems. To
621 use, mark the earliest changeset you know exhibits the problem as
621 use, mark the earliest changeset you know exhibits the problem as
622 bad, then mark the latest changeset which is free from the problem
622 bad, then mark the latest changeset which is free from the problem
623 as good. Bisect will update your working directory to a revision
623 as good. Bisect will update your working directory to a revision
624 for testing (unless the -U/--noupdate option is specified). Once
624 for testing (unless the -U/--noupdate option is specified). Once
625 you have performed tests, mark the working directory as good or
625 you have performed tests, mark the working directory as good or
626 bad, and bisect will either update to another candidate changeset
626 bad, and bisect will either update to another candidate changeset
627 or announce that it has found the bad revision.
627 or announce that it has found the bad revision.
628
628
629 As a shortcut, you can also use the revision argument to mark a
629 As a shortcut, you can also use the revision argument to mark a
630 revision as good or bad without checking it out first.
630 revision as good or bad without checking it out first.
631
631
632 If you supply a command, it will be used for automatic bisection.
632 If you supply a command, it will be used for automatic bisection.
633 The environment variable HG_NODE will contain the ID of the
633 The environment variable HG_NODE will contain the ID of the
634 changeset being tested. The exit status of the command will be
634 changeset being tested. The exit status of the command will be
635 used to mark revisions as good or bad: status 0 means good, 125
635 used to mark revisions as good or bad: status 0 means good, 125
636 means to skip the revision, 127 (command not found) will abort the
636 means to skip the revision, 127 (command not found) will abort the
637 bisection, and any other non-zero exit status means the revision
637 bisection, and any other non-zero exit status means the revision
638 is bad.
638 is bad.
639
639
640 .. container:: verbose
640 .. container:: verbose
641
641
642 Some examples:
642 Some examples:
643
643
644 - start a bisection with known bad revision 34, and good revision 12::
644 - start a bisection with known bad revision 34, and good revision 12::
645
645
646 hg bisect --bad 34
646 hg bisect --bad 34
647 hg bisect --good 12
647 hg bisect --good 12
648
648
649 - advance the current bisection by marking current revision as good or
649 - advance the current bisection by marking current revision as good or
650 bad::
650 bad::
651
651
652 hg bisect --good
652 hg bisect --good
653 hg bisect --bad
653 hg bisect --bad
654
654
655 - mark the current revision, or a known revision, to be skipped (e.g. if
655 - mark the current revision, or a known revision, to be skipped (e.g. if
656 that revision is not usable because of another issue)::
656 that revision is not usable because of another issue)::
657
657
658 hg bisect --skip
658 hg bisect --skip
659 hg bisect --skip 23
659 hg bisect --skip 23
660
660
661 - skip all revisions that do not touch directories ``foo`` or ``bar``::
661 - skip all revisions that do not touch directories ``foo`` or ``bar``::
662
662
663 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
663 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
664
664
665 - forget the current bisection::
665 - forget the current bisection::
666
666
667 hg bisect --reset
667 hg bisect --reset
668
668
669 - use 'make && make tests' to automatically find the first broken
669 - use 'make && make tests' to automatically find the first broken
670 revision::
670 revision::
671
671
672 hg bisect --reset
672 hg bisect --reset
673 hg bisect --bad 34
673 hg bisect --bad 34
674 hg bisect --good 12
674 hg bisect --good 12
675 hg bisect --command "make && make tests"
675 hg bisect --command "make && make tests"
676
676
677 - see all changesets whose states are already known in the current
677 - see all changesets whose states are already known in the current
678 bisection::
678 bisection::
679
679
680 hg log -r "bisect(pruned)"
680 hg log -r "bisect(pruned)"
681
681
682 - see the changeset currently being bisected (especially useful
682 - see the changeset currently being bisected (especially useful
683 if running with -U/--noupdate)::
683 if running with -U/--noupdate)::
684
684
685 hg log -r "bisect(current)"
685 hg log -r "bisect(current)"
686
686
687 - see all changesets that took part in the current bisection::
687 - see all changesets that took part in the current bisection::
688
688
689 hg log -r "bisect(range)"
689 hg log -r "bisect(range)"
690
690
691 - you can even get a nice graph::
691 - you can even get a nice graph::
692
692
693 hg log --graph -r "bisect(range)"
693 hg log --graph -r "bisect(range)"
694
694
695 See :hg:`help revsets` for more about the `bisect()` keyword.
695 See :hg:`help revsets` for more about the `bisect()` keyword.
696
696
697 Returns 0 on success.
697 Returns 0 on success.
698 """
698 """
699 def extendbisectrange(nodes, good):
699 def extendbisectrange(nodes, good):
700 # bisect is incomplete when it ends on a merge node and
700 # bisect is incomplete when it ends on a merge node and
701 # one of the parent was not checked.
701 # one of the parent was not checked.
702 parents = repo[nodes[0]].parents()
702 parents = repo[nodes[0]].parents()
703 if len(parents) > 1:
703 if len(parents) > 1:
704 if good:
704 if good:
705 side = state['bad']
705 side = state['bad']
706 else:
706 else:
707 side = state['good']
707 side = state['good']
708 num = len(set(i.node() for i in parents) & set(side))
708 num = len(set(i.node() for i in parents) & set(side))
709 if num == 1:
709 if num == 1:
710 return parents[0].ancestor(parents[1])
710 return parents[0].ancestor(parents[1])
711 return None
711 return None
712
712
713 def print_result(nodes, good):
713 def print_result(nodes, good):
714 displayer = cmdutil.show_changeset(ui, repo, {})
714 displayer = cmdutil.show_changeset(ui, repo, {})
715 if len(nodes) == 1:
715 if len(nodes) == 1:
716 # narrowed it down to a single revision
716 # narrowed it down to a single revision
717 if good:
717 if good:
718 ui.write(_("The first good revision is:\n"))
718 ui.write(_("The first good revision is:\n"))
719 else:
719 else:
720 ui.write(_("The first bad revision is:\n"))
720 ui.write(_("The first bad revision is:\n"))
721 displayer.show(repo[nodes[0]])
721 displayer.show(repo[nodes[0]])
722 extendnode = extendbisectrange(nodes, good)
722 extendnode = extendbisectrange(nodes, good)
723 if extendnode is not None:
723 if extendnode is not None:
724 ui.write(_('Not all ancestors of this changeset have been'
724 ui.write(_('Not all ancestors of this changeset have been'
725 ' checked.\nUse bisect --extend to continue the '
725 ' checked.\nUse bisect --extend to continue the '
726 'bisection from\nthe common ancestor, %s.\n')
726 'bisection from\nthe common ancestor, %s.\n')
727 % extendnode)
727 % extendnode)
728 else:
728 else:
729 # multiple possible revisions
729 # multiple possible revisions
730 if good:
730 if good:
731 ui.write(_("Due to skipped revisions, the first "
731 ui.write(_("Due to skipped revisions, the first "
732 "good revision could be any of:\n"))
732 "good revision could be any of:\n"))
733 else:
733 else:
734 ui.write(_("Due to skipped revisions, the first "
734 ui.write(_("Due to skipped revisions, the first "
735 "bad revision could be any of:\n"))
735 "bad revision could be any of:\n"))
736 for n in nodes:
736 for n in nodes:
737 displayer.show(repo[n])
737 displayer.show(repo[n])
738 displayer.close()
738 displayer.close()
739
739
740 def check_state(state, interactive=True):
740 def check_state(state, interactive=True):
741 if not state['good'] or not state['bad']:
741 if not state['good'] or not state['bad']:
742 if (good or bad or skip or reset) and interactive:
742 if (good or bad or skip or reset) and interactive:
743 return
743 return
744 if not state['good']:
744 if not state['good']:
745 raise util.Abort(_('cannot bisect (no known good revisions)'))
745 raise util.Abort(_('cannot bisect (no known good revisions)'))
746 else:
746 else:
747 raise util.Abort(_('cannot bisect (no known bad revisions)'))
747 raise util.Abort(_('cannot bisect (no known bad revisions)'))
748 return True
748 return True
749
749
750 # backward compatibility
750 # backward compatibility
751 if rev in "good bad reset init".split():
751 if rev in "good bad reset init".split():
752 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
752 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
753 cmd, rev, extra = rev, extra, None
753 cmd, rev, extra = rev, extra, None
754 if cmd == "good":
754 if cmd == "good":
755 good = True
755 good = True
756 elif cmd == "bad":
756 elif cmd == "bad":
757 bad = True
757 bad = True
758 else:
758 else:
759 reset = True
759 reset = True
760 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
760 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
761 raise util.Abort(_('incompatible arguments'))
761 raise util.Abort(_('incompatible arguments'))
762
762
763 cmdutil.checkunfinished(repo)
763 cmdutil.checkunfinished(repo)
764
764
765 if reset:
765 if reset:
766 p = repo.join("bisect.state")
766 p = repo.join("bisect.state")
767 if os.path.exists(p):
767 if os.path.exists(p):
768 os.unlink(p)
768 os.unlink(p)
769 return
769 return
770
770
771 state = hbisect.load_state(repo)
771 state = hbisect.load_state(repo)
772
772
773 if command:
773 if command:
774 changesets = 1
774 changesets = 1
775 if noupdate:
775 if noupdate:
776 try:
776 try:
777 node = state['current'][0]
777 node = state['current'][0]
778 except LookupError:
778 except LookupError:
779 raise util.Abort(_('current bisect revision is unknown - '
779 raise util.Abort(_('current bisect revision is unknown - '
780 'start a new bisect to fix'))
780 'start a new bisect to fix'))
781 else:
781 else:
782 node, p2 = repo.dirstate.parents()
782 node, p2 = repo.dirstate.parents()
783 if p2 != nullid:
783 if p2 != nullid:
784 raise util.Abort(_('current bisect revision is a merge'))
784 raise util.Abort(_('current bisect revision is a merge'))
785 try:
785 try:
786 while changesets:
786 while changesets:
787 # update state
787 # update state
788 state['current'] = [node]
788 state['current'] = [node]
789 hbisect.save_state(repo, state)
789 hbisect.save_state(repo, state)
790 status = ui.system(command, environ={'HG_NODE': hex(node)})
790 status = ui.system(command, environ={'HG_NODE': hex(node)})
791 if status == 125:
791 if status == 125:
792 transition = "skip"
792 transition = "skip"
793 elif status == 0:
793 elif status == 0:
794 transition = "good"
794 transition = "good"
795 # status < 0 means process was killed
795 # status < 0 means process was killed
796 elif status == 127:
796 elif status == 127:
797 raise util.Abort(_("failed to execute %s") % command)
797 raise util.Abort(_("failed to execute %s") % command)
798 elif status < 0:
798 elif status < 0:
799 raise util.Abort(_("%s killed") % command)
799 raise util.Abort(_("%s killed") % command)
800 else:
800 else:
801 transition = "bad"
801 transition = "bad"
802 ctx = scmutil.revsingle(repo, rev, node)
802 ctx = scmutil.revsingle(repo, rev, node)
803 rev = None # clear for future iterations
803 rev = None # clear for future iterations
804 state[transition].append(ctx.node())
804 state[transition].append(ctx.node())
805 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
805 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
806 check_state(state, interactive=False)
806 check_state(state, interactive=False)
807 # bisect
807 # bisect
808 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
808 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
809 # update to next check
809 # update to next check
810 node = nodes[0]
810 node = nodes[0]
811 if not noupdate:
811 if not noupdate:
812 cmdutil.bailifchanged(repo)
812 cmdutil.bailifchanged(repo)
813 hg.clean(repo, node, show_stats=False)
813 hg.clean(repo, node, show_stats=False)
814 finally:
814 finally:
815 state['current'] = [node]
815 state['current'] = [node]
816 hbisect.save_state(repo, state)
816 hbisect.save_state(repo, state)
817 print_result(nodes, bgood)
817 print_result(nodes, bgood)
818 return
818 return
819
819
820 # update state
820 # update state
821
821
822 if rev:
822 if rev:
823 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
823 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
824 else:
824 else:
825 nodes = [repo.lookup('.')]
825 nodes = [repo.lookup('.')]
826
826
827 if good or bad or skip:
827 if good or bad or skip:
828 if good:
828 if good:
829 state['good'] += nodes
829 state['good'] += nodes
830 elif bad:
830 elif bad:
831 state['bad'] += nodes
831 state['bad'] += nodes
832 elif skip:
832 elif skip:
833 state['skip'] += nodes
833 state['skip'] += nodes
834 hbisect.save_state(repo, state)
834 hbisect.save_state(repo, state)
835
835
836 if not check_state(state):
836 if not check_state(state):
837 return
837 return
838
838
839 # actually bisect
839 # actually bisect
840 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
840 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
841 if extend:
841 if extend:
842 if not changesets:
842 if not changesets:
843 extendnode = extendbisectrange(nodes, good)
843 extendnode = extendbisectrange(nodes, good)
844 if extendnode is not None:
844 if extendnode is not None:
845 ui.write(_("Extending search to changeset %d:%s\n")
845 ui.write(_("Extending search to changeset %d:%s\n")
846 % (extendnode.rev(), extendnode))
846 % (extendnode.rev(), extendnode))
847 state['current'] = [extendnode.node()]
847 state['current'] = [extendnode.node()]
848 hbisect.save_state(repo, state)
848 hbisect.save_state(repo, state)
849 if noupdate:
849 if noupdate:
850 return
850 return
851 cmdutil.bailifchanged(repo)
851 cmdutil.bailifchanged(repo)
852 return hg.clean(repo, extendnode.node())
852 return hg.clean(repo, extendnode.node())
853 raise util.Abort(_("nothing to extend"))
853 raise util.Abort(_("nothing to extend"))
854
854
855 if changesets == 0:
855 if changesets == 0:
856 print_result(nodes, good)
856 print_result(nodes, good)
857 else:
857 else:
858 assert len(nodes) == 1 # only a single node can be tested next
858 assert len(nodes) == 1 # only a single node can be tested next
859 node = nodes[0]
859 node = nodes[0]
860 # compute the approximate number of remaining tests
860 # compute the approximate number of remaining tests
861 tests, size = 0, 2
861 tests, size = 0, 2
862 while size <= changesets:
862 while size <= changesets:
863 tests, size = tests + 1, size * 2
863 tests, size = tests + 1, size * 2
864 rev = repo.changelog.rev(node)
864 rev = repo.changelog.rev(node)
865 ui.write(_("Testing changeset %d:%s "
865 ui.write(_("Testing changeset %d:%s "
866 "(%d changesets remaining, ~%d tests)\n")
866 "(%d changesets remaining, ~%d tests)\n")
867 % (rev, short(node), changesets, tests))
867 % (rev, short(node), changesets, tests))
868 state['current'] = [node]
868 state['current'] = [node]
869 hbisect.save_state(repo, state)
869 hbisect.save_state(repo, state)
870 if not noupdate:
870 if not noupdate:
871 cmdutil.bailifchanged(repo)
871 cmdutil.bailifchanged(repo)
872 return hg.clean(repo, node)
872 return hg.clean(repo, node)
873
873
874 @command('bookmarks|bookmark',
874 @command('bookmarks|bookmark',
875 [('f', 'force', False, _('force')),
875 [('f', 'force', False, _('force')),
876 ('r', 'rev', '', _('revision'), _('REV')),
876 ('r', 'rev', '', _('revision'), _('REV')),
877 ('d', 'delete', False, _('delete a given bookmark')),
877 ('d', 'delete', False, _('delete a given bookmark')),
878 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
878 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
879 ('i', 'inactive', False, _('mark a bookmark inactive')),
879 ('i', 'inactive', False, _('mark a bookmark inactive')),
880 ] + formatteropts,
880 ] + formatteropts,
881 _('hg bookmarks [OPTIONS]... [NAME]...'))
881 _('hg bookmarks [OPTIONS]... [NAME]...'))
882 def bookmark(ui, repo, *names, **opts):
882 def bookmark(ui, repo, *names, **opts):
883 '''create a new bookmark or list existing bookmarks
883 '''create a new bookmark or list existing bookmarks
884
884
885 Bookmarks are labels on changesets to help track lines of development.
885 Bookmarks are labels on changesets to help track lines of development.
886 Bookmarks are unversioned and can be moved, renamed and deleted.
886 Bookmarks are unversioned and can be moved, renamed and deleted.
887 Deleting or moving a bookmark has no effect on the associated changesets.
887 Deleting or moving a bookmark has no effect on the associated changesets.
888
888
889 Creating or updating to a bookmark causes it to be marked as 'active'.
889 Creating or updating to a bookmark causes it to be marked as 'active'.
890 The active bookmark is indicated with a '*'.
890 The active bookmark is indicated with a '*'.
891 When a commit is made, the active bookmark will advance to the new commit.
891 When a commit is made, the active bookmark will advance to the new commit.
892 A plain :hg:`update` will also advance an active bookmark, if possible.
892 A plain :hg:`update` will also advance an active bookmark, if possible.
893 Updating away from a bookmark will cause it to be deactivated.
893 Updating away from a bookmark will cause it to be deactivated.
894
894
895 Bookmarks can be pushed and pulled between repositories (see
895 Bookmarks can be pushed and pulled between repositories (see
896 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
896 :hg:`help push` and :hg:`help pull`). If a shared bookmark has
897 diverged, a new 'divergent bookmark' of the form 'name@path' will
897 diverged, a new 'divergent bookmark' of the form 'name@path' will
898 be created. Using :hg:`merge` will resolve the divergence.
898 be created. Using :hg:`merge` will resolve the divergence.
899
899
900 A bookmark named '@' has the special property that :hg:`clone` will
900 A bookmark named '@' has the special property that :hg:`clone` will
901 check it out by default if it exists.
901 check it out by default if it exists.
902
902
903 .. container:: verbose
903 .. container:: verbose
904
904
905 Examples:
905 Examples:
906
906
907 - create an active bookmark for a new line of development::
907 - create an active bookmark for a new line of development::
908
908
909 hg book new-feature
909 hg book new-feature
910
910
911 - create an inactive bookmark as a place marker::
911 - create an inactive bookmark as a place marker::
912
912
913 hg book -i reviewed
913 hg book -i reviewed
914
914
915 - create an inactive bookmark on another changeset::
915 - create an inactive bookmark on another changeset::
916
916
917 hg book -r .^ tested
917 hg book -r .^ tested
918
918
919 - move the '@' bookmark from another branch::
919 - move the '@' bookmark from another branch::
920
920
921 hg book -f @
921 hg book -f @
922 '''
922 '''
923 force = opts.get('force')
923 force = opts.get('force')
924 rev = opts.get('rev')
924 rev = opts.get('rev')
925 delete = opts.get('delete')
925 delete = opts.get('delete')
926 rename = opts.get('rename')
926 rename = opts.get('rename')
927 inactive = opts.get('inactive')
927 inactive = opts.get('inactive')
928
928
929 def checkformat(mark):
929 def checkformat(mark):
930 mark = mark.strip()
930 mark = mark.strip()
931 if not mark:
931 if not mark:
932 raise util.Abort(_("bookmark names cannot consist entirely of "
932 raise util.Abort(_("bookmark names cannot consist entirely of "
933 "whitespace"))
933 "whitespace"))
934 scmutil.checknewlabel(repo, mark, 'bookmark')
934 scmutil.checknewlabel(repo, mark, 'bookmark')
935 return mark
935 return mark
936
936
937 def checkconflict(repo, mark, cur, force=False, target=None):
937 def checkconflict(repo, mark, cur, force=False, target=None):
938 if mark in marks and not force:
938 if mark in marks and not force:
939 if target:
939 if target:
940 if marks[mark] == target and target == cur:
940 if marks[mark] == target and target == cur:
941 # re-activating a bookmark
941 # re-activating a bookmark
942 return
942 return
943 anc = repo.changelog.ancestors([repo[target].rev()])
943 anc = repo.changelog.ancestors([repo[target].rev()])
944 bmctx = repo[marks[mark]]
944 bmctx = repo[marks[mark]]
945 divs = [repo[b].node() for b in marks
945 divs = [repo[b].node() for b in marks
946 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
946 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
947
947
948 # allow resolving a single divergent bookmark even if moving
948 # allow resolving a single divergent bookmark even if moving
949 # the bookmark across branches when a revision is specified
949 # the bookmark across branches when a revision is specified
950 # that contains a divergent bookmark
950 # that contains a divergent bookmark
951 if bmctx.rev() not in anc and target in divs:
951 if bmctx.rev() not in anc and target in divs:
952 bookmarks.deletedivergent(repo, [target], mark)
952 bookmarks.deletedivergent(repo, [target], mark)
953 return
953 return
954
954
955 deletefrom = [b for b in divs
955 deletefrom = [b for b in divs
956 if repo[b].rev() in anc or b == target]
956 if repo[b].rev() in anc or b == target]
957 bookmarks.deletedivergent(repo, deletefrom, mark)
957 bookmarks.deletedivergent(repo, deletefrom, mark)
958 if bookmarks.validdest(repo, bmctx, repo[target]):
958 if bookmarks.validdest(repo, bmctx, repo[target]):
959 ui.status(_("moving bookmark '%s' forward from %s\n") %
959 ui.status(_("moving bookmark '%s' forward from %s\n") %
960 (mark, short(bmctx.node())))
960 (mark, short(bmctx.node())))
961 return
961 return
962 raise util.Abort(_("bookmark '%s' already exists "
962 raise util.Abort(_("bookmark '%s' already exists "
963 "(use -f to force)") % mark)
963 "(use -f to force)") % mark)
964 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
964 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
965 and not force):
965 and not force):
966 raise util.Abort(
966 raise util.Abort(
967 _("a bookmark cannot have the name of an existing branch"))
967 _("a bookmark cannot have the name of an existing branch"))
968
968
969 if delete and rename:
969 if delete and rename:
970 raise util.Abort(_("--delete and --rename are incompatible"))
970 raise util.Abort(_("--delete and --rename are incompatible"))
971 if delete and rev:
971 if delete and rev:
972 raise util.Abort(_("--rev is incompatible with --delete"))
972 raise util.Abort(_("--rev is incompatible with --delete"))
973 if rename and rev:
973 if rename and rev:
974 raise util.Abort(_("--rev is incompatible with --rename"))
974 raise util.Abort(_("--rev is incompatible with --rename"))
975 if not names and (delete or rev):
975 if not names and (delete or rev):
976 raise util.Abort(_("bookmark name required"))
976 raise util.Abort(_("bookmark name required"))
977
977
978 if delete or rename or names or inactive:
978 if delete or rename or names or inactive:
979 wlock = lock = tr = None
979 wlock = lock = tr = None
980 try:
980 try:
981 wlock = repo.wlock()
981 wlock = repo.wlock()
982 lock = repo.lock()
982 lock = repo.lock()
983 cur = repo.changectx('.').node()
983 cur = repo.changectx('.').node()
984 marks = repo._bookmarks
984 marks = repo._bookmarks
985 if delete:
985 if delete:
986 tr = repo.transaction('bookmark')
986 tr = repo.transaction('bookmark')
987 for mark in names:
987 for mark in names:
988 if mark not in marks:
988 if mark not in marks:
989 raise util.Abort(_("bookmark '%s' does not exist") %
989 raise util.Abort(_("bookmark '%s' does not exist") %
990 mark)
990 mark)
991 if mark == repo._activebookmark:
991 if mark == repo._activebookmark:
992 bookmarks.deactivate(repo)
992 bookmarks.deactivate(repo)
993 del marks[mark]
993 del marks[mark]
994
994
995 elif rename:
995 elif rename:
996 tr = repo.transaction('bookmark')
996 tr = repo.transaction('bookmark')
997 if not names:
997 if not names:
998 raise util.Abort(_("new bookmark name required"))
998 raise util.Abort(_("new bookmark name required"))
999 elif len(names) > 1:
999 elif len(names) > 1:
1000 raise util.Abort(_("only one new bookmark name allowed"))
1000 raise util.Abort(_("only one new bookmark name allowed"))
1001 mark = checkformat(names[0])
1001 mark = checkformat(names[0])
1002 if rename not in marks:
1002 if rename not in marks:
1003 raise util.Abort(_("bookmark '%s' does not exist") % rename)
1003 raise util.Abort(_("bookmark '%s' does not exist") % rename)
1004 checkconflict(repo, mark, cur, force)
1004 checkconflict(repo, mark, cur, force)
1005 marks[mark] = marks[rename]
1005 marks[mark] = marks[rename]
1006 if repo._activebookmark == rename and not inactive:
1006 if repo._activebookmark == rename and not inactive:
1007 bookmarks.activate(repo, mark)
1007 bookmarks.activate(repo, mark)
1008 del marks[rename]
1008 del marks[rename]
1009 elif names:
1009 elif names:
1010 tr = repo.transaction('bookmark')
1010 tr = repo.transaction('bookmark')
1011 newact = None
1011 newact = None
1012 for mark in names:
1012 for mark in names:
1013 mark = checkformat(mark)
1013 mark = checkformat(mark)
1014 if newact is None:
1014 if newact is None:
1015 newact = mark
1015 newact = mark
1016 if inactive and mark == repo._activebookmark:
1016 if inactive and mark == repo._activebookmark:
1017 bookmarks.deactivate(repo)
1017 bookmarks.deactivate(repo)
1018 return
1018 return
1019 tgt = cur
1019 tgt = cur
1020 if rev:
1020 if rev:
1021 tgt = scmutil.revsingle(repo, rev).node()
1021 tgt = scmutil.revsingle(repo, rev).node()
1022 checkconflict(repo, mark, cur, force, tgt)
1022 checkconflict(repo, mark, cur, force, tgt)
1023 marks[mark] = tgt
1023 marks[mark] = tgt
1024 if not inactive and cur == marks[newact] and not rev:
1024 if not inactive and cur == marks[newact] and not rev:
1025 bookmarks.activate(repo, newact)
1025 bookmarks.activate(repo, newact)
1026 elif cur != tgt and newact == repo._activebookmark:
1026 elif cur != tgt and newact == repo._activebookmark:
1027 bookmarks.deactivate(repo)
1027 bookmarks.deactivate(repo)
1028 elif inactive:
1028 elif inactive:
1029 if len(marks) == 0:
1029 if len(marks) == 0:
1030 ui.status(_("no bookmarks set\n"))
1030 ui.status(_("no bookmarks set\n"))
1031 elif not repo._activebookmark:
1031 elif not repo._activebookmark:
1032 ui.status(_("no active bookmark\n"))
1032 ui.status(_("no active bookmark\n"))
1033 else:
1033 else:
1034 bookmarks.deactivate(repo)
1034 bookmarks.deactivate(repo)
1035 if tr is not None:
1035 if tr is not None:
1036 marks.recordchange(tr)
1036 marks.recordchange(tr)
1037 tr.close()
1037 tr.close()
1038 finally:
1038 finally:
1039 lockmod.release(tr, lock, wlock)
1039 lockmod.release(tr, lock, wlock)
1040 else: # show bookmarks
1040 else: # show bookmarks
1041 fm = ui.formatter('bookmarks', opts)
1041 fm = ui.formatter('bookmarks', opts)
1042 hexfn = fm.hexfunc
1042 hexfn = fm.hexfunc
1043 marks = repo._bookmarks
1043 marks = repo._bookmarks
1044 if len(marks) == 0 and not fm:
1044 if len(marks) == 0 and not fm:
1045 ui.status(_("no bookmarks set\n"))
1045 ui.status(_("no bookmarks set\n"))
1046 for bmark, n in sorted(marks.iteritems()):
1046 for bmark, n in sorted(marks.iteritems()):
1047 active = repo._activebookmark
1047 active = repo._activebookmark
1048 if bmark == active:
1048 if bmark == active:
1049 prefix, label = '*', activebookmarklabel
1049 prefix, label = '*', activebookmarklabel
1050 else:
1050 else:
1051 prefix, label = ' ', ''
1051 prefix, label = ' ', ''
1052
1052
1053 fm.startitem()
1053 fm.startitem()
1054 if not ui.quiet:
1054 if not ui.quiet:
1055 fm.plain(' %s ' % prefix, label=label)
1055 fm.plain(' %s ' % prefix, label=label)
1056 fm.write('bookmark', '%s', bmark, label=label)
1056 fm.write('bookmark', '%s', bmark, label=label)
1057 pad = " " * (25 - encoding.colwidth(bmark))
1057 pad = " " * (25 - encoding.colwidth(bmark))
1058 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1058 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
1059 repo.changelog.rev(n), hexfn(n), label=label)
1059 repo.changelog.rev(n), hexfn(n), label=label)
1060 fm.data(active=(bmark == active))
1060 fm.data(active=(bmark == active))
1061 fm.plain('\n')
1061 fm.plain('\n')
1062 fm.end()
1062 fm.end()
1063
1063
1064 @command('branch',
1064 @command('branch',
1065 [('f', 'force', None,
1065 [('f', 'force', None,
1066 _('set branch name even if it shadows an existing branch')),
1066 _('set branch name even if it shadows an existing branch')),
1067 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1067 ('C', 'clean', None, _('reset branch name to parent branch name'))],
1068 _('[-fC] [NAME]'))
1068 _('[-fC] [NAME]'))
1069 def branch(ui, repo, label=None, **opts):
1069 def branch(ui, repo, label=None, **opts):
1070 """set or show the current branch name
1070 """set or show the current branch name
1071
1071
1072 .. note::
1072 .. note::
1073
1073
1074 Branch names are permanent and global. Use :hg:`bookmark` to create a
1074 Branch names are permanent and global. Use :hg:`bookmark` to create a
1075 light-weight bookmark instead. See :hg:`help glossary` for more
1075 light-weight bookmark instead. See :hg:`help glossary` for more
1076 information about named branches and bookmarks.
1076 information about named branches and bookmarks.
1077
1077
1078 With no argument, show the current branch name. With one argument,
1078 With no argument, show the current branch name. With one argument,
1079 set the working directory branch name (the branch will not exist
1079 set the working directory branch name (the branch will not exist
1080 in the repository until the next commit). Standard practice
1080 in the repository until the next commit). Standard practice
1081 recommends that primary development take place on the 'default'
1081 recommends that primary development take place on the 'default'
1082 branch.
1082 branch.
1083
1083
1084 Unless -f/--force is specified, branch will not let you set a
1084 Unless -f/--force is specified, branch will not let you set a
1085 branch name that already exists.
1085 branch name that already exists.
1086
1086
1087 Use -C/--clean to reset the working directory branch to that of
1087 Use -C/--clean to reset the working directory branch to that of
1088 the parent of the working directory, negating a previous branch
1088 the parent of the working directory, negating a previous branch
1089 change.
1089 change.
1090
1090
1091 Use the command :hg:`update` to switch to an existing branch. Use
1091 Use the command :hg:`update` to switch to an existing branch. Use
1092 :hg:`commit --close-branch` to mark this branch head as closed.
1092 :hg:`commit --close-branch` to mark this branch head as closed.
1093 When all heads of the branch are closed, the branch will be
1093 When all heads of the branch are closed, the branch will be
1094 considered closed.
1094 considered closed.
1095
1095
1096 Returns 0 on success.
1096 Returns 0 on success.
1097 """
1097 """
1098 if label:
1098 if label:
1099 label = label.strip()
1099 label = label.strip()
1100
1100
1101 if not opts.get('clean') and not label:
1101 if not opts.get('clean') and not label:
1102 ui.write("%s\n" % repo.dirstate.branch())
1102 ui.write("%s\n" % repo.dirstate.branch())
1103 return
1103 return
1104
1104
1105 wlock = repo.wlock()
1105 wlock = repo.wlock()
1106 try:
1106 try:
1107 if opts.get('clean'):
1107 if opts.get('clean'):
1108 label = repo[None].p1().branch()
1108 label = repo[None].p1().branch()
1109 repo.dirstate.setbranch(label)
1109 repo.dirstate.setbranch(label)
1110 ui.status(_('reset working directory to branch %s\n') % label)
1110 ui.status(_('reset working directory to branch %s\n') % label)
1111 elif label:
1111 elif label:
1112 if not opts.get('force') and label in repo.branchmap():
1112 if not opts.get('force') and label in repo.branchmap():
1113 if label not in [p.branch() for p in repo.parents()]:
1113 if label not in [p.branch() for p in repo.parents()]:
1114 raise util.Abort(_('a branch of the same name already'
1114 raise util.Abort(_('a branch of the same name already'
1115 ' exists'),
1115 ' exists'),
1116 # i18n: "it" refers to an existing branch
1116 # i18n: "it" refers to an existing branch
1117 hint=_("use 'hg update' to switch to it"))
1117 hint=_("use 'hg update' to switch to it"))
1118 scmutil.checknewlabel(repo, label, 'branch')
1118 scmutil.checknewlabel(repo, label, 'branch')
1119 repo.dirstate.setbranch(label)
1119 repo.dirstate.setbranch(label)
1120 ui.status(_('marked working directory as branch %s\n') % label)
1120 ui.status(_('marked working directory as branch %s\n') % label)
1121
1121
1122 # find any open named branches aside from default
1122 # find any open named branches aside from default
1123 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1123 others = [n for n, h, t, c in repo.branchmap().iterbranches()
1124 if n != "default" and not c]
1124 if n != "default" and not c]
1125 if not others:
1125 if not others:
1126 ui.status(_('(branches are permanent and global, '
1126 ui.status(_('(branches are permanent and global, '
1127 'did you want a bookmark?)\n'))
1127 'did you want a bookmark?)\n'))
1128 finally:
1128 finally:
1129 wlock.release()
1129 wlock.release()
1130
1130
1131 @command('branches',
1131 @command('branches',
1132 [('a', 'active', False,
1132 [('a', 'active', False,
1133 _('show only branches that have unmerged heads (DEPRECATED)')),
1133 _('show only branches that have unmerged heads (DEPRECATED)')),
1134 ('c', 'closed', False, _('show normal and closed branches')),
1134 ('c', 'closed', False, _('show normal and closed branches')),
1135 ] + formatteropts,
1135 ] + formatteropts,
1136 _('[-ac]'))
1136 _('[-ac]'))
1137 def branches(ui, repo, active=False, closed=False, **opts):
1137 def branches(ui, repo, active=False, closed=False, **opts):
1138 """list repository named branches
1138 """list repository named branches
1139
1139
1140 List the repository's named branches, indicating which ones are
1140 List the repository's named branches, indicating which ones are
1141 inactive. If -c/--closed is specified, also list branches which have
1141 inactive. If -c/--closed is specified, also list branches which have
1142 been marked closed (see :hg:`commit --close-branch`).
1142 been marked closed (see :hg:`commit --close-branch`).
1143
1143
1144 Use the command :hg:`update` to switch to an existing branch.
1144 Use the command :hg:`update` to switch to an existing branch.
1145
1145
1146 Returns 0.
1146 Returns 0.
1147 """
1147 """
1148
1148
1149 fm = ui.formatter('branches', opts)
1149 fm = ui.formatter('branches', opts)
1150 hexfunc = fm.hexfunc
1150 hexfunc = fm.hexfunc
1151
1151
1152 allheads = set(repo.heads())
1152 allheads = set(repo.heads())
1153 branches = []
1153 branches = []
1154 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1154 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1155 isactive = not isclosed and bool(set(heads) & allheads)
1155 isactive = not isclosed and bool(set(heads) & allheads)
1156 branches.append((tag, repo[tip], isactive, not isclosed))
1156 branches.append((tag, repo[tip], isactive, not isclosed))
1157 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1157 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1158 reverse=True)
1158 reverse=True)
1159
1159
1160 for tag, ctx, isactive, isopen in branches:
1160 for tag, ctx, isactive, isopen in branches:
1161 if active and not isactive:
1161 if active and not isactive:
1162 continue
1162 continue
1163 if isactive:
1163 if isactive:
1164 label = 'branches.active'
1164 label = 'branches.active'
1165 notice = ''
1165 notice = ''
1166 elif not isopen:
1166 elif not isopen:
1167 if not closed:
1167 if not closed:
1168 continue
1168 continue
1169 label = 'branches.closed'
1169 label = 'branches.closed'
1170 notice = _(' (closed)')
1170 notice = _(' (closed)')
1171 else:
1171 else:
1172 label = 'branches.inactive'
1172 label = 'branches.inactive'
1173 notice = _(' (inactive)')
1173 notice = _(' (inactive)')
1174 current = (tag == repo.dirstate.branch())
1174 current = (tag == repo.dirstate.branch())
1175 if current:
1175 if current:
1176 label = 'branches.current'
1176 label = 'branches.current'
1177
1177
1178 fm.startitem()
1178 fm.startitem()
1179 fm.write('branch', '%s', tag, label=label)
1179 fm.write('branch', '%s', tag, label=label)
1180 rev = ctx.rev()
1180 rev = ctx.rev()
1181 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1181 padsize = max(31 - len(str(rev)) - encoding.colwidth(tag), 0)
1182 fmt = ' ' * padsize + ' %d:%s'
1182 fmt = ' ' * padsize + ' %d:%s'
1183 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1183 fm.condwrite(not ui.quiet, 'rev node', fmt, rev, hexfunc(ctx.node()),
1184 label='log.changeset changeset.%s' % ctx.phasestr())
1184 label='log.changeset changeset.%s' % ctx.phasestr())
1185 fm.data(active=isactive, closed=not isopen, current=current)
1185 fm.data(active=isactive, closed=not isopen, current=current)
1186 if not ui.quiet:
1186 if not ui.quiet:
1187 fm.plain(notice)
1187 fm.plain(notice)
1188 fm.plain('\n')
1188 fm.plain('\n')
1189 fm.end()
1189 fm.end()
1190
1190
1191 @command('bundle',
1191 @command('bundle',
1192 [('f', 'force', None, _('run even when the destination is unrelated')),
1192 [('f', 'force', None, _('run even when the destination is unrelated')),
1193 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1193 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1194 _('REV')),
1194 _('REV')),
1195 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1195 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1196 _('BRANCH')),
1196 _('BRANCH')),
1197 ('', 'base', [],
1197 ('', 'base', [],
1198 _('a base changeset assumed to be available at the destination'),
1198 _('a base changeset assumed to be available at the destination'),
1199 _('REV')),
1199 _('REV')),
1200 ('a', 'all', None, _('bundle all changesets in the repository')),
1200 ('a', 'all', None, _('bundle all changesets in the repository')),
1201 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1201 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1202 ] + remoteopts,
1202 ] + remoteopts,
1203 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1203 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1204 def bundle(ui, repo, fname, dest=None, **opts):
1204 def bundle(ui, repo, fname, dest=None, **opts):
1205 """create a changegroup file
1205 """create a changegroup file
1206
1206
1207 Generate a compressed changegroup file collecting changesets not
1207 Generate a compressed changegroup file collecting changesets not
1208 known to be in another repository.
1208 known to be in another repository.
1209
1209
1210 If you omit the destination repository, then hg assumes the
1210 If you omit the destination repository, then hg assumes the
1211 destination will have all the nodes you specify with --base
1211 destination will have all the nodes you specify with --base
1212 parameters. To create a bundle containing all changesets, use
1212 parameters. To create a bundle containing all changesets, use
1213 -a/--all (or --base null).
1213 -a/--all (or --base null).
1214
1214
1215 You can change compression method with the -t/--type option.
1215 You can change compression method with the -t/--type option.
1216 The available compression methods are: none, bzip2, and
1216 The available compression methods are: none, bzip2, and
1217 gzip (by default, bundles are compressed using bzip2).
1217 gzip (by default, bundles are compressed using bzip2).
1218
1218
1219 The bundle file can then be transferred using conventional means
1219 The bundle file can then be transferred using conventional means
1220 and applied to another repository with the unbundle or pull
1220 and applied to another repository with the unbundle or pull
1221 command. This is useful when direct push and pull are not
1221 command. This is useful when direct push and pull are not
1222 available or when exporting an entire repository is undesirable.
1222 available or when exporting an entire repository is undesirable.
1223
1223
1224 Applying bundles preserves all changeset contents including
1224 Applying bundles preserves all changeset contents including
1225 permissions, copy/rename information, and revision history.
1225 permissions, copy/rename information, and revision history.
1226
1226
1227 Returns 0 on success, 1 if no changes found.
1227 Returns 0 on success, 1 if no changes found.
1228 """
1228 """
1229 revs = None
1229 revs = None
1230 if 'rev' in opts:
1230 if 'rev' in opts:
1231 revs = scmutil.revrange(repo, opts['rev'])
1231 revs = scmutil.revrange(repo, opts['rev'])
1232
1232
1233 bundletype = opts.get('type', 'bzip2').lower()
1233 bundletype = opts.get('type', 'bzip2').lower()
1234 btypes = {'none': 'HG10UN',
1234 btypes = {'none': 'HG10UN',
1235 'bzip2': 'HG10BZ',
1235 'bzip2': 'HG10BZ',
1236 'gzip': 'HG10GZ',
1236 'gzip': 'HG10GZ',
1237 'bundle2': 'HG20'}
1237 'bundle2': 'HG20'}
1238 bundletype = btypes.get(bundletype)
1238 bundletype = btypes.get(bundletype)
1239 if bundletype not in changegroup.bundletypes:
1239 if bundletype not in changegroup.bundletypes:
1240 raise util.Abort(_('unknown bundle type specified with --type'))
1240 raise util.Abort(_('unknown bundle type specified with --type'))
1241
1241
1242 if opts.get('all'):
1242 if opts.get('all'):
1243 base = ['null']
1243 base = ['null']
1244 else:
1244 else:
1245 base = scmutil.revrange(repo, opts.get('base'))
1245 base = scmutil.revrange(repo, opts.get('base'))
1246 # TODO: get desired bundlecaps from command line.
1246 # TODO: get desired bundlecaps from command line.
1247 bundlecaps = None
1247 bundlecaps = None
1248 if base:
1248 if base:
1249 if dest:
1249 if dest:
1250 raise util.Abort(_("--base is incompatible with specifying "
1250 raise util.Abort(_("--base is incompatible with specifying "
1251 "a destination"))
1251 "a destination"))
1252 common = [repo.lookup(rev) for rev in base]
1252 common = [repo.lookup(rev) for rev in base]
1253 heads = revs and map(repo.lookup, revs) or revs
1253 heads = revs and map(repo.lookup, revs) or revs
1254 cg = changegroup.getchangegroup(repo, 'bundle', heads=heads,
1254 cg = changegroup.getchangegroup(repo, 'bundle', heads=heads,
1255 common=common, bundlecaps=bundlecaps)
1255 common=common, bundlecaps=bundlecaps)
1256 outgoing = None
1256 outgoing = None
1257 else:
1257 else:
1258 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1258 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1259 dest, branches = hg.parseurl(dest, opts.get('branch'))
1259 dest, branches = hg.parseurl(dest, opts.get('branch'))
1260 other = hg.peer(repo, opts, dest)
1260 other = hg.peer(repo, opts, dest)
1261 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1261 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1262 heads = revs and map(repo.lookup, revs) or revs
1262 heads = revs and map(repo.lookup, revs) or revs
1263 outgoing = discovery.findcommonoutgoing(repo, other,
1263 outgoing = discovery.findcommonoutgoing(repo, other,
1264 onlyheads=heads,
1264 onlyheads=heads,
1265 force=opts.get('force'),
1265 force=opts.get('force'),
1266 portable=True)
1266 portable=True)
1267 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1267 cg = changegroup.getlocalchangegroup(repo, 'bundle', outgoing,
1268 bundlecaps)
1268 bundlecaps)
1269 if not cg:
1269 if not cg:
1270 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1270 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1271 return 1
1271 return 1
1272
1272
1273 changegroup.writebundle(ui, cg, fname, bundletype)
1273 changegroup.writebundle(ui, cg, fname, bundletype)
1274
1274
1275 @command('cat',
1275 @command('cat',
1276 [('o', 'output', '',
1276 [('o', 'output', '',
1277 _('print output to file with formatted name'), _('FORMAT')),
1277 _('print output to file with formatted name'), _('FORMAT')),
1278 ('r', 'rev', '', _('print the given revision'), _('REV')),
1278 ('r', 'rev', '', _('print the given revision'), _('REV')),
1279 ('', 'decode', None, _('apply any matching decode filter')),
1279 ('', 'decode', None, _('apply any matching decode filter')),
1280 ] + walkopts,
1280 ] + walkopts,
1281 _('[OPTION]... FILE...'),
1281 _('[OPTION]... FILE...'),
1282 inferrepo=True)
1282 inferrepo=True)
1283 def cat(ui, repo, file1, *pats, **opts):
1283 def cat(ui, repo, file1, *pats, **opts):
1284 """output the current or given revision of files
1284 """output the current or given revision of files
1285
1285
1286 Print the specified files as they were at the given revision. If
1286 Print the specified files as they were at the given revision. If
1287 no revision is given, the parent of the working directory is used.
1287 no revision is given, the parent of the working directory is used.
1288
1288
1289 Output may be to a file, in which case the name of the file is
1289 Output may be to a file, in which case the name of the file is
1290 given using a format string. The formatting rules as follows:
1290 given using a format string. The formatting rules as follows:
1291
1291
1292 :``%%``: literal "%" character
1292 :``%%``: literal "%" character
1293 :``%s``: basename of file being printed
1293 :``%s``: basename of file being printed
1294 :``%d``: dirname of file being printed, or '.' if in repository root
1294 :``%d``: dirname of file being printed, or '.' if in repository root
1295 :``%p``: root-relative path name of file being printed
1295 :``%p``: root-relative path name of file being printed
1296 :``%H``: changeset hash (40 hexadecimal digits)
1296 :``%H``: changeset hash (40 hexadecimal digits)
1297 :``%R``: changeset revision number
1297 :``%R``: changeset revision number
1298 :``%h``: short-form changeset hash (12 hexadecimal digits)
1298 :``%h``: short-form changeset hash (12 hexadecimal digits)
1299 :``%r``: zero-padded changeset revision number
1299 :``%r``: zero-padded changeset revision number
1300 :``%b``: basename of the exporting repository
1300 :``%b``: basename of the exporting repository
1301
1301
1302 Returns 0 on success.
1302 Returns 0 on success.
1303 """
1303 """
1304 ctx = scmutil.revsingle(repo, opts.get('rev'))
1304 ctx = scmutil.revsingle(repo, opts.get('rev'))
1305 m = scmutil.match(ctx, (file1,) + pats, opts)
1305 m = scmutil.match(ctx, (file1,) + pats, opts)
1306
1306
1307 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1307 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1308
1308
1309 @command('^clone',
1309 @command('^clone',
1310 [('U', 'noupdate', None, _('the clone will include an empty working '
1310 [('U', 'noupdate', None, _('the clone will include an empty working '
1311 'directory (only a repository)')),
1311 'directory (only a repository)')),
1312 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1312 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1313 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1313 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1314 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1314 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1315 ('', 'pull', None, _('use pull protocol to copy metadata')),
1315 ('', 'pull', None, _('use pull protocol to copy metadata')),
1316 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1316 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1317 ] + remoteopts,
1317 ] + remoteopts,
1318 _('[OPTION]... SOURCE [DEST]'),
1318 _('[OPTION]... SOURCE [DEST]'),
1319 norepo=True)
1319 norepo=True)
1320 def clone(ui, source, dest=None, **opts):
1320 def clone(ui, source, dest=None, **opts):
1321 """make a copy of an existing repository
1321 """make a copy of an existing repository
1322
1322
1323 Create a copy of an existing repository in a new directory.
1323 Create a copy of an existing repository in a new directory.
1324
1324
1325 If no destination directory name is specified, it defaults to the
1325 If no destination directory name is specified, it defaults to the
1326 basename of the source.
1326 basename of the source.
1327
1327
1328 The location of the source is added to the new repository's
1328 The location of the source is added to the new repository's
1329 ``.hg/hgrc`` file, as the default to be used for future pulls.
1329 ``.hg/hgrc`` file, as the default to be used for future pulls.
1330
1330
1331 Only local paths and ``ssh://`` URLs are supported as
1331 Only local paths and ``ssh://`` URLs are supported as
1332 destinations. For ``ssh://`` destinations, no working directory or
1332 destinations. For ``ssh://`` destinations, no working directory or
1333 ``.hg/hgrc`` will be created on the remote side.
1333 ``.hg/hgrc`` will be created on the remote side.
1334
1334
1335 To pull only a subset of changesets, specify one or more revisions
1335 To pull only a subset of changesets, specify one or more revisions
1336 identifiers with -r/--rev or branches with -b/--branch. The
1336 identifiers with -r/--rev or branches with -b/--branch. The
1337 resulting clone will contain only the specified changesets and
1337 resulting clone will contain only the specified changesets and
1338 their ancestors. These options (or 'clone src#rev dest') imply
1338 their ancestors. These options (or 'clone src#rev dest') imply
1339 --pull, even for local source repositories. Note that specifying a
1339 --pull, even for local source repositories. Note that specifying a
1340 tag will include the tagged changeset but not the changeset
1340 tag will include the tagged changeset but not the changeset
1341 containing the tag.
1341 containing the tag.
1342
1342
1343 If the source repository has a bookmark called '@' set, that
1343 If the source repository has a bookmark called '@' set, that
1344 revision will be checked out in the new repository by default.
1344 revision will be checked out in the new repository by default.
1345
1345
1346 To check out a particular version, use -u/--update, or
1346 To check out a particular version, use -u/--update, or
1347 -U/--noupdate to create a clone with no working directory.
1347 -U/--noupdate to create a clone with no working directory.
1348
1348
1349 .. container:: verbose
1349 .. container:: verbose
1350
1350
1351 For efficiency, hardlinks are used for cloning whenever the
1351 For efficiency, hardlinks are used for cloning whenever the
1352 source and destination are on the same filesystem (note this
1352 source and destination are on the same filesystem (note this
1353 applies only to the repository data, not to the working
1353 applies only to the repository data, not to the working
1354 directory). Some filesystems, such as AFS, implement hardlinking
1354 directory). Some filesystems, such as AFS, implement hardlinking
1355 incorrectly, but do not report errors. In these cases, use the
1355 incorrectly, but do not report errors. In these cases, use the
1356 --pull option to avoid hardlinking.
1356 --pull option to avoid hardlinking.
1357
1357
1358 In some cases, you can clone repositories and the working
1358 In some cases, you can clone repositories and the working
1359 directory using full hardlinks with ::
1359 directory using full hardlinks with ::
1360
1360
1361 $ cp -al REPO REPOCLONE
1361 $ cp -al REPO REPOCLONE
1362
1362
1363 This is the fastest way to clone, but it is not always safe. The
1363 This is the fastest way to clone, but it is not always safe. The
1364 operation is not atomic (making sure REPO is not modified during
1364 operation is not atomic (making sure REPO is not modified during
1365 the operation is up to you) and you have to make sure your
1365 the operation is up to you) and you have to make sure your
1366 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1366 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1367 so). Also, this is not compatible with certain extensions that
1367 so). Also, this is not compatible with certain extensions that
1368 place their metadata under the .hg directory, such as mq.
1368 place their metadata under the .hg directory, such as mq.
1369
1369
1370 Mercurial will update the working directory to the first applicable
1370 Mercurial will update the working directory to the first applicable
1371 revision from this list:
1371 revision from this list:
1372
1372
1373 a) null if -U or the source repository has no changesets
1373 a) null if -U or the source repository has no changesets
1374 b) if -u . and the source repository is local, the first parent of
1374 b) if -u . and the source repository is local, the first parent of
1375 the source repository's working directory
1375 the source repository's working directory
1376 c) the changeset specified with -u (if a branch name, this means the
1376 c) the changeset specified with -u (if a branch name, this means the
1377 latest head of that branch)
1377 latest head of that branch)
1378 d) the changeset specified with -r
1378 d) the changeset specified with -r
1379 e) the tipmost head specified with -b
1379 e) the tipmost head specified with -b
1380 f) the tipmost head specified with the url#branch source syntax
1380 f) the tipmost head specified with the url#branch source syntax
1381 g) the revision marked with the '@' bookmark, if present
1381 g) the revision marked with the '@' bookmark, if present
1382 h) the tipmost head of the default branch
1382 h) the tipmost head of the default branch
1383 i) tip
1383 i) tip
1384
1384
1385 Examples:
1385 Examples:
1386
1386
1387 - clone a remote repository to a new directory named hg/::
1387 - clone a remote repository to a new directory named hg/::
1388
1388
1389 hg clone http://selenic.com/hg
1389 hg clone http://selenic.com/hg
1390
1390
1391 - create a lightweight local clone::
1391 - create a lightweight local clone::
1392
1392
1393 hg clone project/ project-feature/
1393 hg clone project/ project-feature/
1394
1394
1395 - clone from an absolute path on an ssh server (note double-slash)::
1395 - clone from an absolute path on an ssh server (note double-slash)::
1396
1396
1397 hg clone ssh://user@server//home/projects/alpha/
1397 hg clone ssh://user@server//home/projects/alpha/
1398
1398
1399 - do a high-speed clone over a LAN while checking out a
1399 - do a high-speed clone over a LAN while checking out a
1400 specified version::
1400 specified version::
1401
1401
1402 hg clone --uncompressed http://server/repo -u 1.5
1402 hg clone --uncompressed http://server/repo -u 1.5
1403
1403
1404 - create a repository without changesets after a particular revision::
1404 - create a repository without changesets after a particular revision::
1405
1405
1406 hg clone -r 04e544 experimental/ good/
1406 hg clone -r 04e544 experimental/ good/
1407
1407
1408 - clone (and track) a particular named branch::
1408 - clone (and track) a particular named branch::
1409
1409
1410 hg clone http://selenic.com/hg#stable
1410 hg clone http://selenic.com/hg#stable
1411
1411
1412 See :hg:`help urls` for details on specifying URLs.
1412 See :hg:`help urls` for details on specifying URLs.
1413
1413
1414 Returns 0 on success.
1414 Returns 0 on success.
1415 """
1415 """
1416 if opts.get('noupdate') and opts.get('updaterev'):
1416 if opts.get('noupdate') and opts.get('updaterev'):
1417 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1417 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1418
1418
1419 r = hg.clone(ui, opts, source, dest,
1419 r = hg.clone(ui, opts, source, dest,
1420 pull=opts.get('pull'),
1420 pull=opts.get('pull'),
1421 stream=opts.get('uncompressed'),
1421 stream=opts.get('uncompressed'),
1422 rev=opts.get('rev'),
1422 rev=opts.get('rev'),
1423 update=opts.get('updaterev') or not opts.get('noupdate'),
1423 update=opts.get('updaterev') or not opts.get('noupdate'),
1424 branch=opts.get('branch'),
1424 branch=opts.get('branch'),
1425 shareopts=opts.get('shareopts'))
1425 shareopts=opts.get('shareopts'))
1426
1426
1427 return r is None
1427 return r is None
1428
1428
1429 @command('^commit|ci',
1429 @command('^commit|ci',
1430 [('A', 'addremove', None,
1430 [('A', 'addremove', None,
1431 _('mark new/missing files as added/removed before committing')),
1431 _('mark new/missing files as added/removed before committing')),
1432 ('', 'close-branch', None,
1432 ('', 'close-branch', None,
1433 _('mark a branch head as closed')),
1433 _('mark a branch head as closed')),
1434 ('', 'amend', None, _('amend the parent of the working directory')),
1434 ('', 'amend', None, _('amend the parent of the working directory')),
1435 ('s', 'secret', None, _('use the secret phase for committing')),
1435 ('s', 'secret', None, _('use the secret phase for committing')),
1436 ('e', 'edit', None, _('invoke editor on commit messages')),
1436 ('e', 'edit', None, _('invoke editor on commit messages')),
1437 ('i', 'interactive', None, _('use interactive mode')),
1437 ('i', 'interactive', None, _('use interactive mode')),
1438 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1438 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1439 _('[OPTION]... [FILE]...'),
1439 _('[OPTION]... [FILE]...'),
1440 inferrepo=True)
1440 inferrepo=True)
1441 def commit(ui, repo, *pats, **opts):
1441 def commit(ui, repo, *pats, **opts):
1442 """commit the specified files or all outstanding changes
1442 """commit the specified files or all outstanding changes
1443
1443
1444 Commit changes to the given files into the repository. Unlike a
1444 Commit changes to the given files into the repository. Unlike a
1445 centralized SCM, this operation is a local operation. See
1445 centralized SCM, this operation is a local operation. See
1446 :hg:`push` for a way to actively distribute your changes.
1446 :hg:`push` for a way to actively distribute your changes.
1447
1447
1448 If a list of files is omitted, all changes reported by :hg:`status`
1448 If a list of files is omitted, all changes reported by :hg:`status`
1449 will be committed.
1449 will be committed.
1450
1450
1451 If you are committing the result of a merge, do not provide any
1451 If you are committing the result of a merge, do not provide any
1452 filenames or -I/-X filters.
1452 filenames or -I/-X filters.
1453
1453
1454 If no commit message is specified, Mercurial starts your
1454 If no commit message is specified, Mercurial starts your
1455 configured editor where you can enter a message. In case your
1455 configured editor where you can enter a message. In case your
1456 commit fails, you will find a backup of your message in
1456 commit fails, you will find a backup of your message in
1457 ``.hg/last-message.txt``.
1457 ``.hg/last-message.txt``.
1458
1458
1459 The --close-branch flag can be used to mark the current branch
1459 The --close-branch flag can be used to mark the current branch
1460 head closed. When all heads of a branch are closed, the branch
1460 head closed. When all heads of a branch are closed, the branch
1461 will be considered closed and no longer listed.
1461 will be considered closed and no longer listed.
1462
1462
1463 The --amend flag can be used to amend the parent of the
1463 The --amend flag can be used to amend the parent of the
1464 working directory with a new commit that contains the changes
1464 working directory with a new commit that contains the changes
1465 in the parent in addition to those currently reported by :hg:`status`,
1465 in the parent in addition to those currently reported by :hg:`status`,
1466 if there are any. The old commit is stored in a backup bundle in
1466 if there are any. The old commit is stored in a backup bundle in
1467 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1467 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1468 on how to restore it).
1468 on how to restore it).
1469
1469
1470 Message, user and date are taken from the amended commit unless
1470 Message, user and date are taken from the amended commit unless
1471 specified. When a message isn't specified on the command line,
1471 specified. When a message isn't specified on the command line,
1472 the editor will open with the message of the amended commit.
1472 the editor will open with the message of the amended commit.
1473
1473
1474 It is not possible to amend public changesets (see :hg:`help phases`)
1474 It is not possible to amend public changesets (see :hg:`help phases`)
1475 or changesets that have children.
1475 or changesets that have children.
1476
1476
1477 See :hg:`help dates` for a list of formats valid for -d/--date.
1477 See :hg:`help dates` for a list of formats valid for -d/--date.
1478
1478
1479 Returns 0 on success, 1 if nothing changed.
1479 Returns 0 on success, 1 if nothing changed.
1480 """
1480 """
1481 if opts.get('interactive'):
1481 if opts.get('interactive'):
1482 opts.pop('interactive')
1482 opts.pop('interactive')
1483 cmdutil.dorecord(ui, repo, commit, None, False,
1483 cmdutil.dorecord(ui, repo, commit, None, False,
1484 cmdutil.recordfilter, *pats, **opts)
1484 cmdutil.recordfilter, *pats, **opts)
1485 return
1485 return
1486
1486
1487 if opts.get('subrepos'):
1487 if opts.get('subrepos'):
1488 if opts.get('amend'):
1488 if opts.get('amend'):
1489 raise util.Abort(_('cannot amend with --subrepos'))
1489 raise util.Abort(_('cannot amend with --subrepos'))
1490 # Let --subrepos on the command line override config setting.
1490 # Let --subrepos on the command line override config setting.
1491 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1491 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1492
1492
1493 cmdutil.checkunfinished(repo, commit=True)
1493 cmdutil.checkunfinished(repo, commit=True)
1494
1494
1495 branch = repo[None].branch()
1495 branch = repo[None].branch()
1496 bheads = repo.branchheads(branch)
1496 bheads = repo.branchheads(branch)
1497
1497
1498 extra = {}
1498 extra = {}
1499 if opts.get('close_branch'):
1499 if opts.get('close_branch'):
1500 extra['close'] = 1
1500 extra['close'] = 1
1501
1501
1502 if not bheads:
1502 if not bheads:
1503 raise util.Abort(_('can only close branch heads'))
1503 raise util.Abort(_('can only close branch heads'))
1504 elif opts.get('amend'):
1504 elif opts.get('amend'):
1505 if repo.parents()[0].p1().branch() != branch and \
1505 if repo.parents()[0].p1().branch() != branch and \
1506 repo.parents()[0].p2().branch() != branch:
1506 repo.parents()[0].p2().branch() != branch:
1507 raise util.Abort(_('can only close branch heads'))
1507 raise util.Abort(_('can only close branch heads'))
1508
1508
1509 if opts.get('amend'):
1509 if opts.get('amend'):
1510 if ui.configbool('ui', 'commitsubrepos'):
1510 if ui.configbool('ui', 'commitsubrepos'):
1511 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1511 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1512
1512
1513 old = repo['.']
1513 old = repo['.']
1514 if not old.mutable():
1514 if not old.mutable():
1515 raise util.Abort(_('cannot amend public changesets'))
1515 raise util.Abort(_('cannot amend public changesets'))
1516 if len(repo[None].parents()) > 1:
1516 if len(repo[None].parents()) > 1:
1517 raise util.Abort(_('cannot amend while merging'))
1517 raise util.Abort(_('cannot amend while merging'))
1518 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1518 allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
1519 if not allowunstable and old.children():
1519 if not allowunstable and old.children():
1520 raise util.Abort(_('cannot amend changeset with children'))
1520 raise util.Abort(_('cannot amend changeset with children'))
1521
1521
1522 # commitfunc is used only for temporary amend commit by cmdutil.amend
1522 # commitfunc is used only for temporary amend commit by cmdutil.amend
1523 def commitfunc(ui, repo, message, match, opts):
1523 def commitfunc(ui, repo, message, match, opts):
1524 return repo.commit(message,
1524 return repo.commit(message,
1525 opts.get('user') or old.user(),
1525 opts.get('user') or old.user(),
1526 opts.get('date') or old.date(),
1526 opts.get('date') or old.date(),
1527 match,
1527 match,
1528 extra=extra)
1528 extra=extra)
1529
1529
1530 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1530 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1531 if node == old.node():
1531 if node == old.node():
1532 ui.status(_("nothing changed\n"))
1532 ui.status(_("nothing changed\n"))
1533 return 1
1533 return 1
1534 else:
1534 else:
1535 def commitfunc(ui, repo, message, match, opts):
1535 def commitfunc(ui, repo, message, match, opts):
1536 backup = ui.backupconfig('phases', 'new-commit')
1536 backup = ui.backupconfig('phases', 'new-commit')
1537 baseui = repo.baseui
1537 baseui = repo.baseui
1538 basebackup = baseui.backupconfig('phases', 'new-commit')
1538 basebackup = baseui.backupconfig('phases', 'new-commit')
1539 try:
1539 try:
1540 if opts.get('secret'):
1540 if opts.get('secret'):
1541 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1541 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1542 # Propagate to subrepos
1542 # Propagate to subrepos
1543 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1543 baseui.setconfig('phases', 'new-commit', 'secret', 'commit')
1544
1544
1545 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1545 editform = cmdutil.mergeeditform(repo[None], 'commit.normal')
1546 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1546 editor = cmdutil.getcommiteditor(editform=editform, **opts)
1547 return repo.commit(message, opts.get('user'), opts.get('date'),
1547 return repo.commit(message, opts.get('user'), opts.get('date'),
1548 match,
1548 match,
1549 editor=editor,
1549 editor=editor,
1550 extra=extra)
1550 extra=extra)
1551 finally:
1551 finally:
1552 ui.restoreconfig(backup)
1552 ui.restoreconfig(backup)
1553 repo.baseui.restoreconfig(basebackup)
1553 repo.baseui.restoreconfig(basebackup)
1554
1554
1555
1555
1556 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1556 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1557
1557
1558 if not node:
1558 if not node:
1559 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1559 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1560 if stat[3]:
1560 if stat[3]:
1561 ui.status(_("nothing changed (%d missing files, see "
1561 ui.status(_("nothing changed (%d missing files, see "
1562 "'hg status')\n") % len(stat[3]))
1562 "'hg status')\n") % len(stat[3]))
1563 else:
1563 else:
1564 ui.status(_("nothing changed\n"))
1564 ui.status(_("nothing changed\n"))
1565 return 1
1565 return 1
1566
1566
1567 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1567 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1568
1568
1569 @command('config|showconfig|debugconfig',
1569 @command('config|showconfig|debugconfig',
1570 [('u', 'untrusted', None, _('show untrusted configuration options')),
1570 [('u', 'untrusted', None, _('show untrusted configuration options')),
1571 ('e', 'edit', None, _('edit user config')),
1571 ('e', 'edit', None, _('edit user config')),
1572 ('l', 'local', None, _('edit repository config')),
1572 ('l', 'local', None, _('edit repository config')),
1573 ('g', 'global', None, _('edit global config'))],
1573 ('g', 'global', None, _('edit global config'))],
1574 _('[-u] [NAME]...'),
1574 _('[-u] [NAME]...'),
1575 optionalrepo=True)
1575 optionalrepo=True)
1576 def config(ui, repo, *values, **opts):
1576 def config(ui, repo, *values, **opts):
1577 """show combined config settings from all hgrc files
1577 """show combined config settings from all hgrc files
1578
1578
1579 With no arguments, print names and values of all config items.
1579 With no arguments, print names and values of all config items.
1580
1580
1581 With one argument of the form section.name, print just the value
1581 With one argument of the form section.name, print just the value
1582 of that config item.
1582 of that config item.
1583
1583
1584 With multiple arguments, print names and values of all config
1584 With multiple arguments, print names and values of all config
1585 items with matching section names.
1585 items with matching section names.
1586
1586
1587 With --edit, start an editor on the user-level config file. With
1587 With --edit, start an editor on the user-level config file. With
1588 --global, edit the system-wide config file. With --local, edit the
1588 --global, edit the system-wide config file. With --local, edit the
1589 repository-level config file.
1589 repository-level config file.
1590
1590
1591 With --debug, the source (filename and line number) is printed
1591 With --debug, the source (filename and line number) is printed
1592 for each config item.
1592 for each config item.
1593
1593
1594 See :hg:`help config` for more information about config files.
1594 See :hg:`help config` for more information about config files.
1595
1595
1596 Returns 0 on success, 1 if NAME does not exist.
1596 Returns 0 on success, 1 if NAME does not exist.
1597
1597
1598 """
1598 """
1599
1599
1600 if opts.get('edit') or opts.get('local') or opts.get('global'):
1600 if opts.get('edit') or opts.get('local') or opts.get('global'):
1601 if opts.get('local') and opts.get('global'):
1601 if opts.get('local') and opts.get('global'):
1602 raise util.Abort(_("can't use --local and --global together"))
1602 raise util.Abort(_("can't use --local and --global together"))
1603
1603
1604 if opts.get('local'):
1604 if opts.get('local'):
1605 if not repo:
1605 if not repo:
1606 raise util.Abort(_("can't use --local outside a repository"))
1606 raise util.Abort(_("can't use --local outside a repository"))
1607 paths = [repo.join('hgrc')]
1607 paths = [repo.join('hgrc')]
1608 elif opts.get('global'):
1608 elif opts.get('global'):
1609 paths = scmutil.systemrcpath()
1609 paths = scmutil.systemrcpath()
1610 else:
1610 else:
1611 paths = scmutil.userrcpath()
1611 paths = scmutil.userrcpath()
1612
1612
1613 for f in paths:
1613 for f in paths:
1614 if os.path.exists(f):
1614 if os.path.exists(f):
1615 break
1615 break
1616 else:
1616 else:
1617 if opts.get('global'):
1617 if opts.get('global'):
1618 samplehgrc = uimod.samplehgrcs['global']
1618 samplehgrc = uimod.samplehgrcs['global']
1619 elif opts.get('local'):
1619 elif opts.get('local'):
1620 samplehgrc = uimod.samplehgrcs['local']
1620 samplehgrc = uimod.samplehgrcs['local']
1621 else:
1621 else:
1622 samplehgrc = uimod.samplehgrcs['user']
1622 samplehgrc = uimod.samplehgrcs['user']
1623
1623
1624 f = paths[0]
1624 f = paths[0]
1625 fp = open(f, "w")
1625 fp = open(f, "w")
1626 fp.write(samplehgrc)
1626 fp.write(samplehgrc)
1627 fp.close()
1627 fp.close()
1628
1628
1629 editor = ui.geteditor()
1629 editor = ui.geteditor()
1630 ui.system("%s \"%s\"" % (editor, f),
1630 ui.system("%s \"%s\"" % (editor, f),
1631 onerr=util.Abort, errprefix=_("edit failed"))
1631 onerr=util.Abort, errprefix=_("edit failed"))
1632 return
1632 return
1633
1633
1634 for f in scmutil.rcpath():
1634 for f in scmutil.rcpath():
1635 ui.debug('read config from: %s\n' % f)
1635 ui.debug('read config from: %s\n' % f)
1636 untrusted = bool(opts.get('untrusted'))
1636 untrusted = bool(opts.get('untrusted'))
1637 if values:
1637 if values:
1638 sections = [v for v in values if '.' not in v]
1638 sections = [v for v in values if '.' not in v]
1639 items = [v for v in values if '.' in v]
1639 items = [v for v in values if '.' in v]
1640 if len(items) > 1 or items and sections:
1640 if len(items) > 1 or items and sections:
1641 raise util.Abort(_('only one config item permitted'))
1641 raise util.Abort(_('only one config item permitted'))
1642 matched = False
1642 matched = False
1643 for section, name, value in ui.walkconfig(untrusted=untrusted):
1643 for section, name, value in ui.walkconfig(untrusted=untrusted):
1644 value = str(value).replace('\n', '\\n')
1644 value = str(value).replace('\n', '\\n')
1645 sectname = section + '.' + name
1645 sectname = section + '.' + name
1646 if values:
1646 if values:
1647 for v in values:
1647 for v in values:
1648 if v == section:
1648 if v == section:
1649 ui.debug('%s: ' %
1649 ui.debug('%s: ' %
1650 ui.configsource(section, name, untrusted))
1650 ui.configsource(section, name, untrusted))
1651 ui.write('%s=%s\n' % (sectname, value))
1651 ui.write('%s=%s\n' % (sectname, value))
1652 matched = True
1652 matched = True
1653 elif v == sectname:
1653 elif v == sectname:
1654 ui.debug('%s: ' %
1654 ui.debug('%s: ' %
1655 ui.configsource(section, name, untrusted))
1655 ui.configsource(section, name, untrusted))
1656 ui.write(value, '\n')
1656 ui.write(value, '\n')
1657 matched = True
1657 matched = True
1658 else:
1658 else:
1659 ui.debug('%s: ' %
1659 ui.debug('%s: ' %
1660 ui.configsource(section, name, untrusted))
1660 ui.configsource(section, name, untrusted))
1661 ui.write('%s=%s\n' % (sectname, value))
1661 ui.write('%s=%s\n' % (sectname, value))
1662 matched = True
1662 matched = True
1663 if matched:
1663 if matched:
1664 return 0
1664 return 0
1665 return 1
1665 return 1
1666
1666
1667 @command('copy|cp',
1667 @command('copy|cp',
1668 [('A', 'after', None, _('record a copy that has already occurred')),
1668 [('A', 'after', None, _('record a copy that has already occurred')),
1669 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1669 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1670 ] + walkopts + dryrunopts,
1670 ] + walkopts + dryrunopts,
1671 _('[OPTION]... [SOURCE]... DEST'))
1671 _('[OPTION]... [SOURCE]... DEST'))
1672 def copy(ui, repo, *pats, **opts):
1672 def copy(ui, repo, *pats, **opts):
1673 """mark files as copied for the next commit
1673 """mark files as copied for the next commit
1674
1674
1675 Mark dest as having copies of source files. If dest is a
1675 Mark dest as having copies of source files. If dest is a
1676 directory, copies are put in that directory. If dest is a file,
1676 directory, copies are put in that directory. If dest is a file,
1677 the source must be a single file.
1677 the source must be a single file.
1678
1678
1679 By default, this command copies the contents of files as they
1679 By default, this command copies the contents of files as they
1680 exist in the working directory. If invoked with -A/--after, the
1680 exist in the working directory. If invoked with -A/--after, the
1681 operation is recorded, but no copying is performed.
1681 operation is recorded, but no copying is performed.
1682
1682
1683 This command takes effect with the next commit. To undo a copy
1683 This command takes effect with the next commit. To undo a copy
1684 before that, see :hg:`revert`.
1684 before that, see :hg:`revert`.
1685
1685
1686 Returns 0 on success, 1 if errors are encountered.
1686 Returns 0 on success, 1 if errors are encountered.
1687 """
1687 """
1688 wlock = repo.wlock(False)
1688 wlock = repo.wlock(False)
1689 try:
1689 try:
1690 return cmdutil.copy(ui, repo, pats, opts)
1690 return cmdutil.copy(ui, repo, pats, opts)
1691 finally:
1691 finally:
1692 wlock.release()
1692 wlock.release()
1693
1693
1694 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
1694 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
1695 def debugancestor(ui, repo, *args):
1695 def debugancestor(ui, repo, *args):
1696 """find the ancestor revision of two revisions in a given index"""
1696 """find the ancestor revision of two revisions in a given index"""
1697 if len(args) == 3:
1697 if len(args) == 3:
1698 index, rev1, rev2 = args
1698 index, rev1, rev2 = args
1699 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1699 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1700 lookup = r.lookup
1700 lookup = r.lookup
1701 elif len(args) == 2:
1701 elif len(args) == 2:
1702 if not repo:
1702 if not repo:
1703 raise util.Abort(_("there is no Mercurial repository here "
1703 raise util.Abort(_("there is no Mercurial repository here "
1704 "(.hg not found)"))
1704 "(.hg not found)"))
1705 rev1, rev2 = args
1705 rev1, rev2 = args
1706 r = repo.changelog
1706 r = repo.changelog
1707 lookup = repo.lookup
1707 lookup = repo.lookup
1708 else:
1708 else:
1709 raise util.Abort(_('either two or three arguments required'))
1709 raise util.Abort(_('either two or three arguments required'))
1710 a = r.ancestor(lookup(rev1), lookup(rev2))
1710 a = r.ancestor(lookup(rev1), lookup(rev2))
1711 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1711 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1712
1712
1713 @command('debugbuilddag',
1713 @command('debugbuilddag',
1714 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1714 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1715 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1715 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1716 ('n', 'new-file', None, _('add new file at each rev'))],
1716 ('n', 'new-file', None, _('add new file at each rev'))],
1717 _('[OPTION]... [TEXT]'))
1717 _('[OPTION]... [TEXT]'))
1718 def debugbuilddag(ui, repo, text=None,
1718 def debugbuilddag(ui, repo, text=None,
1719 mergeable_file=False,
1719 mergeable_file=False,
1720 overwritten_file=False,
1720 overwritten_file=False,
1721 new_file=False):
1721 new_file=False):
1722 """builds a repo with a given DAG from scratch in the current empty repo
1722 """builds a repo with a given DAG from scratch in the current empty repo
1723
1723
1724 The description of the DAG is read from stdin if not given on the
1724 The description of the DAG is read from stdin if not given on the
1725 command line.
1725 command line.
1726
1726
1727 Elements:
1727 Elements:
1728
1728
1729 - "+n" is a linear run of n nodes based on the current default parent
1729 - "+n" is a linear run of n nodes based on the current default parent
1730 - "." is a single node based on the current default parent
1730 - "." is a single node based on the current default parent
1731 - "$" resets the default parent to null (implied at the start);
1731 - "$" resets the default parent to null (implied at the start);
1732 otherwise the default parent is always the last node created
1732 otherwise the default parent is always the last node created
1733 - "<p" sets the default parent to the backref p
1733 - "<p" sets the default parent to the backref p
1734 - "*p" is a fork at parent p, which is a backref
1734 - "*p" is a fork at parent p, which is a backref
1735 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1735 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1736 - "/p2" is a merge of the preceding node and p2
1736 - "/p2" is a merge of the preceding node and p2
1737 - ":tag" defines a local tag for the preceding node
1737 - ":tag" defines a local tag for the preceding node
1738 - "@branch" sets the named branch for subsequent nodes
1738 - "@branch" sets the named branch for subsequent nodes
1739 - "#...\\n" is a comment up to the end of the line
1739 - "#...\\n" is a comment up to the end of the line
1740
1740
1741 Whitespace between the above elements is ignored.
1741 Whitespace between the above elements is ignored.
1742
1742
1743 A backref is either
1743 A backref is either
1744
1744
1745 - a number n, which references the node curr-n, where curr is the current
1745 - a number n, which references the node curr-n, where curr is the current
1746 node, or
1746 node, or
1747 - the name of a local tag you placed earlier using ":tag", or
1747 - the name of a local tag you placed earlier using ":tag", or
1748 - empty to denote the default parent.
1748 - empty to denote the default parent.
1749
1749
1750 All string valued-elements are either strictly alphanumeric, or must
1750 All string valued-elements are either strictly alphanumeric, or must
1751 be enclosed in double quotes ("..."), with "\\" as escape character.
1751 be enclosed in double quotes ("..."), with "\\" as escape character.
1752 """
1752 """
1753
1753
1754 if text is None:
1754 if text is None:
1755 ui.status(_("reading DAG from stdin\n"))
1755 ui.status(_("reading DAG from stdin\n"))
1756 text = ui.fin.read()
1756 text = ui.fin.read()
1757
1757
1758 cl = repo.changelog
1758 cl = repo.changelog
1759 if len(cl) > 0:
1759 if len(cl) > 0:
1760 raise util.Abort(_('repository is not empty'))
1760 raise util.Abort(_('repository is not empty'))
1761
1761
1762 # determine number of revs in DAG
1762 # determine number of revs in DAG
1763 total = 0
1763 total = 0
1764 for type, data in dagparser.parsedag(text):
1764 for type, data in dagparser.parsedag(text):
1765 if type == 'n':
1765 if type == 'n':
1766 total += 1
1766 total += 1
1767
1767
1768 if mergeable_file:
1768 if mergeable_file:
1769 linesperrev = 2
1769 linesperrev = 2
1770 # make a file with k lines per rev
1770 # make a file with k lines per rev
1771 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1771 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1772 initialmergedlines.append("")
1772 initialmergedlines.append("")
1773
1773
1774 tags = []
1774 tags = []
1775
1775
1776 lock = tr = None
1776 lock = tr = None
1777 try:
1777 try:
1778 lock = repo.lock()
1778 lock = repo.lock()
1779 tr = repo.transaction("builddag")
1779 tr = repo.transaction("builddag")
1780
1780
1781 at = -1
1781 at = -1
1782 atbranch = 'default'
1782 atbranch = 'default'
1783 nodeids = []
1783 nodeids = []
1784 id = 0
1784 id = 0
1785 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1785 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1786 for type, data in dagparser.parsedag(text):
1786 for type, data in dagparser.parsedag(text):
1787 if type == 'n':
1787 if type == 'n':
1788 ui.note(('node %s\n' % str(data)))
1788 ui.note(('node %s\n' % str(data)))
1789 id, ps = data
1789 id, ps = data
1790
1790
1791 files = []
1791 files = []
1792 fctxs = {}
1792 fctxs = {}
1793
1793
1794 p2 = None
1794 p2 = None
1795 if mergeable_file:
1795 if mergeable_file:
1796 fn = "mf"
1796 fn = "mf"
1797 p1 = repo[ps[0]]
1797 p1 = repo[ps[0]]
1798 if len(ps) > 1:
1798 if len(ps) > 1:
1799 p2 = repo[ps[1]]
1799 p2 = repo[ps[1]]
1800 pa = p1.ancestor(p2)
1800 pa = p1.ancestor(p2)
1801 base, local, other = [x[fn].data() for x in (pa, p1,
1801 base, local, other = [x[fn].data() for x in (pa, p1,
1802 p2)]
1802 p2)]
1803 m3 = simplemerge.Merge3Text(base, local, other)
1803 m3 = simplemerge.Merge3Text(base, local, other)
1804 ml = [l.strip() for l in m3.merge_lines()]
1804 ml = [l.strip() for l in m3.merge_lines()]
1805 ml.append("")
1805 ml.append("")
1806 elif at > 0:
1806 elif at > 0:
1807 ml = p1[fn].data().split("\n")
1807 ml = p1[fn].data().split("\n")
1808 else:
1808 else:
1809 ml = initialmergedlines
1809 ml = initialmergedlines
1810 ml[id * linesperrev] += " r%i" % id
1810 ml[id * linesperrev] += " r%i" % id
1811 mergedtext = "\n".join(ml)
1811 mergedtext = "\n".join(ml)
1812 files.append(fn)
1812 files.append(fn)
1813 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1813 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1814
1814
1815 if overwritten_file:
1815 if overwritten_file:
1816 fn = "of"
1816 fn = "of"
1817 files.append(fn)
1817 files.append(fn)
1818 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1818 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1819
1819
1820 if new_file:
1820 if new_file:
1821 fn = "nf%i" % id
1821 fn = "nf%i" % id
1822 files.append(fn)
1822 files.append(fn)
1823 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1823 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1824 if len(ps) > 1:
1824 if len(ps) > 1:
1825 if not p2:
1825 if not p2:
1826 p2 = repo[ps[1]]
1826 p2 = repo[ps[1]]
1827 for fn in p2:
1827 for fn in p2:
1828 if fn.startswith("nf"):
1828 if fn.startswith("nf"):
1829 files.append(fn)
1829 files.append(fn)
1830 fctxs[fn] = p2[fn]
1830 fctxs[fn] = p2[fn]
1831
1831
1832 def fctxfn(repo, cx, path):
1832 def fctxfn(repo, cx, path):
1833 return fctxs.get(path)
1833 return fctxs.get(path)
1834
1834
1835 if len(ps) == 0 or ps[0] < 0:
1835 if len(ps) == 0 or ps[0] < 0:
1836 pars = [None, None]
1836 pars = [None, None]
1837 elif len(ps) == 1:
1837 elif len(ps) == 1:
1838 pars = [nodeids[ps[0]], None]
1838 pars = [nodeids[ps[0]], None]
1839 else:
1839 else:
1840 pars = [nodeids[p] for p in ps]
1840 pars = [nodeids[p] for p in ps]
1841 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1841 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1842 date=(id, 0),
1842 date=(id, 0),
1843 user="debugbuilddag",
1843 user="debugbuilddag",
1844 extra={'branch': atbranch})
1844 extra={'branch': atbranch})
1845 nodeid = repo.commitctx(cx)
1845 nodeid = repo.commitctx(cx)
1846 nodeids.append(nodeid)
1846 nodeids.append(nodeid)
1847 at = id
1847 at = id
1848 elif type == 'l':
1848 elif type == 'l':
1849 id, name = data
1849 id, name = data
1850 ui.note(('tag %s\n' % name))
1850 ui.note(('tag %s\n' % name))
1851 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1851 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1852 elif type == 'a':
1852 elif type == 'a':
1853 ui.note(('branch %s\n' % data))
1853 ui.note(('branch %s\n' % data))
1854 atbranch = data
1854 atbranch = data
1855 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1855 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1856 tr.close()
1856 tr.close()
1857
1857
1858 if tags:
1858 if tags:
1859 repo.vfs.write("localtags", "".join(tags))
1859 repo.vfs.write("localtags", "".join(tags))
1860 finally:
1860 finally:
1861 ui.progress(_('building'), None)
1861 ui.progress(_('building'), None)
1862 release(tr, lock)
1862 release(tr, lock)
1863
1863
1864 @command('debugbundle',
1864 @command('debugbundle',
1865 [('a', 'all', None, _('show all details'))],
1865 [('a', 'all', None, _('show all details'))],
1866 _('FILE'),
1866 _('FILE'),
1867 norepo=True)
1867 norepo=True)
1868 def debugbundle(ui, bundlepath, all=None, **opts):
1868 def debugbundle(ui, bundlepath, all=None, **opts):
1869 """lists the contents of a bundle"""
1869 """lists the contents of a bundle"""
1870 f = hg.openpath(ui, bundlepath)
1870 f = hg.openpath(ui, bundlepath)
1871 try:
1871 try:
1872 gen = exchange.readbundle(ui, f, bundlepath)
1872 gen = exchange.readbundle(ui, f, bundlepath)
1873 if isinstance(gen, bundle2.unbundle20):
1873 if isinstance(gen, bundle2.unbundle20):
1874 return _debugbundle2(ui, gen, all=all, **opts)
1874 return _debugbundle2(ui, gen, all=all, **opts)
1875 if all:
1875 if all:
1876 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1876 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1877
1877
1878 def showchunks(named):
1878 def showchunks(named):
1879 ui.write("\n%s\n" % named)
1879 ui.write("\n%s\n" % named)
1880 chain = None
1880 chain = None
1881 while True:
1881 while True:
1882 chunkdata = gen.deltachunk(chain)
1882 chunkdata = gen.deltachunk(chain)
1883 if not chunkdata:
1883 if not chunkdata:
1884 break
1884 break
1885 node = chunkdata['node']
1885 node = chunkdata['node']
1886 p1 = chunkdata['p1']
1886 p1 = chunkdata['p1']
1887 p2 = chunkdata['p2']
1887 p2 = chunkdata['p2']
1888 cs = chunkdata['cs']
1888 cs = chunkdata['cs']
1889 deltabase = chunkdata['deltabase']
1889 deltabase = chunkdata['deltabase']
1890 delta = chunkdata['delta']
1890 delta = chunkdata['delta']
1891 ui.write("%s %s %s %s %s %s\n" %
1891 ui.write("%s %s %s %s %s %s\n" %
1892 (hex(node), hex(p1), hex(p2),
1892 (hex(node), hex(p1), hex(p2),
1893 hex(cs), hex(deltabase), len(delta)))
1893 hex(cs), hex(deltabase), len(delta)))
1894 chain = node
1894 chain = node
1895
1895
1896 chunkdata = gen.changelogheader()
1896 chunkdata = gen.changelogheader()
1897 showchunks("changelog")
1897 showchunks("changelog")
1898 chunkdata = gen.manifestheader()
1898 chunkdata = gen.manifestheader()
1899 showchunks("manifest")
1899 showchunks("manifest")
1900 while True:
1900 while True:
1901 chunkdata = gen.filelogheader()
1901 chunkdata = gen.filelogheader()
1902 if not chunkdata:
1902 if not chunkdata:
1903 break
1903 break
1904 fname = chunkdata['filename']
1904 fname = chunkdata['filename']
1905 showchunks(fname)
1905 showchunks(fname)
1906 else:
1906 else:
1907 if isinstance(gen, bundle2.unbundle20):
1907 if isinstance(gen, bundle2.unbundle20):
1908 raise util.Abort(_('use debugbundle2 for this file'))
1908 raise util.Abort(_('use debugbundle2 for this file'))
1909 chunkdata = gen.changelogheader()
1909 chunkdata = gen.changelogheader()
1910 chain = None
1910 chain = None
1911 while True:
1911 while True:
1912 chunkdata = gen.deltachunk(chain)
1912 chunkdata = gen.deltachunk(chain)
1913 if not chunkdata:
1913 if not chunkdata:
1914 break
1914 break
1915 node = chunkdata['node']
1915 node = chunkdata['node']
1916 ui.write("%s\n" % hex(node))
1916 ui.write("%s\n" % hex(node))
1917 chain = node
1917 chain = node
1918 finally:
1918 finally:
1919 f.close()
1919 f.close()
1920
1920
1921 def _debugbundle2(ui, gen, **opts):
1921 def _debugbundle2(ui, gen, **opts):
1922 """lists the contents of a bundle2"""
1922 """lists the contents of a bundle2"""
1923 if not isinstance(gen, bundle2.unbundle20):
1923 if not isinstance(gen, bundle2.unbundle20):
1924 raise util.Abort(_('not a bundle2 file'))
1924 raise util.Abort(_('not a bundle2 file'))
1925 ui.write(('Stream params: %s\n' % repr(gen.params)))
1925 ui.write(('Stream params: %s\n' % repr(gen.params)))
1926 for part in gen.iterparts():
1926 for part in gen.iterparts():
1927 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
1927 ui.write('%s -- %r\n' % (part.type, repr(part.params)))
1928 if part.type == 'changegroup':
1928 if part.type == 'changegroup':
1929 version = part.params.get('version', '01')
1929 version = part.params.get('version', '01')
1930 cg = changegroup.packermap[version][1](part, 'UN')
1930 cg = changegroup.packermap[version][1](part, 'UN')
1931 chunkdata = cg.changelogheader()
1931 chunkdata = cg.changelogheader()
1932 chain = None
1932 chain = None
1933 while True:
1933 while True:
1934 chunkdata = cg.deltachunk(chain)
1934 chunkdata = cg.deltachunk(chain)
1935 if not chunkdata:
1935 if not chunkdata:
1936 break
1936 break
1937 node = chunkdata['node']
1937 node = chunkdata['node']
1938 ui.write(" %s\n" % hex(node))
1938 ui.write(" %s\n" % hex(node))
1939 chain = node
1939 chain = node
1940
1940
1941 @command('debugcheckstate', [], '')
1941 @command('debugcheckstate', [], '')
1942 def debugcheckstate(ui, repo):
1942 def debugcheckstate(ui, repo):
1943 """validate the correctness of the current dirstate"""
1943 """validate the correctness of the current dirstate"""
1944 parent1, parent2 = repo.dirstate.parents()
1944 parent1, parent2 = repo.dirstate.parents()
1945 m1 = repo[parent1].manifest()
1945 m1 = repo[parent1].manifest()
1946 m2 = repo[parent2].manifest()
1946 m2 = repo[parent2].manifest()
1947 errors = 0
1947 errors = 0
1948 for f in repo.dirstate:
1948 for f in repo.dirstate:
1949 state = repo.dirstate[f]
1949 state = repo.dirstate[f]
1950 if state in "nr" and f not in m1:
1950 if state in "nr" and f not in m1:
1951 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1951 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1952 errors += 1
1952 errors += 1
1953 if state in "a" and f in m1:
1953 if state in "a" and f in m1:
1954 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1954 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1955 errors += 1
1955 errors += 1
1956 if state in "m" and f not in m1 and f not in m2:
1956 if state in "m" and f not in m1 and f not in m2:
1957 ui.warn(_("%s in state %s, but not in either manifest\n") %
1957 ui.warn(_("%s in state %s, but not in either manifest\n") %
1958 (f, state))
1958 (f, state))
1959 errors += 1
1959 errors += 1
1960 for f in m1:
1960 for f in m1:
1961 state = repo.dirstate[f]
1961 state = repo.dirstate[f]
1962 if state not in "nrm":
1962 if state not in "nrm":
1963 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1963 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1964 errors += 1
1964 errors += 1
1965 if errors:
1965 if errors:
1966 error = _(".hg/dirstate inconsistent with current parent's manifest")
1966 error = _(".hg/dirstate inconsistent with current parent's manifest")
1967 raise util.Abort(error)
1967 raise util.Abort(error)
1968
1968
1969 @command('debugcommands', [], _('[COMMAND]'), norepo=True)
1969 @command('debugcommands', [], _('[COMMAND]'), norepo=True)
1970 def debugcommands(ui, cmd='', *args):
1970 def debugcommands(ui, cmd='', *args):
1971 """list all available commands and options"""
1971 """list all available commands and options"""
1972 for cmd, vals in sorted(table.iteritems()):
1972 for cmd, vals in sorted(table.iteritems()):
1973 cmd = cmd.split('|')[0].strip('^')
1973 cmd = cmd.split('|')[0].strip('^')
1974 opts = ', '.join([i[1] for i in vals[1]])
1974 opts = ', '.join([i[1] for i in vals[1]])
1975 ui.write('%s: %s\n' % (cmd, opts))
1975 ui.write('%s: %s\n' % (cmd, opts))
1976
1976
1977 @command('debugcomplete',
1977 @command('debugcomplete',
1978 [('o', 'options', None, _('show the command options'))],
1978 [('o', 'options', None, _('show the command options'))],
1979 _('[-o] CMD'),
1979 _('[-o] CMD'),
1980 norepo=True)
1980 norepo=True)
1981 def debugcomplete(ui, cmd='', **opts):
1981 def debugcomplete(ui, cmd='', **opts):
1982 """returns the completion list associated with the given command"""
1982 """returns the completion list associated with the given command"""
1983
1983
1984 if opts.get('options'):
1984 if opts.get('options'):
1985 options = []
1985 options = []
1986 otables = [globalopts]
1986 otables = [globalopts]
1987 if cmd:
1987 if cmd:
1988 aliases, entry = cmdutil.findcmd(cmd, table, False)
1988 aliases, entry = cmdutil.findcmd(cmd, table, False)
1989 otables.append(entry[1])
1989 otables.append(entry[1])
1990 for t in otables:
1990 for t in otables:
1991 for o in t:
1991 for o in t:
1992 if "(DEPRECATED)" in o[3]:
1992 if "(DEPRECATED)" in o[3]:
1993 continue
1993 continue
1994 if o[0]:
1994 if o[0]:
1995 options.append('-%s' % o[0])
1995 options.append('-%s' % o[0])
1996 options.append('--%s' % o[1])
1996 options.append('--%s' % o[1])
1997 ui.write("%s\n" % "\n".join(options))
1997 ui.write("%s\n" % "\n".join(options))
1998 return
1998 return
1999
1999
2000 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2000 cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
2001 if ui.verbose:
2001 if ui.verbose:
2002 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
2002 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
2003 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
2003 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
2004
2004
2005 @command('debugdag',
2005 @command('debugdag',
2006 [('t', 'tags', None, _('use tags as labels')),
2006 [('t', 'tags', None, _('use tags as labels')),
2007 ('b', 'branches', None, _('annotate with branch names')),
2007 ('b', 'branches', None, _('annotate with branch names')),
2008 ('', 'dots', None, _('use dots for runs')),
2008 ('', 'dots', None, _('use dots for runs')),
2009 ('s', 'spaces', None, _('separate elements by spaces'))],
2009 ('s', 'spaces', None, _('separate elements by spaces'))],
2010 _('[OPTION]... [FILE [REV]...]'),
2010 _('[OPTION]... [FILE [REV]...]'),
2011 optionalrepo=True)
2011 optionalrepo=True)
2012 def debugdag(ui, repo, file_=None, *revs, **opts):
2012 def debugdag(ui, repo, file_=None, *revs, **opts):
2013 """format the changelog or an index DAG as a concise textual description
2013 """format the changelog or an index DAG as a concise textual description
2014
2014
2015 If you pass a revlog index, the revlog's DAG is emitted. If you list
2015 If you pass a revlog index, the revlog's DAG is emitted. If you list
2016 revision numbers, they get labeled in the output as rN.
2016 revision numbers, they get labeled in the output as rN.
2017
2017
2018 Otherwise, the changelog DAG of the current repo is emitted.
2018 Otherwise, the changelog DAG of the current repo is emitted.
2019 """
2019 """
2020 spaces = opts.get('spaces')
2020 spaces = opts.get('spaces')
2021 dots = opts.get('dots')
2021 dots = opts.get('dots')
2022 if file_:
2022 if file_:
2023 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2023 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2024 revs = set((int(r) for r in revs))
2024 revs = set((int(r) for r in revs))
2025 def events():
2025 def events():
2026 for r in rlog:
2026 for r in rlog:
2027 yield 'n', (r, list(p for p in rlog.parentrevs(r)
2027 yield 'n', (r, list(p for p in rlog.parentrevs(r)
2028 if p != -1))
2028 if p != -1))
2029 if r in revs:
2029 if r in revs:
2030 yield 'l', (r, "r%i" % r)
2030 yield 'l', (r, "r%i" % r)
2031 elif repo:
2031 elif repo:
2032 cl = repo.changelog
2032 cl = repo.changelog
2033 tags = opts.get('tags')
2033 tags = opts.get('tags')
2034 branches = opts.get('branches')
2034 branches = opts.get('branches')
2035 if tags:
2035 if tags:
2036 labels = {}
2036 labels = {}
2037 for l, n in repo.tags().items():
2037 for l, n in repo.tags().items():
2038 labels.setdefault(cl.rev(n), []).append(l)
2038 labels.setdefault(cl.rev(n), []).append(l)
2039 def events():
2039 def events():
2040 b = "default"
2040 b = "default"
2041 for r in cl:
2041 for r in cl:
2042 if branches:
2042 if branches:
2043 newb = cl.read(cl.node(r))[5]['branch']
2043 newb = cl.read(cl.node(r))[5]['branch']
2044 if newb != b:
2044 if newb != b:
2045 yield 'a', newb
2045 yield 'a', newb
2046 b = newb
2046 b = newb
2047 yield 'n', (r, list(p for p in cl.parentrevs(r)
2047 yield 'n', (r, list(p for p in cl.parentrevs(r)
2048 if p != -1))
2048 if p != -1))
2049 if tags:
2049 if tags:
2050 ls = labels.get(r)
2050 ls = labels.get(r)
2051 if ls:
2051 if ls:
2052 for l in ls:
2052 for l in ls:
2053 yield 'l', (r, l)
2053 yield 'l', (r, l)
2054 else:
2054 else:
2055 raise util.Abort(_('need repo for changelog dag'))
2055 raise util.Abort(_('need repo for changelog dag'))
2056
2056
2057 for line in dagparser.dagtextlines(events(),
2057 for line in dagparser.dagtextlines(events(),
2058 addspaces=spaces,
2058 addspaces=spaces,
2059 wraplabels=True,
2059 wraplabels=True,
2060 wrapannotations=True,
2060 wrapannotations=True,
2061 wrapnonlinear=dots,
2061 wrapnonlinear=dots,
2062 usedots=dots,
2062 usedots=dots,
2063 maxlinewidth=70):
2063 maxlinewidth=70):
2064 ui.write(line)
2064 ui.write(line)
2065 ui.write("\n")
2065 ui.write("\n")
2066
2066
2067 @command('debugdata',
2067 @command('debugdata',
2068 [('c', 'changelog', False, _('open changelog')),
2068 [('c', 'changelog', False, _('open changelog')),
2069 ('m', 'manifest', False, _('open manifest')),
2069 ('m', 'manifest', False, _('open manifest')),
2070 ('', 'dir', False, _('open directory manifest'))],
2070 ('', 'dir', False, _('open directory manifest'))],
2071 _('-c|-m|FILE REV'))
2071 _('-c|-m|FILE REV'))
2072 def debugdata(ui, repo, file_, rev=None, **opts):
2072 def debugdata(ui, repo, file_, rev=None, **opts):
2073 """dump the contents of a data file revision"""
2073 """dump the contents of a data file revision"""
2074 if opts.get('changelog') or opts.get('manifest'):
2074 if opts.get('changelog') or opts.get('manifest'):
2075 file_, rev = None, file_
2075 file_, rev = None, file_
2076 elif rev is None:
2076 elif rev is None:
2077 raise error.CommandError('debugdata', _('invalid arguments'))
2077 raise error.CommandError('debugdata', _('invalid arguments'))
2078 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
2078 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
2079 try:
2079 try:
2080 ui.write(r.revision(r.lookup(rev)))
2080 ui.write(r.revision(r.lookup(rev)))
2081 except KeyError:
2081 except KeyError:
2082 raise util.Abort(_('invalid revision identifier %s') % rev)
2082 raise util.Abort(_('invalid revision identifier %s') % rev)
2083
2083
2084 @command('debugdate',
2084 @command('debugdate',
2085 [('e', 'extended', None, _('try extended date formats'))],
2085 [('e', 'extended', None, _('try extended date formats'))],
2086 _('[-e] DATE [RANGE]'),
2086 _('[-e] DATE [RANGE]'),
2087 norepo=True, optionalrepo=True)
2087 norepo=True, optionalrepo=True)
2088 def debugdate(ui, date, range=None, **opts):
2088 def debugdate(ui, date, range=None, **opts):
2089 """parse and display a date"""
2089 """parse and display a date"""
2090 if opts["extended"]:
2090 if opts["extended"]:
2091 d = util.parsedate(date, util.extendeddateformats)
2091 d = util.parsedate(date, util.extendeddateformats)
2092 else:
2092 else:
2093 d = util.parsedate(date)
2093 d = util.parsedate(date)
2094 ui.write(("internal: %s %s\n") % d)
2094 ui.write(("internal: %s %s\n") % d)
2095 ui.write(("standard: %s\n") % util.datestr(d))
2095 ui.write(("standard: %s\n") % util.datestr(d))
2096 if range:
2096 if range:
2097 m = util.matchdate(range)
2097 m = util.matchdate(range)
2098 ui.write(("match: %s\n") % m(d[0]))
2098 ui.write(("match: %s\n") % m(d[0]))
2099
2099
2100 @command('debugdiscovery',
2100 @command('debugdiscovery',
2101 [('', 'old', None, _('use old-style discovery')),
2101 [('', 'old', None, _('use old-style discovery')),
2102 ('', 'nonheads', None,
2102 ('', 'nonheads', None,
2103 _('use old-style discovery with non-heads included')),
2103 _('use old-style discovery with non-heads included')),
2104 ] + remoteopts,
2104 ] + remoteopts,
2105 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
2105 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
2106 def debugdiscovery(ui, repo, remoteurl="default", **opts):
2106 def debugdiscovery(ui, repo, remoteurl="default", **opts):
2107 """runs the changeset discovery protocol in isolation"""
2107 """runs the changeset discovery protocol in isolation"""
2108 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
2108 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
2109 opts.get('branch'))
2109 opts.get('branch'))
2110 remote = hg.peer(repo, opts, remoteurl)
2110 remote = hg.peer(repo, opts, remoteurl)
2111 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
2111 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
2112
2112
2113 # make sure tests are repeatable
2113 # make sure tests are repeatable
2114 random.seed(12323)
2114 random.seed(12323)
2115
2115
2116 def doit(localheads, remoteheads, remote=remote):
2116 def doit(localheads, remoteheads, remote=remote):
2117 if opts.get('old'):
2117 if opts.get('old'):
2118 if localheads:
2118 if localheads:
2119 raise util.Abort('cannot use localheads with old style '
2119 raise util.Abort('cannot use localheads with old style '
2120 'discovery')
2120 'discovery')
2121 if not util.safehasattr(remote, 'branches'):
2121 if not util.safehasattr(remote, 'branches'):
2122 # enable in-client legacy support
2122 # enable in-client legacy support
2123 remote = localrepo.locallegacypeer(remote.local())
2123 remote = localrepo.locallegacypeer(remote.local())
2124 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
2124 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
2125 force=True)
2125 force=True)
2126 common = set(common)
2126 common = set(common)
2127 if not opts.get('nonheads'):
2127 if not opts.get('nonheads'):
2128 ui.write(("unpruned common: %s\n") %
2128 ui.write(("unpruned common: %s\n") %
2129 " ".join(sorted(short(n) for n in common)))
2129 " ".join(sorted(short(n) for n in common)))
2130 dag = dagutil.revlogdag(repo.changelog)
2130 dag = dagutil.revlogdag(repo.changelog)
2131 all = dag.ancestorset(dag.internalizeall(common))
2131 all = dag.ancestorset(dag.internalizeall(common))
2132 common = dag.externalizeall(dag.headsetofconnecteds(all))
2132 common = dag.externalizeall(dag.headsetofconnecteds(all))
2133 else:
2133 else:
2134 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
2134 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
2135 common = set(common)
2135 common = set(common)
2136 rheads = set(hds)
2136 rheads = set(hds)
2137 lheads = set(repo.heads())
2137 lheads = set(repo.heads())
2138 ui.write(("common heads: %s\n") %
2138 ui.write(("common heads: %s\n") %
2139 " ".join(sorted(short(n) for n in common)))
2139 " ".join(sorted(short(n) for n in common)))
2140 if lheads <= common:
2140 if lheads <= common:
2141 ui.write(("local is subset\n"))
2141 ui.write(("local is subset\n"))
2142 elif rheads <= common:
2142 elif rheads <= common:
2143 ui.write(("remote is subset\n"))
2143 ui.write(("remote is subset\n"))
2144
2144
2145 serverlogs = opts.get('serverlog')
2145 serverlogs = opts.get('serverlog')
2146 if serverlogs:
2146 if serverlogs:
2147 for filename in serverlogs:
2147 for filename in serverlogs:
2148 logfile = open(filename, 'r')
2148 logfile = open(filename, 'r')
2149 try:
2149 try:
2150 line = logfile.readline()
2150 line = logfile.readline()
2151 while line:
2151 while line:
2152 parts = line.strip().split(';')
2152 parts = line.strip().split(';')
2153 op = parts[1]
2153 op = parts[1]
2154 if op == 'cg':
2154 if op == 'cg':
2155 pass
2155 pass
2156 elif op == 'cgss':
2156 elif op == 'cgss':
2157 doit(parts[2].split(' '), parts[3].split(' '))
2157 doit(parts[2].split(' '), parts[3].split(' '))
2158 elif op == 'unb':
2158 elif op == 'unb':
2159 doit(parts[3].split(' '), parts[2].split(' '))
2159 doit(parts[3].split(' '), parts[2].split(' '))
2160 line = logfile.readline()
2160 line = logfile.readline()
2161 finally:
2161 finally:
2162 logfile.close()
2162 logfile.close()
2163
2163
2164 else:
2164 else:
2165 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2165 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2166 opts.get('remote_head'))
2166 opts.get('remote_head'))
2167 localrevs = opts.get('local_head')
2167 localrevs = opts.get('local_head')
2168 doit(localrevs, remoterevs)
2168 doit(localrevs, remoterevs)
2169
2169
2170 @command('debugfileset',
2170 @command('debugfileset',
2171 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2171 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2172 _('[-r REV] FILESPEC'))
2172 _('[-r REV] FILESPEC'))
2173 def debugfileset(ui, repo, expr, **opts):
2173 def debugfileset(ui, repo, expr, **opts):
2174 '''parse and apply a fileset specification'''
2174 '''parse and apply a fileset specification'''
2175 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2175 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2176 if ui.verbose:
2176 if ui.verbose:
2177 tree = fileset.parse(expr)
2177 tree = fileset.parse(expr)
2178 ui.note(fileset.prettyformat(tree), "\n")
2178 ui.note(fileset.prettyformat(tree), "\n")
2179
2179
2180 for f in ctx.getfileset(expr):
2180 for f in ctx.getfileset(expr):
2181 ui.write("%s\n" % f)
2181 ui.write("%s\n" % f)
2182
2182
2183 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
2183 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
2184 def debugfsinfo(ui, path="."):
2184 def debugfsinfo(ui, path="."):
2185 """show information detected about current filesystem"""
2185 """show information detected about current filesystem"""
2186 util.writefile('.debugfsinfo', '')
2186 util.writefile('.debugfsinfo', '')
2187 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2187 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2188 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2188 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2189 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2189 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2190 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2190 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2191 and 'yes' or 'no'))
2191 and 'yes' or 'no'))
2192 os.unlink('.debugfsinfo')
2192 os.unlink('.debugfsinfo')
2193
2193
2194 @command('debuggetbundle',
2194 @command('debuggetbundle',
2195 [('H', 'head', [], _('id of head node'), _('ID')),
2195 [('H', 'head', [], _('id of head node'), _('ID')),
2196 ('C', 'common', [], _('id of common node'), _('ID')),
2196 ('C', 'common', [], _('id of common node'), _('ID')),
2197 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2197 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2198 _('REPO FILE [-H|-C ID]...'),
2198 _('REPO FILE [-H|-C ID]...'),
2199 norepo=True)
2199 norepo=True)
2200 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2200 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2201 """retrieves a bundle from a repo
2201 """retrieves a bundle from a repo
2202
2202
2203 Every ID must be a full-length hex node id string. Saves the bundle to the
2203 Every ID must be a full-length hex node id string. Saves the bundle to the
2204 given file.
2204 given file.
2205 """
2205 """
2206 repo = hg.peer(ui, opts, repopath)
2206 repo = hg.peer(ui, opts, repopath)
2207 if not repo.capable('getbundle'):
2207 if not repo.capable('getbundle'):
2208 raise util.Abort("getbundle() not supported by target repository")
2208 raise util.Abort("getbundle() not supported by target repository")
2209 args = {}
2209 args = {}
2210 if common:
2210 if common:
2211 args['common'] = [bin(s) for s in common]
2211 args['common'] = [bin(s) for s in common]
2212 if head:
2212 if head:
2213 args['heads'] = [bin(s) for s in head]
2213 args['heads'] = [bin(s) for s in head]
2214 # TODO: get desired bundlecaps from command line.
2214 # TODO: get desired bundlecaps from command line.
2215 args['bundlecaps'] = None
2215 args['bundlecaps'] = None
2216 bundle = repo.getbundle('debug', **args)
2216 bundle = repo.getbundle('debug', **args)
2217
2217
2218 bundletype = opts.get('type', 'bzip2').lower()
2218 bundletype = opts.get('type', 'bzip2').lower()
2219 btypes = {'none': 'HG10UN',
2219 btypes = {'none': 'HG10UN',
2220 'bzip2': 'HG10BZ',
2220 'bzip2': 'HG10BZ',
2221 'gzip': 'HG10GZ',
2221 'gzip': 'HG10GZ',
2222 'bundle2': 'HG20'}
2222 'bundle2': 'HG20'}
2223 bundletype = btypes.get(bundletype)
2223 bundletype = btypes.get(bundletype)
2224 if bundletype not in changegroup.bundletypes:
2224 if bundletype not in changegroup.bundletypes:
2225 raise util.Abort(_('unknown bundle type specified with --type'))
2225 raise util.Abort(_('unknown bundle type specified with --type'))
2226 changegroup.writebundle(ui, bundle, bundlepath, bundletype)
2226 changegroup.writebundle(ui, bundle, bundlepath, bundletype)
2227
2227
2228 @command('debugignore', [], '')
2228 @command('debugignore', [], '')
2229 def debugignore(ui, repo, *values, **opts):
2229 def debugignore(ui, repo, *values, **opts):
2230 """display the combined ignore pattern"""
2230 """display the combined ignore pattern"""
2231 ignore = repo.dirstate._ignore
2231 ignore = repo.dirstate._ignore
2232 includepat = getattr(ignore, 'includepat', None)
2232 includepat = getattr(ignore, 'includepat', None)
2233 if includepat is not None:
2233 if includepat is not None:
2234 ui.write("%s\n" % includepat)
2234 ui.write("%s\n" % includepat)
2235 else:
2235 else:
2236 raise util.Abort(_("no ignore patterns found"))
2236 raise util.Abort(_("no ignore patterns found"))
2237
2237
2238 @command('debugindex',
2238 @command('debugindex',
2239 [('c', 'changelog', False, _('open changelog')),
2239 [('c', 'changelog', False, _('open changelog')),
2240 ('m', 'manifest', False, _('open manifest')),
2240 ('m', 'manifest', False, _('open manifest')),
2241 ('', 'dir', False, _('open directory manifest')),
2241 ('', 'dir', False, _('open directory manifest')),
2242 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2242 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2243 _('[-f FORMAT] -c|-m|FILE'),
2243 _('[-f FORMAT] -c|-m|FILE'),
2244 optionalrepo=True)
2244 optionalrepo=True)
2245 def debugindex(ui, repo, file_=None, **opts):
2245 def debugindex(ui, repo, file_=None, **opts):
2246 """dump the contents of an index file"""
2246 """dump the contents of an index file"""
2247 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2247 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2248 format = opts.get('format', 0)
2248 format = opts.get('format', 0)
2249 if format not in (0, 1):
2249 if format not in (0, 1):
2250 raise util.Abort(_("unknown format %d") % format)
2250 raise util.Abort(_("unknown format %d") % format)
2251
2251
2252 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2252 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2253 if generaldelta:
2253 if generaldelta:
2254 basehdr = ' delta'
2254 basehdr = ' delta'
2255 else:
2255 else:
2256 basehdr = ' base'
2256 basehdr = ' base'
2257
2257
2258 if ui.debugflag:
2258 if ui.debugflag:
2259 shortfn = hex
2259 shortfn = hex
2260 else:
2260 else:
2261 shortfn = short
2261 shortfn = short
2262
2262
2263 # There might not be anything in r, so have a sane default
2263 # There might not be anything in r, so have a sane default
2264 idlen = 12
2264 idlen = 12
2265 for i in r:
2265 for i in r:
2266 idlen = len(shortfn(r.node(i)))
2266 idlen = len(shortfn(r.node(i)))
2267 break
2267 break
2268
2268
2269 if format == 0:
2269 if format == 0:
2270 ui.write(" rev offset length " + basehdr + " linkrev"
2270 ui.write(" rev offset length " + basehdr + " linkrev"
2271 " %s %s p2\n" % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
2271 " %s %s p2\n" % ("nodeid".ljust(idlen), "p1".ljust(idlen)))
2272 elif format == 1:
2272 elif format == 1:
2273 ui.write(" rev flag offset length"
2273 ui.write(" rev flag offset length"
2274 " size " + basehdr + " link p1 p2"
2274 " size " + basehdr + " link p1 p2"
2275 " %s\n" % "nodeid".rjust(idlen))
2275 " %s\n" % "nodeid".rjust(idlen))
2276
2276
2277 for i in r:
2277 for i in r:
2278 node = r.node(i)
2278 node = r.node(i)
2279 if generaldelta:
2279 if generaldelta:
2280 base = r.deltaparent(i)
2280 base = r.deltaparent(i)
2281 else:
2281 else:
2282 base = r.chainbase(i)
2282 base = r.chainbase(i)
2283 if format == 0:
2283 if format == 0:
2284 try:
2284 try:
2285 pp = r.parents(node)
2285 pp = r.parents(node)
2286 except Exception:
2286 except Exception:
2287 pp = [nullid, nullid]
2287 pp = [nullid, nullid]
2288 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2288 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2289 i, r.start(i), r.length(i), base, r.linkrev(i),
2289 i, r.start(i), r.length(i), base, r.linkrev(i),
2290 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2290 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
2291 elif format == 1:
2291 elif format == 1:
2292 pr = r.parentrevs(i)
2292 pr = r.parentrevs(i)
2293 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2293 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2294 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2294 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2295 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
2295 base, r.linkrev(i), pr[0], pr[1], shortfn(node)))
2296
2296
2297 @command('debugindexdot', [], _('FILE'), optionalrepo=True)
2297 @command('debugindexdot', [], _('FILE'), optionalrepo=True)
2298 def debugindexdot(ui, repo, file_):
2298 def debugindexdot(ui, repo, file_):
2299 """dump an index DAG as a graphviz dot file"""
2299 """dump an index DAG as a graphviz dot file"""
2300 r = None
2300 r = None
2301 if repo:
2301 if repo:
2302 filelog = repo.file(file_)
2302 filelog = repo.file(file_)
2303 if len(filelog):
2303 if len(filelog):
2304 r = filelog
2304 r = filelog
2305 if not r:
2305 if not r:
2306 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2306 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2307 ui.write(("digraph G {\n"))
2307 ui.write(("digraph G {\n"))
2308 for i in r:
2308 for i in r:
2309 node = r.node(i)
2309 node = r.node(i)
2310 pp = r.parents(node)
2310 pp = r.parents(node)
2311 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2311 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2312 if pp[1] != nullid:
2312 if pp[1] != nullid:
2313 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2313 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2314 ui.write("}\n")
2314 ui.write("}\n")
2315
2315
2316 @command('debuginstall', [], '', norepo=True)
2316 @command('debuginstall', [], '', norepo=True)
2317 def debuginstall(ui):
2317 def debuginstall(ui):
2318 '''test Mercurial installation
2318 '''test Mercurial installation
2319
2319
2320 Returns 0 on success.
2320 Returns 0 on success.
2321 '''
2321 '''
2322
2322
2323 def writetemp(contents):
2323 def writetemp(contents):
2324 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2324 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2325 f = os.fdopen(fd, "wb")
2325 f = os.fdopen(fd, "wb")
2326 f.write(contents)
2326 f.write(contents)
2327 f.close()
2327 f.close()
2328 return name
2328 return name
2329
2329
2330 problems = 0
2330 problems = 0
2331
2331
2332 # encoding
2332 # encoding
2333 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2333 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2334 try:
2334 try:
2335 encoding.fromlocal("test")
2335 encoding.fromlocal("test")
2336 except util.Abort as inst:
2336 except util.Abort as inst:
2337 ui.write(" %s\n" % inst)
2337 ui.write(" %s\n" % inst)
2338 ui.write(_(" (check that your locale is properly set)\n"))
2338 ui.write(_(" (check that your locale is properly set)\n"))
2339 problems += 1
2339 problems += 1
2340
2340
2341 # Python
2341 # Python
2342 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2342 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2343 ui.status(_("checking Python version (%s)\n")
2343 ui.status(_("checking Python version (%s)\n")
2344 % ("%s.%s.%s" % sys.version_info[:3]))
2344 % ("%s.%s.%s" % sys.version_info[:3]))
2345 ui.status(_("checking Python lib (%s)...\n")
2345 ui.status(_("checking Python lib (%s)...\n")
2346 % os.path.dirname(os.__file__))
2346 % os.path.dirname(os.__file__))
2347
2347
2348 # compiled modules
2348 # compiled modules
2349 ui.status(_("checking installed modules (%s)...\n")
2349 ui.status(_("checking installed modules (%s)...\n")
2350 % os.path.dirname(__file__))
2350 % os.path.dirname(__file__))
2351 try:
2351 try:
2352 import bdiff, mpatch, base85, osutil
2352 import bdiff, mpatch, base85, osutil
2353 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2353 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2354 except Exception as inst:
2354 except Exception as inst:
2355 ui.write(" %s\n" % inst)
2355 ui.write(" %s\n" % inst)
2356 ui.write(_(" One or more extensions could not be found"))
2356 ui.write(_(" One or more extensions could not be found"))
2357 ui.write(_(" (check that you compiled the extensions)\n"))
2357 ui.write(_(" (check that you compiled the extensions)\n"))
2358 problems += 1
2358 problems += 1
2359
2359
2360 # templates
2360 # templates
2361 import templater
2361 import templater
2362 p = templater.templatepaths()
2362 p = templater.templatepaths()
2363 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2363 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2364 if p:
2364 if p:
2365 m = templater.templatepath("map-cmdline.default")
2365 m = templater.templatepath("map-cmdline.default")
2366 if m:
2366 if m:
2367 # template found, check if it is working
2367 # template found, check if it is working
2368 try:
2368 try:
2369 templater.templater(m)
2369 templater.templater(m)
2370 except Exception as inst:
2370 except Exception as inst:
2371 ui.write(" %s\n" % inst)
2371 ui.write(" %s\n" % inst)
2372 p = None
2372 p = None
2373 else:
2373 else:
2374 ui.write(_(" template 'default' not found\n"))
2374 ui.write(_(" template 'default' not found\n"))
2375 p = None
2375 p = None
2376 else:
2376 else:
2377 ui.write(_(" no template directories found\n"))
2377 ui.write(_(" no template directories found\n"))
2378 if not p:
2378 if not p:
2379 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2379 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2380 problems += 1
2380 problems += 1
2381
2381
2382 # editor
2382 # editor
2383 ui.status(_("checking commit editor...\n"))
2383 ui.status(_("checking commit editor...\n"))
2384 editor = ui.geteditor()
2384 editor = ui.geteditor()
2385 editor = util.expandpath(editor)
2385 editor = util.expandpath(editor)
2386 cmdpath = util.findexe(shlex.split(editor)[0])
2386 cmdpath = util.findexe(shlex.split(editor)[0])
2387 if not cmdpath:
2387 if not cmdpath:
2388 if editor == 'vi':
2388 if editor == 'vi':
2389 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2389 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2390 ui.write(_(" (specify a commit editor in your configuration"
2390 ui.write(_(" (specify a commit editor in your configuration"
2391 " file)\n"))
2391 " file)\n"))
2392 else:
2392 else:
2393 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2393 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2394 ui.write(_(" (specify a commit editor in your configuration"
2394 ui.write(_(" (specify a commit editor in your configuration"
2395 " file)\n"))
2395 " file)\n"))
2396 problems += 1
2396 problems += 1
2397
2397
2398 # check username
2398 # check username
2399 ui.status(_("checking username...\n"))
2399 ui.status(_("checking username...\n"))
2400 try:
2400 try:
2401 ui.username()
2401 ui.username()
2402 except util.Abort as e:
2402 except util.Abort as e:
2403 ui.write(" %s\n" % e)
2403 ui.write(" %s\n" % e)
2404 ui.write(_(" (specify a username in your configuration file)\n"))
2404 ui.write(_(" (specify a username in your configuration file)\n"))
2405 problems += 1
2405 problems += 1
2406
2406
2407 if not problems:
2407 if not problems:
2408 ui.status(_("no problems detected\n"))
2408 ui.status(_("no problems detected\n"))
2409 else:
2409 else:
2410 ui.write(_("%s problems detected,"
2410 ui.write(_("%s problems detected,"
2411 " please check your install!\n") % problems)
2411 " please check your install!\n") % problems)
2412
2412
2413 return problems
2413 return problems
2414
2414
2415 @command('debugknown', [], _('REPO ID...'), norepo=True)
2415 @command('debugknown', [], _('REPO ID...'), norepo=True)
2416 def debugknown(ui, repopath, *ids, **opts):
2416 def debugknown(ui, repopath, *ids, **opts):
2417 """test whether node ids are known to a repo
2417 """test whether node ids are known to a repo
2418
2418
2419 Every ID must be a full-length hex node id string. Returns a list of 0s
2419 Every ID must be a full-length hex node id string. Returns a list of 0s
2420 and 1s indicating unknown/known.
2420 and 1s indicating unknown/known.
2421 """
2421 """
2422 repo = hg.peer(ui, opts, repopath)
2422 repo = hg.peer(ui, opts, repopath)
2423 if not repo.capable('known'):
2423 if not repo.capable('known'):
2424 raise util.Abort("known() not supported by target repository")
2424 raise util.Abort("known() not supported by target repository")
2425 flags = repo.known([bin(s) for s in ids])
2425 flags = repo.known([bin(s) for s in ids])
2426 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2426 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2427
2427
2428 @command('debuglabelcomplete', [], _('LABEL...'))
2428 @command('debuglabelcomplete', [], _('LABEL...'))
2429 def debuglabelcomplete(ui, repo, *args):
2429 def debuglabelcomplete(ui, repo, *args):
2430 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2430 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
2431 debugnamecomplete(ui, repo, *args)
2431 debugnamecomplete(ui, repo, *args)
2432
2432
2433 @command('debugnamecomplete', [], _('NAME...'))
2433 @command('debugnamecomplete', [], _('NAME...'))
2434 def debugnamecomplete(ui, repo, *args):
2434 def debugnamecomplete(ui, repo, *args):
2435 '''complete "names" - tags, open branch names, bookmark names'''
2435 '''complete "names" - tags, open branch names, bookmark names'''
2436
2436
2437 names = set()
2437 names = set()
2438 # since we previously only listed open branches, we will handle that
2438 # since we previously only listed open branches, we will handle that
2439 # specially (after this for loop)
2439 # specially (after this for loop)
2440 for name, ns in repo.names.iteritems():
2440 for name, ns in repo.names.iteritems():
2441 if name != 'branches':
2441 if name != 'branches':
2442 names.update(ns.listnames(repo))
2442 names.update(ns.listnames(repo))
2443 names.update(tag for (tag, heads, tip, closed)
2443 names.update(tag for (tag, heads, tip, closed)
2444 in repo.branchmap().iterbranches() if not closed)
2444 in repo.branchmap().iterbranches() if not closed)
2445 completions = set()
2445 completions = set()
2446 if not args:
2446 if not args:
2447 args = ['']
2447 args = ['']
2448 for a in args:
2448 for a in args:
2449 completions.update(n for n in names if n.startswith(a))
2449 completions.update(n for n in names if n.startswith(a))
2450 ui.write('\n'.join(sorted(completions)))
2450 ui.write('\n'.join(sorted(completions)))
2451 ui.write('\n')
2451 ui.write('\n')
2452
2452
2453 @command('debuglocks',
2453 @command('debuglocks',
2454 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2454 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
2455 ('W', 'force-wlock', None,
2455 ('W', 'force-wlock', None,
2456 _('free the working state lock (DANGEROUS)'))],
2456 _('free the working state lock (DANGEROUS)'))],
2457 _('[OPTION]...'))
2457 _('[OPTION]...'))
2458 def debuglocks(ui, repo, **opts):
2458 def debuglocks(ui, repo, **opts):
2459 """show or modify state of locks
2459 """show or modify state of locks
2460
2460
2461 By default, this command will show which locks are held. This
2461 By default, this command will show which locks are held. This
2462 includes the user and process holding the lock, the amount of time
2462 includes the user and process holding the lock, the amount of time
2463 the lock has been held, and the machine name where the process is
2463 the lock has been held, and the machine name where the process is
2464 running if it's not local.
2464 running if it's not local.
2465
2465
2466 Locks protect the integrity of Mercurial's data, so should be
2466 Locks protect the integrity of Mercurial's data, so should be
2467 treated with care. System crashes or other interruptions may cause
2467 treated with care. System crashes or other interruptions may cause
2468 locks to not be properly released, though Mercurial will usually
2468 locks to not be properly released, though Mercurial will usually
2469 detect and remove such stale locks automatically.
2469 detect and remove such stale locks automatically.
2470
2470
2471 However, detecting stale locks may not always be possible (for
2471 However, detecting stale locks may not always be possible (for
2472 instance, on a shared filesystem). Removing locks may also be
2472 instance, on a shared filesystem). Removing locks may also be
2473 blocked by filesystem permissions.
2473 blocked by filesystem permissions.
2474
2474
2475 Returns 0 if no locks are held.
2475 Returns 0 if no locks are held.
2476
2476
2477 """
2477 """
2478
2478
2479 if opts.get('force_lock'):
2479 if opts.get('force_lock'):
2480 repo.svfs.unlink('lock')
2480 repo.svfs.unlink('lock')
2481 if opts.get('force_wlock'):
2481 if opts.get('force_wlock'):
2482 repo.vfs.unlink('wlock')
2482 repo.vfs.unlink('wlock')
2483 if opts.get('force_lock') or opts.get('force_lock'):
2483 if opts.get('force_lock') or opts.get('force_lock'):
2484 return 0
2484 return 0
2485
2485
2486 now = time.time()
2486 now = time.time()
2487 held = 0
2487 held = 0
2488
2488
2489 def report(vfs, name, method):
2489 def report(vfs, name, method):
2490 # this causes stale locks to get reaped for more accurate reporting
2490 # this causes stale locks to get reaped for more accurate reporting
2491 try:
2491 try:
2492 l = method(False)
2492 l = method(False)
2493 except error.LockHeld:
2493 except error.LockHeld:
2494 l = None
2494 l = None
2495
2495
2496 if l:
2496 if l:
2497 l.release()
2497 l.release()
2498 else:
2498 else:
2499 try:
2499 try:
2500 stat = vfs.lstat(name)
2500 stat = vfs.lstat(name)
2501 age = now - stat.st_mtime
2501 age = now - stat.st_mtime
2502 user = util.username(stat.st_uid)
2502 user = util.username(stat.st_uid)
2503 locker = vfs.readlock(name)
2503 locker = vfs.readlock(name)
2504 if ":" in locker:
2504 if ":" in locker:
2505 host, pid = locker.split(':')
2505 host, pid = locker.split(':')
2506 if host == socket.gethostname():
2506 if host == socket.gethostname():
2507 locker = 'user %s, process %s' % (user, pid)
2507 locker = 'user %s, process %s' % (user, pid)
2508 else:
2508 else:
2509 locker = 'user %s, process %s, host %s' \
2509 locker = 'user %s, process %s, host %s' \
2510 % (user, pid, host)
2510 % (user, pid, host)
2511 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
2511 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age))
2512 return 1
2512 return 1
2513 except OSError as e:
2513 except OSError as e:
2514 if e.errno != errno.ENOENT:
2514 if e.errno != errno.ENOENT:
2515 raise
2515 raise
2516
2516
2517 ui.write("%-6s free\n" % (name + ":"))
2517 ui.write("%-6s free\n" % (name + ":"))
2518 return 0
2518 return 0
2519
2519
2520 held += report(repo.svfs, "lock", repo.lock)
2520 held += report(repo.svfs, "lock", repo.lock)
2521 held += report(repo.vfs, "wlock", repo.wlock)
2521 held += report(repo.vfs, "wlock", repo.wlock)
2522
2522
2523 return held
2523 return held
2524
2524
2525 @command('debugobsolete',
2525 @command('debugobsolete',
2526 [('', 'flags', 0, _('markers flag')),
2526 [('', 'flags', 0, _('markers flag')),
2527 ('', 'record-parents', False,
2527 ('', 'record-parents', False,
2528 _('record parent information for the precursor')),
2528 _('record parent information for the precursor')),
2529 ('r', 'rev', [], _('display markers relevant to REV')),
2529 ('r', 'rev', [], _('display markers relevant to REV')),
2530 ] + commitopts2,
2530 ] + commitopts2,
2531 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2531 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2532 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2532 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2533 """create arbitrary obsolete marker
2533 """create arbitrary obsolete marker
2534
2534
2535 With no arguments, displays the list of obsolescence markers."""
2535 With no arguments, displays the list of obsolescence markers."""
2536
2536
2537 def parsenodeid(s):
2537 def parsenodeid(s):
2538 try:
2538 try:
2539 # We do not use revsingle/revrange functions here to accept
2539 # We do not use revsingle/revrange functions here to accept
2540 # arbitrary node identifiers, possibly not present in the
2540 # arbitrary node identifiers, possibly not present in the
2541 # local repository.
2541 # local repository.
2542 n = bin(s)
2542 n = bin(s)
2543 if len(n) != len(nullid):
2543 if len(n) != len(nullid):
2544 raise TypeError()
2544 raise TypeError()
2545 return n
2545 return n
2546 except TypeError:
2546 except TypeError:
2547 raise util.Abort('changeset references must be full hexadecimal '
2547 raise util.Abort('changeset references must be full hexadecimal '
2548 'node identifiers')
2548 'node identifiers')
2549
2549
2550 if precursor is not None:
2550 if precursor is not None:
2551 if opts['rev']:
2551 if opts['rev']:
2552 raise util.Abort('cannot select revision when creating marker')
2552 raise util.Abort('cannot select revision when creating marker')
2553 metadata = {}
2553 metadata = {}
2554 metadata['user'] = opts['user'] or ui.username()
2554 metadata['user'] = opts['user'] or ui.username()
2555 succs = tuple(parsenodeid(succ) for succ in successors)
2555 succs = tuple(parsenodeid(succ) for succ in successors)
2556 l = repo.lock()
2556 l = repo.lock()
2557 try:
2557 try:
2558 tr = repo.transaction('debugobsolete')
2558 tr = repo.transaction('debugobsolete')
2559 try:
2559 try:
2560 date = opts.get('date')
2560 date = opts.get('date')
2561 if date:
2561 if date:
2562 date = util.parsedate(date)
2562 date = util.parsedate(date)
2563 else:
2563 else:
2564 date = None
2564 date = None
2565 prec = parsenodeid(precursor)
2565 prec = parsenodeid(precursor)
2566 parents = None
2566 parents = None
2567 if opts['record_parents']:
2567 if opts['record_parents']:
2568 if prec not in repo.unfiltered():
2568 if prec not in repo.unfiltered():
2569 raise util.Abort('cannot used --record-parents on '
2569 raise util.Abort('cannot used --record-parents on '
2570 'unknown changesets')
2570 'unknown changesets')
2571 parents = repo.unfiltered()[prec].parents()
2571 parents = repo.unfiltered()[prec].parents()
2572 parents = tuple(p.node() for p in parents)
2572 parents = tuple(p.node() for p in parents)
2573 repo.obsstore.create(tr, prec, succs, opts['flags'],
2573 repo.obsstore.create(tr, prec, succs, opts['flags'],
2574 parents=parents, date=date,
2574 parents=parents, date=date,
2575 metadata=metadata)
2575 metadata=metadata)
2576 tr.close()
2576 tr.close()
2577 except ValueError as exc:
2577 except ValueError as exc:
2578 raise util.Abort(_('bad obsmarker input: %s') % exc)
2578 raise util.Abort(_('bad obsmarker input: %s') % exc)
2579 finally:
2579 finally:
2580 tr.release()
2580 tr.release()
2581 finally:
2581 finally:
2582 l.release()
2582 l.release()
2583 else:
2583 else:
2584 if opts['rev']:
2584 if opts['rev']:
2585 revs = scmutil.revrange(repo, opts['rev'])
2585 revs = scmutil.revrange(repo, opts['rev'])
2586 nodes = [repo[r].node() for r in revs]
2586 nodes = [repo[r].node() for r in revs]
2587 markers = list(obsolete.getmarkers(repo, nodes=nodes))
2587 markers = list(obsolete.getmarkers(repo, nodes=nodes))
2588 markers.sort(key=lambda x: x._data)
2588 markers.sort(key=lambda x: x._data)
2589 else:
2589 else:
2590 markers = obsolete.getmarkers(repo)
2590 markers = obsolete.getmarkers(repo)
2591
2591
2592 for m in markers:
2592 for m in markers:
2593 cmdutil.showmarker(ui, m)
2593 cmdutil.showmarker(ui, m)
2594
2594
2595 @command('debugpathcomplete',
2595 @command('debugpathcomplete',
2596 [('f', 'full', None, _('complete an entire path')),
2596 [('f', 'full', None, _('complete an entire path')),
2597 ('n', 'normal', None, _('show only normal files')),
2597 ('n', 'normal', None, _('show only normal files')),
2598 ('a', 'added', None, _('show only added files')),
2598 ('a', 'added', None, _('show only added files')),
2599 ('r', 'removed', None, _('show only removed files'))],
2599 ('r', 'removed', None, _('show only removed files'))],
2600 _('FILESPEC...'))
2600 _('FILESPEC...'))
2601 def debugpathcomplete(ui, repo, *specs, **opts):
2601 def debugpathcomplete(ui, repo, *specs, **opts):
2602 '''complete part or all of a tracked path
2602 '''complete part or all of a tracked path
2603
2603
2604 This command supports shells that offer path name completion. It
2604 This command supports shells that offer path name completion. It
2605 currently completes only files already known to the dirstate.
2605 currently completes only files already known to the dirstate.
2606
2606
2607 Completion extends only to the next path segment unless
2607 Completion extends only to the next path segment unless
2608 --full is specified, in which case entire paths are used.'''
2608 --full is specified, in which case entire paths are used.'''
2609
2609
2610 def complete(path, acceptable):
2610 def complete(path, acceptable):
2611 dirstate = repo.dirstate
2611 dirstate = repo.dirstate
2612 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2612 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2613 rootdir = repo.root + os.sep
2613 rootdir = repo.root + os.sep
2614 if spec != repo.root and not spec.startswith(rootdir):
2614 if spec != repo.root and not spec.startswith(rootdir):
2615 return [], []
2615 return [], []
2616 if os.path.isdir(spec):
2616 if os.path.isdir(spec):
2617 spec += '/'
2617 spec += '/'
2618 spec = spec[len(rootdir):]
2618 spec = spec[len(rootdir):]
2619 fixpaths = os.sep != '/'
2619 fixpaths = os.sep != '/'
2620 if fixpaths:
2620 if fixpaths:
2621 spec = spec.replace(os.sep, '/')
2621 spec = spec.replace(os.sep, '/')
2622 speclen = len(spec)
2622 speclen = len(spec)
2623 fullpaths = opts['full']
2623 fullpaths = opts['full']
2624 files, dirs = set(), set()
2624 files, dirs = set(), set()
2625 adddir, addfile = dirs.add, files.add
2625 adddir, addfile = dirs.add, files.add
2626 for f, st in dirstate.iteritems():
2626 for f, st in dirstate.iteritems():
2627 if f.startswith(spec) and st[0] in acceptable:
2627 if f.startswith(spec) and st[0] in acceptable:
2628 if fixpaths:
2628 if fixpaths:
2629 f = f.replace('/', os.sep)
2629 f = f.replace('/', os.sep)
2630 if fullpaths:
2630 if fullpaths:
2631 addfile(f)
2631 addfile(f)
2632 continue
2632 continue
2633 s = f.find(os.sep, speclen)
2633 s = f.find(os.sep, speclen)
2634 if s >= 0:
2634 if s >= 0:
2635 adddir(f[:s])
2635 adddir(f[:s])
2636 else:
2636 else:
2637 addfile(f)
2637 addfile(f)
2638 return files, dirs
2638 return files, dirs
2639
2639
2640 acceptable = ''
2640 acceptable = ''
2641 if opts['normal']:
2641 if opts['normal']:
2642 acceptable += 'nm'
2642 acceptable += 'nm'
2643 if opts['added']:
2643 if opts['added']:
2644 acceptable += 'a'
2644 acceptable += 'a'
2645 if opts['removed']:
2645 if opts['removed']:
2646 acceptable += 'r'
2646 acceptable += 'r'
2647 cwd = repo.getcwd()
2647 cwd = repo.getcwd()
2648 if not specs:
2648 if not specs:
2649 specs = ['.']
2649 specs = ['.']
2650
2650
2651 files, dirs = set(), set()
2651 files, dirs = set(), set()
2652 for spec in specs:
2652 for spec in specs:
2653 f, d = complete(spec, acceptable or 'nmar')
2653 f, d = complete(spec, acceptable or 'nmar')
2654 files.update(f)
2654 files.update(f)
2655 dirs.update(d)
2655 dirs.update(d)
2656 files.update(dirs)
2656 files.update(dirs)
2657 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2657 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2658 ui.write('\n')
2658 ui.write('\n')
2659
2659
2660 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2660 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
2661 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2661 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2662 '''access the pushkey key/value protocol
2662 '''access the pushkey key/value protocol
2663
2663
2664 With two args, list the keys in the given namespace.
2664 With two args, list the keys in the given namespace.
2665
2665
2666 With five args, set a key to new if it currently is set to old.
2666 With five args, set a key to new if it currently is set to old.
2667 Reports success or failure.
2667 Reports success or failure.
2668 '''
2668 '''
2669
2669
2670 target = hg.peer(ui, {}, repopath)
2670 target = hg.peer(ui, {}, repopath)
2671 if keyinfo:
2671 if keyinfo:
2672 key, old, new = keyinfo
2672 key, old, new = keyinfo
2673 r = target.pushkey(namespace, key, old, new)
2673 r = target.pushkey(namespace, key, old, new)
2674 ui.status(str(r) + '\n')
2674 ui.status(str(r) + '\n')
2675 return not r
2675 return not r
2676 else:
2676 else:
2677 for k, v in sorted(target.listkeys(namespace).iteritems()):
2677 for k, v in sorted(target.listkeys(namespace).iteritems()):
2678 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2678 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2679 v.encode('string-escape')))
2679 v.encode('string-escape')))
2680
2680
2681 @command('debugpvec', [], _('A B'))
2681 @command('debugpvec', [], _('A B'))
2682 def debugpvec(ui, repo, a, b=None):
2682 def debugpvec(ui, repo, a, b=None):
2683 ca = scmutil.revsingle(repo, a)
2683 ca = scmutil.revsingle(repo, a)
2684 cb = scmutil.revsingle(repo, b)
2684 cb = scmutil.revsingle(repo, b)
2685 pa = pvec.ctxpvec(ca)
2685 pa = pvec.ctxpvec(ca)
2686 pb = pvec.ctxpvec(cb)
2686 pb = pvec.ctxpvec(cb)
2687 if pa == pb:
2687 if pa == pb:
2688 rel = "="
2688 rel = "="
2689 elif pa > pb:
2689 elif pa > pb:
2690 rel = ">"
2690 rel = ">"
2691 elif pa < pb:
2691 elif pa < pb:
2692 rel = "<"
2692 rel = "<"
2693 elif pa | pb:
2693 elif pa | pb:
2694 rel = "|"
2694 rel = "|"
2695 ui.write(_("a: %s\n") % pa)
2695 ui.write(_("a: %s\n") % pa)
2696 ui.write(_("b: %s\n") % pb)
2696 ui.write(_("b: %s\n") % pb)
2697 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2697 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2698 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2698 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2699 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2699 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2700 pa.distance(pb), rel))
2700 pa.distance(pb), rel))
2701
2701
2702 @command('debugrebuilddirstate|debugrebuildstate',
2702 @command('debugrebuilddirstate|debugrebuildstate',
2703 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
2703 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
2704 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
2705 'the working copy parent')),
2706 ],
2704 _('[-r REV]'))
2707 _('[-r REV]'))
2705 def debugrebuilddirstate(ui, repo, rev):
2708 def debugrebuilddirstate(ui, repo, rev, **opts):
2706 """rebuild the dirstate as it would look like for the given revision
2709 """rebuild the dirstate as it would look like for the given revision
2707
2710
2708 If no revision is specified the first current parent will be used.
2711 If no revision is specified the first current parent will be used.
2709
2712
2710 The dirstate will be set to the files of the given revision.
2713 The dirstate will be set to the files of the given revision.
2711 The actual working directory content or existing dirstate
2714 The actual working directory content or existing dirstate
2712 information such as adds or removes is not considered.
2715 information such as adds or removes is not considered.
2713
2716
2717 ``minimal`` will only rebuild the dirstate status for files that claim to be
2718 tracked but are not in the parent manifest, or that exist in the parent
2719 manifest but are not in the dirstate. It will not change adds, removes, or
2720 modified files that are in the working copy parent.
2721
2714 One use of this command is to make the next :hg:`status` invocation
2722 One use of this command is to make the next :hg:`status` invocation
2715 check the actual file content.
2723 check the actual file content.
2716 """
2724 """
2717 ctx = scmutil.revsingle(repo, rev)
2725 ctx = scmutil.revsingle(repo, rev)
2718 wlock = repo.wlock()
2726 wlock = repo.wlock()
2719 try:
2727 try:
2720 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
2728 dirstate = repo.dirstate
2729
2730 # See command doc for what minimal does.
2731 if opts.get('minimal'):
2732 dirstatefiles = set(dirstate)
2733 ctxfiles = set(ctx.manifest().keys())
2734 for file in (dirstatefiles | ctxfiles):
2735 indirstate = file in dirstatefiles
2736 inctx = file in ctxfiles
2737
2738 if indirstate and not inctx and dirstate[file] != 'a':
2739 dirstate.drop(file)
2740 elif inctx and not indirstate:
2741 dirstate.normallookup(file)
2742 else:
2743 dirstate.rebuild(ctx.node(), ctx.manifest())
2721 finally:
2744 finally:
2722 wlock.release()
2745 wlock.release()
2723
2746
2724 @command('debugrebuildfncache', [], '')
2747 @command('debugrebuildfncache', [], '')
2725 def debugrebuildfncache(ui, repo):
2748 def debugrebuildfncache(ui, repo):
2726 """rebuild the fncache file"""
2749 """rebuild the fncache file"""
2727 repair.rebuildfncache(ui, repo)
2750 repair.rebuildfncache(ui, repo)
2728
2751
2729 @command('debugrename',
2752 @command('debugrename',
2730 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2753 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2731 _('[-r REV] FILE'))
2754 _('[-r REV] FILE'))
2732 def debugrename(ui, repo, file1, *pats, **opts):
2755 def debugrename(ui, repo, file1, *pats, **opts):
2733 """dump rename information"""
2756 """dump rename information"""
2734
2757
2735 ctx = scmutil.revsingle(repo, opts.get('rev'))
2758 ctx = scmutil.revsingle(repo, opts.get('rev'))
2736 m = scmutil.match(ctx, (file1,) + pats, opts)
2759 m = scmutil.match(ctx, (file1,) + pats, opts)
2737 for abs in ctx.walk(m):
2760 for abs in ctx.walk(m):
2738 fctx = ctx[abs]
2761 fctx = ctx[abs]
2739 o = fctx.filelog().renamed(fctx.filenode())
2762 o = fctx.filelog().renamed(fctx.filenode())
2740 rel = m.rel(abs)
2763 rel = m.rel(abs)
2741 if o:
2764 if o:
2742 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2765 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2743 else:
2766 else:
2744 ui.write(_("%s not renamed\n") % rel)
2767 ui.write(_("%s not renamed\n") % rel)
2745
2768
2746 @command('debugrevlog',
2769 @command('debugrevlog',
2747 [('c', 'changelog', False, _('open changelog')),
2770 [('c', 'changelog', False, _('open changelog')),
2748 ('m', 'manifest', False, _('open manifest')),
2771 ('m', 'manifest', False, _('open manifest')),
2749 ('', 'dir', False, _('open directory manifest')),
2772 ('', 'dir', False, _('open directory manifest')),
2750 ('d', 'dump', False, _('dump index data'))],
2773 ('d', 'dump', False, _('dump index data'))],
2751 _('-c|-m|FILE'),
2774 _('-c|-m|FILE'),
2752 optionalrepo=True)
2775 optionalrepo=True)
2753 def debugrevlog(ui, repo, file_=None, **opts):
2776 def debugrevlog(ui, repo, file_=None, **opts):
2754 """show data and statistics about a revlog"""
2777 """show data and statistics about a revlog"""
2755 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2778 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2756
2779
2757 if opts.get("dump"):
2780 if opts.get("dump"):
2758 numrevs = len(r)
2781 numrevs = len(r)
2759 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2782 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2760 " rawsize totalsize compression heads chainlen\n")
2783 " rawsize totalsize compression heads chainlen\n")
2761 ts = 0
2784 ts = 0
2762 heads = set()
2785 heads = set()
2763
2786
2764 for rev in xrange(numrevs):
2787 for rev in xrange(numrevs):
2765 dbase = r.deltaparent(rev)
2788 dbase = r.deltaparent(rev)
2766 if dbase == -1:
2789 if dbase == -1:
2767 dbase = rev
2790 dbase = rev
2768 cbase = r.chainbase(rev)
2791 cbase = r.chainbase(rev)
2769 clen = r.chainlen(rev)
2792 clen = r.chainlen(rev)
2770 p1, p2 = r.parentrevs(rev)
2793 p1, p2 = r.parentrevs(rev)
2771 rs = r.rawsize(rev)
2794 rs = r.rawsize(rev)
2772 ts = ts + rs
2795 ts = ts + rs
2773 heads -= set(r.parentrevs(rev))
2796 heads -= set(r.parentrevs(rev))
2774 heads.add(rev)
2797 heads.add(rev)
2775 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2798 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
2776 "%11d %5d %8d\n" %
2799 "%11d %5d %8d\n" %
2777 (rev, p1, p2, r.start(rev), r.end(rev),
2800 (rev, p1, p2, r.start(rev), r.end(rev),
2778 r.start(dbase), r.start(cbase),
2801 r.start(dbase), r.start(cbase),
2779 r.start(p1), r.start(p2),
2802 r.start(p1), r.start(p2),
2780 rs, ts, ts / r.end(rev), len(heads), clen))
2803 rs, ts, ts / r.end(rev), len(heads), clen))
2781 return 0
2804 return 0
2782
2805
2783 v = r.version
2806 v = r.version
2784 format = v & 0xFFFF
2807 format = v & 0xFFFF
2785 flags = []
2808 flags = []
2786 gdelta = False
2809 gdelta = False
2787 if v & revlog.REVLOGNGINLINEDATA:
2810 if v & revlog.REVLOGNGINLINEDATA:
2788 flags.append('inline')
2811 flags.append('inline')
2789 if v & revlog.REVLOGGENERALDELTA:
2812 if v & revlog.REVLOGGENERALDELTA:
2790 gdelta = True
2813 gdelta = True
2791 flags.append('generaldelta')
2814 flags.append('generaldelta')
2792 if not flags:
2815 if not flags:
2793 flags = ['(none)']
2816 flags = ['(none)']
2794
2817
2795 nummerges = 0
2818 nummerges = 0
2796 numfull = 0
2819 numfull = 0
2797 numprev = 0
2820 numprev = 0
2798 nump1 = 0
2821 nump1 = 0
2799 nump2 = 0
2822 nump2 = 0
2800 numother = 0
2823 numother = 0
2801 nump1prev = 0
2824 nump1prev = 0
2802 nump2prev = 0
2825 nump2prev = 0
2803 chainlengths = []
2826 chainlengths = []
2804
2827
2805 datasize = [None, 0, 0L]
2828 datasize = [None, 0, 0L]
2806 fullsize = [None, 0, 0L]
2829 fullsize = [None, 0, 0L]
2807 deltasize = [None, 0, 0L]
2830 deltasize = [None, 0, 0L]
2808
2831
2809 def addsize(size, l):
2832 def addsize(size, l):
2810 if l[0] is None or size < l[0]:
2833 if l[0] is None or size < l[0]:
2811 l[0] = size
2834 l[0] = size
2812 if size > l[1]:
2835 if size > l[1]:
2813 l[1] = size
2836 l[1] = size
2814 l[2] += size
2837 l[2] += size
2815
2838
2816 numrevs = len(r)
2839 numrevs = len(r)
2817 for rev in xrange(numrevs):
2840 for rev in xrange(numrevs):
2818 p1, p2 = r.parentrevs(rev)
2841 p1, p2 = r.parentrevs(rev)
2819 delta = r.deltaparent(rev)
2842 delta = r.deltaparent(rev)
2820 if format > 0:
2843 if format > 0:
2821 addsize(r.rawsize(rev), datasize)
2844 addsize(r.rawsize(rev), datasize)
2822 if p2 != nullrev:
2845 if p2 != nullrev:
2823 nummerges += 1
2846 nummerges += 1
2824 size = r.length(rev)
2847 size = r.length(rev)
2825 if delta == nullrev:
2848 if delta == nullrev:
2826 chainlengths.append(0)
2849 chainlengths.append(0)
2827 numfull += 1
2850 numfull += 1
2828 addsize(size, fullsize)
2851 addsize(size, fullsize)
2829 else:
2852 else:
2830 chainlengths.append(chainlengths[delta] + 1)
2853 chainlengths.append(chainlengths[delta] + 1)
2831 addsize(size, deltasize)
2854 addsize(size, deltasize)
2832 if delta == rev - 1:
2855 if delta == rev - 1:
2833 numprev += 1
2856 numprev += 1
2834 if delta == p1:
2857 if delta == p1:
2835 nump1prev += 1
2858 nump1prev += 1
2836 elif delta == p2:
2859 elif delta == p2:
2837 nump2prev += 1
2860 nump2prev += 1
2838 elif delta == p1:
2861 elif delta == p1:
2839 nump1 += 1
2862 nump1 += 1
2840 elif delta == p2:
2863 elif delta == p2:
2841 nump2 += 1
2864 nump2 += 1
2842 elif delta != nullrev:
2865 elif delta != nullrev:
2843 numother += 1
2866 numother += 1
2844
2867
2845 # Adjust size min value for empty cases
2868 # Adjust size min value for empty cases
2846 for size in (datasize, fullsize, deltasize):
2869 for size in (datasize, fullsize, deltasize):
2847 if size[0] is None:
2870 if size[0] is None:
2848 size[0] = 0
2871 size[0] = 0
2849
2872
2850 numdeltas = numrevs - numfull
2873 numdeltas = numrevs - numfull
2851 numoprev = numprev - nump1prev - nump2prev
2874 numoprev = numprev - nump1prev - nump2prev
2852 totalrawsize = datasize[2]
2875 totalrawsize = datasize[2]
2853 datasize[2] /= numrevs
2876 datasize[2] /= numrevs
2854 fulltotal = fullsize[2]
2877 fulltotal = fullsize[2]
2855 fullsize[2] /= numfull
2878 fullsize[2] /= numfull
2856 deltatotal = deltasize[2]
2879 deltatotal = deltasize[2]
2857 if numrevs - numfull > 0:
2880 if numrevs - numfull > 0:
2858 deltasize[2] /= numrevs - numfull
2881 deltasize[2] /= numrevs - numfull
2859 totalsize = fulltotal + deltatotal
2882 totalsize = fulltotal + deltatotal
2860 avgchainlen = sum(chainlengths) / numrevs
2883 avgchainlen = sum(chainlengths) / numrevs
2861 maxchainlen = max(chainlengths)
2884 maxchainlen = max(chainlengths)
2862 compratio = totalrawsize / totalsize
2885 compratio = totalrawsize / totalsize
2863
2886
2864 basedfmtstr = '%%%dd\n'
2887 basedfmtstr = '%%%dd\n'
2865 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2888 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2866
2889
2867 def dfmtstr(max):
2890 def dfmtstr(max):
2868 return basedfmtstr % len(str(max))
2891 return basedfmtstr % len(str(max))
2869 def pcfmtstr(max, padding=0):
2892 def pcfmtstr(max, padding=0):
2870 return basepcfmtstr % (len(str(max)), ' ' * padding)
2893 return basepcfmtstr % (len(str(max)), ' ' * padding)
2871
2894
2872 def pcfmt(value, total):
2895 def pcfmt(value, total):
2873 return (value, 100 * float(value) / total)
2896 return (value, 100 * float(value) / total)
2874
2897
2875 ui.write(('format : %d\n') % format)
2898 ui.write(('format : %d\n') % format)
2876 ui.write(('flags : %s\n') % ', '.join(flags))
2899 ui.write(('flags : %s\n') % ', '.join(flags))
2877
2900
2878 ui.write('\n')
2901 ui.write('\n')
2879 fmt = pcfmtstr(totalsize)
2902 fmt = pcfmtstr(totalsize)
2880 fmt2 = dfmtstr(totalsize)
2903 fmt2 = dfmtstr(totalsize)
2881 ui.write(('revisions : ') + fmt2 % numrevs)
2904 ui.write(('revisions : ') + fmt2 % numrevs)
2882 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2905 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2883 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2906 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2884 ui.write(('revisions : ') + fmt2 % numrevs)
2907 ui.write(('revisions : ') + fmt2 % numrevs)
2885 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2908 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2886 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2909 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2887 ui.write(('revision size : ') + fmt2 % totalsize)
2910 ui.write(('revision size : ') + fmt2 % totalsize)
2888 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2911 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2889 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2912 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2890
2913
2891 ui.write('\n')
2914 ui.write('\n')
2892 fmt = dfmtstr(max(avgchainlen, compratio))
2915 fmt = dfmtstr(max(avgchainlen, compratio))
2893 ui.write(('avg chain length : ') + fmt % avgchainlen)
2916 ui.write(('avg chain length : ') + fmt % avgchainlen)
2894 ui.write(('max chain length : ') + fmt % maxchainlen)
2917 ui.write(('max chain length : ') + fmt % maxchainlen)
2895 ui.write(('compression ratio : ') + fmt % compratio)
2918 ui.write(('compression ratio : ') + fmt % compratio)
2896
2919
2897 if format > 0:
2920 if format > 0:
2898 ui.write('\n')
2921 ui.write('\n')
2899 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2922 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2900 % tuple(datasize))
2923 % tuple(datasize))
2901 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2924 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2902 % tuple(fullsize))
2925 % tuple(fullsize))
2903 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2926 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2904 % tuple(deltasize))
2927 % tuple(deltasize))
2905
2928
2906 if numdeltas > 0:
2929 if numdeltas > 0:
2907 ui.write('\n')
2930 ui.write('\n')
2908 fmt = pcfmtstr(numdeltas)
2931 fmt = pcfmtstr(numdeltas)
2909 fmt2 = pcfmtstr(numdeltas, 4)
2932 fmt2 = pcfmtstr(numdeltas, 4)
2910 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2933 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2911 if numprev > 0:
2934 if numprev > 0:
2912 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2935 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2913 numprev))
2936 numprev))
2914 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2937 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2915 numprev))
2938 numprev))
2916 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2939 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2917 numprev))
2940 numprev))
2918 if gdelta:
2941 if gdelta:
2919 ui.write(('deltas against p1 : ')
2942 ui.write(('deltas against p1 : ')
2920 + fmt % pcfmt(nump1, numdeltas))
2943 + fmt % pcfmt(nump1, numdeltas))
2921 ui.write(('deltas against p2 : ')
2944 ui.write(('deltas against p2 : ')
2922 + fmt % pcfmt(nump2, numdeltas))
2945 + fmt % pcfmt(nump2, numdeltas))
2923 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2946 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2924 numdeltas))
2947 numdeltas))
2925
2948
2926 @command('debugrevspec',
2949 @command('debugrevspec',
2927 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2950 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2928 ('REVSPEC'))
2951 ('REVSPEC'))
2929 def debugrevspec(ui, repo, expr, **opts):
2952 def debugrevspec(ui, repo, expr, **opts):
2930 """parse and apply a revision specification
2953 """parse and apply a revision specification
2931
2954
2932 Use --verbose to print the parsed tree before and after aliases
2955 Use --verbose to print the parsed tree before and after aliases
2933 expansion.
2956 expansion.
2934 """
2957 """
2935 if ui.verbose:
2958 if ui.verbose:
2936 tree = revset.parse(expr, lookup=repo.__contains__)
2959 tree = revset.parse(expr, lookup=repo.__contains__)
2937 ui.note(revset.prettyformat(tree), "\n")
2960 ui.note(revset.prettyformat(tree), "\n")
2938 newtree = revset.findaliases(ui, tree)
2961 newtree = revset.findaliases(ui, tree)
2939 if newtree != tree:
2962 if newtree != tree:
2940 ui.note(revset.prettyformat(newtree), "\n")
2963 ui.note(revset.prettyformat(newtree), "\n")
2941 tree = newtree
2964 tree = newtree
2942 newtree = revset.foldconcat(tree)
2965 newtree = revset.foldconcat(tree)
2943 if newtree != tree:
2966 if newtree != tree:
2944 ui.note(revset.prettyformat(newtree), "\n")
2967 ui.note(revset.prettyformat(newtree), "\n")
2945 if opts["optimize"]:
2968 if opts["optimize"]:
2946 weight, optimizedtree = revset.optimize(newtree, True)
2969 weight, optimizedtree = revset.optimize(newtree, True)
2947 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2970 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2948 func = revset.match(ui, expr, repo)
2971 func = revset.match(ui, expr, repo)
2949 revs = func(repo)
2972 revs = func(repo)
2950 if ui.verbose:
2973 if ui.verbose:
2951 ui.note("* set:\n", revset.prettyformatset(revs), "\n")
2974 ui.note("* set:\n", revset.prettyformatset(revs), "\n")
2952 for c in revs:
2975 for c in revs:
2953 ui.write("%s\n" % c)
2976 ui.write("%s\n" % c)
2954
2977
2955 @command('debugsetparents', [], _('REV1 [REV2]'))
2978 @command('debugsetparents', [], _('REV1 [REV2]'))
2956 def debugsetparents(ui, repo, rev1, rev2=None):
2979 def debugsetparents(ui, repo, rev1, rev2=None):
2957 """manually set the parents of the current working directory
2980 """manually set the parents of the current working directory
2958
2981
2959 This is useful for writing repository conversion tools, but should
2982 This is useful for writing repository conversion tools, but should
2960 be used with care. For example, neither the working directory nor the
2983 be used with care. For example, neither the working directory nor the
2961 dirstate is updated, so file status may be incorrect after running this
2984 dirstate is updated, so file status may be incorrect after running this
2962 command.
2985 command.
2963
2986
2964 Returns 0 on success.
2987 Returns 0 on success.
2965 """
2988 """
2966
2989
2967 r1 = scmutil.revsingle(repo, rev1).node()
2990 r1 = scmutil.revsingle(repo, rev1).node()
2968 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2991 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2969
2992
2970 wlock = repo.wlock()
2993 wlock = repo.wlock()
2971 try:
2994 try:
2972 repo.dirstate.beginparentchange()
2995 repo.dirstate.beginparentchange()
2973 repo.setparents(r1, r2)
2996 repo.setparents(r1, r2)
2974 repo.dirstate.endparentchange()
2997 repo.dirstate.endparentchange()
2975 finally:
2998 finally:
2976 wlock.release()
2999 wlock.release()
2977
3000
2978 @command('debugdirstate|debugstate',
3001 @command('debugdirstate|debugstate',
2979 [('', 'nodates', None, _('do not display the saved mtime')),
3002 [('', 'nodates', None, _('do not display the saved mtime')),
2980 ('', 'datesort', None, _('sort by saved mtime'))],
3003 ('', 'datesort', None, _('sort by saved mtime'))],
2981 _('[OPTION]...'))
3004 _('[OPTION]...'))
2982 def debugstate(ui, repo, nodates=None, datesort=None):
3005 def debugstate(ui, repo, nodates=None, datesort=None):
2983 """show the contents of the current dirstate"""
3006 """show the contents of the current dirstate"""
2984 timestr = ""
3007 timestr = ""
2985 if datesort:
3008 if datesort:
2986 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
3009 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2987 else:
3010 else:
2988 keyfunc = None # sort by filename
3011 keyfunc = None # sort by filename
2989 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
3012 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2990 if ent[3] == -1:
3013 if ent[3] == -1:
2991 timestr = 'unset '
3014 timestr = 'unset '
2992 elif nodates:
3015 elif nodates:
2993 timestr = 'set '
3016 timestr = 'set '
2994 else:
3017 else:
2995 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
3018 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2996 time.localtime(ent[3]))
3019 time.localtime(ent[3]))
2997 if ent[1] & 0o20000:
3020 if ent[1] & 0o20000:
2998 mode = 'lnk'
3021 mode = 'lnk'
2999 else:
3022 else:
3000 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
3023 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
3001 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
3024 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
3002 for f in repo.dirstate.copies():
3025 for f in repo.dirstate.copies():
3003 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
3026 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
3004
3027
3005 @command('debugsub',
3028 @command('debugsub',
3006 [('r', 'rev', '',
3029 [('r', 'rev', '',
3007 _('revision to check'), _('REV'))],
3030 _('revision to check'), _('REV'))],
3008 _('[-r REV] [REV]'))
3031 _('[-r REV] [REV]'))
3009 def debugsub(ui, repo, rev=None):
3032 def debugsub(ui, repo, rev=None):
3010 ctx = scmutil.revsingle(repo, rev, None)
3033 ctx = scmutil.revsingle(repo, rev, None)
3011 for k, v in sorted(ctx.substate.items()):
3034 for k, v in sorted(ctx.substate.items()):
3012 ui.write(('path %s\n') % k)
3035 ui.write(('path %s\n') % k)
3013 ui.write((' source %s\n') % v[0])
3036 ui.write((' source %s\n') % v[0])
3014 ui.write((' revision %s\n') % v[1])
3037 ui.write((' revision %s\n') % v[1])
3015
3038
3016 @command('debugsuccessorssets',
3039 @command('debugsuccessorssets',
3017 [],
3040 [],
3018 _('[REV]'))
3041 _('[REV]'))
3019 def debugsuccessorssets(ui, repo, *revs):
3042 def debugsuccessorssets(ui, repo, *revs):
3020 """show set of successors for revision
3043 """show set of successors for revision
3021
3044
3022 A successors set of changeset A is a consistent group of revisions that
3045 A successors set of changeset A is a consistent group of revisions that
3023 succeed A. It contains non-obsolete changesets only.
3046 succeed A. It contains non-obsolete changesets only.
3024
3047
3025 In most cases a changeset A has a single successors set containing a single
3048 In most cases a changeset A has a single successors set containing a single
3026 successor (changeset A replaced by A').
3049 successor (changeset A replaced by A').
3027
3050
3028 A changeset that is made obsolete with no successors are called "pruned".
3051 A changeset that is made obsolete with no successors are called "pruned".
3029 Such changesets have no successors sets at all.
3052 Such changesets have no successors sets at all.
3030
3053
3031 A changeset that has been "split" will have a successors set containing
3054 A changeset that has been "split" will have a successors set containing
3032 more than one successor.
3055 more than one successor.
3033
3056
3034 A changeset that has been rewritten in multiple different ways is called
3057 A changeset that has been rewritten in multiple different ways is called
3035 "divergent". Such changesets have multiple successor sets (each of which
3058 "divergent". Such changesets have multiple successor sets (each of which
3036 may also be split, i.e. have multiple successors).
3059 may also be split, i.e. have multiple successors).
3037
3060
3038 Results are displayed as follows::
3061 Results are displayed as follows::
3039
3062
3040 <rev1>
3063 <rev1>
3041 <successors-1A>
3064 <successors-1A>
3042 <rev2>
3065 <rev2>
3043 <successors-2A>
3066 <successors-2A>
3044 <successors-2B1> <successors-2B2> <successors-2B3>
3067 <successors-2B1> <successors-2B2> <successors-2B3>
3045
3068
3046 Here rev2 has two possible (i.e. divergent) successors sets. The first
3069 Here rev2 has two possible (i.e. divergent) successors sets. The first
3047 holds one element, whereas the second holds three (i.e. the changeset has
3070 holds one element, whereas the second holds three (i.e. the changeset has
3048 been split).
3071 been split).
3049 """
3072 """
3050 # passed to successorssets caching computation from one call to another
3073 # passed to successorssets caching computation from one call to another
3051 cache = {}
3074 cache = {}
3052 ctx2str = str
3075 ctx2str = str
3053 node2str = short
3076 node2str = short
3054 if ui.debug():
3077 if ui.debug():
3055 def ctx2str(ctx):
3078 def ctx2str(ctx):
3056 return ctx.hex()
3079 return ctx.hex()
3057 node2str = hex
3080 node2str = hex
3058 for rev in scmutil.revrange(repo, revs):
3081 for rev in scmutil.revrange(repo, revs):
3059 ctx = repo[rev]
3082 ctx = repo[rev]
3060 ui.write('%s\n'% ctx2str(ctx))
3083 ui.write('%s\n'% ctx2str(ctx))
3061 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
3084 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
3062 if succsset:
3085 if succsset:
3063 ui.write(' ')
3086 ui.write(' ')
3064 ui.write(node2str(succsset[0]))
3087 ui.write(node2str(succsset[0]))
3065 for node in succsset[1:]:
3088 for node in succsset[1:]:
3066 ui.write(' ')
3089 ui.write(' ')
3067 ui.write(node2str(node))
3090 ui.write(node2str(node))
3068 ui.write('\n')
3091 ui.write('\n')
3069
3092
3070 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3093 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'), inferrepo=True)
3071 def debugwalk(ui, repo, *pats, **opts):
3094 def debugwalk(ui, repo, *pats, **opts):
3072 """show how files match on given patterns"""
3095 """show how files match on given patterns"""
3073 m = scmutil.match(repo[None], pats, opts)
3096 m = scmutil.match(repo[None], pats, opts)
3074 items = list(repo.walk(m))
3097 items = list(repo.walk(m))
3075 if not items:
3098 if not items:
3076 return
3099 return
3077 f = lambda fn: fn
3100 f = lambda fn: fn
3078 if ui.configbool('ui', 'slash') and os.sep != '/':
3101 if ui.configbool('ui', 'slash') and os.sep != '/':
3079 f = lambda fn: util.normpath(fn)
3102 f = lambda fn: util.normpath(fn)
3080 fmt = 'f %%-%ds %%-%ds %%s' % (
3103 fmt = 'f %%-%ds %%-%ds %%s' % (
3081 max([len(abs) for abs in items]),
3104 max([len(abs) for abs in items]),
3082 max([len(m.rel(abs)) for abs in items]))
3105 max([len(m.rel(abs)) for abs in items]))
3083 for abs in items:
3106 for abs in items:
3084 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3107 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
3085 ui.write("%s\n" % line.rstrip())
3108 ui.write("%s\n" % line.rstrip())
3086
3109
3087 @command('debugwireargs',
3110 @command('debugwireargs',
3088 [('', 'three', '', 'three'),
3111 [('', 'three', '', 'three'),
3089 ('', 'four', '', 'four'),
3112 ('', 'four', '', 'four'),
3090 ('', 'five', '', 'five'),
3113 ('', 'five', '', 'five'),
3091 ] + remoteopts,
3114 ] + remoteopts,
3092 _('REPO [OPTIONS]... [ONE [TWO]]'),
3115 _('REPO [OPTIONS]... [ONE [TWO]]'),
3093 norepo=True)
3116 norepo=True)
3094 def debugwireargs(ui, repopath, *vals, **opts):
3117 def debugwireargs(ui, repopath, *vals, **opts):
3095 repo = hg.peer(ui, opts, repopath)
3118 repo = hg.peer(ui, opts, repopath)
3096 for opt in remoteopts:
3119 for opt in remoteopts:
3097 del opts[opt[1]]
3120 del opts[opt[1]]
3098 args = {}
3121 args = {}
3099 for k, v in opts.iteritems():
3122 for k, v in opts.iteritems():
3100 if v:
3123 if v:
3101 args[k] = v
3124 args[k] = v
3102 # run twice to check that we don't mess up the stream for the next command
3125 # run twice to check that we don't mess up the stream for the next command
3103 res1 = repo.debugwireargs(*vals, **args)
3126 res1 = repo.debugwireargs(*vals, **args)
3104 res2 = repo.debugwireargs(*vals, **args)
3127 res2 = repo.debugwireargs(*vals, **args)
3105 ui.write("%s\n" % res1)
3128 ui.write("%s\n" % res1)
3106 if res1 != res2:
3129 if res1 != res2:
3107 ui.warn("%s\n" % res2)
3130 ui.warn("%s\n" % res2)
3108
3131
3109 @command('^diff',
3132 @command('^diff',
3110 [('r', 'rev', [], _('revision'), _('REV')),
3133 [('r', 'rev', [], _('revision'), _('REV')),
3111 ('c', 'change', '', _('change made by revision'), _('REV'))
3134 ('c', 'change', '', _('change made by revision'), _('REV'))
3112 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3135 ] + diffopts + diffopts2 + walkopts + subrepoopts,
3113 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3136 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
3114 inferrepo=True)
3137 inferrepo=True)
3115 def diff(ui, repo, *pats, **opts):
3138 def diff(ui, repo, *pats, **opts):
3116 """diff repository (or selected files)
3139 """diff repository (or selected files)
3117
3140
3118 Show differences between revisions for the specified files.
3141 Show differences between revisions for the specified files.
3119
3142
3120 Differences between files are shown using the unified diff format.
3143 Differences between files are shown using the unified diff format.
3121
3144
3122 .. note::
3145 .. note::
3123
3146
3124 diff may generate unexpected results for merges, as it will
3147 diff may generate unexpected results for merges, as it will
3125 default to comparing against the working directory's first
3148 default to comparing against the working directory's first
3126 parent changeset if no revisions are specified.
3149 parent changeset if no revisions are specified.
3127
3150
3128 When two revision arguments are given, then changes are shown
3151 When two revision arguments are given, then changes are shown
3129 between those revisions. If only one revision is specified then
3152 between those revisions. If only one revision is specified then
3130 that revision is compared to the working directory, and, when no
3153 that revision is compared to the working directory, and, when no
3131 revisions are specified, the working directory files are compared
3154 revisions are specified, the working directory files are compared
3132 to its parent.
3155 to its parent.
3133
3156
3134 Alternatively you can specify -c/--change with a revision to see
3157 Alternatively you can specify -c/--change with a revision to see
3135 the changes in that changeset relative to its first parent.
3158 the changes in that changeset relative to its first parent.
3136
3159
3137 Without the -a/--text option, diff will avoid generating diffs of
3160 Without the -a/--text option, diff will avoid generating diffs of
3138 files it detects as binary. With -a, diff will generate a diff
3161 files it detects as binary. With -a, diff will generate a diff
3139 anyway, probably with undesirable results.
3162 anyway, probably with undesirable results.
3140
3163
3141 Use the -g/--git option to generate diffs in the git extended diff
3164 Use the -g/--git option to generate diffs in the git extended diff
3142 format. For more information, read :hg:`help diffs`.
3165 format. For more information, read :hg:`help diffs`.
3143
3166
3144 .. container:: verbose
3167 .. container:: verbose
3145
3168
3146 Examples:
3169 Examples:
3147
3170
3148 - compare a file in the current working directory to its parent::
3171 - compare a file in the current working directory to its parent::
3149
3172
3150 hg diff foo.c
3173 hg diff foo.c
3151
3174
3152 - compare two historical versions of a directory, with rename info::
3175 - compare two historical versions of a directory, with rename info::
3153
3176
3154 hg diff --git -r 1.0:1.2 lib/
3177 hg diff --git -r 1.0:1.2 lib/
3155
3178
3156 - get change stats relative to the last change on some date::
3179 - get change stats relative to the last change on some date::
3157
3180
3158 hg diff --stat -r "date('may 2')"
3181 hg diff --stat -r "date('may 2')"
3159
3182
3160 - diff all newly-added files that contain a keyword::
3183 - diff all newly-added files that contain a keyword::
3161
3184
3162 hg diff "set:added() and grep(GNU)"
3185 hg diff "set:added() and grep(GNU)"
3163
3186
3164 - compare a revision and its parents::
3187 - compare a revision and its parents::
3165
3188
3166 hg diff -c 9353 # compare against first parent
3189 hg diff -c 9353 # compare against first parent
3167 hg diff -r 9353^:9353 # same using revset syntax
3190 hg diff -r 9353^:9353 # same using revset syntax
3168 hg diff -r 9353^2:9353 # compare against the second parent
3191 hg diff -r 9353^2:9353 # compare against the second parent
3169
3192
3170 Returns 0 on success.
3193 Returns 0 on success.
3171 """
3194 """
3172
3195
3173 revs = opts.get('rev')
3196 revs = opts.get('rev')
3174 change = opts.get('change')
3197 change = opts.get('change')
3175 stat = opts.get('stat')
3198 stat = opts.get('stat')
3176 reverse = opts.get('reverse')
3199 reverse = opts.get('reverse')
3177
3200
3178 if revs and change:
3201 if revs and change:
3179 msg = _('cannot specify --rev and --change at the same time')
3202 msg = _('cannot specify --rev and --change at the same time')
3180 raise util.Abort(msg)
3203 raise util.Abort(msg)
3181 elif change:
3204 elif change:
3182 node2 = scmutil.revsingle(repo, change, None).node()
3205 node2 = scmutil.revsingle(repo, change, None).node()
3183 node1 = repo[node2].p1().node()
3206 node1 = repo[node2].p1().node()
3184 else:
3207 else:
3185 node1, node2 = scmutil.revpair(repo, revs)
3208 node1, node2 = scmutil.revpair(repo, revs)
3186
3209
3187 if reverse:
3210 if reverse:
3188 node1, node2 = node2, node1
3211 node1, node2 = node2, node1
3189
3212
3190 diffopts = patch.diffallopts(ui, opts)
3213 diffopts = patch.diffallopts(ui, opts)
3191 m = scmutil.match(repo[node2], pats, opts)
3214 m = scmutil.match(repo[node2], pats, opts)
3192 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3215 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
3193 listsubrepos=opts.get('subrepos'),
3216 listsubrepos=opts.get('subrepos'),
3194 root=opts.get('root'))
3217 root=opts.get('root'))
3195
3218
3196 @command('^export',
3219 @command('^export',
3197 [('o', 'output', '',
3220 [('o', 'output', '',
3198 _('print output to file with formatted name'), _('FORMAT')),
3221 _('print output to file with formatted name'), _('FORMAT')),
3199 ('', 'switch-parent', None, _('diff against the second parent')),
3222 ('', 'switch-parent', None, _('diff against the second parent')),
3200 ('r', 'rev', [], _('revisions to export'), _('REV')),
3223 ('r', 'rev', [], _('revisions to export'), _('REV')),
3201 ] + diffopts,
3224 ] + diffopts,
3202 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3225 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
3203 def export(ui, repo, *changesets, **opts):
3226 def export(ui, repo, *changesets, **opts):
3204 """dump the header and diffs for one or more changesets
3227 """dump the header and diffs for one or more changesets
3205
3228
3206 Print the changeset header and diffs for one or more revisions.
3229 Print the changeset header and diffs for one or more revisions.
3207 If no revision is given, the parent of the working directory is used.
3230 If no revision is given, the parent of the working directory is used.
3208
3231
3209 The information shown in the changeset header is: author, date,
3232 The information shown in the changeset header is: author, date,
3210 branch name (if non-default), changeset hash, parent(s) and commit
3233 branch name (if non-default), changeset hash, parent(s) and commit
3211 comment.
3234 comment.
3212
3235
3213 .. note::
3236 .. note::
3214
3237
3215 export may generate unexpected diff output for merge
3238 export may generate unexpected diff output for merge
3216 changesets, as it will compare the merge changeset against its
3239 changesets, as it will compare the merge changeset against its
3217 first parent only.
3240 first parent only.
3218
3241
3219 Output may be to a file, in which case the name of the file is
3242 Output may be to a file, in which case the name of the file is
3220 given using a format string. The formatting rules are as follows:
3243 given using a format string. The formatting rules are as follows:
3221
3244
3222 :``%%``: literal "%" character
3245 :``%%``: literal "%" character
3223 :``%H``: changeset hash (40 hexadecimal digits)
3246 :``%H``: changeset hash (40 hexadecimal digits)
3224 :``%N``: number of patches being generated
3247 :``%N``: number of patches being generated
3225 :``%R``: changeset revision number
3248 :``%R``: changeset revision number
3226 :``%b``: basename of the exporting repository
3249 :``%b``: basename of the exporting repository
3227 :``%h``: short-form changeset hash (12 hexadecimal digits)
3250 :``%h``: short-form changeset hash (12 hexadecimal digits)
3228 :``%m``: first line of the commit message (only alphanumeric characters)
3251 :``%m``: first line of the commit message (only alphanumeric characters)
3229 :``%n``: zero-padded sequence number, starting at 1
3252 :``%n``: zero-padded sequence number, starting at 1
3230 :``%r``: zero-padded changeset revision number
3253 :``%r``: zero-padded changeset revision number
3231
3254
3232 Without the -a/--text option, export will avoid generating diffs
3255 Without the -a/--text option, export will avoid generating diffs
3233 of files it detects as binary. With -a, export will generate a
3256 of files it detects as binary. With -a, export will generate a
3234 diff anyway, probably with undesirable results.
3257 diff anyway, probably with undesirable results.
3235
3258
3236 Use the -g/--git option to generate diffs in the git extended diff
3259 Use the -g/--git option to generate diffs in the git extended diff
3237 format. See :hg:`help diffs` for more information.
3260 format. See :hg:`help diffs` for more information.
3238
3261
3239 With the --switch-parent option, the diff will be against the
3262 With the --switch-parent option, the diff will be against the
3240 second parent. It can be useful to review a merge.
3263 second parent. It can be useful to review a merge.
3241
3264
3242 .. container:: verbose
3265 .. container:: verbose
3243
3266
3244 Examples:
3267 Examples:
3245
3268
3246 - use export and import to transplant a bugfix to the current
3269 - use export and import to transplant a bugfix to the current
3247 branch::
3270 branch::
3248
3271
3249 hg export -r 9353 | hg import -
3272 hg export -r 9353 | hg import -
3250
3273
3251 - export all the changesets between two revisions to a file with
3274 - export all the changesets between two revisions to a file with
3252 rename information::
3275 rename information::
3253
3276
3254 hg export --git -r 123:150 > changes.txt
3277 hg export --git -r 123:150 > changes.txt
3255
3278
3256 - split outgoing changes into a series of patches with
3279 - split outgoing changes into a series of patches with
3257 descriptive names::
3280 descriptive names::
3258
3281
3259 hg export -r "outgoing()" -o "%n-%m.patch"
3282 hg export -r "outgoing()" -o "%n-%m.patch"
3260
3283
3261 Returns 0 on success.
3284 Returns 0 on success.
3262 """
3285 """
3263 changesets += tuple(opts.get('rev', []))
3286 changesets += tuple(opts.get('rev', []))
3264 if not changesets:
3287 if not changesets:
3265 changesets = ['.']
3288 changesets = ['.']
3266 revs = scmutil.revrange(repo, changesets)
3289 revs = scmutil.revrange(repo, changesets)
3267 if not revs:
3290 if not revs:
3268 raise util.Abort(_("export requires at least one changeset"))
3291 raise util.Abort(_("export requires at least one changeset"))
3269 if len(revs) > 1:
3292 if len(revs) > 1:
3270 ui.note(_('exporting patches:\n'))
3293 ui.note(_('exporting patches:\n'))
3271 else:
3294 else:
3272 ui.note(_('exporting patch:\n'))
3295 ui.note(_('exporting patch:\n'))
3273 cmdutil.export(repo, revs, template=opts.get('output'),
3296 cmdutil.export(repo, revs, template=opts.get('output'),
3274 switch_parent=opts.get('switch_parent'),
3297 switch_parent=opts.get('switch_parent'),
3275 opts=patch.diffallopts(ui, opts))
3298 opts=patch.diffallopts(ui, opts))
3276
3299
3277 @command('files',
3300 @command('files',
3278 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3301 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3279 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3302 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3280 ] + walkopts + formatteropts + subrepoopts,
3303 ] + walkopts + formatteropts + subrepoopts,
3281 _('[OPTION]... [PATTERN]...'))
3304 _('[OPTION]... [PATTERN]...'))
3282 def files(ui, repo, *pats, **opts):
3305 def files(ui, repo, *pats, **opts):
3283 """list tracked files
3306 """list tracked files
3284
3307
3285 Print files under Mercurial control in the working directory or
3308 Print files under Mercurial control in the working directory or
3286 specified revision whose names match the given patterns (excluding
3309 specified revision whose names match the given patterns (excluding
3287 removed files).
3310 removed files).
3288
3311
3289 If no patterns are given to match, this command prints the names
3312 If no patterns are given to match, this command prints the names
3290 of all files under Mercurial control in the working directory.
3313 of all files under Mercurial control in the working directory.
3291
3314
3292 .. container:: verbose
3315 .. container:: verbose
3293
3316
3294 Examples:
3317 Examples:
3295
3318
3296 - list all files under the current directory::
3319 - list all files under the current directory::
3297
3320
3298 hg files .
3321 hg files .
3299
3322
3300 - shows sizes and flags for current revision::
3323 - shows sizes and flags for current revision::
3301
3324
3302 hg files -vr .
3325 hg files -vr .
3303
3326
3304 - list all files named README::
3327 - list all files named README::
3305
3328
3306 hg files -I "**/README"
3329 hg files -I "**/README"
3307
3330
3308 - list all binary files::
3331 - list all binary files::
3309
3332
3310 hg files "set:binary()"
3333 hg files "set:binary()"
3311
3334
3312 - find files containing a regular expression::
3335 - find files containing a regular expression::
3313
3336
3314 hg files "set:grep('bob')"
3337 hg files "set:grep('bob')"
3315
3338
3316 - search tracked file contents with xargs and grep::
3339 - search tracked file contents with xargs and grep::
3317
3340
3318 hg files -0 | xargs -0 grep foo
3341 hg files -0 | xargs -0 grep foo
3319
3342
3320 See :hg:`help patterns` and :hg:`help filesets` for more information
3343 See :hg:`help patterns` and :hg:`help filesets` for more information
3321 on specifying file patterns.
3344 on specifying file patterns.
3322
3345
3323 Returns 0 if a match is found, 1 otherwise.
3346 Returns 0 if a match is found, 1 otherwise.
3324
3347
3325 """
3348 """
3326 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3349 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
3327
3350
3328 end = '\n'
3351 end = '\n'
3329 if opts.get('print0'):
3352 if opts.get('print0'):
3330 end = '\0'
3353 end = '\0'
3331 fm = ui.formatter('files', opts)
3354 fm = ui.formatter('files', opts)
3332 fmt = '%s' + end
3355 fmt = '%s' + end
3333
3356
3334 m = scmutil.match(ctx, pats, opts)
3357 m = scmutil.match(ctx, pats, opts)
3335 ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3358 ret = cmdutil.files(ui, ctx, m, fm, fmt, opts.get('subrepos'))
3336
3359
3337 fm.end()
3360 fm.end()
3338
3361
3339 return ret
3362 return ret
3340
3363
3341 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3364 @command('^forget', walkopts, _('[OPTION]... FILE...'), inferrepo=True)
3342 def forget(ui, repo, *pats, **opts):
3365 def forget(ui, repo, *pats, **opts):
3343 """forget the specified files on the next commit
3366 """forget the specified files on the next commit
3344
3367
3345 Mark the specified files so they will no longer be tracked
3368 Mark the specified files so they will no longer be tracked
3346 after the next commit.
3369 after the next commit.
3347
3370
3348 This only removes files from the current branch, not from the
3371 This only removes files from the current branch, not from the
3349 entire project history, and it does not delete them from the
3372 entire project history, and it does not delete them from the
3350 working directory.
3373 working directory.
3351
3374
3352 To delete the file from the working directory, see :hg:`remove`.
3375 To delete the file from the working directory, see :hg:`remove`.
3353
3376
3354 To undo a forget before the next commit, see :hg:`add`.
3377 To undo a forget before the next commit, see :hg:`add`.
3355
3378
3356 .. container:: verbose
3379 .. container:: verbose
3357
3380
3358 Examples:
3381 Examples:
3359
3382
3360 - forget newly-added binary files::
3383 - forget newly-added binary files::
3361
3384
3362 hg forget "set:added() and binary()"
3385 hg forget "set:added() and binary()"
3363
3386
3364 - forget files that would be excluded by .hgignore::
3387 - forget files that would be excluded by .hgignore::
3365
3388
3366 hg forget "set:hgignore()"
3389 hg forget "set:hgignore()"
3367
3390
3368 Returns 0 on success.
3391 Returns 0 on success.
3369 """
3392 """
3370
3393
3371 if not pats:
3394 if not pats:
3372 raise util.Abort(_('no files specified'))
3395 raise util.Abort(_('no files specified'))
3373
3396
3374 m = scmutil.match(repo[None], pats, opts)
3397 m = scmutil.match(repo[None], pats, opts)
3375 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3398 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3376 return rejected and 1 or 0
3399 return rejected and 1 or 0
3377
3400
3378 @command(
3401 @command(
3379 'graft',
3402 'graft',
3380 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3403 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3381 ('c', 'continue', False, _('resume interrupted graft')),
3404 ('c', 'continue', False, _('resume interrupted graft')),
3382 ('e', 'edit', False, _('invoke editor on commit messages')),
3405 ('e', 'edit', False, _('invoke editor on commit messages')),
3383 ('', 'log', None, _('append graft info to log message')),
3406 ('', 'log', None, _('append graft info to log message')),
3384 ('f', 'force', False, _('force graft')),
3407 ('f', 'force', False, _('force graft')),
3385 ('D', 'currentdate', False,
3408 ('D', 'currentdate', False,
3386 _('record the current date as commit date')),
3409 _('record the current date as commit date')),
3387 ('U', 'currentuser', False,
3410 ('U', 'currentuser', False,
3388 _('record the current user as committer'), _('DATE'))]
3411 _('record the current user as committer'), _('DATE'))]
3389 + commitopts2 + mergetoolopts + dryrunopts,
3412 + commitopts2 + mergetoolopts + dryrunopts,
3390 _('[OPTION]... [-r] REV...'))
3413 _('[OPTION]... [-r] REV...'))
3391 def graft(ui, repo, *revs, **opts):
3414 def graft(ui, repo, *revs, **opts):
3392 '''copy changes from other branches onto the current branch
3415 '''copy changes from other branches onto the current branch
3393
3416
3394 This command uses Mercurial's merge logic to copy individual
3417 This command uses Mercurial's merge logic to copy individual
3395 changes from other branches without merging branches in the
3418 changes from other branches without merging branches in the
3396 history graph. This is sometimes known as 'backporting' or
3419 history graph. This is sometimes known as 'backporting' or
3397 'cherry-picking'. By default, graft will copy user, date, and
3420 'cherry-picking'. By default, graft will copy user, date, and
3398 description from the source changesets.
3421 description from the source changesets.
3399
3422
3400 Changesets that are ancestors of the current revision, that have
3423 Changesets that are ancestors of the current revision, that have
3401 already been grafted, or that are merges will be skipped.
3424 already been grafted, or that are merges will be skipped.
3402
3425
3403 If --log is specified, log messages will have a comment appended
3426 If --log is specified, log messages will have a comment appended
3404 of the form::
3427 of the form::
3405
3428
3406 (grafted from CHANGESETHASH)
3429 (grafted from CHANGESETHASH)
3407
3430
3408 If --force is specified, revisions will be grafted even if they
3431 If --force is specified, revisions will be grafted even if they
3409 are already ancestors of or have been grafted to the destination.
3432 are already ancestors of or have been grafted to the destination.
3410 This is useful when the revisions have since been backed out.
3433 This is useful when the revisions have since been backed out.
3411
3434
3412 If a graft merge results in conflicts, the graft process is
3435 If a graft merge results in conflicts, the graft process is
3413 interrupted so that the current merge can be manually resolved.
3436 interrupted so that the current merge can be manually resolved.
3414 Once all conflicts are addressed, the graft process can be
3437 Once all conflicts are addressed, the graft process can be
3415 continued with the -c/--continue option.
3438 continued with the -c/--continue option.
3416
3439
3417 .. note::
3440 .. note::
3418
3441
3419 The -c/--continue option does not reapply earlier options, except
3442 The -c/--continue option does not reapply earlier options, except
3420 for --force.
3443 for --force.
3421
3444
3422 .. container:: verbose
3445 .. container:: verbose
3423
3446
3424 Examples:
3447 Examples:
3425
3448
3426 - copy a single change to the stable branch and edit its description::
3449 - copy a single change to the stable branch and edit its description::
3427
3450
3428 hg update stable
3451 hg update stable
3429 hg graft --edit 9393
3452 hg graft --edit 9393
3430
3453
3431 - graft a range of changesets with one exception, updating dates::
3454 - graft a range of changesets with one exception, updating dates::
3432
3455
3433 hg graft -D "2085::2093 and not 2091"
3456 hg graft -D "2085::2093 and not 2091"
3434
3457
3435 - continue a graft after resolving conflicts::
3458 - continue a graft after resolving conflicts::
3436
3459
3437 hg graft -c
3460 hg graft -c
3438
3461
3439 - show the source of a grafted changeset::
3462 - show the source of a grafted changeset::
3440
3463
3441 hg log --debug -r .
3464 hg log --debug -r .
3442
3465
3443 See :hg:`help revisions` and :hg:`help revsets` for more about
3466 See :hg:`help revisions` and :hg:`help revsets` for more about
3444 specifying revisions.
3467 specifying revisions.
3445
3468
3446 Returns 0 on successful completion.
3469 Returns 0 on successful completion.
3447 '''
3470 '''
3448
3471
3449 revs = list(revs)
3472 revs = list(revs)
3450 revs.extend(opts['rev'])
3473 revs.extend(opts['rev'])
3451
3474
3452 if not opts.get('user') and opts.get('currentuser'):
3475 if not opts.get('user') and opts.get('currentuser'):
3453 opts['user'] = ui.username()
3476 opts['user'] = ui.username()
3454 if not opts.get('date') and opts.get('currentdate'):
3477 if not opts.get('date') and opts.get('currentdate'):
3455 opts['date'] = "%d %d" % util.makedate()
3478 opts['date'] = "%d %d" % util.makedate()
3456
3479
3457 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3480 editor = cmdutil.getcommiteditor(editform='graft', **opts)
3458
3481
3459 cont = False
3482 cont = False
3460 if opts['continue']:
3483 if opts['continue']:
3461 cont = True
3484 cont = True
3462 if revs:
3485 if revs:
3463 raise util.Abort(_("can't specify --continue and revisions"))
3486 raise util.Abort(_("can't specify --continue and revisions"))
3464 # read in unfinished revisions
3487 # read in unfinished revisions
3465 try:
3488 try:
3466 nodes = repo.vfs.read('graftstate').splitlines()
3489 nodes = repo.vfs.read('graftstate').splitlines()
3467 revs = [repo[node].rev() for node in nodes]
3490 revs = [repo[node].rev() for node in nodes]
3468 except IOError as inst:
3491 except IOError as inst:
3469 if inst.errno != errno.ENOENT:
3492 if inst.errno != errno.ENOENT:
3470 raise
3493 raise
3471 raise util.Abort(_("no graft state found, can't continue"))
3494 raise util.Abort(_("no graft state found, can't continue"))
3472 else:
3495 else:
3473 cmdutil.checkunfinished(repo)
3496 cmdutil.checkunfinished(repo)
3474 cmdutil.bailifchanged(repo)
3497 cmdutil.bailifchanged(repo)
3475 if not revs:
3498 if not revs:
3476 raise util.Abort(_('no revisions specified'))
3499 raise util.Abort(_('no revisions specified'))
3477 revs = scmutil.revrange(repo, revs)
3500 revs = scmutil.revrange(repo, revs)
3478
3501
3479 skipped = set()
3502 skipped = set()
3480 # check for merges
3503 # check for merges
3481 for rev in repo.revs('%ld and merge()', revs):
3504 for rev in repo.revs('%ld and merge()', revs):
3482 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3505 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3483 skipped.add(rev)
3506 skipped.add(rev)
3484 revs = [r for r in revs if r not in skipped]
3507 revs = [r for r in revs if r not in skipped]
3485 if not revs:
3508 if not revs:
3486 return -1
3509 return -1
3487
3510
3488 # Don't check in the --continue case, in effect retaining --force across
3511 # Don't check in the --continue case, in effect retaining --force across
3489 # --continues. That's because without --force, any revisions we decided to
3512 # --continues. That's because without --force, any revisions we decided to
3490 # skip would have been filtered out here, so they wouldn't have made their
3513 # skip would have been filtered out here, so they wouldn't have made their
3491 # way to the graftstate. With --force, any revisions we would have otherwise
3514 # way to the graftstate. With --force, any revisions we would have otherwise
3492 # skipped would not have been filtered out, and if they hadn't been applied
3515 # skipped would not have been filtered out, and if they hadn't been applied
3493 # already, they'd have been in the graftstate.
3516 # already, they'd have been in the graftstate.
3494 if not (cont or opts.get('force')):
3517 if not (cont or opts.get('force')):
3495 # check for ancestors of dest branch
3518 # check for ancestors of dest branch
3496 crev = repo['.'].rev()
3519 crev = repo['.'].rev()
3497 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3520 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3498 # Cannot use x.remove(y) on smart set, this has to be a list.
3521 # Cannot use x.remove(y) on smart set, this has to be a list.
3499 # XXX make this lazy in the future
3522 # XXX make this lazy in the future
3500 revs = list(revs)
3523 revs = list(revs)
3501 # don't mutate while iterating, create a copy
3524 # don't mutate while iterating, create a copy
3502 for rev in list(revs):
3525 for rev in list(revs):
3503 if rev in ancestors:
3526 if rev in ancestors:
3504 ui.warn(_('skipping ancestor revision %d:%s\n') %
3527 ui.warn(_('skipping ancestor revision %d:%s\n') %
3505 (rev, repo[rev]))
3528 (rev, repo[rev]))
3506 # XXX remove on list is slow
3529 # XXX remove on list is slow
3507 revs.remove(rev)
3530 revs.remove(rev)
3508 if not revs:
3531 if not revs:
3509 return -1
3532 return -1
3510
3533
3511 # analyze revs for earlier grafts
3534 # analyze revs for earlier grafts
3512 ids = {}
3535 ids = {}
3513 for ctx in repo.set("%ld", revs):
3536 for ctx in repo.set("%ld", revs):
3514 ids[ctx.hex()] = ctx.rev()
3537 ids[ctx.hex()] = ctx.rev()
3515 n = ctx.extra().get('source')
3538 n = ctx.extra().get('source')
3516 if n:
3539 if n:
3517 ids[n] = ctx.rev()
3540 ids[n] = ctx.rev()
3518
3541
3519 # check ancestors for earlier grafts
3542 # check ancestors for earlier grafts
3520 ui.debug('scanning for duplicate grafts\n')
3543 ui.debug('scanning for duplicate grafts\n')
3521
3544
3522 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3545 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3523 ctx = repo[rev]
3546 ctx = repo[rev]
3524 n = ctx.extra().get('source')
3547 n = ctx.extra().get('source')
3525 if n in ids:
3548 if n in ids:
3526 try:
3549 try:
3527 r = repo[n].rev()
3550 r = repo[n].rev()
3528 except error.RepoLookupError:
3551 except error.RepoLookupError:
3529 r = None
3552 r = None
3530 if r in revs:
3553 if r in revs:
3531 ui.warn(_('skipping revision %d:%s '
3554 ui.warn(_('skipping revision %d:%s '
3532 '(already grafted to %d:%s)\n')
3555 '(already grafted to %d:%s)\n')
3533 % (r, repo[r], rev, ctx))
3556 % (r, repo[r], rev, ctx))
3534 revs.remove(r)
3557 revs.remove(r)
3535 elif ids[n] in revs:
3558 elif ids[n] in revs:
3536 if r is None:
3559 if r is None:
3537 ui.warn(_('skipping already grafted revision %d:%s '
3560 ui.warn(_('skipping already grafted revision %d:%s '
3538 '(%d:%s also has unknown origin %s)\n')
3561 '(%d:%s also has unknown origin %s)\n')
3539 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3562 % (ids[n], repo[ids[n]], rev, ctx, n[:12]))
3540 else:
3563 else:
3541 ui.warn(_('skipping already grafted revision %d:%s '
3564 ui.warn(_('skipping already grafted revision %d:%s '
3542 '(%d:%s also has origin %d:%s)\n')
3565 '(%d:%s also has origin %d:%s)\n')
3543 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3566 % (ids[n], repo[ids[n]], rev, ctx, r, n[:12]))
3544 revs.remove(ids[n])
3567 revs.remove(ids[n])
3545 elif ctx.hex() in ids:
3568 elif ctx.hex() in ids:
3546 r = ids[ctx.hex()]
3569 r = ids[ctx.hex()]
3547 ui.warn(_('skipping already grafted revision %d:%s '
3570 ui.warn(_('skipping already grafted revision %d:%s '
3548 '(was grafted from %d:%s)\n') %
3571 '(was grafted from %d:%s)\n') %
3549 (r, repo[r], rev, ctx))
3572 (r, repo[r], rev, ctx))
3550 revs.remove(r)
3573 revs.remove(r)
3551 if not revs:
3574 if not revs:
3552 return -1
3575 return -1
3553
3576
3554 wlock = repo.wlock()
3577 wlock = repo.wlock()
3555 try:
3578 try:
3556 for pos, ctx in enumerate(repo.set("%ld", revs)):
3579 for pos, ctx in enumerate(repo.set("%ld", revs)):
3557 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3580 desc = '%d:%s "%s"' % (ctx.rev(), ctx,
3558 ctx.description().split('\n', 1)[0])
3581 ctx.description().split('\n', 1)[0])
3559 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3582 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
3560 if names:
3583 if names:
3561 desc += ' (%s)' % ' '.join(names)
3584 desc += ' (%s)' % ' '.join(names)
3562 ui.status(_('grafting %s\n') % desc)
3585 ui.status(_('grafting %s\n') % desc)
3563 if opts.get('dry_run'):
3586 if opts.get('dry_run'):
3564 continue
3587 continue
3565
3588
3566 source = ctx.extra().get('source')
3589 source = ctx.extra().get('source')
3567 extra = {}
3590 extra = {}
3568 if source:
3591 if source:
3569 extra['source'] = source
3592 extra['source'] = source
3570 extra['intermediate-source'] = ctx.hex()
3593 extra['intermediate-source'] = ctx.hex()
3571 else:
3594 else:
3572 extra['source'] = ctx.hex()
3595 extra['source'] = ctx.hex()
3573 user = ctx.user()
3596 user = ctx.user()
3574 if opts.get('user'):
3597 if opts.get('user'):
3575 user = opts['user']
3598 user = opts['user']
3576 date = ctx.date()
3599 date = ctx.date()
3577 if opts.get('date'):
3600 if opts.get('date'):
3578 date = opts['date']
3601 date = opts['date']
3579 message = ctx.description()
3602 message = ctx.description()
3580 if opts.get('log'):
3603 if opts.get('log'):
3581 message += '\n(grafted from %s)' % ctx.hex()
3604 message += '\n(grafted from %s)' % ctx.hex()
3582
3605
3583 # we don't merge the first commit when continuing
3606 # we don't merge the first commit when continuing
3584 if not cont:
3607 if not cont:
3585 # perform the graft merge with p1(rev) as 'ancestor'
3608 # perform the graft merge with p1(rev) as 'ancestor'
3586 try:
3609 try:
3587 # ui.forcemerge is an internal variable, do not document
3610 # ui.forcemerge is an internal variable, do not document
3588 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3611 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3589 'graft')
3612 'graft')
3590 stats = mergemod.graft(repo, ctx, ctx.p1(),
3613 stats = mergemod.graft(repo, ctx, ctx.p1(),
3591 ['local', 'graft'])
3614 ['local', 'graft'])
3592 finally:
3615 finally:
3593 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3616 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3594 # report any conflicts
3617 # report any conflicts
3595 if stats and stats[3] > 0:
3618 if stats and stats[3] > 0:
3596 # write out state for --continue
3619 # write out state for --continue
3597 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3620 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3598 repo.vfs.write('graftstate', ''.join(nodelines))
3621 repo.vfs.write('graftstate', ''.join(nodelines))
3599 raise util.Abort(
3622 raise util.Abort(
3600 _("unresolved conflicts, can't continue"),
3623 _("unresolved conflicts, can't continue"),
3601 hint=_('use hg resolve and hg graft --continue'))
3624 hint=_('use hg resolve and hg graft --continue'))
3602 else:
3625 else:
3603 cont = False
3626 cont = False
3604
3627
3605 # commit
3628 # commit
3606 node = repo.commit(text=message, user=user,
3629 node = repo.commit(text=message, user=user,
3607 date=date, extra=extra, editor=editor)
3630 date=date, extra=extra, editor=editor)
3608 if node is None:
3631 if node is None:
3609 ui.warn(
3632 ui.warn(
3610 _('note: graft of %d:%s created no changes to commit\n') %
3633 _('note: graft of %d:%s created no changes to commit\n') %
3611 (ctx.rev(), ctx))
3634 (ctx.rev(), ctx))
3612 finally:
3635 finally:
3613 wlock.release()
3636 wlock.release()
3614
3637
3615 # remove state when we complete successfully
3638 # remove state when we complete successfully
3616 if not opts.get('dry_run'):
3639 if not opts.get('dry_run'):
3617 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3640 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3618
3641
3619 return 0
3642 return 0
3620
3643
3621 @command('grep',
3644 @command('grep',
3622 [('0', 'print0', None, _('end fields with NUL')),
3645 [('0', 'print0', None, _('end fields with NUL')),
3623 ('', 'all', None, _('print all revisions that match')),
3646 ('', 'all', None, _('print all revisions that match')),
3624 ('a', 'text', None, _('treat all files as text')),
3647 ('a', 'text', None, _('treat all files as text')),
3625 ('f', 'follow', None,
3648 ('f', 'follow', None,
3626 _('follow changeset history,'
3649 _('follow changeset history,'
3627 ' or file history across copies and renames')),
3650 ' or file history across copies and renames')),
3628 ('i', 'ignore-case', None, _('ignore case when matching')),
3651 ('i', 'ignore-case', None, _('ignore case when matching')),
3629 ('l', 'files-with-matches', None,
3652 ('l', 'files-with-matches', None,
3630 _('print only filenames and revisions that match')),
3653 _('print only filenames and revisions that match')),
3631 ('n', 'line-number', None, _('print matching line numbers')),
3654 ('n', 'line-number', None, _('print matching line numbers')),
3632 ('r', 'rev', [],
3655 ('r', 'rev', [],
3633 _('only search files changed within revision range'), _('REV')),
3656 _('only search files changed within revision range'), _('REV')),
3634 ('u', 'user', None, _('list the author (long with -v)')),
3657 ('u', 'user', None, _('list the author (long with -v)')),
3635 ('d', 'date', None, _('list the date (short with -q)')),
3658 ('d', 'date', None, _('list the date (short with -q)')),
3636 ] + walkopts,
3659 ] + walkopts,
3637 _('[OPTION]... PATTERN [FILE]...'),
3660 _('[OPTION]... PATTERN [FILE]...'),
3638 inferrepo=True)
3661 inferrepo=True)
3639 def grep(ui, repo, pattern, *pats, **opts):
3662 def grep(ui, repo, pattern, *pats, **opts):
3640 """search for a pattern in specified files and revisions
3663 """search for a pattern in specified files and revisions
3641
3664
3642 Search revisions of files for a regular expression.
3665 Search revisions of files for a regular expression.
3643
3666
3644 This command behaves differently than Unix grep. It only accepts
3667 This command behaves differently than Unix grep. It only accepts
3645 Python/Perl regexps. It searches repository history, not the
3668 Python/Perl regexps. It searches repository history, not the
3646 working directory. It always prints the revision number in which a
3669 working directory. It always prints the revision number in which a
3647 match appears.
3670 match appears.
3648
3671
3649 By default, grep only prints output for the first revision of a
3672 By default, grep only prints output for the first revision of a
3650 file in which it finds a match. To get it to print every revision
3673 file in which it finds a match. To get it to print every revision
3651 that contains a change in match status ("-" for a match that
3674 that contains a change in match status ("-" for a match that
3652 becomes a non-match, or "+" for a non-match that becomes a match),
3675 becomes a non-match, or "+" for a non-match that becomes a match),
3653 use the --all flag.
3676 use the --all flag.
3654
3677
3655 Returns 0 if a match is found, 1 otherwise.
3678 Returns 0 if a match is found, 1 otherwise.
3656 """
3679 """
3657 reflags = re.M
3680 reflags = re.M
3658 if opts.get('ignore_case'):
3681 if opts.get('ignore_case'):
3659 reflags |= re.I
3682 reflags |= re.I
3660 try:
3683 try:
3661 regexp = util.re.compile(pattern, reflags)
3684 regexp = util.re.compile(pattern, reflags)
3662 except re.error as inst:
3685 except re.error as inst:
3663 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3686 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3664 return 1
3687 return 1
3665 sep, eol = ':', '\n'
3688 sep, eol = ':', '\n'
3666 if opts.get('print0'):
3689 if opts.get('print0'):
3667 sep = eol = '\0'
3690 sep = eol = '\0'
3668
3691
3669 getfile = util.lrucachefunc(repo.file)
3692 getfile = util.lrucachefunc(repo.file)
3670
3693
3671 def matchlines(body):
3694 def matchlines(body):
3672 begin = 0
3695 begin = 0
3673 linenum = 0
3696 linenum = 0
3674 while begin < len(body):
3697 while begin < len(body):
3675 match = regexp.search(body, begin)
3698 match = regexp.search(body, begin)
3676 if not match:
3699 if not match:
3677 break
3700 break
3678 mstart, mend = match.span()
3701 mstart, mend = match.span()
3679 linenum += body.count('\n', begin, mstart) + 1
3702 linenum += body.count('\n', begin, mstart) + 1
3680 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3703 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3681 begin = body.find('\n', mend) + 1 or len(body) + 1
3704 begin = body.find('\n', mend) + 1 or len(body) + 1
3682 lend = begin - 1
3705 lend = begin - 1
3683 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3706 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3684
3707
3685 class linestate(object):
3708 class linestate(object):
3686 def __init__(self, line, linenum, colstart, colend):
3709 def __init__(self, line, linenum, colstart, colend):
3687 self.line = line
3710 self.line = line
3688 self.linenum = linenum
3711 self.linenum = linenum
3689 self.colstart = colstart
3712 self.colstart = colstart
3690 self.colend = colend
3713 self.colend = colend
3691
3714
3692 def __hash__(self):
3715 def __hash__(self):
3693 return hash((self.linenum, self.line))
3716 return hash((self.linenum, self.line))
3694
3717
3695 def __eq__(self, other):
3718 def __eq__(self, other):
3696 return self.line == other.line
3719 return self.line == other.line
3697
3720
3698 def __iter__(self):
3721 def __iter__(self):
3699 yield (self.line[:self.colstart], '')
3722 yield (self.line[:self.colstart], '')
3700 yield (self.line[self.colstart:self.colend], 'grep.match')
3723 yield (self.line[self.colstart:self.colend], 'grep.match')
3701 rest = self.line[self.colend:]
3724 rest = self.line[self.colend:]
3702 while rest != '':
3725 while rest != '':
3703 match = regexp.search(rest)
3726 match = regexp.search(rest)
3704 if not match:
3727 if not match:
3705 yield (rest, '')
3728 yield (rest, '')
3706 break
3729 break
3707 mstart, mend = match.span()
3730 mstart, mend = match.span()
3708 yield (rest[:mstart], '')
3731 yield (rest[:mstart], '')
3709 yield (rest[mstart:mend], 'grep.match')
3732 yield (rest[mstart:mend], 'grep.match')
3710 rest = rest[mend:]
3733 rest = rest[mend:]
3711
3734
3712 matches = {}
3735 matches = {}
3713 copies = {}
3736 copies = {}
3714 def grepbody(fn, rev, body):
3737 def grepbody(fn, rev, body):
3715 matches[rev].setdefault(fn, [])
3738 matches[rev].setdefault(fn, [])
3716 m = matches[rev][fn]
3739 m = matches[rev][fn]
3717 for lnum, cstart, cend, line in matchlines(body):
3740 for lnum, cstart, cend, line in matchlines(body):
3718 s = linestate(line, lnum, cstart, cend)
3741 s = linestate(line, lnum, cstart, cend)
3719 m.append(s)
3742 m.append(s)
3720
3743
3721 def difflinestates(a, b):
3744 def difflinestates(a, b):
3722 sm = difflib.SequenceMatcher(None, a, b)
3745 sm = difflib.SequenceMatcher(None, a, b)
3723 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3746 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3724 if tag == 'insert':
3747 if tag == 'insert':
3725 for i in xrange(blo, bhi):
3748 for i in xrange(blo, bhi):
3726 yield ('+', b[i])
3749 yield ('+', b[i])
3727 elif tag == 'delete':
3750 elif tag == 'delete':
3728 for i in xrange(alo, ahi):
3751 for i in xrange(alo, ahi):
3729 yield ('-', a[i])
3752 yield ('-', a[i])
3730 elif tag == 'replace':
3753 elif tag == 'replace':
3731 for i in xrange(alo, ahi):
3754 for i in xrange(alo, ahi):
3732 yield ('-', a[i])
3755 yield ('-', a[i])
3733 for i in xrange(blo, bhi):
3756 for i in xrange(blo, bhi):
3734 yield ('+', b[i])
3757 yield ('+', b[i])
3735
3758
3736 def display(fn, ctx, pstates, states):
3759 def display(fn, ctx, pstates, states):
3737 rev = ctx.rev()
3760 rev = ctx.rev()
3738 if ui.quiet:
3761 if ui.quiet:
3739 datefunc = util.shortdate
3762 datefunc = util.shortdate
3740 else:
3763 else:
3741 datefunc = util.datestr
3764 datefunc = util.datestr
3742 found = False
3765 found = False
3743 @util.cachefunc
3766 @util.cachefunc
3744 def binary():
3767 def binary():
3745 flog = getfile(fn)
3768 flog = getfile(fn)
3746 return util.binary(flog.read(ctx.filenode(fn)))
3769 return util.binary(flog.read(ctx.filenode(fn)))
3747
3770
3748 if opts.get('all'):
3771 if opts.get('all'):
3749 iter = difflinestates(pstates, states)
3772 iter = difflinestates(pstates, states)
3750 else:
3773 else:
3751 iter = [('', l) for l in states]
3774 iter = [('', l) for l in states]
3752 for change, l in iter:
3775 for change, l in iter:
3753 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3776 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3754
3777
3755 if opts.get('line_number'):
3778 if opts.get('line_number'):
3756 cols.append((str(l.linenum), 'grep.linenumber'))
3779 cols.append((str(l.linenum), 'grep.linenumber'))
3757 if opts.get('all'):
3780 if opts.get('all'):
3758 cols.append((change, 'grep.change'))
3781 cols.append((change, 'grep.change'))
3759 if opts.get('user'):
3782 if opts.get('user'):
3760 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3783 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3761 if opts.get('date'):
3784 if opts.get('date'):
3762 cols.append((datefunc(ctx.date()), 'grep.date'))
3785 cols.append((datefunc(ctx.date()), 'grep.date'))
3763 for col, label in cols[:-1]:
3786 for col, label in cols[:-1]:
3764 ui.write(col, label=label)
3787 ui.write(col, label=label)
3765 ui.write(sep, label='grep.sep')
3788 ui.write(sep, label='grep.sep')
3766 ui.write(cols[-1][0], label=cols[-1][1])
3789 ui.write(cols[-1][0], label=cols[-1][1])
3767 if not opts.get('files_with_matches'):
3790 if not opts.get('files_with_matches'):
3768 ui.write(sep, label='grep.sep')
3791 ui.write(sep, label='grep.sep')
3769 if not opts.get('text') and binary():
3792 if not opts.get('text') and binary():
3770 ui.write(" Binary file matches")
3793 ui.write(" Binary file matches")
3771 else:
3794 else:
3772 for s, label in l:
3795 for s, label in l:
3773 ui.write(s, label=label)
3796 ui.write(s, label=label)
3774 ui.write(eol)
3797 ui.write(eol)
3775 found = True
3798 found = True
3776 if opts.get('files_with_matches'):
3799 if opts.get('files_with_matches'):
3777 break
3800 break
3778 return found
3801 return found
3779
3802
3780 skip = {}
3803 skip = {}
3781 revfiles = {}
3804 revfiles = {}
3782 matchfn = scmutil.match(repo[None], pats, opts)
3805 matchfn = scmutil.match(repo[None], pats, opts)
3783 found = False
3806 found = False
3784 follow = opts.get('follow')
3807 follow = opts.get('follow')
3785
3808
3786 def prep(ctx, fns):
3809 def prep(ctx, fns):
3787 rev = ctx.rev()
3810 rev = ctx.rev()
3788 pctx = ctx.p1()
3811 pctx = ctx.p1()
3789 parent = pctx.rev()
3812 parent = pctx.rev()
3790 matches.setdefault(rev, {})
3813 matches.setdefault(rev, {})
3791 matches.setdefault(parent, {})
3814 matches.setdefault(parent, {})
3792 files = revfiles.setdefault(rev, [])
3815 files = revfiles.setdefault(rev, [])
3793 for fn in fns:
3816 for fn in fns:
3794 flog = getfile(fn)
3817 flog = getfile(fn)
3795 try:
3818 try:
3796 fnode = ctx.filenode(fn)
3819 fnode = ctx.filenode(fn)
3797 except error.LookupError:
3820 except error.LookupError:
3798 continue
3821 continue
3799
3822
3800 copied = flog.renamed(fnode)
3823 copied = flog.renamed(fnode)
3801 copy = follow and copied and copied[0]
3824 copy = follow and copied and copied[0]
3802 if copy:
3825 if copy:
3803 copies.setdefault(rev, {})[fn] = copy
3826 copies.setdefault(rev, {})[fn] = copy
3804 if fn in skip:
3827 if fn in skip:
3805 if copy:
3828 if copy:
3806 skip[copy] = True
3829 skip[copy] = True
3807 continue
3830 continue
3808 files.append(fn)
3831 files.append(fn)
3809
3832
3810 if fn not in matches[rev]:
3833 if fn not in matches[rev]:
3811 grepbody(fn, rev, flog.read(fnode))
3834 grepbody(fn, rev, flog.read(fnode))
3812
3835
3813 pfn = copy or fn
3836 pfn = copy or fn
3814 if pfn not in matches[parent]:
3837 if pfn not in matches[parent]:
3815 try:
3838 try:
3816 fnode = pctx.filenode(pfn)
3839 fnode = pctx.filenode(pfn)
3817 grepbody(pfn, parent, flog.read(fnode))
3840 grepbody(pfn, parent, flog.read(fnode))
3818 except error.LookupError:
3841 except error.LookupError:
3819 pass
3842 pass
3820
3843
3821 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3844 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3822 rev = ctx.rev()
3845 rev = ctx.rev()
3823 parent = ctx.p1().rev()
3846 parent = ctx.p1().rev()
3824 for fn in sorted(revfiles.get(rev, [])):
3847 for fn in sorted(revfiles.get(rev, [])):
3825 states = matches[rev][fn]
3848 states = matches[rev][fn]
3826 copy = copies.get(rev, {}).get(fn)
3849 copy = copies.get(rev, {}).get(fn)
3827 if fn in skip:
3850 if fn in skip:
3828 if copy:
3851 if copy:
3829 skip[copy] = True
3852 skip[copy] = True
3830 continue
3853 continue
3831 pstates = matches.get(parent, {}).get(copy or fn, [])
3854 pstates = matches.get(parent, {}).get(copy or fn, [])
3832 if pstates or states:
3855 if pstates or states:
3833 r = display(fn, ctx, pstates, states)
3856 r = display(fn, ctx, pstates, states)
3834 found = found or r
3857 found = found or r
3835 if r and not opts.get('all'):
3858 if r and not opts.get('all'):
3836 skip[fn] = True
3859 skip[fn] = True
3837 if copy:
3860 if copy:
3838 skip[copy] = True
3861 skip[copy] = True
3839 del matches[rev]
3862 del matches[rev]
3840 del revfiles[rev]
3863 del revfiles[rev]
3841
3864
3842 return not found
3865 return not found
3843
3866
3844 @command('heads',
3867 @command('heads',
3845 [('r', 'rev', '',
3868 [('r', 'rev', '',
3846 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3869 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3847 ('t', 'topo', False, _('show topological heads only')),
3870 ('t', 'topo', False, _('show topological heads only')),
3848 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3871 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3849 ('c', 'closed', False, _('show normal and closed branch heads')),
3872 ('c', 'closed', False, _('show normal and closed branch heads')),
3850 ] + templateopts,
3873 ] + templateopts,
3851 _('[-ct] [-r STARTREV] [REV]...'))
3874 _('[-ct] [-r STARTREV] [REV]...'))
3852 def heads(ui, repo, *branchrevs, **opts):
3875 def heads(ui, repo, *branchrevs, **opts):
3853 """show branch heads
3876 """show branch heads
3854
3877
3855 With no arguments, show all open branch heads in the repository.
3878 With no arguments, show all open branch heads in the repository.
3856 Branch heads are changesets that have no descendants on the
3879 Branch heads are changesets that have no descendants on the
3857 same branch. They are where development generally takes place and
3880 same branch. They are where development generally takes place and
3858 are the usual targets for update and merge operations.
3881 are the usual targets for update and merge operations.
3859
3882
3860 If one or more REVs are given, only open branch heads on the
3883 If one or more REVs are given, only open branch heads on the
3861 branches associated with the specified changesets are shown. This
3884 branches associated with the specified changesets are shown. This
3862 means that you can use :hg:`heads .` to see the heads on the
3885 means that you can use :hg:`heads .` to see the heads on the
3863 currently checked-out branch.
3886 currently checked-out branch.
3864
3887
3865 If -c/--closed is specified, also show branch heads marked closed
3888 If -c/--closed is specified, also show branch heads marked closed
3866 (see :hg:`commit --close-branch`).
3889 (see :hg:`commit --close-branch`).
3867
3890
3868 If STARTREV is specified, only those heads that are descendants of
3891 If STARTREV is specified, only those heads that are descendants of
3869 STARTREV will be displayed.
3892 STARTREV will be displayed.
3870
3893
3871 If -t/--topo is specified, named branch mechanics will be ignored and only
3894 If -t/--topo is specified, named branch mechanics will be ignored and only
3872 topological heads (changesets with no children) will be shown.
3895 topological heads (changesets with no children) will be shown.
3873
3896
3874 Returns 0 if matching heads are found, 1 if not.
3897 Returns 0 if matching heads are found, 1 if not.
3875 """
3898 """
3876
3899
3877 start = None
3900 start = None
3878 if 'rev' in opts:
3901 if 'rev' in opts:
3879 start = scmutil.revsingle(repo, opts['rev'], None).node()
3902 start = scmutil.revsingle(repo, opts['rev'], None).node()
3880
3903
3881 if opts.get('topo'):
3904 if opts.get('topo'):
3882 heads = [repo[h] for h in repo.heads(start)]
3905 heads = [repo[h] for h in repo.heads(start)]
3883 else:
3906 else:
3884 heads = []
3907 heads = []
3885 for branch in repo.branchmap():
3908 for branch in repo.branchmap():
3886 heads += repo.branchheads(branch, start, opts.get('closed'))
3909 heads += repo.branchheads(branch, start, opts.get('closed'))
3887 heads = [repo[h] for h in heads]
3910 heads = [repo[h] for h in heads]
3888
3911
3889 if branchrevs:
3912 if branchrevs:
3890 branches = set(repo[br].branch() for br in branchrevs)
3913 branches = set(repo[br].branch() for br in branchrevs)
3891 heads = [h for h in heads if h.branch() in branches]
3914 heads = [h for h in heads if h.branch() in branches]
3892
3915
3893 if opts.get('active') and branchrevs:
3916 if opts.get('active') and branchrevs:
3894 dagheads = repo.heads(start)
3917 dagheads = repo.heads(start)
3895 heads = [h for h in heads if h.node() in dagheads]
3918 heads = [h for h in heads if h.node() in dagheads]
3896
3919
3897 if branchrevs:
3920 if branchrevs:
3898 haveheads = set(h.branch() for h in heads)
3921 haveheads = set(h.branch() for h in heads)
3899 if branches - haveheads:
3922 if branches - haveheads:
3900 headless = ', '.join(b for b in branches - haveheads)
3923 headless = ', '.join(b for b in branches - haveheads)
3901 msg = _('no open branch heads found on branches %s')
3924 msg = _('no open branch heads found on branches %s')
3902 if opts.get('rev'):
3925 if opts.get('rev'):
3903 msg += _(' (started at %s)') % opts['rev']
3926 msg += _(' (started at %s)') % opts['rev']
3904 ui.warn((msg + '\n') % headless)
3927 ui.warn((msg + '\n') % headless)
3905
3928
3906 if not heads:
3929 if not heads:
3907 return 1
3930 return 1
3908
3931
3909 heads = sorted(heads, key=lambda x: -x.rev())
3932 heads = sorted(heads, key=lambda x: -x.rev())
3910 displayer = cmdutil.show_changeset(ui, repo, opts)
3933 displayer = cmdutil.show_changeset(ui, repo, opts)
3911 for ctx in heads:
3934 for ctx in heads:
3912 displayer.show(ctx)
3935 displayer.show(ctx)
3913 displayer.close()
3936 displayer.close()
3914
3937
3915 @command('help',
3938 @command('help',
3916 [('e', 'extension', None, _('show only help for extensions')),
3939 [('e', 'extension', None, _('show only help for extensions')),
3917 ('c', 'command', None, _('show only help for commands')),
3940 ('c', 'command', None, _('show only help for commands')),
3918 ('k', 'keyword', '', _('show topics matching keyword')),
3941 ('k', 'keyword', '', _('show topics matching keyword')),
3919 ],
3942 ],
3920 _('[-ec] [TOPIC]'),
3943 _('[-ec] [TOPIC]'),
3921 norepo=True)
3944 norepo=True)
3922 def help_(ui, name=None, **opts):
3945 def help_(ui, name=None, **opts):
3923 """show help for a given topic or a help overview
3946 """show help for a given topic or a help overview
3924
3947
3925 With no arguments, print a list of commands with short help messages.
3948 With no arguments, print a list of commands with short help messages.
3926
3949
3927 Given a topic, extension, or command name, print help for that
3950 Given a topic, extension, or command name, print help for that
3928 topic.
3951 topic.
3929
3952
3930 Returns 0 if successful.
3953 Returns 0 if successful.
3931 """
3954 """
3932
3955
3933 textwidth = min(ui.termwidth(), 80) - 2
3956 textwidth = min(ui.termwidth(), 80) - 2
3934
3957
3935 keep = []
3958 keep = []
3936 if ui.verbose:
3959 if ui.verbose:
3937 keep.append('verbose')
3960 keep.append('verbose')
3938 if sys.platform.startswith('win'):
3961 if sys.platform.startswith('win'):
3939 keep.append('windows')
3962 keep.append('windows')
3940 elif sys.platform == 'OpenVMS':
3963 elif sys.platform == 'OpenVMS':
3941 keep.append('vms')
3964 keep.append('vms')
3942 elif sys.platform == 'plan9':
3965 elif sys.platform == 'plan9':
3943 keep.append('plan9')
3966 keep.append('plan9')
3944 else:
3967 else:
3945 keep.append('unix')
3968 keep.append('unix')
3946 keep.append(sys.platform.lower())
3969 keep.append(sys.platform.lower())
3947
3970
3948 section = None
3971 section = None
3949 if name and '.' in name:
3972 if name and '.' in name:
3950 name, section = name.split('.', 1)
3973 name, section = name.split('.', 1)
3951
3974
3952 text = help.help_(ui, name, **opts)
3975 text = help.help_(ui, name, **opts)
3953
3976
3954 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3977 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3955 section=section)
3978 section=section)
3956 if section and not formatted:
3979 if section and not formatted:
3957 raise util.Abort(_("help section not found"))
3980 raise util.Abort(_("help section not found"))
3958
3981
3959 if 'verbose' in pruned:
3982 if 'verbose' in pruned:
3960 keep.append('omitted')
3983 keep.append('omitted')
3961 else:
3984 else:
3962 keep.append('notomitted')
3985 keep.append('notomitted')
3963 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3986 formatted, pruned = minirst.format(text, textwidth, keep=keep,
3964 section=section)
3987 section=section)
3965 ui.write(formatted)
3988 ui.write(formatted)
3966
3989
3967
3990
3968 @command('identify|id',
3991 @command('identify|id',
3969 [('r', 'rev', '',
3992 [('r', 'rev', '',
3970 _('identify the specified revision'), _('REV')),
3993 _('identify the specified revision'), _('REV')),
3971 ('n', 'num', None, _('show local revision number')),
3994 ('n', 'num', None, _('show local revision number')),
3972 ('i', 'id', None, _('show global revision id')),
3995 ('i', 'id', None, _('show global revision id')),
3973 ('b', 'branch', None, _('show branch')),
3996 ('b', 'branch', None, _('show branch')),
3974 ('t', 'tags', None, _('show tags')),
3997 ('t', 'tags', None, _('show tags')),
3975 ('B', 'bookmarks', None, _('show bookmarks')),
3998 ('B', 'bookmarks', None, _('show bookmarks')),
3976 ] + remoteopts,
3999 ] + remoteopts,
3977 _('[-nibtB] [-r REV] [SOURCE]'),
4000 _('[-nibtB] [-r REV] [SOURCE]'),
3978 optionalrepo=True)
4001 optionalrepo=True)
3979 def identify(ui, repo, source=None, rev=None,
4002 def identify(ui, repo, source=None, rev=None,
3980 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
4003 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3981 """identify the working directory or specified revision
4004 """identify the working directory or specified revision
3982
4005
3983 Print a summary identifying the repository state at REV using one or
4006 Print a summary identifying the repository state at REV using one or
3984 two parent hash identifiers, followed by a "+" if the working
4007 two parent hash identifiers, followed by a "+" if the working
3985 directory has uncommitted changes, the branch name (if not default),
4008 directory has uncommitted changes, the branch name (if not default),
3986 a list of tags, and a list of bookmarks.
4009 a list of tags, and a list of bookmarks.
3987
4010
3988 When REV is not given, print a summary of the current state of the
4011 When REV is not given, print a summary of the current state of the
3989 repository.
4012 repository.
3990
4013
3991 Specifying a path to a repository root or Mercurial bundle will
4014 Specifying a path to a repository root or Mercurial bundle will
3992 cause lookup to operate on that repository/bundle.
4015 cause lookup to operate on that repository/bundle.
3993
4016
3994 .. container:: verbose
4017 .. container:: verbose
3995
4018
3996 Examples:
4019 Examples:
3997
4020
3998 - generate a build identifier for the working directory::
4021 - generate a build identifier for the working directory::
3999
4022
4000 hg id --id > build-id.dat
4023 hg id --id > build-id.dat
4001
4024
4002 - find the revision corresponding to a tag::
4025 - find the revision corresponding to a tag::
4003
4026
4004 hg id -n -r 1.3
4027 hg id -n -r 1.3
4005
4028
4006 - check the most recent revision of a remote repository::
4029 - check the most recent revision of a remote repository::
4007
4030
4008 hg id -r tip http://selenic.com/hg/
4031 hg id -r tip http://selenic.com/hg/
4009
4032
4010 Returns 0 if successful.
4033 Returns 0 if successful.
4011 """
4034 """
4012
4035
4013 if not repo and not source:
4036 if not repo and not source:
4014 raise util.Abort(_("there is no Mercurial repository here "
4037 raise util.Abort(_("there is no Mercurial repository here "
4015 "(.hg not found)"))
4038 "(.hg not found)"))
4016
4039
4017 if ui.debugflag:
4040 if ui.debugflag:
4018 hexfunc = hex
4041 hexfunc = hex
4019 else:
4042 else:
4020 hexfunc = short
4043 hexfunc = short
4021 default = not (num or id or branch or tags or bookmarks)
4044 default = not (num or id or branch or tags or bookmarks)
4022 output = []
4045 output = []
4023 revs = []
4046 revs = []
4024
4047
4025 if source:
4048 if source:
4026 source, branches = hg.parseurl(ui.expandpath(source))
4049 source, branches = hg.parseurl(ui.expandpath(source))
4027 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4050 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
4028 repo = peer.local()
4051 repo = peer.local()
4029 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4052 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
4030
4053
4031 if not repo:
4054 if not repo:
4032 if num or branch or tags:
4055 if num or branch or tags:
4033 raise util.Abort(
4056 raise util.Abort(
4034 _("can't query remote revision number, branch, or tags"))
4057 _("can't query remote revision number, branch, or tags"))
4035 if not rev and revs:
4058 if not rev and revs:
4036 rev = revs[0]
4059 rev = revs[0]
4037 if not rev:
4060 if not rev:
4038 rev = "tip"
4061 rev = "tip"
4039
4062
4040 remoterev = peer.lookup(rev)
4063 remoterev = peer.lookup(rev)
4041 if default or id:
4064 if default or id:
4042 output = [hexfunc(remoterev)]
4065 output = [hexfunc(remoterev)]
4043
4066
4044 def getbms():
4067 def getbms():
4045 bms = []
4068 bms = []
4046
4069
4047 if 'bookmarks' in peer.listkeys('namespaces'):
4070 if 'bookmarks' in peer.listkeys('namespaces'):
4048 hexremoterev = hex(remoterev)
4071 hexremoterev = hex(remoterev)
4049 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4072 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
4050 if bmr == hexremoterev]
4073 if bmr == hexremoterev]
4051
4074
4052 return sorted(bms)
4075 return sorted(bms)
4053
4076
4054 if bookmarks:
4077 if bookmarks:
4055 output.extend(getbms())
4078 output.extend(getbms())
4056 elif default and not ui.quiet:
4079 elif default and not ui.quiet:
4057 # multiple bookmarks for a single parent separated by '/'
4080 # multiple bookmarks for a single parent separated by '/'
4058 bm = '/'.join(getbms())
4081 bm = '/'.join(getbms())
4059 if bm:
4082 if bm:
4060 output.append(bm)
4083 output.append(bm)
4061 else:
4084 else:
4062 ctx = scmutil.revsingle(repo, rev, None)
4085 ctx = scmutil.revsingle(repo, rev, None)
4063
4086
4064 if ctx.rev() is None:
4087 if ctx.rev() is None:
4065 ctx = repo[None]
4088 ctx = repo[None]
4066 parents = ctx.parents()
4089 parents = ctx.parents()
4067 taglist = []
4090 taglist = []
4068 for p in parents:
4091 for p in parents:
4069 taglist.extend(p.tags())
4092 taglist.extend(p.tags())
4070
4093
4071 changed = ""
4094 changed = ""
4072 if default or id or num:
4095 if default or id or num:
4073 if (any(repo.status())
4096 if (any(repo.status())
4074 or any(ctx.sub(s).dirty() for s in ctx.substate)):
4097 or any(ctx.sub(s).dirty() for s in ctx.substate)):
4075 changed = '+'
4098 changed = '+'
4076 if default or id:
4099 if default or id:
4077 output = ["%s%s" %
4100 output = ["%s%s" %
4078 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4101 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
4079 if num:
4102 if num:
4080 output.append("%s%s" %
4103 output.append("%s%s" %
4081 ('+'.join([str(p.rev()) for p in parents]), changed))
4104 ('+'.join([str(p.rev()) for p in parents]), changed))
4082 else:
4105 else:
4083 if default or id:
4106 if default or id:
4084 output = [hexfunc(ctx.node())]
4107 output = [hexfunc(ctx.node())]
4085 if num:
4108 if num:
4086 output.append(str(ctx.rev()))
4109 output.append(str(ctx.rev()))
4087 taglist = ctx.tags()
4110 taglist = ctx.tags()
4088
4111
4089 if default and not ui.quiet:
4112 if default and not ui.quiet:
4090 b = ctx.branch()
4113 b = ctx.branch()
4091 if b != 'default':
4114 if b != 'default':
4092 output.append("(%s)" % b)
4115 output.append("(%s)" % b)
4093
4116
4094 # multiple tags for a single parent separated by '/'
4117 # multiple tags for a single parent separated by '/'
4095 t = '/'.join(taglist)
4118 t = '/'.join(taglist)
4096 if t:
4119 if t:
4097 output.append(t)
4120 output.append(t)
4098
4121
4099 # multiple bookmarks for a single parent separated by '/'
4122 # multiple bookmarks for a single parent separated by '/'
4100 bm = '/'.join(ctx.bookmarks())
4123 bm = '/'.join(ctx.bookmarks())
4101 if bm:
4124 if bm:
4102 output.append(bm)
4125 output.append(bm)
4103 else:
4126 else:
4104 if branch:
4127 if branch:
4105 output.append(ctx.branch())
4128 output.append(ctx.branch())
4106
4129
4107 if tags:
4130 if tags:
4108 output.extend(taglist)
4131 output.extend(taglist)
4109
4132
4110 if bookmarks:
4133 if bookmarks:
4111 output.extend(ctx.bookmarks())
4134 output.extend(ctx.bookmarks())
4112
4135
4113 ui.write("%s\n" % ' '.join(output))
4136 ui.write("%s\n" % ' '.join(output))
4114
4137
4115 @command('import|patch',
4138 @command('import|patch',
4116 [('p', 'strip', 1,
4139 [('p', 'strip', 1,
4117 _('directory strip option for patch. This has the same '
4140 _('directory strip option for patch. This has the same '
4118 'meaning as the corresponding patch option'), _('NUM')),
4141 'meaning as the corresponding patch option'), _('NUM')),
4119 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4142 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
4120 ('e', 'edit', False, _('invoke editor on commit messages')),
4143 ('e', 'edit', False, _('invoke editor on commit messages')),
4121 ('f', 'force', None,
4144 ('f', 'force', None,
4122 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4145 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
4123 ('', 'no-commit', None,
4146 ('', 'no-commit', None,
4124 _("don't commit, just update the working directory")),
4147 _("don't commit, just update the working directory")),
4125 ('', 'bypass', None,
4148 ('', 'bypass', None,
4126 _("apply patch without touching the working directory")),
4149 _("apply patch without touching the working directory")),
4127 ('', 'partial', None,
4150 ('', 'partial', None,
4128 _('commit even if some hunks fail')),
4151 _('commit even if some hunks fail')),
4129 ('', 'exact', None,
4152 ('', 'exact', None,
4130 _('apply patch to the nodes from which it was generated')),
4153 _('apply patch to the nodes from which it was generated')),
4131 ('', 'prefix', '',
4154 ('', 'prefix', '',
4132 _('apply patch to subdirectory'), _('DIR')),
4155 _('apply patch to subdirectory'), _('DIR')),
4133 ('', 'import-branch', None,
4156 ('', 'import-branch', None,
4134 _('use any branch information in patch (implied by --exact)'))] +
4157 _('use any branch information in patch (implied by --exact)'))] +
4135 commitopts + commitopts2 + similarityopts,
4158 commitopts + commitopts2 + similarityopts,
4136 _('[OPTION]... PATCH...'))
4159 _('[OPTION]... PATCH...'))
4137 def import_(ui, repo, patch1=None, *patches, **opts):
4160 def import_(ui, repo, patch1=None, *patches, **opts):
4138 """import an ordered set of patches
4161 """import an ordered set of patches
4139
4162
4140 Import a list of patches and commit them individually (unless
4163 Import a list of patches and commit them individually (unless
4141 --no-commit is specified).
4164 --no-commit is specified).
4142
4165
4143 Because import first applies changes to the working directory,
4166 Because import first applies changes to the working directory,
4144 import will abort if there are outstanding changes.
4167 import will abort if there are outstanding changes.
4145
4168
4146 You can import a patch straight from a mail message. Even patches
4169 You can import a patch straight from a mail message. Even patches
4147 as attachments work (to use the body part, it must have type
4170 as attachments work (to use the body part, it must have type
4148 text/plain or text/x-patch). From and Subject headers of email
4171 text/plain or text/x-patch). From and Subject headers of email
4149 message are used as default committer and commit message. All
4172 message are used as default committer and commit message. All
4150 text/plain body parts before first diff are added to commit
4173 text/plain body parts before first diff are added to commit
4151 message.
4174 message.
4152
4175
4153 If the imported patch was generated by :hg:`export`, user and
4176 If the imported patch was generated by :hg:`export`, user and
4154 description from patch override values from message headers and
4177 description from patch override values from message headers and
4155 body. Values given on command line with -m/--message and -u/--user
4178 body. Values given on command line with -m/--message and -u/--user
4156 override these.
4179 override these.
4157
4180
4158 If --exact is specified, import will set the working directory to
4181 If --exact is specified, import will set the working directory to
4159 the parent of each patch before applying it, and will abort if the
4182 the parent of each patch before applying it, and will abort if the
4160 resulting changeset has a different ID than the one recorded in
4183 resulting changeset has a different ID than the one recorded in
4161 the patch. This may happen due to character set problems or other
4184 the patch. This may happen due to character set problems or other
4162 deficiencies in the text patch format.
4185 deficiencies in the text patch format.
4163
4186
4164 Use --bypass to apply and commit patches directly to the
4187 Use --bypass to apply and commit patches directly to the
4165 repository, not touching the working directory. Without --exact,
4188 repository, not touching the working directory. Without --exact,
4166 patches will be applied on top of the working directory parent
4189 patches will be applied on top of the working directory parent
4167 revision.
4190 revision.
4168
4191
4169 With -s/--similarity, hg will attempt to discover renames and
4192 With -s/--similarity, hg will attempt to discover renames and
4170 copies in the patch in the same way as :hg:`addremove`.
4193 copies in the patch in the same way as :hg:`addremove`.
4171
4194
4172 Use --partial to ensure a changeset will be created from the patch
4195 Use --partial to ensure a changeset will be created from the patch
4173 even if some hunks fail to apply. Hunks that fail to apply will be
4196 even if some hunks fail to apply. Hunks that fail to apply will be
4174 written to a <target-file>.rej file. Conflicts can then be resolved
4197 written to a <target-file>.rej file. Conflicts can then be resolved
4175 by hand before :hg:`commit --amend` is run to update the created
4198 by hand before :hg:`commit --amend` is run to update the created
4176 changeset. This flag exists to let people import patches that
4199 changeset. This flag exists to let people import patches that
4177 partially apply without losing the associated metadata (author,
4200 partially apply without losing the associated metadata (author,
4178 date, description, ...). Note that when none of the hunk applies
4201 date, description, ...). Note that when none of the hunk applies
4179 cleanly, :hg:`import --partial` will create an empty changeset,
4202 cleanly, :hg:`import --partial` will create an empty changeset,
4180 importing only the patch metadata.
4203 importing only the patch metadata.
4181
4204
4182 It is possible to use external patch programs to perform the patch
4205 It is possible to use external patch programs to perform the patch
4183 by setting the ``ui.patch`` configuration option. For the default
4206 by setting the ``ui.patch`` configuration option. For the default
4184 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4207 internal tool, the fuzz can also be configured via ``patch.fuzz``.
4185 See :hg:`help config` for more information about configuration
4208 See :hg:`help config` for more information about configuration
4186 files and how to use these options.
4209 files and how to use these options.
4187
4210
4188 To read a patch from standard input, use "-" as the patch name. If
4211 To read a patch from standard input, use "-" as the patch name. If
4189 a URL is specified, the patch will be downloaded from it.
4212 a URL is specified, the patch will be downloaded from it.
4190 See :hg:`help dates` for a list of formats valid for -d/--date.
4213 See :hg:`help dates` for a list of formats valid for -d/--date.
4191
4214
4192 .. container:: verbose
4215 .. container:: verbose
4193
4216
4194 Examples:
4217 Examples:
4195
4218
4196 - import a traditional patch from a website and detect renames::
4219 - import a traditional patch from a website and detect renames::
4197
4220
4198 hg import -s 80 http://example.com/bugfix.patch
4221 hg import -s 80 http://example.com/bugfix.patch
4199
4222
4200 - import a changeset from an hgweb server::
4223 - import a changeset from an hgweb server::
4201
4224
4202 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
4225 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
4203
4226
4204 - import all the patches in an Unix-style mbox::
4227 - import all the patches in an Unix-style mbox::
4205
4228
4206 hg import incoming-patches.mbox
4229 hg import incoming-patches.mbox
4207
4230
4208 - attempt to exactly restore an exported changeset (not always
4231 - attempt to exactly restore an exported changeset (not always
4209 possible)::
4232 possible)::
4210
4233
4211 hg import --exact proposed-fix.patch
4234 hg import --exact proposed-fix.patch
4212
4235
4213 - use an external tool to apply a patch which is too fuzzy for
4236 - use an external tool to apply a patch which is too fuzzy for
4214 the default internal tool.
4237 the default internal tool.
4215
4238
4216 hg import --config ui.patch="patch --merge" fuzzy.patch
4239 hg import --config ui.patch="patch --merge" fuzzy.patch
4217
4240
4218 - change the default fuzzing from 2 to a less strict 7
4241 - change the default fuzzing from 2 to a less strict 7
4219
4242
4220 hg import --config ui.fuzz=7 fuzz.patch
4243 hg import --config ui.fuzz=7 fuzz.patch
4221
4244
4222 Returns 0 on success, 1 on partial success (see --partial).
4245 Returns 0 on success, 1 on partial success (see --partial).
4223 """
4246 """
4224
4247
4225 if not patch1:
4248 if not patch1:
4226 raise util.Abort(_('need at least one patch to import'))
4249 raise util.Abort(_('need at least one patch to import'))
4227
4250
4228 patches = (patch1,) + patches
4251 patches = (patch1,) + patches
4229
4252
4230 date = opts.get('date')
4253 date = opts.get('date')
4231 if date:
4254 if date:
4232 opts['date'] = util.parsedate(date)
4255 opts['date'] = util.parsedate(date)
4233
4256
4234 update = not opts.get('bypass')
4257 update = not opts.get('bypass')
4235 if not update and opts.get('no_commit'):
4258 if not update and opts.get('no_commit'):
4236 raise util.Abort(_('cannot use --no-commit with --bypass'))
4259 raise util.Abort(_('cannot use --no-commit with --bypass'))
4237 try:
4260 try:
4238 sim = float(opts.get('similarity') or 0)
4261 sim = float(opts.get('similarity') or 0)
4239 except ValueError:
4262 except ValueError:
4240 raise util.Abort(_('similarity must be a number'))
4263 raise util.Abort(_('similarity must be a number'))
4241 if sim < 0 or sim > 100:
4264 if sim < 0 or sim > 100:
4242 raise util.Abort(_('similarity must be between 0 and 100'))
4265 raise util.Abort(_('similarity must be between 0 and 100'))
4243 if sim and not update:
4266 if sim and not update:
4244 raise util.Abort(_('cannot use --similarity with --bypass'))
4267 raise util.Abort(_('cannot use --similarity with --bypass'))
4245 if opts.get('exact') and opts.get('edit'):
4268 if opts.get('exact') and opts.get('edit'):
4246 raise util.Abort(_('cannot use --exact with --edit'))
4269 raise util.Abort(_('cannot use --exact with --edit'))
4247 if opts.get('exact') and opts.get('prefix'):
4270 if opts.get('exact') and opts.get('prefix'):
4248 raise util.Abort(_('cannot use --exact with --prefix'))
4271 raise util.Abort(_('cannot use --exact with --prefix'))
4249
4272
4250 if update:
4273 if update:
4251 cmdutil.checkunfinished(repo)
4274 cmdutil.checkunfinished(repo)
4252 if (opts.get('exact') or not opts.get('force')) and update:
4275 if (opts.get('exact') or not opts.get('force')) and update:
4253 cmdutil.bailifchanged(repo)
4276 cmdutil.bailifchanged(repo)
4254
4277
4255 base = opts["base"]
4278 base = opts["base"]
4256 wlock = dsguard = lock = tr = None
4279 wlock = dsguard = lock = tr = None
4257 msgs = []
4280 msgs = []
4258 ret = 0
4281 ret = 0
4259
4282
4260
4283
4261 try:
4284 try:
4262 try:
4285 try:
4263 wlock = repo.wlock()
4286 wlock = repo.wlock()
4264 dsguard = cmdutil.dirstateguard(repo, 'import')
4287 dsguard = cmdutil.dirstateguard(repo, 'import')
4265 if not opts.get('no_commit'):
4288 if not opts.get('no_commit'):
4266 lock = repo.lock()
4289 lock = repo.lock()
4267 tr = repo.transaction('import')
4290 tr = repo.transaction('import')
4268 parents = repo.parents()
4291 parents = repo.parents()
4269 for patchurl in patches:
4292 for patchurl in patches:
4270 if patchurl == '-':
4293 if patchurl == '-':
4271 ui.status(_('applying patch from stdin\n'))
4294 ui.status(_('applying patch from stdin\n'))
4272 patchfile = ui.fin
4295 patchfile = ui.fin
4273 patchurl = 'stdin' # for error message
4296 patchurl = 'stdin' # for error message
4274 else:
4297 else:
4275 patchurl = os.path.join(base, patchurl)
4298 patchurl = os.path.join(base, patchurl)
4276 ui.status(_('applying %s\n') % patchurl)
4299 ui.status(_('applying %s\n') % patchurl)
4277 patchfile = hg.openpath(ui, patchurl)
4300 patchfile = hg.openpath(ui, patchurl)
4278
4301
4279 haspatch = False
4302 haspatch = False
4280 for hunk in patch.split(patchfile):
4303 for hunk in patch.split(patchfile):
4281 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4304 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
4282 parents, opts,
4305 parents, opts,
4283 msgs, hg.clean)
4306 msgs, hg.clean)
4284 if msg:
4307 if msg:
4285 haspatch = True
4308 haspatch = True
4286 ui.note(msg + '\n')
4309 ui.note(msg + '\n')
4287 if update or opts.get('exact'):
4310 if update or opts.get('exact'):
4288 parents = repo.parents()
4311 parents = repo.parents()
4289 else:
4312 else:
4290 parents = [repo[node]]
4313 parents = [repo[node]]
4291 if rej:
4314 if rej:
4292 ui.write_err(_("patch applied partially\n"))
4315 ui.write_err(_("patch applied partially\n"))
4293 ui.write_err(_("(fix the .rej files and run "
4316 ui.write_err(_("(fix the .rej files and run "
4294 "`hg commit --amend`)\n"))
4317 "`hg commit --amend`)\n"))
4295 ret = 1
4318 ret = 1
4296 break
4319 break
4297
4320
4298 if not haspatch:
4321 if not haspatch:
4299 raise util.Abort(_('%s: no diffs found') % patchurl)
4322 raise util.Abort(_('%s: no diffs found') % patchurl)
4300
4323
4301 if tr:
4324 if tr:
4302 tr.close()
4325 tr.close()
4303 if msgs:
4326 if msgs:
4304 repo.savecommitmessage('\n* * *\n'.join(msgs))
4327 repo.savecommitmessage('\n* * *\n'.join(msgs))
4305 dsguard.close()
4328 dsguard.close()
4306 return ret
4329 return ret
4307 finally:
4330 finally:
4308 # TODO: get rid of this meaningless try/finally enclosing.
4331 # TODO: get rid of this meaningless try/finally enclosing.
4309 # this is kept only to reduce changes in a patch.
4332 # this is kept only to reduce changes in a patch.
4310 pass
4333 pass
4311 finally:
4334 finally:
4312 if tr:
4335 if tr:
4313 tr.release()
4336 tr.release()
4314 release(lock, dsguard, wlock)
4337 release(lock, dsguard, wlock)
4315
4338
4316 @command('incoming|in',
4339 @command('incoming|in',
4317 [('f', 'force', None,
4340 [('f', 'force', None,
4318 _('run even if remote repository is unrelated')),
4341 _('run even if remote repository is unrelated')),
4319 ('n', 'newest-first', None, _('show newest record first')),
4342 ('n', 'newest-first', None, _('show newest record first')),
4320 ('', 'bundle', '',
4343 ('', 'bundle', '',
4321 _('file to store the bundles into'), _('FILE')),
4344 _('file to store the bundles into'), _('FILE')),
4322 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4345 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4323 ('B', 'bookmarks', False, _("compare bookmarks")),
4346 ('B', 'bookmarks', False, _("compare bookmarks")),
4324 ('b', 'branch', [],
4347 ('b', 'branch', [],
4325 _('a specific branch you would like to pull'), _('BRANCH')),
4348 _('a specific branch you would like to pull'), _('BRANCH')),
4326 ] + logopts + remoteopts + subrepoopts,
4349 ] + logopts + remoteopts + subrepoopts,
4327 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4350 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
4328 def incoming(ui, repo, source="default", **opts):
4351 def incoming(ui, repo, source="default", **opts):
4329 """show new changesets found in source
4352 """show new changesets found in source
4330
4353
4331 Show new changesets found in the specified path/URL or the default
4354 Show new changesets found in the specified path/URL or the default
4332 pull location. These are the changesets that would have been pulled
4355 pull location. These are the changesets that would have been pulled
4333 if a pull at the time you issued this command.
4356 if a pull at the time you issued this command.
4334
4357
4335 See pull for valid source format details.
4358 See pull for valid source format details.
4336
4359
4337 .. container:: verbose
4360 .. container:: verbose
4338
4361
4339 With -B/--bookmarks, the result of bookmark comparison between
4362 With -B/--bookmarks, the result of bookmark comparison between
4340 local and remote repositories is displayed. With -v/--verbose,
4363 local and remote repositories is displayed. With -v/--verbose,
4341 status is also displayed for each bookmark like below::
4364 status is also displayed for each bookmark like below::
4342
4365
4343 BM1 01234567890a added
4366 BM1 01234567890a added
4344 BM2 1234567890ab advanced
4367 BM2 1234567890ab advanced
4345 BM3 234567890abc diverged
4368 BM3 234567890abc diverged
4346 BM4 34567890abcd changed
4369 BM4 34567890abcd changed
4347
4370
4348 The action taken locally when pulling depends on the
4371 The action taken locally when pulling depends on the
4349 status of each bookmark:
4372 status of each bookmark:
4350
4373
4351 :``added``: pull will create it
4374 :``added``: pull will create it
4352 :``advanced``: pull will update it
4375 :``advanced``: pull will update it
4353 :``diverged``: pull will create a divergent bookmark
4376 :``diverged``: pull will create a divergent bookmark
4354 :``changed``: result depends on remote changesets
4377 :``changed``: result depends on remote changesets
4355
4378
4356 From the point of view of pulling behavior, bookmark
4379 From the point of view of pulling behavior, bookmark
4357 existing only in the remote repository are treated as ``added``,
4380 existing only in the remote repository are treated as ``added``,
4358 even if it is in fact locally deleted.
4381 even if it is in fact locally deleted.
4359
4382
4360 .. container:: verbose
4383 .. container:: verbose
4361
4384
4362 For remote repository, using --bundle avoids downloading the
4385 For remote repository, using --bundle avoids downloading the
4363 changesets twice if the incoming is followed by a pull.
4386 changesets twice if the incoming is followed by a pull.
4364
4387
4365 Examples:
4388 Examples:
4366
4389
4367 - show incoming changes with patches and full description::
4390 - show incoming changes with patches and full description::
4368
4391
4369 hg incoming -vp
4392 hg incoming -vp
4370
4393
4371 - show incoming changes excluding merges, store a bundle::
4394 - show incoming changes excluding merges, store a bundle::
4372
4395
4373 hg in -vpM --bundle incoming.hg
4396 hg in -vpM --bundle incoming.hg
4374 hg pull incoming.hg
4397 hg pull incoming.hg
4375
4398
4376 - briefly list changes inside a bundle::
4399 - briefly list changes inside a bundle::
4377
4400
4378 hg in changes.hg -T "{desc|firstline}\\n"
4401 hg in changes.hg -T "{desc|firstline}\\n"
4379
4402
4380 Returns 0 if there are incoming changes, 1 otherwise.
4403 Returns 0 if there are incoming changes, 1 otherwise.
4381 """
4404 """
4382 if opts.get('graph'):
4405 if opts.get('graph'):
4383 cmdutil.checkunsupportedgraphflags([], opts)
4406 cmdutil.checkunsupportedgraphflags([], opts)
4384 def display(other, chlist, displayer):
4407 def display(other, chlist, displayer):
4385 revdag = cmdutil.graphrevs(other, chlist, opts)
4408 revdag = cmdutil.graphrevs(other, chlist, opts)
4386 showparents = [ctx.node() for ctx in repo[None].parents()]
4409 showparents = [ctx.node() for ctx in repo[None].parents()]
4387 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4410 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4388 graphmod.asciiedges)
4411 graphmod.asciiedges)
4389
4412
4390 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4413 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
4391 return 0
4414 return 0
4392
4415
4393 if opts.get('bundle') and opts.get('subrepos'):
4416 if opts.get('bundle') and opts.get('subrepos'):
4394 raise util.Abort(_('cannot combine --bundle and --subrepos'))
4417 raise util.Abort(_('cannot combine --bundle and --subrepos'))
4395
4418
4396 if opts.get('bookmarks'):
4419 if opts.get('bookmarks'):
4397 source, branches = hg.parseurl(ui.expandpath(source),
4420 source, branches = hg.parseurl(ui.expandpath(source),
4398 opts.get('branch'))
4421 opts.get('branch'))
4399 other = hg.peer(repo, opts, source)
4422 other = hg.peer(repo, opts, source)
4400 if 'bookmarks' not in other.listkeys('namespaces'):
4423 if 'bookmarks' not in other.listkeys('namespaces'):
4401 ui.warn(_("remote doesn't support bookmarks\n"))
4424 ui.warn(_("remote doesn't support bookmarks\n"))
4402 return 0
4425 return 0
4403 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4426 ui.status(_('comparing with %s\n') % util.hidepassword(source))
4404 return bookmarks.incoming(ui, repo, other)
4427 return bookmarks.incoming(ui, repo, other)
4405
4428
4406 repo._subtoppath = ui.expandpath(source)
4429 repo._subtoppath = ui.expandpath(source)
4407 try:
4430 try:
4408 return hg.incoming(ui, repo, source, opts)
4431 return hg.incoming(ui, repo, source, opts)
4409 finally:
4432 finally:
4410 del repo._subtoppath
4433 del repo._subtoppath
4411
4434
4412
4435
4413 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4436 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'),
4414 norepo=True)
4437 norepo=True)
4415 def init(ui, dest=".", **opts):
4438 def init(ui, dest=".", **opts):
4416 """create a new repository in the given directory
4439 """create a new repository in the given directory
4417
4440
4418 Initialize a new repository in the given directory. If the given
4441 Initialize a new repository in the given directory. If the given
4419 directory does not exist, it will be created.
4442 directory does not exist, it will be created.
4420
4443
4421 If no directory is given, the current directory is used.
4444 If no directory is given, the current directory is used.
4422
4445
4423 It is possible to specify an ``ssh://`` URL as the destination.
4446 It is possible to specify an ``ssh://`` URL as the destination.
4424 See :hg:`help urls` for more information.
4447 See :hg:`help urls` for more information.
4425
4448
4426 Returns 0 on success.
4449 Returns 0 on success.
4427 """
4450 """
4428 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4451 hg.peer(ui, opts, ui.expandpath(dest), create=True)
4429
4452
4430 @command('locate',
4453 @command('locate',
4431 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4454 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
4432 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4455 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
4433 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4456 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
4434 ] + walkopts,
4457 ] + walkopts,
4435 _('[OPTION]... [PATTERN]...'))
4458 _('[OPTION]... [PATTERN]...'))
4436 def locate(ui, repo, *pats, **opts):
4459 def locate(ui, repo, *pats, **opts):
4437 """locate files matching specific patterns (DEPRECATED)
4460 """locate files matching specific patterns (DEPRECATED)
4438
4461
4439 Print files under Mercurial control in the working directory whose
4462 Print files under Mercurial control in the working directory whose
4440 names match the given patterns.
4463 names match the given patterns.
4441
4464
4442 By default, this command searches all directories in the working
4465 By default, this command searches all directories in the working
4443 directory. To search just the current directory and its
4466 directory. To search just the current directory and its
4444 subdirectories, use "--include .".
4467 subdirectories, use "--include .".
4445
4468
4446 If no patterns are given to match, this command prints the names
4469 If no patterns are given to match, this command prints the names
4447 of all files under Mercurial control in the working directory.
4470 of all files under Mercurial control in the working directory.
4448
4471
4449 If you want to feed the output of this command into the "xargs"
4472 If you want to feed the output of this command into the "xargs"
4450 command, use the -0 option to both this command and "xargs". This
4473 command, use the -0 option to both this command and "xargs". This
4451 will avoid the problem of "xargs" treating single filenames that
4474 will avoid the problem of "xargs" treating single filenames that
4452 contain whitespace as multiple filenames.
4475 contain whitespace as multiple filenames.
4453
4476
4454 See :hg:`help files` for a more versatile command.
4477 See :hg:`help files` for a more versatile command.
4455
4478
4456 Returns 0 if a match is found, 1 otherwise.
4479 Returns 0 if a match is found, 1 otherwise.
4457 """
4480 """
4458 if opts.get('print0'):
4481 if opts.get('print0'):
4459 end = '\0'
4482 end = '\0'
4460 else:
4483 else:
4461 end = '\n'
4484 end = '\n'
4462 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4485 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
4463
4486
4464 ret = 1
4487 ret = 1
4465 ctx = repo[rev]
4488 ctx = repo[rev]
4466 m = scmutil.match(ctx, pats, opts, default='relglob',
4489 m = scmutil.match(ctx, pats, opts, default='relglob',
4467 badfn=lambda x, y: False)
4490 badfn=lambda x, y: False)
4468
4491
4469 for abs in ctx.matches(m):
4492 for abs in ctx.matches(m):
4470 if opts.get('fullpath'):
4493 if opts.get('fullpath'):
4471 ui.write(repo.wjoin(abs), end)
4494 ui.write(repo.wjoin(abs), end)
4472 else:
4495 else:
4473 ui.write(((pats and m.rel(abs)) or abs), end)
4496 ui.write(((pats and m.rel(abs)) or abs), end)
4474 ret = 0
4497 ret = 0
4475
4498
4476 return ret
4499 return ret
4477
4500
4478 @command('^log|history',
4501 @command('^log|history',
4479 [('f', 'follow', None,
4502 [('f', 'follow', None,
4480 _('follow changeset history, or file history across copies and renames')),
4503 _('follow changeset history, or file history across copies and renames')),
4481 ('', 'follow-first', None,
4504 ('', 'follow-first', None,
4482 _('only follow the first parent of merge changesets (DEPRECATED)')),
4505 _('only follow the first parent of merge changesets (DEPRECATED)')),
4483 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4506 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
4484 ('C', 'copies', None, _('show copied files')),
4507 ('C', 'copies', None, _('show copied files')),
4485 ('k', 'keyword', [],
4508 ('k', 'keyword', [],
4486 _('do case-insensitive search for a given text'), _('TEXT')),
4509 _('do case-insensitive search for a given text'), _('TEXT')),
4487 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4510 ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
4488 ('', 'removed', None, _('include revisions where files were removed')),
4511 ('', 'removed', None, _('include revisions where files were removed')),
4489 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4512 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4490 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4513 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4491 ('', 'only-branch', [],
4514 ('', 'only-branch', [],
4492 _('show only changesets within the given named branch (DEPRECATED)'),
4515 _('show only changesets within the given named branch (DEPRECATED)'),
4493 _('BRANCH')),
4516 _('BRANCH')),
4494 ('b', 'branch', [],
4517 ('b', 'branch', [],
4495 _('show changesets within the given named branch'), _('BRANCH')),
4518 _('show changesets within the given named branch'), _('BRANCH')),
4496 ('P', 'prune', [],
4519 ('P', 'prune', [],
4497 _('do not display revision or any of its ancestors'), _('REV')),
4520 _('do not display revision or any of its ancestors'), _('REV')),
4498 ] + logopts + walkopts,
4521 ] + logopts + walkopts,
4499 _('[OPTION]... [FILE]'),
4522 _('[OPTION]... [FILE]'),
4500 inferrepo=True)
4523 inferrepo=True)
4501 def log(ui, repo, *pats, **opts):
4524 def log(ui, repo, *pats, **opts):
4502 """show revision history of entire repository or files
4525 """show revision history of entire repository or files
4503
4526
4504 Print the revision history of the specified files or the entire
4527 Print the revision history of the specified files or the entire
4505 project.
4528 project.
4506
4529
4507 If no revision range is specified, the default is ``tip:0`` unless
4530 If no revision range is specified, the default is ``tip:0`` unless
4508 --follow is set, in which case the working directory parent is
4531 --follow is set, in which case the working directory parent is
4509 used as the starting revision.
4532 used as the starting revision.
4510
4533
4511 File history is shown without following rename or copy history of
4534 File history is shown without following rename or copy history of
4512 files. Use -f/--follow with a filename to follow history across
4535 files. Use -f/--follow with a filename to follow history across
4513 renames and copies. --follow without a filename will only show
4536 renames and copies. --follow without a filename will only show
4514 ancestors or descendants of the starting revision.
4537 ancestors or descendants of the starting revision.
4515
4538
4516 By default this command prints revision number and changeset id,
4539 By default this command prints revision number and changeset id,
4517 tags, non-trivial parents, user, date and time, and a summary for
4540 tags, non-trivial parents, user, date and time, and a summary for
4518 each commit. When the -v/--verbose switch is used, the list of
4541 each commit. When the -v/--verbose switch is used, the list of
4519 changed files and full commit message are shown.
4542 changed files and full commit message are shown.
4520
4543
4521 With --graph the revisions are shown as an ASCII art DAG with the most
4544 With --graph the revisions are shown as an ASCII art DAG with the most
4522 recent changeset at the top.
4545 recent changeset at the top.
4523 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4546 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4524 and '+' represents a fork where the changeset from the lines below is a
4547 and '+' represents a fork where the changeset from the lines below is a
4525 parent of the 'o' merge on the same line.
4548 parent of the 'o' merge on the same line.
4526
4549
4527 .. note::
4550 .. note::
4528
4551
4529 log -p/--patch may generate unexpected diff output for merge
4552 log -p/--patch may generate unexpected diff output for merge
4530 changesets, as it will only compare the merge changeset against
4553 changesets, as it will only compare the merge changeset against
4531 its first parent. Also, only files different from BOTH parents
4554 its first parent. Also, only files different from BOTH parents
4532 will appear in files:.
4555 will appear in files:.
4533
4556
4534 .. note::
4557 .. note::
4535
4558
4536 for performance reasons, log FILE may omit duplicate changes
4559 for performance reasons, log FILE may omit duplicate changes
4537 made on branches and will not show removals or mode changes. To
4560 made on branches and will not show removals or mode changes. To
4538 see all such changes, use the --removed switch.
4561 see all such changes, use the --removed switch.
4539
4562
4540 .. container:: verbose
4563 .. container:: verbose
4541
4564
4542 Some examples:
4565 Some examples:
4543
4566
4544 - changesets with full descriptions and file lists::
4567 - changesets with full descriptions and file lists::
4545
4568
4546 hg log -v
4569 hg log -v
4547
4570
4548 - changesets ancestral to the working directory::
4571 - changesets ancestral to the working directory::
4549
4572
4550 hg log -f
4573 hg log -f
4551
4574
4552 - last 10 commits on the current branch::
4575 - last 10 commits on the current branch::
4553
4576
4554 hg log -l 10 -b .
4577 hg log -l 10 -b .
4555
4578
4556 - changesets showing all modifications of a file, including removals::
4579 - changesets showing all modifications of a file, including removals::
4557
4580
4558 hg log --removed file.c
4581 hg log --removed file.c
4559
4582
4560 - all changesets that touch a directory, with diffs, excluding merges::
4583 - all changesets that touch a directory, with diffs, excluding merges::
4561
4584
4562 hg log -Mp lib/
4585 hg log -Mp lib/
4563
4586
4564 - all revision numbers that match a keyword::
4587 - all revision numbers that match a keyword::
4565
4588
4566 hg log -k bug --template "{rev}\\n"
4589 hg log -k bug --template "{rev}\\n"
4567
4590
4568 - list available log templates::
4591 - list available log templates::
4569
4592
4570 hg log -T list
4593 hg log -T list
4571
4594
4572 - check if a given changeset is included in a tagged release::
4595 - check if a given changeset is included in a tagged release::
4573
4596
4574 hg log -r "a21ccf and ancestor(1.9)"
4597 hg log -r "a21ccf and ancestor(1.9)"
4575
4598
4576 - find all changesets by some user in a date range::
4599 - find all changesets by some user in a date range::
4577
4600
4578 hg log -k alice -d "may 2008 to jul 2008"
4601 hg log -k alice -d "may 2008 to jul 2008"
4579
4602
4580 - summary of all changesets after the last tag::
4603 - summary of all changesets after the last tag::
4581
4604
4582 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4605 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4583
4606
4584 See :hg:`help dates` for a list of formats valid for -d/--date.
4607 See :hg:`help dates` for a list of formats valid for -d/--date.
4585
4608
4586 See :hg:`help revisions` and :hg:`help revsets` for more about
4609 See :hg:`help revisions` and :hg:`help revsets` for more about
4587 specifying revisions.
4610 specifying revisions.
4588
4611
4589 See :hg:`help templates` for more about pre-packaged styles and
4612 See :hg:`help templates` for more about pre-packaged styles and
4590 specifying custom templates.
4613 specifying custom templates.
4591
4614
4592 Returns 0 on success.
4615 Returns 0 on success.
4593
4616
4594 """
4617 """
4595 if opts.get('follow') and opts.get('rev'):
4618 if opts.get('follow') and opts.get('rev'):
4596 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
4619 opts['rev'] = [revset.formatspec('reverse(::%lr)', opts.get('rev'))]
4597 del opts['follow']
4620 del opts['follow']
4598
4621
4599 if opts.get('graph'):
4622 if opts.get('graph'):
4600 return cmdutil.graphlog(ui, repo, *pats, **opts)
4623 return cmdutil.graphlog(ui, repo, *pats, **opts)
4601
4624
4602 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4625 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4603 limit = cmdutil.loglimit(opts)
4626 limit = cmdutil.loglimit(opts)
4604 count = 0
4627 count = 0
4605
4628
4606 getrenamed = None
4629 getrenamed = None
4607 if opts.get('copies'):
4630 if opts.get('copies'):
4608 endrev = None
4631 endrev = None
4609 if opts.get('rev'):
4632 if opts.get('rev'):
4610 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4633 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4611 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4634 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4612
4635
4613 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4636 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4614 for rev in revs:
4637 for rev in revs:
4615 if count == limit:
4638 if count == limit:
4616 break
4639 break
4617 ctx = repo[rev]
4640 ctx = repo[rev]
4618 copies = None
4641 copies = None
4619 if getrenamed is not None and rev:
4642 if getrenamed is not None and rev:
4620 copies = []
4643 copies = []
4621 for fn in ctx.files():
4644 for fn in ctx.files():
4622 rename = getrenamed(fn, rev)
4645 rename = getrenamed(fn, rev)
4623 if rename:
4646 if rename:
4624 copies.append((fn, rename[0]))
4647 copies.append((fn, rename[0]))
4625 if filematcher:
4648 if filematcher:
4626 revmatchfn = filematcher(ctx.rev())
4649 revmatchfn = filematcher(ctx.rev())
4627 else:
4650 else:
4628 revmatchfn = None
4651 revmatchfn = None
4629 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4652 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4630 if displayer.flush(ctx):
4653 if displayer.flush(ctx):
4631 count += 1
4654 count += 1
4632
4655
4633 displayer.close()
4656 displayer.close()
4634
4657
4635 @command('manifest',
4658 @command('manifest',
4636 [('r', 'rev', '', _('revision to display'), _('REV')),
4659 [('r', 'rev', '', _('revision to display'), _('REV')),
4637 ('', 'all', False, _("list files from all revisions"))]
4660 ('', 'all', False, _("list files from all revisions"))]
4638 + formatteropts,
4661 + formatteropts,
4639 _('[-r REV]'))
4662 _('[-r REV]'))
4640 def manifest(ui, repo, node=None, rev=None, **opts):
4663 def manifest(ui, repo, node=None, rev=None, **opts):
4641 """output the current or given revision of the project manifest
4664 """output the current or given revision of the project manifest
4642
4665
4643 Print a list of version controlled files for the given revision.
4666 Print a list of version controlled files for the given revision.
4644 If no revision is given, the first parent of the working directory
4667 If no revision is given, the first parent of the working directory
4645 is used, or the null revision if no revision is checked out.
4668 is used, or the null revision if no revision is checked out.
4646
4669
4647 With -v, print file permissions, symlink and executable bits.
4670 With -v, print file permissions, symlink and executable bits.
4648 With --debug, print file revision hashes.
4671 With --debug, print file revision hashes.
4649
4672
4650 If option --all is specified, the list of all files from all revisions
4673 If option --all is specified, the list of all files from all revisions
4651 is printed. This includes deleted and renamed files.
4674 is printed. This includes deleted and renamed files.
4652
4675
4653 Returns 0 on success.
4676 Returns 0 on success.
4654 """
4677 """
4655
4678
4656 fm = ui.formatter('manifest', opts)
4679 fm = ui.formatter('manifest', opts)
4657
4680
4658 if opts.get('all'):
4681 if opts.get('all'):
4659 if rev or node:
4682 if rev or node:
4660 raise util.Abort(_("can't specify a revision with --all"))
4683 raise util.Abort(_("can't specify a revision with --all"))
4661
4684
4662 res = []
4685 res = []
4663 prefix = "data/"
4686 prefix = "data/"
4664 suffix = ".i"
4687 suffix = ".i"
4665 plen = len(prefix)
4688 plen = len(prefix)
4666 slen = len(suffix)
4689 slen = len(suffix)
4667 lock = repo.lock()
4690 lock = repo.lock()
4668 try:
4691 try:
4669 for fn, b, size in repo.store.datafiles():
4692 for fn, b, size in repo.store.datafiles():
4670 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4693 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4671 res.append(fn[plen:-slen])
4694 res.append(fn[plen:-slen])
4672 finally:
4695 finally:
4673 lock.release()
4696 lock.release()
4674 for f in res:
4697 for f in res:
4675 fm.startitem()
4698 fm.startitem()
4676 fm.write("path", '%s\n', f)
4699 fm.write("path", '%s\n', f)
4677 fm.end()
4700 fm.end()
4678 return
4701 return
4679
4702
4680 if rev and node:
4703 if rev and node:
4681 raise util.Abort(_("please specify just one revision"))
4704 raise util.Abort(_("please specify just one revision"))
4682
4705
4683 if not node:
4706 if not node:
4684 node = rev
4707 node = rev
4685
4708
4686 char = {'l': '@', 'x': '*', '': ''}
4709 char = {'l': '@', 'x': '*', '': ''}
4687 mode = {'l': '644', 'x': '755', '': '644'}
4710 mode = {'l': '644', 'x': '755', '': '644'}
4688 ctx = scmutil.revsingle(repo, node)
4711 ctx = scmutil.revsingle(repo, node)
4689 mf = ctx.manifest()
4712 mf = ctx.manifest()
4690 for f in ctx:
4713 for f in ctx:
4691 fm.startitem()
4714 fm.startitem()
4692 fl = ctx[f].flags()
4715 fl = ctx[f].flags()
4693 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4716 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4694 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4717 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4695 fm.write('path', '%s\n', f)
4718 fm.write('path', '%s\n', f)
4696 fm.end()
4719 fm.end()
4697
4720
4698 @command('^merge',
4721 @command('^merge',
4699 [('f', 'force', None,
4722 [('f', 'force', None,
4700 _('force a merge including outstanding changes (DEPRECATED)')),
4723 _('force a merge including outstanding changes (DEPRECATED)')),
4701 ('r', 'rev', '', _('revision to merge'), _('REV')),
4724 ('r', 'rev', '', _('revision to merge'), _('REV')),
4702 ('P', 'preview', None,
4725 ('P', 'preview', None,
4703 _('review revisions to merge (no merge is performed)'))
4726 _('review revisions to merge (no merge is performed)'))
4704 ] + mergetoolopts,
4727 ] + mergetoolopts,
4705 _('[-P] [-f] [[-r] REV]'))
4728 _('[-P] [-f] [[-r] REV]'))
4706 def merge(ui, repo, node=None, **opts):
4729 def merge(ui, repo, node=None, **opts):
4707 """merge another revision into working directory
4730 """merge another revision into working directory
4708
4731
4709 The current working directory is updated with all changes made in
4732 The current working directory is updated with all changes made in
4710 the requested revision since the last common predecessor revision.
4733 the requested revision since the last common predecessor revision.
4711
4734
4712 Files that changed between either parent are marked as changed for
4735 Files that changed between either parent are marked as changed for
4713 the next commit and a commit must be performed before any further
4736 the next commit and a commit must be performed before any further
4714 updates to the repository are allowed. The next commit will have
4737 updates to the repository are allowed. The next commit will have
4715 two parents.
4738 two parents.
4716
4739
4717 ``--tool`` can be used to specify the merge tool used for file
4740 ``--tool`` can be used to specify the merge tool used for file
4718 merges. It overrides the HGMERGE environment variable and your
4741 merges. It overrides the HGMERGE environment variable and your
4719 configuration files. See :hg:`help merge-tools` for options.
4742 configuration files. See :hg:`help merge-tools` for options.
4720
4743
4721 If no revision is specified, the working directory's parent is a
4744 If no revision is specified, the working directory's parent is a
4722 head revision, and the current branch contains exactly one other
4745 head revision, and the current branch contains exactly one other
4723 head, the other head is merged with by default. Otherwise, an
4746 head, the other head is merged with by default. Otherwise, an
4724 explicit revision with which to merge with must be provided.
4747 explicit revision with which to merge with must be provided.
4725
4748
4726 :hg:`resolve` must be used to resolve unresolved files.
4749 :hg:`resolve` must be used to resolve unresolved files.
4727
4750
4728 To undo an uncommitted merge, use :hg:`update --clean .` which
4751 To undo an uncommitted merge, use :hg:`update --clean .` which
4729 will check out a clean copy of the original merge parent, losing
4752 will check out a clean copy of the original merge parent, losing
4730 all changes.
4753 all changes.
4731
4754
4732 Returns 0 on success, 1 if there are unresolved files.
4755 Returns 0 on success, 1 if there are unresolved files.
4733 """
4756 """
4734
4757
4735 if opts.get('rev') and node:
4758 if opts.get('rev') and node:
4736 raise util.Abort(_("please specify just one revision"))
4759 raise util.Abort(_("please specify just one revision"))
4737 if not node:
4760 if not node:
4738 node = opts.get('rev')
4761 node = opts.get('rev')
4739
4762
4740 if node:
4763 if node:
4741 node = scmutil.revsingle(repo, node).node()
4764 node = scmutil.revsingle(repo, node).node()
4742
4765
4743 if not node and repo._activebookmark:
4766 if not node and repo._activebookmark:
4744 bmheads = repo.bookmarkheads(repo._activebookmark)
4767 bmheads = repo.bookmarkheads(repo._activebookmark)
4745 curhead = repo[repo._activebookmark].node()
4768 curhead = repo[repo._activebookmark].node()
4746 if len(bmheads) == 2:
4769 if len(bmheads) == 2:
4747 if curhead == bmheads[0]:
4770 if curhead == bmheads[0]:
4748 node = bmheads[1]
4771 node = bmheads[1]
4749 else:
4772 else:
4750 node = bmheads[0]
4773 node = bmheads[0]
4751 elif len(bmheads) > 2:
4774 elif len(bmheads) > 2:
4752 raise util.Abort(_("multiple matching bookmarks to merge - "
4775 raise util.Abort(_("multiple matching bookmarks to merge - "
4753 "please merge with an explicit rev or bookmark"),
4776 "please merge with an explicit rev or bookmark"),
4754 hint=_("run 'hg heads' to see all heads"))
4777 hint=_("run 'hg heads' to see all heads"))
4755 elif len(bmheads) <= 1:
4778 elif len(bmheads) <= 1:
4756 raise util.Abort(_("no matching bookmark to merge - "
4779 raise util.Abort(_("no matching bookmark to merge - "
4757 "please merge with an explicit rev or bookmark"),
4780 "please merge with an explicit rev or bookmark"),
4758 hint=_("run 'hg heads' to see all heads"))
4781 hint=_("run 'hg heads' to see all heads"))
4759
4782
4760 if not node and not repo._activebookmark:
4783 if not node and not repo._activebookmark:
4761 branch = repo[None].branch()
4784 branch = repo[None].branch()
4762 bheads = repo.branchheads(branch)
4785 bheads = repo.branchheads(branch)
4763 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4786 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4764
4787
4765 if len(nbhs) > 2:
4788 if len(nbhs) > 2:
4766 raise util.Abort(_("branch '%s' has %d heads - "
4789 raise util.Abort(_("branch '%s' has %d heads - "
4767 "please merge with an explicit rev")
4790 "please merge with an explicit rev")
4768 % (branch, len(bheads)),
4791 % (branch, len(bheads)),
4769 hint=_("run 'hg heads .' to see heads"))
4792 hint=_("run 'hg heads .' to see heads"))
4770
4793
4771 parent = repo.dirstate.p1()
4794 parent = repo.dirstate.p1()
4772 if len(nbhs) <= 1:
4795 if len(nbhs) <= 1:
4773 if len(bheads) > 1:
4796 if len(bheads) > 1:
4774 raise util.Abort(_("heads are bookmarked - "
4797 raise util.Abort(_("heads are bookmarked - "
4775 "please merge with an explicit rev"),
4798 "please merge with an explicit rev"),
4776 hint=_("run 'hg heads' to see all heads"))
4799 hint=_("run 'hg heads' to see all heads"))
4777 if len(repo.heads()) > 1:
4800 if len(repo.heads()) > 1:
4778 raise util.Abort(_("branch '%s' has one head - "
4801 raise util.Abort(_("branch '%s' has one head - "
4779 "please merge with an explicit rev")
4802 "please merge with an explicit rev")
4780 % branch,
4803 % branch,
4781 hint=_("run 'hg heads' to see all heads"))
4804 hint=_("run 'hg heads' to see all heads"))
4782 msg, hint = _('nothing to merge'), None
4805 msg, hint = _('nothing to merge'), None
4783 if parent != repo.lookup(branch):
4806 if parent != repo.lookup(branch):
4784 hint = _("use 'hg update' instead")
4807 hint = _("use 'hg update' instead")
4785 raise util.Abort(msg, hint=hint)
4808 raise util.Abort(msg, hint=hint)
4786
4809
4787 if parent not in bheads:
4810 if parent not in bheads:
4788 raise util.Abort(_('working directory not at a head revision'),
4811 raise util.Abort(_('working directory not at a head revision'),
4789 hint=_("use 'hg update' or merge with an "
4812 hint=_("use 'hg update' or merge with an "
4790 "explicit revision"))
4813 "explicit revision"))
4791 if parent == nbhs[0]:
4814 if parent == nbhs[0]:
4792 node = nbhs[-1]
4815 node = nbhs[-1]
4793 else:
4816 else:
4794 node = nbhs[0]
4817 node = nbhs[0]
4795
4818
4796 if opts.get('preview'):
4819 if opts.get('preview'):
4797 # find nodes that are ancestors of p2 but not of p1
4820 # find nodes that are ancestors of p2 but not of p1
4798 p1 = repo.lookup('.')
4821 p1 = repo.lookup('.')
4799 p2 = repo.lookup(node)
4822 p2 = repo.lookup(node)
4800 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4823 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4801
4824
4802 displayer = cmdutil.show_changeset(ui, repo, opts)
4825 displayer = cmdutil.show_changeset(ui, repo, opts)
4803 for node in nodes:
4826 for node in nodes:
4804 displayer.show(repo[node])
4827 displayer.show(repo[node])
4805 displayer.close()
4828 displayer.close()
4806 return 0
4829 return 0
4807
4830
4808 try:
4831 try:
4809 # ui.forcemerge is an internal variable, do not document
4832 # ui.forcemerge is an internal variable, do not document
4810 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4833 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4811 return hg.merge(repo, node, force=opts.get('force'))
4834 return hg.merge(repo, node, force=opts.get('force'))
4812 finally:
4835 finally:
4813 ui.setconfig('ui', 'forcemerge', '', 'merge')
4836 ui.setconfig('ui', 'forcemerge', '', 'merge')
4814
4837
4815 @command('outgoing|out',
4838 @command('outgoing|out',
4816 [('f', 'force', None, _('run even when the destination is unrelated')),
4839 [('f', 'force', None, _('run even when the destination is unrelated')),
4817 ('r', 'rev', [],
4840 ('r', 'rev', [],
4818 _('a changeset intended to be included in the destination'), _('REV')),
4841 _('a changeset intended to be included in the destination'), _('REV')),
4819 ('n', 'newest-first', None, _('show newest record first')),
4842 ('n', 'newest-first', None, _('show newest record first')),
4820 ('B', 'bookmarks', False, _('compare bookmarks')),
4843 ('B', 'bookmarks', False, _('compare bookmarks')),
4821 ('b', 'branch', [], _('a specific branch you would like to push'),
4844 ('b', 'branch', [], _('a specific branch you would like to push'),
4822 _('BRANCH')),
4845 _('BRANCH')),
4823 ] + logopts + remoteopts + subrepoopts,
4846 ] + logopts + remoteopts + subrepoopts,
4824 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4847 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4825 def outgoing(ui, repo, dest=None, **opts):
4848 def outgoing(ui, repo, dest=None, **opts):
4826 """show changesets not found in the destination
4849 """show changesets not found in the destination
4827
4850
4828 Show changesets not found in the specified destination repository
4851 Show changesets not found in the specified destination repository
4829 or the default push location. These are the changesets that would
4852 or the default push location. These are the changesets that would
4830 be pushed if a push was requested.
4853 be pushed if a push was requested.
4831
4854
4832 See pull for details of valid destination formats.
4855 See pull for details of valid destination formats.
4833
4856
4834 .. container:: verbose
4857 .. container:: verbose
4835
4858
4836 With -B/--bookmarks, the result of bookmark comparison between
4859 With -B/--bookmarks, the result of bookmark comparison between
4837 local and remote repositories is displayed. With -v/--verbose,
4860 local and remote repositories is displayed. With -v/--verbose,
4838 status is also displayed for each bookmark like below::
4861 status is also displayed for each bookmark like below::
4839
4862
4840 BM1 01234567890a added
4863 BM1 01234567890a added
4841 BM2 deleted
4864 BM2 deleted
4842 BM3 234567890abc advanced
4865 BM3 234567890abc advanced
4843 BM4 34567890abcd diverged
4866 BM4 34567890abcd diverged
4844 BM5 4567890abcde changed
4867 BM5 4567890abcde changed
4845
4868
4846 The action taken when pushing depends on the
4869 The action taken when pushing depends on the
4847 status of each bookmark:
4870 status of each bookmark:
4848
4871
4849 :``added``: push with ``-B`` will create it
4872 :``added``: push with ``-B`` will create it
4850 :``deleted``: push with ``-B`` will delete it
4873 :``deleted``: push with ``-B`` will delete it
4851 :``advanced``: push will update it
4874 :``advanced``: push will update it
4852 :``diverged``: push with ``-B`` will update it
4875 :``diverged``: push with ``-B`` will update it
4853 :``changed``: push with ``-B`` will update it
4876 :``changed``: push with ``-B`` will update it
4854
4877
4855 From the point of view of pushing behavior, bookmarks
4878 From the point of view of pushing behavior, bookmarks
4856 existing only in the remote repository are treated as
4879 existing only in the remote repository are treated as
4857 ``deleted``, even if it is in fact added remotely.
4880 ``deleted``, even if it is in fact added remotely.
4858
4881
4859 Returns 0 if there are outgoing changes, 1 otherwise.
4882 Returns 0 if there are outgoing changes, 1 otherwise.
4860 """
4883 """
4861 if opts.get('graph'):
4884 if opts.get('graph'):
4862 cmdutil.checkunsupportedgraphflags([], opts)
4885 cmdutil.checkunsupportedgraphflags([], opts)
4863 o, other = hg._outgoing(ui, repo, dest, opts)
4886 o, other = hg._outgoing(ui, repo, dest, opts)
4864 if not o:
4887 if not o:
4865 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4888 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4866 return
4889 return
4867
4890
4868 revdag = cmdutil.graphrevs(repo, o, opts)
4891 revdag = cmdutil.graphrevs(repo, o, opts)
4869 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4892 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4870 showparents = [ctx.node() for ctx in repo[None].parents()]
4893 showparents = [ctx.node() for ctx in repo[None].parents()]
4871 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4894 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4872 graphmod.asciiedges)
4895 graphmod.asciiedges)
4873 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4896 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4874 return 0
4897 return 0
4875
4898
4876 if opts.get('bookmarks'):
4899 if opts.get('bookmarks'):
4877 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4900 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4878 dest, branches = hg.parseurl(dest, opts.get('branch'))
4901 dest, branches = hg.parseurl(dest, opts.get('branch'))
4879 other = hg.peer(repo, opts, dest)
4902 other = hg.peer(repo, opts, dest)
4880 if 'bookmarks' not in other.listkeys('namespaces'):
4903 if 'bookmarks' not in other.listkeys('namespaces'):
4881 ui.warn(_("remote doesn't support bookmarks\n"))
4904 ui.warn(_("remote doesn't support bookmarks\n"))
4882 return 0
4905 return 0
4883 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4906 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4884 return bookmarks.outgoing(ui, repo, other)
4907 return bookmarks.outgoing(ui, repo, other)
4885
4908
4886 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4909 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4887 try:
4910 try:
4888 return hg.outgoing(ui, repo, dest, opts)
4911 return hg.outgoing(ui, repo, dest, opts)
4889 finally:
4912 finally:
4890 del repo._subtoppath
4913 del repo._subtoppath
4891
4914
4892 @command('parents',
4915 @command('parents',
4893 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4916 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4894 ] + templateopts,
4917 ] + templateopts,
4895 _('[-r REV] [FILE]'),
4918 _('[-r REV] [FILE]'),
4896 inferrepo=True)
4919 inferrepo=True)
4897 def parents(ui, repo, file_=None, **opts):
4920 def parents(ui, repo, file_=None, **opts):
4898 """show the parents of the working directory or revision (DEPRECATED)
4921 """show the parents of the working directory or revision (DEPRECATED)
4899
4922
4900 Print the working directory's parent revisions. If a revision is
4923 Print the working directory's parent revisions. If a revision is
4901 given via -r/--rev, the parent of that revision will be printed.
4924 given via -r/--rev, the parent of that revision will be printed.
4902 If a file argument is given, the revision in which the file was
4925 If a file argument is given, the revision in which the file was
4903 last changed (before the working directory revision or the
4926 last changed (before the working directory revision or the
4904 argument to --rev if given) is printed.
4927 argument to --rev if given) is printed.
4905
4928
4906 See :hg:`summary` and :hg:`help revsets` for related information.
4929 See :hg:`summary` and :hg:`help revsets` for related information.
4907
4930
4908 Returns 0 on success.
4931 Returns 0 on success.
4909 """
4932 """
4910
4933
4911 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4934 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4912
4935
4913 if file_:
4936 if file_:
4914 m = scmutil.match(ctx, (file_,), opts)
4937 m = scmutil.match(ctx, (file_,), opts)
4915 if m.anypats() or len(m.files()) != 1:
4938 if m.anypats() or len(m.files()) != 1:
4916 raise util.Abort(_('can only specify an explicit filename'))
4939 raise util.Abort(_('can only specify an explicit filename'))
4917 file_ = m.files()[0]
4940 file_ = m.files()[0]
4918 filenodes = []
4941 filenodes = []
4919 for cp in ctx.parents():
4942 for cp in ctx.parents():
4920 if not cp:
4943 if not cp:
4921 continue
4944 continue
4922 try:
4945 try:
4923 filenodes.append(cp.filenode(file_))
4946 filenodes.append(cp.filenode(file_))
4924 except error.LookupError:
4947 except error.LookupError:
4925 pass
4948 pass
4926 if not filenodes:
4949 if not filenodes:
4927 raise util.Abort(_("'%s' not found in manifest!") % file_)
4950 raise util.Abort(_("'%s' not found in manifest!") % file_)
4928 p = []
4951 p = []
4929 for fn in filenodes:
4952 for fn in filenodes:
4930 fctx = repo.filectx(file_, fileid=fn)
4953 fctx = repo.filectx(file_, fileid=fn)
4931 p.append(fctx.node())
4954 p.append(fctx.node())
4932 else:
4955 else:
4933 p = [cp.node() for cp in ctx.parents()]
4956 p = [cp.node() for cp in ctx.parents()]
4934
4957
4935 displayer = cmdutil.show_changeset(ui, repo, opts)
4958 displayer = cmdutil.show_changeset(ui, repo, opts)
4936 for n in p:
4959 for n in p:
4937 if n != nullid:
4960 if n != nullid:
4938 displayer.show(repo[n])
4961 displayer.show(repo[n])
4939 displayer.close()
4962 displayer.close()
4940
4963
4941 @command('paths', [], _('[NAME]'), optionalrepo=True)
4964 @command('paths', [], _('[NAME]'), optionalrepo=True)
4942 def paths(ui, repo, search=None):
4965 def paths(ui, repo, search=None):
4943 """show aliases for remote repositories
4966 """show aliases for remote repositories
4944
4967
4945 Show definition of symbolic path name NAME. If no name is given,
4968 Show definition of symbolic path name NAME. If no name is given,
4946 show definition of all available names.
4969 show definition of all available names.
4947
4970
4948 Option -q/--quiet suppresses all output when searching for NAME
4971 Option -q/--quiet suppresses all output when searching for NAME
4949 and shows only the path names when listing all definitions.
4972 and shows only the path names when listing all definitions.
4950
4973
4951 Path names are defined in the [paths] section of your
4974 Path names are defined in the [paths] section of your
4952 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4975 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4953 repository, ``.hg/hgrc`` is used, too.
4976 repository, ``.hg/hgrc`` is used, too.
4954
4977
4955 The path names ``default`` and ``default-push`` have a special
4978 The path names ``default`` and ``default-push`` have a special
4956 meaning. When performing a push or pull operation, they are used
4979 meaning. When performing a push or pull operation, they are used
4957 as fallbacks if no location is specified on the command-line.
4980 as fallbacks if no location is specified on the command-line.
4958 When ``default-push`` is set, it will be used for push and
4981 When ``default-push`` is set, it will be used for push and
4959 ``default`` will be used for pull; otherwise ``default`` is used
4982 ``default`` will be used for pull; otherwise ``default`` is used
4960 as the fallback for both. When cloning a repository, the clone
4983 as the fallback for both. When cloning a repository, the clone
4961 source is written as ``default`` in ``.hg/hgrc``. Note that
4984 source is written as ``default`` in ``.hg/hgrc``. Note that
4962 ``default`` and ``default-push`` apply to all inbound (e.g.
4985 ``default`` and ``default-push`` apply to all inbound (e.g.
4963 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4986 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4964 :hg:`bundle`) operations.
4987 :hg:`bundle`) operations.
4965
4988
4966 See :hg:`help urls` for more information.
4989 See :hg:`help urls` for more information.
4967
4990
4968 Returns 0 on success.
4991 Returns 0 on success.
4969 """
4992 """
4970 if search:
4993 if search:
4971 for name, path in sorted(ui.paths.iteritems()):
4994 for name, path in sorted(ui.paths.iteritems()):
4972 if name == search:
4995 if name == search:
4973 ui.status("%s\n" % util.hidepassword(path.loc))
4996 ui.status("%s\n" % util.hidepassword(path.loc))
4974 return
4997 return
4975 if not ui.quiet:
4998 if not ui.quiet:
4976 ui.warn(_("not found!\n"))
4999 ui.warn(_("not found!\n"))
4977 return 1
5000 return 1
4978 else:
5001 else:
4979 for name, path in sorted(ui.paths.iteritems()):
5002 for name, path in sorted(ui.paths.iteritems()):
4980 if ui.quiet:
5003 if ui.quiet:
4981 ui.write("%s\n" % name)
5004 ui.write("%s\n" % name)
4982 else:
5005 else:
4983 ui.write("%s = %s\n" % (name,
5006 ui.write("%s = %s\n" % (name,
4984 util.hidepassword(path.loc)))
5007 util.hidepassword(path.loc)))
4985
5008
4986 @command('phase',
5009 @command('phase',
4987 [('p', 'public', False, _('set changeset phase to public')),
5010 [('p', 'public', False, _('set changeset phase to public')),
4988 ('d', 'draft', False, _('set changeset phase to draft')),
5011 ('d', 'draft', False, _('set changeset phase to draft')),
4989 ('s', 'secret', False, _('set changeset phase to secret')),
5012 ('s', 'secret', False, _('set changeset phase to secret')),
4990 ('f', 'force', False, _('allow to move boundary backward')),
5013 ('f', 'force', False, _('allow to move boundary backward')),
4991 ('r', 'rev', [], _('target revision'), _('REV')),
5014 ('r', 'rev', [], _('target revision'), _('REV')),
4992 ],
5015 ],
4993 _('[-p|-d|-s] [-f] [-r] [REV...]'))
5016 _('[-p|-d|-s] [-f] [-r] [REV...]'))
4994 def phase(ui, repo, *revs, **opts):
5017 def phase(ui, repo, *revs, **opts):
4995 """set or show the current phase name
5018 """set or show the current phase name
4996
5019
4997 With no argument, show the phase name of the current revision(s).
5020 With no argument, show the phase name of the current revision(s).
4998
5021
4999 With one of -p/--public, -d/--draft or -s/--secret, change the
5022 With one of -p/--public, -d/--draft or -s/--secret, change the
5000 phase value of the specified revisions.
5023 phase value of the specified revisions.
5001
5024
5002 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
5025 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
5003 lower phase to an higher phase. Phases are ordered as follows::
5026 lower phase to an higher phase. Phases are ordered as follows::
5004
5027
5005 public < draft < secret
5028 public < draft < secret
5006
5029
5007 Returns 0 on success, 1 if no phases were changed or some could not
5030 Returns 0 on success, 1 if no phases were changed or some could not
5008 be changed.
5031 be changed.
5009
5032
5010 (For more information about the phases concept, see :hg:`help phases`.)
5033 (For more information about the phases concept, see :hg:`help phases`.)
5011 """
5034 """
5012 # search for a unique phase argument
5035 # search for a unique phase argument
5013 targetphase = None
5036 targetphase = None
5014 for idx, name in enumerate(phases.phasenames):
5037 for idx, name in enumerate(phases.phasenames):
5015 if opts[name]:
5038 if opts[name]:
5016 if targetphase is not None:
5039 if targetphase is not None:
5017 raise util.Abort(_('only one phase can be specified'))
5040 raise util.Abort(_('only one phase can be specified'))
5018 targetphase = idx
5041 targetphase = idx
5019
5042
5020 # look for specified revision
5043 # look for specified revision
5021 revs = list(revs)
5044 revs = list(revs)
5022 revs.extend(opts['rev'])
5045 revs.extend(opts['rev'])
5023 if not revs:
5046 if not revs:
5024 # display both parents as the second parent phase can influence
5047 # display both parents as the second parent phase can influence
5025 # the phase of a merge commit
5048 # the phase of a merge commit
5026 revs = [c.rev() for c in repo[None].parents()]
5049 revs = [c.rev() for c in repo[None].parents()]
5027
5050
5028 revs = scmutil.revrange(repo, revs)
5051 revs = scmutil.revrange(repo, revs)
5029
5052
5030 lock = None
5053 lock = None
5031 ret = 0
5054 ret = 0
5032 if targetphase is None:
5055 if targetphase is None:
5033 # display
5056 # display
5034 for r in revs:
5057 for r in revs:
5035 ctx = repo[r]
5058 ctx = repo[r]
5036 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5059 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
5037 else:
5060 else:
5038 tr = None
5061 tr = None
5039 lock = repo.lock()
5062 lock = repo.lock()
5040 try:
5063 try:
5041 tr = repo.transaction("phase")
5064 tr = repo.transaction("phase")
5042 # set phase
5065 # set phase
5043 if not revs:
5066 if not revs:
5044 raise util.Abort(_('empty revision set'))
5067 raise util.Abort(_('empty revision set'))
5045 nodes = [repo[r].node() for r in revs]
5068 nodes = [repo[r].node() for r in revs]
5046 # moving revision from public to draft may hide them
5069 # moving revision from public to draft may hide them
5047 # We have to check result on an unfiltered repository
5070 # We have to check result on an unfiltered repository
5048 unfi = repo.unfiltered()
5071 unfi = repo.unfiltered()
5049 getphase = unfi._phasecache.phase
5072 getphase = unfi._phasecache.phase
5050 olddata = [getphase(unfi, r) for r in unfi]
5073 olddata = [getphase(unfi, r) for r in unfi]
5051 phases.advanceboundary(repo, tr, targetphase, nodes)
5074 phases.advanceboundary(repo, tr, targetphase, nodes)
5052 if opts['force']:
5075 if opts['force']:
5053 phases.retractboundary(repo, tr, targetphase, nodes)
5076 phases.retractboundary(repo, tr, targetphase, nodes)
5054 tr.close()
5077 tr.close()
5055 finally:
5078 finally:
5056 if tr is not None:
5079 if tr is not None:
5057 tr.release()
5080 tr.release()
5058 lock.release()
5081 lock.release()
5059 getphase = unfi._phasecache.phase
5082 getphase = unfi._phasecache.phase
5060 newdata = [getphase(unfi, r) for r in unfi]
5083 newdata = [getphase(unfi, r) for r in unfi]
5061 changes = sum(newdata[r] != olddata[r] for r in unfi)
5084 changes = sum(newdata[r] != olddata[r] for r in unfi)
5062 cl = unfi.changelog
5085 cl = unfi.changelog
5063 rejected = [n for n in nodes
5086 rejected = [n for n in nodes
5064 if newdata[cl.rev(n)] < targetphase]
5087 if newdata[cl.rev(n)] < targetphase]
5065 if rejected:
5088 if rejected:
5066 ui.warn(_('cannot move %i changesets to a higher '
5089 ui.warn(_('cannot move %i changesets to a higher '
5067 'phase, use --force\n') % len(rejected))
5090 'phase, use --force\n') % len(rejected))
5068 ret = 1
5091 ret = 1
5069 if changes:
5092 if changes:
5070 msg = _('phase changed for %i changesets\n') % changes
5093 msg = _('phase changed for %i changesets\n') % changes
5071 if ret:
5094 if ret:
5072 ui.status(msg)
5095 ui.status(msg)
5073 else:
5096 else:
5074 ui.note(msg)
5097 ui.note(msg)
5075 else:
5098 else:
5076 ui.warn(_('no phases changed\n'))
5099 ui.warn(_('no phases changed\n'))
5077 ret = 1
5100 ret = 1
5078 return ret
5101 return ret
5079
5102
5080 def postincoming(ui, repo, modheads, optupdate, checkout):
5103 def postincoming(ui, repo, modheads, optupdate, checkout):
5081 if modheads == 0:
5104 if modheads == 0:
5082 return
5105 return
5083 if optupdate:
5106 if optupdate:
5084 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
5107 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
5085 try:
5108 try:
5086 ret = hg.update(repo, checkout)
5109 ret = hg.update(repo, checkout)
5087 except util.Abort as inst:
5110 except util.Abort as inst:
5088 ui.warn(_("not updating: %s\n") % str(inst))
5111 ui.warn(_("not updating: %s\n") % str(inst))
5089 if inst.hint:
5112 if inst.hint:
5090 ui.warn(_("(%s)\n") % inst.hint)
5113 ui.warn(_("(%s)\n") % inst.hint)
5091 return 0
5114 return 0
5092 if not ret and not checkout:
5115 if not ret and not checkout:
5093 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5116 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5094 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
5117 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
5095 return ret
5118 return ret
5096 if modheads > 1:
5119 if modheads > 1:
5097 currentbranchheads = len(repo.branchheads())
5120 currentbranchheads = len(repo.branchheads())
5098 if currentbranchheads == modheads:
5121 if currentbranchheads == modheads:
5099 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5122 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
5100 elif currentbranchheads > 1:
5123 elif currentbranchheads > 1:
5101 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5124 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
5102 "merge)\n"))
5125 "merge)\n"))
5103 else:
5126 else:
5104 ui.status(_("(run 'hg heads' to see heads)\n"))
5127 ui.status(_("(run 'hg heads' to see heads)\n"))
5105 else:
5128 else:
5106 ui.status(_("(run 'hg update' to get a working copy)\n"))
5129 ui.status(_("(run 'hg update' to get a working copy)\n"))
5107
5130
5108 @command('^pull',
5131 @command('^pull',
5109 [('u', 'update', None,
5132 [('u', 'update', None,
5110 _('update to new branch head if changesets were pulled')),
5133 _('update to new branch head if changesets were pulled')),
5111 ('f', 'force', None, _('run even when remote repository is unrelated')),
5134 ('f', 'force', None, _('run even when remote repository is unrelated')),
5112 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5135 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
5113 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5136 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
5114 ('b', 'branch', [], _('a specific branch you would like to pull'),
5137 ('b', 'branch', [], _('a specific branch you would like to pull'),
5115 _('BRANCH')),
5138 _('BRANCH')),
5116 ] + remoteopts,
5139 ] + remoteopts,
5117 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5140 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
5118 def pull(ui, repo, source="default", **opts):
5141 def pull(ui, repo, source="default", **opts):
5119 """pull changes from the specified source
5142 """pull changes from the specified source
5120
5143
5121 Pull changes from a remote repository to a local one.
5144 Pull changes from a remote repository to a local one.
5122
5145
5123 This finds all changes from the repository at the specified path
5146 This finds all changes from the repository at the specified path
5124 or URL and adds them to a local repository (the current one unless
5147 or URL and adds them to a local repository (the current one unless
5125 -R is specified). By default, this does not update the copy of the
5148 -R is specified). By default, this does not update the copy of the
5126 project in the working directory.
5149 project in the working directory.
5127
5150
5128 Use :hg:`incoming` if you want to see what would have been added
5151 Use :hg:`incoming` if you want to see what would have been added
5129 by a pull at the time you issued this command. If you then decide
5152 by a pull at the time you issued this command. If you then decide
5130 to add those changes to the repository, you should use :hg:`pull
5153 to add those changes to the repository, you should use :hg:`pull
5131 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5154 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
5132
5155
5133 If SOURCE is omitted, the 'default' path will be used.
5156 If SOURCE is omitted, the 'default' path will be used.
5134 See :hg:`help urls` for more information.
5157 See :hg:`help urls` for more information.
5135
5158
5136 Returns 0 on success, 1 if an update had unresolved files.
5159 Returns 0 on success, 1 if an update had unresolved files.
5137 """
5160 """
5138 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5161 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
5139 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5162 ui.status(_('pulling from %s\n') % util.hidepassword(source))
5140 other = hg.peer(repo, opts, source)
5163 other = hg.peer(repo, opts, source)
5141 try:
5164 try:
5142 revs, checkout = hg.addbranchrevs(repo, other, branches,
5165 revs, checkout = hg.addbranchrevs(repo, other, branches,
5143 opts.get('rev'))
5166 opts.get('rev'))
5144
5167
5145
5168
5146 pullopargs = {}
5169 pullopargs = {}
5147 if opts.get('bookmark'):
5170 if opts.get('bookmark'):
5148 if not revs:
5171 if not revs:
5149 revs = []
5172 revs = []
5150 # The list of bookmark used here is not the one used to actually
5173 # The list of bookmark used here is not the one used to actually
5151 # update the bookmark name. This can result in the revision pulled
5174 # update the bookmark name. This can result in the revision pulled
5152 # not ending up with the name of the bookmark because of a race
5175 # not ending up with the name of the bookmark because of a race
5153 # condition on the server. (See issue 4689 for details)
5176 # condition on the server. (See issue 4689 for details)
5154 remotebookmarks = other.listkeys('bookmarks')
5177 remotebookmarks = other.listkeys('bookmarks')
5155 pullopargs['remotebookmarks'] = remotebookmarks
5178 pullopargs['remotebookmarks'] = remotebookmarks
5156 for b in opts['bookmark']:
5179 for b in opts['bookmark']:
5157 if b not in remotebookmarks:
5180 if b not in remotebookmarks:
5158 raise util.Abort(_('remote bookmark %s not found!') % b)
5181 raise util.Abort(_('remote bookmark %s not found!') % b)
5159 revs.append(remotebookmarks[b])
5182 revs.append(remotebookmarks[b])
5160
5183
5161 if revs:
5184 if revs:
5162 try:
5185 try:
5163 # When 'rev' is a bookmark name, we cannot guarantee that it
5186 # When 'rev' is a bookmark name, we cannot guarantee that it
5164 # will be updated with that name because of a race condition
5187 # will be updated with that name because of a race condition
5165 # server side. (See issue 4689 for details)
5188 # server side. (See issue 4689 for details)
5166 oldrevs = revs
5189 oldrevs = revs
5167 revs = [] # actually, nodes
5190 revs = [] # actually, nodes
5168 for r in oldrevs:
5191 for r in oldrevs:
5169 node = other.lookup(r)
5192 node = other.lookup(r)
5170 revs.append(node)
5193 revs.append(node)
5171 if r == checkout:
5194 if r == checkout:
5172 checkout = node
5195 checkout = node
5173 except error.CapabilityError:
5196 except error.CapabilityError:
5174 err = _("other repository doesn't support revision lookup, "
5197 err = _("other repository doesn't support revision lookup, "
5175 "so a rev cannot be specified.")
5198 "so a rev cannot be specified.")
5176 raise util.Abort(err)
5199 raise util.Abort(err)
5177
5200
5178 modheads = exchange.pull(repo, other, heads=revs,
5201 modheads = exchange.pull(repo, other, heads=revs,
5179 force=opts.get('force'),
5202 force=opts.get('force'),
5180 bookmarks=opts.get('bookmark', ()),
5203 bookmarks=opts.get('bookmark', ()),
5181 opargs=pullopargs).cgresult
5204 opargs=pullopargs).cgresult
5182 if checkout:
5205 if checkout:
5183 checkout = str(repo.changelog.rev(checkout))
5206 checkout = str(repo.changelog.rev(checkout))
5184 repo._subtoppath = source
5207 repo._subtoppath = source
5185 try:
5208 try:
5186 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
5209 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
5187
5210
5188 finally:
5211 finally:
5189 del repo._subtoppath
5212 del repo._subtoppath
5190
5213
5191 finally:
5214 finally:
5192 other.close()
5215 other.close()
5193 return ret
5216 return ret
5194
5217
5195 @command('^push',
5218 @command('^push',
5196 [('f', 'force', None, _('force push')),
5219 [('f', 'force', None, _('force push')),
5197 ('r', 'rev', [],
5220 ('r', 'rev', [],
5198 _('a changeset intended to be included in the destination'),
5221 _('a changeset intended to be included in the destination'),
5199 _('REV')),
5222 _('REV')),
5200 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5223 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
5201 ('b', 'branch', [],
5224 ('b', 'branch', [],
5202 _('a specific branch you would like to push'), _('BRANCH')),
5225 _('a specific branch you would like to push'), _('BRANCH')),
5203 ('', 'new-branch', False, _('allow pushing a new branch')),
5226 ('', 'new-branch', False, _('allow pushing a new branch')),
5204 ] + remoteopts,
5227 ] + remoteopts,
5205 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5228 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
5206 def push(ui, repo, dest=None, **opts):
5229 def push(ui, repo, dest=None, **opts):
5207 """push changes to the specified destination
5230 """push changes to the specified destination
5208
5231
5209 Push changesets from the local repository to the specified
5232 Push changesets from the local repository to the specified
5210 destination.
5233 destination.
5211
5234
5212 This operation is symmetrical to pull: it is identical to a pull
5235 This operation is symmetrical to pull: it is identical to a pull
5213 in the destination repository from the current one.
5236 in the destination repository from the current one.
5214
5237
5215 By default, push will not allow creation of new heads at the
5238 By default, push will not allow creation of new heads at the
5216 destination, since multiple heads would make it unclear which head
5239 destination, since multiple heads would make it unclear which head
5217 to use. In this situation, it is recommended to pull and merge
5240 to use. In this situation, it is recommended to pull and merge
5218 before pushing.
5241 before pushing.
5219
5242
5220 Use --new-branch if you want to allow push to create a new named
5243 Use --new-branch if you want to allow push to create a new named
5221 branch that is not present at the destination. This allows you to
5244 branch that is not present at the destination. This allows you to
5222 only create a new branch without forcing other changes.
5245 only create a new branch without forcing other changes.
5223
5246
5224 .. note::
5247 .. note::
5225
5248
5226 Extra care should be taken with the -f/--force option,
5249 Extra care should be taken with the -f/--force option,
5227 which will push all new heads on all branches, an action which will
5250 which will push all new heads on all branches, an action which will
5228 almost always cause confusion for collaborators.
5251 almost always cause confusion for collaborators.
5229
5252
5230 If -r/--rev is used, the specified revision and all its ancestors
5253 If -r/--rev is used, the specified revision and all its ancestors
5231 will be pushed to the remote repository.
5254 will be pushed to the remote repository.
5232
5255
5233 If -B/--bookmark is used, the specified bookmarked revision, its
5256 If -B/--bookmark is used, the specified bookmarked revision, its
5234 ancestors, and the bookmark will be pushed to the remote
5257 ancestors, and the bookmark will be pushed to the remote
5235 repository.
5258 repository.
5236
5259
5237 Please see :hg:`help urls` for important details about ``ssh://``
5260 Please see :hg:`help urls` for important details about ``ssh://``
5238 URLs. If DESTINATION is omitted, a default path will be used.
5261 URLs. If DESTINATION is omitted, a default path will be used.
5239
5262
5240 Returns 0 if push was successful, 1 if nothing to push.
5263 Returns 0 if push was successful, 1 if nothing to push.
5241 """
5264 """
5242
5265
5243 if opts.get('bookmark'):
5266 if opts.get('bookmark'):
5244 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5267 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
5245 for b in opts['bookmark']:
5268 for b in opts['bookmark']:
5246 # translate -B options to -r so changesets get pushed
5269 # translate -B options to -r so changesets get pushed
5247 if b in repo._bookmarks:
5270 if b in repo._bookmarks:
5248 opts.setdefault('rev', []).append(b)
5271 opts.setdefault('rev', []).append(b)
5249 else:
5272 else:
5250 # if we try to push a deleted bookmark, translate it to null
5273 # if we try to push a deleted bookmark, translate it to null
5251 # this lets simultaneous -r, -b options continue working
5274 # this lets simultaneous -r, -b options continue working
5252 opts.setdefault('rev', []).append("null")
5275 opts.setdefault('rev', []).append("null")
5253
5276
5254 dest = ui.expandpath(dest or 'default-push', dest or 'default')
5277 dest = ui.expandpath(dest or 'default-push', dest or 'default')
5255 dest, branches = hg.parseurl(dest, opts.get('branch'))
5278 dest, branches = hg.parseurl(dest, opts.get('branch'))
5256 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5279 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
5257 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5280 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
5258 try:
5281 try:
5259 other = hg.peer(repo, opts, dest)
5282 other = hg.peer(repo, opts, dest)
5260 except error.RepoError:
5283 except error.RepoError:
5261 if dest == "default-push":
5284 if dest == "default-push":
5262 raise util.Abort(_("default repository not configured!"),
5285 raise util.Abort(_("default repository not configured!"),
5263 hint=_('see the "path" section in "hg help config"'))
5286 hint=_('see the "path" section in "hg help config"'))
5264 else:
5287 else:
5265 raise
5288 raise
5266
5289
5267 if revs:
5290 if revs:
5268 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5291 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
5269 if not revs:
5292 if not revs:
5270 raise util.Abort(_("specified revisions evaluate to an empty set"),
5293 raise util.Abort(_("specified revisions evaluate to an empty set"),
5271 hint=_("use different revision arguments"))
5294 hint=_("use different revision arguments"))
5272
5295
5273 repo._subtoppath = dest
5296 repo._subtoppath = dest
5274 try:
5297 try:
5275 # push subrepos depth-first for coherent ordering
5298 # push subrepos depth-first for coherent ordering
5276 c = repo['']
5299 c = repo['']
5277 subs = c.substate # only repos that are committed
5300 subs = c.substate # only repos that are committed
5278 for s in sorted(subs):
5301 for s in sorted(subs):
5279 result = c.sub(s).push(opts)
5302 result = c.sub(s).push(opts)
5280 if result == 0:
5303 if result == 0:
5281 return not result
5304 return not result
5282 finally:
5305 finally:
5283 del repo._subtoppath
5306 del repo._subtoppath
5284 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5307 pushop = exchange.push(repo, other, opts.get('force'), revs=revs,
5285 newbranch=opts.get('new_branch'),
5308 newbranch=opts.get('new_branch'),
5286 bookmarks=opts.get('bookmark', ()))
5309 bookmarks=opts.get('bookmark', ()))
5287
5310
5288 result = not pushop.cgresult
5311 result = not pushop.cgresult
5289
5312
5290 if pushop.bkresult is not None:
5313 if pushop.bkresult is not None:
5291 if pushop.bkresult == 2:
5314 if pushop.bkresult == 2:
5292 result = 2
5315 result = 2
5293 elif not result and pushop.bkresult:
5316 elif not result and pushop.bkresult:
5294 result = 2
5317 result = 2
5295
5318
5296 return result
5319 return result
5297
5320
5298 @command('recover', [])
5321 @command('recover', [])
5299 def recover(ui, repo):
5322 def recover(ui, repo):
5300 """roll back an interrupted transaction
5323 """roll back an interrupted transaction
5301
5324
5302 Recover from an interrupted commit or pull.
5325 Recover from an interrupted commit or pull.
5303
5326
5304 This command tries to fix the repository status after an
5327 This command tries to fix the repository status after an
5305 interrupted operation. It should only be necessary when Mercurial
5328 interrupted operation. It should only be necessary when Mercurial
5306 suggests it.
5329 suggests it.
5307
5330
5308 Returns 0 if successful, 1 if nothing to recover or verify fails.
5331 Returns 0 if successful, 1 if nothing to recover or verify fails.
5309 """
5332 """
5310 if repo.recover():
5333 if repo.recover():
5311 return hg.verify(repo)
5334 return hg.verify(repo)
5312 return 1
5335 return 1
5313
5336
5314 @command('^remove|rm',
5337 @command('^remove|rm',
5315 [('A', 'after', None, _('record delete for missing files')),
5338 [('A', 'after', None, _('record delete for missing files')),
5316 ('f', 'force', None,
5339 ('f', 'force', None,
5317 _('remove (and delete) file even if added or modified')),
5340 _('remove (and delete) file even if added or modified')),
5318 ] + subrepoopts + walkopts,
5341 ] + subrepoopts + walkopts,
5319 _('[OPTION]... FILE...'),
5342 _('[OPTION]... FILE...'),
5320 inferrepo=True)
5343 inferrepo=True)
5321 def remove(ui, repo, *pats, **opts):
5344 def remove(ui, repo, *pats, **opts):
5322 """remove the specified files on the next commit
5345 """remove the specified files on the next commit
5323
5346
5324 Schedule the indicated files for removal from the current branch.
5347 Schedule the indicated files for removal from the current branch.
5325
5348
5326 This command schedules the files to be removed at the next commit.
5349 This command schedules the files to be removed at the next commit.
5327 To undo a remove before that, see :hg:`revert`. To undo added
5350 To undo a remove before that, see :hg:`revert`. To undo added
5328 files, see :hg:`forget`.
5351 files, see :hg:`forget`.
5329
5352
5330 .. container:: verbose
5353 .. container:: verbose
5331
5354
5332 -A/--after can be used to remove only files that have already
5355 -A/--after can be used to remove only files that have already
5333 been deleted, -f/--force can be used to force deletion, and -Af
5356 been deleted, -f/--force can be used to force deletion, and -Af
5334 can be used to remove files from the next revision without
5357 can be used to remove files from the next revision without
5335 deleting them from the working directory.
5358 deleting them from the working directory.
5336
5359
5337 The following table details the behavior of remove for different
5360 The following table details the behavior of remove for different
5338 file states (columns) and option combinations (rows). The file
5361 file states (columns) and option combinations (rows). The file
5339 states are Added [A], Clean [C], Modified [M] and Missing [!]
5362 states are Added [A], Clean [C], Modified [M] and Missing [!]
5340 (as reported by :hg:`status`). The actions are Warn, Remove
5363 (as reported by :hg:`status`). The actions are Warn, Remove
5341 (from branch) and Delete (from disk):
5364 (from branch) and Delete (from disk):
5342
5365
5343 ========= == == == ==
5366 ========= == == == ==
5344 opt/state A C M !
5367 opt/state A C M !
5345 ========= == == == ==
5368 ========= == == == ==
5346 none W RD W R
5369 none W RD W R
5347 -f R RD RD R
5370 -f R RD RD R
5348 -A W W W R
5371 -A W W W R
5349 -Af R R R R
5372 -Af R R R R
5350 ========= == == == ==
5373 ========= == == == ==
5351
5374
5352 Note that remove never deletes files in Added [A] state from the
5375 Note that remove never deletes files in Added [A] state from the
5353 working directory, not even if option --force is specified.
5376 working directory, not even if option --force is specified.
5354
5377
5355 Returns 0 on success, 1 if any warnings encountered.
5378 Returns 0 on success, 1 if any warnings encountered.
5356 """
5379 """
5357
5380
5358 after, force = opts.get('after'), opts.get('force')
5381 after, force = opts.get('after'), opts.get('force')
5359 if not pats and not after:
5382 if not pats and not after:
5360 raise util.Abort(_('no files specified'))
5383 raise util.Abort(_('no files specified'))
5361
5384
5362 m = scmutil.match(repo[None], pats, opts)
5385 m = scmutil.match(repo[None], pats, opts)
5363 subrepos = opts.get('subrepos')
5386 subrepos = opts.get('subrepos')
5364 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5387 return cmdutil.remove(ui, repo, m, "", after, force, subrepos)
5365
5388
5366 @command('rename|move|mv',
5389 @command('rename|move|mv',
5367 [('A', 'after', None, _('record a rename that has already occurred')),
5390 [('A', 'after', None, _('record a rename that has already occurred')),
5368 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5391 ('f', 'force', None, _('forcibly copy over an existing managed file')),
5369 ] + walkopts + dryrunopts,
5392 ] + walkopts + dryrunopts,
5370 _('[OPTION]... SOURCE... DEST'))
5393 _('[OPTION]... SOURCE... DEST'))
5371 def rename(ui, repo, *pats, **opts):
5394 def rename(ui, repo, *pats, **opts):
5372 """rename files; equivalent of copy + remove
5395 """rename files; equivalent of copy + remove
5373
5396
5374 Mark dest as copies of sources; mark sources for deletion. If dest
5397 Mark dest as copies of sources; mark sources for deletion. If dest
5375 is a directory, copies are put in that directory. If dest is a
5398 is a directory, copies are put in that directory. If dest is a
5376 file, there can only be one source.
5399 file, there can only be one source.
5377
5400
5378 By default, this command copies the contents of files as they
5401 By default, this command copies the contents of files as they
5379 exist in the working directory. If invoked with -A/--after, the
5402 exist in the working directory. If invoked with -A/--after, the
5380 operation is recorded, but no copying is performed.
5403 operation is recorded, but no copying is performed.
5381
5404
5382 This command takes effect at the next commit. To undo a rename
5405 This command takes effect at the next commit. To undo a rename
5383 before that, see :hg:`revert`.
5406 before that, see :hg:`revert`.
5384
5407
5385 Returns 0 on success, 1 if errors are encountered.
5408 Returns 0 on success, 1 if errors are encountered.
5386 """
5409 """
5387 wlock = repo.wlock(False)
5410 wlock = repo.wlock(False)
5388 try:
5411 try:
5389 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5412 return cmdutil.copy(ui, repo, pats, opts, rename=True)
5390 finally:
5413 finally:
5391 wlock.release()
5414 wlock.release()
5392
5415
5393 @command('resolve',
5416 @command('resolve',
5394 [('a', 'all', None, _('select all unresolved files')),
5417 [('a', 'all', None, _('select all unresolved files')),
5395 ('l', 'list', None, _('list state of files needing merge')),
5418 ('l', 'list', None, _('list state of files needing merge')),
5396 ('m', 'mark', None, _('mark files as resolved')),
5419 ('m', 'mark', None, _('mark files as resolved')),
5397 ('u', 'unmark', None, _('mark files as unresolved')),
5420 ('u', 'unmark', None, _('mark files as unresolved')),
5398 ('n', 'no-status', None, _('hide status prefix'))]
5421 ('n', 'no-status', None, _('hide status prefix'))]
5399 + mergetoolopts + walkopts + formatteropts,
5422 + mergetoolopts + walkopts + formatteropts,
5400 _('[OPTION]... [FILE]...'),
5423 _('[OPTION]... [FILE]...'),
5401 inferrepo=True)
5424 inferrepo=True)
5402 def resolve(ui, repo, *pats, **opts):
5425 def resolve(ui, repo, *pats, **opts):
5403 """redo merges or set/view the merge status of files
5426 """redo merges or set/view the merge status of files
5404
5427
5405 Merges with unresolved conflicts are often the result of
5428 Merges with unresolved conflicts are often the result of
5406 non-interactive merging using the ``internal:merge`` configuration
5429 non-interactive merging using the ``internal:merge`` configuration
5407 setting, or a command-line merge tool like ``diff3``. The resolve
5430 setting, or a command-line merge tool like ``diff3``. The resolve
5408 command is used to manage the files involved in a merge, after
5431 command is used to manage the files involved in a merge, after
5409 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5432 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
5410 working directory must have two parents). See :hg:`help
5433 working directory must have two parents). See :hg:`help
5411 merge-tools` for information on configuring merge tools.
5434 merge-tools` for information on configuring merge tools.
5412
5435
5413 The resolve command can be used in the following ways:
5436 The resolve command can be used in the following ways:
5414
5437
5415 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5438 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
5416 files, discarding any previous merge attempts. Re-merging is not
5439 files, discarding any previous merge attempts. Re-merging is not
5417 performed for files already marked as resolved. Use ``--all/-a``
5440 performed for files already marked as resolved. Use ``--all/-a``
5418 to select all unresolved files. ``--tool`` can be used to specify
5441 to select all unresolved files. ``--tool`` can be used to specify
5419 the merge tool used for the given files. It overrides the HGMERGE
5442 the merge tool used for the given files. It overrides the HGMERGE
5420 environment variable and your configuration files. Previous file
5443 environment variable and your configuration files. Previous file
5421 contents are saved with a ``.orig`` suffix.
5444 contents are saved with a ``.orig`` suffix.
5422
5445
5423 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5446 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
5424 (e.g. after having manually fixed-up the files). The default is
5447 (e.g. after having manually fixed-up the files). The default is
5425 to mark all unresolved files.
5448 to mark all unresolved files.
5426
5449
5427 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5450 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
5428 default is to mark all resolved files.
5451 default is to mark all resolved files.
5429
5452
5430 - :hg:`resolve -l`: list files which had or still have conflicts.
5453 - :hg:`resolve -l`: list files which had or still have conflicts.
5431 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5454 In the printed list, ``U`` = unresolved and ``R`` = resolved.
5432
5455
5433 Note that Mercurial will not let you commit files with unresolved
5456 Note that Mercurial will not let you commit files with unresolved
5434 merge conflicts. You must use :hg:`resolve -m ...` before you can
5457 merge conflicts. You must use :hg:`resolve -m ...` before you can
5435 commit after a conflicting merge.
5458 commit after a conflicting merge.
5436
5459
5437 Returns 0 on success, 1 if any files fail a resolve attempt.
5460 Returns 0 on success, 1 if any files fail a resolve attempt.
5438 """
5461 """
5439
5462
5440 all, mark, unmark, show, nostatus = \
5463 all, mark, unmark, show, nostatus = \
5441 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
5464 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
5442
5465
5443 if (show and (mark or unmark)) or (mark and unmark):
5466 if (show and (mark or unmark)) or (mark and unmark):
5444 raise util.Abort(_("too many options specified"))
5467 raise util.Abort(_("too many options specified"))
5445 if pats and all:
5468 if pats and all:
5446 raise util.Abort(_("can't specify --all and patterns"))
5469 raise util.Abort(_("can't specify --all and patterns"))
5447 if not (all or pats or show or mark or unmark):
5470 if not (all or pats or show or mark or unmark):
5448 raise util.Abort(_('no files or directories specified'),
5471 raise util.Abort(_('no files or directories specified'),
5449 hint=('use --all to remerge all files'))
5472 hint=('use --all to remerge all files'))
5450
5473
5451 if show:
5474 if show:
5452 fm = ui.formatter('resolve', opts)
5475 fm = ui.formatter('resolve', opts)
5453 ms = mergemod.mergestate(repo)
5476 ms = mergemod.mergestate(repo)
5454 m = scmutil.match(repo[None], pats, opts)
5477 m = scmutil.match(repo[None], pats, opts)
5455 for f in ms:
5478 for f in ms:
5456 if not m(f):
5479 if not m(f):
5457 continue
5480 continue
5458 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved'}[ms[f]]
5481 l = 'resolve.' + {'u': 'unresolved', 'r': 'resolved'}[ms[f]]
5459 fm.startitem()
5482 fm.startitem()
5460 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5483 fm.condwrite(not nostatus, 'status', '%s ', ms[f].upper(), label=l)
5461 fm.write('path', '%s\n', f, label=l)
5484 fm.write('path', '%s\n', f, label=l)
5462 fm.end()
5485 fm.end()
5463 return 0
5486 return 0
5464
5487
5465 wlock = repo.wlock()
5488 wlock = repo.wlock()
5466 try:
5489 try:
5467 ms = mergemod.mergestate(repo)
5490 ms = mergemod.mergestate(repo)
5468
5491
5469 if not (ms.active() or repo.dirstate.p2() != nullid):
5492 if not (ms.active() or repo.dirstate.p2() != nullid):
5470 raise util.Abort(
5493 raise util.Abort(
5471 _('resolve command not applicable when not merging'))
5494 _('resolve command not applicable when not merging'))
5472
5495
5473 m = scmutil.match(repo[None], pats, opts)
5496 m = scmutil.match(repo[None], pats, opts)
5474 ret = 0
5497 ret = 0
5475 didwork = False
5498 didwork = False
5476
5499
5477 for f in ms:
5500 for f in ms:
5478 if not m(f):
5501 if not m(f):
5479 continue
5502 continue
5480
5503
5481 didwork = True
5504 didwork = True
5482
5505
5483 if mark:
5506 if mark:
5484 ms.mark(f, "r")
5507 ms.mark(f, "r")
5485 elif unmark:
5508 elif unmark:
5486 ms.mark(f, "u")
5509 ms.mark(f, "u")
5487 else:
5510 else:
5488 wctx = repo[None]
5511 wctx = repo[None]
5489
5512
5490 # backup pre-resolve (merge uses .orig for its own purposes)
5513 # backup pre-resolve (merge uses .orig for its own purposes)
5491 a = repo.wjoin(f)
5514 a = repo.wjoin(f)
5492 util.copyfile(a, a + ".resolve")
5515 util.copyfile(a, a + ".resolve")
5493
5516
5494 try:
5517 try:
5495 # resolve file
5518 # resolve file
5496 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5519 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
5497 'resolve')
5520 'resolve')
5498 if ms.resolve(f, wctx):
5521 if ms.resolve(f, wctx):
5499 ret = 1
5522 ret = 1
5500 finally:
5523 finally:
5501 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5524 ui.setconfig('ui', 'forcemerge', '', 'resolve')
5502 ms.commit()
5525 ms.commit()
5503
5526
5504 # replace filemerge's .orig file with our resolve file
5527 # replace filemerge's .orig file with our resolve file
5505 util.rename(a + ".resolve", a + ".orig")
5528 util.rename(a + ".resolve", a + ".orig")
5506
5529
5507 ms.commit()
5530 ms.commit()
5508
5531
5509 if not didwork and pats:
5532 if not didwork and pats:
5510 ui.warn(_("arguments do not match paths that need resolving\n"))
5533 ui.warn(_("arguments do not match paths that need resolving\n"))
5511
5534
5512 finally:
5535 finally:
5513 wlock.release()
5536 wlock.release()
5514
5537
5515 # Nudge users into finishing an unfinished operation
5538 # Nudge users into finishing an unfinished operation
5516 if not list(ms.unresolved()):
5539 if not list(ms.unresolved()):
5517 ui.status(_('(no more unresolved files)\n'))
5540 ui.status(_('(no more unresolved files)\n'))
5518
5541
5519 return ret
5542 return ret
5520
5543
5521 @command('revert',
5544 @command('revert',
5522 [('a', 'all', None, _('revert all changes when no arguments given')),
5545 [('a', 'all', None, _('revert all changes when no arguments given')),
5523 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5546 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5524 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5547 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5525 ('C', 'no-backup', None, _('do not save backup copies of files')),
5548 ('C', 'no-backup', None, _('do not save backup copies of files')),
5526 ('i', 'interactive', None,
5549 ('i', 'interactive', None,
5527 _('interactively select the changes (EXPERIMENTAL)')),
5550 _('interactively select the changes (EXPERIMENTAL)')),
5528 ] + walkopts + dryrunopts,
5551 ] + walkopts + dryrunopts,
5529 _('[OPTION]... [-r REV] [NAME]...'))
5552 _('[OPTION]... [-r REV] [NAME]...'))
5530 def revert(ui, repo, *pats, **opts):
5553 def revert(ui, repo, *pats, **opts):
5531 """restore files to their checkout state
5554 """restore files to their checkout state
5532
5555
5533 .. note::
5556 .. note::
5534
5557
5535 To check out earlier revisions, you should use :hg:`update REV`.
5558 To check out earlier revisions, you should use :hg:`update REV`.
5536 To cancel an uncommitted merge (and lose your changes),
5559 To cancel an uncommitted merge (and lose your changes),
5537 use :hg:`update --clean .`.
5560 use :hg:`update --clean .`.
5538
5561
5539 With no revision specified, revert the specified files or directories
5562 With no revision specified, revert the specified files or directories
5540 to the contents they had in the parent of the working directory.
5563 to the contents they had in the parent of the working directory.
5541 This restores the contents of files to an unmodified
5564 This restores the contents of files to an unmodified
5542 state and unschedules adds, removes, copies, and renames. If the
5565 state and unschedules adds, removes, copies, and renames. If the
5543 working directory has two parents, you must explicitly specify a
5566 working directory has two parents, you must explicitly specify a
5544 revision.
5567 revision.
5545
5568
5546 Using the -r/--rev or -d/--date options, revert the given files or
5569 Using the -r/--rev or -d/--date options, revert the given files or
5547 directories to their states as of a specific revision. Because
5570 directories to their states as of a specific revision. Because
5548 revert does not change the working directory parents, this will
5571 revert does not change the working directory parents, this will
5549 cause these files to appear modified. This can be helpful to "back
5572 cause these files to appear modified. This can be helpful to "back
5550 out" some or all of an earlier change. See :hg:`backout` for a
5573 out" some or all of an earlier change. See :hg:`backout` for a
5551 related method.
5574 related method.
5552
5575
5553 Modified files are saved with a .orig suffix before reverting.
5576 Modified files are saved with a .orig suffix before reverting.
5554 To disable these backups, use --no-backup.
5577 To disable these backups, use --no-backup.
5555
5578
5556 See :hg:`help dates` for a list of formats valid for -d/--date.
5579 See :hg:`help dates` for a list of formats valid for -d/--date.
5557
5580
5558 Returns 0 on success.
5581 Returns 0 on success.
5559 """
5582 """
5560
5583
5561 if opts.get("date"):
5584 if opts.get("date"):
5562 if opts.get("rev"):
5585 if opts.get("rev"):
5563 raise util.Abort(_("you can't specify a revision and a date"))
5586 raise util.Abort(_("you can't specify a revision and a date"))
5564 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5587 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5565
5588
5566 parent, p2 = repo.dirstate.parents()
5589 parent, p2 = repo.dirstate.parents()
5567 if not opts.get('rev') and p2 != nullid:
5590 if not opts.get('rev') and p2 != nullid:
5568 # revert after merge is a trap for new users (issue2915)
5591 # revert after merge is a trap for new users (issue2915)
5569 raise util.Abort(_('uncommitted merge with no revision specified'),
5592 raise util.Abort(_('uncommitted merge with no revision specified'),
5570 hint=_('use "hg update" or see "hg help revert"'))
5593 hint=_('use "hg update" or see "hg help revert"'))
5571
5594
5572 ctx = scmutil.revsingle(repo, opts.get('rev'))
5595 ctx = scmutil.revsingle(repo, opts.get('rev'))
5573
5596
5574 if (not (pats or opts.get('include') or opts.get('exclude') or
5597 if (not (pats or opts.get('include') or opts.get('exclude') or
5575 opts.get('all') or opts.get('interactive'))):
5598 opts.get('all') or opts.get('interactive'))):
5576 msg = _("no files or directories specified")
5599 msg = _("no files or directories specified")
5577 if p2 != nullid:
5600 if p2 != nullid:
5578 hint = _("uncommitted merge, use --all to discard all changes,"
5601 hint = _("uncommitted merge, use --all to discard all changes,"
5579 " or 'hg update -C .' to abort the merge")
5602 " or 'hg update -C .' to abort the merge")
5580 raise util.Abort(msg, hint=hint)
5603 raise util.Abort(msg, hint=hint)
5581 dirty = any(repo.status())
5604 dirty = any(repo.status())
5582 node = ctx.node()
5605 node = ctx.node()
5583 if node != parent:
5606 if node != parent:
5584 if dirty:
5607 if dirty:
5585 hint = _("uncommitted changes, use --all to discard all"
5608 hint = _("uncommitted changes, use --all to discard all"
5586 " changes, or 'hg update %s' to update") % ctx.rev()
5609 " changes, or 'hg update %s' to update") % ctx.rev()
5587 else:
5610 else:
5588 hint = _("use --all to revert all files,"
5611 hint = _("use --all to revert all files,"
5589 " or 'hg update %s' to update") % ctx.rev()
5612 " or 'hg update %s' to update") % ctx.rev()
5590 elif dirty:
5613 elif dirty:
5591 hint = _("uncommitted changes, use --all to discard all changes")
5614 hint = _("uncommitted changes, use --all to discard all changes")
5592 else:
5615 else:
5593 hint = _("use --all to revert all files")
5616 hint = _("use --all to revert all files")
5594 raise util.Abort(msg, hint=hint)
5617 raise util.Abort(msg, hint=hint)
5595
5618
5596 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5619 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5597
5620
5598 @command('rollback', dryrunopts +
5621 @command('rollback', dryrunopts +
5599 [('f', 'force', False, _('ignore safety measures'))])
5622 [('f', 'force', False, _('ignore safety measures'))])
5600 def rollback(ui, repo, **opts):
5623 def rollback(ui, repo, **opts):
5601 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5624 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5602
5625
5603 Please use :hg:`commit --amend` instead of rollback to correct
5626 Please use :hg:`commit --amend` instead of rollback to correct
5604 mistakes in the last commit.
5627 mistakes in the last commit.
5605
5628
5606 This command should be used with care. There is only one level of
5629 This command should be used with care. There is only one level of
5607 rollback, and there is no way to undo a rollback. It will also
5630 rollback, and there is no way to undo a rollback. It will also
5608 restore the dirstate at the time of the last transaction, losing
5631 restore the dirstate at the time of the last transaction, losing
5609 any dirstate changes since that time. This command does not alter
5632 any dirstate changes since that time. This command does not alter
5610 the working directory.
5633 the working directory.
5611
5634
5612 Transactions are used to encapsulate the effects of all commands
5635 Transactions are used to encapsulate the effects of all commands
5613 that create new changesets or propagate existing changesets into a
5636 that create new changesets or propagate existing changesets into a
5614 repository.
5637 repository.
5615
5638
5616 .. container:: verbose
5639 .. container:: verbose
5617
5640
5618 For example, the following commands are transactional, and their
5641 For example, the following commands are transactional, and their
5619 effects can be rolled back:
5642 effects can be rolled back:
5620
5643
5621 - commit
5644 - commit
5622 - import
5645 - import
5623 - pull
5646 - pull
5624 - push (with this repository as the destination)
5647 - push (with this repository as the destination)
5625 - unbundle
5648 - unbundle
5626
5649
5627 To avoid permanent data loss, rollback will refuse to rollback a
5650 To avoid permanent data loss, rollback will refuse to rollback a
5628 commit transaction if it isn't checked out. Use --force to
5651 commit transaction if it isn't checked out. Use --force to
5629 override this protection.
5652 override this protection.
5630
5653
5631 This command is not intended for use on public repositories. Once
5654 This command is not intended for use on public repositories. Once
5632 changes are visible for pull by other users, rolling a transaction
5655 changes are visible for pull by other users, rolling a transaction
5633 back locally is ineffective (someone else may already have pulled
5656 back locally is ineffective (someone else may already have pulled
5634 the changes). Furthermore, a race is possible with readers of the
5657 the changes). Furthermore, a race is possible with readers of the
5635 repository; for example an in-progress pull from the repository
5658 repository; for example an in-progress pull from the repository
5636 may fail if a rollback is performed.
5659 may fail if a rollback is performed.
5637
5660
5638 Returns 0 on success, 1 if no rollback data is available.
5661 Returns 0 on success, 1 if no rollback data is available.
5639 """
5662 """
5640 return repo.rollback(dryrun=opts.get('dry_run'),
5663 return repo.rollback(dryrun=opts.get('dry_run'),
5641 force=opts.get('force'))
5664 force=opts.get('force'))
5642
5665
5643 @command('root', [])
5666 @command('root', [])
5644 def root(ui, repo):
5667 def root(ui, repo):
5645 """print the root (top) of the current working directory
5668 """print the root (top) of the current working directory
5646
5669
5647 Print the root directory of the current repository.
5670 Print the root directory of the current repository.
5648
5671
5649 Returns 0 on success.
5672 Returns 0 on success.
5650 """
5673 """
5651 ui.write(repo.root + "\n")
5674 ui.write(repo.root + "\n")
5652
5675
5653 @command('^serve',
5676 @command('^serve',
5654 [('A', 'accesslog', '', _('name of access log file to write to'),
5677 [('A', 'accesslog', '', _('name of access log file to write to'),
5655 _('FILE')),
5678 _('FILE')),
5656 ('d', 'daemon', None, _('run server in background')),
5679 ('d', 'daemon', None, _('run server in background')),
5657 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('FILE')),
5680 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('FILE')),
5658 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5681 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5659 # use string type, then we can check if something was passed
5682 # use string type, then we can check if something was passed
5660 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5683 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5661 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5684 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5662 _('ADDR')),
5685 _('ADDR')),
5663 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5686 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5664 _('PREFIX')),
5687 _('PREFIX')),
5665 ('n', 'name', '',
5688 ('n', 'name', '',
5666 _('name to show in web pages (default: working directory)'), _('NAME')),
5689 _('name to show in web pages (default: working directory)'), _('NAME')),
5667 ('', 'web-conf', '',
5690 ('', 'web-conf', '',
5668 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5691 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5669 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5692 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5670 _('FILE')),
5693 _('FILE')),
5671 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5694 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5672 ('', 'stdio', None, _('for remote clients')),
5695 ('', 'stdio', None, _('for remote clients')),
5673 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5696 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5674 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5697 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5675 ('', 'style', '', _('template style to use'), _('STYLE')),
5698 ('', 'style', '', _('template style to use'), _('STYLE')),
5676 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5699 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5677 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5700 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5678 _('[OPTION]...'),
5701 _('[OPTION]...'),
5679 optionalrepo=True)
5702 optionalrepo=True)
5680 def serve(ui, repo, **opts):
5703 def serve(ui, repo, **opts):
5681 """start stand-alone webserver
5704 """start stand-alone webserver
5682
5705
5683 Start a local HTTP repository browser and pull server. You can use
5706 Start a local HTTP repository browser and pull server. You can use
5684 this for ad-hoc sharing and browsing of repositories. It is
5707 this for ad-hoc sharing and browsing of repositories. It is
5685 recommended to use a real web server to serve a repository for
5708 recommended to use a real web server to serve a repository for
5686 longer periods of time.
5709 longer periods of time.
5687
5710
5688 Please note that the server does not implement access control.
5711 Please note that the server does not implement access control.
5689 This means that, by default, anybody can read from the server and
5712 This means that, by default, anybody can read from the server and
5690 nobody can write to it by default. Set the ``web.allow_push``
5713 nobody can write to it by default. Set the ``web.allow_push``
5691 option to ``*`` to allow everybody to push to the server. You
5714 option to ``*`` to allow everybody to push to the server. You
5692 should use a real web server if you need to authenticate users.
5715 should use a real web server if you need to authenticate users.
5693
5716
5694 By default, the server logs accesses to stdout and errors to
5717 By default, the server logs accesses to stdout and errors to
5695 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5718 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5696 files.
5719 files.
5697
5720
5698 To have the server choose a free port number to listen on, specify
5721 To have the server choose a free port number to listen on, specify
5699 a port number of 0; in this case, the server will print the port
5722 a port number of 0; in this case, the server will print the port
5700 number it uses.
5723 number it uses.
5701
5724
5702 Returns 0 on success.
5725 Returns 0 on success.
5703 """
5726 """
5704
5727
5705 if opts["stdio"] and opts["cmdserver"]:
5728 if opts["stdio"] and opts["cmdserver"]:
5706 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5729 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5707
5730
5708 if opts["stdio"]:
5731 if opts["stdio"]:
5709 if repo is None:
5732 if repo is None:
5710 raise error.RepoError(_("there is no Mercurial repository here"
5733 raise error.RepoError(_("there is no Mercurial repository here"
5711 " (.hg not found)"))
5734 " (.hg not found)"))
5712 s = sshserver.sshserver(ui, repo)
5735 s = sshserver.sshserver(ui, repo)
5713 s.serve_forever()
5736 s.serve_forever()
5714
5737
5715 if opts["cmdserver"]:
5738 if opts["cmdserver"]:
5716 import commandserver
5739 import commandserver
5717 service = commandserver.createservice(ui, repo, opts)
5740 service = commandserver.createservice(ui, repo, opts)
5718 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
5741 return cmdutil.service(opts, initfn=service.init, runfn=service.run)
5719
5742
5720 # this way we can check if something was given in the command-line
5743 # this way we can check if something was given in the command-line
5721 if opts.get('port'):
5744 if opts.get('port'):
5722 opts['port'] = util.getport(opts.get('port'))
5745 opts['port'] = util.getport(opts.get('port'))
5723
5746
5724 if repo:
5747 if repo:
5725 baseui = repo.baseui
5748 baseui = repo.baseui
5726 else:
5749 else:
5727 baseui = ui
5750 baseui = ui
5728 optlist = ("name templates style address port prefix ipv6"
5751 optlist = ("name templates style address port prefix ipv6"
5729 " accesslog errorlog certificate encoding")
5752 " accesslog errorlog certificate encoding")
5730 for o in optlist.split():
5753 for o in optlist.split():
5731 val = opts.get(o, '')
5754 val = opts.get(o, '')
5732 if val in (None, ''): # should check against default options instead
5755 if val in (None, ''): # should check against default options instead
5733 continue
5756 continue
5734 baseui.setconfig("web", o, val, 'serve')
5757 baseui.setconfig("web", o, val, 'serve')
5735 if repo and repo.ui != baseui:
5758 if repo and repo.ui != baseui:
5736 repo.ui.setconfig("web", o, val, 'serve')
5759 repo.ui.setconfig("web", o, val, 'serve')
5737
5760
5738 o = opts.get('web_conf') or opts.get('webdir_conf')
5761 o = opts.get('web_conf') or opts.get('webdir_conf')
5739 if not o:
5762 if not o:
5740 if not repo:
5763 if not repo:
5741 raise error.RepoError(_("there is no Mercurial repository"
5764 raise error.RepoError(_("there is no Mercurial repository"
5742 " here (.hg not found)"))
5765 " here (.hg not found)"))
5743 o = repo
5766 o = repo
5744
5767
5745 app = hgweb.hgweb(o, baseui=baseui)
5768 app = hgweb.hgweb(o, baseui=baseui)
5746 service = httpservice(ui, app, opts)
5769 service = httpservice(ui, app, opts)
5747 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5770 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5748
5771
5749 class httpservice(object):
5772 class httpservice(object):
5750 def __init__(self, ui, app, opts):
5773 def __init__(self, ui, app, opts):
5751 self.ui = ui
5774 self.ui = ui
5752 self.app = app
5775 self.app = app
5753 self.opts = opts
5776 self.opts = opts
5754
5777
5755 def init(self):
5778 def init(self):
5756 util.setsignalhandler()
5779 util.setsignalhandler()
5757 self.httpd = hgweb_server.create_server(self.ui, self.app)
5780 self.httpd = hgweb_server.create_server(self.ui, self.app)
5758
5781
5759 if self.opts['port'] and not self.ui.verbose:
5782 if self.opts['port'] and not self.ui.verbose:
5760 return
5783 return
5761
5784
5762 if self.httpd.prefix:
5785 if self.httpd.prefix:
5763 prefix = self.httpd.prefix.strip('/') + '/'
5786 prefix = self.httpd.prefix.strip('/') + '/'
5764 else:
5787 else:
5765 prefix = ''
5788 prefix = ''
5766
5789
5767 port = ':%d' % self.httpd.port
5790 port = ':%d' % self.httpd.port
5768 if port == ':80':
5791 if port == ':80':
5769 port = ''
5792 port = ''
5770
5793
5771 bindaddr = self.httpd.addr
5794 bindaddr = self.httpd.addr
5772 if bindaddr == '0.0.0.0':
5795 if bindaddr == '0.0.0.0':
5773 bindaddr = '*'
5796 bindaddr = '*'
5774 elif ':' in bindaddr: # IPv6
5797 elif ':' in bindaddr: # IPv6
5775 bindaddr = '[%s]' % bindaddr
5798 bindaddr = '[%s]' % bindaddr
5776
5799
5777 fqaddr = self.httpd.fqaddr
5800 fqaddr = self.httpd.fqaddr
5778 if ':' in fqaddr:
5801 if ':' in fqaddr:
5779 fqaddr = '[%s]' % fqaddr
5802 fqaddr = '[%s]' % fqaddr
5780 if self.opts['port']:
5803 if self.opts['port']:
5781 write = self.ui.status
5804 write = self.ui.status
5782 else:
5805 else:
5783 write = self.ui.write
5806 write = self.ui.write
5784 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5807 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5785 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5808 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5786 self.ui.flush() # avoid buffering of status message
5809 self.ui.flush() # avoid buffering of status message
5787
5810
5788 def run(self):
5811 def run(self):
5789 self.httpd.serve_forever()
5812 self.httpd.serve_forever()
5790
5813
5791
5814
5792 @command('^status|st',
5815 @command('^status|st',
5793 [('A', 'all', None, _('show status of all files')),
5816 [('A', 'all', None, _('show status of all files')),
5794 ('m', 'modified', None, _('show only modified files')),
5817 ('m', 'modified', None, _('show only modified files')),
5795 ('a', 'added', None, _('show only added files')),
5818 ('a', 'added', None, _('show only added files')),
5796 ('r', 'removed', None, _('show only removed files')),
5819 ('r', 'removed', None, _('show only removed files')),
5797 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5820 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5798 ('c', 'clean', None, _('show only files without changes')),
5821 ('c', 'clean', None, _('show only files without changes')),
5799 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5822 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5800 ('i', 'ignored', None, _('show only ignored files')),
5823 ('i', 'ignored', None, _('show only ignored files')),
5801 ('n', 'no-status', None, _('hide status prefix')),
5824 ('n', 'no-status', None, _('hide status prefix')),
5802 ('C', 'copies', None, _('show source of copied files')),
5825 ('C', 'copies', None, _('show source of copied files')),
5803 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5826 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5804 ('', 'rev', [], _('show difference from revision'), _('REV')),
5827 ('', 'rev', [], _('show difference from revision'), _('REV')),
5805 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5828 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5806 ] + walkopts + subrepoopts + formatteropts,
5829 ] + walkopts + subrepoopts + formatteropts,
5807 _('[OPTION]... [FILE]...'),
5830 _('[OPTION]... [FILE]...'),
5808 inferrepo=True)
5831 inferrepo=True)
5809 def status(ui, repo, *pats, **opts):
5832 def status(ui, repo, *pats, **opts):
5810 """show changed files in the working directory
5833 """show changed files in the working directory
5811
5834
5812 Show status of files in the repository. If names are given, only
5835 Show status of files in the repository. If names are given, only
5813 files that match are shown. Files that are clean or ignored or
5836 files that match are shown. Files that are clean or ignored or
5814 the source of a copy/move operation, are not listed unless
5837 the source of a copy/move operation, are not listed unless
5815 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5838 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5816 Unless options described with "show only ..." are given, the
5839 Unless options described with "show only ..." are given, the
5817 options -mardu are used.
5840 options -mardu are used.
5818
5841
5819 Option -q/--quiet hides untracked (unknown and ignored) files
5842 Option -q/--quiet hides untracked (unknown and ignored) files
5820 unless explicitly requested with -u/--unknown or -i/--ignored.
5843 unless explicitly requested with -u/--unknown or -i/--ignored.
5821
5844
5822 .. note::
5845 .. note::
5823
5846
5824 status may appear to disagree with diff if permissions have
5847 status may appear to disagree with diff if permissions have
5825 changed or a merge has occurred. The standard diff format does
5848 changed or a merge has occurred. The standard diff format does
5826 not report permission changes and diff only reports changes
5849 not report permission changes and diff only reports changes
5827 relative to one merge parent.
5850 relative to one merge parent.
5828
5851
5829 If one revision is given, it is used as the base revision.
5852 If one revision is given, it is used as the base revision.
5830 If two revisions are given, the differences between them are
5853 If two revisions are given, the differences between them are
5831 shown. The --change option can also be used as a shortcut to list
5854 shown. The --change option can also be used as a shortcut to list
5832 the changed files of a revision from its first parent.
5855 the changed files of a revision from its first parent.
5833
5856
5834 The codes used to show the status of files are::
5857 The codes used to show the status of files are::
5835
5858
5836 M = modified
5859 M = modified
5837 A = added
5860 A = added
5838 R = removed
5861 R = removed
5839 C = clean
5862 C = clean
5840 ! = missing (deleted by non-hg command, but still tracked)
5863 ! = missing (deleted by non-hg command, but still tracked)
5841 ? = not tracked
5864 ? = not tracked
5842 I = ignored
5865 I = ignored
5843 = origin of the previous file (with --copies)
5866 = origin of the previous file (with --copies)
5844
5867
5845 .. container:: verbose
5868 .. container:: verbose
5846
5869
5847 Examples:
5870 Examples:
5848
5871
5849 - show changes in the working directory relative to a
5872 - show changes in the working directory relative to a
5850 changeset::
5873 changeset::
5851
5874
5852 hg status --rev 9353
5875 hg status --rev 9353
5853
5876
5854 - show changes in the working directory relative to the
5877 - show changes in the working directory relative to the
5855 current directory (see :hg:`help patterns` for more information)::
5878 current directory (see :hg:`help patterns` for more information)::
5856
5879
5857 hg status re:
5880 hg status re:
5858
5881
5859 - show all changes including copies in an existing changeset::
5882 - show all changes including copies in an existing changeset::
5860
5883
5861 hg status --copies --change 9353
5884 hg status --copies --change 9353
5862
5885
5863 - get a NUL separated list of added files, suitable for xargs::
5886 - get a NUL separated list of added files, suitable for xargs::
5864
5887
5865 hg status -an0
5888 hg status -an0
5866
5889
5867 Returns 0 on success.
5890 Returns 0 on success.
5868 """
5891 """
5869
5892
5870 revs = opts.get('rev')
5893 revs = opts.get('rev')
5871 change = opts.get('change')
5894 change = opts.get('change')
5872
5895
5873 if revs and change:
5896 if revs and change:
5874 msg = _('cannot specify --rev and --change at the same time')
5897 msg = _('cannot specify --rev and --change at the same time')
5875 raise util.Abort(msg)
5898 raise util.Abort(msg)
5876 elif change:
5899 elif change:
5877 node2 = scmutil.revsingle(repo, change, None).node()
5900 node2 = scmutil.revsingle(repo, change, None).node()
5878 node1 = repo[node2].p1().node()
5901 node1 = repo[node2].p1().node()
5879 else:
5902 else:
5880 node1, node2 = scmutil.revpair(repo, revs)
5903 node1, node2 = scmutil.revpair(repo, revs)
5881
5904
5882 if pats:
5905 if pats:
5883 cwd = repo.getcwd()
5906 cwd = repo.getcwd()
5884 else:
5907 else:
5885 cwd = ''
5908 cwd = ''
5886
5909
5887 if opts.get('print0'):
5910 if opts.get('print0'):
5888 end = '\0'
5911 end = '\0'
5889 else:
5912 else:
5890 end = '\n'
5913 end = '\n'
5891 copy = {}
5914 copy = {}
5892 states = 'modified added removed deleted unknown ignored clean'.split()
5915 states = 'modified added removed deleted unknown ignored clean'.split()
5893 show = [k for k in states if opts.get(k)]
5916 show = [k for k in states if opts.get(k)]
5894 if opts.get('all'):
5917 if opts.get('all'):
5895 show += ui.quiet and (states[:4] + ['clean']) or states
5918 show += ui.quiet and (states[:4] + ['clean']) or states
5896 if not show:
5919 if not show:
5897 if ui.quiet:
5920 if ui.quiet:
5898 show = states[:4]
5921 show = states[:4]
5899 else:
5922 else:
5900 show = states[:5]
5923 show = states[:5]
5901
5924
5902 m = scmutil.match(repo[node2], pats, opts)
5925 m = scmutil.match(repo[node2], pats, opts)
5903 stat = repo.status(node1, node2, m,
5926 stat = repo.status(node1, node2, m,
5904 'ignored' in show, 'clean' in show, 'unknown' in show,
5927 'ignored' in show, 'clean' in show, 'unknown' in show,
5905 opts.get('subrepos'))
5928 opts.get('subrepos'))
5906 changestates = zip(states, 'MAR!?IC', stat)
5929 changestates = zip(states, 'MAR!?IC', stat)
5907
5930
5908 if (opts.get('all') or opts.get('copies')
5931 if (opts.get('all') or opts.get('copies')
5909 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5932 or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
5910 copy = copies.pathcopies(repo[node1], repo[node2], m)
5933 copy = copies.pathcopies(repo[node1], repo[node2], m)
5911
5934
5912 fm = ui.formatter('status', opts)
5935 fm = ui.formatter('status', opts)
5913 fmt = '%s' + end
5936 fmt = '%s' + end
5914 showchar = not opts.get('no_status')
5937 showchar = not opts.get('no_status')
5915
5938
5916 for state, char, files in changestates:
5939 for state, char, files in changestates:
5917 if state in show:
5940 if state in show:
5918 label = 'status.' + state
5941 label = 'status.' + state
5919 for f in files:
5942 for f in files:
5920 fm.startitem()
5943 fm.startitem()
5921 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5944 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5922 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5945 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5923 if f in copy:
5946 if f in copy:
5924 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5947 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5925 label='status.copied')
5948 label='status.copied')
5926 fm.end()
5949 fm.end()
5927
5950
5928 @command('^summary|sum',
5951 @command('^summary|sum',
5929 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5952 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5930 def summary(ui, repo, **opts):
5953 def summary(ui, repo, **opts):
5931 """summarize working directory state
5954 """summarize working directory state
5932
5955
5933 This generates a brief summary of the working directory state,
5956 This generates a brief summary of the working directory state,
5934 including parents, branch, commit status, phase and available updates.
5957 including parents, branch, commit status, phase and available updates.
5935
5958
5936 With the --remote option, this will check the default paths for
5959 With the --remote option, this will check the default paths for
5937 incoming and outgoing changes. This can be time-consuming.
5960 incoming and outgoing changes. This can be time-consuming.
5938
5961
5939 Returns 0 on success.
5962 Returns 0 on success.
5940 """
5963 """
5941
5964
5942 ctx = repo[None]
5965 ctx = repo[None]
5943 parents = ctx.parents()
5966 parents = ctx.parents()
5944 pnode = parents[0].node()
5967 pnode = parents[0].node()
5945 marks = []
5968 marks = []
5946
5969
5947 for p in parents:
5970 for p in parents:
5948 # label with log.changeset (instead of log.parent) since this
5971 # label with log.changeset (instead of log.parent) since this
5949 # shows a working directory parent *changeset*:
5972 # shows a working directory parent *changeset*:
5950 # i18n: column positioning for "hg summary"
5973 # i18n: column positioning for "hg summary"
5951 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5974 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5952 label='log.changeset changeset.%s' % p.phasestr())
5975 label='log.changeset changeset.%s' % p.phasestr())
5953 ui.write(' '.join(p.tags()), label='log.tag')
5976 ui.write(' '.join(p.tags()), label='log.tag')
5954 if p.bookmarks():
5977 if p.bookmarks():
5955 marks.extend(p.bookmarks())
5978 marks.extend(p.bookmarks())
5956 if p.rev() == -1:
5979 if p.rev() == -1:
5957 if not len(repo):
5980 if not len(repo):
5958 ui.write(_(' (empty repository)'))
5981 ui.write(_(' (empty repository)'))
5959 else:
5982 else:
5960 ui.write(_(' (no revision checked out)'))
5983 ui.write(_(' (no revision checked out)'))
5961 ui.write('\n')
5984 ui.write('\n')
5962 if p.description():
5985 if p.description():
5963 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5986 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5964 label='log.summary')
5987 label='log.summary')
5965
5988
5966 branch = ctx.branch()
5989 branch = ctx.branch()
5967 bheads = repo.branchheads(branch)
5990 bheads = repo.branchheads(branch)
5968 # i18n: column positioning for "hg summary"
5991 # i18n: column positioning for "hg summary"
5969 m = _('branch: %s\n') % branch
5992 m = _('branch: %s\n') % branch
5970 if branch != 'default':
5993 if branch != 'default':
5971 ui.write(m, label='log.branch')
5994 ui.write(m, label='log.branch')
5972 else:
5995 else:
5973 ui.status(m, label='log.branch')
5996 ui.status(m, label='log.branch')
5974
5997
5975 if marks:
5998 if marks:
5976 active = repo._activebookmark
5999 active = repo._activebookmark
5977 # i18n: column positioning for "hg summary"
6000 # i18n: column positioning for "hg summary"
5978 ui.write(_('bookmarks:'), label='log.bookmark')
6001 ui.write(_('bookmarks:'), label='log.bookmark')
5979 if active is not None:
6002 if active is not None:
5980 if active in marks:
6003 if active in marks:
5981 ui.write(' *' + active, label=activebookmarklabel)
6004 ui.write(' *' + active, label=activebookmarklabel)
5982 marks.remove(active)
6005 marks.remove(active)
5983 else:
6006 else:
5984 ui.write(' [%s]' % active, label=activebookmarklabel)
6007 ui.write(' [%s]' % active, label=activebookmarklabel)
5985 for m in marks:
6008 for m in marks:
5986 ui.write(' ' + m, label='log.bookmark')
6009 ui.write(' ' + m, label='log.bookmark')
5987 ui.write('\n', label='log.bookmark')
6010 ui.write('\n', label='log.bookmark')
5988
6011
5989 status = repo.status(unknown=True)
6012 status = repo.status(unknown=True)
5990
6013
5991 c = repo.dirstate.copies()
6014 c = repo.dirstate.copies()
5992 copied, renamed = [], []
6015 copied, renamed = [], []
5993 for d, s in c.iteritems():
6016 for d, s in c.iteritems():
5994 if s in status.removed:
6017 if s in status.removed:
5995 status.removed.remove(s)
6018 status.removed.remove(s)
5996 renamed.append(d)
6019 renamed.append(d)
5997 else:
6020 else:
5998 copied.append(d)
6021 copied.append(d)
5999 if d in status.added:
6022 if d in status.added:
6000 status.added.remove(d)
6023 status.added.remove(d)
6001
6024
6002 ms = mergemod.mergestate(repo)
6025 ms = mergemod.mergestate(repo)
6003 unresolved = [f for f in ms if ms[f] == 'u']
6026 unresolved = [f for f in ms if ms[f] == 'u']
6004
6027
6005 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6028 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
6006
6029
6007 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
6030 labels = [(ui.label(_('%d modified'), 'status.modified'), status.modified),
6008 (ui.label(_('%d added'), 'status.added'), status.added),
6031 (ui.label(_('%d added'), 'status.added'), status.added),
6009 (ui.label(_('%d removed'), 'status.removed'), status.removed),
6032 (ui.label(_('%d removed'), 'status.removed'), status.removed),
6010 (ui.label(_('%d renamed'), 'status.copied'), renamed),
6033 (ui.label(_('%d renamed'), 'status.copied'), renamed),
6011 (ui.label(_('%d copied'), 'status.copied'), copied),
6034 (ui.label(_('%d copied'), 'status.copied'), copied),
6012 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
6035 (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
6013 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
6036 (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
6014 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6037 (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
6015 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
6038 (ui.label(_('%d subrepos'), 'status.modified'), subs)]
6016 t = []
6039 t = []
6017 for l, s in labels:
6040 for l, s in labels:
6018 if s:
6041 if s:
6019 t.append(l % len(s))
6042 t.append(l % len(s))
6020
6043
6021 t = ', '.join(t)
6044 t = ', '.join(t)
6022 cleanworkdir = False
6045 cleanworkdir = False
6023
6046
6024 if repo.vfs.exists('updatestate'):
6047 if repo.vfs.exists('updatestate'):
6025 t += _(' (interrupted update)')
6048 t += _(' (interrupted update)')
6026 elif len(parents) > 1:
6049 elif len(parents) > 1:
6027 t += _(' (merge)')
6050 t += _(' (merge)')
6028 elif branch != parents[0].branch():
6051 elif branch != parents[0].branch():
6029 t += _(' (new branch)')
6052 t += _(' (new branch)')
6030 elif (parents[0].closesbranch() and
6053 elif (parents[0].closesbranch() and
6031 pnode in repo.branchheads(branch, closed=True)):
6054 pnode in repo.branchheads(branch, closed=True)):
6032 t += _(' (head closed)')
6055 t += _(' (head closed)')
6033 elif not (status.modified or status.added or status.removed or renamed or
6056 elif not (status.modified or status.added or status.removed or renamed or
6034 copied or subs):
6057 copied or subs):
6035 t += _(' (clean)')
6058 t += _(' (clean)')
6036 cleanworkdir = True
6059 cleanworkdir = True
6037 elif pnode not in bheads:
6060 elif pnode not in bheads:
6038 t += _(' (new branch head)')
6061 t += _(' (new branch head)')
6039
6062
6040 if parents:
6063 if parents:
6041 pendingphase = max(p.phase() for p in parents)
6064 pendingphase = max(p.phase() for p in parents)
6042 else:
6065 else:
6043 pendingphase = phases.public
6066 pendingphase = phases.public
6044
6067
6045 if pendingphase > phases.newcommitphase(ui):
6068 if pendingphase > phases.newcommitphase(ui):
6046 t += ' (%s)' % phases.phasenames[pendingphase]
6069 t += ' (%s)' % phases.phasenames[pendingphase]
6047
6070
6048 if cleanworkdir:
6071 if cleanworkdir:
6049 # i18n: column positioning for "hg summary"
6072 # i18n: column positioning for "hg summary"
6050 ui.status(_('commit: %s\n') % t.strip())
6073 ui.status(_('commit: %s\n') % t.strip())
6051 else:
6074 else:
6052 # i18n: column positioning for "hg summary"
6075 # i18n: column positioning for "hg summary"
6053 ui.write(_('commit: %s\n') % t.strip())
6076 ui.write(_('commit: %s\n') % t.strip())
6054
6077
6055 # all ancestors of branch heads - all ancestors of parent = new csets
6078 # all ancestors of branch heads - all ancestors of parent = new csets
6056 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
6079 new = len(repo.changelog.findmissing([pctx.node() for pctx in parents],
6057 bheads))
6080 bheads))
6058
6081
6059 if new == 0:
6082 if new == 0:
6060 # i18n: column positioning for "hg summary"
6083 # i18n: column positioning for "hg summary"
6061 ui.status(_('update: (current)\n'))
6084 ui.status(_('update: (current)\n'))
6062 elif pnode not in bheads:
6085 elif pnode not in bheads:
6063 # i18n: column positioning for "hg summary"
6086 # i18n: column positioning for "hg summary"
6064 ui.write(_('update: %d new changesets (update)\n') % new)
6087 ui.write(_('update: %d new changesets (update)\n') % new)
6065 else:
6088 else:
6066 # i18n: column positioning for "hg summary"
6089 # i18n: column positioning for "hg summary"
6067 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
6090 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
6068 (new, len(bheads)))
6091 (new, len(bheads)))
6069
6092
6070 t = []
6093 t = []
6071 draft = len(repo.revs('draft()'))
6094 draft = len(repo.revs('draft()'))
6072 if draft:
6095 if draft:
6073 t.append(_('%d draft') % draft)
6096 t.append(_('%d draft') % draft)
6074 secret = len(repo.revs('secret()'))
6097 secret = len(repo.revs('secret()'))
6075 if secret:
6098 if secret:
6076 t.append(_('%d secret') % secret)
6099 t.append(_('%d secret') % secret)
6077
6100
6078 if draft or secret:
6101 if draft or secret:
6079 ui.status(_('phases: %s\n') % ', '.join(t))
6102 ui.status(_('phases: %s\n') % ', '.join(t))
6080
6103
6081 cmdutil.summaryhooks(ui, repo)
6104 cmdutil.summaryhooks(ui, repo)
6082
6105
6083 if opts.get('remote'):
6106 if opts.get('remote'):
6084 needsincoming, needsoutgoing = True, True
6107 needsincoming, needsoutgoing = True, True
6085 else:
6108 else:
6086 needsincoming, needsoutgoing = False, False
6109 needsincoming, needsoutgoing = False, False
6087 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
6110 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
6088 if i:
6111 if i:
6089 needsincoming = True
6112 needsincoming = True
6090 if o:
6113 if o:
6091 needsoutgoing = True
6114 needsoutgoing = True
6092 if not needsincoming and not needsoutgoing:
6115 if not needsincoming and not needsoutgoing:
6093 return
6116 return
6094
6117
6095 def getincoming():
6118 def getincoming():
6096 source, branches = hg.parseurl(ui.expandpath('default'))
6119 source, branches = hg.parseurl(ui.expandpath('default'))
6097 sbranch = branches[0]
6120 sbranch = branches[0]
6098 try:
6121 try:
6099 other = hg.peer(repo, {}, source)
6122 other = hg.peer(repo, {}, source)
6100 except error.RepoError:
6123 except error.RepoError:
6101 if opts.get('remote'):
6124 if opts.get('remote'):
6102 raise
6125 raise
6103 return source, sbranch, None, None, None
6126 return source, sbranch, None, None, None
6104 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
6127 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
6105 if revs:
6128 if revs:
6106 revs = [other.lookup(rev) for rev in revs]
6129 revs = [other.lookup(rev) for rev in revs]
6107 ui.debug('comparing with %s\n' % util.hidepassword(source))
6130 ui.debug('comparing with %s\n' % util.hidepassword(source))
6108 repo.ui.pushbuffer()
6131 repo.ui.pushbuffer()
6109 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
6132 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
6110 repo.ui.popbuffer()
6133 repo.ui.popbuffer()
6111 return source, sbranch, other, commoninc, commoninc[1]
6134 return source, sbranch, other, commoninc, commoninc[1]
6112
6135
6113 if needsincoming:
6136 if needsincoming:
6114 source, sbranch, sother, commoninc, incoming = getincoming()
6137 source, sbranch, sother, commoninc, incoming = getincoming()
6115 else:
6138 else:
6116 source = sbranch = sother = commoninc = incoming = None
6139 source = sbranch = sother = commoninc = incoming = None
6117
6140
6118 def getoutgoing():
6141 def getoutgoing():
6119 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
6142 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
6120 dbranch = branches[0]
6143 dbranch = branches[0]
6121 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
6144 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
6122 if source != dest:
6145 if source != dest:
6123 try:
6146 try:
6124 dother = hg.peer(repo, {}, dest)
6147 dother = hg.peer(repo, {}, dest)
6125 except error.RepoError:
6148 except error.RepoError:
6126 if opts.get('remote'):
6149 if opts.get('remote'):
6127 raise
6150 raise
6128 return dest, dbranch, None, None
6151 return dest, dbranch, None, None
6129 ui.debug('comparing with %s\n' % util.hidepassword(dest))
6152 ui.debug('comparing with %s\n' % util.hidepassword(dest))
6130 elif sother is None:
6153 elif sother is None:
6131 # there is no explicit destination peer, but source one is invalid
6154 # there is no explicit destination peer, but source one is invalid
6132 return dest, dbranch, None, None
6155 return dest, dbranch, None, None
6133 else:
6156 else:
6134 dother = sother
6157 dother = sother
6135 if (source != dest or (sbranch is not None and sbranch != dbranch)):
6158 if (source != dest or (sbranch is not None and sbranch != dbranch)):
6136 common = None
6159 common = None
6137 else:
6160 else:
6138 common = commoninc
6161 common = commoninc
6139 if revs:
6162 if revs:
6140 revs = [repo.lookup(rev) for rev in revs]
6163 revs = [repo.lookup(rev) for rev in revs]
6141 repo.ui.pushbuffer()
6164 repo.ui.pushbuffer()
6142 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
6165 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
6143 commoninc=common)
6166 commoninc=common)
6144 repo.ui.popbuffer()
6167 repo.ui.popbuffer()
6145 return dest, dbranch, dother, outgoing
6168 return dest, dbranch, dother, outgoing
6146
6169
6147 if needsoutgoing:
6170 if needsoutgoing:
6148 dest, dbranch, dother, outgoing = getoutgoing()
6171 dest, dbranch, dother, outgoing = getoutgoing()
6149 else:
6172 else:
6150 dest = dbranch = dother = outgoing = None
6173 dest = dbranch = dother = outgoing = None
6151
6174
6152 if opts.get('remote'):
6175 if opts.get('remote'):
6153 t = []
6176 t = []
6154 if incoming:
6177 if incoming:
6155 t.append(_('1 or more incoming'))
6178 t.append(_('1 or more incoming'))
6156 o = outgoing.missing
6179 o = outgoing.missing
6157 if o:
6180 if o:
6158 t.append(_('%d outgoing') % len(o))
6181 t.append(_('%d outgoing') % len(o))
6159 other = dother or sother
6182 other = dother or sother
6160 if 'bookmarks' in other.listkeys('namespaces'):
6183 if 'bookmarks' in other.listkeys('namespaces'):
6161 counts = bookmarks.summary(repo, other)
6184 counts = bookmarks.summary(repo, other)
6162 if counts[0] > 0:
6185 if counts[0] > 0:
6163 t.append(_('%d incoming bookmarks') % counts[0])
6186 t.append(_('%d incoming bookmarks') % counts[0])
6164 if counts[1] > 0:
6187 if counts[1] > 0:
6165 t.append(_('%d outgoing bookmarks') % counts[1])
6188 t.append(_('%d outgoing bookmarks') % counts[1])
6166
6189
6167 if t:
6190 if t:
6168 # i18n: column positioning for "hg summary"
6191 # i18n: column positioning for "hg summary"
6169 ui.write(_('remote: %s\n') % (', '.join(t)))
6192 ui.write(_('remote: %s\n') % (', '.join(t)))
6170 else:
6193 else:
6171 # i18n: column positioning for "hg summary"
6194 # i18n: column positioning for "hg summary"
6172 ui.status(_('remote: (synced)\n'))
6195 ui.status(_('remote: (synced)\n'))
6173
6196
6174 cmdutil.summaryremotehooks(ui, repo, opts,
6197 cmdutil.summaryremotehooks(ui, repo, opts,
6175 ((source, sbranch, sother, commoninc),
6198 ((source, sbranch, sother, commoninc),
6176 (dest, dbranch, dother, outgoing)))
6199 (dest, dbranch, dother, outgoing)))
6177
6200
6178 @command('tag',
6201 @command('tag',
6179 [('f', 'force', None, _('force tag')),
6202 [('f', 'force', None, _('force tag')),
6180 ('l', 'local', None, _('make the tag local')),
6203 ('l', 'local', None, _('make the tag local')),
6181 ('r', 'rev', '', _('revision to tag'), _('REV')),
6204 ('r', 'rev', '', _('revision to tag'), _('REV')),
6182 ('', 'remove', None, _('remove a tag')),
6205 ('', 'remove', None, _('remove a tag')),
6183 # -l/--local is already there, commitopts cannot be used
6206 # -l/--local is already there, commitopts cannot be used
6184 ('e', 'edit', None, _('invoke editor on commit messages')),
6207 ('e', 'edit', None, _('invoke editor on commit messages')),
6185 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6208 ('m', 'message', '', _('use text as commit message'), _('TEXT')),
6186 ] + commitopts2,
6209 ] + commitopts2,
6187 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6210 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
6188 def tag(ui, repo, name1, *names, **opts):
6211 def tag(ui, repo, name1, *names, **opts):
6189 """add one or more tags for the current or given revision
6212 """add one or more tags for the current or given revision
6190
6213
6191 Name a particular revision using <name>.
6214 Name a particular revision using <name>.
6192
6215
6193 Tags are used to name particular revisions of the repository and are
6216 Tags are used to name particular revisions of the repository and are
6194 very useful to compare different revisions, to go back to significant
6217 very useful to compare different revisions, to go back to significant
6195 earlier versions or to mark branch points as releases, etc. Changing
6218 earlier versions or to mark branch points as releases, etc. Changing
6196 an existing tag is normally disallowed; use -f/--force to override.
6219 an existing tag is normally disallowed; use -f/--force to override.
6197
6220
6198 If no revision is given, the parent of the working directory is
6221 If no revision is given, the parent of the working directory is
6199 used.
6222 used.
6200
6223
6201 To facilitate version control, distribution, and merging of tags,
6224 To facilitate version control, distribution, and merging of tags,
6202 they are stored as a file named ".hgtags" which is managed similarly
6225 they are stored as a file named ".hgtags" which is managed similarly
6203 to other project files and can be hand-edited if necessary. This
6226 to other project files and can be hand-edited if necessary. This
6204 also means that tagging creates a new commit. The file
6227 also means that tagging creates a new commit. The file
6205 ".hg/localtags" is used for local tags (not shared among
6228 ".hg/localtags" is used for local tags (not shared among
6206 repositories).
6229 repositories).
6207
6230
6208 Tag commits are usually made at the head of a branch. If the parent
6231 Tag commits are usually made at the head of a branch. If the parent
6209 of the working directory is not a branch head, :hg:`tag` aborts; use
6232 of the working directory is not a branch head, :hg:`tag` aborts; use
6210 -f/--force to force the tag commit to be based on a non-head
6233 -f/--force to force the tag commit to be based on a non-head
6211 changeset.
6234 changeset.
6212
6235
6213 See :hg:`help dates` for a list of formats valid for -d/--date.
6236 See :hg:`help dates` for a list of formats valid for -d/--date.
6214
6237
6215 Since tag names have priority over branch names during revision
6238 Since tag names have priority over branch names during revision
6216 lookup, using an existing branch name as a tag name is discouraged.
6239 lookup, using an existing branch name as a tag name is discouraged.
6217
6240
6218 Returns 0 on success.
6241 Returns 0 on success.
6219 """
6242 """
6220 wlock = lock = None
6243 wlock = lock = None
6221 try:
6244 try:
6222 wlock = repo.wlock()
6245 wlock = repo.wlock()
6223 lock = repo.lock()
6246 lock = repo.lock()
6224 rev_ = "."
6247 rev_ = "."
6225 names = [t.strip() for t in (name1,) + names]
6248 names = [t.strip() for t in (name1,) + names]
6226 if len(names) != len(set(names)):
6249 if len(names) != len(set(names)):
6227 raise util.Abort(_('tag names must be unique'))
6250 raise util.Abort(_('tag names must be unique'))
6228 for n in names:
6251 for n in names:
6229 scmutil.checknewlabel(repo, n, 'tag')
6252 scmutil.checknewlabel(repo, n, 'tag')
6230 if not n:
6253 if not n:
6231 raise util.Abort(_('tag names cannot consist entirely of '
6254 raise util.Abort(_('tag names cannot consist entirely of '
6232 'whitespace'))
6255 'whitespace'))
6233 if opts.get('rev') and opts.get('remove'):
6256 if opts.get('rev') and opts.get('remove'):
6234 raise util.Abort(_("--rev and --remove are incompatible"))
6257 raise util.Abort(_("--rev and --remove are incompatible"))
6235 if opts.get('rev'):
6258 if opts.get('rev'):
6236 rev_ = opts['rev']
6259 rev_ = opts['rev']
6237 message = opts.get('message')
6260 message = opts.get('message')
6238 if opts.get('remove'):
6261 if opts.get('remove'):
6239 if opts.get('local'):
6262 if opts.get('local'):
6240 expectedtype = 'local'
6263 expectedtype = 'local'
6241 else:
6264 else:
6242 expectedtype = 'global'
6265 expectedtype = 'global'
6243
6266
6244 for n in names:
6267 for n in names:
6245 if not repo.tagtype(n):
6268 if not repo.tagtype(n):
6246 raise util.Abort(_("tag '%s' does not exist") % n)
6269 raise util.Abort(_("tag '%s' does not exist") % n)
6247 if repo.tagtype(n) != expectedtype:
6270 if repo.tagtype(n) != expectedtype:
6248 if expectedtype == 'global':
6271 if expectedtype == 'global':
6249 raise util.Abort(_("tag '%s' is not a global tag") % n)
6272 raise util.Abort(_("tag '%s' is not a global tag") % n)
6250 else:
6273 else:
6251 raise util.Abort(_("tag '%s' is not a local tag") % n)
6274 raise util.Abort(_("tag '%s' is not a local tag") % n)
6252 rev_ = 'null'
6275 rev_ = 'null'
6253 if not message:
6276 if not message:
6254 # we don't translate commit messages
6277 # we don't translate commit messages
6255 message = 'Removed tag %s' % ', '.join(names)
6278 message = 'Removed tag %s' % ', '.join(names)
6256 elif not opts.get('force'):
6279 elif not opts.get('force'):
6257 for n in names:
6280 for n in names:
6258 if n in repo.tags():
6281 if n in repo.tags():
6259 raise util.Abort(_("tag '%s' already exists "
6282 raise util.Abort(_("tag '%s' already exists "
6260 "(use -f to force)") % n)
6283 "(use -f to force)") % n)
6261 if not opts.get('local'):
6284 if not opts.get('local'):
6262 p1, p2 = repo.dirstate.parents()
6285 p1, p2 = repo.dirstate.parents()
6263 if p2 != nullid:
6286 if p2 != nullid:
6264 raise util.Abort(_('uncommitted merge'))
6287 raise util.Abort(_('uncommitted merge'))
6265 bheads = repo.branchheads()
6288 bheads = repo.branchheads()
6266 if not opts.get('force') and bheads and p1 not in bheads:
6289 if not opts.get('force') and bheads and p1 not in bheads:
6267 raise util.Abort(_('not at a branch head (use -f to force)'))
6290 raise util.Abort(_('not at a branch head (use -f to force)'))
6268 r = scmutil.revsingle(repo, rev_).node()
6291 r = scmutil.revsingle(repo, rev_).node()
6269
6292
6270 if not message:
6293 if not message:
6271 # we don't translate commit messages
6294 # we don't translate commit messages
6272 message = ('Added tag %s for changeset %s' %
6295 message = ('Added tag %s for changeset %s' %
6273 (', '.join(names), short(r)))
6296 (', '.join(names), short(r)))
6274
6297
6275 date = opts.get('date')
6298 date = opts.get('date')
6276 if date:
6299 if date:
6277 date = util.parsedate(date)
6300 date = util.parsedate(date)
6278
6301
6279 if opts.get('remove'):
6302 if opts.get('remove'):
6280 editform = 'tag.remove'
6303 editform = 'tag.remove'
6281 else:
6304 else:
6282 editform = 'tag.add'
6305 editform = 'tag.add'
6283 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6306 editor = cmdutil.getcommiteditor(editform=editform, **opts)
6284
6307
6285 # don't allow tagging the null rev
6308 # don't allow tagging the null rev
6286 if (not opts.get('remove') and
6309 if (not opts.get('remove') and
6287 scmutil.revsingle(repo, rev_).rev() == nullrev):
6310 scmutil.revsingle(repo, rev_).rev() == nullrev):
6288 raise util.Abort(_("cannot tag null revision"))
6311 raise util.Abort(_("cannot tag null revision"))
6289
6312
6290 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6313 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
6291 editor=editor)
6314 editor=editor)
6292 finally:
6315 finally:
6293 release(lock, wlock)
6316 release(lock, wlock)
6294
6317
6295 @command('tags', formatteropts, '')
6318 @command('tags', formatteropts, '')
6296 def tags(ui, repo, **opts):
6319 def tags(ui, repo, **opts):
6297 """list repository tags
6320 """list repository tags
6298
6321
6299 This lists both regular and local tags. When the -v/--verbose
6322 This lists both regular and local tags. When the -v/--verbose
6300 switch is used, a third column "local" is printed for local tags.
6323 switch is used, a third column "local" is printed for local tags.
6301
6324
6302 Returns 0 on success.
6325 Returns 0 on success.
6303 """
6326 """
6304
6327
6305 fm = ui.formatter('tags', opts)
6328 fm = ui.formatter('tags', opts)
6306 hexfunc = fm.hexfunc
6329 hexfunc = fm.hexfunc
6307 tagtype = ""
6330 tagtype = ""
6308
6331
6309 for t, n in reversed(repo.tagslist()):
6332 for t, n in reversed(repo.tagslist()):
6310 hn = hexfunc(n)
6333 hn = hexfunc(n)
6311 label = 'tags.normal'
6334 label = 'tags.normal'
6312 tagtype = ''
6335 tagtype = ''
6313 if repo.tagtype(t) == 'local':
6336 if repo.tagtype(t) == 'local':
6314 label = 'tags.local'
6337 label = 'tags.local'
6315 tagtype = 'local'
6338 tagtype = 'local'
6316
6339
6317 fm.startitem()
6340 fm.startitem()
6318 fm.write('tag', '%s', t, label=label)
6341 fm.write('tag', '%s', t, label=label)
6319 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6342 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
6320 fm.condwrite(not ui.quiet, 'rev node', fmt,
6343 fm.condwrite(not ui.quiet, 'rev node', fmt,
6321 repo.changelog.rev(n), hn, label=label)
6344 repo.changelog.rev(n), hn, label=label)
6322 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6345 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
6323 tagtype, label=label)
6346 tagtype, label=label)
6324 fm.plain('\n')
6347 fm.plain('\n')
6325 fm.end()
6348 fm.end()
6326
6349
6327 @command('tip',
6350 @command('tip',
6328 [('p', 'patch', None, _('show patch')),
6351 [('p', 'patch', None, _('show patch')),
6329 ('g', 'git', None, _('use git extended diff format')),
6352 ('g', 'git', None, _('use git extended diff format')),
6330 ] + templateopts,
6353 ] + templateopts,
6331 _('[-p] [-g]'))
6354 _('[-p] [-g]'))
6332 def tip(ui, repo, **opts):
6355 def tip(ui, repo, **opts):
6333 """show the tip revision (DEPRECATED)
6356 """show the tip revision (DEPRECATED)
6334
6357
6335 The tip revision (usually just called the tip) is the changeset
6358 The tip revision (usually just called the tip) is the changeset
6336 most recently added to the repository (and therefore the most
6359 most recently added to the repository (and therefore the most
6337 recently changed head).
6360 recently changed head).
6338
6361
6339 If you have just made a commit, that commit will be the tip. If
6362 If you have just made a commit, that commit will be the tip. If
6340 you have just pulled changes from another repository, the tip of
6363 you have just pulled changes from another repository, the tip of
6341 that repository becomes the current tip. The "tip" tag is special
6364 that repository becomes the current tip. The "tip" tag is special
6342 and cannot be renamed or assigned to a different changeset.
6365 and cannot be renamed or assigned to a different changeset.
6343
6366
6344 This command is deprecated, please use :hg:`heads` instead.
6367 This command is deprecated, please use :hg:`heads` instead.
6345
6368
6346 Returns 0 on success.
6369 Returns 0 on success.
6347 """
6370 """
6348 displayer = cmdutil.show_changeset(ui, repo, opts)
6371 displayer = cmdutil.show_changeset(ui, repo, opts)
6349 displayer.show(repo['tip'])
6372 displayer.show(repo['tip'])
6350 displayer.close()
6373 displayer.close()
6351
6374
6352 @command('unbundle',
6375 @command('unbundle',
6353 [('u', 'update', None,
6376 [('u', 'update', None,
6354 _('update to new branch head if changesets were unbundled'))],
6377 _('update to new branch head if changesets were unbundled'))],
6355 _('[-u] FILE...'))
6378 _('[-u] FILE...'))
6356 def unbundle(ui, repo, fname1, *fnames, **opts):
6379 def unbundle(ui, repo, fname1, *fnames, **opts):
6357 """apply one or more changegroup files
6380 """apply one or more changegroup files
6358
6381
6359 Apply one or more compressed changegroup files generated by the
6382 Apply one or more compressed changegroup files generated by the
6360 bundle command.
6383 bundle command.
6361
6384
6362 Returns 0 on success, 1 if an update has unresolved files.
6385 Returns 0 on success, 1 if an update has unresolved files.
6363 """
6386 """
6364 fnames = (fname1,) + fnames
6387 fnames = (fname1,) + fnames
6365
6388
6366 lock = repo.lock()
6389 lock = repo.lock()
6367 try:
6390 try:
6368 for fname in fnames:
6391 for fname in fnames:
6369 f = hg.openpath(ui, fname)
6392 f = hg.openpath(ui, fname)
6370 gen = exchange.readbundle(ui, f, fname)
6393 gen = exchange.readbundle(ui, f, fname)
6371 if isinstance(gen, bundle2.unbundle20):
6394 if isinstance(gen, bundle2.unbundle20):
6372 tr = repo.transaction('unbundle')
6395 tr = repo.transaction('unbundle')
6373 try:
6396 try:
6374 op = bundle2.processbundle(repo, gen, lambda: tr)
6397 op = bundle2.processbundle(repo, gen, lambda: tr)
6375 tr.close()
6398 tr.close()
6376 finally:
6399 finally:
6377 if tr:
6400 if tr:
6378 tr.release()
6401 tr.release()
6379 changes = [r.get('result', 0)
6402 changes = [r.get('result', 0)
6380 for r in op.records['changegroup']]
6403 for r in op.records['changegroup']]
6381 modheads = changegroup.combineresults(changes)
6404 modheads = changegroup.combineresults(changes)
6382 else:
6405 else:
6383 modheads = changegroup.addchangegroup(repo, gen, 'unbundle',
6406 modheads = changegroup.addchangegroup(repo, gen, 'unbundle',
6384 'bundle:' + fname)
6407 'bundle:' + fname)
6385 finally:
6408 finally:
6386 lock.release()
6409 lock.release()
6387
6410
6388 return postincoming(ui, repo, modheads, opts.get('update'), None)
6411 return postincoming(ui, repo, modheads, opts.get('update'), None)
6389
6412
6390 @command('^update|up|checkout|co',
6413 @command('^update|up|checkout|co',
6391 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6414 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
6392 ('c', 'check', None,
6415 ('c', 'check', None,
6393 _('update across branches if no uncommitted changes')),
6416 _('update across branches if no uncommitted changes')),
6394 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6417 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
6395 ('r', 'rev', '', _('revision'), _('REV'))
6418 ('r', 'rev', '', _('revision'), _('REV'))
6396 ] + mergetoolopts,
6419 ] + mergetoolopts,
6397 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6420 _('[-c] [-C] [-d DATE] [[-r] REV]'))
6398 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6421 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
6399 tool=None):
6422 tool=None):
6400 """update working directory (or switch revisions)
6423 """update working directory (or switch revisions)
6401
6424
6402 Update the repository's working directory to the specified
6425 Update the repository's working directory to the specified
6403 changeset. If no changeset is specified, update to the tip of the
6426 changeset. If no changeset is specified, update to the tip of the
6404 current named branch and move the active bookmark (see :hg:`help
6427 current named branch and move the active bookmark (see :hg:`help
6405 bookmarks`).
6428 bookmarks`).
6406
6429
6407 Update sets the working directory's parent revision to the specified
6430 Update sets the working directory's parent revision to the specified
6408 changeset (see :hg:`help parents`).
6431 changeset (see :hg:`help parents`).
6409
6432
6410 If the changeset is not a descendant or ancestor of the working
6433 If the changeset is not a descendant or ancestor of the working
6411 directory's parent, the update is aborted. With the -c/--check
6434 directory's parent, the update is aborted. With the -c/--check
6412 option, the working directory is checked for uncommitted changes; if
6435 option, the working directory is checked for uncommitted changes; if
6413 none are found, the working directory is updated to the specified
6436 none are found, the working directory is updated to the specified
6414 changeset.
6437 changeset.
6415
6438
6416 .. container:: verbose
6439 .. container:: verbose
6417
6440
6418 The following rules apply when the working directory contains
6441 The following rules apply when the working directory contains
6419 uncommitted changes:
6442 uncommitted changes:
6420
6443
6421 1. If neither -c/--check nor -C/--clean is specified, and if
6444 1. If neither -c/--check nor -C/--clean is specified, and if
6422 the requested changeset is an ancestor or descendant of
6445 the requested changeset is an ancestor or descendant of
6423 the working directory's parent, the uncommitted changes
6446 the working directory's parent, the uncommitted changes
6424 are merged into the requested changeset and the merged
6447 are merged into the requested changeset and the merged
6425 result is left uncommitted. If the requested changeset is
6448 result is left uncommitted. If the requested changeset is
6426 not an ancestor or descendant (that is, it is on another
6449 not an ancestor or descendant (that is, it is on another
6427 branch), the update is aborted and the uncommitted changes
6450 branch), the update is aborted and the uncommitted changes
6428 are preserved.
6451 are preserved.
6429
6452
6430 2. With the -c/--check option, the update is aborted and the
6453 2. With the -c/--check option, the update is aborted and the
6431 uncommitted changes are preserved.
6454 uncommitted changes are preserved.
6432
6455
6433 3. With the -C/--clean option, uncommitted changes are discarded and
6456 3. With the -C/--clean option, uncommitted changes are discarded and
6434 the working directory is updated to the requested changeset.
6457 the working directory is updated to the requested changeset.
6435
6458
6436 To cancel an uncommitted merge (and lose your changes), use
6459 To cancel an uncommitted merge (and lose your changes), use
6437 :hg:`update --clean .`.
6460 :hg:`update --clean .`.
6438
6461
6439 Use null as the changeset to remove the working directory (like
6462 Use null as the changeset to remove the working directory (like
6440 :hg:`clone -U`).
6463 :hg:`clone -U`).
6441
6464
6442 If you want to revert just one file to an older revision, use
6465 If you want to revert just one file to an older revision, use
6443 :hg:`revert [-r REV] NAME`.
6466 :hg:`revert [-r REV] NAME`.
6444
6467
6445 See :hg:`help dates` for a list of formats valid for -d/--date.
6468 See :hg:`help dates` for a list of formats valid for -d/--date.
6446
6469
6447 Returns 0 on success, 1 if there are unresolved files.
6470 Returns 0 on success, 1 if there are unresolved files.
6448 """
6471 """
6449 if rev and node:
6472 if rev and node:
6450 raise util.Abort(_("please specify just one revision"))
6473 raise util.Abort(_("please specify just one revision"))
6451
6474
6452 if rev is None or rev == '':
6475 if rev is None or rev == '':
6453 rev = node
6476 rev = node
6454
6477
6455 cmdutil.clearunfinished(repo)
6478 cmdutil.clearunfinished(repo)
6456
6479
6457 # with no argument, we also move the active bookmark, if any
6480 # with no argument, we also move the active bookmark, if any
6458 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
6481 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
6459
6482
6460 # if we defined a bookmark, we have to remember the original bookmark name
6483 # if we defined a bookmark, we have to remember the original bookmark name
6461 brev = rev
6484 brev = rev
6462 rev = scmutil.revsingle(repo, rev, rev).rev()
6485 rev = scmutil.revsingle(repo, rev, rev).rev()
6463
6486
6464 if check and clean:
6487 if check and clean:
6465 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
6488 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
6466
6489
6467 if date:
6490 if date:
6468 if rev is not None:
6491 if rev is not None:
6469 raise util.Abort(_("you can't specify a revision and a date"))
6492 raise util.Abort(_("you can't specify a revision and a date"))
6470 rev = cmdutil.finddate(ui, repo, date)
6493 rev = cmdutil.finddate(ui, repo, date)
6471
6494
6472 if check:
6495 if check:
6473 cmdutil.bailifchanged(repo, merge=False)
6496 cmdutil.bailifchanged(repo, merge=False)
6474 if rev is None:
6497 if rev is None:
6475 rev = repo[repo[None].branch()].rev()
6498 rev = repo[repo[None].branch()].rev()
6476
6499
6477 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6500 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
6478
6501
6479 if clean:
6502 if clean:
6480 ret = hg.clean(repo, rev)
6503 ret = hg.clean(repo, rev)
6481 else:
6504 else:
6482 ret = hg.update(repo, rev)
6505 ret = hg.update(repo, rev)
6483
6506
6484 if not ret and movemarkfrom:
6507 if not ret and movemarkfrom:
6485 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
6508 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
6486 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
6509 ui.status(_("updating bookmark %s\n") % repo._activebookmark)
6487 else:
6510 else:
6488 # this can happen with a non-linear update
6511 # this can happen with a non-linear update
6489 ui.status(_("(leaving bookmark %s)\n") %
6512 ui.status(_("(leaving bookmark %s)\n") %
6490 repo._activebookmark)
6513 repo._activebookmark)
6491 bookmarks.deactivate(repo)
6514 bookmarks.deactivate(repo)
6492 elif brev in repo._bookmarks:
6515 elif brev in repo._bookmarks:
6493 bookmarks.activate(repo, brev)
6516 bookmarks.activate(repo, brev)
6494 ui.status(_("(activating bookmark %s)\n") % brev)
6517 ui.status(_("(activating bookmark %s)\n") % brev)
6495 elif brev:
6518 elif brev:
6496 if repo._activebookmark:
6519 if repo._activebookmark:
6497 ui.status(_("(leaving bookmark %s)\n") %
6520 ui.status(_("(leaving bookmark %s)\n") %
6498 repo._activebookmark)
6521 repo._activebookmark)
6499 bookmarks.deactivate(repo)
6522 bookmarks.deactivate(repo)
6500
6523
6501 return ret
6524 return ret
6502
6525
6503 @command('verify', [])
6526 @command('verify', [])
6504 def verify(ui, repo):
6527 def verify(ui, repo):
6505 """verify the integrity of the repository
6528 """verify the integrity of the repository
6506
6529
6507 Verify the integrity of the current repository.
6530 Verify the integrity of the current repository.
6508
6531
6509 This will perform an extensive check of the repository's
6532 This will perform an extensive check of the repository's
6510 integrity, validating the hashes and checksums of each entry in
6533 integrity, validating the hashes and checksums of each entry in
6511 the changelog, manifest, and tracked files, as well as the
6534 the changelog, manifest, and tracked files, as well as the
6512 integrity of their crosslinks and indices.
6535 integrity of their crosslinks and indices.
6513
6536
6514 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
6537 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
6515 for more information about recovery from corruption of the
6538 for more information about recovery from corruption of the
6516 repository.
6539 repository.
6517
6540
6518 Returns 0 on success, 1 if errors are encountered.
6541 Returns 0 on success, 1 if errors are encountered.
6519 """
6542 """
6520 return hg.verify(repo)
6543 return hg.verify(repo)
6521
6544
6522 @command('version', [], norepo=True)
6545 @command('version', [], norepo=True)
6523 def version_(ui):
6546 def version_(ui):
6524 """output version and copyright information"""
6547 """output version and copyright information"""
6525 ui.write(_("Mercurial Distributed SCM (version %s)\n")
6548 ui.write(_("Mercurial Distributed SCM (version %s)\n")
6526 % util.version())
6549 % util.version())
6527 ui.status(_(
6550 ui.status(_(
6528 "(see http://mercurial.selenic.com for more information)\n"
6551 "(see http://mercurial.selenic.com for more information)\n"
6529 "\nCopyright (C) 2005-2015 Matt Mackall and others\n"
6552 "\nCopyright (C) 2005-2015 Matt Mackall and others\n"
6530 "This is free software; see the source for copying conditions. "
6553 "This is free software; see the source for copying conditions. "
6531 "There is NO\nwarranty; "
6554 "There is NO\nwarranty; "
6532 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6555 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
6533 ))
6556 ))
6534
6557
6535 ui.note(_("\nEnabled extensions:\n\n"))
6558 ui.note(_("\nEnabled extensions:\n\n"))
6536 if ui.verbose:
6559 if ui.verbose:
6537 # format names and versions into columns
6560 # format names and versions into columns
6538 names = []
6561 names = []
6539 vers = []
6562 vers = []
6540 for name, module in extensions.extensions():
6563 for name, module in extensions.extensions():
6541 names.append(name)
6564 names.append(name)
6542 vers.append(extensions.moduleversion(module))
6565 vers.append(extensions.moduleversion(module))
6543 if names:
6566 if names:
6544 maxnamelen = max(len(n) for n in names)
6567 maxnamelen = max(len(n) for n in names)
6545 for i, name in enumerate(names):
6568 for i, name in enumerate(names):
6546 ui.write(" %-*s %s\n" % (maxnamelen, name, vers[i]))
6569 ui.write(" %-*s %s\n" % (maxnamelen, name, vers[i]))
@@ -1,340 +1,340 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 debugbuilddag
72 debugbuilddag
73 debugbundle
73 debugbundle
74 debugcheckstate
74 debugcheckstate
75 debugcommands
75 debugcommands
76 debugcomplete
76 debugcomplete
77 debugconfig
77 debugconfig
78 debugdag
78 debugdag
79 debugdata
79 debugdata
80 debugdate
80 debugdate
81 debugdirstate
81 debugdirstate
82 debugdiscovery
82 debugdiscovery
83 debugfileset
83 debugfileset
84 debugfsinfo
84 debugfsinfo
85 debuggetbundle
85 debuggetbundle
86 debugignore
86 debugignore
87 debugindex
87 debugindex
88 debugindexdot
88 debugindexdot
89 debuginstall
89 debuginstall
90 debugknown
90 debugknown
91 debuglabelcomplete
91 debuglabelcomplete
92 debuglocks
92 debuglocks
93 debugnamecomplete
93 debugnamecomplete
94 debugobsolete
94 debugobsolete
95 debugpathcomplete
95 debugpathcomplete
96 debugpushkey
96 debugpushkey
97 debugpvec
97 debugpvec
98 debugrebuilddirstate
98 debugrebuilddirstate
99 debugrebuildfncache
99 debugrebuildfncache
100 debugrename
100 debugrename
101 debugrevlog
101 debugrevlog
102 debugrevspec
102 debugrevspec
103 debugsetparents
103 debugsetparents
104 debugsub
104 debugsub
105 debugsuccessorssets
105 debugsuccessorssets
106 debugwalk
106 debugwalk
107 debugwireargs
107 debugwireargs
108
108
109 Do not show the alias of a debug command if there are other candidates
109 Do not show the alias of a debug command if there are other candidates
110 (this should hide rawcommit)
110 (this should hide rawcommit)
111 $ hg debugcomplete r
111 $ hg debugcomplete r
112 recover
112 recover
113 remove
113 remove
114 rename
114 rename
115 resolve
115 resolve
116 revert
116 revert
117 rollback
117 rollback
118 root
118 root
119 Show the alias of a debug command if there are no other candidates
119 Show the alias of a debug command if there are no other candidates
120 $ hg debugcomplete rawc
120 $ hg debugcomplete rawc
121
121
122
122
123 Show the global options
123 Show the global options
124 $ hg debugcomplete --options | sort
124 $ hg debugcomplete --options | sort
125 --config
125 --config
126 --cwd
126 --cwd
127 --debug
127 --debug
128 --debugger
128 --debugger
129 --encoding
129 --encoding
130 --encodingmode
130 --encodingmode
131 --help
131 --help
132 --hidden
132 --hidden
133 --noninteractive
133 --noninteractive
134 --profile
134 --profile
135 --quiet
135 --quiet
136 --repository
136 --repository
137 --time
137 --time
138 --traceback
138 --traceback
139 --verbose
139 --verbose
140 --version
140 --version
141 -R
141 -R
142 -h
142 -h
143 -q
143 -q
144 -v
144 -v
145 -y
145 -y
146
146
147 Show the options for the "serve" command
147 Show the options for the "serve" command
148 $ hg debugcomplete --options serve | sort
148 $ hg debugcomplete --options serve | sort
149 --accesslog
149 --accesslog
150 --address
150 --address
151 --certificate
151 --certificate
152 --cmdserver
152 --cmdserver
153 --config
153 --config
154 --cwd
154 --cwd
155 --daemon
155 --daemon
156 --daemon-pipefds
156 --daemon-pipefds
157 --debug
157 --debug
158 --debugger
158 --debugger
159 --encoding
159 --encoding
160 --encodingmode
160 --encodingmode
161 --errorlog
161 --errorlog
162 --help
162 --help
163 --hidden
163 --hidden
164 --ipv6
164 --ipv6
165 --name
165 --name
166 --noninteractive
166 --noninteractive
167 --pid-file
167 --pid-file
168 --port
168 --port
169 --prefix
169 --prefix
170 --profile
170 --profile
171 --quiet
171 --quiet
172 --repository
172 --repository
173 --stdio
173 --stdio
174 --style
174 --style
175 --templates
175 --templates
176 --time
176 --time
177 --traceback
177 --traceback
178 --verbose
178 --verbose
179 --version
179 --version
180 --web-conf
180 --web-conf
181 -6
181 -6
182 -A
182 -A
183 -E
183 -E
184 -R
184 -R
185 -a
185 -a
186 -d
186 -d
187 -h
187 -h
188 -n
188 -n
189 -p
189 -p
190 -q
190 -q
191 -t
191 -t
192 -v
192 -v
193 -y
193 -y
194
194
195 Show an error if we use --options with an ambiguous abbreviation
195 Show an error if we use --options with an ambiguous abbreviation
196 $ hg debugcomplete --options s
196 $ hg debugcomplete --options s
197 hg: command 's' is ambiguous:
197 hg: command 's' is ambiguous:
198 serve showconfig status summary
198 serve showconfig status summary
199 [255]
199 [255]
200
200
201 Show all commands + options
201 Show all commands + options
202 $ hg debugcommands
202 $ hg debugcommands
203 add: include, exclude, subrepos, dry-run
203 add: include, exclude, subrepos, dry-run
204 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
204 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
205 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
205 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
206 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
206 commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos
207 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
207 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
208 export: output, switch-parent, rev, text, git, nodates
208 export: output, switch-parent, rev, text, git, nodates
209 forget: include, exclude
209 forget: include, exclude
210 init: ssh, remotecmd, insecure
210 init: ssh, remotecmd, insecure
211 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
211 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
212 merge: force, rev, preview, tool
212 merge: force, rev, preview, tool
213 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
213 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
214 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
214 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
215 remove: after, force, subrepos, include, exclude
215 remove: after, force, subrepos, include, exclude
216 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
216 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
217 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
217 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
218 summary: remote
218 summary: remote
219 update: clean, check, date, rev, tool
219 update: clean, check, date, rev, tool
220 addremove: similarity, subrepos, include, exclude, dry-run
220 addremove: similarity, subrepos, include, exclude, dry-run
221 archive: no-decode, prefix, rev, type, subrepos, include, exclude
221 archive: no-decode, prefix, rev, type, subrepos, include, exclude
222 backout: merge, commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
222 backout: merge, commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
223 bisect: reset, good, bad, skip, extend, command, noupdate
223 bisect: reset, good, bad, skip, extend, command, noupdate
224 bookmarks: force, rev, delete, rename, inactive, template
224 bookmarks: force, rev, delete, rename, inactive, template
225 branch: force, clean
225 branch: force, clean
226 branches: active, closed, template
226 branches: active, closed, template
227 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
227 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
228 cat: output, rev, decode, include, exclude
228 cat: output, rev, decode, include, exclude
229 config: untrusted, edit, local, global
229 config: untrusted, edit, local, global
230 copy: after, force, include, exclude, dry-run
230 copy: after, force, include, exclude, dry-run
231 debugancestor:
231 debugancestor:
232 debugbuilddag: mergeable-file, overwritten-file, new-file
232 debugbuilddag: mergeable-file, overwritten-file, new-file
233 debugbundle: all
233 debugbundle: all
234 debugcheckstate:
234 debugcheckstate:
235 debugcommands:
235 debugcommands:
236 debugcomplete: options
236 debugcomplete: options
237 debugdag: tags, branches, dots, spaces
237 debugdag: tags, branches, dots, spaces
238 debugdata: changelog, manifest, dir
238 debugdata: changelog, manifest, dir
239 debugdate: extended
239 debugdate: extended
240 debugdirstate: nodates, datesort
240 debugdirstate: nodates, datesort
241 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
241 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
242 debugfileset: rev
242 debugfileset: rev
243 debugfsinfo:
243 debugfsinfo:
244 debuggetbundle: head, common, type
244 debuggetbundle: head, common, type
245 debugignore:
245 debugignore:
246 debugindex: changelog, manifest, dir, format
246 debugindex: changelog, manifest, dir, format
247 debugindexdot:
247 debugindexdot:
248 debuginstall:
248 debuginstall:
249 debugknown:
249 debugknown:
250 debuglabelcomplete:
250 debuglabelcomplete:
251 debuglocks: force-lock, force-wlock
251 debuglocks: force-lock, force-wlock
252 debugnamecomplete:
252 debugnamecomplete:
253 debugobsolete: flags, record-parents, rev, date, user
253 debugobsolete: flags, record-parents, rev, date, user
254 debugpathcomplete: full, normal, added, removed
254 debugpathcomplete: full, normal, added, removed
255 debugpushkey:
255 debugpushkey:
256 debugpvec:
256 debugpvec:
257 debugrebuilddirstate: rev
257 debugrebuilddirstate: rev, minimal
258 debugrebuildfncache:
258 debugrebuildfncache:
259 debugrename: rev
259 debugrename: rev
260 debugrevlog: changelog, manifest, dir, dump
260 debugrevlog: changelog, manifest, dir, dump
261 debugrevspec: optimize
261 debugrevspec: optimize
262 debugsetparents:
262 debugsetparents:
263 debugsub: rev
263 debugsub: rev
264 debugsuccessorssets:
264 debugsuccessorssets:
265 debugwalk: include, exclude
265 debugwalk: include, exclude
266 debugwireargs: three, four, five, ssh, remotecmd, insecure
266 debugwireargs: three, four, five, ssh, remotecmd, insecure
267 files: rev, print0, include, exclude, template, subrepos
267 files: rev, print0, include, exclude, template, subrepos
268 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
268 graft: rev, continue, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
269 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
269 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
270 heads: rev, topo, active, closed, style, template
270 heads: rev, topo, active, closed, style, template
271 help: extension, command, keyword
271 help: extension, command, keyword
272 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
272 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
273 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
273 import: strip, base, edit, force, no-commit, bypass, partial, exact, prefix, import-branch, message, logfile, date, user, similarity
274 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
274 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
275 locate: rev, print0, fullpath, include, exclude
275 locate: rev, print0, fullpath, include, exclude
276 manifest: rev, all, template
276 manifest: rev, all, template
277 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
277 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
278 parents: rev, style, template
278 parents: rev, style, template
279 paths:
279 paths:
280 phase: public, draft, secret, force, rev
280 phase: public, draft, secret, force, rev
281 recover:
281 recover:
282 rename: after, force, include, exclude, dry-run
282 rename: after, force, include, exclude, dry-run
283 resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
283 resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
284 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
284 revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
285 rollback: dry-run, force
285 rollback: dry-run, force
286 root:
286 root:
287 tag: force, local, rev, remove, edit, message, date, user
287 tag: force, local, rev, remove, edit, message, date, user
288 tags: template
288 tags: template
289 tip: patch, git, style, template
289 tip: patch, git, style, template
290 unbundle: update
290 unbundle: update
291 verify:
291 verify:
292 version:
292 version:
293
293
294 $ hg init a
294 $ hg init a
295 $ cd a
295 $ cd a
296 $ echo fee > fee
296 $ echo fee > fee
297 $ hg ci -q -Amfee
297 $ hg ci -q -Amfee
298 $ hg tag fee
298 $ hg tag fee
299 $ mkdir fie
299 $ mkdir fie
300 $ echo dead > fie/dead
300 $ echo dead > fie/dead
301 $ echo live > fie/live
301 $ echo live > fie/live
302 $ hg bookmark fo
302 $ hg bookmark fo
303 $ hg branch -q fie
303 $ hg branch -q fie
304 $ hg ci -q -Amfie
304 $ hg ci -q -Amfie
305 $ echo fo > fo
305 $ echo fo > fo
306 $ hg branch -qf default
306 $ hg branch -qf default
307 $ hg ci -q -Amfo
307 $ hg ci -q -Amfo
308 $ echo Fum > Fum
308 $ echo Fum > Fum
309 $ hg ci -q -AmFum
309 $ hg ci -q -AmFum
310 $ hg bookmark Fum
310 $ hg bookmark Fum
311
311
312 Test debugpathcomplete
312 Test debugpathcomplete
313
313
314 $ hg debugpathcomplete f
314 $ hg debugpathcomplete f
315 fee
315 fee
316 fie
316 fie
317 fo
317 fo
318 $ hg debugpathcomplete -f f
318 $ hg debugpathcomplete -f f
319 fee
319 fee
320 fie/dead
320 fie/dead
321 fie/live
321 fie/live
322 fo
322 fo
323
323
324 $ hg rm Fum
324 $ hg rm Fum
325 $ hg debugpathcomplete -r F
325 $ hg debugpathcomplete -r F
326 Fum
326 Fum
327
327
328 Test debugnamecomplete
328 Test debugnamecomplete
329
329
330 $ hg debugnamecomplete
330 $ hg debugnamecomplete
331 Fum
331 Fum
332 default
332 default
333 fee
333 fee
334 fie
334 fie
335 fo
335 fo
336 tip
336 tip
337 $ hg debugnamecomplete f
337 $ hg debugnamecomplete f
338 fee
338 fee
339 fie
339 fie
340 fo
340 fo
General Comments 0
You need to be logged in to leave comments. Login now