##// END OF EJS Templates
backout: accept '--edit' like other commands creating new changeset...
FUJIWARA Katsunori -
r21712:51035af2 default
parent child Browse files
Show More
@@ -1,5966 +1,5967 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
11 import os, re, difflib, time, tempfile, errno
12 import sys
12 import sys
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, commandserver
16 import sshserver, hgweb, commandserver
17 from hgweb import server as hgweb_server
17 from hgweb import server as hgweb_server
18 import merge as mergemod
18 import merge as mergemod
19 import minirst, revset, fileset
19 import minirst, revset, fileset
20 import dagparser, context, simplemerge, graphmod
20 import dagparser, context, simplemerge, graphmod
21 import random
21 import random
22 import setdiscovery, treediscovery, dagutil, pvec, localrepo
22 import setdiscovery, treediscovery, dagutil, pvec, localrepo
23 import phases, obsolete, exchange
23 import phases, obsolete, exchange
24
24
25 table = {}
25 table = {}
26
26
27 command = cmdutil.command(table)
27 command = cmdutil.command(table)
28
28
29 # common command options
29 # common command options
30
30
31 globalopts = [
31 globalopts = [
32 ('R', 'repository', '',
32 ('R', 'repository', '',
33 _('repository root directory or name of overlay bundle file'),
33 _('repository root directory or name of overlay bundle file'),
34 _('REPO')),
34 _('REPO')),
35 ('', 'cwd', '',
35 ('', 'cwd', '',
36 _('change working directory'), _('DIR')),
36 _('change working directory'), _('DIR')),
37 ('y', 'noninteractive', None,
37 ('y', 'noninteractive', None,
38 _('do not prompt, automatically pick the first choice for all prompts')),
38 _('do not prompt, automatically pick the first choice for all prompts')),
39 ('q', 'quiet', None, _('suppress output')),
39 ('q', 'quiet', None, _('suppress output')),
40 ('v', 'verbose', None, _('enable additional output')),
40 ('v', 'verbose', None, _('enable additional output')),
41 ('', 'config', [],
41 ('', 'config', [],
42 _('set/override config option (use \'section.name=value\')'),
42 _('set/override config option (use \'section.name=value\')'),
43 _('CONFIG')),
43 _('CONFIG')),
44 ('', 'debug', None, _('enable debugging output')),
44 ('', 'debug', None, _('enable debugging output')),
45 ('', 'debugger', None, _('start debugger')),
45 ('', 'debugger', None, _('start debugger')),
46 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
46 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
47 _('ENCODE')),
47 _('ENCODE')),
48 ('', 'encodingmode', encoding.encodingmode,
48 ('', 'encodingmode', encoding.encodingmode,
49 _('set the charset encoding mode'), _('MODE')),
49 _('set the charset encoding mode'), _('MODE')),
50 ('', 'traceback', None, _('always print a traceback on exception')),
50 ('', 'traceback', None, _('always print a traceback on exception')),
51 ('', 'time', None, _('time how long the command takes')),
51 ('', 'time', None, _('time how long the command takes')),
52 ('', 'profile', None, _('print command execution profile')),
52 ('', 'profile', None, _('print command execution profile')),
53 ('', 'version', None, _('output version information and exit')),
53 ('', 'version', None, _('output version information and exit')),
54 ('h', 'help', None, _('display help and exit')),
54 ('h', 'help', None, _('display help and exit')),
55 ('', 'hidden', False, _('consider hidden changesets')),
55 ('', 'hidden', False, _('consider hidden changesets')),
56 ]
56 ]
57
57
58 dryrunopts = [('n', 'dry-run', None,
58 dryrunopts = [('n', 'dry-run', None,
59 _('do not perform actions, just print output'))]
59 _('do not perform actions, just print output'))]
60
60
61 remoteopts = [
61 remoteopts = [
62 ('e', 'ssh', '',
62 ('e', 'ssh', '',
63 _('specify ssh command to use'), _('CMD')),
63 _('specify ssh command to use'), _('CMD')),
64 ('', 'remotecmd', '',
64 ('', 'remotecmd', '',
65 _('specify hg command to run on the remote side'), _('CMD')),
65 _('specify hg command to run on the remote side'), _('CMD')),
66 ('', 'insecure', None,
66 ('', 'insecure', None,
67 _('do not verify server certificate (ignoring web.cacerts config)')),
67 _('do not verify server certificate (ignoring web.cacerts config)')),
68 ]
68 ]
69
69
70 walkopts = [
70 walkopts = [
71 ('I', 'include', [],
71 ('I', 'include', [],
72 _('include names matching the given patterns'), _('PATTERN')),
72 _('include names matching the given patterns'), _('PATTERN')),
73 ('X', 'exclude', [],
73 ('X', 'exclude', [],
74 _('exclude names matching the given patterns'), _('PATTERN')),
74 _('exclude names matching the given patterns'), _('PATTERN')),
75 ]
75 ]
76
76
77 commitopts = [
77 commitopts = [
78 ('m', 'message', '',
78 ('m', 'message', '',
79 _('use text as commit message'), _('TEXT')),
79 _('use text as commit message'), _('TEXT')),
80 ('l', 'logfile', '',
80 ('l', 'logfile', '',
81 _('read commit message from file'), _('FILE')),
81 _('read commit message from file'), _('FILE')),
82 ]
82 ]
83
83
84 commitopts2 = [
84 commitopts2 = [
85 ('d', 'date', '',
85 ('d', 'date', '',
86 _('record the specified date as commit date'), _('DATE')),
86 _('record the specified date as commit date'), _('DATE')),
87 ('u', 'user', '',
87 ('u', 'user', '',
88 _('record the specified user as committer'), _('USER')),
88 _('record the specified user as committer'), _('USER')),
89 ]
89 ]
90
90
91 templateopts = [
91 templateopts = [
92 ('', 'style', '',
92 ('', 'style', '',
93 _('display using template map file (DEPRECATED)'), _('STYLE')),
93 _('display using template map file (DEPRECATED)'), _('STYLE')),
94 ('T', 'template', '',
94 ('T', 'template', '',
95 _('display with template'), _('TEMPLATE')),
95 _('display with template'), _('TEMPLATE')),
96 ]
96 ]
97
97
98 logopts = [
98 logopts = [
99 ('p', 'patch', None, _('show patch')),
99 ('p', 'patch', None, _('show patch')),
100 ('g', 'git', None, _('use git extended diff format')),
100 ('g', 'git', None, _('use git extended diff format')),
101 ('l', 'limit', '',
101 ('l', 'limit', '',
102 _('limit number of changes displayed'), _('NUM')),
102 _('limit number of changes displayed'), _('NUM')),
103 ('M', 'no-merges', None, _('do not show merges')),
103 ('M', 'no-merges', None, _('do not show merges')),
104 ('', 'stat', None, _('output diffstat-style summary of changes')),
104 ('', 'stat', None, _('output diffstat-style summary of changes')),
105 ('G', 'graph', None, _("show the revision DAG")),
105 ('G', 'graph', None, _("show the revision DAG")),
106 ] + templateopts
106 ] + templateopts
107
107
108 diffopts = [
108 diffopts = [
109 ('a', 'text', None, _('treat all files as text')),
109 ('a', 'text', None, _('treat all files as text')),
110 ('g', 'git', None, _('use git extended diff format')),
110 ('g', 'git', None, _('use git extended diff format')),
111 ('', 'nodates', None, _('omit dates from diff headers'))
111 ('', 'nodates', None, _('omit dates from diff headers'))
112 ]
112 ]
113
113
114 diffwsopts = [
114 diffwsopts = [
115 ('w', 'ignore-all-space', None,
115 ('w', 'ignore-all-space', None,
116 _('ignore white space when comparing lines')),
116 _('ignore white space when comparing lines')),
117 ('b', 'ignore-space-change', None,
117 ('b', 'ignore-space-change', None,
118 _('ignore changes in the amount of white space')),
118 _('ignore changes in the amount of white space')),
119 ('B', 'ignore-blank-lines', None,
119 ('B', 'ignore-blank-lines', None,
120 _('ignore changes whose lines are all blank')),
120 _('ignore changes whose lines are all blank')),
121 ]
121 ]
122
122
123 diffopts2 = [
123 diffopts2 = [
124 ('p', 'show-function', None, _('show which function each change is in')),
124 ('p', 'show-function', None, _('show which function each change is in')),
125 ('', 'reverse', None, _('produce a diff that undoes the changes')),
125 ('', 'reverse', None, _('produce a diff that undoes the changes')),
126 ] + diffwsopts + [
126 ] + diffwsopts + [
127 ('U', 'unified', '',
127 ('U', 'unified', '',
128 _('number of lines of context to show'), _('NUM')),
128 _('number of lines of context to show'), _('NUM')),
129 ('', 'stat', None, _('output diffstat-style summary of changes')),
129 ('', 'stat', None, _('output diffstat-style summary of changes')),
130 ]
130 ]
131
131
132 mergetoolopts = [
132 mergetoolopts = [
133 ('t', 'tool', '', _('specify merge tool')),
133 ('t', 'tool', '', _('specify merge tool')),
134 ]
134 ]
135
135
136 similarityopts = [
136 similarityopts = [
137 ('s', 'similarity', '',
137 ('s', 'similarity', '',
138 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
138 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
139 ]
139 ]
140
140
141 subrepoopts = [
141 subrepoopts = [
142 ('S', 'subrepos', None,
142 ('S', 'subrepos', None,
143 _('recurse into subrepositories'))
143 _('recurse into subrepositories'))
144 ]
144 ]
145
145
146 # Commands start here, listed alphabetically
146 # Commands start here, listed alphabetically
147
147
148 @command('^add',
148 @command('^add',
149 walkopts + subrepoopts + dryrunopts,
149 walkopts + subrepoopts + dryrunopts,
150 _('[OPTION]... [FILE]...'))
150 _('[OPTION]... [FILE]...'))
151 def add(ui, repo, *pats, **opts):
151 def add(ui, repo, *pats, **opts):
152 """add the specified files on the next commit
152 """add the specified files on the next commit
153
153
154 Schedule files to be version controlled and added to the
154 Schedule files to be version controlled and added to the
155 repository.
155 repository.
156
156
157 The files will be added to the repository at the next commit. To
157 The files will be added to the repository at the next commit. To
158 undo an add before that, see :hg:`forget`.
158 undo an add before that, see :hg:`forget`.
159
159
160 If no names are given, add all files to the repository.
160 If no names are given, add all files to the repository.
161
161
162 .. container:: verbose
162 .. container:: verbose
163
163
164 An example showing how new (unknown) files are added
164 An example showing how new (unknown) files are added
165 automatically by :hg:`add`::
165 automatically by :hg:`add`::
166
166
167 $ ls
167 $ ls
168 foo.c
168 foo.c
169 $ hg status
169 $ hg status
170 ? foo.c
170 ? foo.c
171 $ hg add
171 $ hg add
172 adding foo.c
172 adding foo.c
173 $ hg status
173 $ hg status
174 A foo.c
174 A foo.c
175
175
176 Returns 0 if all files are successfully added.
176 Returns 0 if all files are successfully added.
177 """
177 """
178
178
179 m = scmutil.match(repo[None], pats, opts)
179 m = scmutil.match(repo[None], pats, opts)
180 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
180 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
181 opts.get('subrepos'), prefix="", explicitonly=False)
181 opts.get('subrepos'), prefix="", explicitonly=False)
182 return rejected and 1 or 0
182 return rejected and 1 or 0
183
183
184 @command('addremove',
184 @command('addremove',
185 similarityopts + walkopts + dryrunopts,
185 similarityopts + walkopts + dryrunopts,
186 _('[OPTION]... [FILE]...'))
186 _('[OPTION]... [FILE]...'))
187 def addremove(ui, repo, *pats, **opts):
187 def addremove(ui, repo, *pats, **opts):
188 """add all new files, delete all missing files
188 """add all new files, delete all missing files
189
189
190 Add all new files and remove all missing files from the
190 Add all new files and remove all missing files from the
191 repository.
191 repository.
192
192
193 New files are ignored if they match any of the patterns in
193 New files are ignored if they match any of the patterns in
194 ``.hgignore``. As with add, these changes take effect at the next
194 ``.hgignore``. As with add, these changes take effect at the next
195 commit.
195 commit.
196
196
197 Use the -s/--similarity option to detect renamed files. This
197 Use the -s/--similarity option to detect renamed files. This
198 option takes a percentage between 0 (disabled) and 100 (files must
198 option takes a percentage between 0 (disabled) and 100 (files must
199 be identical) as its parameter. With a parameter greater than 0,
199 be identical) as its parameter. With a parameter greater than 0,
200 this compares every removed file with every added file and records
200 this compares every removed file with every added file and records
201 those similar enough as renames. Detecting renamed files this way
201 those similar enough as renames. Detecting renamed files this way
202 can be expensive. After using this option, :hg:`status -C` can be
202 can be expensive. After using this option, :hg:`status -C` can be
203 used to check which files were identified as moved or renamed. If
203 used to check which files were identified as moved or renamed. If
204 not specified, -s/--similarity defaults to 100 and only renames of
204 not specified, -s/--similarity defaults to 100 and only renames of
205 identical files are detected.
205 identical files are detected.
206
206
207 Returns 0 if all files are successfully added.
207 Returns 0 if all files are successfully added.
208 """
208 """
209 try:
209 try:
210 sim = float(opts.get('similarity') or 100)
210 sim = float(opts.get('similarity') or 100)
211 except ValueError:
211 except ValueError:
212 raise util.Abort(_('similarity must be a number'))
212 raise util.Abort(_('similarity must be a number'))
213 if sim < 0 or sim > 100:
213 if sim < 0 or sim > 100:
214 raise util.Abort(_('similarity must be between 0 and 100'))
214 raise util.Abort(_('similarity must be between 0 and 100'))
215 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
215 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
216
216
217 @command('^annotate|blame',
217 @command('^annotate|blame',
218 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
218 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
219 ('', 'follow', None,
219 ('', 'follow', None,
220 _('follow copies/renames and list the filename (DEPRECATED)')),
220 _('follow copies/renames and list the filename (DEPRECATED)')),
221 ('', 'no-follow', None, _("don't follow copies and renames")),
221 ('', 'no-follow', None, _("don't follow copies and renames")),
222 ('a', 'text', None, _('treat all files as text')),
222 ('a', 'text', None, _('treat all files as text')),
223 ('u', 'user', None, _('list the author (long with -v)')),
223 ('u', 'user', None, _('list the author (long with -v)')),
224 ('f', 'file', None, _('list the filename')),
224 ('f', 'file', None, _('list the filename')),
225 ('d', 'date', None, _('list the date (short with -q)')),
225 ('d', 'date', None, _('list the date (short with -q)')),
226 ('n', 'number', None, _('list the revision number (default)')),
226 ('n', 'number', None, _('list the revision number (default)')),
227 ('c', 'changeset', None, _('list the changeset')),
227 ('c', 'changeset', None, _('list the changeset')),
228 ('l', 'line-number', None, _('show line number at the first appearance'))
228 ('l', 'line-number', None, _('show line number at the first appearance'))
229 ] + diffwsopts + walkopts,
229 ] + diffwsopts + walkopts,
230 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
230 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
231 def annotate(ui, repo, *pats, **opts):
231 def annotate(ui, repo, *pats, **opts):
232 """show changeset information by line for each file
232 """show changeset information by line for each file
233
233
234 List changes in files, showing the revision id responsible for
234 List changes in files, showing the revision id responsible for
235 each line
235 each line
236
236
237 This command is useful for discovering when a change was made and
237 This command is useful for discovering when a change was made and
238 by whom.
238 by whom.
239
239
240 Without the -a/--text option, annotate will avoid processing files
240 Without the -a/--text option, annotate will avoid processing files
241 it detects as binary. With -a, annotate will annotate the file
241 it detects as binary. With -a, annotate will annotate the file
242 anyway, although the results will probably be neither useful
242 anyway, although the results will probably be neither useful
243 nor desirable.
243 nor desirable.
244
244
245 Returns 0 on success.
245 Returns 0 on success.
246 """
246 """
247 if opts.get('follow'):
247 if opts.get('follow'):
248 # --follow is deprecated and now just an alias for -f/--file
248 # --follow is deprecated and now just an alias for -f/--file
249 # to mimic the behavior of Mercurial before version 1.5
249 # to mimic the behavior of Mercurial before version 1.5
250 opts['file'] = True
250 opts['file'] = True
251
251
252 datefunc = ui.quiet and util.shortdate or util.datestr
252 datefunc = ui.quiet and util.shortdate or util.datestr
253 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
253 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
254
254
255 if not pats:
255 if not pats:
256 raise util.Abort(_('at least one filename or pattern is required'))
256 raise util.Abort(_('at least one filename or pattern is required'))
257
257
258 hexfn = ui.debugflag and hex or short
258 hexfn = ui.debugflag and hex or short
259
259
260 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
260 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
261 ('number', ' ', lambda x: str(x[0].rev())),
261 ('number', ' ', lambda x: str(x[0].rev())),
262 ('changeset', ' ', lambda x: hexfn(x[0].node())),
262 ('changeset', ' ', lambda x: hexfn(x[0].node())),
263 ('date', ' ', getdate),
263 ('date', ' ', getdate),
264 ('file', ' ', lambda x: x[0].path()),
264 ('file', ' ', lambda x: x[0].path()),
265 ('line_number', ':', lambda x: str(x[1])),
265 ('line_number', ':', lambda x: str(x[1])),
266 ]
266 ]
267
267
268 if (not opts.get('user') and not opts.get('changeset')
268 if (not opts.get('user') and not opts.get('changeset')
269 and not opts.get('date') and not opts.get('file')):
269 and not opts.get('date') and not opts.get('file')):
270 opts['number'] = True
270 opts['number'] = True
271
271
272 linenumber = opts.get('line_number') is not None
272 linenumber = opts.get('line_number') is not None
273 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
273 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
274 raise util.Abort(_('at least one of -n/-c is required for -l'))
274 raise util.Abort(_('at least one of -n/-c is required for -l'))
275
275
276 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
276 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
277 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
277 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
278
278
279 def bad(x, y):
279 def bad(x, y):
280 raise util.Abort("%s: %s" % (x, y))
280 raise util.Abort("%s: %s" % (x, y))
281
281
282 ctx = scmutil.revsingle(repo, opts.get('rev'))
282 ctx = scmutil.revsingle(repo, opts.get('rev'))
283 m = scmutil.match(ctx, pats, opts)
283 m = scmutil.match(ctx, pats, opts)
284 m.bad = bad
284 m.bad = bad
285 follow = not opts.get('no_follow')
285 follow = not opts.get('no_follow')
286 diffopts = patch.diffopts(ui, opts, section='annotate')
286 diffopts = patch.diffopts(ui, opts, section='annotate')
287 for abs in ctx.walk(m):
287 for abs in ctx.walk(m):
288 fctx = ctx[abs]
288 fctx = ctx[abs]
289 if not opts.get('text') and util.binary(fctx.data()):
289 if not opts.get('text') and util.binary(fctx.data()):
290 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
290 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
291 continue
291 continue
292
292
293 lines = fctx.annotate(follow=follow, linenumber=linenumber,
293 lines = fctx.annotate(follow=follow, linenumber=linenumber,
294 diffopts=diffopts)
294 diffopts=diffopts)
295 pieces = []
295 pieces = []
296
296
297 for f, sep in funcmap:
297 for f, sep in funcmap:
298 l = [f(n) for n, dummy in lines]
298 l = [f(n) for n, dummy in lines]
299 if l:
299 if l:
300 sized = [(x, encoding.colwidth(x)) for x in l]
300 sized = [(x, encoding.colwidth(x)) for x in l]
301 ml = max([w for x, w in sized])
301 ml = max([w for x, w in sized])
302 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
302 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
303 for x, w in sized])
303 for x, w in sized])
304
304
305 if pieces:
305 if pieces:
306 for p, l in zip(zip(*pieces), lines):
306 for p, l in zip(zip(*pieces), lines):
307 ui.write("%s: %s" % ("".join(p), l[1]))
307 ui.write("%s: %s" % ("".join(p), l[1]))
308
308
309 if lines and not lines[-1][1].endswith('\n'):
309 if lines and not lines[-1][1].endswith('\n'):
310 ui.write('\n')
310 ui.write('\n')
311
311
312 @command('archive',
312 @command('archive',
313 [('', 'no-decode', None, _('do not pass files through decoders')),
313 [('', 'no-decode', None, _('do not pass files through decoders')),
314 ('p', 'prefix', '', _('directory prefix for files in archive'),
314 ('p', 'prefix', '', _('directory prefix for files in archive'),
315 _('PREFIX')),
315 _('PREFIX')),
316 ('r', 'rev', '', _('revision to distribute'), _('REV')),
316 ('r', 'rev', '', _('revision to distribute'), _('REV')),
317 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
317 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
318 ] + subrepoopts + walkopts,
318 ] + subrepoopts + walkopts,
319 _('[OPTION]... DEST'))
319 _('[OPTION]... DEST'))
320 def archive(ui, repo, dest, **opts):
320 def archive(ui, repo, dest, **opts):
321 '''create an unversioned archive of a repository revision
321 '''create an unversioned archive of a repository revision
322
322
323 By default, the revision used is the parent of the working
323 By default, the revision used is the parent of the working
324 directory; use -r/--rev to specify a different revision.
324 directory; use -r/--rev to specify a different revision.
325
325
326 The archive type is automatically detected based on file
326 The archive type is automatically detected based on file
327 extension (or override using -t/--type).
327 extension (or override using -t/--type).
328
328
329 .. container:: verbose
329 .. container:: verbose
330
330
331 Examples:
331 Examples:
332
332
333 - create a zip file containing the 1.0 release::
333 - create a zip file containing the 1.0 release::
334
334
335 hg archive -r 1.0 project-1.0.zip
335 hg archive -r 1.0 project-1.0.zip
336
336
337 - create a tarball excluding .hg files::
337 - create a tarball excluding .hg files::
338
338
339 hg archive project.tar.gz -X ".hg*"
339 hg archive project.tar.gz -X ".hg*"
340
340
341 Valid types are:
341 Valid types are:
342
342
343 :``files``: a directory full of files (default)
343 :``files``: a directory full of files (default)
344 :``tar``: tar archive, uncompressed
344 :``tar``: tar archive, uncompressed
345 :``tbz2``: tar archive, compressed using bzip2
345 :``tbz2``: tar archive, compressed using bzip2
346 :``tgz``: tar archive, compressed using gzip
346 :``tgz``: tar archive, compressed using gzip
347 :``uzip``: zip archive, uncompressed
347 :``uzip``: zip archive, uncompressed
348 :``zip``: zip archive, compressed using deflate
348 :``zip``: zip archive, compressed using deflate
349
349
350 The exact name of the destination archive or directory is given
350 The exact name of the destination archive or directory is given
351 using a format string; see :hg:`help export` for details.
351 using a format string; see :hg:`help export` for details.
352
352
353 Each member added to an archive file has a directory prefix
353 Each member added to an archive file has a directory prefix
354 prepended. Use -p/--prefix to specify a format string for the
354 prepended. Use -p/--prefix to specify a format string for the
355 prefix. The default is the basename of the archive, with suffixes
355 prefix. The default is the basename of the archive, with suffixes
356 removed.
356 removed.
357
357
358 Returns 0 on success.
358 Returns 0 on success.
359 '''
359 '''
360
360
361 ctx = scmutil.revsingle(repo, opts.get('rev'))
361 ctx = scmutil.revsingle(repo, opts.get('rev'))
362 if not ctx:
362 if not ctx:
363 raise util.Abort(_('no working directory: please specify a revision'))
363 raise util.Abort(_('no working directory: please specify a revision'))
364 node = ctx.node()
364 node = ctx.node()
365 dest = cmdutil.makefilename(repo, dest, node)
365 dest = cmdutil.makefilename(repo, dest, node)
366 if os.path.realpath(dest) == repo.root:
366 if os.path.realpath(dest) == repo.root:
367 raise util.Abort(_('repository root cannot be destination'))
367 raise util.Abort(_('repository root cannot be destination'))
368
368
369 kind = opts.get('type') or archival.guesskind(dest) or 'files'
369 kind = opts.get('type') or archival.guesskind(dest) or 'files'
370 prefix = opts.get('prefix')
370 prefix = opts.get('prefix')
371
371
372 if dest == '-':
372 if dest == '-':
373 if kind == 'files':
373 if kind == 'files':
374 raise util.Abort(_('cannot archive plain files to stdout'))
374 raise util.Abort(_('cannot archive plain files to stdout'))
375 dest = cmdutil.makefileobj(repo, dest)
375 dest = cmdutil.makefileobj(repo, dest)
376 if not prefix:
376 if not prefix:
377 prefix = os.path.basename(repo.root) + '-%h'
377 prefix = os.path.basename(repo.root) + '-%h'
378
378
379 prefix = cmdutil.makefilename(repo, prefix, node)
379 prefix = cmdutil.makefilename(repo, prefix, node)
380 matchfn = scmutil.match(ctx, [], opts)
380 matchfn = scmutil.match(ctx, [], opts)
381 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
381 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
382 matchfn, prefix, subrepos=opts.get('subrepos'))
382 matchfn, prefix, subrepos=opts.get('subrepos'))
383
383
384 @command('backout',
384 @command('backout',
385 [('', 'merge', None, _('merge with old dirstate parent after backout')),
385 [('', 'merge', None, _('merge with old dirstate parent after backout')),
386 ('', 'parent', '',
386 ('', 'parent', '',
387 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
387 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
388 ('r', 'rev', '', _('revision to backout'), _('REV')),
388 ('r', 'rev', '', _('revision to backout'), _('REV')),
389 ('e', 'edit', False, _('invoke editor on commit messages')),
389 ] + mergetoolopts + walkopts + commitopts + commitopts2,
390 ] + mergetoolopts + walkopts + commitopts + commitopts2,
390 _('[OPTION]... [-r] REV'))
391 _('[OPTION]... [-r] REV'))
391 def backout(ui, repo, node=None, rev=None, **opts):
392 def backout(ui, repo, node=None, rev=None, **opts):
392 '''reverse effect of earlier changeset
393 '''reverse effect of earlier changeset
393
394
394 Prepare a new changeset with the effect of REV undone in the
395 Prepare a new changeset with the effect of REV undone in the
395 current working directory.
396 current working directory.
396
397
397 If REV is the parent of the working directory, then this new changeset
398 If REV is the parent of the working directory, then this new changeset
398 is committed automatically. Otherwise, hg needs to merge the
399 is committed automatically. Otherwise, hg needs to merge the
399 changes and the merged result is left uncommitted.
400 changes and the merged result is left uncommitted.
400
401
401 .. note::
402 .. note::
402
403
403 backout cannot be used to fix either an unwanted or
404 backout cannot be used to fix either an unwanted or
404 incorrect merge.
405 incorrect merge.
405
406
406 .. container:: verbose
407 .. container:: verbose
407
408
408 By default, the pending changeset will have one parent,
409 By default, the pending changeset will have one parent,
409 maintaining a linear history. With --merge, the pending
410 maintaining a linear history. With --merge, the pending
410 changeset will instead have two parents: the old parent of the
411 changeset will instead have two parents: the old parent of the
411 working directory and a new child of REV that simply undoes REV.
412 working directory and a new child of REV that simply undoes REV.
412
413
413 Before version 1.7, the behavior without --merge was equivalent
414 Before version 1.7, the behavior without --merge was equivalent
414 to specifying --merge followed by :hg:`update --clean .` to
415 to specifying --merge followed by :hg:`update --clean .` to
415 cancel the merge and leave the child of REV as a head to be
416 cancel the merge and leave the child of REV as a head to be
416 merged separately.
417 merged separately.
417
418
418 See :hg:`help dates` for a list of formats valid for -d/--date.
419 See :hg:`help dates` for a list of formats valid for -d/--date.
419
420
420 Returns 0 on success, 1 if nothing to backout or there are unresolved
421 Returns 0 on success, 1 if nothing to backout or there are unresolved
421 files.
422 files.
422 '''
423 '''
423 if rev and node:
424 if rev and node:
424 raise util.Abort(_("please specify just one revision"))
425 raise util.Abort(_("please specify just one revision"))
425
426
426 if not rev:
427 if not rev:
427 rev = node
428 rev = node
428
429
429 if not rev:
430 if not rev:
430 raise util.Abort(_("please specify a revision to backout"))
431 raise util.Abort(_("please specify a revision to backout"))
431
432
432 date = opts.get('date')
433 date = opts.get('date')
433 if date:
434 if date:
434 opts['date'] = util.parsedate(date)
435 opts['date'] = util.parsedate(date)
435
436
436 cmdutil.checkunfinished(repo)
437 cmdutil.checkunfinished(repo)
437 cmdutil.bailifchanged(repo)
438 cmdutil.bailifchanged(repo)
438 node = scmutil.revsingle(repo, rev).node()
439 node = scmutil.revsingle(repo, rev).node()
439
440
440 op1, op2 = repo.dirstate.parents()
441 op1, op2 = repo.dirstate.parents()
441 if node not in repo.changelog.commonancestorsheads(op1, node):
442 if node not in repo.changelog.commonancestorsheads(op1, node):
442 raise util.Abort(_('cannot backout change that is not an ancestor'))
443 raise util.Abort(_('cannot backout change that is not an ancestor'))
443
444
444 p1, p2 = repo.changelog.parents(node)
445 p1, p2 = repo.changelog.parents(node)
445 if p1 == nullid:
446 if p1 == nullid:
446 raise util.Abort(_('cannot backout a change with no parents'))
447 raise util.Abort(_('cannot backout a change with no parents'))
447 if p2 != nullid:
448 if p2 != nullid:
448 if not opts.get('parent'):
449 if not opts.get('parent'):
449 raise util.Abort(_('cannot backout a merge changeset'))
450 raise util.Abort(_('cannot backout a merge changeset'))
450 p = repo.lookup(opts['parent'])
451 p = repo.lookup(opts['parent'])
451 if p not in (p1, p2):
452 if p not in (p1, p2):
452 raise util.Abort(_('%s is not a parent of %s') %
453 raise util.Abort(_('%s is not a parent of %s') %
453 (short(p), short(node)))
454 (short(p), short(node)))
454 parent = p
455 parent = p
455 else:
456 else:
456 if opts.get('parent'):
457 if opts.get('parent'):
457 raise util.Abort(_('cannot use --parent on non-merge changeset'))
458 raise util.Abort(_('cannot use --parent on non-merge changeset'))
458 parent = p1
459 parent = p1
459
460
460 # the backout should appear on the same branch
461 # the backout should appear on the same branch
461 wlock = repo.wlock()
462 wlock = repo.wlock()
462 try:
463 try:
463 branch = repo.dirstate.branch()
464 branch = repo.dirstate.branch()
464 bheads = repo.branchheads(branch)
465 bheads = repo.branchheads(branch)
465 rctx = scmutil.revsingle(repo, hex(parent))
466 rctx = scmutil.revsingle(repo, hex(parent))
466 if not opts.get('merge') and op1 != node:
467 if not opts.get('merge') and op1 != node:
467 try:
468 try:
468 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
469 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
469 'backout')
470 'backout')
470 stats = mergemod.update(repo, parent, True, True, False,
471 stats = mergemod.update(repo, parent, True, True, False,
471 node, False)
472 node, False)
472 repo.setparents(op1, op2)
473 repo.setparents(op1, op2)
473 hg._showstats(repo, stats)
474 hg._showstats(repo, stats)
474 if stats[3]:
475 if stats[3]:
475 repo.ui.status(_("use 'hg resolve' to retry unresolved "
476 repo.ui.status(_("use 'hg resolve' to retry unresolved "
476 "file merges\n"))
477 "file merges\n"))
477 else:
478 else:
478 msg = _("changeset %s backed out, "
479 msg = _("changeset %s backed out, "
479 "don't forget to commit.\n")
480 "don't forget to commit.\n")
480 ui.status(msg % short(node))
481 ui.status(msg % short(node))
481 return stats[3] > 0
482 return stats[3] > 0
482 finally:
483 finally:
483 ui.setconfig('ui', 'forcemerge', '', '')
484 ui.setconfig('ui', 'forcemerge', '', '')
484 else:
485 else:
485 hg.clean(repo, node, show_stats=False)
486 hg.clean(repo, node, show_stats=False)
486 repo.dirstate.setbranch(branch)
487 repo.dirstate.setbranch(branch)
487 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
488 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
488
489
489
490
490 def commitfunc(ui, repo, message, match, opts):
491 def commitfunc(ui, repo, message, match, opts):
491 e = cmdutil.getcommiteditor()
492 e = cmdutil.getcommiteditor(**opts)
492 if not message:
493 if not message:
493 # we don't translate commit messages
494 # we don't translate commit messages
494 message = "Backed out changeset %s" % short(node)
495 message = "Backed out changeset %s" % short(node)
495 e = cmdutil.getcommiteditor(edit=True)
496 e = cmdutil.getcommiteditor(edit=True)
496 return repo.commit(message, opts.get('user'), opts.get('date'),
497 return repo.commit(message, opts.get('user'), opts.get('date'),
497 match, editor=e)
498 match, editor=e)
498 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
499 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
499 if not newnode:
500 if not newnode:
500 ui.status(_("nothing changed\n"))
501 ui.status(_("nothing changed\n"))
501 return 1
502 return 1
502 cmdutil.commitstatus(repo, newnode, branch, bheads)
503 cmdutil.commitstatus(repo, newnode, branch, bheads)
503
504
504 def nice(node):
505 def nice(node):
505 return '%d:%s' % (repo.changelog.rev(node), short(node))
506 return '%d:%s' % (repo.changelog.rev(node), short(node))
506 ui.status(_('changeset %s backs out changeset %s\n') %
507 ui.status(_('changeset %s backs out changeset %s\n') %
507 (nice(repo.changelog.tip()), nice(node)))
508 (nice(repo.changelog.tip()), nice(node)))
508 if opts.get('merge') and op1 != node:
509 if opts.get('merge') and op1 != node:
509 hg.clean(repo, op1, show_stats=False)
510 hg.clean(repo, op1, show_stats=False)
510 ui.status(_('merging with changeset %s\n')
511 ui.status(_('merging with changeset %s\n')
511 % nice(repo.changelog.tip()))
512 % nice(repo.changelog.tip()))
512 try:
513 try:
513 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
514 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
514 'backout')
515 'backout')
515 return hg.merge(repo, hex(repo.changelog.tip()))
516 return hg.merge(repo, hex(repo.changelog.tip()))
516 finally:
517 finally:
517 ui.setconfig('ui', 'forcemerge', '', '')
518 ui.setconfig('ui', 'forcemerge', '', '')
518 finally:
519 finally:
519 wlock.release()
520 wlock.release()
520 return 0
521 return 0
521
522
522 @command('bisect',
523 @command('bisect',
523 [('r', 'reset', False, _('reset bisect state')),
524 [('r', 'reset', False, _('reset bisect state')),
524 ('g', 'good', False, _('mark changeset good')),
525 ('g', 'good', False, _('mark changeset good')),
525 ('b', 'bad', False, _('mark changeset bad')),
526 ('b', 'bad', False, _('mark changeset bad')),
526 ('s', 'skip', False, _('skip testing changeset')),
527 ('s', 'skip', False, _('skip testing changeset')),
527 ('e', 'extend', False, _('extend the bisect range')),
528 ('e', 'extend', False, _('extend the bisect range')),
528 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
529 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
529 ('U', 'noupdate', False, _('do not update to target'))],
530 ('U', 'noupdate', False, _('do not update to target'))],
530 _("[-gbsr] [-U] [-c CMD] [REV]"))
531 _("[-gbsr] [-U] [-c CMD] [REV]"))
531 def bisect(ui, repo, rev=None, extra=None, command=None,
532 def bisect(ui, repo, rev=None, extra=None, command=None,
532 reset=None, good=None, bad=None, skip=None, extend=None,
533 reset=None, good=None, bad=None, skip=None, extend=None,
533 noupdate=None):
534 noupdate=None):
534 """subdivision search of changesets
535 """subdivision search of changesets
535
536
536 This command helps to find changesets which introduce problems. To
537 This command helps to find changesets which introduce problems. To
537 use, mark the earliest changeset you know exhibits the problem as
538 use, mark the earliest changeset you know exhibits the problem as
538 bad, then mark the latest changeset which is free from the problem
539 bad, then mark the latest changeset which is free from the problem
539 as good. Bisect will update your working directory to a revision
540 as good. Bisect will update your working directory to a revision
540 for testing (unless the -U/--noupdate option is specified). Once
541 for testing (unless the -U/--noupdate option is specified). Once
541 you have performed tests, mark the working directory as good or
542 you have performed tests, mark the working directory as good or
542 bad, and bisect will either update to another candidate changeset
543 bad, and bisect will either update to another candidate changeset
543 or announce that it has found the bad revision.
544 or announce that it has found the bad revision.
544
545
545 As a shortcut, you can also use the revision argument to mark a
546 As a shortcut, you can also use the revision argument to mark a
546 revision as good or bad without checking it out first.
547 revision as good or bad without checking it out first.
547
548
548 If you supply a command, it will be used for automatic bisection.
549 If you supply a command, it will be used for automatic bisection.
549 The environment variable HG_NODE will contain the ID of the
550 The environment variable HG_NODE will contain the ID of the
550 changeset being tested. The exit status of the command will be
551 changeset being tested. The exit status of the command will be
551 used to mark revisions as good or bad: status 0 means good, 125
552 used to mark revisions as good or bad: status 0 means good, 125
552 means to skip the revision, 127 (command not found) will abort the
553 means to skip the revision, 127 (command not found) will abort the
553 bisection, and any other non-zero exit status means the revision
554 bisection, and any other non-zero exit status means the revision
554 is bad.
555 is bad.
555
556
556 .. container:: verbose
557 .. container:: verbose
557
558
558 Some examples:
559 Some examples:
559
560
560 - start a bisection with known bad revision 34, and good revision 12::
561 - start a bisection with known bad revision 34, and good revision 12::
561
562
562 hg bisect --bad 34
563 hg bisect --bad 34
563 hg bisect --good 12
564 hg bisect --good 12
564
565
565 - advance the current bisection by marking current revision as good or
566 - advance the current bisection by marking current revision as good or
566 bad::
567 bad::
567
568
568 hg bisect --good
569 hg bisect --good
569 hg bisect --bad
570 hg bisect --bad
570
571
571 - mark the current revision, or a known revision, to be skipped (e.g. if
572 - mark the current revision, or a known revision, to be skipped (e.g. if
572 that revision is not usable because of another issue)::
573 that revision is not usable because of another issue)::
573
574
574 hg bisect --skip
575 hg bisect --skip
575 hg bisect --skip 23
576 hg bisect --skip 23
576
577
577 - skip all revisions that do not touch directories ``foo`` or ``bar``::
578 - skip all revisions that do not touch directories ``foo`` or ``bar``::
578
579
579 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
580 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
580
581
581 - forget the current bisection::
582 - forget the current bisection::
582
583
583 hg bisect --reset
584 hg bisect --reset
584
585
585 - use 'make && make tests' to automatically find the first broken
586 - use 'make && make tests' to automatically find the first broken
586 revision::
587 revision::
587
588
588 hg bisect --reset
589 hg bisect --reset
589 hg bisect --bad 34
590 hg bisect --bad 34
590 hg bisect --good 12
591 hg bisect --good 12
591 hg bisect --command "make && make tests"
592 hg bisect --command "make && make tests"
592
593
593 - see all changesets whose states are already known in the current
594 - see all changesets whose states are already known in the current
594 bisection::
595 bisection::
595
596
596 hg log -r "bisect(pruned)"
597 hg log -r "bisect(pruned)"
597
598
598 - see the changeset currently being bisected (especially useful
599 - see the changeset currently being bisected (especially useful
599 if running with -U/--noupdate)::
600 if running with -U/--noupdate)::
600
601
601 hg log -r "bisect(current)"
602 hg log -r "bisect(current)"
602
603
603 - see all changesets that took part in the current bisection::
604 - see all changesets that took part in the current bisection::
604
605
605 hg log -r "bisect(range)"
606 hg log -r "bisect(range)"
606
607
607 - you can even get a nice graph::
608 - you can even get a nice graph::
608
609
609 hg log --graph -r "bisect(range)"
610 hg log --graph -r "bisect(range)"
610
611
611 See :hg:`help revsets` for more about the `bisect()` keyword.
612 See :hg:`help revsets` for more about the `bisect()` keyword.
612
613
613 Returns 0 on success.
614 Returns 0 on success.
614 """
615 """
615 def extendbisectrange(nodes, good):
616 def extendbisectrange(nodes, good):
616 # bisect is incomplete when it ends on a merge node and
617 # bisect is incomplete when it ends on a merge node and
617 # one of the parent was not checked.
618 # one of the parent was not checked.
618 parents = repo[nodes[0]].parents()
619 parents = repo[nodes[0]].parents()
619 if len(parents) > 1:
620 if len(parents) > 1:
620 side = good and state['bad'] or state['good']
621 side = good and state['bad'] or state['good']
621 num = len(set(i.node() for i in parents) & set(side))
622 num = len(set(i.node() for i in parents) & set(side))
622 if num == 1:
623 if num == 1:
623 return parents[0].ancestor(parents[1])
624 return parents[0].ancestor(parents[1])
624 return None
625 return None
625
626
626 def print_result(nodes, good):
627 def print_result(nodes, good):
627 displayer = cmdutil.show_changeset(ui, repo, {})
628 displayer = cmdutil.show_changeset(ui, repo, {})
628 if len(nodes) == 1:
629 if len(nodes) == 1:
629 # narrowed it down to a single revision
630 # narrowed it down to a single revision
630 if good:
631 if good:
631 ui.write(_("The first good revision is:\n"))
632 ui.write(_("The first good revision is:\n"))
632 else:
633 else:
633 ui.write(_("The first bad revision is:\n"))
634 ui.write(_("The first bad revision is:\n"))
634 displayer.show(repo[nodes[0]])
635 displayer.show(repo[nodes[0]])
635 extendnode = extendbisectrange(nodes, good)
636 extendnode = extendbisectrange(nodes, good)
636 if extendnode is not None:
637 if extendnode is not None:
637 ui.write(_('Not all ancestors of this changeset have been'
638 ui.write(_('Not all ancestors of this changeset have been'
638 ' checked.\nUse bisect --extend to continue the '
639 ' checked.\nUse bisect --extend to continue the '
639 'bisection from\nthe common ancestor, %s.\n')
640 'bisection from\nthe common ancestor, %s.\n')
640 % extendnode)
641 % extendnode)
641 else:
642 else:
642 # multiple possible revisions
643 # multiple possible revisions
643 if good:
644 if good:
644 ui.write(_("Due to skipped revisions, the first "
645 ui.write(_("Due to skipped revisions, the first "
645 "good revision could be any of:\n"))
646 "good revision could be any of:\n"))
646 else:
647 else:
647 ui.write(_("Due to skipped revisions, the first "
648 ui.write(_("Due to skipped revisions, the first "
648 "bad revision could be any of:\n"))
649 "bad revision could be any of:\n"))
649 for n in nodes:
650 for n in nodes:
650 displayer.show(repo[n])
651 displayer.show(repo[n])
651 displayer.close()
652 displayer.close()
652
653
653 def check_state(state, interactive=True):
654 def check_state(state, interactive=True):
654 if not state['good'] or not state['bad']:
655 if not state['good'] or not state['bad']:
655 if (good or bad or skip or reset) and interactive:
656 if (good or bad or skip or reset) and interactive:
656 return
657 return
657 if not state['good']:
658 if not state['good']:
658 raise util.Abort(_('cannot bisect (no known good revisions)'))
659 raise util.Abort(_('cannot bisect (no known good revisions)'))
659 else:
660 else:
660 raise util.Abort(_('cannot bisect (no known bad revisions)'))
661 raise util.Abort(_('cannot bisect (no known bad revisions)'))
661 return True
662 return True
662
663
663 # backward compatibility
664 # backward compatibility
664 if rev in "good bad reset init".split():
665 if rev in "good bad reset init".split():
665 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
666 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
666 cmd, rev, extra = rev, extra, None
667 cmd, rev, extra = rev, extra, None
667 if cmd == "good":
668 if cmd == "good":
668 good = True
669 good = True
669 elif cmd == "bad":
670 elif cmd == "bad":
670 bad = True
671 bad = True
671 else:
672 else:
672 reset = True
673 reset = True
673 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
674 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
674 raise util.Abort(_('incompatible arguments'))
675 raise util.Abort(_('incompatible arguments'))
675
676
676 cmdutil.checkunfinished(repo)
677 cmdutil.checkunfinished(repo)
677
678
678 if reset:
679 if reset:
679 p = repo.join("bisect.state")
680 p = repo.join("bisect.state")
680 if os.path.exists(p):
681 if os.path.exists(p):
681 os.unlink(p)
682 os.unlink(p)
682 return
683 return
683
684
684 state = hbisect.load_state(repo)
685 state = hbisect.load_state(repo)
685
686
686 if command:
687 if command:
687 changesets = 1
688 changesets = 1
688 if noupdate:
689 if noupdate:
689 try:
690 try:
690 node = state['current'][0]
691 node = state['current'][0]
691 except LookupError:
692 except LookupError:
692 raise util.Abort(_('current bisect revision is unknown - '
693 raise util.Abort(_('current bisect revision is unknown - '
693 'start a new bisect to fix'))
694 'start a new bisect to fix'))
694 else:
695 else:
695 node, p2 = repo.dirstate.parents()
696 node, p2 = repo.dirstate.parents()
696 if p2 != nullid:
697 if p2 != nullid:
697 raise util.Abort(_('current bisect revision is a merge'))
698 raise util.Abort(_('current bisect revision is a merge'))
698 try:
699 try:
699 while changesets:
700 while changesets:
700 # update state
701 # update state
701 state['current'] = [node]
702 state['current'] = [node]
702 hbisect.save_state(repo, state)
703 hbisect.save_state(repo, state)
703 status = util.system(command,
704 status = util.system(command,
704 environ={'HG_NODE': hex(node)},
705 environ={'HG_NODE': hex(node)},
705 out=ui.fout)
706 out=ui.fout)
706 if status == 125:
707 if status == 125:
707 transition = "skip"
708 transition = "skip"
708 elif status == 0:
709 elif status == 0:
709 transition = "good"
710 transition = "good"
710 # status < 0 means process was killed
711 # status < 0 means process was killed
711 elif status == 127:
712 elif status == 127:
712 raise util.Abort(_("failed to execute %s") % command)
713 raise util.Abort(_("failed to execute %s") % command)
713 elif status < 0:
714 elif status < 0:
714 raise util.Abort(_("%s killed") % command)
715 raise util.Abort(_("%s killed") % command)
715 else:
716 else:
716 transition = "bad"
717 transition = "bad"
717 ctx = scmutil.revsingle(repo, rev, node)
718 ctx = scmutil.revsingle(repo, rev, node)
718 rev = None # clear for future iterations
719 rev = None # clear for future iterations
719 state[transition].append(ctx.node())
720 state[transition].append(ctx.node())
720 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
721 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
721 check_state(state, interactive=False)
722 check_state(state, interactive=False)
722 # bisect
723 # bisect
723 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
724 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
724 # update to next check
725 # update to next check
725 node = nodes[0]
726 node = nodes[0]
726 if not noupdate:
727 if not noupdate:
727 cmdutil.bailifchanged(repo)
728 cmdutil.bailifchanged(repo)
728 hg.clean(repo, node, show_stats=False)
729 hg.clean(repo, node, show_stats=False)
729 finally:
730 finally:
730 state['current'] = [node]
731 state['current'] = [node]
731 hbisect.save_state(repo, state)
732 hbisect.save_state(repo, state)
732 print_result(nodes, bgood)
733 print_result(nodes, bgood)
733 return
734 return
734
735
735 # update state
736 # update state
736
737
737 if rev:
738 if rev:
738 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
739 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
739 else:
740 else:
740 nodes = [repo.lookup('.')]
741 nodes = [repo.lookup('.')]
741
742
742 if good or bad or skip:
743 if good or bad or skip:
743 if good:
744 if good:
744 state['good'] += nodes
745 state['good'] += nodes
745 elif bad:
746 elif bad:
746 state['bad'] += nodes
747 state['bad'] += nodes
747 elif skip:
748 elif skip:
748 state['skip'] += nodes
749 state['skip'] += nodes
749 hbisect.save_state(repo, state)
750 hbisect.save_state(repo, state)
750
751
751 if not check_state(state):
752 if not check_state(state):
752 return
753 return
753
754
754 # actually bisect
755 # actually bisect
755 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
756 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
756 if extend:
757 if extend:
757 if not changesets:
758 if not changesets:
758 extendnode = extendbisectrange(nodes, good)
759 extendnode = extendbisectrange(nodes, good)
759 if extendnode is not None:
760 if extendnode is not None:
760 ui.write(_("Extending search to changeset %d:%s\n")
761 ui.write(_("Extending search to changeset %d:%s\n")
761 % (extendnode.rev(), extendnode))
762 % (extendnode.rev(), extendnode))
762 state['current'] = [extendnode.node()]
763 state['current'] = [extendnode.node()]
763 hbisect.save_state(repo, state)
764 hbisect.save_state(repo, state)
764 if noupdate:
765 if noupdate:
765 return
766 return
766 cmdutil.bailifchanged(repo)
767 cmdutil.bailifchanged(repo)
767 return hg.clean(repo, extendnode.node())
768 return hg.clean(repo, extendnode.node())
768 raise util.Abort(_("nothing to extend"))
769 raise util.Abort(_("nothing to extend"))
769
770
770 if changesets == 0:
771 if changesets == 0:
771 print_result(nodes, good)
772 print_result(nodes, good)
772 else:
773 else:
773 assert len(nodes) == 1 # only a single node can be tested next
774 assert len(nodes) == 1 # only a single node can be tested next
774 node = nodes[0]
775 node = nodes[0]
775 # compute the approximate number of remaining tests
776 # compute the approximate number of remaining tests
776 tests, size = 0, 2
777 tests, size = 0, 2
777 while size <= changesets:
778 while size <= changesets:
778 tests, size = tests + 1, size * 2
779 tests, size = tests + 1, size * 2
779 rev = repo.changelog.rev(node)
780 rev = repo.changelog.rev(node)
780 ui.write(_("Testing changeset %d:%s "
781 ui.write(_("Testing changeset %d:%s "
781 "(%d changesets remaining, ~%d tests)\n")
782 "(%d changesets remaining, ~%d tests)\n")
782 % (rev, short(node), changesets, tests))
783 % (rev, short(node), changesets, tests))
783 state['current'] = [node]
784 state['current'] = [node]
784 hbisect.save_state(repo, state)
785 hbisect.save_state(repo, state)
785 if not noupdate:
786 if not noupdate:
786 cmdutil.bailifchanged(repo)
787 cmdutil.bailifchanged(repo)
787 return hg.clean(repo, node)
788 return hg.clean(repo, node)
788
789
789 @command('bookmarks|bookmark',
790 @command('bookmarks|bookmark',
790 [('f', 'force', False, _('force')),
791 [('f', 'force', False, _('force')),
791 ('r', 'rev', '', _('revision'), _('REV')),
792 ('r', 'rev', '', _('revision'), _('REV')),
792 ('d', 'delete', False, _('delete a given bookmark')),
793 ('d', 'delete', False, _('delete a given bookmark')),
793 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
794 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
794 ('i', 'inactive', False, _('mark a bookmark inactive'))],
795 ('i', 'inactive', False, _('mark a bookmark inactive'))],
795 _('hg bookmarks [OPTIONS]... [NAME]...'))
796 _('hg bookmarks [OPTIONS]... [NAME]...'))
796 def bookmark(ui, repo, *names, **opts):
797 def bookmark(ui, repo, *names, **opts):
797 '''track a line of development with movable markers
798 '''track a line of development with movable markers
798
799
799 Bookmarks are pointers to certain commits that move when committing.
800 Bookmarks are pointers to certain commits that move when committing.
800 Bookmarks are local. They can be renamed, copied and deleted. It is
801 Bookmarks are local. They can be renamed, copied and deleted. It is
801 possible to use :hg:`merge NAME` to merge from a given bookmark, and
802 possible to use :hg:`merge NAME` to merge from a given bookmark, and
802 :hg:`update NAME` to update to a given bookmark.
803 :hg:`update NAME` to update to a given bookmark.
803
804
804 You can use :hg:`bookmark NAME` to set a bookmark on the working
805 You can use :hg:`bookmark NAME` to set a bookmark on the working
805 directory's parent revision with the given name. If you specify
806 directory's parent revision with the given name. If you specify
806 a revision using -r REV (where REV may be an existing bookmark),
807 a revision using -r REV (where REV may be an existing bookmark),
807 the bookmark is assigned to that revision.
808 the bookmark is assigned to that revision.
808
809
809 Bookmarks can be pushed and pulled between repositories (see :hg:`help
810 Bookmarks can be pushed and pulled between repositories (see :hg:`help
810 push` and :hg:`help pull`). This requires both the local and remote
811 push` and :hg:`help pull`). This requires both the local and remote
811 repositories to support bookmarks. For versions prior to 1.8, this means
812 repositories to support bookmarks. For versions prior to 1.8, this means
812 the bookmarks extension must be enabled.
813 the bookmarks extension must be enabled.
813
814
814 If you set a bookmark called '@', new clones of the repository will
815 If you set a bookmark called '@', new clones of the repository will
815 have that revision checked out (and the bookmark made active) by
816 have that revision checked out (and the bookmark made active) by
816 default.
817 default.
817
818
818 With -i/--inactive, the new bookmark will not be made the active
819 With -i/--inactive, the new bookmark will not be made the active
819 bookmark. If -r/--rev is given, the new bookmark will not be made
820 bookmark. If -r/--rev is given, the new bookmark will not be made
820 active even if -i/--inactive is not given. If no NAME is given, the
821 active even if -i/--inactive is not given. If no NAME is given, the
821 current active bookmark will be marked inactive.
822 current active bookmark will be marked inactive.
822 '''
823 '''
823 force = opts.get('force')
824 force = opts.get('force')
824 rev = opts.get('rev')
825 rev = opts.get('rev')
825 delete = opts.get('delete')
826 delete = opts.get('delete')
826 rename = opts.get('rename')
827 rename = opts.get('rename')
827 inactive = opts.get('inactive')
828 inactive = opts.get('inactive')
828
829
829 def checkformat(mark):
830 def checkformat(mark):
830 mark = mark.strip()
831 mark = mark.strip()
831 if not mark:
832 if not mark:
832 raise util.Abort(_("bookmark names cannot consist entirely of "
833 raise util.Abort(_("bookmark names cannot consist entirely of "
833 "whitespace"))
834 "whitespace"))
834 scmutil.checknewlabel(repo, mark, 'bookmark')
835 scmutil.checknewlabel(repo, mark, 'bookmark')
835 return mark
836 return mark
836
837
837 def checkconflict(repo, mark, cur, force=False, target=None):
838 def checkconflict(repo, mark, cur, force=False, target=None):
838 if mark in marks and not force:
839 if mark in marks and not force:
839 if target:
840 if target:
840 if marks[mark] == target and target == cur:
841 if marks[mark] == target and target == cur:
841 # re-activating a bookmark
842 # re-activating a bookmark
842 return
843 return
843 anc = repo.changelog.ancestors([repo[target].rev()])
844 anc = repo.changelog.ancestors([repo[target].rev()])
844 bmctx = repo[marks[mark]]
845 bmctx = repo[marks[mark]]
845 divs = [repo[b].node() for b in marks
846 divs = [repo[b].node() for b in marks
846 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
847 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
847
848
848 # allow resolving a single divergent bookmark even if moving
849 # allow resolving a single divergent bookmark even if moving
849 # the bookmark across branches when a revision is specified
850 # the bookmark across branches when a revision is specified
850 # that contains a divergent bookmark
851 # that contains a divergent bookmark
851 if bmctx.rev() not in anc and target in divs:
852 if bmctx.rev() not in anc and target in divs:
852 bookmarks.deletedivergent(repo, [target], mark)
853 bookmarks.deletedivergent(repo, [target], mark)
853 return
854 return
854
855
855 deletefrom = [b for b in divs
856 deletefrom = [b for b in divs
856 if repo[b].rev() in anc or b == target]
857 if repo[b].rev() in anc or b == target]
857 bookmarks.deletedivergent(repo, deletefrom, mark)
858 bookmarks.deletedivergent(repo, deletefrom, mark)
858 if bookmarks.validdest(repo, bmctx, repo[target]):
859 if bookmarks.validdest(repo, bmctx, repo[target]):
859 ui.status(_("moving bookmark '%s' forward from %s\n") %
860 ui.status(_("moving bookmark '%s' forward from %s\n") %
860 (mark, short(bmctx.node())))
861 (mark, short(bmctx.node())))
861 return
862 return
862 raise util.Abort(_("bookmark '%s' already exists "
863 raise util.Abort(_("bookmark '%s' already exists "
863 "(use -f to force)") % mark)
864 "(use -f to force)") % mark)
864 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
865 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
865 and not force):
866 and not force):
866 raise util.Abort(
867 raise util.Abort(
867 _("a bookmark cannot have the name of an existing branch"))
868 _("a bookmark cannot have the name of an existing branch"))
868
869
869 if delete and rename:
870 if delete and rename:
870 raise util.Abort(_("--delete and --rename are incompatible"))
871 raise util.Abort(_("--delete and --rename are incompatible"))
871 if delete and rev:
872 if delete and rev:
872 raise util.Abort(_("--rev is incompatible with --delete"))
873 raise util.Abort(_("--rev is incompatible with --delete"))
873 if rename and rev:
874 if rename and rev:
874 raise util.Abort(_("--rev is incompatible with --rename"))
875 raise util.Abort(_("--rev is incompatible with --rename"))
875 if not names and (delete or rev):
876 if not names and (delete or rev):
876 raise util.Abort(_("bookmark name required"))
877 raise util.Abort(_("bookmark name required"))
877
878
878 if delete or rename or names or inactive:
879 if delete or rename or names or inactive:
879 wlock = repo.wlock()
880 wlock = repo.wlock()
880 try:
881 try:
881 cur = repo.changectx('.').node()
882 cur = repo.changectx('.').node()
882 marks = repo._bookmarks
883 marks = repo._bookmarks
883 if delete:
884 if delete:
884 for mark in names:
885 for mark in names:
885 if mark not in marks:
886 if mark not in marks:
886 raise util.Abort(_("bookmark '%s' does not exist") %
887 raise util.Abort(_("bookmark '%s' does not exist") %
887 mark)
888 mark)
888 if mark == repo._bookmarkcurrent:
889 if mark == repo._bookmarkcurrent:
889 bookmarks.unsetcurrent(repo)
890 bookmarks.unsetcurrent(repo)
890 del marks[mark]
891 del marks[mark]
891 marks.write()
892 marks.write()
892
893
893 elif rename:
894 elif rename:
894 if not names:
895 if not names:
895 raise util.Abort(_("new bookmark name required"))
896 raise util.Abort(_("new bookmark name required"))
896 elif len(names) > 1:
897 elif len(names) > 1:
897 raise util.Abort(_("only one new bookmark name allowed"))
898 raise util.Abort(_("only one new bookmark name allowed"))
898 mark = checkformat(names[0])
899 mark = checkformat(names[0])
899 if rename not in marks:
900 if rename not in marks:
900 raise util.Abort(_("bookmark '%s' does not exist") % rename)
901 raise util.Abort(_("bookmark '%s' does not exist") % rename)
901 checkconflict(repo, mark, cur, force)
902 checkconflict(repo, mark, cur, force)
902 marks[mark] = marks[rename]
903 marks[mark] = marks[rename]
903 if repo._bookmarkcurrent == rename and not inactive:
904 if repo._bookmarkcurrent == rename and not inactive:
904 bookmarks.setcurrent(repo, mark)
905 bookmarks.setcurrent(repo, mark)
905 del marks[rename]
906 del marks[rename]
906 marks.write()
907 marks.write()
907
908
908 elif names:
909 elif names:
909 newact = None
910 newact = None
910 for mark in names:
911 for mark in names:
911 mark = checkformat(mark)
912 mark = checkformat(mark)
912 if newact is None:
913 if newact is None:
913 newact = mark
914 newact = mark
914 if inactive and mark == repo._bookmarkcurrent:
915 if inactive and mark == repo._bookmarkcurrent:
915 bookmarks.unsetcurrent(repo)
916 bookmarks.unsetcurrent(repo)
916 return
917 return
917 tgt = cur
918 tgt = cur
918 if rev:
919 if rev:
919 tgt = scmutil.revsingle(repo, rev).node()
920 tgt = scmutil.revsingle(repo, rev).node()
920 checkconflict(repo, mark, cur, force, tgt)
921 checkconflict(repo, mark, cur, force, tgt)
921 marks[mark] = tgt
922 marks[mark] = tgt
922 if not inactive and cur == marks[newact] and not rev:
923 if not inactive and cur == marks[newact] and not rev:
923 bookmarks.setcurrent(repo, newact)
924 bookmarks.setcurrent(repo, newact)
924 elif cur != tgt and newact == repo._bookmarkcurrent:
925 elif cur != tgt and newact == repo._bookmarkcurrent:
925 bookmarks.unsetcurrent(repo)
926 bookmarks.unsetcurrent(repo)
926 marks.write()
927 marks.write()
927
928
928 elif inactive:
929 elif inactive:
929 if len(marks) == 0:
930 if len(marks) == 0:
930 ui.status(_("no bookmarks set\n"))
931 ui.status(_("no bookmarks set\n"))
931 elif not repo._bookmarkcurrent:
932 elif not repo._bookmarkcurrent:
932 ui.status(_("no active bookmark\n"))
933 ui.status(_("no active bookmark\n"))
933 else:
934 else:
934 bookmarks.unsetcurrent(repo)
935 bookmarks.unsetcurrent(repo)
935 finally:
936 finally:
936 wlock.release()
937 wlock.release()
937 else: # show bookmarks
938 else: # show bookmarks
938 hexfn = ui.debugflag and hex or short
939 hexfn = ui.debugflag and hex or short
939 marks = repo._bookmarks
940 marks = repo._bookmarks
940 if len(marks) == 0:
941 if len(marks) == 0:
941 ui.status(_("no bookmarks set\n"))
942 ui.status(_("no bookmarks set\n"))
942 else:
943 else:
943 for bmark, n in sorted(marks.iteritems()):
944 for bmark, n in sorted(marks.iteritems()):
944 current = repo._bookmarkcurrent
945 current = repo._bookmarkcurrent
945 if bmark == current:
946 if bmark == current:
946 prefix, label = '*', 'bookmarks.current'
947 prefix, label = '*', 'bookmarks.current'
947 else:
948 else:
948 prefix, label = ' ', ''
949 prefix, label = ' ', ''
949
950
950 if ui.quiet:
951 if ui.quiet:
951 ui.write("%s\n" % bmark, label=label)
952 ui.write("%s\n" % bmark, label=label)
952 else:
953 else:
953 pad = " " * (25 - encoding.colwidth(bmark))
954 pad = " " * (25 - encoding.colwidth(bmark))
954 ui.write(" %s %s%s %d:%s\n" % (
955 ui.write(" %s %s%s %d:%s\n" % (
955 prefix, bmark, pad, repo.changelog.rev(n), hexfn(n)),
956 prefix, bmark, pad, repo.changelog.rev(n), hexfn(n)),
956 label=label)
957 label=label)
957
958
958 @command('branch',
959 @command('branch',
959 [('f', 'force', None,
960 [('f', 'force', None,
960 _('set branch name even if it shadows an existing branch')),
961 _('set branch name even if it shadows an existing branch')),
961 ('C', 'clean', None, _('reset branch name to parent branch name'))],
962 ('C', 'clean', None, _('reset branch name to parent branch name'))],
962 _('[-fC] [NAME]'))
963 _('[-fC] [NAME]'))
963 def branch(ui, repo, label=None, **opts):
964 def branch(ui, repo, label=None, **opts):
964 """set or show the current branch name
965 """set or show the current branch name
965
966
966 .. note::
967 .. note::
967
968
968 Branch names are permanent and global. Use :hg:`bookmark` to create a
969 Branch names are permanent and global. Use :hg:`bookmark` to create a
969 light-weight bookmark instead. See :hg:`help glossary` for more
970 light-weight bookmark instead. See :hg:`help glossary` for more
970 information about named branches and bookmarks.
971 information about named branches and bookmarks.
971
972
972 With no argument, show the current branch name. With one argument,
973 With no argument, show the current branch name. With one argument,
973 set the working directory branch name (the branch will not exist
974 set the working directory branch name (the branch will not exist
974 in the repository until the next commit). Standard practice
975 in the repository until the next commit). Standard practice
975 recommends that primary development take place on the 'default'
976 recommends that primary development take place on the 'default'
976 branch.
977 branch.
977
978
978 Unless -f/--force is specified, branch will not let you set a
979 Unless -f/--force is specified, branch will not let you set a
979 branch name that already exists, even if it's inactive.
980 branch name that already exists, even if it's inactive.
980
981
981 Use -C/--clean to reset the working directory branch to that of
982 Use -C/--clean to reset the working directory branch to that of
982 the parent of the working directory, negating a previous branch
983 the parent of the working directory, negating a previous branch
983 change.
984 change.
984
985
985 Use the command :hg:`update` to switch to an existing branch. Use
986 Use the command :hg:`update` to switch to an existing branch. Use
986 :hg:`commit --close-branch` to mark this branch as closed.
987 :hg:`commit --close-branch` to mark this branch as closed.
987
988
988 Returns 0 on success.
989 Returns 0 on success.
989 """
990 """
990 if label:
991 if label:
991 label = label.strip()
992 label = label.strip()
992
993
993 if not opts.get('clean') and not label:
994 if not opts.get('clean') and not label:
994 ui.write("%s\n" % repo.dirstate.branch())
995 ui.write("%s\n" % repo.dirstate.branch())
995 return
996 return
996
997
997 wlock = repo.wlock()
998 wlock = repo.wlock()
998 try:
999 try:
999 if opts.get('clean'):
1000 if opts.get('clean'):
1000 label = repo[None].p1().branch()
1001 label = repo[None].p1().branch()
1001 repo.dirstate.setbranch(label)
1002 repo.dirstate.setbranch(label)
1002 ui.status(_('reset working directory to branch %s\n') % label)
1003 ui.status(_('reset working directory to branch %s\n') % label)
1003 elif label:
1004 elif label:
1004 if not opts.get('force') and label in repo.branchmap():
1005 if not opts.get('force') and label in repo.branchmap():
1005 if label not in [p.branch() for p in repo.parents()]:
1006 if label not in [p.branch() for p in repo.parents()]:
1006 raise util.Abort(_('a branch of the same name already'
1007 raise util.Abort(_('a branch of the same name already'
1007 ' exists'),
1008 ' exists'),
1008 # i18n: "it" refers to an existing branch
1009 # i18n: "it" refers to an existing branch
1009 hint=_("use 'hg update' to switch to it"))
1010 hint=_("use 'hg update' to switch to it"))
1010 scmutil.checknewlabel(repo, label, 'branch')
1011 scmutil.checknewlabel(repo, label, 'branch')
1011 repo.dirstate.setbranch(label)
1012 repo.dirstate.setbranch(label)
1012 ui.status(_('marked working directory as branch %s\n') % label)
1013 ui.status(_('marked working directory as branch %s\n') % label)
1013 ui.status(_('(branches are permanent and global, '
1014 ui.status(_('(branches are permanent and global, '
1014 'did you want a bookmark?)\n'))
1015 'did you want a bookmark?)\n'))
1015 finally:
1016 finally:
1016 wlock.release()
1017 wlock.release()
1017
1018
1018 @command('branches',
1019 @command('branches',
1019 [('a', 'active', False, _('show only branches that have unmerged heads')),
1020 [('a', 'active', False, _('show only branches that have unmerged heads')),
1020 ('c', 'closed', False, _('show normal and closed branches'))],
1021 ('c', 'closed', False, _('show normal and closed branches'))],
1021 _('[-ac]'))
1022 _('[-ac]'))
1022 def branches(ui, repo, active=False, closed=False):
1023 def branches(ui, repo, active=False, closed=False):
1023 """list repository named branches
1024 """list repository named branches
1024
1025
1025 List the repository's named branches, indicating which ones are
1026 List the repository's named branches, indicating which ones are
1026 inactive. If -c/--closed is specified, also list branches which have
1027 inactive. If -c/--closed is specified, also list branches which have
1027 been marked closed (see :hg:`commit --close-branch`).
1028 been marked closed (see :hg:`commit --close-branch`).
1028
1029
1029 If -a/--active is specified, only show active branches. A branch
1030 If -a/--active is specified, only show active branches. A branch
1030 is considered active if it contains repository heads.
1031 is considered active if it contains repository heads.
1031
1032
1032 Use the command :hg:`update` to switch to an existing branch.
1033 Use the command :hg:`update` to switch to an existing branch.
1033
1034
1034 Returns 0.
1035 Returns 0.
1035 """
1036 """
1036
1037
1037 hexfunc = ui.debugflag and hex or short
1038 hexfunc = ui.debugflag and hex or short
1038
1039
1039 allheads = set(repo.heads())
1040 allheads = set(repo.heads())
1040 branches = []
1041 branches = []
1041 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1042 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1042 isactive = not isclosed and bool(set(heads) & allheads)
1043 isactive = not isclosed and bool(set(heads) & allheads)
1043 branches.append((tag, repo[tip], isactive, not isclosed))
1044 branches.append((tag, repo[tip], isactive, not isclosed))
1044 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1045 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1045 reverse=True)
1046 reverse=True)
1046
1047
1047 for tag, ctx, isactive, isopen in branches:
1048 for tag, ctx, isactive, isopen in branches:
1048 if (not active) or isactive:
1049 if (not active) or isactive:
1049 if isactive:
1050 if isactive:
1050 label = 'branches.active'
1051 label = 'branches.active'
1051 notice = ''
1052 notice = ''
1052 elif not isopen:
1053 elif not isopen:
1053 if not closed:
1054 if not closed:
1054 continue
1055 continue
1055 label = 'branches.closed'
1056 label = 'branches.closed'
1056 notice = _(' (closed)')
1057 notice = _(' (closed)')
1057 else:
1058 else:
1058 label = 'branches.inactive'
1059 label = 'branches.inactive'
1059 notice = _(' (inactive)')
1060 notice = _(' (inactive)')
1060 if tag == repo.dirstate.branch():
1061 if tag == repo.dirstate.branch():
1061 label = 'branches.current'
1062 label = 'branches.current'
1062 rev = str(ctx.rev()).rjust(31 - encoding.colwidth(tag))
1063 rev = str(ctx.rev()).rjust(31 - encoding.colwidth(tag))
1063 rev = ui.label('%s:%s' % (rev, hexfunc(ctx.node())),
1064 rev = ui.label('%s:%s' % (rev, hexfunc(ctx.node())),
1064 'log.changeset changeset.%s' % ctx.phasestr())
1065 'log.changeset changeset.%s' % ctx.phasestr())
1065 labeledtag = ui.label(tag, label)
1066 labeledtag = ui.label(tag, label)
1066 if ui.quiet:
1067 if ui.quiet:
1067 ui.write("%s\n" % labeledtag)
1068 ui.write("%s\n" % labeledtag)
1068 else:
1069 else:
1069 ui.write("%s %s%s\n" % (labeledtag, rev, notice))
1070 ui.write("%s %s%s\n" % (labeledtag, rev, notice))
1070
1071
1071 @command('bundle',
1072 @command('bundle',
1072 [('f', 'force', None, _('run even when the destination is unrelated')),
1073 [('f', 'force', None, _('run even when the destination is unrelated')),
1073 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1074 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1074 _('REV')),
1075 _('REV')),
1075 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1076 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1076 _('BRANCH')),
1077 _('BRANCH')),
1077 ('', 'base', [],
1078 ('', 'base', [],
1078 _('a base changeset assumed to be available at the destination'),
1079 _('a base changeset assumed to be available at the destination'),
1079 _('REV')),
1080 _('REV')),
1080 ('a', 'all', None, _('bundle all changesets in the repository')),
1081 ('a', 'all', None, _('bundle all changesets in the repository')),
1081 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1082 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1082 ] + remoteopts,
1083 ] + remoteopts,
1083 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1084 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1084 def bundle(ui, repo, fname, dest=None, **opts):
1085 def bundle(ui, repo, fname, dest=None, **opts):
1085 """create a changegroup file
1086 """create a changegroup file
1086
1087
1087 Generate a compressed changegroup file collecting changesets not
1088 Generate a compressed changegroup file collecting changesets not
1088 known to be in another repository.
1089 known to be in another repository.
1089
1090
1090 If you omit the destination repository, then hg assumes the
1091 If you omit the destination repository, then hg assumes the
1091 destination will have all the nodes you specify with --base
1092 destination will have all the nodes you specify with --base
1092 parameters. To create a bundle containing all changesets, use
1093 parameters. To create a bundle containing all changesets, use
1093 -a/--all (or --base null).
1094 -a/--all (or --base null).
1094
1095
1095 You can change compression method with the -t/--type option.
1096 You can change compression method with the -t/--type option.
1096 The available compression methods are: none, bzip2, and
1097 The available compression methods are: none, bzip2, and
1097 gzip (by default, bundles are compressed using bzip2).
1098 gzip (by default, bundles are compressed using bzip2).
1098
1099
1099 The bundle file can then be transferred using conventional means
1100 The bundle file can then be transferred using conventional means
1100 and applied to another repository with the unbundle or pull
1101 and applied to another repository with the unbundle or pull
1101 command. This is useful when direct push and pull are not
1102 command. This is useful when direct push and pull are not
1102 available or when exporting an entire repository is undesirable.
1103 available or when exporting an entire repository is undesirable.
1103
1104
1104 Applying bundles preserves all changeset contents including
1105 Applying bundles preserves all changeset contents including
1105 permissions, copy/rename information, and revision history.
1106 permissions, copy/rename information, and revision history.
1106
1107
1107 Returns 0 on success, 1 if no changes found.
1108 Returns 0 on success, 1 if no changes found.
1108 """
1109 """
1109 revs = None
1110 revs = None
1110 if 'rev' in opts:
1111 if 'rev' in opts:
1111 revs = scmutil.revrange(repo, opts['rev'])
1112 revs = scmutil.revrange(repo, opts['rev'])
1112
1113
1113 bundletype = opts.get('type', 'bzip2').lower()
1114 bundletype = opts.get('type', 'bzip2').lower()
1114 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1115 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1115 bundletype = btypes.get(bundletype)
1116 bundletype = btypes.get(bundletype)
1116 if bundletype not in changegroup.bundletypes:
1117 if bundletype not in changegroup.bundletypes:
1117 raise util.Abort(_('unknown bundle type specified with --type'))
1118 raise util.Abort(_('unknown bundle type specified with --type'))
1118
1119
1119 if opts.get('all'):
1120 if opts.get('all'):
1120 base = ['null']
1121 base = ['null']
1121 else:
1122 else:
1122 base = scmutil.revrange(repo, opts.get('base'))
1123 base = scmutil.revrange(repo, opts.get('base'))
1123 # TODO: get desired bundlecaps from command line.
1124 # TODO: get desired bundlecaps from command line.
1124 bundlecaps = None
1125 bundlecaps = None
1125 if base:
1126 if base:
1126 if dest:
1127 if dest:
1127 raise util.Abort(_("--base is incompatible with specifying "
1128 raise util.Abort(_("--base is incompatible with specifying "
1128 "a destination"))
1129 "a destination"))
1129 common = [repo.lookup(rev) for rev in base]
1130 common = [repo.lookup(rev) for rev in base]
1130 heads = revs and map(repo.lookup, revs) or revs
1131 heads = revs and map(repo.lookup, revs) or revs
1131 cg = changegroup.getbundle(repo, 'bundle', heads=heads, common=common,
1132 cg = changegroup.getbundle(repo, 'bundle', heads=heads, common=common,
1132 bundlecaps=bundlecaps)
1133 bundlecaps=bundlecaps)
1133 outgoing = None
1134 outgoing = None
1134 else:
1135 else:
1135 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1136 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1136 dest, branches = hg.parseurl(dest, opts.get('branch'))
1137 dest, branches = hg.parseurl(dest, opts.get('branch'))
1137 other = hg.peer(repo, opts, dest)
1138 other = hg.peer(repo, opts, dest)
1138 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1139 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1139 heads = revs and map(repo.lookup, revs) or revs
1140 heads = revs and map(repo.lookup, revs) or revs
1140 outgoing = discovery.findcommonoutgoing(repo, other,
1141 outgoing = discovery.findcommonoutgoing(repo, other,
1141 onlyheads=heads,
1142 onlyheads=heads,
1142 force=opts.get('force'),
1143 force=opts.get('force'),
1143 portable=True)
1144 portable=True)
1144 cg = changegroup.getlocalbundle(repo, 'bundle', outgoing, bundlecaps)
1145 cg = changegroup.getlocalbundle(repo, 'bundle', outgoing, bundlecaps)
1145 if not cg:
1146 if not cg:
1146 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1147 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1147 return 1
1148 return 1
1148
1149
1149 changegroup.writebundle(cg, fname, bundletype)
1150 changegroup.writebundle(cg, fname, bundletype)
1150
1151
1151 @command('cat',
1152 @command('cat',
1152 [('o', 'output', '',
1153 [('o', 'output', '',
1153 _('print output to file with formatted name'), _('FORMAT')),
1154 _('print output to file with formatted name'), _('FORMAT')),
1154 ('r', 'rev', '', _('print the given revision'), _('REV')),
1155 ('r', 'rev', '', _('print the given revision'), _('REV')),
1155 ('', 'decode', None, _('apply any matching decode filter')),
1156 ('', 'decode', None, _('apply any matching decode filter')),
1156 ] + walkopts,
1157 ] + walkopts,
1157 _('[OPTION]... FILE...'))
1158 _('[OPTION]... FILE...'))
1158 def cat(ui, repo, file1, *pats, **opts):
1159 def cat(ui, repo, file1, *pats, **opts):
1159 """output the current or given revision of files
1160 """output the current or given revision of files
1160
1161
1161 Print the specified files as they were at the given revision. If
1162 Print the specified files as they were at the given revision. If
1162 no revision is given, the parent of the working directory is used.
1163 no revision is given, the parent of the working directory is used.
1163
1164
1164 Output may be to a file, in which case the name of the file is
1165 Output may be to a file, in which case the name of the file is
1165 given using a format string. The formatting rules as follows:
1166 given using a format string. The formatting rules as follows:
1166
1167
1167 :``%%``: literal "%" character
1168 :``%%``: literal "%" character
1168 :``%s``: basename of file being printed
1169 :``%s``: basename of file being printed
1169 :``%d``: dirname of file being printed, or '.' if in repository root
1170 :``%d``: dirname of file being printed, or '.' if in repository root
1170 :``%p``: root-relative path name of file being printed
1171 :``%p``: root-relative path name of file being printed
1171 :``%H``: changeset hash (40 hexadecimal digits)
1172 :``%H``: changeset hash (40 hexadecimal digits)
1172 :``%R``: changeset revision number
1173 :``%R``: changeset revision number
1173 :``%h``: short-form changeset hash (12 hexadecimal digits)
1174 :``%h``: short-form changeset hash (12 hexadecimal digits)
1174 :``%r``: zero-padded changeset revision number
1175 :``%r``: zero-padded changeset revision number
1175 :``%b``: basename of the exporting repository
1176 :``%b``: basename of the exporting repository
1176
1177
1177 Returns 0 on success.
1178 Returns 0 on success.
1178 """
1179 """
1179 ctx = scmutil.revsingle(repo, opts.get('rev'))
1180 ctx = scmutil.revsingle(repo, opts.get('rev'))
1180 m = scmutil.match(ctx, (file1,) + pats, opts)
1181 m = scmutil.match(ctx, (file1,) + pats, opts)
1181
1182
1182 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1183 return cmdutil.cat(ui, repo, ctx, m, '', **opts)
1183
1184
1184 @command('^clone',
1185 @command('^clone',
1185 [('U', 'noupdate', None,
1186 [('U', 'noupdate', None,
1186 _('the clone will include an empty working copy (only a repository)')),
1187 _('the clone will include an empty working copy (only a repository)')),
1187 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1188 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1188 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1189 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1189 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1190 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1190 ('', 'pull', None, _('use pull protocol to copy metadata')),
1191 ('', 'pull', None, _('use pull protocol to copy metadata')),
1191 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1192 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1192 ] + remoteopts,
1193 ] + remoteopts,
1193 _('[OPTION]... SOURCE [DEST]'))
1194 _('[OPTION]... SOURCE [DEST]'))
1194 def clone(ui, source, dest=None, **opts):
1195 def clone(ui, source, dest=None, **opts):
1195 """make a copy of an existing repository
1196 """make a copy of an existing repository
1196
1197
1197 Create a copy of an existing repository in a new directory.
1198 Create a copy of an existing repository in a new directory.
1198
1199
1199 If no destination directory name is specified, it defaults to the
1200 If no destination directory name is specified, it defaults to the
1200 basename of the source.
1201 basename of the source.
1201
1202
1202 The location of the source is added to the new repository's
1203 The location of the source is added to the new repository's
1203 ``.hg/hgrc`` file, as the default to be used for future pulls.
1204 ``.hg/hgrc`` file, as the default to be used for future pulls.
1204
1205
1205 Only local paths and ``ssh://`` URLs are supported as
1206 Only local paths and ``ssh://`` URLs are supported as
1206 destinations. For ``ssh://`` destinations, no working directory or
1207 destinations. For ``ssh://`` destinations, no working directory or
1207 ``.hg/hgrc`` will be created on the remote side.
1208 ``.hg/hgrc`` will be created on the remote side.
1208
1209
1209 To pull only a subset of changesets, specify one or more revisions
1210 To pull only a subset of changesets, specify one or more revisions
1210 identifiers with -r/--rev or branches with -b/--branch. The
1211 identifiers with -r/--rev or branches with -b/--branch. The
1211 resulting clone will contain only the specified changesets and
1212 resulting clone will contain only the specified changesets and
1212 their ancestors. These options (or 'clone src#rev dest') imply
1213 their ancestors. These options (or 'clone src#rev dest') imply
1213 --pull, even for local source repositories. Note that specifying a
1214 --pull, even for local source repositories. Note that specifying a
1214 tag will include the tagged changeset but not the changeset
1215 tag will include the tagged changeset but not the changeset
1215 containing the tag.
1216 containing the tag.
1216
1217
1217 If the source repository has a bookmark called '@' set, that
1218 If the source repository has a bookmark called '@' set, that
1218 revision will be checked out in the new repository by default.
1219 revision will be checked out in the new repository by default.
1219
1220
1220 To check out a particular version, use -u/--update, or
1221 To check out a particular version, use -u/--update, or
1221 -U/--noupdate to create a clone with no working directory.
1222 -U/--noupdate to create a clone with no working directory.
1222
1223
1223 .. container:: verbose
1224 .. container:: verbose
1224
1225
1225 For efficiency, hardlinks are used for cloning whenever the
1226 For efficiency, hardlinks are used for cloning whenever the
1226 source and destination are on the same filesystem (note this
1227 source and destination are on the same filesystem (note this
1227 applies only to the repository data, not to the working
1228 applies only to the repository data, not to the working
1228 directory). Some filesystems, such as AFS, implement hardlinking
1229 directory). Some filesystems, such as AFS, implement hardlinking
1229 incorrectly, but do not report errors. In these cases, use the
1230 incorrectly, but do not report errors. In these cases, use the
1230 --pull option to avoid hardlinking.
1231 --pull option to avoid hardlinking.
1231
1232
1232 In some cases, you can clone repositories and the working
1233 In some cases, you can clone repositories and the working
1233 directory using full hardlinks with ::
1234 directory using full hardlinks with ::
1234
1235
1235 $ cp -al REPO REPOCLONE
1236 $ cp -al REPO REPOCLONE
1236
1237
1237 This is the fastest way to clone, but it is not always safe. The
1238 This is the fastest way to clone, but it is not always safe. The
1238 operation is not atomic (making sure REPO is not modified during
1239 operation is not atomic (making sure REPO is not modified during
1239 the operation is up to you) and you have to make sure your
1240 the operation is up to you) and you have to make sure your
1240 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1241 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1241 so). Also, this is not compatible with certain extensions that
1242 so). Also, this is not compatible with certain extensions that
1242 place their metadata under the .hg directory, such as mq.
1243 place their metadata under the .hg directory, such as mq.
1243
1244
1244 Mercurial will update the working directory to the first applicable
1245 Mercurial will update the working directory to the first applicable
1245 revision from this list:
1246 revision from this list:
1246
1247
1247 a) null if -U or the source repository has no changesets
1248 a) null if -U or the source repository has no changesets
1248 b) if -u . and the source repository is local, the first parent of
1249 b) if -u . and the source repository is local, the first parent of
1249 the source repository's working directory
1250 the source repository's working directory
1250 c) the changeset specified with -u (if a branch name, this means the
1251 c) the changeset specified with -u (if a branch name, this means the
1251 latest head of that branch)
1252 latest head of that branch)
1252 d) the changeset specified with -r
1253 d) the changeset specified with -r
1253 e) the tipmost head specified with -b
1254 e) the tipmost head specified with -b
1254 f) the tipmost head specified with the url#branch source syntax
1255 f) the tipmost head specified with the url#branch source syntax
1255 g) the revision marked with the '@' bookmark, if present
1256 g) the revision marked with the '@' bookmark, if present
1256 h) the tipmost head of the default branch
1257 h) the tipmost head of the default branch
1257 i) tip
1258 i) tip
1258
1259
1259 Examples:
1260 Examples:
1260
1261
1261 - clone a remote repository to a new directory named hg/::
1262 - clone a remote repository to a new directory named hg/::
1262
1263
1263 hg clone http://selenic.com/hg
1264 hg clone http://selenic.com/hg
1264
1265
1265 - create a lightweight local clone::
1266 - create a lightweight local clone::
1266
1267
1267 hg clone project/ project-feature/
1268 hg clone project/ project-feature/
1268
1269
1269 - clone from an absolute path on an ssh server (note double-slash)::
1270 - clone from an absolute path on an ssh server (note double-slash)::
1270
1271
1271 hg clone ssh://user@server//home/projects/alpha/
1272 hg clone ssh://user@server//home/projects/alpha/
1272
1273
1273 - do a high-speed clone over a LAN while checking out a
1274 - do a high-speed clone over a LAN while checking out a
1274 specified version::
1275 specified version::
1275
1276
1276 hg clone --uncompressed http://server/repo -u 1.5
1277 hg clone --uncompressed http://server/repo -u 1.5
1277
1278
1278 - create a repository without changesets after a particular revision::
1279 - create a repository without changesets after a particular revision::
1279
1280
1280 hg clone -r 04e544 experimental/ good/
1281 hg clone -r 04e544 experimental/ good/
1281
1282
1282 - clone (and track) a particular named branch::
1283 - clone (and track) a particular named branch::
1283
1284
1284 hg clone http://selenic.com/hg#stable
1285 hg clone http://selenic.com/hg#stable
1285
1286
1286 See :hg:`help urls` for details on specifying URLs.
1287 See :hg:`help urls` for details on specifying URLs.
1287
1288
1288 Returns 0 on success.
1289 Returns 0 on success.
1289 """
1290 """
1290 if opts.get('noupdate') and opts.get('updaterev'):
1291 if opts.get('noupdate') and opts.get('updaterev'):
1291 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1292 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1292
1293
1293 r = hg.clone(ui, opts, source, dest,
1294 r = hg.clone(ui, opts, source, dest,
1294 pull=opts.get('pull'),
1295 pull=opts.get('pull'),
1295 stream=opts.get('uncompressed'),
1296 stream=opts.get('uncompressed'),
1296 rev=opts.get('rev'),
1297 rev=opts.get('rev'),
1297 update=opts.get('updaterev') or not opts.get('noupdate'),
1298 update=opts.get('updaterev') or not opts.get('noupdate'),
1298 branch=opts.get('branch'))
1299 branch=opts.get('branch'))
1299
1300
1300 return r is None
1301 return r is None
1301
1302
1302 @command('^commit|ci',
1303 @command('^commit|ci',
1303 [('A', 'addremove', None,
1304 [('A', 'addremove', None,
1304 _('mark new/missing files as added/removed before committing')),
1305 _('mark new/missing files as added/removed before committing')),
1305 ('', 'close-branch', None,
1306 ('', 'close-branch', None,
1306 _('mark a branch as closed, hiding it from the branch list')),
1307 _('mark a branch as closed, hiding it from the branch list')),
1307 ('', 'amend', None, _('amend the parent of the working dir')),
1308 ('', 'amend', None, _('amend the parent of the working dir')),
1308 ('s', 'secret', None, _('use the secret phase for committing')),
1309 ('s', 'secret', None, _('use the secret phase for committing')),
1309 ('e', 'edit', None,
1310 ('e', 'edit', None,
1310 _('further edit commit message already specified')),
1311 _('further edit commit message already specified')),
1311 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1312 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1312 _('[OPTION]... [FILE]...'))
1313 _('[OPTION]... [FILE]...'))
1313 def commit(ui, repo, *pats, **opts):
1314 def commit(ui, repo, *pats, **opts):
1314 """commit the specified files or all outstanding changes
1315 """commit the specified files or all outstanding changes
1315
1316
1316 Commit changes to the given files into the repository. Unlike a
1317 Commit changes to the given files into the repository. Unlike a
1317 centralized SCM, this operation is a local operation. See
1318 centralized SCM, this operation is a local operation. See
1318 :hg:`push` for a way to actively distribute your changes.
1319 :hg:`push` for a way to actively distribute your changes.
1319
1320
1320 If a list of files is omitted, all changes reported by :hg:`status`
1321 If a list of files is omitted, all changes reported by :hg:`status`
1321 will be committed.
1322 will be committed.
1322
1323
1323 If you are committing the result of a merge, do not provide any
1324 If you are committing the result of a merge, do not provide any
1324 filenames or -I/-X filters.
1325 filenames or -I/-X filters.
1325
1326
1326 If no commit message is specified, Mercurial starts your
1327 If no commit message is specified, Mercurial starts your
1327 configured editor where you can enter a message. In case your
1328 configured editor where you can enter a message. In case your
1328 commit fails, you will find a backup of your message in
1329 commit fails, you will find a backup of your message in
1329 ``.hg/last-message.txt``.
1330 ``.hg/last-message.txt``.
1330
1331
1331 The --amend flag can be used to amend the parent of the
1332 The --amend flag can be used to amend the parent of the
1332 working directory with a new commit that contains the changes
1333 working directory with a new commit that contains the changes
1333 in the parent in addition to those currently reported by :hg:`status`,
1334 in the parent in addition to those currently reported by :hg:`status`,
1334 if there are any. The old commit is stored in a backup bundle in
1335 if there are any. The old commit is stored in a backup bundle in
1335 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1336 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1336 on how to restore it).
1337 on how to restore it).
1337
1338
1338 Message, user and date are taken from the amended commit unless
1339 Message, user and date are taken from the amended commit unless
1339 specified. When a message isn't specified on the command line,
1340 specified. When a message isn't specified on the command line,
1340 the editor will open with the message of the amended commit.
1341 the editor will open with the message of the amended commit.
1341
1342
1342 It is not possible to amend public changesets (see :hg:`help phases`)
1343 It is not possible to amend public changesets (see :hg:`help phases`)
1343 or changesets that have children.
1344 or changesets that have children.
1344
1345
1345 See :hg:`help dates` for a list of formats valid for -d/--date.
1346 See :hg:`help dates` for a list of formats valid for -d/--date.
1346
1347
1347 Returns 0 on success, 1 if nothing changed.
1348 Returns 0 on success, 1 if nothing changed.
1348 """
1349 """
1349 if opts.get('subrepos'):
1350 if opts.get('subrepos'):
1350 if opts.get('amend'):
1351 if opts.get('amend'):
1351 raise util.Abort(_('cannot amend with --subrepos'))
1352 raise util.Abort(_('cannot amend with --subrepos'))
1352 # Let --subrepos on the command line override config setting.
1353 # Let --subrepos on the command line override config setting.
1353 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1354 ui.setconfig('ui', 'commitsubrepos', True, 'commit')
1354
1355
1355 # Save this for restoring it later
1356 # Save this for restoring it later
1356 oldcommitphase = ui.config('phases', 'new-commit')
1357 oldcommitphase = ui.config('phases', 'new-commit')
1357
1358
1358 cmdutil.checkunfinished(repo, commit=True)
1359 cmdutil.checkunfinished(repo, commit=True)
1359
1360
1360 branch = repo[None].branch()
1361 branch = repo[None].branch()
1361 bheads = repo.branchheads(branch)
1362 bheads = repo.branchheads(branch)
1362
1363
1363 extra = {}
1364 extra = {}
1364 if opts.get('close_branch'):
1365 if opts.get('close_branch'):
1365 extra['close'] = 1
1366 extra['close'] = 1
1366
1367
1367 if not bheads:
1368 if not bheads:
1368 raise util.Abort(_('can only close branch heads'))
1369 raise util.Abort(_('can only close branch heads'))
1369 elif opts.get('amend'):
1370 elif opts.get('amend'):
1370 if repo.parents()[0].p1().branch() != branch and \
1371 if repo.parents()[0].p1().branch() != branch and \
1371 repo.parents()[0].p2().branch() != branch:
1372 repo.parents()[0].p2().branch() != branch:
1372 raise util.Abort(_('can only close branch heads'))
1373 raise util.Abort(_('can only close branch heads'))
1373
1374
1374 if opts.get('amend'):
1375 if opts.get('amend'):
1375 if ui.configbool('ui', 'commitsubrepos'):
1376 if ui.configbool('ui', 'commitsubrepos'):
1376 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1377 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1377
1378
1378 old = repo['.']
1379 old = repo['.']
1379 if old.phase() == phases.public:
1380 if old.phase() == phases.public:
1380 raise util.Abort(_('cannot amend public changesets'))
1381 raise util.Abort(_('cannot amend public changesets'))
1381 if len(repo[None].parents()) > 1:
1382 if len(repo[None].parents()) > 1:
1382 raise util.Abort(_('cannot amend while merging'))
1383 raise util.Abort(_('cannot amend while merging'))
1383 if (not obsolete._enabled) and old.children():
1384 if (not obsolete._enabled) and old.children():
1384 raise util.Abort(_('cannot amend changeset with children'))
1385 raise util.Abort(_('cannot amend changeset with children'))
1385
1386
1386 # commitfunc is used only for temporary amend commit by cmdutil.amend
1387 # commitfunc is used only for temporary amend commit by cmdutil.amend
1387 def commitfunc(ui, repo, message, match, opts):
1388 def commitfunc(ui, repo, message, match, opts):
1388 return repo.commit(message,
1389 return repo.commit(message,
1389 opts.get('user') or old.user(),
1390 opts.get('user') or old.user(),
1390 opts.get('date') or old.date(),
1391 opts.get('date') or old.date(),
1391 match,
1392 match,
1392 extra=extra)
1393 extra=extra)
1393
1394
1394 current = repo._bookmarkcurrent
1395 current = repo._bookmarkcurrent
1395 marks = old.bookmarks()
1396 marks = old.bookmarks()
1396 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1397 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1397 if node == old.node():
1398 if node == old.node():
1398 ui.status(_("nothing changed\n"))
1399 ui.status(_("nothing changed\n"))
1399 return 1
1400 return 1
1400 elif marks:
1401 elif marks:
1401 ui.debug('moving bookmarks %r from %s to %s\n' %
1402 ui.debug('moving bookmarks %r from %s to %s\n' %
1402 (marks, old.hex(), hex(node)))
1403 (marks, old.hex(), hex(node)))
1403 newmarks = repo._bookmarks
1404 newmarks = repo._bookmarks
1404 for bm in marks:
1405 for bm in marks:
1405 newmarks[bm] = node
1406 newmarks[bm] = node
1406 if bm == current:
1407 if bm == current:
1407 bookmarks.setcurrent(repo, bm)
1408 bookmarks.setcurrent(repo, bm)
1408 newmarks.write()
1409 newmarks.write()
1409 else:
1410 else:
1410 def commitfunc(ui, repo, message, match, opts):
1411 def commitfunc(ui, repo, message, match, opts):
1411 try:
1412 try:
1412 if opts.get('secret'):
1413 if opts.get('secret'):
1413 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1414 ui.setconfig('phases', 'new-commit', 'secret', 'commit')
1414 # Propagate to subrepos
1415 # Propagate to subrepos
1415 repo.baseui.setconfig('phases', 'new-commit', 'secret',
1416 repo.baseui.setconfig('phases', 'new-commit', 'secret',
1416 'commit')
1417 'commit')
1417
1418
1418 return repo.commit(message, opts.get('user'), opts.get('date'),
1419 return repo.commit(message, opts.get('user'), opts.get('date'),
1419 match,
1420 match,
1420 editor=cmdutil.getcommiteditor(**opts),
1421 editor=cmdutil.getcommiteditor(**opts),
1421 extra=extra)
1422 extra=extra)
1422 finally:
1423 finally:
1423 ui.setconfig('phases', 'new-commit', oldcommitphase, 'commit')
1424 ui.setconfig('phases', 'new-commit', oldcommitphase, 'commit')
1424 repo.baseui.setconfig('phases', 'new-commit', oldcommitphase,
1425 repo.baseui.setconfig('phases', 'new-commit', oldcommitphase,
1425 'commit')
1426 'commit')
1426
1427
1427
1428
1428 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1429 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1429
1430
1430 if not node:
1431 if not node:
1431 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1432 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1432 if stat[3]:
1433 if stat[3]:
1433 ui.status(_("nothing changed (%d missing files, see "
1434 ui.status(_("nothing changed (%d missing files, see "
1434 "'hg status')\n") % len(stat[3]))
1435 "'hg status')\n") % len(stat[3]))
1435 else:
1436 else:
1436 ui.status(_("nothing changed\n"))
1437 ui.status(_("nothing changed\n"))
1437 return 1
1438 return 1
1438
1439
1439 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1440 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1440
1441
1441 @command('config|showconfig|debugconfig',
1442 @command('config|showconfig|debugconfig',
1442 [('u', 'untrusted', None, _('show untrusted configuration options')),
1443 [('u', 'untrusted', None, _('show untrusted configuration options')),
1443 ('e', 'edit', None, _('edit user config')),
1444 ('e', 'edit', None, _('edit user config')),
1444 ('l', 'local', None, _('edit repository config')),
1445 ('l', 'local', None, _('edit repository config')),
1445 ('g', 'global', None, _('edit global config'))],
1446 ('g', 'global', None, _('edit global config'))],
1446 _('[-u] [NAME]...'))
1447 _('[-u] [NAME]...'))
1447 def config(ui, repo, *values, **opts):
1448 def config(ui, repo, *values, **opts):
1448 """show combined config settings from all hgrc files
1449 """show combined config settings from all hgrc files
1449
1450
1450 With no arguments, print names and values of all config items.
1451 With no arguments, print names and values of all config items.
1451
1452
1452 With one argument of the form section.name, print just the value
1453 With one argument of the form section.name, print just the value
1453 of that config item.
1454 of that config item.
1454
1455
1455 With multiple arguments, print names and values of all config
1456 With multiple arguments, print names and values of all config
1456 items with matching section names.
1457 items with matching section names.
1457
1458
1458 With --edit, start an editor on the user-level config file. With
1459 With --edit, start an editor on the user-level config file. With
1459 --global, edit the system-wide config file. With --local, edit the
1460 --global, edit the system-wide config file. With --local, edit the
1460 repository-level config file.
1461 repository-level config file.
1461
1462
1462 With --debug, the source (filename and line number) is printed
1463 With --debug, the source (filename and line number) is printed
1463 for each config item.
1464 for each config item.
1464
1465
1465 See :hg:`help config` for more information about config files.
1466 See :hg:`help config` for more information about config files.
1466
1467
1467 Returns 0 on success.
1468 Returns 0 on success.
1468
1469
1469 """
1470 """
1470
1471
1471 if opts.get('edit') or opts.get('local') or opts.get('global'):
1472 if opts.get('edit') or opts.get('local') or opts.get('global'):
1472 if opts.get('local') and opts.get('global'):
1473 if opts.get('local') and opts.get('global'):
1473 raise util.Abort(_("can't use --local and --global together"))
1474 raise util.Abort(_("can't use --local and --global together"))
1474
1475
1475 if opts.get('local'):
1476 if opts.get('local'):
1476 if not repo:
1477 if not repo:
1477 raise util.Abort(_("can't use --local outside a repository"))
1478 raise util.Abort(_("can't use --local outside a repository"))
1478 paths = [repo.join('hgrc')]
1479 paths = [repo.join('hgrc')]
1479 elif opts.get('global'):
1480 elif opts.get('global'):
1480 paths = scmutil.systemrcpath()
1481 paths = scmutil.systemrcpath()
1481 else:
1482 else:
1482 paths = scmutil.userrcpath()
1483 paths = scmutil.userrcpath()
1483
1484
1484 for f in paths:
1485 for f in paths:
1485 if os.path.exists(f):
1486 if os.path.exists(f):
1486 break
1487 break
1487 else:
1488 else:
1488 f = paths[0]
1489 f = paths[0]
1489 fp = open(f, "w")
1490 fp = open(f, "w")
1490 fp.write(
1491 fp.write(
1491 '# example config (see "hg help config" for more info)\n'
1492 '# example config (see "hg help config" for more info)\n'
1492 '\n'
1493 '\n'
1493 '[ui]\n'
1494 '[ui]\n'
1494 '# name and email, e.g.\n'
1495 '# name and email, e.g.\n'
1495 '# username = Jane Doe <jdoe@example.com>\n'
1496 '# username = Jane Doe <jdoe@example.com>\n'
1496 'username =\n'
1497 'username =\n'
1497 '\n'
1498 '\n'
1498 '[extensions]\n'
1499 '[extensions]\n'
1499 '# uncomment these lines to enable some popular extensions\n'
1500 '# uncomment these lines to enable some popular extensions\n'
1500 '# (see "hg help extensions" for more info)\n'
1501 '# (see "hg help extensions" for more info)\n'
1501 '# pager =\n'
1502 '# pager =\n'
1502 '# progress =\n'
1503 '# progress =\n'
1503 '# color =\n')
1504 '# color =\n')
1504 fp.close()
1505 fp.close()
1505
1506
1506 editor = ui.geteditor()
1507 editor = ui.geteditor()
1507 util.system("%s \"%s\"" % (editor, f),
1508 util.system("%s \"%s\"" % (editor, f),
1508 onerr=util.Abort, errprefix=_("edit failed"),
1509 onerr=util.Abort, errprefix=_("edit failed"),
1509 out=ui.fout)
1510 out=ui.fout)
1510 return
1511 return
1511
1512
1512 for f in scmutil.rcpath():
1513 for f in scmutil.rcpath():
1513 ui.debug('read config from: %s\n' % f)
1514 ui.debug('read config from: %s\n' % f)
1514 untrusted = bool(opts.get('untrusted'))
1515 untrusted = bool(opts.get('untrusted'))
1515 if values:
1516 if values:
1516 sections = [v for v in values if '.' not in v]
1517 sections = [v for v in values if '.' not in v]
1517 items = [v for v in values if '.' in v]
1518 items = [v for v in values if '.' in v]
1518 if len(items) > 1 or items and sections:
1519 if len(items) > 1 or items and sections:
1519 raise util.Abort(_('only one config item permitted'))
1520 raise util.Abort(_('only one config item permitted'))
1520 for section, name, value in ui.walkconfig(untrusted=untrusted):
1521 for section, name, value in ui.walkconfig(untrusted=untrusted):
1521 value = str(value).replace('\n', '\\n')
1522 value = str(value).replace('\n', '\\n')
1522 sectname = section + '.' + name
1523 sectname = section + '.' + name
1523 if values:
1524 if values:
1524 for v in values:
1525 for v in values:
1525 if v == section:
1526 if v == section:
1526 ui.debug('%s: ' %
1527 ui.debug('%s: ' %
1527 ui.configsource(section, name, untrusted))
1528 ui.configsource(section, name, untrusted))
1528 ui.write('%s=%s\n' % (sectname, value))
1529 ui.write('%s=%s\n' % (sectname, value))
1529 elif v == sectname:
1530 elif v == sectname:
1530 ui.debug('%s: ' %
1531 ui.debug('%s: ' %
1531 ui.configsource(section, name, untrusted))
1532 ui.configsource(section, name, untrusted))
1532 ui.write(value, '\n')
1533 ui.write(value, '\n')
1533 else:
1534 else:
1534 ui.debug('%s: ' %
1535 ui.debug('%s: ' %
1535 ui.configsource(section, name, untrusted))
1536 ui.configsource(section, name, untrusted))
1536 ui.write('%s=%s\n' % (sectname, value))
1537 ui.write('%s=%s\n' % (sectname, value))
1537
1538
1538 @command('copy|cp',
1539 @command('copy|cp',
1539 [('A', 'after', None, _('record a copy that has already occurred')),
1540 [('A', 'after', None, _('record a copy that has already occurred')),
1540 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1541 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1541 ] + walkopts + dryrunopts,
1542 ] + walkopts + dryrunopts,
1542 _('[OPTION]... [SOURCE]... DEST'))
1543 _('[OPTION]... [SOURCE]... DEST'))
1543 def copy(ui, repo, *pats, **opts):
1544 def copy(ui, repo, *pats, **opts):
1544 """mark files as copied for the next commit
1545 """mark files as copied for the next commit
1545
1546
1546 Mark dest as having copies of source files. If dest is a
1547 Mark dest as having copies of source files. If dest is a
1547 directory, copies are put in that directory. If dest is a file,
1548 directory, copies are put in that directory. If dest is a file,
1548 the source must be a single file.
1549 the source must be a single file.
1549
1550
1550 By default, this command copies the contents of files as they
1551 By default, this command copies the contents of files as they
1551 exist in the working directory. If invoked with -A/--after, the
1552 exist in the working directory. If invoked with -A/--after, the
1552 operation is recorded, but no copying is performed.
1553 operation is recorded, but no copying is performed.
1553
1554
1554 This command takes effect with the next commit. To undo a copy
1555 This command takes effect with the next commit. To undo a copy
1555 before that, see :hg:`revert`.
1556 before that, see :hg:`revert`.
1556
1557
1557 Returns 0 on success, 1 if errors are encountered.
1558 Returns 0 on success, 1 if errors are encountered.
1558 """
1559 """
1559 wlock = repo.wlock(False)
1560 wlock = repo.wlock(False)
1560 try:
1561 try:
1561 return cmdutil.copy(ui, repo, pats, opts)
1562 return cmdutil.copy(ui, repo, pats, opts)
1562 finally:
1563 finally:
1563 wlock.release()
1564 wlock.release()
1564
1565
1565 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1566 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1566 def debugancestor(ui, repo, *args):
1567 def debugancestor(ui, repo, *args):
1567 """find the ancestor revision of two revisions in a given index"""
1568 """find the ancestor revision of two revisions in a given index"""
1568 if len(args) == 3:
1569 if len(args) == 3:
1569 index, rev1, rev2 = args
1570 index, rev1, rev2 = args
1570 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1571 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1571 lookup = r.lookup
1572 lookup = r.lookup
1572 elif len(args) == 2:
1573 elif len(args) == 2:
1573 if not repo:
1574 if not repo:
1574 raise util.Abort(_("there is no Mercurial repository here "
1575 raise util.Abort(_("there is no Mercurial repository here "
1575 "(.hg not found)"))
1576 "(.hg not found)"))
1576 rev1, rev2 = args
1577 rev1, rev2 = args
1577 r = repo.changelog
1578 r = repo.changelog
1578 lookup = repo.lookup
1579 lookup = repo.lookup
1579 else:
1580 else:
1580 raise util.Abort(_('either two or three arguments required'))
1581 raise util.Abort(_('either two or three arguments required'))
1581 a = r.ancestor(lookup(rev1), lookup(rev2))
1582 a = r.ancestor(lookup(rev1), lookup(rev2))
1582 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1583 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1583
1584
1584 @command('debugbuilddag',
1585 @command('debugbuilddag',
1585 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1586 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1586 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1587 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1587 ('n', 'new-file', None, _('add new file at each rev'))],
1588 ('n', 'new-file', None, _('add new file at each rev'))],
1588 _('[OPTION]... [TEXT]'))
1589 _('[OPTION]... [TEXT]'))
1589 def debugbuilddag(ui, repo, text=None,
1590 def debugbuilddag(ui, repo, text=None,
1590 mergeable_file=False,
1591 mergeable_file=False,
1591 overwritten_file=False,
1592 overwritten_file=False,
1592 new_file=False):
1593 new_file=False):
1593 """builds a repo with a given DAG from scratch in the current empty repo
1594 """builds a repo with a given DAG from scratch in the current empty repo
1594
1595
1595 The description of the DAG is read from stdin if not given on the
1596 The description of the DAG is read from stdin if not given on the
1596 command line.
1597 command line.
1597
1598
1598 Elements:
1599 Elements:
1599
1600
1600 - "+n" is a linear run of n nodes based on the current default parent
1601 - "+n" is a linear run of n nodes based on the current default parent
1601 - "." is a single node based on the current default parent
1602 - "." is a single node based on the current default parent
1602 - "$" resets the default parent to null (implied at the start);
1603 - "$" resets the default parent to null (implied at the start);
1603 otherwise the default parent is always the last node created
1604 otherwise the default parent is always the last node created
1604 - "<p" sets the default parent to the backref p
1605 - "<p" sets the default parent to the backref p
1605 - "*p" is a fork at parent p, which is a backref
1606 - "*p" is a fork at parent p, which is a backref
1606 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1607 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1607 - "/p2" is a merge of the preceding node and p2
1608 - "/p2" is a merge of the preceding node and p2
1608 - ":tag" defines a local tag for the preceding node
1609 - ":tag" defines a local tag for the preceding node
1609 - "@branch" sets the named branch for subsequent nodes
1610 - "@branch" sets the named branch for subsequent nodes
1610 - "#...\\n" is a comment up to the end of the line
1611 - "#...\\n" is a comment up to the end of the line
1611
1612
1612 Whitespace between the above elements is ignored.
1613 Whitespace between the above elements is ignored.
1613
1614
1614 A backref is either
1615 A backref is either
1615
1616
1616 - a number n, which references the node curr-n, where curr is the current
1617 - a number n, which references the node curr-n, where curr is the current
1617 node, or
1618 node, or
1618 - the name of a local tag you placed earlier using ":tag", or
1619 - the name of a local tag you placed earlier using ":tag", or
1619 - empty to denote the default parent.
1620 - empty to denote the default parent.
1620
1621
1621 All string valued-elements are either strictly alphanumeric, or must
1622 All string valued-elements are either strictly alphanumeric, or must
1622 be enclosed in double quotes ("..."), with "\\" as escape character.
1623 be enclosed in double quotes ("..."), with "\\" as escape character.
1623 """
1624 """
1624
1625
1625 if text is None:
1626 if text is None:
1626 ui.status(_("reading DAG from stdin\n"))
1627 ui.status(_("reading DAG from stdin\n"))
1627 text = ui.fin.read()
1628 text = ui.fin.read()
1628
1629
1629 cl = repo.changelog
1630 cl = repo.changelog
1630 if len(cl) > 0:
1631 if len(cl) > 0:
1631 raise util.Abort(_('repository is not empty'))
1632 raise util.Abort(_('repository is not empty'))
1632
1633
1633 # determine number of revs in DAG
1634 # determine number of revs in DAG
1634 total = 0
1635 total = 0
1635 for type, data in dagparser.parsedag(text):
1636 for type, data in dagparser.parsedag(text):
1636 if type == 'n':
1637 if type == 'n':
1637 total += 1
1638 total += 1
1638
1639
1639 if mergeable_file:
1640 if mergeable_file:
1640 linesperrev = 2
1641 linesperrev = 2
1641 # make a file with k lines per rev
1642 # make a file with k lines per rev
1642 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1643 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1643 initialmergedlines.append("")
1644 initialmergedlines.append("")
1644
1645
1645 tags = []
1646 tags = []
1646
1647
1647 lock = tr = None
1648 lock = tr = None
1648 try:
1649 try:
1649 lock = repo.lock()
1650 lock = repo.lock()
1650 tr = repo.transaction("builddag")
1651 tr = repo.transaction("builddag")
1651
1652
1652 at = -1
1653 at = -1
1653 atbranch = 'default'
1654 atbranch = 'default'
1654 nodeids = []
1655 nodeids = []
1655 id = 0
1656 id = 0
1656 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1657 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1657 for type, data in dagparser.parsedag(text):
1658 for type, data in dagparser.parsedag(text):
1658 if type == 'n':
1659 if type == 'n':
1659 ui.note(('node %s\n' % str(data)))
1660 ui.note(('node %s\n' % str(data)))
1660 id, ps = data
1661 id, ps = data
1661
1662
1662 files = []
1663 files = []
1663 fctxs = {}
1664 fctxs = {}
1664
1665
1665 p2 = None
1666 p2 = None
1666 if mergeable_file:
1667 if mergeable_file:
1667 fn = "mf"
1668 fn = "mf"
1668 p1 = repo[ps[0]]
1669 p1 = repo[ps[0]]
1669 if len(ps) > 1:
1670 if len(ps) > 1:
1670 p2 = repo[ps[1]]
1671 p2 = repo[ps[1]]
1671 pa = p1.ancestor(p2)
1672 pa = p1.ancestor(p2)
1672 base, local, other = [x[fn].data() for x in (pa, p1,
1673 base, local, other = [x[fn].data() for x in (pa, p1,
1673 p2)]
1674 p2)]
1674 m3 = simplemerge.Merge3Text(base, local, other)
1675 m3 = simplemerge.Merge3Text(base, local, other)
1675 ml = [l.strip() for l in m3.merge_lines()]
1676 ml = [l.strip() for l in m3.merge_lines()]
1676 ml.append("")
1677 ml.append("")
1677 elif at > 0:
1678 elif at > 0:
1678 ml = p1[fn].data().split("\n")
1679 ml = p1[fn].data().split("\n")
1679 else:
1680 else:
1680 ml = initialmergedlines
1681 ml = initialmergedlines
1681 ml[id * linesperrev] += " r%i" % id
1682 ml[id * linesperrev] += " r%i" % id
1682 mergedtext = "\n".join(ml)
1683 mergedtext = "\n".join(ml)
1683 files.append(fn)
1684 files.append(fn)
1684 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1685 fctxs[fn] = context.memfilectx(repo, fn, mergedtext)
1685
1686
1686 if overwritten_file:
1687 if overwritten_file:
1687 fn = "of"
1688 fn = "of"
1688 files.append(fn)
1689 files.append(fn)
1689 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1690 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1690
1691
1691 if new_file:
1692 if new_file:
1692 fn = "nf%i" % id
1693 fn = "nf%i" % id
1693 files.append(fn)
1694 files.append(fn)
1694 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1695 fctxs[fn] = context.memfilectx(repo, fn, "r%i\n" % id)
1695 if len(ps) > 1:
1696 if len(ps) > 1:
1696 if not p2:
1697 if not p2:
1697 p2 = repo[ps[1]]
1698 p2 = repo[ps[1]]
1698 for fn in p2:
1699 for fn in p2:
1699 if fn.startswith("nf"):
1700 if fn.startswith("nf"):
1700 files.append(fn)
1701 files.append(fn)
1701 fctxs[fn] = p2[fn]
1702 fctxs[fn] = p2[fn]
1702
1703
1703 def fctxfn(repo, cx, path):
1704 def fctxfn(repo, cx, path):
1704 return fctxs.get(path)
1705 return fctxs.get(path)
1705
1706
1706 if len(ps) == 0 or ps[0] < 0:
1707 if len(ps) == 0 or ps[0] < 0:
1707 pars = [None, None]
1708 pars = [None, None]
1708 elif len(ps) == 1:
1709 elif len(ps) == 1:
1709 pars = [nodeids[ps[0]], None]
1710 pars = [nodeids[ps[0]], None]
1710 else:
1711 else:
1711 pars = [nodeids[p] for p in ps]
1712 pars = [nodeids[p] for p in ps]
1712 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1713 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1713 date=(id, 0),
1714 date=(id, 0),
1714 user="debugbuilddag",
1715 user="debugbuilddag",
1715 extra={'branch': atbranch})
1716 extra={'branch': atbranch})
1716 nodeid = repo.commitctx(cx)
1717 nodeid = repo.commitctx(cx)
1717 nodeids.append(nodeid)
1718 nodeids.append(nodeid)
1718 at = id
1719 at = id
1719 elif type == 'l':
1720 elif type == 'l':
1720 id, name = data
1721 id, name = data
1721 ui.note(('tag %s\n' % name))
1722 ui.note(('tag %s\n' % name))
1722 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1723 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1723 elif type == 'a':
1724 elif type == 'a':
1724 ui.note(('branch %s\n' % data))
1725 ui.note(('branch %s\n' % data))
1725 atbranch = data
1726 atbranch = data
1726 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1727 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1727 tr.close()
1728 tr.close()
1728
1729
1729 if tags:
1730 if tags:
1730 repo.opener.write("localtags", "".join(tags))
1731 repo.opener.write("localtags", "".join(tags))
1731 finally:
1732 finally:
1732 ui.progress(_('building'), None)
1733 ui.progress(_('building'), None)
1733 release(tr, lock)
1734 release(tr, lock)
1734
1735
1735 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1736 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1736 def debugbundle(ui, bundlepath, all=None, **opts):
1737 def debugbundle(ui, bundlepath, all=None, **opts):
1737 """lists the contents of a bundle"""
1738 """lists the contents of a bundle"""
1738 f = hg.openpath(ui, bundlepath)
1739 f = hg.openpath(ui, bundlepath)
1739 try:
1740 try:
1740 gen = exchange.readbundle(ui, f, bundlepath)
1741 gen = exchange.readbundle(ui, f, bundlepath)
1741 if all:
1742 if all:
1742 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1743 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1743
1744
1744 def showchunks(named):
1745 def showchunks(named):
1745 ui.write("\n%s\n" % named)
1746 ui.write("\n%s\n" % named)
1746 chain = None
1747 chain = None
1747 while True:
1748 while True:
1748 chunkdata = gen.deltachunk(chain)
1749 chunkdata = gen.deltachunk(chain)
1749 if not chunkdata:
1750 if not chunkdata:
1750 break
1751 break
1751 node = chunkdata['node']
1752 node = chunkdata['node']
1752 p1 = chunkdata['p1']
1753 p1 = chunkdata['p1']
1753 p2 = chunkdata['p2']
1754 p2 = chunkdata['p2']
1754 cs = chunkdata['cs']
1755 cs = chunkdata['cs']
1755 deltabase = chunkdata['deltabase']
1756 deltabase = chunkdata['deltabase']
1756 delta = chunkdata['delta']
1757 delta = chunkdata['delta']
1757 ui.write("%s %s %s %s %s %s\n" %
1758 ui.write("%s %s %s %s %s %s\n" %
1758 (hex(node), hex(p1), hex(p2),
1759 (hex(node), hex(p1), hex(p2),
1759 hex(cs), hex(deltabase), len(delta)))
1760 hex(cs), hex(deltabase), len(delta)))
1760 chain = node
1761 chain = node
1761
1762
1762 chunkdata = gen.changelogheader()
1763 chunkdata = gen.changelogheader()
1763 showchunks("changelog")
1764 showchunks("changelog")
1764 chunkdata = gen.manifestheader()
1765 chunkdata = gen.manifestheader()
1765 showchunks("manifest")
1766 showchunks("manifest")
1766 while True:
1767 while True:
1767 chunkdata = gen.filelogheader()
1768 chunkdata = gen.filelogheader()
1768 if not chunkdata:
1769 if not chunkdata:
1769 break
1770 break
1770 fname = chunkdata['filename']
1771 fname = chunkdata['filename']
1771 showchunks(fname)
1772 showchunks(fname)
1772 else:
1773 else:
1773 chunkdata = gen.changelogheader()
1774 chunkdata = gen.changelogheader()
1774 chain = None
1775 chain = None
1775 while True:
1776 while True:
1776 chunkdata = gen.deltachunk(chain)
1777 chunkdata = gen.deltachunk(chain)
1777 if not chunkdata:
1778 if not chunkdata:
1778 break
1779 break
1779 node = chunkdata['node']
1780 node = chunkdata['node']
1780 ui.write("%s\n" % hex(node))
1781 ui.write("%s\n" % hex(node))
1781 chain = node
1782 chain = node
1782 finally:
1783 finally:
1783 f.close()
1784 f.close()
1784
1785
1785 @command('debugcheckstate', [], '')
1786 @command('debugcheckstate', [], '')
1786 def debugcheckstate(ui, repo):
1787 def debugcheckstate(ui, repo):
1787 """validate the correctness of the current dirstate"""
1788 """validate the correctness of the current dirstate"""
1788 parent1, parent2 = repo.dirstate.parents()
1789 parent1, parent2 = repo.dirstate.parents()
1789 m1 = repo[parent1].manifest()
1790 m1 = repo[parent1].manifest()
1790 m2 = repo[parent2].manifest()
1791 m2 = repo[parent2].manifest()
1791 errors = 0
1792 errors = 0
1792 for f in repo.dirstate:
1793 for f in repo.dirstate:
1793 state = repo.dirstate[f]
1794 state = repo.dirstate[f]
1794 if state in "nr" and f not in m1:
1795 if state in "nr" and f not in m1:
1795 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1796 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1796 errors += 1
1797 errors += 1
1797 if state in "a" and f in m1:
1798 if state in "a" and f in m1:
1798 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1799 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1799 errors += 1
1800 errors += 1
1800 if state in "m" and f not in m1 and f not in m2:
1801 if state in "m" and f not in m1 and f not in m2:
1801 ui.warn(_("%s in state %s, but not in either manifest\n") %
1802 ui.warn(_("%s in state %s, but not in either manifest\n") %
1802 (f, state))
1803 (f, state))
1803 errors += 1
1804 errors += 1
1804 for f in m1:
1805 for f in m1:
1805 state = repo.dirstate[f]
1806 state = repo.dirstate[f]
1806 if state not in "nrm":
1807 if state not in "nrm":
1807 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1808 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1808 errors += 1
1809 errors += 1
1809 if errors:
1810 if errors:
1810 error = _(".hg/dirstate inconsistent with current parent's manifest")
1811 error = _(".hg/dirstate inconsistent with current parent's manifest")
1811 raise util.Abort(error)
1812 raise util.Abort(error)
1812
1813
1813 @command('debugcommands', [], _('[COMMAND]'))
1814 @command('debugcommands', [], _('[COMMAND]'))
1814 def debugcommands(ui, cmd='', *args):
1815 def debugcommands(ui, cmd='', *args):
1815 """list all available commands and options"""
1816 """list all available commands and options"""
1816 for cmd, vals in sorted(table.iteritems()):
1817 for cmd, vals in sorted(table.iteritems()):
1817 cmd = cmd.split('|')[0].strip('^')
1818 cmd = cmd.split('|')[0].strip('^')
1818 opts = ', '.join([i[1] for i in vals[1]])
1819 opts = ', '.join([i[1] for i in vals[1]])
1819 ui.write('%s: %s\n' % (cmd, opts))
1820 ui.write('%s: %s\n' % (cmd, opts))
1820
1821
1821 @command('debugcomplete',
1822 @command('debugcomplete',
1822 [('o', 'options', None, _('show the command options'))],
1823 [('o', 'options', None, _('show the command options'))],
1823 _('[-o] CMD'))
1824 _('[-o] CMD'))
1824 def debugcomplete(ui, cmd='', **opts):
1825 def debugcomplete(ui, cmd='', **opts):
1825 """returns the completion list associated with the given command"""
1826 """returns the completion list associated with the given command"""
1826
1827
1827 if opts.get('options'):
1828 if opts.get('options'):
1828 options = []
1829 options = []
1829 otables = [globalopts]
1830 otables = [globalopts]
1830 if cmd:
1831 if cmd:
1831 aliases, entry = cmdutil.findcmd(cmd, table, False)
1832 aliases, entry = cmdutil.findcmd(cmd, table, False)
1832 otables.append(entry[1])
1833 otables.append(entry[1])
1833 for t in otables:
1834 for t in otables:
1834 for o in t:
1835 for o in t:
1835 if "(DEPRECATED)" in o[3]:
1836 if "(DEPRECATED)" in o[3]:
1836 continue
1837 continue
1837 if o[0]:
1838 if o[0]:
1838 options.append('-%s' % o[0])
1839 options.append('-%s' % o[0])
1839 options.append('--%s' % o[1])
1840 options.append('--%s' % o[1])
1840 ui.write("%s\n" % "\n".join(options))
1841 ui.write("%s\n" % "\n".join(options))
1841 return
1842 return
1842
1843
1843 cmdlist = cmdutil.findpossible(cmd, table)
1844 cmdlist = cmdutil.findpossible(cmd, table)
1844 if ui.verbose:
1845 if ui.verbose:
1845 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1846 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1846 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1847 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1847
1848
1848 @command('debugdag',
1849 @command('debugdag',
1849 [('t', 'tags', None, _('use tags as labels')),
1850 [('t', 'tags', None, _('use tags as labels')),
1850 ('b', 'branches', None, _('annotate with branch names')),
1851 ('b', 'branches', None, _('annotate with branch names')),
1851 ('', 'dots', None, _('use dots for runs')),
1852 ('', 'dots', None, _('use dots for runs')),
1852 ('s', 'spaces', None, _('separate elements by spaces'))],
1853 ('s', 'spaces', None, _('separate elements by spaces'))],
1853 _('[OPTION]... [FILE [REV]...]'))
1854 _('[OPTION]... [FILE [REV]...]'))
1854 def debugdag(ui, repo, file_=None, *revs, **opts):
1855 def debugdag(ui, repo, file_=None, *revs, **opts):
1855 """format the changelog or an index DAG as a concise textual description
1856 """format the changelog or an index DAG as a concise textual description
1856
1857
1857 If you pass a revlog index, the revlog's DAG is emitted. If you list
1858 If you pass a revlog index, the revlog's DAG is emitted. If you list
1858 revision numbers, they get labeled in the output as rN.
1859 revision numbers, they get labeled in the output as rN.
1859
1860
1860 Otherwise, the changelog DAG of the current repo is emitted.
1861 Otherwise, the changelog DAG of the current repo is emitted.
1861 """
1862 """
1862 spaces = opts.get('spaces')
1863 spaces = opts.get('spaces')
1863 dots = opts.get('dots')
1864 dots = opts.get('dots')
1864 if file_:
1865 if file_:
1865 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1866 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1866 revs = set((int(r) for r in revs))
1867 revs = set((int(r) for r in revs))
1867 def events():
1868 def events():
1868 for r in rlog:
1869 for r in rlog:
1869 yield 'n', (r, list(set(p for p in rlog.parentrevs(r)
1870 yield 'n', (r, list(set(p for p in rlog.parentrevs(r)
1870 if p != -1)))
1871 if p != -1)))
1871 if r in revs:
1872 if r in revs:
1872 yield 'l', (r, "r%i" % r)
1873 yield 'l', (r, "r%i" % r)
1873 elif repo:
1874 elif repo:
1874 cl = repo.changelog
1875 cl = repo.changelog
1875 tags = opts.get('tags')
1876 tags = opts.get('tags')
1876 branches = opts.get('branches')
1877 branches = opts.get('branches')
1877 if tags:
1878 if tags:
1878 labels = {}
1879 labels = {}
1879 for l, n in repo.tags().items():
1880 for l, n in repo.tags().items():
1880 labels.setdefault(cl.rev(n), []).append(l)
1881 labels.setdefault(cl.rev(n), []).append(l)
1881 def events():
1882 def events():
1882 b = "default"
1883 b = "default"
1883 for r in cl:
1884 for r in cl:
1884 if branches:
1885 if branches:
1885 newb = cl.read(cl.node(r))[5]['branch']
1886 newb = cl.read(cl.node(r))[5]['branch']
1886 if newb != b:
1887 if newb != b:
1887 yield 'a', newb
1888 yield 'a', newb
1888 b = newb
1889 b = newb
1889 yield 'n', (r, list(set(p for p in cl.parentrevs(r)
1890 yield 'n', (r, list(set(p for p in cl.parentrevs(r)
1890 if p != -1)))
1891 if p != -1)))
1891 if tags:
1892 if tags:
1892 ls = labels.get(r)
1893 ls = labels.get(r)
1893 if ls:
1894 if ls:
1894 for l in ls:
1895 for l in ls:
1895 yield 'l', (r, l)
1896 yield 'l', (r, l)
1896 else:
1897 else:
1897 raise util.Abort(_('need repo for changelog dag'))
1898 raise util.Abort(_('need repo for changelog dag'))
1898
1899
1899 for line in dagparser.dagtextlines(events(),
1900 for line in dagparser.dagtextlines(events(),
1900 addspaces=spaces,
1901 addspaces=spaces,
1901 wraplabels=True,
1902 wraplabels=True,
1902 wrapannotations=True,
1903 wrapannotations=True,
1903 wrapnonlinear=dots,
1904 wrapnonlinear=dots,
1904 usedots=dots,
1905 usedots=dots,
1905 maxlinewidth=70):
1906 maxlinewidth=70):
1906 ui.write(line)
1907 ui.write(line)
1907 ui.write("\n")
1908 ui.write("\n")
1908
1909
1909 @command('debugdata',
1910 @command('debugdata',
1910 [('c', 'changelog', False, _('open changelog')),
1911 [('c', 'changelog', False, _('open changelog')),
1911 ('m', 'manifest', False, _('open manifest'))],
1912 ('m', 'manifest', False, _('open manifest'))],
1912 _('-c|-m|FILE REV'))
1913 _('-c|-m|FILE REV'))
1913 def debugdata(ui, repo, file_, rev=None, **opts):
1914 def debugdata(ui, repo, file_, rev=None, **opts):
1914 """dump the contents of a data file revision"""
1915 """dump the contents of a data file revision"""
1915 if opts.get('changelog') or opts.get('manifest'):
1916 if opts.get('changelog') or opts.get('manifest'):
1916 file_, rev = None, file_
1917 file_, rev = None, file_
1917 elif rev is None:
1918 elif rev is None:
1918 raise error.CommandError('debugdata', _('invalid arguments'))
1919 raise error.CommandError('debugdata', _('invalid arguments'))
1919 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1920 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1920 try:
1921 try:
1921 ui.write(r.revision(r.lookup(rev)))
1922 ui.write(r.revision(r.lookup(rev)))
1922 except KeyError:
1923 except KeyError:
1923 raise util.Abort(_('invalid revision identifier %s') % rev)
1924 raise util.Abort(_('invalid revision identifier %s') % rev)
1924
1925
1925 @command('debugdate',
1926 @command('debugdate',
1926 [('e', 'extended', None, _('try extended date formats'))],
1927 [('e', 'extended', None, _('try extended date formats'))],
1927 _('[-e] DATE [RANGE]'))
1928 _('[-e] DATE [RANGE]'))
1928 def debugdate(ui, date, range=None, **opts):
1929 def debugdate(ui, date, range=None, **opts):
1929 """parse and display a date"""
1930 """parse and display a date"""
1930 if opts["extended"]:
1931 if opts["extended"]:
1931 d = util.parsedate(date, util.extendeddateformats)
1932 d = util.parsedate(date, util.extendeddateformats)
1932 else:
1933 else:
1933 d = util.parsedate(date)
1934 d = util.parsedate(date)
1934 ui.write(("internal: %s %s\n") % d)
1935 ui.write(("internal: %s %s\n") % d)
1935 ui.write(("standard: %s\n") % util.datestr(d))
1936 ui.write(("standard: %s\n") % util.datestr(d))
1936 if range:
1937 if range:
1937 m = util.matchdate(range)
1938 m = util.matchdate(range)
1938 ui.write(("match: %s\n") % m(d[0]))
1939 ui.write(("match: %s\n") % m(d[0]))
1939
1940
1940 @command('debugdiscovery',
1941 @command('debugdiscovery',
1941 [('', 'old', None, _('use old-style discovery')),
1942 [('', 'old', None, _('use old-style discovery')),
1942 ('', 'nonheads', None,
1943 ('', 'nonheads', None,
1943 _('use old-style discovery with non-heads included')),
1944 _('use old-style discovery with non-heads included')),
1944 ] + remoteopts,
1945 ] + remoteopts,
1945 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1946 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1946 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1947 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1947 """runs the changeset discovery protocol in isolation"""
1948 """runs the changeset discovery protocol in isolation"""
1948 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
1949 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
1949 opts.get('branch'))
1950 opts.get('branch'))
1950 remote = hg.peer(repo, opts, remoteurl)
1951 remote = hg.peer(repo, opts, remoteurl)
1951 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1952 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1952
1953
1953 # make sure tests are repeatable
1954 # make sure tests are repeatable
1954 random.seed(12323)
1955 random.seed(12323)
1955
1956
1956 def doit(localheads, remoteheads, remote=remote):
1957 def doit(localheads, remoteheads, remote=remote):
1957 if opts.get('old'):
1958 if opts.get('old'):
1958 if localheads:
1959 if localheads:
1959 raise util.Abort('cannot use localheads with old style '
1960 raise util.Abort('cannot use localheads with old style '
1960 'discovery')
1961 'discovery')
1961 if not util.safehasattr(remote, 'branches'):
1962 if not util.safehasattr(remote, 'branches'):
1962 # enable in-client legacy support
1963 # enable in-client legacy support
1963 remote = localrepo.locallegacypeer(remote.local())
1964 remote = localrepo.locallegacypeer(remote.local())
1964 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1965 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1965 force=True)
1966 force=True)
1966 common = set(common)
1967 common = set(common)
1967 if not opts.get('nonheads'):
1968 if not opts.get('nonheads'):
1968 ui.write(("unpruned common: %s\n") %
1969 ui.write(("unpruned common: %s\n") %
1969 " ".join(sorted(short(n) for n in common)))
1970 " ".join(sorted(short(n) for n in common)))
1970 dag = dagutil.revlogdag(repo.changelog)
1971 dag = dagutil.revlogdag(repo.changelog)
1971 all = dag.ancestorset(dag.internalizeall(common))
1972 all = dag.ancestorset(dag.internalizeall(common))
1972 common = dag.externalizeall(dag.headsetofconnecteds(all))
1973 common = dag.externalizeall(dag.headsetofconnecteds(all))
1973 else:
1974 else:
1974 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1975 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1975 common = set(common)
1976 common = set(common)
1976 rheads = set(hds)
1977 rheads = set(hds)
1977 lheads = set(repo.heads())
1978 lheads = set(repo.heads())
1978 ui.write(("common heads: %s\n") %
1979 ui.write(("common heads: %s\n") %
1979 " ".join(sorted(short(n) for n in common)))
1980 " ".join(sorted(short(n) for n in common)))
1980 if lheads <= common:
1981 if lheads <= common:
1981 ui.write(("local is subset\n"))
1982 ui.write(("local is subset\n"))
1982 elif rheads <= common:
1983 elif rheads <= common:
1983 ui.write(("remote is subset\n"))
1984 ui.write(("remote is subset\n"))
1984
1985
1985 serverlogs = opts.get('serverlog')
1986 serverlogs = opts.get('serverlog')
1986 if serverlogs:
1987 if serverlogs:
1987 for filename in serverlogs:
1988 for filename in serverlogs:
1988 logfile = open(filename, 'r')
1989 logfile = open(filename, 'r')
1989 try:
1990 try:
1990 line = logfile.readline()
1991 line = logfile.readline()
1991 while line:
1992 while line:
1992 parts = line.strip().split(';')
1993 parts = line.strip().split(';')
1993 op = parts[1]
1994 op = parts[1]
1994 if op == 'cg':
1995 if op == 'cg':
1995 pass
1996 pass
1996 elif op == 'cgss':
1997 elif op == 'cgss':
1997 doit(parts[2].split(' '), parts[3].split(' '))
1998 doit(parts[2].split(' '), parts[3].split(' '))
1998 elif op == 'unb':
1999 elif op == 'unb':
1999 doit(parts[3].split(' '), parts[2].split(' '))
2000 doit(parts[3].split(' '), parts[2].split(' '))
2000 line = logfile.readline()
2001 line = logfile.readline()
2001 finally:
2002 finally:
2002 logfile.close()
2003 logfile.close()
2003
2004
2004 else:
2005 else:
2005 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2006 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2006 opts.get('remote_head'))
2007 opts.get('remote_head'))
2007 localrevs = opts.get('local_head')
2008 localrevs = opts.get('local_head')
2008 doit(localrevs, remoterevs)
2009 doit(localrevs, remoterevs)
2009
2010
2010 @command('debugfileset',
2011 @command('debugfileset',
2011 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2012 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2012 _('[-r REV] FILESPEC'))
2013 _('[-r REV] FILESPEC'))
2013 def debugfileset(ui, repo, expr, **opts):
2014 def debugfileset(ui, repo, expr, **opts):
2014 '''parse and apply a fileset specification'''
2015 '''parse and apply a fileset specification'''
2015 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2016 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2016 if ui.verbose:
2017 if ui.verbose:
2017 tree = fileset.parse(expr)[0]
2018 tree = fileset.parse(expr)[0]
2018 ui.note(tree, "\n")
2019 ui.note(tree, "\n")
2019
2020
2020 for f in ctx.getfileset(expr):
2021 for f in ctx.getfileset(expr):
2021 ui.write("%s\n" % f)
2022 ui.write("%s\n" % f)
2022
2023
2023 @command('debugfsinfo', [], _('[PATH]'))
2024 @command('debugfsinfo', [], _('[PATH]'))
2024 def debugfsinfo(ui, path="."):
2025 def debugfsinfo(ui, path="."):
2025 """show information detected about current filesystem"""
2026 """show information detected about current filesystem"""
2026 util.writefile('.debugfsinfo', '')
2027 util.writefile('.debugfsinfo', '')
2027 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2028 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2028 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2029 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2029 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2030 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2030 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2031 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2031 and 'yes' or 'no'))
2032 and 'yes' or 'no'))
2032 os.unlink('.debugfsinfo')
2033 os.unlink('.debugfsinfo')
2033
2034
2034 @command('debuggetbundle',
2035 @command('debuggetbundle',
2035 [('H', 'head', [], _('id of head node'), _('ID')),
2036 [('H', 'head', [], _('id of head node'), _('ID')),
2036 ('C', 'common', [], _('id of common node'), _('ID')),
2037 ('C', 'common', [], _('id of common node'), _('ID')),
2037 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2038 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2038 _('REPO FILE [-H|-C ID]...'))
2039 _('REPO FILE [-H|-C ID]...'))
2039 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2040 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2040 """retrieves a bundle from a repo
2041 """retrieves a bundle from a repo
2041
2042
2042 Every ID must be a full-length hex node id string. Saves the bundle to the
2043 Every ID must be a full-length hex node id string. Saves the bundle to the
2043 given file.
2044 given file.
2044 """
2045 """
2045 repo = hg.peer(ui, opts, repopath)
2046 repo = hg.peer(ui, opts, repopath)
2046 if not repo.capable('getbundle'):
2047 if not repo.capable('getbundle'):
2047 raise util.Abort("getbundle() not supported by target repository")
2048 raise util.Abort("getbundle() not supported by target repository")
2048 args = {}
2049 args = {}
2049 if common:
2050 if common:
2050 args['common'] = [bin(s) for s in common]
2051 args['common'] = [bin(s) for s in common]
2051 if head:
2052 if head:
2052 args['heads'] = [bin(s) for s in head]
2053 args['heads'] = [bin(s) for s in head]
2053 # TODO: get desired bundlecaps from command line.
2054 # TODO: get desired bundlecaps from command line.
2054 args['bundlecaps'] = None
2055 args['bundlecaps'] = None
2055 bundle = repo.getbundle('debug', **args)
2056 bundle = repo.getbundle('debug', **args)
2056
2057
2057 bundletype = opts.get('type', 'bzip2').lower()
2058 bundletype = opts.get('type', 'bzip2').lower()
2058 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
2059 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
2059 bundletype = btypes.get(bundletype)
2060 bundletype = btypes.get(bundletype)
2060 if bundletype not in changegroup.bundletypes:
2061 if bundletype not in changegroup.bundletypes:
2061 raise util.Abort(_('unknown bundle type specified with --type'))
2062 raise util.Abort(_('unknown bundle type specified with --type'))
2062 changegroup.writebundle(bundle, bundlepath, bundletype)
2063 changegroup.writebundle(bundle, bundlepath, bundletype)
2063
2064
2064 @command('debugignore', [], '')
2065 @command('debugignore', [], '')
2065 def debugignore(ui, repo, *values, **opts):
2066 def debugignore(ui, repo, *values, **opts):
2066 """display the combined ignore pattern"""
2067 """display the combined ignore pattern"""
2067 ignore = repo.dirstate._ignore
2068 ignore = repo.dirstate._ignore
2068 includepat = getattr(ignore, 'includepat', None)
2069 includepat = getattr(ignore, 'includepat', None)
2069 if includepat is not None:
2070 if includepat is not None:
2070 ui.write("%s\n" % includepat)
2071 ui.write("%s\n" % includepat)
2071 else:
2072 else:
2072 raise util.Abort(_("no ignore patterns found"))
2073 raise util.Abort(_("no ignore patterns found"))
2073
2074
2074 @command('debugindex',
2075 @command('debugindex',
2075 [('c', 'changelog', False, _('open changelog')),
2076 [('c', 'changelog', False, _('open changelog')),
2076 ('m', 'manifest', False, _('open manifest')),
2077 ('m', 'manifest', False, _('open manifest')),
2077 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2078 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2078 _('[-f FORMAT] -c|-m|FILE'))
2079 _('[-f FORMAT] -c|-m|FILE'))
2079 def debugindex(ui, repo, file_=None, **opts):
2080 def debugindex(ui, repo, file_=None, **opts):
2080 """dump the contents of an index file"""
2081 """dump the contents of an index file"""
2081 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2082 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2082 format = opts.get('format', 0)
2083 format = opts.get('format', 0)
2083 if format not in (0, 1):
2084 if format not in (0, 1):
2084 raise util.Abort(_("unknown format %d") % format)
2085 raise util.Abort(_("unknown format %d") % format)
2085
2086
2086 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2087 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2087 if generaldelta:
2088 if generaldelta:
2088 basehdr = ' delta'
2089 basehdr = ' delta'
2089 else:
2090 else:
2090 basehdr = ' base'
2091 basehdr = ' base'
2091
2092
2092 if format == 0:
2093 if format == 0:
2093 ui.write(" rev offset length " + basehdr + " linkrev"
2094 ui.write(" rev offset length " + basehdr + " linkrev"
2094 " nodeid p1 p2\n")
2095 " nodeid p1 p2\n")
2095 elif format == 1:
2096 elif format == 1:
2096 ui.write(" rev flag offset length"
2097 ui.write(" rev flag offset length"
2097 " size " + basehdr + " link p1 p2"
2098 " size " + basehdr + " link p1 p2"
2098 " nodeid\n")
2099 " nodeid\n")
2099
2100
2100 for i in r:
2101 for i in r:
2101 node = r.node(i)
2102 node = r.node(i)
2102 if generaldelta:
2103 if generaldelta:
2103 base = r.deltaparent(i)
2104 base = r.deltaparent(i)
2104 else:
2105 else:
2105 base = r.chainbase(i)
2106 base = r.chainbase(i)
2106 if format == 0:
2107 if format == 0:
2107 try:
2108 try:
2108 pp = r.parents(node)
2109 pp = r.parents(node)
2109 except Exception:
2110 except Exception:
2110 pp = [nullid, nullid]
2111 pp = [nullid, nullid]
2111 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2112 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2112 i, r.start(i), r.length(i), base, r.linkrev(i),
2113 i, r.start(i), r.length(i), base, r.linkrev(i),
2113 short(node), short(pp[0]), short(pp[1])))
2114 short(node), short(pp[0]), short(pp[1])))
2114 elif format == 1:
2115 elif format == 1:
2115 pr = r.parentrevs(i)
2116 pr = r.parentrevs(i)
2116 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2117 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2117 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2118 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2118 base, r.linkrev(i), pr[0], pr[1], short(node)))
2119 base, r.linkrev(i), pr[0], pr[1], short(node)))
2119
2120
2120 @command('debugindexdot', [], _('FILE'))
2121 @command('debugindexdot', [], _('FILE'))
2121 def debugindexdot(ui, repo, file_):
2122 def debugindexdot(ui, repo, file_):
2122 """dump an index DAG as a graphviz dot file"""
2123 """dump an index DAG as a graphviz dot file"""
2123 r = None
2124 r = None
2124 if repo:
2125 if repo:
2125 filelog = repo.file(file_)
2126 filelog = repo.file(file_)
2126 if len(filelog):
2127 if len(filelog):
2127 r = filelog
2128 r = filelog
2128 if not r:
2129 if not r:
2129 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2130 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2130 ui.write(("digraph G {\n"))
2131 ui.write(("digraph G {\n"))
2131 for i in r:
2132 for i in r:
2132 node = r.node(i)
2133 node = r.node(i)
2133 pp = r.parents(node)
2134 pp = r.parents(node)
2134 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2135 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2135 if pp[1] != nullid:
2136 if pp[1] != nullid:
2136 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2137 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2137 ui.write("}\n")
2138 ui.write("}\n")
2138
2139
2139 @command('debuginstall', [], '')
2140 @command('debuginstall', [], '')
2140 def debuginstall(ui):
2141 def debuginstall(ui):
2141 '''test Mercurial installation
2142 '''test Mercurial installation
2142
2143
2143 Returns 0 on success.
2144 Returns 0 on success.
2144 '''
2145 '''
2145
2146
2146 def writetemp(contents):
2147 def writetemp(contents):
2147 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2148 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2148 f = os.fdopen(fd, "wb")
2149 f = os.fdopen(fd, "wb")
2149 f.write(contents)
2150 f.write(contents)
2150 f.close()
2151 f.close()
2151 return name
2152 return name
2152
2153
2153 problems = 0
2154 problems = 0
2154
2155
2155 # encoding
2156 # encoding
2156 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2157 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2157 try:
2158 try:
2158 encoding.fromlocal("test")
2159 encoding.fromlocal("test")
2159 except util.Abort, inst:
2160 except util.Abort, inst:
2160 ui.write(" %s\n" % inst)
2161 ui.write(" %s\n" % inst)
2161 ui.write(_(" (check that your locale is properly set)\n"))
2162 ui.write(_(" (check that your locale is properly set)\n"))
2162 problems += 1
2163 problems += 1
2163
2164
2164 # Python
2165 # Python
2165 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2166 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2166 ui.status(_("checking Python version (%s)\n")
2167 ui.status(_("checking Python version (%s)\n")
2167 % ("%s.%s.%s" % sys.version_info[:3]))
2168 % ("%s.%s.%s" % sys.version_info[:3]))
2168 ui.status(_("checking Python lib (%s)...\n")
2169 ui.status(_("checking Python lib (%s)...\n")
2169 % os.path.dirname(os.__file__))
2170 % os.path.dirname(os.__file__))
2170
2171
2171 # compiled modules
2172 # compiled modules
2172 ui.status(_("checking installed modules (%s)...\n")
2173 ui.status(_("checking installed modules (%s)...\n")
2173 % os.path.dirname(__file__))
2174 % os.path.dirname(__file__))
2174 try:
2175 try:
2175 import bdiff, mpatch, base85, osutil
2176 import bdiff, mpatch, base85, osutil
2176 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2177 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2177 except Exception, inst:
2178 except Exception, inst:
2178 ui.write(" %s\n" % inst)
2179 ui.write(" %s\n" % inst)
2179 ui.write(_(" One or more extensions could not be found"))
2180 ui.write(_(" One or more extensions could not be found"))
2180 ui.write(_(" (check that you compiled the extensions)\n"))
2181 ui.write(_(" (check that you compiled the extensions)\n"))
2181 problems += 1
2182 problems += 1
2182
2183
2183 # templates
2184 # templates
2184 import templater
2185 import templater
2185 p = templater.templatepath()
2186 p = templater.templatepath()
2186 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2187 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2187 if p:
2188 if p:
2188 m = templater.templatepath("map-cmdline.default")
2189 m = templater.templatepath("map-cmdline.default")
2189 if m:
2190 if m:
2190 # template found, check if it is working
2191 # template found, check if it is working
2191 try:
2192 try:
2192 templater.templater(m)
2193 templater.templater(m)
2193 except Exception, inst:
2194 except Exception, inst:
2194 ui.write(" %s\n" % inst)
2195 ui.write(" %s\n" % inst)
2195 p = None
2196 p = None
2196 else:
2197 else:
2197 ui.write(_(" template 'default' not found\n"))
2198 ui.write(_(" template 'default' not found\n"))
2198 p = None
2199 p = None
2199 else:
2200 else:
2200 ui.write(_(" no template directories found\n"))
2201 ui.write(_(" no template directories found\n"))
2201 if not p:
2202 if not p:
2202 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2203 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2203 problems += 1
2204 problems += 1
2204
2205
2205 # editor
2206 # editor
2206 ui.status(_("checking commit editor...\n"))
2207 ui.status(_("checking commit editor...\n"))
2207 editor = ui.geteditor()
2208 editor = ui.geteditor()
2208 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
2209 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
2209 if not cmdpath:
2210 if not cmdpath:
2210 if editor == 'vi':
2211 if editor == 'vi':
2211 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2212 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2212 ui.write(_(" (specify a commit editor in your configuration"
2213 ui.write(_(" (specify a commit editor in your configuration"
2213 " file)\n"))
2214 " file)\n"))
2214 else:
2215 else:
2215 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2216 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2216 ui.write(_(" (specify a commit editor in your configuration"
2217 ui.write(_(" (specify a commit editor in your configuration"
2217 " file)\n"))
2218 " file)\n"))
2218 problems += 1
2219 problems += 1
2219
2220
2220 # check username
2221 # check username
2221 ui.status(_("checking username...\n"))
2222 ui.status(_("checking username...\n"))
2222 try:
2223 try:
2223 ui.username()
2224 ui.username()
2224 except util.Abort, e:
2225 except util.Abort, e:
2225 ui.write(" %s\n" % e)
2226 ui.write(" %s\n" % e)
2226 ui.write(_(" (specify a username in your configuration file)\n"))
2227 ui.write(_(" (specify a username in your configuration file)\n"))
2227 problems += 1
2228 problems += 1
2228
2229
2229 if not problems:
2230 if not problems:
2230 ui.status(_("no problems detected\n"))
2231 ui.status(_("no problems detected\n"))
2231 else:
2232 else:
2232 ui.write(_("%s problems detected,"
2233 ui.write(_("%s problems detected,"
2233 " please check your install!\n") % problems)
2234 " please check your install!\n") % problems)
2234
2235
2235 return problems
2236 return problems
2236
2237
2237 @command('debugknown', [], _('REPO ID...'))
2238 @command('debugknown', [], _('REPO ID...'))
2238 def debugknown(ui, repopath, *ids, **opts):
2239 def debugknown(ui, repopath, *ids, **opts):
2239 """test whether node ids are known to a repo
2240 """test whether node ids are known to a repo
2240
2241
2241 Every ID must be a full-length hex node id string. Returns a list of 0s
2242 Every ID must be a full-length hex node id string. Returns a list of 0s
2242 and 1s indicating unknown/known.
2243 and 1s indicating unknown/known.
2243 """
2244 """
2244 repo = hg.peer(ui, opts, repopath)
2245 repo = hg.peer(ui, opts, repopath)
2245 if not repo.capable('known'):
2246 if not repo.capable('known'):
2246 raise util.Abort("known() not supported by target repository")
2247 raise util.Abort("known() not supported by target repository")
2247 flags = repo.known([bin(s) for s in ids])
2248 flags = repo.known([bin(s) for s in ids])
2248 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2249 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2249
2250
2250 @command('debuglabelcomplete', [], _('LABEL...'))
2251 @command('debuglabelcomplete', [], _('LABEL...'))
2251 def debuglabelcomplete(ui, repo, *args):
2252 def debuglabelcomplete(ui, repo, *args):
2252 '''complete "labels" - tags, open branch names, bookmark names'''
2253 '''complete "labels" - tags, open branch names, bookmark names'''
2253
2254
2254 labels = set()
2255 labels = set()
2255 labels.update(t[0] for t in repo.tagslist())
2256 labels.update(t[0] for t in repo.tagslist())
2256 labels.update(repo._bookmarks.keys())
2257 labels.update(repo._bookmarks.keys())
2257 labels.update(tag for (tag, heads, tip, closed)
2258 labels.update(tag for (tag, heads, tip, closed)
2258 in repo.branchmap().iterbranches() if not closed)
2259 in repo.branchmap().iterbranches() if not closed)
2259 completions = set()
2260 completions = set()
2260 if not args:
2261 if not args:
2261 args = ['']
2262 args = ['']
2262 for a in args:
2263 for a in args:
2263 completions.update(l for l in labels if l.startswith(a))
2264 completions.update(l for l in labels if l.startswith(a))
2264 ui.write('\n'.join(sorted(completions)))
2265 ui.write('\n'.join(sorted(completions)))
2265 ui.write('\n')
2266 ui.write('\n')
2266
2267
2267 @command('debugobsolete',
2268 @command('debugobsolete',
2268 [('', 'flags', 0, _('markers flag')),
2269 [('', 'flags', 0, _('markers flag')),
2269 ] + commitopts2,
2270 ] + commitopts2,
2270 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2271 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2271 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2272 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2272 """create arbitrary obsolete marker
2273 """create arbitrary obsolete marker
2273
2274
2274 With no arguments, displays the list of obsolescence markers."""
2275 With no arguments, displays the list of obsolescence markers."""
2275 def parsenodeid(s):
2276 def parsenodeid(s):
2276 try:
2277 try:
2277 # We do not use revsingle/revrange functions here to accept
2278 # We do not use revsingle/revrange functions here to accept
2278 # arbitrary node identifiers, possibly not present in the
2279 # arbitrary node identifiers, possibly not present in the
2279 # local repository.
2280 # local repository.
2280 n = bin(s)
2281 n = bin(s)
2281 if len(n) != len(nullid):
2282 if len(n) != len(nullid):
2282 raise TypeError()
2283 raise TypeError()
2283 return n
2284 return n
2284 except TypeError:
2285 except TypeError:
2285 raise util.Abort('changeset references must be full hexadecimal '
2286 raise util.Abort('changeset references must be full hexadecimal '
2286 'node identifiers')
2287 'node identifiers')
2287
2288
2288 if precursor is not None:
2289 if precursor is not None:
2289 metadata = {}
2290 metadata = {}
2290 if 'date' in opts:
2291 if 'date' in opts:
2291 metadata['date'] = opts['date']
2292 metadata['date'] = opts['date']
2292 metadata['user'] = opts['user'] or ui.username()
2293 metadata['user'] = opts['user'] or ui.username()
2293 succs = tuple(parsenodeid(succ) for succ in successors)
2294 succs = tuple(parsenodeid(succ) for succ in successors)
2294 l = repo.lock()
2295 l = repo.lock()
2295 try:
2296 try:
2296 tr = repo.transaction('debugobsolete')
2297 tr = repo.transaction('debugobsolete')
2297 try:
2298 try:
2298 repo.obsstore.create(tr, parsenodeid(precursor), succs,
2299 repo.obsstore.create(tr, parsenodeid(precursor), succs,
2299 opts['flags'], metadata)
2300 opts['flags'], metadata)
2300 tr.close()
2301 tr.close()
2301 finally:
2302 finally:
2302 tr.release()
2303 tr.release()
2303 finally:
2304 finally:
2304 l.release()
2305 l.release()
2305 else:
2306 else:
2306 for m in obsolete.allmarkers(repo):
2307 for m in obsolete.allmarkers(repo):
2307 cmdutil.showmarker(ui, m)
2308 cmdutil.showmarker(ui, m)
2308
2309
2309 @command('debugpathcomplete',
2310 @command('debugpathcomplete',
2310 [('f', 'full', None, _('complete an entire path')),
2311 [('f', 'full', None, _('complete an entire path')),
2311 ('n', 'normal', None, _('show only normal files')),
2312 ('n', 'normal', None, _('show only normal files')),
2312 ('a', 'added', None, _('show only added files')),
2313 ('a', 'added', None, _('show only added files')),
2313 ('r', 'removed', None, _('show only removed files'))],
2314 ('r', 'removed', None, _('show only removed files'))],
2314 _('FILESPEC...'))
2315 _('FILESPEC...'))
2315 def debugpathcomplete(ui, repo, *specs, **opts):
2316 def debugpathcomplete(ui, repo, *specs, **opts):
2316 '''complete part or all of a tracked path
2317 '''complete part or all of a tracked path
2317
2318
2318 This command supports shells that offer path name completion. It
2319 This command supports shells that offer path name completion. It
2319 currently completes only files already known to the dirstate.
2320 currently completes only files already known to the dirstate.
2320
2321
2321 Completion extends only to the next path segment unless
2322 Completion extends only to the next path segment unless
2322 --full is specified, in which case entire paths are used.'''
2323 --full is specified, in which case entire paths are used.'''
2323
2324
2324 def complete(path, acceptable):
2325 def complete(path, acceptable):
2325 dirstate = repo.dirstate
2326 dirstate = repo.dirstate
2326 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2327 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2327 rootdir = repo.root + os.sep
2328 rootdir = repo.root + os.sep
2328 if spec != repo.root and not spec.startswith(rootdir):
2329 if spec != repo.root and not spec.startswith(rootdir):
2329 return [], []
2330 return [], []
2330 if os.path.isdir(spec):
2331 if os.path.isdir(spec):
2331 spec += '/'
2332 spec += '/'
2332 spec = spec[len(rootdir):]
2333 spec = spec[len(rootdir):]
2333 fixpaths = os.sep != '/'
2334 fixpaths = os.sep != '/'
2334 if fixpaths:
2335 if fixpaths:
2335 spec = spec.replace(os.sep, '/')
2336 spec = spec.replace(os.sep, '/')
2336 speclen = len(spec)
2337 speclen = len(spec)
2337 fullpaths = opts['full']
2338 fullpaths = opts['full']
2338 files, dirs = set(), set()
2339 files, dirs = set(), set()
2339 adddir, addfile = dirs.add, files.add
2340 adddir, addfile = dirs.add, files.add
2340 for f, st in dirstate.iteritems():
2341 for f, st in dirstate.iteritems():
2341 if f.startswith(spec) and st[0] in acceptable:
2342 if f.startswith(spec) and st[0] in acceptable:
2342 if fixpaths:
2343 if fixpaths:
2343 f = f.replace('/', os.sep)
2344 f = f.replace('/', os.sep)
2344 if fullpaths:
2345 if fullpaths:
2345 addfile(f)
2346 addfile(f)
2346 continue
2347 continue
2347 s = f.find(os.sep, speclen)
2348 s = f.find(os.sep, speclen)
2348 if s >= 0:
2349 if s >= 0:
2349 adddir(f[:s])
2350 adddir(f[:s])
2350 else:
2351 else:
2351 addfile(f)
2352 addfile(f)
2352 return files, dirs
2353 return files, dirs
2353
2354
2354 acceptable = ''
2355 acceptable = ''
2355 if opts['normal']:
2356 if opts['normal']:
2356 acceptable += 'nm'
2357 acceptable += 'nm'
2357 if opts['added']:
2358 if opts['added']:
2358 acceptable += 'a'
2359 acceptable += 'a'
2359 if opts['removed']:
2360 if opts['removed']:
2360 acceptable += 'r'
2361 acceptable += 'r'
2361 cwd = repo.getcwd()
2362 cwd = repo.getcwd()
2362 if not specs:
2363 if not specs:
2363 specs = ['.']
2364 specs = ['.']
2364
2365
2365 files, dirs = set(), set()
2366 files, dirs = set(), set()
2366 for spec in specs:
2367 for spec in specs:
2367 f, d = complete(spec, acceptable or 'nmar')
2368 f, d = complete(spec, acceptable or 'nmar')
2368 files.update(f)
2369 files.update(f)
2369 dirs.update(d)
2370 dirs.update(d)
2370 files.update(dirs)
2371 files.update(dirs)
2371 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2372 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2372 ui.write('\n')
2373 ui.write('\n')
2373
2374
2374 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
2375 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
2375 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2376 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2376 '''access the pushkey key/value protocol
2377 '''access the pushkey key/value protocol
2377
2378
2378 With two args, list the keys in the given namespace.
2379 With two args, list the keys in the given namespace.
2379
2380
2380 With five args, set a key to new if it currently is set to old.
2381 With five args, set a key to new if it currently is set to old.
2381 Reports success or failure.
2382 Reports success or failure.
2382 '''
2383 '''
2383
2384
2384 target = hg.peer(ui, {}, repopath)
2385 target = hg.peer(ui, {}, repopath)
2385 if keyinfo:
2386 if keyinfo:
2386 key, old, new = keyinfo
2387 key, old, new = keyinfo
2387 r = target.pushkey(namespace, key, old, new)
2388 r = target.pushkey(namespace, key, old, new)
2388 ui.status(str(r) + '\n')
2389 ui.status(str(r) + '\n')
2389 return not r
2390 return not r
2390 else:
2391 else:
2391 for k, v in sorted(target.listkeys(namespace).iteritems()):
2392 for k, v in sorted(target.listkeys(namespace).iteritems()):
2392 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2393 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2393 v.encode('string-escape')))
2394 v.encode('string-escape')))
2394
2395
2395 @command('debugpvec', [], _('A B'))
2396 @command('debugpvec', [], _('A B'))
2396 def debugpvec(ui, repo, a, b=None):
2397 def debugpvec(ui, repo, a, b=None):
2397 ca = scmutil.revsingle(repo, a)
2398 ca = scmutil.revsingle(repo, a)
2398 cb = scmutil.revsingle(repo, b)
2399 cb = scmutil.revsingle(repo, b)
2399 pa = pvec.ctxpvec(ca)
2400 pa = pvec.ctxpvec(ca)
2400 pb = pvec.ctxpvec(cb)
2401 pb = pvec.ctxpvec(cb)
2401 if pa == pb:
2402 if pa == pb:
2402 rel = "="
2403 rel = "="
2403 elif pa > pb:
2404 elif pa > pb:
2404 rel = ">"
2405 rel = ">"
2405 elif pa < pb:
2406 elif pa < pb:
2406 rel = "<"
2407 rel = "<"
2407 elif pa | pb:
2408 elif pa | pb:
2408 rel = "|"
2409 rel = "|"
2409 ui.write(_("a: %s\n") % pa)
2410 ui.write(_("a: %s\n") % pa)
2410 ui.write(_("b: %s\n") % pb)
2411 ui.write(_("b: %s\n") % pb)
2411 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2412 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2412 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2413 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2413 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2414 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2414 pa.distance(pb), rel))
2415 pa.distance(pb), rel))
2415
2416
2416 @command('debugrebuilddirstate|debugrebuildstate',
2417 @command('debugrebuilddirstate|debugrebuildstate',
2417 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
2418 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
2418 _('[-r REV]'))
2419 _('[-r REV]'))
2419 def debugrebuilddirstate(ui, repo, rev):
2420 def debugrebuilddirstate(ui, repo, rev):
2420 """rebuild the dirstate as it would look like for the given revision
2421 """rebuild the dirstate as it would look like for the given revision
2421
2422
2422 If no revision is specified the first current parent will be used.
2423 If no revision is specified the first current parent will be used.
2423
2424
2424 The dirstate will be set to the files of the given revision.
2425 The dirstate will be set to the files of the given revision.
2425 The actual working directory content or existing dirstate
2426 The actual working directory content or existing dirstate
2426 information such as adds or removes is not considered.
2427 information such as adds or removes is not considered.
2427
2428
2428 One use of this command is to make the next :hg:`status` invocation
2429 One use of this command is to make the next :hg:`status` invocation
2429 check the actual file content.
2430 check the actual file content.
2430 """
2431 """
2431 ctx = scmutil.revsingle(repo, rev)
2432 ctx = scmutil.revsingle(repo, rev)
2432 wlock = repo.wlock()
2433 wlock = repo.wlock()
2433 try:
2434 try:
2434 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
2435 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
2435 finally:
2436 finally:
2436 wlock.release()
2437 wlock.release()
2437
2438
2438 @command('debugrename',
2439 @command('debugrename',
2439 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2440 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2440 _('[-r REV] FILE'))
2441 _('[-r REV] FILE'))
2441 def debugrename(ui, repo, file1, *pats, **opts):
2442 def debugrename(ui, repo, file1, *pats, **opts):
2442 """dump rename information"""
2443 """dump rename information"""
2443
2444
2444 ctx = scmutil.revsingle(repo, opts.get('rev'))
2445 ctx = scmutil.revsingle(repo, opts.get('rev'))
2445 m = scmutil.match(ctx, (file1,) + pats, opts)
2446 m = scmutil.match(ctx, (file1,) + pats, opts)
2446 for abs in ctx.walk(m):
2447 for abs in ctx.walk(m):
2447 fctx = ctx[abs]
2448 fctx = ctx[abs]
2448 o = fctx.filelog().renamed(fctx.filenode())
2449 o = fctx.filelog().renamed(fctx.filenode())
2449 rel = m.rel(abs)
2450 rel = m.rel(abs)
2450 if o:
2451 if o:
2451 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2452 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2452 else:
2453 else:
2453 ui.write(_("%s not renamed\n") % rel)
2454 ui.write(_("%s not renamed\n") % rel)
2454
2455
2455 @command('debugrevlog',
2456 @command('debugrevlog',
2456 [('c', 'changelog', False, _('open changelog')),
2457 [('c', 'changelog', False, _('open changelog')),
2457 ('m', 'manifest', False, _('open manifest')),
2458 ('m', 'manifest', False, _('open manifest')),
2458 ('d', 'dump', False, _('dump index data'))],
2459 ('d', 'dump', False, _('dump index data'))],
2459 _('-c|-m|FILE'))
2460 _('-c|-m|FILE'))
2460 def debugrevlog(ui, repo, file_=None, **opts):
2461 def debugrevlog(ui, repo, file_=None, **opts):
2461 """show data and statistics about a revlog"""
2462 """show data and statistics about a revlog"""
2462 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2463 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2463
2464
2464 if opts.get("dump"):
2465 if opts.get("dump"):
2465 numrevs = len(r)
2466 numrevs = len(r)
2466 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2467 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2467 " rawsize totalsize compression heads\n")
2468 " rawsize totalsize compression heads\n")
2468 ts = 0
2469 ts = 0
2469 heads = set()
2470 heads = set()
2470 for rev in xrange(numrevs):
2471 for rev in xrange(numrevs):
2471 dbase = r.deltaparent(rev)
2472 dbase = r.deltaparent(rev)
2472 if dbase == -1:
2473 if dbase == -1:
2473 dbase = rev
2474 dbase = rev
2474 cbase = r.chainbase(rev)
2475 cbase = r.chainbase(rev)
2475 p1, p2 = r.parentrevs(rev)
2476 p1, p2 = r.parentrevs(rev)
2476 rs = r.rawsize(rev)
2477 rs = r.rawsize(rev)
2477 ts = ts + rs
2478 ts = ts + rs
2478 heads -= set(r.parentrevs(rev))
2479 heads -= set(r.parentrevs(rev))
2479 heads.add(rev)
2480 heads.add(rev)
2480 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d %11d %5d\n" %
2481 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d %11d %5d\n" %
2481 (rev, p1, p2, r.start(rev), r.end(rev),
2482 (rev, p1, p2, r.start(rev), r.end(rev),
2482 r.start(dbase), r.start(cbase),
2483 r.start(dbase), r.start(cbase),
2483 r.start(p1), r.start(p2),
2484 r.start(p1), r.start(p2),
2484 rs, ts, ts / r.end(rev), len(heads)))
2485 rs, ts, ts / r.end(rev), len(heads)))
2485 return 0
2486 return 0
2486
2487
2487 v = r.version
2488 v = r.version
2488 format = v & 0xFFFF
2489 format = v & 0xFFFF
2489 flags = []
2490 flags = []
2490 gdelta = False
2491 gdelta = False
2491 if v & revlog.REVLOGNGINLINEDATA:
2492 if v & revlog.REVLOGNGINLINEDATA:
2492 flags.append('inline')
2493 flags.append('inline')
2493 if v & revlog.REVLOGGENERALDELTA:
2494 if v & revlog.REVLOGGENERALDELTA:
2494 gdelta = True
2495 gdelta = True
2495 flags.append('generaldelta')
2496 flags.append('generaldelta')
2496 if not flags:
2497 if not flags:
2497 flags = ['(none)']
2498 flags = ['(none)']
2498
2499
2499 nummerges = 0
2500 nummerges = 0
2500 numfull = 0
2501 numfull = 0
2501 numprev = 0
2502 numprev = 0
2502 nump1 = 0
2503 nump1 = 0
2503 nump2 = 0
2504 nump2 = 0
2504 numother = 0
2505 numother = 0
2505 nump1prev = 0
2506 nump1prev = 0
2506 nump2prev = 0
2507 nump2prev = 0
2507 chainlengths = []
2508 chainlengths = []
2508
2509
2509 datasize = [None, 0, 0L]
2510 datasize = [None, 0, 0L]
2510 fullsize = [None, 0, 0L]
2511 fullsize = [None, 0, 0L]
2511 deltasize = [None, 0, 0L]
2512 deltasize = [None, 0, 0L]
2512
2513
2513 def addsize(size, l):
2514 def addsize(size, l):
2514 if l[0] is None or size < l[0]:
2515 if l[0] is None or size < l[0]:
2515 l[0] = size
2516 l[0] = size
2516 if size > l[1]:
2517 if size > l[1]:
2517 l[1] = size
2518 l[1] = size
2518 l[2] += size
2519 l[2] += size
2519
2520
2520 numrevs = len(r)
2521 numrevs = len(r)
2521 for rev in xrange(numrevs):
2522 for rev in xrange(numrevs):
2522 p1, p2 = r.parentrevs(rev)
2523 p1, p2 = r.parentrevs(rev)
2523 delta = r.deltaparent(rev)
2524 delta = r.deltaparent(rev)
2524 if format > 0:
2525 if format > 0:
2525 addsize(r.rawsize(rev), datasize)
2526 addsize(r.rawsize(rev), datasize)
2526 if p2 != nullrev:
2527 if p2 != nullrev:
2527 nummerges += 1
2528 nummerges += 1
2528 size = r.length(rev)
2529 size = r.length(rev)
2529 if delta == nullrev:
2530 if delta == nullrev:
2530 chainlengths.append(0)
2531 chainlengths.append(0)
2531 numfull += 1
2532 numfull += 1
2532 addsize(size, fullsize)
2533 addsize(size, fullsize)
2533 else:
2534 else:
2534 chainlengths.append(chainlengths[delta] + 1)
2535 chainlengths.append(chainlengths[delta] + 1)
2535 addsize(size, deltasize)
2536 addsize(size, deltasize)
2536 if delta == rev - 1:
2537 if delta == rev - 1:
2537 numprev += 1
2538 numprev += 1
2538 if delta == p1:
2539 if delta == p1:
2539 nump1prev += 1
2540 nump1prev += 1
2540 elif delta == p2:
2541 elif delta == p2:
2541 nump2prev += 1
2542 nump2prev += 1
2542 elif delta == p1:
2543 elif delta == p1:
2543 nump1 += 1
2544 nump1 += 1
2544 elif delta == p2:
2545 elif delta == p2:
2545 nump2 += 1
2546 nump2 += 1
2546 elif delta != nullrev:
2547 elif delta != nullrev:
2547 numother += 1
2548 numother += 1
2548
2549
2549 # Adjust size min value for empty cases
2550 # Adjust size min value for empty cases
2550 for size in (datasize, fullsize, deltasize):
2551 for size in (datasize, fullsize, deltasize):
2551 if size[0] is None:
2552 if size[0] is None:
2552 size[0] = 0
2553 size[0] = 0
2553
2554
2554 numdeltas = numrevs - numfull
2555 numdeltas = numrevs - numfull
2555 numoprev = numprev - nump1prev - nump2prev
2556 numoprev = numprev - nump1prev - nump2prev
2556 totalrawsize = datasize[2]
2557 totalrawsize = datasize[2]
2557 datasize[2] /= numrevs
2558 datasize[2] /= numrevs
2558 fulltotal = fullsize[2]
2559 fulltotal = fullsize[2]
2559 fullsize[2] /= numfull
2560 fullsize[2] /= numfull
2560 deltatotal = deltasize[2]
2561 deltatotal = deltasize[2]
2561 if numrevs - numfull > 0:
2562 if numrevs - numfull > 0:
2562 deltasize[2] /= numrevs - numfull
2563 deltasize[2] /= numrevs - numfull
2563 totalsize = fulltotal + deltatotal
2564 totalsize = fulltotal + deltatotal
2564 avgchainlen = sum(chainlengths) / numrevs
2565 avgchainlen = sum(chainlengths) / numrevs
2565 compratio = totalrawsize / totalsize
2566 compratio = totalrawsize / totalsize
2566
2567
2567 basedfmtstr = '%%%dd\n'
2568 basedfmtstr = '%%%dd\n'
2568 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2569 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2569
2570
2570 def dfmtstr(max):
2571 def dfmtstr(max):
2571 return basedfmtstr % len(str(max))
2572 return basedfmtstr % len(str(max))
2572 def pcfmtstr(max, padding=0):
2573 def pcfmtstr(max, padding=0):
2573 return basepcfmtstr % (len(str(max)), ' ' * padding)
2574 return basepcfmtstr % (len(str(max)), ' ' * padding)
2574
2575
2575 def pcfmt(value, total):
2576 def pcfmt(value, total):
2576 return (value, 100 * float(value) / total)
2577 return (value, 100 * float(value) / total)
2577
2578
2578 ui.write(('format : %d\n') % format)
2579 ui.write(('format : %d\n') % format)
2579 ui.write(('flags : %s\n') % ', '.join(flags))
2580 ui.write(('flags : %s\n') % ', '.join(flags))
2580
2581
2581 ui.write('\n')
2582 ui.write('\n')
2582 fmt = pcfmtstr(totalsize)
2583 fmt = pcfmtstr(totalsize)
2583 fmt2 = dfmtstr(totalsize)
2584 fmt2 = dfmtstr(totalsize)
2584 ui.write(('revisions : ') + fmt2 % numrevs)
2585 ui.write(('revisions : ') + fmt2 % numrevs)
2585 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2586 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2586 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2587 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2587 ui.write(('revisions : ') + fmt2 % numrevs)
2588 ui.write(('revisions : ') + fmt2 % numrevs)
2588 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2589 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2589 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2590 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2590 ui.write(('revision size : ') + fmt2 % totalsize)
2591 ui.write(('revision size : ') + fmt2 % totalsize)
2591 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2592 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2592 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2593 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2593
2594
2594 ui.write('\n')
2595 ui.write('\n')
2595 fmt = dfmtstr(max(avgchainlen, compratio))
2596 fmt = dfmtstr(max(avgchainlen, compratio))
2596 ui.write(('avg chain length : ') + fmt % avgchainlen)
2597 ui.write(('avg chain length : ') + fmt % avgchainlen)
2597 ui.write(('compression ratio : ') + fmt % compratio)
2598 ui.write(('compression ratio : ') + fmt % compratio)
2598
2599
2599 if format > 0:
2600 if format > 0:
2600 ui.write('\n')
2601 ui.write('\n')
2601 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2602 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2602 % tuple(datasize))
2603 % tuple(datasize))
2603 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2604 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2604 % tuple(fullsize))
2605 % tuple(fullsize))
2605 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2606 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2606 % tuple(deltasize))
2607 % tuple(deltasize))
2607
2608
2608 if numdeltas > 0:
2609 if numdeltas > 0:
2609 ui.write('\n')
2610 ui.write('\n')
2610 fmt = pcfmtstr(numdeltas)
2611 fmt = pcfmtstr(numdeltas)
2611 fmt2 = pcfmtstr(numdeltas, 4)
2612 fmt2 = pcfmtstr(numdeltas, 4)
2612 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2613 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2613 if numprev > 0:
2614 if numprev > 0:
2614 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2615 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2615 numprev))
2616 numprev))
2616 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2617 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2617 numprev))
2618 numprev))
2618 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2619 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2619 numprev))
2620 numprev))
2620 if gdelta:
2621 if gdelta:
2621 ui.write(('deltas against p1 : ')
2622 ui.write(('deltas against p1 : ')
2622 + fmt % pcfmt(nump1, numdeltas))
2623 + fmt % pcfmt(nump1, numdeltas))
2623 ui.write(('deltas against p2 : ')
2624 ui.write(('deltas against p2 : ')
2624 + fmt % pcfmt(nump2, numdeltas))
2625 + fmt % pcfmt(nump2, numdeltas))
2625 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2626 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2626 numdeltas))
2627 numdeltas))
2627
2628
2628 @command('debugrevspec',
2629 @command('debugrevspec',
2629 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2630 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2630 ('REVSPEC'))
2631 ('REVSPEC'))
2631 def debugrevspec(ui, repo, expr, **opts):
2632 def debugrevspec(ui, repo, expr, **opts):
2632 """parse and apply a revision specification
2633 """parse and apply a revision specification
2633
2634
2634 Use --verbose to print the parsed tree before and after aliases
2635 Use --verbose to print the parsed tree before and after aliases
2635 expansion.
2636 expansion.
2636 """
2637 """
2637 if ui.verbose:
2638 if ui.verbose:
2638 tree = revset.parse(expr)[0]
2639 tree = revset.parse(expr)[0]
2639 ui.note(revset.prettyformat(tree), "\n")
2640 ui.note(revset.prettyformat(tree), "\n")
2640 newtree = revset.findaliases(ui, tree)
2641 newtree = revset.findaliases(ui, tree)
2641 if newtree != tree:
2642 if newtree != tree:
2642 ui.note(revset.prettyformat(newtree), "\n")
2643 ui.note(revset.prettyformat(newtree), "\n")
2643 if opts["optimize"]:
2644 if opts["optimize"]:
2644 weight, optimizedtree = revset.optimize(newtree, True)
2645 weight, optimizedtree = revset.optimize(newtree, True)
2645 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2646 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2646 func = revset.match(ui, expr)
2647 func = revset.match(ui, expr)
2647 for c in func(repo, revset.spanset(repo)):
2648 for c in func(repo, revset.spanset(repo)):
2648 ui.write("%s\n" % c)
2649 ui.write("%s\n" % c)
2649
2650
2650 @command('debugsetparents', [], _('REV1 [REV2]'))
2651 @command('debugsetparents', [], _('REV1 [REV2]'))
2651 def debugsetparents(ui, repo, rev1, rev2=None):
2652 def debugsetparents(ui, repo, rev1, rev2=None):
2652 """manually set the parents of the current working directory
2653 """manually set the parents of the current working directory
2653
2654
2654 This is useful for writing repository conversion tools, but should
2655 This is useful for writing repository conversion tools, but should
2655 be used with care.
2656 be used with care.
2656
2657
2657 Returns 0 on success.
2658 Returns 0 on success.
2658 """
2659 """
2659
2660
2660 r1 = scmutil.revsingle(repo, rev1).node()
2661 r1 = scmutil.revsingle(repo, rev1).node()
2661 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2662 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2662
2663
2663 wlock = repo.wlock()
2664 wlock = repo.wlock()
2664 try:
2665 try:
2665 repo.setparents(r1, r2)
2666 repo.setparents(r1, r2)
2666 finally:
2667 finally:
2667 wlock.release()
2668 wlock.release()
2668
2669
2669 @command('debugdirstate|debugstate',
2670 @command('debugdirstate|debugstate',
2670 [('', 'nodates', None, _('do not display the saved mtime')),
2671 [('', 'nodates', None, _('do not display the saved mtime')),
2671 ('', 'datesort', None, _('sort by saved mtime'))],
2672 ('', 'datesort', None, _('sort by saved mtime'))],
2672 _('[OPTION]...'))
2673 _('[OPTION]...'))
2673 def debugstate(ui, repo, nodates=None, datesort=None):
2674 def debugstate(ui, repo, nodates=None, datesort=None):
2674 """show the contents of the current dirstate"""
2675 """show the contents of the current dirstate"""
2675 timestr = ""
2676 timestr = ""
2676 showdate = not nodates
2677 showdate = not nodates
2677 if datesort:
2678 if datesort:
2678 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2679 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2679 else:
2680 else:
2680 keyfunc = None # sort by filename
2681 keyfunc = None # sort by filename
2681 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2682 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2682 if showdate:
2683 if showdate:
2683 if ent[3] == -1:
2684 if ent[3] == -1:
2684 # Pad or slice to locale representation
2685 # Pad or slice to locale representation
2685 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2686 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2686 time.localtime(0)))
2687 time.localtime(0)))
2687 timestr = 'unset'
2688 timestr = 'unset'
2688 timestr = (timestr[:locale_len] +
2689 timestr = (timestr[:locale_len] +
2689 ' ' * (locale_len - len(timestr)))
2690 ' ' * (locale_len - len(timestr)))
2690 else:
2691 else:
2691 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2692 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2692 time.localtime(ent[3]))
2693 time.localtime(ent[3]))
2693 if ent[1] & 020000:
2694 if ent[1] & 020000:
2694 mode = 'lnk'
2695 mode = 'lnk'
2695 else:
2696 else:
2696 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2697 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2697 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2698 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2698 for f in repo.dirstate.copies():
2699 for f in repo.dirstate.copies():
2699 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2700 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2700
2701
2701 @command('debugsub',
2702 @command('debugsub',
2702 [('r', 'rev', '',
2703 [('r', 'rev', '',
2703 _('revision to check'), _('REV'))],
2704 _('revision to check'), _('REV'))],
2704 _('[-r REV] [REV]'))
2705 _('[-r REV] [REV]'))
2705 def debugsub(ui, repo, rev=None):
2706 def debugsub(ui, repo, rev=None):
2706 ctx = scmutil.revsingle(repo, rev, None)
2707 ctx = scmutil.revsingle(repo, rev, None)
2707 for k, v in sorted(ctx.substate.items()):
2708 for k, v in sorted(ctx.substate.items()):
2708 ui.write(('path %s\n') % k)
2709 ui.write(('path %s\n') % k)
2709 ui.write((' source %s\n') % v[0])
2710 ui.write((' source %s\n') % v[0])
2710 ui.write((' revision %s\n') % v[1])
2711 ui.write((' revision %s\n') % v[1])
2711
2712
2712 @command('debugsuccessorssets',
2713 @command('debugsuccessorssets',
2713 [],
2714 [],
2714 _('[REV]'))
2715 _('[REV]'))
2715 def debugsuccessorssets(ui, repo, *revs):
2716 def debugsuccessorssets(ui, repo, *revs):
2716 """show set of successors for revision
2717 """show set of successors for revision
2717
2718
2718 A successors set of changeset A is a consistent group of revisions that
2719 A successors set of changeset A is a consistent group of revisions that
2719 succeed A. It contains non-obsolete changesets only.
2720 succeed A. It contains non-obsolete changesets only.
2720
2721
2721 In most cases a changeset A has a single successors set containing a single
2722 In most cases a changeset A has a single successors set containing a single
2722 successor (changeset A replaced by A').
2723 successor (changeset A replaced by A').
2723
2724
2724 A changeset that is made obsolete with no successors are called "pruned".
2725 A changeset that is made obsolete with no successors are called "pruned".
2725 Such changesets have no successors sets at all.
2726 Such changesets have no successors sets at all.
2726
2727
2727 A changeset that has been "split" will have a successors set containing
2728 A changeset that has been "split" will have a successors set containing
2728 more than one successor.
2729 more than one successor.
2729
2730
2730 A changeset that has been rewritten in multiple different ways is called
2731 A changeset that has been rewritten in multiple different ways is called
2731 "divergent". Such changesets have multiple successor sets (each of which
2732 "divergent". Such changesets have multiple successor sets (each of which
2732 may also be split, i.e. have multiple successors).
2733 may also be split, i.e. have multiple successors).
2733
2734
2734 Results are displayed as follows::
2735 Results are displayed as follows::
2735
2736
2736 <rev1>
2737 <rev1>
2737 <successors-1A>
2738 <successors-1A>
2738 <rev2>
2739 <rev2>
2739 <successors-2A>
2740 <successors-2A>
2740 <successors-2B1> <successors-2B2> <successors-2B3>
2741 <successors-2B1> <successors-2B2> <successors-2B3>
2741
2742
2742 Here rev2 has two possible (i.e. divergent) successors sets. The first
2743 Here rev2 has two possible (i.e. divergent) successors sets. The first
2743 holds one element, whereas the second holds three (i.e. the changeset has
2744 holds one element, whereas the second holds three (i.e. the changeset has
2744 been split).
2745 been split).
2745 """
2746 """
2746 # passed to successorssets caching computation from one call to another
2747 # passed to successorssets caching computation from one call to another
2747 cache = {}
2748 cache = {}
2748 ctx2str = str
2749 ctx2str = str
2749 node2str = short
2750 node2str = short
2750 if ui.debug():
2751 if ui.debug():
2751 def ctx2str(ctx):
2752 def ctx2str(ctx):
2752 return ctx.hex()
2753 return ctx.hex()
2753 node2str = hex
2754 node2str = hex
2754 for rev in scmutil.revrange(repo, revs):
2755 for rev in scmutil.revrange(repo, revs):
2755 ctx = repo[rev]
2756 ctx = repo[rev]
2756 ui.write('%s\n'% ctx2str(ctx))
2757 ui.write('%s\n'% ctx2str(ctx))
2757 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2758 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2758 if succsset:
2759 if succsset:
2759 ui.write(' ')
2760 ui.write(' ')
2760 ui.write(node2str(succsset[0]))
2761 ui.write(node2str(succsset[0]))
2761 for node in succsset[1:]:
2762 for node in succsset[1:]:
2762 ui.write(' ')
2763 ui.write(' ')
2763 ui.write(node2str(node))
2764 ui.write(node2str(node))
2764 ui.write('\n')
2765 ui.write('\n')
2765
2766
2766 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2767 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2767 def debugwalk(ui, repo, *pats, **opts):
2768 def debugwalk(ui, repo, *pats, **opts):
2768 """show how files match on given patterns"""
2769 """show how files match on given patterns"""
2769 m = scmutil.match(repo[None], pats, opts)
2770 m = scmutil.match(repo[None], pats, opts)
2770 items = list(repo.walk(m))
2771 items = list(repo.walk(m))
2771 if not items:
2772 if not items:
2772 return
2773 return
2773 f = lambda fn: fn
2774 f = lambda fn: fn
2774 if ui.configbool('ui', 'slash') and os.sep != '/':
2775 if ui.configbool('ui', 'slash') and os.sep != '/':
2775 f = lambda fn: util.normpath(fn)
2776 f = lambda fn: util.normpath(fn)
2776 fmt = 'f %%-%ds %%-%ds %%s' % (
2777 fmt = 'f %%-%ds %%-%ds %%s' % (
2777 max([len(abs) for abs in items]),
2778 max([len(abs) for abs in items]),
2778 max([len(m.rel(abs)) for abs in items]))
2779 max([len(m.rel(abs)) for abs in items]))
2779 for abs in items:
2780 for abs in items:
2780 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2781 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2781 ui.write("%s\n" % line.rstrip())
2782 ui.write("%s\n" % line.rstrip())
2782
2783
2783 @command('debugwireargs',
2784 @command('debugwireargs',
2784 [('', 'three', '', 'three'),
2785 [('', 'three', '', 'three'),
2785 ('', 'four', '', 'four'),
2786 ('', 'four', '', 'four'),
2786 ('', 'five', '', 'five'),
2787 ('', 'five', '', 'five'),
2787 ] + remoteopts,
2788 ] + remoteopts,
2788 _('REPO [OPTIONS]... [ONE [TWO]]'))
2789 _('REPO [OPTIONS]... [ONE [TWO]]'))
2789 def debugwireargs(ui, repopath, *vals, **opts):
2790 def debugwireargs(ui, repopath, *vals, **opts):
2790 repo = hg.peer(ui, opts, repopath)
2791 repo = hg.peer(ui, opts, repopath)
2791 for opt in remoteopts:
2792 for opt in remoteopts:
2792 del opts[opt[1]]
2793 del opts[opt[1]]
2793 args = {}
2794 args = {}
2794 for k, v in opts.iteritems():
2795 for k, v in opts.iteritems():
2795 if v:
2796 if v:
2796 args[k] = v
2797 args[k] = v
2797 # run twice to check that we don't mess up the stream for the next command
2798 # run twice to check that we don't mess up the stream for the next command
2798 res1 = repo.debugwireargs(*vals, **args)
2799 res1 = repo.debugwireargs(*vals, **args)
2799 res2 = repo.debugwireargs(*vals, **args)
2800 res2 = repo.debugwireargs(*vals, **args)
2800 ui.write("%s\n" % res1)
2801 ui.write("%s\n" % res1)
2801 if res1 != res2:
2802 if res1 != res2:
2802 ui.warn("%s\n" % res2)
2803 ui.warn("%s\n" % res2)
2803
2804
2804 @command('^diff',
2805 @command('^diff',
2805 [('r', 'rev', [], _('revision'), _('REV')),
2806 [('r', 'rev', [], _('revision'), _('REV')),
2806 ('c', 'change', '', _('change made by revision'), _('REV'))
2807 ('c', 'change', '', _('change made by revision'), _('REV'))
2807 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2808 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2808 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2809 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2809 def diff(ui, repo, *pats, **opts):
2810 def diff(ui, repo, *pats, **opts):
2810 """diff repository (or selected files)
2811 """diff repository (or selected files)
2811
2812
2812 Show differences between revisions for the specified files.
2813 Show differences between revisions for the specified files.
2813
2814
2814 Differences between files are shown using the unified diff format.
2815 Differences between files are shown using the unified diff format.
2815
2816
2816 .. note::
2817 .. note::
2817
2818
2818 diff may generate unexpected results for merges, as it will
2819 diff may generate unexpected results for merges, as it will
2819 default to comparing against the working directory's first
2820 default to comparing against the working directory's first
2820 parent changeset if no revisions are specified.
2821 parent changeset if no revisions are specified.
2821
2822
2822 When two revision arguments are given, then changes are shown
2823 When two revision arguments are given, then changes are shown
2823 between those revisions. If only one revision is specified then
2824 between those revisions. If only one revision is specified then
2824 that revision is compared to the working directory, and, when no
2825 that revision is compared to the working directory, and, when no
2825 revisions are specified, the working directory files are compared
2826 revisions are specified, the working directory files are compared
2826 to its parent.
2827 to its parent.
2827
2828
2828 Alternatively you can specify -c/--change with a revision to see
2829 Alternatively you can specify -c/--change with a revision to see
2829 the changes in that changeset relative to its first parent.
2830 the changes in that changeset relative to its first parent.
2830
2831
2831 Without the -a/--text option, diff will avoid generating diffs of
2832 Without the -a/--text option, diff will avoid generating diffs of
2832 files it detects as binary. With -a, diff will generate a diff
2833 files it detects as binary. With -a, diff will generate a diff
2833 anyway, probably with undesirable results.
2834 anyway, probably with undesirable results.
2834
2835
2835 Use the -g/--git option to generate diffs in the git extended diff
2836 Use the -g/--git option to generate diffs in the git extended diff
2836 format. For more information, read :hg:`help diffs`.
2837 format. For more information, read :hg:`help diffs`.
2837
2838
2838 .. container:: verbose
2839 .. container:: verbose
2839
2840
2840 Examples:
2841 Examples:
2841
2842
2842 - compare a file in the current working directory to its parent::
2843 - compare a file in the current working directory to its parent::
2843
2844
2844 hg diff foo.c
2845 hg diff foo.c
2845
2846
2846 - compare two historical versions of a directory, with rename info::
2847 - compare two historical versions of a directory, with rename info::
2847
2848
2848 hg diff --git -r 1.0:1.2 lib/
2849 hg diff --git -r 1.0:1.2 lib/
2849
2850
2850 - get change stats relative to the last change on some date::
2851 - get change stats relative to the last change on some date::
2851
2852
2852 hg diff --stat -r "date('may 2')"
2853 hg diff --stat -r "date('may 2')"
2853
2854
2854 - diff all newly-added files that contain a keyword::
2855 - diff all newly-added files that contain a keyword::
2855
2856
2856 hg diff "set:added() and grep(GNU)"
2857 hg diff "set:added() and grep(GNU)"
2857
2858
2858 - compare a revision and its parents::
2859 - compare a revision and its parents::
2859
2860
2860 hg diff -c 9353 # compare against first parent
2861 hg diff -c 9353 # compare against first parent
2861 hg diff -r 9353^:9353 # same using revset syntax
2862 hg diff -r 9353^:9353 # same using revset syntax
2862 hg diff -r 9353^2:9353 # compare against the second parent
2863 hg diff -r 9353^2:9353 # compare against the second parent
2863
2864
2864 Returns 0 on success.
2865 Returns 0 on success.
2865 """
2866 """
2866
2867
2867 revs = opts.get('rev')
2868 revs = opts.get('rev')
2868 change = opts.get('change')
2869 change = opts.get('change')
2869 stat = opts.get('stat')
2870 stat = opts.get('stat')
2870 reverse = opts.get('reverse')
2871 reverse = opts.get('reverse')
2871
2872
2872 if revs and change:
2873 if revs and change:
2873 msg = _('cannot specify --rev and --change at the same time')
2874 msg = _('cannot specify --rev and --change at the same time')
2874 raise util.Abort(msg)
2875 raise util.Abort(msg)
2875 elif change:
2876 elif change:
2876 node2 = scmutil.revsingle(repo, change, None).node()
2877 node2 = scmutil.revsingle(repo, change, None).node()
2877 node1 = repo[node2].p1().node()
2878 node1 = repo[node2].p1().node()
2878 else:
2879 else:
2879 node1, node2 = scmutil.revpair(repo, revs)
2880 node1, node2 = scmutil.revpair(repo, revs)
2880
2881
2881 if reverse:
2882 if reverse:
2882 node1, node2 = node2, node1
2883 node1, node2 = node2, node1
2883
2884
2884 diffopts = patch.diffopts(ui, opts)
2885 diffopts = patch.diffopts(ui, opts)
2885 m = scmutil.match(repo[node2], pats, opts)
2886 m = scmutil.match(repo[node2], pats, opts)
2886 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2887 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2887 listsubrepos=opts.get('subrepos'))
2888 listsubrepos=opts.get('subrepos'))
2888
2889
2889 @command('^export',
2890 @command('^export',
2890 [('o', 'output', '',
2891 [('o', 'output', '',
2891 _('print output to file with formatted name'), _('FORMAT')),
2892 _('print output to file with formatted name'), _('FORMAT')),
2892 ('', 'switch-parent', None, _('diff against the second parent')),
2893 ('', 'switch-parent', None, _('diff against the second parent')),
2893 ('r', 'rev', [], _('revisions to export'), _('REV')),
2894 ('r', 'rev', [], _('revisions to export'), _('REV')),
2894 ] + diffopts,
2895 ] + diffopts,
2895 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
2896 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
2896 def export(ui, repo, *changesets, **opts):
2897 def export(ui, repo, *changesets, **opts):
2897 """dump the header and diffs for one or more changesets
2898 """dump the header and diffs for one or more changesets
2898
2899
2899 Print the changeset header and diffs for one or more revisions.
2900 Print the changeset header and diffs for one or more revisions.
2900 If no revision is given, the parent of the working directory is used.
2901 If no revision is given, the parent of the working directory is used.
2901
2902
2902 The information shown in the changeset header is: author, date,
2903 The information shown in the changeset header is: author, date,
2903 branch name (if non-default), changeset hash, parent(s) and commit
2904 branch name (if non-default), changeset hash, parent(s) and commit
2904 comment.
2905 comment.
2905
2906
2906 .. note::
2907 .. note::
2907
2908
2908 export may generate unexpected diff output for merge
2909 export may generate unexpected diff output for merge
2909 changesets, as it will compare the merge changeset against its
2910 changesets, as it will compare the merge changeset against its
2910 first parent only.
2911 first parent only.
2911
2912
2912 Output may be to a file, in which case the name of the file is
2913 Output may be to a file, in which case the name of the file is
2913 given using a format string. The formatting rules are as follows:
2914 given using a format string. The formatting rules are as follows:
2914
2915
2915 :``%%``: literal "%" character
2916 :``%%``: literal "%" character
2916 :``%H``: changeset hash (40 hexadecimal digits)
2917 :``%H``: changeset hash (40 hexadecimal digits)
2917 :``%N``: number of patches being generated
2918 :``%N``: number of patches being generated
2918 :``%R``: changeset revision number
2919 :``%R``: changeset revision number
2919 :``%b``: basename of the exporting repository
2920 :``%b``: basename of the exporting repository
2920 :``%h``: short-form changeset hash (12 hexadecimal digits)
2921 :``%h``: short-form changeset hash (12 hexadecimal digits)
2921 :``%m``: first line of the commit message (only alphanumeric characters)
2922 :``%m``: first line of the commit message (only alphanumeric characters)
2922 :``%n``: zero-padded sequence number, starting at 1
2923 :``%n``: zero-padded sequence number, starting at 1
2923 :``%r``: zero-padded changeset revision number
2924 :``%r``: zero-padded changeset revision number
2924
2925
2925 Without the -a/--text option, export will avoid generating diffs
2926 Without the -a/--text option, export will avoid generating diffs
2926 of files it detects as binary. With -a, export will generate a
2927 of files it detects as binary. With -a, export will generate a
2927 diff anyway, probably with undesirable results.
2928 diff anyway, probably with undesirable results.
2928
2929
2929 Use the -g/--git option to generate diffs in the git extended diff
2930 Use the -g/--git option to generate diffs in the git extended diff
2930 format. See :hg:`help diffs` for more information.
2931 format. See :hg:`help diffs` for more information.
2931
2932
2932 With the --switch-parent option, the diff will be against the
2933 With the --switch-parent option, the diff will be against the
2933 second parent. It can be useful to review a merge.
2934 second parent. It can be useful to review a merge.
2934
2935
2935 .. container:: verbose
2936 .. container:: verbose
2936
2937
2937 Examples:
2938 Examples:
2938
2939
2939 - use export and import to transplant a bugfix to the current
2940 - use export and import to transplant a bugfix to the current
2940 branch::
2941 branch::
2941
2942
2942 hg export -r 9353 | hg import -
2943 hg export -r 9353 | hg import -
2943
2944
2944 - export all the changesets between two revisions to a file with
2945 - export all the changesets between two revisions to a file with
2945 rename information::
2946 rename information::
2946
2947
2947 hg export --git -r 123:150 > changes.txt
2948 hg export --git -r 123:150 > changes.txt
2948
2949
2949 - split outgoing changes into a series of patches with
2950 - split outgoing changes into a series of patches with
2950 descriptive names::
2951 descriptive names::
2951
2952
2952 hg export -r "outgoing()" -o "%n-%m.patch"
2953 hg export -r "outgoing()" -o "%n-%m.patch"
2953
2954
2954 Returns 0 on success.
2955 Returns 0 on success.
2955 """
2956 """
2956 changesets += tuple(opts.get('rev', []))
2957 changesets += tuple(opts.get('rev', []))
2957 if not changesets:
2958 if not changesets:
2958 changesets = ['.']
2959 changesets = ['.']
2959 revs = scmutil.revrange(repo, changesets)
2960 revs = scmutil.revrange(repo, changesets)
2960 if not revs:
2961 if not revs:
2961 raise util.Abort(_("export requires at least one changeset"))
2962 raise util.Abort(_("export requires at least one changeset"))
2962 if len(revs) > 1:
2963 if len(revs) > 1:
2963 ui.note(_('exporting patches:\n'))
2964 ui.note(_('exporting patches:\n'))
2964 else:
2965 else:
2965 ui.note(_('exporting patch:\n'))
2966 ui.note(_('exporting patch:\n'))
2966 cmdutil.export(repo, revs, template=opts.get('output'),
2967 cmdutil.export(repo, revs, template=opts.get('output'),
2967 switch_parent=opts.get('switch_parent'),
2968 switch_parent=opts.get('switch_parent'),
2968 opts=patch.diffopts(ui, opts))
2969 opts=patch.diffopts(ui, opts))
2969
2970
2970 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2971 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2971 def forget(ui, repo, *pats, **opts):
2972 def forget(ui, repo, *pats, **opts):
2972 """forget the specified files on the next commit
2973 """forget the specified files on the next commit
2973
2974
2974 Mark the specified files so they will no longer be tracked
2975 Mark the specified files so they will no longer be tracked
2975 after the next commit.
2976 after the next commit.
2976
2977
2977 This only removes files from the current branch, not from the
2978 This only removes files from the current branch, not from the
2978 entire project history, and it does not delete them from the
2979 entire project history, and it does not delete them from the
2979 working directory.
2980 working directory.
2980
2981
2981 To undo a forget before the next commit, see :hg:`add`.
2982 To undo a forget before the next commit, see :hg:`add`.
2982
2983
2983 .. container:: verbose
2984 .. container:: verbose
2984
2985
2985 Examples:
2986 Examples:
2986
2987
2987 - forget newly-added binary files::
2988 - forget newly-added binary files::
2988
2989
2989 hg forget "set:added() and binary()"
2990 hg forget "set:added() and binary()"
2990
2991
2991 - forget files that would be excluded by .hgignore::
2992 - forget files that would be excluded by .hgignore::
2992
2993
2993 hg forget "set:hgignore()"
2994 hg forget "set:hgignore()"
2994
2995
2995 Returns 0 on success.
2996 Returns 0 on success.
2996 """
2997 """
2997
2998
2998 if not pats:
2999 if not pats:
2999 raise util.Abort(_('no files specified'))
3000 raise util.Abort(_('no files specified'))
3000
3001
3001 m = scmutil.match(repo[None], pats, opts)
3002 m = scmutil.match(repo[None], pats, opts)
3002 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3003 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3003 return rejected and 1 or 0
3004 return rejected and 1 or 0
3004
3005
3005 @command(
3006 @command(
3006 'graft',
3007 'graft',
3007 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3008 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3008 ('c', 'continue', False, _('resume interrupted graft')),
3009 ('c', 'continue', False, _('resume interrupted graft')),
3009 ('e', 'edit', False, _('invoke editor on commit messages')),
3010 ('e', 'edit', False, _('invoke editor on commit messages')),
3010 ('', 'log', None, _('append graft info to log message')),
3011 ('', 'log', None, _('append graft info to log message')),
3011 ('D', 'currentdate', False,
3012 ('D', 'currentdate', False,
3012 _('record the current date as commit date')),
3013 _('record the current date as commit date')),
3013 ('U', 'currentuser', False,
3014 ('U', 'currentuser', False,
3014 _('record the current user as committer'), _('DATE'))]
3015 _('record the current user as committer'), _('DATE'))]
3015 + commitopts2 + mergetoolopts + dryrunopts,
3016 + commitopts2 + mergetoolopts + dryrunopts,
3016 _('[OPTION]... [-r] REV...'))
3017 _('[OPTION]... [-r] REV...'))
3017 def graft(ui, repo, *revs, **opts):
3018 def graft(ui, repo, *revs, **opts):
3018 '''copy changes from other branches onto the current branch
3019 '''copy changes from other branches onto the current branch
3019
3020
3020 This command uses Mercurial's merge logic to copy individual
3021 This command uses Mercurial's merge logic to copy individual
3021 changes from other branches without merging branches in the
3022 changes from other branches without merging branches in the
3022 history graph. This is sometimes known as 'backporting' or
3023 history graph. This is sometimes known as 'backporting' or
3023 'cherry-picking'. By default, graft will copy user, date, and
3024 'cherry-picking'. By default, graft will copy user, date, and
3024 description from the source changesets.
3025 description from the source changesets.
3025
3026
3026 Changesets that are ancestors of the current revision, that have
3027 Changesets that are ancestors of the current revision, that have
3027 already been grafted, or that are merges will be skipped.
3028 already been grafted, or that are merges will be skipped.
3028
3029
3029 If --log is specified, log messages will have a comment appended
3030 If --log is specified, log messages will have a comment appended
3030 of the form::
3031 of the form::
3031
3032
3032 (grafted from CHANGESETHASH)
3033 (grafted from CHANGESETHASH)
3033
3034
3034 If a graft merge results in conflicts, the graft process is
3035 If a graft merge results in conflicts, the graft process is
3035 interrupted so that the current merge can be manually resolved.
3036 interrupted so that the current merge can be manually resolved.
3036 Once all conflicts are addressed, the graft process can be
3037 Once all conflicts are addressed, the graft process can be
3037 continued with the -c/--continue option.
3038 continued with the -c/--continue option.
3038
3039
3039 .. note::
3040 .. note::
3040
3041
3041 The -c/--continue option does not reapply earlier options.
3042 The -c/--continue option does not reapply earlier options.
3042
3043
3043 .. container:: verbose
3044 .. container:: verbose
3044
3045
3045 Examples:
3046 Examples:
3046
3047
3047 - copy a single change to the stable branch and edit its description::
3048 - copy a single change to the stable branch and edit its description::
3048
3049
3049 hg update stable
3050 hg update stable
3050 hg graft --edit 9393
3051 hg graft --edit 9393
3051
3052
3052 - graft a range of changesets with one exception, updating dates::
3053 - graft a range of changesets with one exception, updating dates::
3053
3054
3054 hg graft -D "2085::2093 and not 2091"
3055 hg graft -D "2085::2093 and not 2091"
3055
3056
3056 - continue a graft after resolving conflicts::
3057 - continue a graft after resolving conflicts::
3057
3058
3058 hg graft -c
3059 hg graft -c
3059
3060
3060 - show the source of a grafted changeset::
3061 - show the source of a grafted changeset::
3061
3062
3062 hg log --debug -r .
3063 hg log --debug -r .
3063
3064
3064 Returns 0 on successful completion.
3065 Returns 0 on successful completion.
3065 '''
3066 '''
3066
3067
3067 revs = list(revs)
3068 revs = list(revs)
3068 revs.extend(opts['rev'])
3069 revs.extend(opts['rev'])
3069
3070
3070 if not opts.get('user') and opts.get('currentuser'):
3071 if not opts.get('user') and opts.get('currentuser'):
3071 opts['user'] = ui.username()
3072 opts['user'] = ui.username()
3072 if not opts.get('date') and opts.get('currentdate'):
3073 if not opts.get('date') and opts.get('currentdate'):
3073 opts['date'] = "%d %d" % util.makedate()
3074 opts['date'] = "%d %d" % util.makedate()
3074
3075
3075 editor = cmdutil.getcommiteditor(**opts)
3076 editor = cmdutil.getcommiteditor(**opts)
3076
3077
3077 cont = False
3078 cont = False
3078 if opts['continue']:
3079 if opts['continue']:
3079 cont = True
3080 cont = True
3080 if revs:
3081 if revs:
3081 raise util.Abort(_("can't specify --continue and revisions"))
3082 raise util.Abort(_("can't specify --continue and revisions"))
3082 # read in unfinished revisions
3083 # read in unfinished revisions
3083 try:
3084 try:
3084 nodes = repo.opener.read('graftstate').splitlines()
3085 nodes = repo.opener.read('graftstate').splitlines()
3085 revs = [repo[node].rev() for node in nodes]
3086 revs = [repo[node].rev() for node in nodes]
3086 except IOError, inst:
3087 except IOError, inst:
3087 if inst.errno != errno.ENOENT:
3088 if inst.errno != errno.ENOENT:
3088 raise
3089 raise
3089 raise util.Abort(_("no graft state found, can't continue"))
3090 raise util.Abort(_("no graft state found, can't continue"))
3090 else:
3091 else:
3091 cmdutil.checkunfinished(repo)
3092 cmdutil.checkunfinished(repo)
3092 cmdutil.bailifchanged(repo)
3093 cmdutil.bailifchanged(repo)
3093 if not revs:
3094 if not revs:
3094 raise util.Abort(_('no revisions specified'))
3095 raise util.Abort(_('no revisions specified'))
3095 revs = scmutil.revrange(repo, revs)
3096 revs = scmutil.revrange(repo, revs)
3096
3097
3097 # check for merges
3098 # check for merges
3098 for rev in repo.revs('%ld and merge()', revs):
3099 for rev in repo.revs('%ld and merge()', revs):
3099 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3100 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3100 revs.remove(rev)
3101 revs.remove(rev)
3101 if not revs:
3102 if not revs:
3102 return -1
3103 return -1
3103
3104
3104 # check for ancestors of dest branch
3105 # check for ancestors of dest branch
3105 crev = repo['.'].rev()
3106 crev = repo['.'].rev()
3106 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3107 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3107 # Cannot use x.remove(y) on smart set, this has to be a list.
3108 # Cannot use x.remove(y) on smart set, this has to be a list.
3108 # XXX make this lazy in the future
3109 # XXX make this lazy in the future
3109 revs = list(revs)
3110 revs = list(revs)
3110 # don't mutate while iterating, create a copy
3111 # don't mutate while iterating, create a copy
3111 for rev in list(revs):
3112 for rev in list(revs):
3112 if rev in ancestors:
3113 if rev in ancestors:
3113 ui.warn(_('skipping ancestor revision %s\n') % rev)
3114 ui.warn(_('skipping ancestor revision %s\n') % rev)
3114 # XXX remove on list is slow
3115 # XXX remove on list is slow
3115 revs.remove(rev)
3116 revs.remove(rev)
3116 if not revs:
3117 if not revs:
3117 return -1
3118 return -1
3118
3119
3119 # analyze revs for earlier grafts
3120 # analyze revs for earlier grafts
3120 ids = {}
3121 ids = {}
3121 for ctx in repo.set("%ld", revs):
3122 for ctx in repo.set("%ld", revs):
3122 ids[ctx.hex()] = ctx.rev()
3123 ids[ctx.hex()] = ctx.rev()
3123 n = ctx.extra().get('source')
3124 n = ctx.extra().get('source')
3124 if n:
3125 if n:
3125 ids[n] = ctx.rev()
3126 ids[n] = ctx.rev()
3126
3127
3127 # check ancestors for earlier grafts
3128 # check ancestors for earlier grafts
3128 ui.debug('scanning for duplicate grafts\n')
3129 ui.debug('scanning for duplicate grafts\n')
3129
3130
3130 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3131 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3131 ctx = repo[rev]
3132 ctx = repo[rev]
3132 n = ctx.extra().get('source')
3133 n = ctx.extra().get('source')
3133 if n in ids:
3134 if n in ids:
3134 r = repo[n].rev()
3135 r = repo[n].rev()
3135 if r in revs:
3136 if r in revs:
3136 ui.warn(_('skipping revision %s (already grafted to %s)\n')
3137 ui.warn(_('skipping revision %s (already grafted to %s)\n')
3137 % (r, rev))
3138 % (r, rev))
3138 revs.remove(r)
3139 revs.remove(r)
3139 elif ids[n] in revs:
3140 elif ids[n] in revs:
3140 ui.warn(_('skipping already grafted revision %s '
3141 ui.warn(_('skipping already grafted revision %s '
3141 '(%s also has origin %d)\n') % (ids[n], rev, r))
3142 '(%s also has origin %d)\n') % (ids[n], rev, r))
3142 revs.remove(ids[n])
3143 revs.remove(ids[n])
3143 elif ctx.hex() in ids:
3144 elif ctx.hex() in ids:
3144 r = ids[ctx.hex()]
3145 r = ids[ctx.hex()]
3145 ui.warn(_('skipping already grafted revision %s '
3146 ui.warn(_('skipping already grafted revision %s '
3146 '(was grafted from %d)\n') % (r, rev))
3147 '(was grafted from %d)\n') % (r, rev))
3147 revs.remove(r)
3148 revs.remove(r)
3148 if not revs:
3149 if not revs:
3149 return -1
3150 return -1
3150
3151
3151 wlock = repo.wlock()
3152 wlock = repo.wlock()
3152 try:
3153 try:
3153 current = repo['.']
3154 current = repo['.']
3154 for pos, ctx in enumerate(repo.set("%ld", revs)):
3155 for pos, ctx in enumerate(repo.set("%ld", revs)):
3155
3156
3156 ui.status(_('grafting revision %s\n') % ctx.rev())
3157 ui.status(_('grafting revision %s\n') % ctx.rev())
3157 if opts.get('dry_run'):
3158 if opts.get('dry_run'):
3158 continue
3159 continue
3159
3160
3160 source = ctx.extra().get('source')
3161 source = ctx.extra().get('source')
3161 if not source:
3162 if not source:
3162 source = ctx.hex()
3163 source = ctx.hex()
3163 extra = {'source': source}
3164 extra = {'source': source}
3164 user = ctx.user()
3165 user = ctx.user()
3165 if opts.get('user'):
3166 if opts.get('user'):
3166 user = opts['user']
3167 user = opts['user']
3167 date = ctx.date()
3168 date = ctx.date()
3168 if opts.get('date'):
3169 if opts.get('date'):
3169 date = opts['date']
3170 date = opts['date']
3170 message = ctx.description()
3171 message = ctx.description()
3171 if opts.get('log'):
3172 if opts.get('log'):
3172 message += '\n(grafted from %s)' % ctx.hex()
3173 message += '\n(grafted from %s)' % ctx.hex()
3173
3174
3174 # we don't merge the first commit when continuing
3175 # we don't merge the first commit when continuing
3175 if not cont:
3176 if not cont:
3176 # perform the graft merge with p1(rev) as 'ancestor'
3177 # perform the graft merge with p1(rev) as 'ancestor'
3177 try:
3178 try:
3178 # ui.forcemerge is an internal variable, do not document
3179 # ui.forcemerge is an internal variable, do not document
3179 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3180 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
3180 'graft')
3181 'graft')
3181 stats = mergemod.update(repo, ctx.node(), True, True, False,
3182 stats = mergemod.update(repo, ctx.node(), True, True, False,
3182 ctx.p1().node(),
3183 ctx.p1().node(),
3183 labels=['local', 'graft'])
3184 labels=['local', 'graft'])
3184 finally:
3185 finally:
3185 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3186 repo.ui.setconfig('ui', 'forcemerge', '', 'graft')
3186 # report any conflicts
3187 # report any conflicts
3187 if stats and stats[3] > 0:
3188 if stats and stats[3] > 0:
3188 # write out state for --continue
3189 # write out state for --continue
3189 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3190 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3190 repo.opener.write('graftstate', ''.join(nodelines))
3191 repo.opener.write('graftstate', ''.join(nodelines))
3191 raise util.Abort(
3192 raise util.Abort(
3192 _("unresolved conflicts, can't continue"),
3193 _("unresolved conflicts, can't continue"),
3193 hint=_('use hg resolve and hg graft --continue'))
3194 hint=_('use hg resolve and hg graft --continue'))
3194 else:
3195 else:
3195 cont = False
3196 cont = False
3196
3197
3197 # drop the second merge parent
3198 # drop the second merge parent
3198 repo.setparents(current.node(), nullid)
3199 repo.setparents(current.node(), nullid)
3199 repo.dirstate.write()
3200 repo.dirstate.write()
3200 # fix up dirstate for copies and renames
3201 # fix up dirstate for copies and renames
3201 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
3202 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
3202
3203
3203 # commit
3204 # commit
3204 node = repo.commit(text=message, user=user,
3205 node = repo.commit(text=message, user=user,
3205 date=date, extra=extra, editor=editor)
3206 date=date, extra=extra, editor=editor)
3206 if node is None:
3207 if node is None:
3207 ui.status(_('graft for revision %s is empty\n') % ctx.rev())
3208 ui.status(_('graft for revision %s is empty\n') % ctx.rev())
3208 else:
3209 else:
3209 current = repo[node]
3210 current = repo[node]
3210 finally:
3211 finally:
3211 wlock.release()
3212 wlock.release()
3212
3213
3213 # remove state when we complete successfully
3214 # remove state when we complete successfully
3214 if not opts.get('dry_run'):
3215 if not opts.get('dry_run'):
3215 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3216 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3216
3217
3217 return 0
3218 return 0
3218
3219
3219 @command('grep',
3220 @command('grep',
3220 [('0', 'print0', None, _('end fields with NUL')),
3221 [('0', 'print0', None, _('end fields with NUL')),
3221 ('', 'all', None, _('print all revisions that match')),
3222 ('', 'all', None, _('print all revisions that match')),
3222 ('a', 'text', None, _('treat all files as text')),
3223 ('a', 'text', None, _('treat all files as text')),
3223 ('f', 'follow', None,
3224 ('f', 'follow', None,
3224 _('follow changeset history,'
3225 _('follow changeset history,'
3225 ' or file history across copies and renames')),
3226 ' or file history across copies and renames')),
3226 ('i', 'ignore-case', None, _('ignore case when matching')),
3227 ('i', 'ignore-case', None, _('ignore case when matching')),
3227 ('l', 'files-with-matches', None,
3228 ('l', 'files-with-matches', None,
3228 _('print only filenames and revisions that match')),
3229 _('print only filenames and revisions that match')),
3229 ('n', 'line-number', None, _('print matching line numbers')),
3230 ('n', 'line-number', None, _('print matching line numbers')),
3230 ('r', 'rev', [],
3231 ('r', 'rev', [],
3231 _('only search files changed within revision range'), _('REV')),
3232 _('only search files changed within revision range'), _('REV')),
3232 ('u', 'user', None, _('list the author (long with -v)')),
3233 ('u', 'user', None, _('list the author (long with -v)')),
3233 ('d', 'date', None, _('list the date (short with -q)')),
3234 ('d', 'date', None, _('list the date (short with -q)')),
3234 ] + walkopts,
3235 ] + walkopts,
3235 _('[OPTION]... PATTERN [FILE]...'))
3236 _('[OPTION]... PATTERN [FILE]...'))
3236 def grep(ui, repo, pattern, *pats, **opts):
3237 def grep(ui, repo, pattern, *pats, **opts):
3237 """search for a pattern in specified files and revisions
3238 """search for a pattern in specified files and revisions
3238
3239
3239 Search revisions of files for a regular expression.
3240 Search revisions of files for a regular expression.
3240
3241
3241 This command behaves differently than Unix grep. It only accepts
3242 This command behaves differently than Unix grep. It only accepts
3242 Python/Perl regexps. It searches repository history, not the
3243 Python/Perl regexps. It searches repository history, not the
3243 working directory. It always prints the revision number in which a
3244 working directory. It always prints the revision number in which a
3244 match appears.
3245 match appears.
3245
3246
3246 By default, grep only prints output for the first revision of a
3247 By default, grep only prints output for the first revision of a
3247 file in which it finds a match. To get it to print every revision
3248 file in which it finds a match. To get it to print every revision
3248 that contains a change in match status ("-" for a match that
3249 that contains a change in match status ("-" for a match that
3249 becomes a non-match, or "+" for a non-match that becomes a match),
3250 becomes a non-match, or "+" for a non-match that becomes a match),
3250 use the --all flag.
3251 use the --all flag.
3251
3252
3252 Returns 0 if a match is found, 1 otherwise.
3253 Returns 0 if a match is found, 1 otherwise.
3253 """
3254 """
3254 reflags = re.M
3255 reflags = re.M
3255 if opts.get('ignore_case'):
3256 if opts.get('ignore_case'):
3256 reflags |= re.I
3257 reflags |= re.I
3257 try:
3258 try:
3258 regexp = util.compilere(pattern, reflags)
3259 regexp = util.compilere(pattern, reflags)
3259 except re.error, inst:
3260 except re.error, inst:
3260 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3261 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3261 return 1
3262 return 1
3262 sep, eol = ':', '\n'
3263 sep, eol = ':', '\n'
3263 if opts.get('print0'):
3264 if opts.get('print0'):
3264 sep = eol = '\0'
3265 sep = eol = '\0'
3265
3266
3266 getfile = util.lrucachefunc(repo.file)
3267 getfile = util.lrucachefunc(repo.file)
3267
3268
3268 def matchlines(body):
3269 def matchlines(body):
3269 begin = 0
3270 begin = 0
3270 linenum = 0
3271 linenum = 0
3271 while begin < len(body):
3272 while begin < len(body):
3272 match = regexp.search(body, begin)
3273 match = regexp.search(body, begin)
3273 if not match:
3274 if not match:
3274 break
3275 break
3275 mstart, mend = match.span()
3276 mstart, mend = match.span()
3276 linenum += body.count('\n', begin, mstart) + 1
3277 linenum += body.count('\n', begin, mstart) + 1
3277 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3278 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3278 begin = body.find('\n', mend) + 1 or len(body) + 1
3279 begin = body.find('\n', mend) + 1 or len(body) + 1
3279 lend = begin - 1
3280 lend = begin - 1
3280 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3281 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3281
3282
3282 class linestate(object):
3283 class linestate(object):
3283 def __init__(self, line, linenum, colstart, colend):
3284 def __init__(self, line, linenum, colstart, colend):
3284 self.line = line
3285 self.line = line
3285 self.linenum = linenum
3286 self.linenum = linenum
3286 self.colstart = colstart
3287 self.colstart = colstart
3287 self.colend = colend
3288 self.colend = colend
3288
3289
3289 def __hash__(self):
3290 def __hash__(self):
3290 return hash((self.linenum, self.line))
3291 return hash((self.linenum, self.line))
3291
3292
3292 def __eq__(self, other):
3293 def __eq__(self, other):
3293 return self.line == other.line
3294 return self.line == other.line
3294
3295
3295 def __iter__(self):
3296 def __iter__(self):
3296 yield (self.line[:self.colstart], '')
3297 yield (self.line[:self.colstart], '')
3297 yield (self.line[self.colstart:self.colend], 'grep.match')
3298 yield (self.line[self.colstart:self.colend], 'grep.match')
3298 rest = self.line[self.colend:]
3299 rest = self.line[self.colend:]
3299 while rest != '':
3300 while rest != '':
3300 match = regexp.search(rest)
3301 match = regexp.search(rest)
3301 if not match:
3302 if not match:
3302 yield (rest, '')
3303 yield (rest, '')
3303 break
3304 break
3304 mstart, mend = match.span()
3305 mstart, mend = match.span()
3305 yield (rest[:mstart], '')
3306 yield (rest[:mstart], '')
3306 yield (rest[mstart:mend], 'grep.match')
3307 yield (rest[mstart:mend], 'grep.match')
3307 rest = rest[mend:]
3308 rest = rest[mend:]
3308
3309
3309 matches = {}
3310 matches = {}
3310 copies = {}
3311 copies = {}
3311 def grepbody(fn, rev, body):
3312 def grepbody(fn, rev, body):
3312 matches[rev].setdefault(fn, [])
3313 matches[rev].setdefault(fn, [])
3313 m = matches[rev][fn]
3314 m = matches[rev][fn]
3314 for lnum, cstart, cend, line in matchlines(body):
3315 for lnum, cstart, cend, line in matchlines(body):
3315 s = linestate(line, lnum, cstart, cend)
3316 s = linestate(line, lnum, cstart, cend)
3316 m.append(s)
3317 m.append(s)
3317
3318
3318 def difflinestates(a, b):
3319 def difflinestates(a, b):
3319 sm = difflib.SequenceMatcher(None, a, b)
3320 sm = difflib.SequenceMatcher(None, a, b)
3320 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3321 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3321 if tag == 'insert':
3322 if tag == 'insert':
3322 for i in xrange(blo, bhi):
3323 for i in xrange(blo, bhi):
3323 yield ('+', b[i])
3324 yield ('+', b[i])
3324 elif tag == 'delete':
3325 elif tag == 'delete':
3325 for i in xrange(alo, ahi):
3326 for i in xrange(alo, ahi):
3326 yield ('-', a[i])
3327 yield ('-', a[i])
3327 elif tag == 'replace':
3328 elif tag == 'replace':
3328 for i in xrange(alo, ahi):
3329 for i in xrange(alo, ahi):
3329 yield ('-', a[i])
3330 yield ('-', a[i])
3330 for i in xrange(blo, bhi):
3331 for i in xrange(blo, bhi):
3331 yield ('+', b[i])
3332 yield ('+', b[i])
3332
3333
3333 def display(fn, ctx, pstates, states):
3334 def display(fn, ctx, pstates, states):
3334 rev = ctx.rev()
3335 rev = ctx.rev()
3335 datefunc = ui.quiet and util.shortdate or util.datestr
3336 datefunc = ui.quiet and util.shortdate or util.datestr
3336 found = False
3337 found = False
3337 @util.cachefunc
3338 @util.cachefunc
3338 def binary():
3339 def binary():
3339 flog = getfile(fn)
3340 flog = getfile(fn)
3340 return util.binary(flog.read(ctx.filenode(fn)))
3341 return util.binary(flog.read(ctx.filenode(fn)))
3341
3342
3342 if opts.get('all'):
3343 if opts.get('all'):
3343 iter = difflinestates(pstates, states)
3344 iter = difflinestates(pstates, states)
3344 else:
3345 else:
3345 iter = [('', l) for l in states]
3346 iter = [('', l) for l in states]
3346 for change, l in iter:
3347 for change, l in iter:
3347 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3348 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3348
3349
3349 if opts.get('line_number'):
3350 if opts.get('line_number'):
3350 cols.append((str(l.linenum), 'grep.linenumber'))
3351 cols.append((str(l.linenum), 'grep.linenumber'))
3351 if opts.get('all'):
3352 if opts.get('all'):
3352 cols.append((change, 'grep.change'))
3353 cols.append((change, 'grep.change'))
3353 if opts.get('user'):
3354 if opts.get('user'):
3354 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3355 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3355 if opts.get('date'):
3356 if opts.get('date'):
3356 cols.append((datefunc(ctx.date()), 'grep.date'))
3357 cols.append((datefunc(ctx.date()), 'grep.date'))
3357 for col, label in cols[:-1]:
3358 for col, label in cols[:-1]:
3358 ui.write(col, label=label)
3359 ui.write(col, label=label)
3359 ui.write(sep, label='grep.sep')
3360 ui.write(sep, label='grep.sep')
3360 ui.write(cols[-1][0], label=cols[-1][1])
3361 ui.write(cols[-1][0], label=cols[-1][1])
3361 if not opts.get('files_with_matches'):
3362 if not opts.get('files_with_matches'):
3362 ui.write(sep, label='grep.sep')
3363 ui.write(sep, label='grep.sep')
3363 if not opts.get('text') and binary():
3364 if not opts.get('text') and binary():
3364 ui.write(" Binary file matches")
3365 ui.write(" Binary file matches")
3365 else:
3366 else:
3366 for s, label in l:
3367 for s, label in l:
3367 ui.write(s, label=label)
3368 ui.write(s, label=label)
3368 ui.write(eol)
3369 ui.write(eol)
3369 found = True
3370 found = True
3370 if opts.get('files_with_matches'):
3371 if opts.get('files_with_matches'):
3371 break
3372 break
3372 return found
3373 return found
3373
3374
3374 skip = {}
3375 skip = {}
3375 revfiles = {}
3376 revfiles = {}
3376 matchfn = scmutil.match(repo[None], pats, opts)
3377 matchfn = scmutil.match(repo[None], pats, opts)
3377 found = False
3378 found = False
3378 follow = opts.get('follow')
3379 follow = opts.get('follow')
3379
3380
3380 def prep(ctx, fns):
3381 def prep(ctx, fns):
3381 rev = ctx.rev()
3382 rev = ctx.rev()
3382 pctx = ctx.p1()
3383 pctx = ctx.p1()
3383 parent = pctx.rev()
3384 parent = pctx.rev()
3384 matches.setdefault(rev, {})
3385 matches.setdefault(rev, {})
3385 matches.setdefault(parent, {})
3386 matches.setdefault(parent, {})
3386 files = revfiles.setdefault(rev, [])
3387 files = revfiles.setdefault(rev, [])
3387 for fn in fns:
3388 for fn in fns:
3388 flog = getfile(fn)
3389 flog = getfile(fn)
3389 try:
3390 try:
3390 fnode = ctx.filenode(fn)
3391 fnode = ctx.filenode(fn)
3391 except error.LookupError:
3392 except error.LookupError:
3392 continue
3393 continue
3393
3394
3394 copied = flog.renamed(fnode)
3395 copied = flog.renamed(fnode)
3395 copy = follow and copied and copied[0]
3396 copy = follow and copied and copied[0]
3396 if copy:
3397 if copy:
3397 copies.setdefault(rev, {})[fn] = copy
3398 copies.setdefault(rev, {})[fn] = copy
3398 if fn in skip:
3399 if fn in skip:
3399 if copy:
3400 if copy:
3400 skip[copy] = True
3401 skip[copy] = True
3401 continue
3402 continue
3402 files.append(fn)
3403 files.append(fn)
3403
3404
3404 if fn not in matches[rev]:
3405 if fn not in matches[rev]:
3405 grepbody(fn, rev, flog.read(fnode))
3406 grepbody(fn, rev, flog.read(fnode))
3406
3407
3407 pfn = copy or fn
3408 pfn = copy or fn
3408 if pfn not in matches[parent]:
3409 if pfn not in matches[parent]:
3409 try:
3410 try:
3410 fnode = pctx.filenode(pfn)
3411 fnode = pctx.filenode(pfn)
3411 grepbody(pfn, parent, flog.read(fnode))
3412 grepbody(pfn, parent, flog.read(fnode))
3412 except error.LookupError:
3413 except error.LookupError:
3413 pass
3414 pass
3414
3415
3415 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3416 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3416 rev = ctx.rev()
3417 rev = ctx.rev()
3417 parent = ctx.p1().rev()
3418 parent = ctx.p1().rev()
3418 for fn in sorted(revfiles.get(rev, [])):
3419 for fn in sorted(revfiles.get(rev, [])):
3419 states = matches[rev][fn]
3420 states = matches[rev][fn]
3420 copy = copies.get(rev, {}).get(fn)
3421 copy = copies.get(rev, {}).get(fn)
3421 if fn in skip:
3422 if fn in skip:
3422 if copy:
3423 if copy:
3423 skip[copy] = True
3424 skip[copy] = True
3424 continue
3425 continue
3425 pstates = matches.get(parent, {}).get(copy or fn, [])
3426 pstates = matches.get(parent, {}).get(copy or fn, [])
3426 if pstates or states:
3427 if pstates or states:
3427 r = display(fn, ctx, pstates, states)
3428 r = display(fn, ctx, pstates, states)
3428 found = found or r
3429 found = found or r
3429 if r and not opts.get('all'):
3430 if r and not opts.get('all'):
3430 skip[fn] = True
3431 skip[fn] = True
3431 if copy:
3432 if copy:
3432 skip[copy] = True
3433 skip[copy] = True
3433 del matches[rev]
3434 del matches[rev]
3434 del revfiles[rev]
3435 del revfiles[rev]
3435
3436
3436 return not found
3437 return not found
3437
3438
3438 @command('heads',
3439 @command('heads',
3439 [('r', 'rev', '',
3440 [('r', 'rev', '',
3440 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3441 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3441 ('t', 'topo', False, _('show topological heads only')),
3442 ('t', 'topo', False, _('show topological heads only')),
3442 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3443 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3443 ('c', 'closed', False, _('show normal and closed branch heads')),
3444 ('c', 'closed', False, _('show normal and closed branch heads')),
3444 ] + templateopts,
3445 ] + templateopts,
3445 _('[-ct] [-r STARTREV] [REV]...'))
3446 _('[-ct] [-r STARTREV] [REV]...'))
3446 def heads(ui, repo, *branchrevs, **opts):
3447 def heads(ui, repo, *branchrevs, **opts):
3447 """show branch heads
3448 """show branch heads
3448
3449
3449 With no arguments, show all open branch heads in the repository.
3450 With no arguments, show all open branch heads in the repository.
3450 Branch heads are changesets that have no descendants on the
3451 Branch heads are changesets that have no descendants on the
3451 same branch. They are where development generally takes place and
3452 same branch. They are where development generally takes place and
3452 are the usual targets for update and merge operations.
3453 are the usual targets for update and merge operations.
3453
3454
3454 If one or more REVs are given, only open branch heads on the
3455 If one or more REVs are given, only open branch heads on the
3455 branches associated with the specified changesets are shown. This
3456 branches associated with the specified changesets are shown. This
3456 means that you can use :hg:`heads .` to see the heads on the
3457 means that you can use :hg:`heads .` to see the heads on the
3457 currently checked-out branch.
3458 currently checked-out branch.
3458
3459
3459 If -c/--closed is specified, also show branch heads marked closed
3460 If -c/--closed is specified, also show branch heads marked closed
3460 (see :hg:`commit --close-branch`).
3461 (see :hg:`commit --close-branch`).
3461
3462
3462 If STARTREV is specified, only those heads that are descendants of
3463 If STARTREV is specified, only those heads that are descendants of
3463 STARTREV will be displayed.
3464 STARTREV will be displayed.
3464
3465
3465 If -t/--topo is specified, named branch mechanics will be ignored and only
3466 If -t/--topo is specified, named branch mechanics will be ignored and only
3466 topological heads (changesets with no children) will be shown.
3467 topological heads (changesets with no children) will be shown.
3467
3468
3468 Returns 0 if matching heads are found, 1 if not.
3469 Returns 0 if matching heads are found, 1 if not.
3469 """
3470 """
3470
3471
3471 start = None
3472 start = None
3472 if 'rev' in opts:
3473 if 'rev' in opts:
3473 start = scmutil.revsingle(repo, opts['rev'], None).node()
3474 start = scmutil.revsingle(repo, opts['rev'], None).node()
3474
3475
3475 if opts.get('topo'):
3476 if opts.get('topo'):
3476 heads = [repo[h] for h in repo.heads(start)]
3477 heads = [repo[h] for h in repo.heads(start)]
3477 else:
3478 else:
3478 heads = []
3479 heads = []
3479 for branch in repo.branchmap():
3480 for branch in repo.branchmap():
3480 heads += repo.branchheads(branch, start, opts.get('closed'))
3481 heads += repo.branchheads(branch, start, opts.get('closed'))
3481 heads = [repo[h] for h in heads]
3482 heads = [repo[h] for h in heads]
3482
3483
3483 if branchrevs:
3484 if branchrevs:
3484 branches = set(repo[br].branch() for br in branchrevs)
3485 branches = set(repo[br].branch() for br in branchrevs)
3485 heads = [h for h in heads if h.branch() in branches]
3486 heads = [h for h in heads if h.branch() in branches]
3486
3487
3487 if opts.get('active') and branchrevs:
3488 if opts.get('active') and branchrevs:
3488 dagheads = repo.heads(start)
3489 dagheads = repo.heads(start)
3489 heads = [h for h in heads if h.node() in dagheads]
3490 heads = [h for h in heads if h.node() in dagheads]
3490
3491
3491 if branchrevs:
3492 if branchrevs:
3492 haveheads = set(h.branch() for h in heads)
3493 haveheads = set(h.branch() for h in heads)
3493 if branches - haveheads:
3494 if branches - haveheads:
3494 headless = ', '.join(b for b in branches - haveheads)
3495 headless = ', '.join(b for b in branches - haveheads)
3495 msg = _('no open branch heads found on branches %s')
3496 msg = _('no open branch heads found on branches %s')
3496 if opts.get('rev'):
3497 if opts.get('rev'):
3497 msg += _(' (started at %s)') % opts['rev']
3498 msg += _(' (started at %s)') % opts['rev']
3498 ui.warn((msg + '\n') % headless)
3499 ui.warn((msg + '\n') % headless)
3499
3500
3500 if not heads:
3501 if not heads:
3501 return 1
3502 return 1
3502
3503
3503 heads = sorted(heads, key=lambda x: -x.rev())
3504 heads = sorted(heads, key=lambda x: -x.rev())
3504 displayer = cmdutil.show_changeset(ui, repo, opts)
3505 displayer = cmdutil.show_changeset(ui, repo, opts)
3505 for ctx in heads:
3506 for ctx in heads:
3506 displayer.show(ctx)
3507 displayer.show(ctx)
3507 displayer.close()
3508 displayer.close()
3508
3509
3509 @command('help',
3510 @command('help',
3510 [('e', 'extension', None, _('show only help for extensions')),
3511 [('e', 'extension', None, _('show only help for extensions')),
3511 ('c', 'command', None, _('show only help for commands')),
3512 ('c', 'command', None, _('show only help for commands')),
3512 ('k', 'keyword', '', _('show topics matching keyword')),
3513 ('k', 'keyword', '', _('show topics matching keyword')),
3513 ],
3514 ],
3514 _('[-ec] [TOPIC]'))
3515 _('[-ec] [TOPIC]'))
3515 def help_(ui, name=None, **opts):
3516 def help_(ui, name=None, **opts):
3516 """show help for a given topic or a help overview
3517 """show help for a given topic or a help overview
3517
3518
3518 With no arguments, print a list of commands with short help messages.
3519 With no arguments, print a list of commands with short help messages.
3519
3520
3520 Given a topic, extension, or command name, print help for that
3521 Given a topic, extension, or command name, print help for that
3521 topic.
3522 topic.
3522
3523
3523 Returns 0 if successful.
3524 Returns 0 if successful.
3524 """
3525 """
3525
3526
3526 textwidth = min(ui.termwidth(), 80) - 2
3527 textwidth = min(ui.termwidth(), 80) - 2
3527
3528
3528 keep = ui.verbose and ['verbose'] or []
3529 keep = ui.verbose and ['verbose'] or []
3529 text = help.help_(ui, name, **opts)
3530 text = help.help_(ui, name, **opts)
3530
3531
3531 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3532 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3532 if 'verbose' in pruned:
3533 if 'verbose' in pruned:
3533 keep.append('omitted')
3534 keep.append('omitted')
3534 else:
3535 else:
3535 keep.append('notomitted')
3536 keep.append('notomitted')
3536 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3537 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3537 ui.write(formatted)
3538 ui.write(formatted)
3538
3539
3539
3540
3540 @command('identify|id',
3541 @command('identify|id',
3541 [('r', 'rev', '',
3542 [('r', 'rev', '',
3542 _('identify the specified revision'), _('REV')),
3543 _('identify the specified revision'), _('REV')),
3543 ('n', 'num', None, _('show local revision number')),
3544 ('n', 'num', None, _('show local revision number')),
3544 ('i', 'id', None, _('show global revision id')),
3545 ('i', 'id', None, _('show global revision id')),
3545 ('b', 'branch', None, _('show branch')),
3546 ('b', 'branch', None, _('show branch')),
3546 ('t', 'tags', None, _('show tags')),
3547 ('t', 'tags', None, _('show tags')),
3547 ('B', 'bookmarks', None, _('show bookmarks')),
3548 ('B', 'bookmarks', None, _('show bookmarks')),
3548 ] + remoteopts,
3549 ] + remoteopts,
3549 _('[-nibtB] [-r REV] [SOURCE]'))
3550 _('[-nibtB] [-r REV] [SOURCE]'))
3550 def identify(ui, repo, source=None, rev=None,
3551 def identify(ui, repo, source=None, rev=None,
3551 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3552 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3552 """identify the working copy or specified revision
3553 """identify the working copy or specified revision
3553
3554
3554 Print a summary identifying the repository state at REV using one or
3555 Print a summary identifying the repository state at REV using one or
3555 two parent hash identifiers, followed by a "+" if the working
3556 two parent hash identifiers, followed by a "+" if the working
3556 directory has uncommitted changes, the branch name (if not default),
3557 directory has uncommitted changes, the branch name (if not default),
3557 a list of tags, and a list of bookmarks.
3558 a list of tags, and a list of bookmarks.
3558
3559
3559 When REV is not given, print a summary of the current state of the
3560 When REV is not given, print a summary of the current state of the
3560 repository.
3561 repository.
3561
3562
3562 Specifying a path to a repository root or Mercurial bundle will
3563 Specifying a path to a repository root or Mercurial bundle will
3563 cause lookup to operate on that repository/bundle.
3564 cause lookup to operate on that repository/bundle.
3564
3565
3565 .. container:: verbose
3566 .. container:: verbose
3566
3567
3567 Examples:
3568 Examples:
3568
3569
3569 - generate a build identifier for the working directory::
3570 - generate a build identifier for the working directory::
3570
3571
3571 hg id --id > build-id.dat
3572 hg id --id > build-id.dat
3572
3573
3573 - find the revision corresponding to a tag::
3574 - find the revision corresponding to a tag::
3574
3575
3575 hg id -n -r 1.3
3576 hg id -n -r 1.3
3576
3577
3577 - check the most recent revision of a remote repository::
3578 - check the most recent revision of a remote repository::
3578
3579
3579 hg id -r tip http://selenic.com/hg/
3580 hg id -r tip http://selenic.com/hg/
3580
3581
3581 Returns 0 if successful.
3582 Returns 0 if successful.
3582 """
3583 """
3583
3584
3584 if not repo and not source:
3585 if not repo and not source:
3585 raise util.Abort(_("there is no Mercurial repository here "
3586 raise util.Abort(_("there is no Mercurial repository here "
3586 "(.hg not found)"))
3587 "(.hg not found)"))
3587
3588
3588 hexfunc = ui.debugflag and hex or short
3589 hexfunc = ui.debugflag and hex or short
3589 default = not (num or id or branch or tags or bookmarks)
3590 default = not (num or id or branch or tags or bookmarks)
3590 output = []
3591 output = []
3591 revs = []
3592 revs = []
3592
3593
3593 if source:
3594 if source:
3594 source, branches = hg.parseurl(ui.expandpath(source))
3595 source, branches = hg.parseurl(ui.expandpath(source))
3595 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3596 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3596 repo = peer.local()
3597 repo = peer.local()
3597 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3598 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3598
3599
3599 if not repo:
3600 if not repo:
3600 if num or branch or tags:
3601 if num or branch or tags:
3601 raise util.Abort(
3602 raise util.Abort(
3602 _("can't query remote revision number, branch, or tags"))
3603 _("can't query remote revision number, branch, or tags"))
3603 if not rev and revs:
3604 if not rev and revs:
3604 rev = revs[0]
3605 rev = revs[0]
3605 if not rev:
3606 if not rev:
3606 rev = "tip"
3607 rev = "tip"
3607
3608
3608 remoterev = peer.lookup(rev)
3609 remoterev = peer.lookup(rev)
3609 if default or id:
3610 if default or id:
3610 output = [hexfunc(remoterev)]
3611 output = [hexfunc(remoterev)]
3611
3612
3612 def getbms():
3613 def getbms():
3613 bms = []
3614 bms = []
3614
3615
3615 if 'bookmarks' in peer.listkeys('namespaces'):
3616 if 'bookmarks' in peer.listkeys('namespaces'):
3616 hexremoterev = hex(remoterev)
3617 hexremoterev = hex(remoterev)
3617 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3618 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3618 if bmr == hexremoterev]
3619 if bmr == hexremoterev]
3619
3620
3620 return sorted(bms)
3621 return sorted(bms)
3621
3622
3622 if bookmarks:
3623 if bookmarks:
3623 output.extend(getbms())
3624 output.extend(getbms())
3624 elif default and not ui.quiet:
3625 elif default and not ui.quiet:
3625 # multiple bookmarks for a single parent separated by '/'
3626 # multiple bookmarks for a single parent separated by '/'
3626 bm = '/'.join(getbms())
3627 bm = '/'.join(getbms())
3627 if bm:
3628 if bm:
3628 output.append(bm)
3629 output.append(bm)
3629 else:
3630 else:
3630 if not rev:
3631 if not rev:
3631 ctx = repo[None]
3632 ctx = repo[None]
3632 parents = ctx.parents()
3633 parents = ctx.parents()
3633 changed = ""
3634 changed = ""
3634 if default or id or num:
3635 if default or id or num:
3635 if (util.any(repo.status())
3636 if (util.any(repo.status())
3636 or util.any(ctx.sub(s).dirty() for s in ctx.substate)):
3637 or util.any(ctx.sub(s).dirty() for s in ctx.substate)):
3637 changed = '+'
3638 changed = '+'
3638 if default or id:
3639 if default or id:
3639 output = ["%s%s" %
3640 output = ["%s%s" %
3640 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3641 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3641 if num:
3642 if num:
3642 output.append("%s%s" %
3643 output.append("%s%s" %
3643 ('+'.join([str(p.rev()) for p in parents]), changed))
3644 ('+'.join([str(p.rev()) for p in parents]), changed))
3644 else:
3645 else:
3645 ctx = scmutil.revsingle(repo, rev)
3646 ctx = scmutil.revsingle(repo, rev)
3646 if default or id:
3647 if default or id:
3647 output = [hexfunc(ctx.node())]
3648 output = [hexfunc(ctx.node())]
3648 if num:
3649 if num:
3649 output.append(str(ctx.rev()))
3650 output.append(str(ctx.rev()))
3650
3651
3651 if default and not ui.quiet:
3652 if default and not ui.quiet:
3652 b = ctx.branch()
3653 b = ctx.branch()
3653 if b != 'default':
3654 if b != 'default':
3654 output.append("(%s)" % b)
3655 output.append("(%s)" % b)
3655
3656
3656 # multiple tags for a single parent separated by '/'
3657 # multiple tags for a single parent separated by '/'
3657 t = '/'.join(ctx.tags())
3658 t = '/'.join(ctx.tags())
3658 if t:
3659 if t:
3659 output.append(t)
3660 output.append(t)
3660
3661
3661 # multiple bookmarks for a single parent separated by '/'
3662 # multiple bookmarks for a single parent separated by '/'
3662 bm = '/'.join(ctx.bookmarks())
3663 bm = '/'.join(ctx.bookmarks())
3663 if bm:
3664 if bm:
3664 output.append(bm)
3665 output.append(bm)
3665 else:
3666 else:
3666 if branch:
3667 if branch:
3667 output.append(ctx.branch())
3668 output.append(ctx.branch())
3668
3669
3669 if tags:
3670 if tags:
3670 output.extend(ctx.tags())
3671 output.extend(ctx.tags())
3671
3672
3672 if bookmarks:
3673 if bookmarks:
3673 output.extend(ctx.bookmarks())
3674 output.extend(ctx.bookmarks())
3674
3675
3675 ui.write("%s\n" % ' '.join(output))
3676 ui.write("%s\n" % ' '.join(output))
3676
3677
3677 @command('import|patch',
3678 @command('import|patch',
3678 [('p', 'strip', 1,
3679 [('p', 'strip', 1,
3679 _('directory strip option for patch. This has the same '
3680 _('directory strip option for patch. This has the same '
3680 'meaning as the corresponding patch option'), _('NUM')),
3681 'meaning as the corresponding patch option'), _('NUM')),
3681 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3682 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3682 ('e', 'edit', False, _('invoke editor on commit messages')),
3683 ('e', 'edit', False, _('invoke editor on commit messages')),
3683 ('f', 'force', None,
3684 ('f', 'force', None,
3684 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3685 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3685 ('', 'no-commit', None,
3686 ('', 'no-commit', None,
3686 _("don't commit, just update the working directory")),
3687 _("don't commit, just update the working directory")),
3687 ('', 'bypass', None,
3688 ('', 'bypass', None,
3688 _("apply patch without touching the working directory")),
3689 _("apply patch without touching the working directory")),
3689 ('', 'partial', None,
3690 ('', 'partial', None,
3690 _('commit even if some hunks fail')),
3691 _('commit even if some hunks fail')),
3691 ('', 'exact', None,
3692 ('', 'exact', None,
3692 _('apply patch to the nodes from which it was generated')),
3693 _('apply patch to the nodes from which it was generated')),
3693 ('', 'import-branch', None,
3694 ('', 'import-branch', None,
3694 _('use any branch information in patch (implied by --exact)'))] +
3695 _('use any branch information in patch (implied by --exact)'))] +
3695 commitopts + commitopts2 + similarityopts,
3696 commitopts + commitopts2 + similarityopts,
3696 _('[OPTION]... PATCH...'))
3697 _('[OPTION]... PATCH...'))
3697 def import_(ui, repo, patch1=None, *patches, **opts):
3698 def import_(ui, repo, patch1=None, *patches, **opts):
3698 """import an ordered set of patches
3699 """import an ordered set of patches
3699
3700
3700 Import a list of patches and commit them individually (unless
3701 Import a list of patches and commit them individually (unless
3701 --no-commit is specified).
3702 --no-commit is specified).
3702
3703
3703 Because import first applies changes to the working directory,
3704 Because import first applies changes to the working directory,
3704 import will abort if there are outstanding changes.
3705 import will abort if there are outstanding changes.
3705
3706
3706 You can import a patch straight from a mail message. Even patches
3707 You can import a patch straight from a mail message. Even patches
3707 as attachments work (to use the body part, it must have type
3708 as attachments work (to use the body part, it must have type
3708 text/plain or text/x-patch). From and Subject headers of email
3709 text/plain or text/x-patch). From and Subject headers of email
3709 message are used as default committer and commit message. All
3710 message are used as default committer and commit message. All
3710 text/plain body parts before first diff are added to commit
3711 text/plain body parts before first diff are added to commit
3711 message.
3712 message.
3712
3713
3713 If the imported patch was generated by :hg:`export`, user and
3714 If the imported patch was generated by :hg:`export`, user and
3714 description from patch override values from message headers and
3715 description from patch override values from message headers and
3715 body. Values given on command line with -m/--message and -u/--user
3716 body. Values given on command line with -m/--message and -u/--user
3716 override these.
3717 override these.
3717
3718
3718 If --exact is specified, import will set the working directory to
3719 If --exact is specified, import will set the working directory to
3719 the parent of each patch before applying it, and will abort if the
3720 the parent of each patch before applying it, and will abort if the
3720 resulting changeset has a different ID than the one recorded in
3721 resulting changeset has a different ID than the one recorded in
3721 the patch. This may happen due to character set problems or other
3722 the patch. This may happen due to character set problems or other
3722 deficiencies in the text patch format.
3723 deficiencies in the text patch format.
3723
3724
3724 Use --bypass to apply and commit patches directly to the
3725 Use --bypass to apply and commit patches directly to the
3725 repository, not touching the working directory. Without --exact,
3726 repository, not touching the working directory. Without --exact,
3726 patches will be applied on top of the working directory parent
3727 patches will be applied on top of the working directory parent
3727 revision.
3728 revision.
3728
3729
3729 With -s/--similarity, hg will attempt to discover renames and
3730 With -s/--similarity, hg will attempt to discover renames and
3730 copies in the patch in the same way as :hg:`addremove`.
3731 copies in the patch in the same way as :hg:`addremove`.
3731
3732
3732 Use --partial to ensure a changeset will be created from the patch
3733 Use --partial to ensure a changeset will be created from the patch
3733 even if some hunks fail to apply. Hunks that fail to apply will be
3734 even if some hunks fail to apply. Hunks that fail to apply will be
3734 written to a <target-file>.rej file. Conflicts can then be resolved
3735 written to a <target-file>.rej file. Conflicts can then be resolved
3735 by hand before :hg:`commit --amend` is run to update the created
3736 by hand before :hg:`commit --amend` is run to update the created
3736 changeset. This flag exists to let people import patches that
3737 changeset. This flag exists to let people import patches that
3737 partially apply without losing the associated metadata (author,
3738 partially apply without losing the associated metadata (author,
3738 date, description, ...), Note that when none of the hunk applies
3739 date, description, ...), Note that when none of the hunk applies
3739 cleanly, :hg:`import --partial` will create an empty changeset,
3740 cleanly, :hg:`import --partial` will create an empty changeset,
3740 importing only the patch metadata.
3741 importing only the patch metadata.
3741
3742
3742 To read a patch from standard input, use "-" as the patch name. If
3743 To read a patch from standard input, use "-" as the patch name. If
3743 a URL is specified, the patch will be downloaded from it.
3744 a URL is specified, the patch will be downloaded from it.
3744 See :hg:`help dates` for a list of formats valid for -d/--date.
3745 See :hg:`help dates` for a list of formats valid for -d/--date.
3745
3746
3746 .. container:: verbose
3747 .. container:: verbose
3747
3748
3748 Examples:
3749 Examples:
3749
3750
3750 - import a traditional patch from a website and detect renames::
3751 - import a traditional patch from a website and detect renames::
3751
3752
3752 hg import -s 80 http://example.com/bugfix.patch
3753 hg import -s 80 http://example.com/bugfix.patch
3753
3754
3754 - import a changeset from an hgweb server::
3755 - import a changeset from an hgweb server::
3755
3756
3756 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3757 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3757
3758
3758 - import all the patches in an Unix-style mbox::
3759 - import all the patches in an Unix-style mbox::
3759
3760
3760 hg import incoming-patches.mbox
3761 hg import incoming-patches.mbox
3761
3762
3762 - attempt to exactly restore an exported changeset (not always
3763 - attempt to exactly restore an exported changeset (not always
3763 possible)::
3764 possible)::
3764
3765
3765 hg import --exact proposed-fix.patch
3766 hg import --exact proposed-fix.patch
3766
3767
3767 Returns 0 on success, 1 on partial success (see --partial).
3768 Returns 0 on success, 1 on partial success (see --partial).
3768 """
3769 """
3769
3770
3770 if not patch1:
3771 if not patch1:
3771 raise util.Abort(_('need at least one patch to import'))
3772 raise util.Abort(_('need at least one patch to import'))
3772
3773
3773 patches = (patch1,) + patches
3774 patches = (patch1,) + patches
3774
3775
3775 date = opts.get('date')
3776 date = opts.get('date')
3776 if date:
3777 if date:
3777 opts['date'] = util.parsedate(date)
3778 opts['date'] = util.parsedate(date)
3778
3779
3779 update = not opts.get('bypass')
3780 update = not opts.get('bypass')
3780 if not update and opts.get('no_commit'):
3781 if not update and opts.get('no_commit'):
3781 raise util.Abort(_('cannot use --no-commit with --bypass'))
3782 raise util.Abort(_('cannot use --no-commit with --bypass'))
3782 try:
3783 try:
3783 sim = float(opts.get('similarity') or 0)
3784 sim = float(opts.get('similarity') or 0)
3784 except ValueError:
3785 except ValueError:
3785 raise util.Abort(_('similarity must be a number'))
3786 raise util.Abort(_('similarity must be a number'))
3786 if sim < 0 or sim > 100:
3787 if sim < 0 or sim > 100:
3787 raise util.Abort(_('similarity must be between 0 and 100'))
3788 raise util.Abort(_('similarity must be between 0 and 100'))
3788 if sim and not update:
3789 if sim and not update:
3789 raise util.Abort(_('cannot use --similarity with --bypass'))
3790 raise util.Abort(_('cannot use --similarity with --bypass'))
3790
3791
3791 if update:
3792 if update:
3792 cmdutil.checkunfinished(repo)
3793 cmdutil.checkunfinished(repo)
3793 if (opts.get('exact') or not opts.get('force')) and update:
3794 if (opts.get('exact') or not opts.get('force')) and update:
3794 cmdutil.bailifchanged(repo)
3795 cmdutil.bailifchanged(repo)
3795
3796
3796 base = opts["base"]
3797 base = opts["base"]
3797 wlock = lock = tr = None
3798 wlock = lock = tr = None
3798 msgs = []
3799 msgs = []
3799 ret = 0
3800 ret = 0
3800
3801
3801
3802
3802 try:
3803 try:
3803 try:
3804 try:
3804 wlock = repo.wlock()
3805 wlock = repo.wlock()
3805 if not opts.get('no_commit'):
3806 if not opts.get('no_commit'):
3806 lock = repo.lock()
3807 lock = repo.lock()
3807 tr = repo.transaction('import')
3808 tr = repo.transaction('import')
3808 parents = repo.parents()
3809 parents = repo.parents()
3809 for patchurl in patches:
3810 for patchurl in patches:
3810 if patchurl == '-':
3811 if patchurl == '-':
3811 ui.status(_('applying patch from stdin\n'))
3812 ui.status(_('applying patch from stdin\n'))
3812 patchfile = ui.fin
3813 patchfile = ui.fin
3813 patchurl = 'stdin' # for error message
3814 patchurl = 'stdin' # for error message
3814 else:
3815 else:
3815 patchurl = os.path.join(base, patchurl)
3816 patchurl = os.path.join(base, patchurl)
3816 ui.status(_('applying %s\n') % patchurl)
3817 ui.status(_('applying %s\n') % patchurl)
3817 patchfile = hg.openpath(ui, patchurl)
3818 patchfile = hg.openpath(ui, patchurl)
3818
3819
3819 haspatch = False
3820 haspatch = False
3820 for hunk in patch.split(patchfile):
3821 for hunk in patch.split(patchfile):
3821 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
3822 (msg, node, rej) = cmdutil.tryimportone(ui, repo, hunk,
3822 parents, opts,
3823 parents, opts,
3823 msgs, hg.clean)
3824 msgs, hg.clean)
3824 if msg:
3825 if msg:
3825 haspatch = True
3826 haspatch = True
3826 ui.note(msg + '\n')
3827 ui.note(msg + '\n')
3827 if update or opts.get('exact'):
3828 if update or opts.get('exact'):
3828 parents = repo.parents()
3829 parents = repo.parents()
3829 else:
3830 else:
3830 parents = [repo[node]]
3831 parents = [repo[node]]
3831 if rej:
3832 if rej:
3832 ui.write_err(_("patch applied partially\n"))
3833 ui.write_err(_("patch applied partially\n"))
3833 ui.write_err(("(fix the .rej files and run "
3834 ui.write_err(("(fix the .rej files and run "
3834 "`hg commit --amend`)\n"))
3835 "`hg commit --amend`)\n"))
3835 ret = 1
3836 ret = 1
3836 break
3837 break
3837
3838
3838 if not haspatch:
3839 if not haspatch:
3839 raise util.Abort(_('%s: no diffs found') % patchurl)
3840 raise util.Abort(_('%s: no diffs found') % patchurl)
3840
3841
3841 if tr:
3842 if tr:
3842 tr.close()
3843 tr.close()
3843 if msgs:
3844 if msgs:
3844 repo.savecommitmessage('\n* * *\n'.join(msgs))
3845 repo.savecommitmessage('\n* * *\n'.join(msgs))
3845 return ret
3846 return ret
3846 except: # re-raises
3847 except: # re-raises
3847 # wlock.release() indirectly calls dirstate.write(): since
3848 # wlock.release() indirectly calls dirstate.write(): since
3848 # we're crashing, we do not want to change the working dir
3849 # we're crashing, we do not want to change the working dir
3849 # parent after all, so make sure it writes nothing
3850 # parent after all, so make sure it writes nothing
3850 repo.dirstate.invalidate()
3851 repo.dirstate.invalidate()
3851 raise
3852 raise
3852 finally:
3853 finally:
3853 if tr:
3854 if tr:
3854 tr.release()
3855 tr.release()
3855 release(lock, wlock)
3856 release(lock, wlock)
3856
3857
3857 @command('incoming|in',
3858 @command('incoming|in',
3858 [('f', 'force', None,
3859 [('f', 'force', None,
3859 _('run even if remote repository is unrelated')),
3860 _('run even if remote repository is unrelated')),
3860 ('n', 'newest-first', None, _('show newest record first')),
3861 ('n', 'newest-first', None, _('show newest record first')),
3861 ('', 'bundle', '',
3862 ('', 'bundle', '',
3862 _('file to store the bundles into'), _('FILE')),
3863 _('file to store the bundles into'), _('FILE')),
3863 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3864 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3864 ('B', 'bookmarks', False, _("compare bookmarks")),
3865 ('B', 'bookmarks', False, _("compare bookmarks")),
3865 ('b', 'branch', [],
3866 ('b', 'branch', [],
3866 _('a specific branch you would like to pull'), _('BRANCH')),
3867 _('a specific branch you would like to pull'), _('BRANCH')),
3867 ] + logopts + remoteopts + subrepoopts,
3868 ] + logopts + remoteopts + subrepoopts,
3868 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3869 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3869 def incoming(ui, repo, source="default", **opts):
3870 def incoming(ui, repo, source="default", **opts):
3870 """show new changesets found in source
3871 """show new changesets found in source
3871
3872
3872 Show new changesets found in the specified path/URL or the default
3873 Show new changesets found in the specified path/URL or the default
3873 pull location. These are the changesets that would have been pulled
3874 pull location. These are the changesets that would have been pulled
3874 if a pull at the time you issued this command.
3875 if a pull at the time you issued this command.
3875
3876
3876 For remote repository, using --bundle avoids downloading the
3877 For remote repository, using --bundle avoids downloading the
3877 changesets twice if the incoming is followed by a pull.
3878 changesets twice if the incoming is followed by a pull.
3878
3879
3879 See pull for valid source format details.
3880 See pull for valid source format details.
3880
3881
3881 .. container:: verbose
3882 .. container:: verbose
3882
3883
3883 Examples:
3884 Examples:
3884
3885
3885 - show incoming changes with patches and full description::
3886 - show incoming changes with patches and full description::
3886
3887
3887 hg incoming -vp
3888 hg incoming -vp
3888
3889
3889 - show incoming changes excluding merges, store a bundle::
3890 - show incoming changes excluding merges, store a bundle::
3890
3891
3891 hg in -vpM --bundle incoming.hg
3892 hg in -vpM --bundle incoming.hg
3892 hg pull incoming.hg
3893 hg pull incoming.hg
3893
3894
3894 - briefly list changes inside a bundle::
3895 - briefly list changes inside a bundle::
3895
3896
3896 hg in changes.hg -T "{desc|firstline}\\n"
3897 hg in changes.hg -T "{desc|firstline}\\n"
3897
3898
3898 Returns 0 if there are incoming changes, 1 otherwise.
3899 Returns 0 if there are incoming changes, 1 otherwise.
3899 """
3900 """
3900 if opts.get('graph'):
3901 if opts.get('graph'):
3901 cmdutil.checkunsupportedgraphflags([], opts)
3902 cmdutil.checkunsupportedgraphflags([], opts)
3902 def display(other, chlist, displayer):
3903 def display(other, chlist, displayer):
3903 revdag = cmdutil.graphrevs(other, chlist, opts)
3904 revdag = cmdutil.graphrevs(other, chlist, opts)
3904 showparents = [ctx.node() for ctx in repo[None].parents()]
3905 showparents = [ctx.node() for ctx in repo[None].parents()]
3905 cmdutil.displaygraph(ui, revdag, displayer, showparents,
3906 cmdutil.displaygraph(ui, revdag, displayer, showparents,
3906 graphmod.asciiedges)
3907 graphmod.asciiedges)
3907
3908
3908 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3909 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3909 return 0
3910 return 0
3910
3911
3911 if opts.get('bundle') and opts.get('subrepos'):
3912 if opts.get('bundle') and opts.get('subrepos'):
3912 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3913 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3913
3914
3914 if opts.get('bookmarks'):
3915 if opts.get('bookmarks'):
3915 source, branches = hg.parseurl(ui.expandpath(source),
3916 source, branches = hg.parseurl(ui.expandpath(source),
3916 opts.get('branch'))
3917 opts.get('branch'))
3917 other = hg.peer(repo, opts, source)
3918 other = hg.peer(repo, opts, source)
3918 if 'bookmarks' not in other.listkeys('namespaces'):
3919 if 'bookmarks' not in other.listkeys('namespaces'):
3919 ui.warn(_("remote doesn't support bookmarks\n"))
3920 ui.warn(_("remote doesn't support bookmarks\n"))
3920 return 0
3921 return 0
3921 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3922 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3922 return bookmarks.diff(ui, repo, other)
3923 return bookmarks.diff(ui, repo, other)
3923
3924
3924 repo._subtoppath = ui.expandpath(source)
3925 repo._subtoppath = ui.expandpath(source)
3925 try:
3926 try:
3926 return hg.incoming(ui, repo, source, opts)
3927 return hg.incoming(ui, repo, source, opts)
3927 finally:
3928 finally:
3928 del repo._subtoppath
3929 del repo._subtoppath
3929
3930
3930
3931
3931 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3932 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3932 def init(ui, dest=".", **opts):
3933 def init(ui, dest=".", **opts):
3933 """create a new repository in the given directory
3934 """create a new repository in the given directory
3934
3935
3935 Initialize a new repository in the given directory. If the given
3936 Initialize a new repository in the given directory. If the given
3936 directory does not exist, it will be created.
3937 directory does not exist, it will be created.
3937
3938
3938 If no directory is given, the current directory is used.
3939 If no directory is given, the current directory is used.
3939
3940
3940 It is possible to specify an ``ssh://`` URL as the destination.
3941 It is possible to specify an ``ssh://`` URL as the destination.
3941 See :hg:`help urls` for more information.
3942 See :hg:`help urls` for more information.
3942
3943
3943 Returns 0 on success.
3944 Returns 0 on success.
3944 """
3945 """
3945 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3946 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3946
3947
3947 @command('locate',
3948 @command('locate',
3948 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3949 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3949 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3950 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3950 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3951 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3951 ] + walkopts,
3952 ] + walkopts,
3952 _('[OPTION]... [PATTERN]...'))
3953 _('[OPTION]... [PATTERN]...'))
3953 def locate(ui, repo, *pats, **opts):
3954 def locate(ui, repo, *pats, **opts):
3954 """locate files matching specific patterns
3955 """locate files matching specific patterns
3955
3956
3956 Print files under Mercurial control in the working directory whose
3957 Print files under Mercurial control in the working directory whose
3957 names match the given patterns.
3958 names match the given patterns.
3958
3959
3959 By default, this command searches all directories in the working
3960 By default, this command searches all directories in the working
3960 directory. To search just the current directory and its
3961 directory. To search just the current directory and its
3961 subdirectories, use "--include .".
3962 subdirectories, use "--include .".
3962
3963
3963 If no patterns are given to match, this command prints the names
3964 If no patterns are given to match, this command prints the names
3964 of all files under Mercurial control in the working directory.
3965 of all files under Mercurial control in the working directory.
3965
3966
3966 If you want to feed the output of this command into the "xargs"
3967 If you want to feed the output of this command into the "xargs"
3967 command, use the -0 option to both this command and "xargs". This
3968 command, use the -0 option to both this command and "xargs". This
3968 will avoid the problem of "xargs" treating single filenames that
3969 will avoid the problem of "xargs" treating single filenames that
3969 contain whitespace as multiple filenames.
3970 contain whitespace as multiple filenames.
3970
3971
3971 Returns 0 if a match is found, 1 otherwise.
3972 Returns 0 if a match is found, 1 otherwise.
3972 """
3973 """
3973 end = opts.get('print0') and '\0' or '\n'
3974 end = opts.get('print0') and '\0' or '\n'
3974 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3975 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3975
3976
3976 ret = 1
3977 ret = 1
3977 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3978 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3978 m.bad = lambda x, y: False
3979 m.bad = lambda x, y: False
3979 for abs in repo[rev].walk(m):
3980 for abs in repo[rev].walk(m):
3980 if not rev and abs not in repo.dirstate:
3981 if not rev and abs not in repo.dirstate:
3981 continue
3982 continue
3982 if opts.get('fullpath'):
3983 if opts.get('fullpath'):
3983 ui.write(repo.wjoin(abs), end)
3984 ui.write(repo.wjoin(abs), end)
3984 else:
3985 else:
3985 ui.write(((pats and m.rel(abs)) or abs), end)
3986 ui.write(((pats and m.rel(abs)) or abs), end)
3986 ret = 0
3987 ret = 0
3987
3988
3988 return ret
3989 return ret
3989
3990
3990 @command('^log|history',
3991 @command('^log|history',
3991 [('f', 'follow', None,
3992 [('f', 'follow', None,
3992 _('follow changeset history, or file history across copies and renames')),
3993 _('follow changeset history, or file history across copies and renames')),
3993 ('', 'follow-first', None,
3994 ('', 'follow-first', None,
3994 _('only follow the first parent of merge changesets (DEPRECATED)')),
3995 _('only follow the first parent of merge changesets (DEPRECATED)')),
3995 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3996 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3996 ('C', 'copies', None, _('show copied files')),
3997 ('C', 'copies', None, _('show copied files')),
3997 ('k', 'keyword', [],
3998 ('k', 'keyword', [],
3998 _('do case-insensitive search for a given text'), _('TEXT')),
3999 _('do case-insensitive search for a given text'), _('TEXT')),
3999 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
4000 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
4000 ('', 'removed', None, _('include revisions where files were removed')),
4001 ('', 'removed', None, _('include revisions where files were removed')),
4001 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4002 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
4002 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4003 ('u', 'user', [], _('revisions committed by user'), _('USER')),
4003 ('', 'only-branch', [],
4004 ('', 'only-branch', [],
4004 _('show only changesets within the given named branch (DEPRECATED)'),
4005 _('show only changesets within the given named branch (DEPRECATED)'),
4005 _('BRANCH')),
4006 _('BRANCH')),
4006 ('b', 'branch', [],
4007 ('b', 'branch', [],
4007 _('show changesets within the given named branch'), _('BRANCH')),
4008 _('show changesets within the given named branch'), _('BRANCH')),
4008 ('P', 'prune', [],
4009 ('P', 'prune', [],
4009 _('do not display revision or any of its ancestors'), _('REV')),
4010 _('do not display revision or any of its ancestors'), _('REV')),
4010 ] + logopts + walkopts,
4011 ] + logopts + walkopts,
4011 _('[OPTION]... [FILE]'))
4012 _('[OPTION]... [FILE]'))
4012 def log(ui, repo, *pats, **opts):
4013 def log(ui, repo, *pats, **opts):
4013 """show revision history of entire repository or files
4014 """show revision history of entire repository or files
4014
4015
4015 Print the revision history of the specified files or the entire
4016 Print the revision history of the specified files or the entire
4016 project.
4017 project.
4017
4018
4018 If no revision range is specified, the default is ``tip:0`` unless
4019 If no revision range is specified, the default is ``tip:0`` unless
4019 --follow is set, in which case the working directory parent is
4020 --follow is set, in which case the working directory parent is
4020 used as the starting revision.
4021 used as the starting revision.
4021
4022
4022 File history is shown without following rename or copy history of
4023 File history is shown without following rename or copy history of
4023 files. Use -f/--follow with a filename to follow history across
4024 files. Use -f/--follow with a filename to follow history across
4024 renames and copies. --follow without a filename will only show
4025 renames and copies. --follow without a filename will only show
4025 ancestors or descendants of the starting revision.
4026 ancestors or descendants of the starting revision.
4026
4027
4027 By default this command prints revision number and changeset id,
4028 By default this command prints revision number and changeset id,
4028 tags, non-trivial parents, user, date and time, and a summary for
4029 tags, non-trivial parents, user, date and time, and a summary for
4029 each commit. When the -v/--verbose switch is used, the list of
4030 each commit. When the -v/--verbose switch is used, the list of
4030 changed files and full commit message are shown.
4031 changed files and full commit message are shown.
4031
4032
4032 With --graph the revisions are shown as an ASCII art DAG with the most
4033 With --graph the revisions are shown as an ASCII art DAG with the most
4033 recent changeset at the top.
4034 recent changeset at the top.
4034 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4035 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4035 and '+' represents a fork where the changeset from the lines below is a
4036 and '+' represents a fork where the changeset from the lines below is a
4036 parent of the 'o' merge on the same line.
4037 parent of the 'o' merge on the same line.
4037
4038
4038 .. note::
4039 .. note::
4039
4040
4040 log -p/--patch may generate unexpected diff output for merge
4041 log -p/--patch may generate unexpected diff output for merge
4041 changesets, as it will only compare the merge changeset against
4042 changesets, as it will only compare the merge changeset against
4042 its first parent. Also, only files different from BOTH parents
4043 its first parent. Also, only files different from BOTH parents
4043 will appear in files:.
4044 will appear in files:.
4044
4045
4045 .. note::
4046 .. note::
4046
4047
4047 for performance reasons, log FILE may omit duplicate changes
4048 for performance reasons, log FILE may omit duplicate changes
4048 made on branches and will not show deletions. To see all
4049 made on branches and will not show deletions. To see all
4049 changes including duplicates and deletions, use the --removed
4050 changes including duplicates and deletions, use the --removed
4050 switch.
4051 switch.
4051
4052
4052 .. container:: verbose
4053 .. container:: verbose
4053
4054
4054 Some examples:
4055 Some examples:
4055
4056
4056 - changesets with full descriptions and file lists::
4057 - changesets with full descriptions and file lists::
4057
4058
4058 hg log -v
4059 hg log -v
4059
4060
4060 - changesets ancestral to the working directory::
4061 - changesets ancestral to the working directory::
4061
4062
4062 hg log -f
4063 hg log -f
4063
4064
4064 - last 10 commits on the current branch::
4065 - last 10 commits on the current branch::
4065
4066
4066 hg log -l 10 -b .
4067 hg log -l 10 -b .
4067
4068
4068 - changesets showing all modifications of a file, including removals::
4069 - changesets showing all modifications of a file, including removals::
4069
4070
4070 hg log --removed file.c
4071 hg log --removed file.c
4071
4072
4072 - all changesets that touch a directory, with diffs, excluding merges::
4073 - all changesets that touch a directory, with diffs, excluding merges::
4073
4074
4074 hg log -Mp lib/
4075 hg log -Mp lib/
4075
4076
4076 - all revision numbers that match a keyword::
4077 - all revision numbers that match a keyword::
4077
4078
4078 hg log -k bug --template "{rev}\\n"
4079 hg log -k bug --template "{rev}\\n"
4079
4080
4080 - check if a given changeset is included is a tagged release::
4081 - check if a given changeset is included is a tagged release::
4081
4082
4082 hg log -r "a21ccf and ancestor(1.9)"
4083 hg log -r "a21ccf and ancestor(1.9)"
4083
4084
4084 - find all changesets by some user in a date range::
4085 - find all changesets by some user in a date range::
4085
4086
4086 hg log -k alice -d "may 2008 to jul 2008"
4087 hg log -k alice -d "may 2008 to jul 2008"
4087
4088
4088 - summary of all changesets after the last tag::
4089 - summary of all changesets after the last tag::
4089
4090
4090 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4091 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4091
4092
4092 See :hg:`help dates` for a list of formats valid for -d/--date.
4093 See :hg:`help dates` for a list of formats valid for -d/--date.
4093
4094
4094 See :hg:`help revisions` and :hg:`help revsets` for more about
4095 See :hg:`help revisions` and :hg:`help revsets` for more about
4095 specifying revisions.
4096 specifying revisions.
4096
4097
4097 See :hg:`help templates` for more about pre-packaged styles and
4098 See :hg:`help templates` for more about pre-packaged styles and
4098 specifying custom templates.
4099 specifying custom templates.
4099
4100
4100 Returns 0 on success.
4101 Returns 0 on success.
4101 """
4102 """
4102 if opts.get('graph'):
4103 if opts.get('graph'):
4103 return cmdutil.graphlog(ui, repo, *pats, **opts)
4104 return cmdutil.graphlog(ui, repo, *pats, **opts)
4104
4105
4105 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4106 revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
4106 limit = cmdutil.loglimit(opts)
4107 limit = cmdutil.loglimit(opts)
4107 count = 0
4108 count = 0
4108
4109
4109 getrenamed = None
4110 getrenamed = None
4110 if opts.get('copies'):
4111 if opts.get('copies'):
4111 endrev = None
4112 endrev = None
4112 if opts.get('rev'):
4113 if opts.get('rev'):
4113 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4114 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
4114 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4115 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4115
4116
4116 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4117 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4117 for rev in revs:
4118 for rev in revs:
4118 if count == limit:
4119 if count == limit:
4119 break
4120 break
4120 ctx = repo[rev]
4121 ctx = repo[rev]
4121 copies = None
4122 copies = None
4122 if getrenamed is not None and rev:
4123 if getrenamed is not None and rev:
4123 copies = []
4124 copies = []
4124 for fn in ctx.files():
4125 for fn in ctx.files():
4125 rename = getrenamed(fn, rev)
4126 rename = getrenamed(fn, rev)
4126 if rename:
4127 if rename:
4127 copies.append((fn, rename[0]))
4128 copies.append((fn, rename[0]))
4128 revmatchfn = filematcher and filematcher(ctx.rev()) or None
4129 revmatchfn = filematcher and filematcher(ctx.rev()) or None
4129 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4130 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4130 if displayer.flush(rev):
4131 if displayer.flush(rev):
4131 count += 1
4132 count += 1
4132
4133
4133 displayer.close()
4134 displayer.close()
4134
4135
4135 @command('manifest',
4136 @command('manifest',
4136 [('r', 'rev', '', _('revision to display'), _('REV')),
4137 [('r', 'rev', '', _('revision to display'), _('REV')),
4137 ('', 'all', False, _("list files from all revisions"))],
4138 ('', 'all', False, _("list files from all revisions"))],
4138 _('[-r REV]'))
4139 _('[-r REV]'))
4139 def manifest(ui, repo, node=None, rev=None, **opts):
4140 def manifest(ui, repo, node=None, rev=None, **opts):
4140 """output the current or given revision of the project manifest
4141 """output the current or given revision of the project manifest
4141
4142
4142 Print a list of version controlled files for the given revision.
4143 Print a list of version controlled files for the given revision.
4143 If no revision is given, the first parent of the working directory
4144 If no revision is given, the first parent of the working directory
4144 is used, or the null revision if no revision is checked out.
4145 is used, or the null revision if no revision is checked out.
4145
4146
4146 With -v, print file permissions, symlink and executable bits.
4147 With -v, print file permissions, symlink and executable bits.
4147 With --debug, print file revision hashes.
4148 With --debug, print file revision hashes.
4148
4149
4149 If option --all is specified, the list of all files from all revisions
4150 If option --all is specified, the list of all files from all revisions
4150 is printed. This includes deleted and renamed files.
4151 is printed. This includes deleted and renamed files.
4151
4152
4152 Returns 0 on success.
4153 Returns 0 on success.
4153 """
4154 """
4154
4155
4155 fm = ui.formatter('manifest', opts)
4156 fm = ui.formatter('manifest', opts)
4156
4157
4157 if opts.get('all'):
4158 if opts.get('all'):
4158 if rev or node:
4159 if rev or node:
4159 raise util.Abort(_("can't specify a revision with --all"))
4160 raise util.Abort(_("can't specify a revision with --all"))
4160
4161
4161 res = []
4162 res = []
4162 prefix = "data/"
4163 prefix = "data/"
4163 suffix = ".i"
4164 suffix = ".i"
4164 plen = len(prefix)
4165 plen = len(prefix)
4165 slen = len(suffix)
4166 slen = len(suffix)
4166 lock = repo.lock()
4167 lock = repo.lock()
4167 try:
4168 try:
4168 for fn, b, size in repo.store.datafiles():
4169 for fn, b, size in repo.store.datafiles():
4169 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4170 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4170 res.append(fn[plen:-slen])
4171 res.append(fn[plen:-slen])
4171 finally:
4172 finally:
4172 lock.release()
4173 lock.release()
4173 for f in res:
4174 for f in res:
4174 fm.startitem()
4175 fm.startitem()
4175 fm.write("path", '%s\n', f)
4176 fm.write("path", '%s\n', f)
4176 fm.end()
4177 fm.end()
4177 return
4178 return
4178
4179
4179 if rev and node:
4180 if rev and node:
4180 raise util.Abort(_("please specify just one revision"))
4181 raise util.Abort(_("please specify just one revision"))
4181
4182
4182 if not node:
4183 if not node:
4183 node = rev
4184 node = rev
4184
4185
4185 char = {'l': '@', 'x': '*', '': ''}
4186 char = {'l': '@', 'x': '*', '': ''}
4186 mode = {'l': '644', 'x': '755', '': '644'}
4187 mode = {'l': '644', 'x': '755', '': '644'}
4187 ctx = scmutil.revsingle(repo, node)
4188 ctx = scmutil.revsingle(repo, node)
4188 mf = ctx.manifest()
4189 mf = ctx.manifest()
4189 for f in ctx:
4190 for f in ctx:
4190 fm.startitem()
4191 fm.startitem()
4191 fl = ctx[f].flags()
4192 fl = ctx[f].flags()
4192 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4193 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4193 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4194 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4194 fm.write('path', '%s\n', f)
4195 fm.write('path', '%s\n', f)
4195 fm.end()
4196 fm.end()
4196
4197
4197 @command('^merge',
4198 @command('^merge',
4198 [('f', 'force', None,
4199 [('f', 'force', None,
4199 _('force a merge including outstanding changes (DEPRECATED)')),
4200 _('force a merge including outstanding changes (DEPRECATED)')),
4200 ('r', 'rev', '', _('revision to merge'), _('REV')),
4201 ('r', 'rev', '', _('revision to merge'), _('REV')),
4201 ('P', 'preview', None,
4202 ('P', 'preview', None,
4202 _('review revisions to merge (no merge is performed)'))
4203 _('review revisions to merge (no merge is performed)'))
4203 ] + mergetoolopts,
4204 ] + mergetoolopts,
4204 _('[-P] [-f] [[-r] REV]'))
4205 _('[-P] [-f] [[-r] REV]'))
4205 def merge(ui, repo, node=None, **opts):
4206 def merge(ui, repo, node=None, **opts):
4206 """merge working directory with another revision
4207 """merge working directory with another revision
4207
4208
4208 The current working directory is updated with all changes made in
4209 The current working directory is updated with all changes made in
4209 the requested revision since the last common predecessor revision.
4210 the requested revision since the last common predecessor revision.
4210
4211
4211 Files that changed between either parent are marked as changed for
4212 Files that changed between either parent are marked as changed for
4212 the next commit and a commit must be performed before any further
4213 the next commit and a commit must be performed before any further
4213 updates to the repository are allowed. The next commit will have
4214 updates to the repository are allowed. The next commit will have
4214 two parents.
4215 two parents.
4215
4216
4216 ``--tool`` can be used to specify the merge tool used for file
4217 ``--tool`` can be used to specify the merge tool used for file
4217 merges. It overrides the HGMERGE environment variable and your
4218 merges. It overrides the HGMERGE environment variable and your
4218 configuration files. See :hg:`help merge-tools` for options.
4219 configuration files. See :hg:`help merge-tools` for options.
4219
4220
4220 If no revision is specified, the working directory's parent is a
4221 If no revision is specified, the working directory's parent is a
4221 head revision, and the current branch contains exactly one other
4222 head revision, and the current branch contains exactly one other
4222 head, the other head is merged with by default. Otherwise, an
4223 head, the other head is merged with by default. Otherwise, an
4223 explicit revision with which to merge with must be provided.
4224 explicit revision with which to merge with must be provided.
4224
4225
4225 :hg:`resolve` must be used to resolve unresolved files.
4226 :hg:`resolve` must be used to resolve unresolved files.
4226
4227
4227 To undo an uncommitted merge, use :hg:`update --clean .` which
4228 To undo an uncommitted merge, use :hg:`update --clean .` which
4228 will check out a clean copy of the original merge parent, losing
4229 will check out a clean copy of the original merge parent, losing
4229 all changes.
4230 all changes.
4230
4231
4231 Returns 0 on success, 1 if there are unresolved files.
4232 Returns 0 on success, 1 if there are unresolved files.
4232 """
4233 """
4233
4234
4234 if opts.get('rev') and node:
4235 if opts.get('rev') and node:
4235 raise util.Abort(_("please specify just one revision"))
4236 raise util.Abort(_("please specify just one revision"))
4236 if not node:
4237 if not node:
4237 node = opts.get('rev')
4238 node = opts.get('rev')
4238
4239
4239 if node:
4240 if node:
4240 node = scmutil.revsingle(repo, node).node()
4241 node = scmutil.revsingle(repo, node).node()
4241
4242
4242 if not node and repo._bookmarkcurrent:
4243 if not node and repo._bookmarkcurrent:
4243 bmheads = repo.bookmarkheads(repo._bookmarkcurrent)
4244 bmheads = repo.bookmarkheads(repo._bookmarkcurrent)
4244 curhead = repo[repo._bookmarkcurrent].node()
4245 curhead = repo[repo._bookmarkcurrent].node()
4245 if len(bmheads) == 2:
4246 if len(bmheads) == 2:
4246 if curhead == bmheads[0]:
4247 if curhead == bmheads[0]:
4247 node = bmheads[1]
4248 node = bmheads[1]
4248 else:
4249 else:
4249 node = bmheads[0]
4250 node = bmheads[0]
4250 elif len(bmheads) > 2:
4251 elif len(bmheads) > 2:
4251 raise util.Abort(_("multiple matching bookmarks to merge - "
4252 raise util.Abort(_("multiple matching bookmarks to merge - "
4252 "please merge with an explicit rev or bookmark"),
4253 "please merge with an explicit rev or bookmark"),
4253 hint=_("run 'hg heads' to see all heads"))
4254 hint=_("run 'hg heads' to see all heads"))
4254 elif len(bmheads) <= 1:
4255 elif len(bmheads) <= 1:
4255 raise util.Abort(_("no matching bookmark to merge - "
4256 raise util.Abort(_("no matching bookmark to merge - "
4256 "please merge with an explicit rev or bookmark"),
4257 "please merge with an explicit rev or bookmark"),
4257 hint=_("run 'hg heads' to see all heads"))
4258 hint=_("run 'hg heads' to see all heads"))
4258
4259
4259 if not node and not repo._bookmarkcurrent:
4260 if not node and not repo._bookmarkcurrent:
4260 branch = repo[None].branch()
4261 branch = repo[None].branch()
4261 bheads = repo.branchheads(branch)
4262 bheads = repo.branchheads(branch)
4262 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4263 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4263
4264
4264 if len(nbhs) > 2:
4265 if len(nbhs) > 2:
4265 raise util.Abort(_("branch '%s' has %d heads - "
4266 raise util.Abort(_("branch '%s' has %d heads - "
4266 "please merge with an explicit rev")
4267 "please merge with an explicit rev")
4267 % (branch, len(bheads)),
4268 % (branch, len(bheads)),
4268 hint=_("run 'hg heads .' to see heads"))
4269 hint=_("run 'hg heads .' to see heads"))
4269
4270
4270 parent = repo.dirstate.p1()
4271 parent = repo.dirstate.p1()
4271 if len(nbhs) <= 1:
4272 if len(nbhs) <= 1:
4272 if len(bheads) > 1:
4273 if len(bheads) > 1:
4273 raise util.Abort(_("heads are bookmarked - "
4274 raise util.Abort(_("heads are bookmarked - "
4274 "please merge with an explicit rev"),
4275 "please merge with an explicit rev"),
4275 hint=_("run 'hg heads' to see all heads"))
4276 hint=_("run 'hg heads' to see all heads"))
4276 if len(repo.heads()) > 1:
4277 if len(repo.heads()) > 1:
4277 raise util.Abort(_("branch '%s' has one head - "
4278 raise util.Abort(_("branch '%s' has one head - "
4278 "please merge with an explicit rev")
4279 "please merge with an explicit rev")
4279 % branch,
4280 % branch,
4280 hint=_("run 'hg heads' to see all heads"))
4281 hint=_("run 'hg heads' to see all heads"))
4281 msg, hint = _('nothing to merge'), None
4282 msg, hint = _('nothing to merge'), None
4282 if parent != repo.lookup(branch):
4283 if parent != repo.lookup(branch):
4283 hint = _("use 'hg update' instead")
4284 hint = _("use 'hg update' instead")
4284 raise util.Abort(msg, hint=hint)
4285 raise util.Abort(msg, hint=hint)
4285
4286
4286 if parent not in bheads:
4287 if parent not in bheads:
4287 raise util.Abort(_('working directory not at a head revision'),
4288 raise util.Abort(_('working directory not at a head revision'),
4288 hint=_("use 'hg update' or merge with an "
4289 hint=_("use 'hg update' or merge with an "
4289 "explicit revision"))
4290 "explicit revision"))
4290 if parent == nbhs[0]:
4291 if parent == nbhs[0]:
4291 node = nbhs[-1]
4292 node = nbhs[-1]
4292 else:
4293 else:
4293 node = nbhs[0]
4294 node = nbhs[0]
4294
4295
4295 if opts.get('preview'):
4296 if opts.get('preview'):
4296 # find nodes that are ancestors of p2 but not of p1
4297 # find nodes that are ancestors of p2 but not of p1
4297 p1 = repo.lookup('.')
4298 p1 = repo.lookup('.')
4298 p2 = repo.lookup(node)
4299 p2 = repo.lookup(node)
4299 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4300 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4300
4301
4301 displayer = cmdutil.show_changeset(ui, repo, opts)
4302 displayer = cmdutil.show_changeset(ui, repo, opts)
4302 for node in nodes:
4303 for node in nodes:
4303 displayer.show(repo[node])
4304 displayer.show(repo[node])
4304 displayer.close()
4305 displayer.close()
4305 return 0
4306 return 0
4306
4307
4307 try:
4308 try:
4308 # ui.forcemerge is an internal variable, do not document
4309 # ui.forcemerge is an internal variable, do not document
4309 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4310 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'merge')
4310 return hg.merge(repo, node, force=opts.get('force'))
4311 return hg.merge(repo, node, force=opts.get('force'))
4311 finally:
4312 finally:
4312 ui.setconfig('ui', 'forcemerge', '', 'merge')
4313 ui.setconfig('ui', 'forcemerge', '', 'merge')
4313
4314
4314 @command('outgoing|out',
4315 @command('outgoing|out',
4315 [('f', 'force', None, _('run even when the destination is unrelated')),
4316 [('f', 'force', None, _('run even when the destination is unrelated')),
4316 ('r', 'rev', [],
4317 ('r', 'rev', [],
4317 _('a changeset intended to be included in the destination'), _('REV')),
4318 _('a changeset intended to be included in the destination'), _('REV')),
4318 ('n', 'newest-first', None, _('show newest record first')),
4319 ('n', 'newest-first', None, _('show newest record first')),
4319 ('B', 'bookmarks', False, _('compare bookmarks')),
4320 ('B', 'bookmarks', False, _('compare bookmarks')),
4320 ('b', 'branch', [], _('a specific branch you would like to push'),
4321 ('b', 'branch', [], _('a specific branch you would like to push'),
4321 _('BRANCH')),
4322 _('BRANCH')),
4322 ] + logopts + remoteopts + subrepoopts,
4323 ] + logopts + remoteopts + subrepoopts,
4323 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4324 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4324 def outgoing(ui, repo, dest=None, **opts):
4325 def outgoing(ui, repo, dest=None, **opts):
4325 """show changesets not found in the destination
4326 """show changesets not found in the destination
4326
4327
4327 Show changesets not found in the specified destination repository
4328 Show changesets not found in the specified destination repository
4328 or the default push location. These are the changesets that would
4329 or the default push location. These are the changesets that would
4329 be pushed if a push was requested.
4330 be pushed if a push was requested.
4330
4331
4331 See pull for details of valid destination formats.
4332 See pull for details of valid destination formats.
4332
4333
4333 Returns 0 if there are outgoing changes, 1 otherwise.
4334 Returns 0 if there are outgoing changes, 1 otherwise.
4334 """
4335 """
4335 if opts.get('graph'):
4336 if opts.get('graph'):
4336 cmdutil.checkunsupportedgraphflags([], opts)
4337 cmdutil.checkunsupportedgraphflags([], opts)
4337 o, other = hg._outgoing(ui, repo, dest, opts)
4338 o, other = hg._outgoing(ui, repo, dest, opts)
4338 if not o:
4339 if not o:
4339 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4340 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4340 return
4341 return
4341
4342
4342 revdag = cmdutil.graphrevs(repo, o, opts)
4343 revdag = cmdutil.graphrevs(repo, o, opts)
4343 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4344 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4344 showparents = [ctx.node() for ctx in repo[None].parents()]
4345 showparents = [ctx.node() for ctx in repo[None].parents()]
4345 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4346 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4346 graphmod.asciiedges)
4347 graphmod.asciiedges)
4347 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4348 cmdutil.outgoinghooks(ui, repo, other, opts, o)
4348 return 0
4349 return 0
4349
4350
4350 if opts.get('bookmarks'):
4351 if opts.get('bookmarks'):
4351 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4352 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4352 dest, branches = hg.parseurl(dest, opts.get('branch'))
4353 dest, branches = hg.parseurl(dest, opts.get('branch'))
4353 other = hg.peer(repo, opts, dest)
4354 other = hg.peer(repo, opts, dest)
4354 if 'bookmarks' not in other.listkeys('namespaces'):
4355 if 'bookmarks' not in other.listkeys('namespaces'):
4355 ui.warn(_("remote doesn't support bookmarks\n"))
4356 ui.warn(_("remote doesn't support bookmarks\n"))
4356 return 0
4357 return 0
4357 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4358 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4358 return bookmarks.diff(ui, other, repo)
4359 return bookmarks.diff(ui, other, repo)
4359
4360
4360 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4361 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4361 try:
4362 try:
4362 return hg.outgoing(ui, repo, dest, opts)
4363 return hg.outgoing(ui, repo, dest, opts)
4363 finally:
4364 finally:
4364 del repo._subtoppath
4365 del repo._subtoppath
4365
4366
4366 @command('parents',
4367 @command('parents',
4367 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4368 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4368 ] + templateopts,
4369 ] + templateopts,
4369 _('[-r REV] [FILE]'))
4370 _('[-r REV] [FILE]'))
4370 def parents(ui, repo, file_=None, **opts):
4371 def parents(ui, repo, file_=None, **opts):
4371 """show the parents of the working directory or revision
4372 """show the parents of the working directory or revision
4372
4373
4373 Print the working directory's parent revisions. If a revision is
4374 Print the working directory's parent revisions. If a revision is
4374 given via -r/--rev, the parent of that revision will be printed.
4375 given via -r/--rev, the parent of that revision will be printed.
4375 If a file argument is given, the revision in which the file was
4376 If a file argument is given, the revision in which the file was
4376 last changed (before the working directory revision or the
4377 last changed (before the working directory revision or the
4377 argument to --rev if given) is printed.
4378 argument to --rev if given) is printed.
4378
4379
4379 Returns 0 on success.
4380 Returns 0 on success.
4380 """
4381 """
4381
4382
4382 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4383 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4383
4384
4384 if file_:
4385 if file_:
4385 m = scmutil.match(ctx, (file_,), opts)
4386 m = scmutil.match(ctx, (file_,), opts)
4386 if m.anypats() or len(m.files()) != 1:
4387 if m.anypats() or len(m.files()) != 1:
4387 raise util.Abort(_('can only specify an explicit filename'))
4388 raise util.Abort(_('can only specify an explicit filename'))
4388 file_ = m.files()[0]
4389 file_ = m.files()[0]
4389 filenodes = []
4390 filenodes = []
4390 for cp in ctx.parents():
4391 for cp in ctx.parents():
4391 if not cp:
4392 if not cp:
4392 continue
4393 continue
4393 try:
4394 try:
4394 filenodes.append(cp.filenode(file_))
4395 filenodes.append(cp.filenode(file_))
4395 except error.LookupError:
4396 except error.LookupError:
4396 pass
4397 pass
4397 if not filenodes:
4398 if not filenodes:
4398 raise util.Abort(_("'%s' not found in manifest!") % file_)
4399 raise util.Abort(_("'%s' not found in manifest!") % file_)
4399 p = []
4400 p = []
4400 for fn in filenodes:
4401 for fn in filenodes:
4401 fctx = repo.filectx(file_, fileid=fn)
4402 fctx = repo.filectx(file_, fileid=fn)
4402 p.append(fctx.node())
4403 p.append(fctx.node())
4403 else:
4404 else:
4404 p = [cp.node() for cp in ctx.parents()]
4405 p = [cp.node() for cp in ctx.parents()]
4405
4406
4406 displayer = cmdutil.show_changeset(ui, repo, opts)
4407 displayer = cmdutil.show_changeset(ui, repo, opts)
4407 for n in p:
4408 for n in p:
4408 if n != nullid:
4409 if n != nullid:
4409 displayer.show(repo[n])
4410 displayer.show(repo[n])
4410 displayer.close()
4411 displayer.close()
4411
4412
4412 @command('paths', [], _('[NAME]'))
4413 @command('paths', [], _('[NAME]'))
4413 def paths(ui, repo, search=None):
4414 def paths(ui, repo, search=None):
4414 """show aliases for remote repositories
4415 """show aliases for remote repositories
4415
4416
4416 Show definition of symbolic path name NAME. If no name is given,
4417 Show definition of symbolic path name NAME. If no name is given,
4417 show definition of all available names.
4418 show definition of all available names.
4418
4419
4419 Option -q/--quiet suppresses all output when searching for NAME
4420 Option -q/--quiet suppresses all output when searching for NAME
4420 and shows only the path names when listing all definitions.
4421 and shows only the path names when listing all definitions.
4421
4422
4422 Path names are defined in the [paths] section of your
4423 Path names are defined in the [paths] section of your
4423 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4424 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4424 repository, ``.hg/hgrc`` is used, too.
4425 repository, ``.hg/hgrc`` is used, too.
4425
4426
4426 The path names ``default`` and ``default-push`` have a special
4427 The path names ``default`` and ``default-push`` have a special
4427 meaning. When performing a push or pull operation, they are used
4428 meaning. When performing a push or pull operation, they are used
4428 as fallbacks if no location is specified on the command-line.
4429 as fallbacks if no location is specified on the command-line.
4429 When ``default-push`` is set, it will be used for push and
4430 When ``default-push`` is set, it will be used for push and
4430 ``default`` will be used for pull; otherwise ``default`` is used
4431 ``default`` will be used for pull; otherwise ``default`` is used
4431 as the fallback for both. When cloning a repository, the clone
4432 as the fallback for both. When cloning a repository, the clone
4432 source is written as ``default`` in ``.hg/hgrc``. Note that
4433 source is written as ``default`` in ``.hg/hgrc``. Note that
4433 ``default`` and ``default-push`` apply to all inbound (e.g.
4434 ``default`` and ``default-push`` apply to all inbound (e.g.
4434 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4435 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4435 :hg:`bundle`) operations.
4436 :hg:`bundle`) operations.
4436
4437
4437 See :hg:`help urls` for more information.
4438 See :hg:`help urls` for more information.
4438
4439
4439 Returns 0 on success.
4440 Returns 0 on success.
4440 """
4441 """
4441 if search:
4442 if search:
4442 for name, path in ui.configitems("paths"):
4443 for name, path in ui.configitems("paths"):
4443 if name == search:
4444 if name == search:
4444 ui.status("%s\n" % util.hidepassword(path))
4445 ui.status("%s\n" % util.hidepassword(path))
4445 return
4446 return
4446 if not ui.quiet:
4447 if not ui.quiet:
4447 ui.warn(_("not found!\n"))
4448 ui.warn(_("not found!\n"))
4448 return 1
4449 return 1
4449 else:
4450 else:
4450 for name, path in ui.configitems("paths"):
4451 for name, path in ui.configitems("paths"):
4451 if ui.quiet:
4452 if ui.quiet:
4452 ui.write("%s\n" % name)
4453 ui.write("%s\n" % name)
4453 else:
4454 else:
4454 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4455 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4455
4456
4456 @command('phase',
4457 @command('phase',
4457 [('p', 'public', False, _('set changeset phase to public')),
4458 [('p', 'public', False, _('set changeset phase to public')),
4458 ('d', 'draft', False, _('set changeset phase to draft')),
4459 ('d', 'draft', False, _('set changeset phase to draft')),
4459 ('s', 'secret', False, _('set changeset phase to secret')),
4460 ('s', 'secret', False, _('set changeset phase to secret')),
4460 ('f', 'force', False, _('allow to move boundary backward')),
4461 ('f', 'force', False, _('allow to move boundary backward')),
4461 ('r', 'rev', [], _('target revision'), _('REV')),
4462 ('r', 'rev', [], _('target revision'), _('REV')),
4462 ],
4463 ],
4463 _('[-p|-d|-s] [-f] [-r] REV...'))
4464 _('[-p|-d|-s] [-f] [-r] REV...'))
4464 def phase(ui, repo, *revs, **opts):
4465 def phase(ui, repo, *revs, **opts):
4465 """set or show the current phase name
4466 """set or show the current phase name
4466
4467
4467 With no argument, show the phase name of specified revisions.
4468 With no argument, show the phase name of specified revisions.
4468
4469
4469 With one of -p/--public, -d/--draft or -s/--secret, change the
4470 With one of -p/--public, -d/--draft or -s/--secret, change the
4470 phase value of the specified revisions.
4471 phase value of the specified revisions.
4471
4472
4472 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4473 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4473 lower phase to an higher phase. Phases are ordered as follows::
4474 lower phase to an higher phase. Phases are ordered as follows::
4474
4475
4475 public < draft < secret
4476 public < draft < secret
4476
4477
4477 Returns 0 on success, 1 if no phases were changed or some could not
4478 Returns 0 on success, 1 if no phases were changed or some could not
4478 be changed.
4479 be changed.
4479 """
4480 """
4480 # search for a unique phase argument
4481 # search for a unique phase argument
4481 targetphase = None
4482 targetphase = None
4482 for idx, name in enumerate(phases.phasenames):
4483 for idx, name in enumerate(phases.phasenames):
4483 if opts[name]:
4484 if opts[name]:
4484 if targetphase is not None:
4485 if targetphase is not None:
4485 raise util.Abort(_('only one phase can be specified'))
4486 raise util.Abort(_('only one phase can be specified'))
4486 targetphase = idx
4487 targetphase = idx
4487
4488
4488 # look for specified revision
4489 # look for specified revision
4489 revs = list(revs)
4490 revs = list(revs)
4490 revs.extend(opts['rev'])
4491 revs.extend(opts['rev'])
4491 if not revs:
4492 if not revs:
4492 raise util.Abort(_('no revisions specified'))
4493 raise util.Abort(_('no revisions specified'))
4493
4494
4494 revs = scmutil.revrange(repo, revs)
4495 revs = scmutil.revrange(repo, revs)
4495
4496
4496 lock = None
4497 lock = None
4497 ret = 0
4498 ret = 0
4498 if targetphase is None:
4499 if targetphase is None:
4499 # display
4500 # display
4500 for r in revs:
4501 for r in revs:
4501 ctx = repo[r]
4502 ctx = repo[r]
4502 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4503 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4503 else:
4504 else:
4504 lock = repo.lock()
4505 lock = repo.lock()
4505 try:
4506 try:
4506 # set phase
4507 # set phase
4507 if not revs:
4508 if not revs:
4508 raise util.Abort(_('empty revision set'))
4509 raise util.Abort(_('empty revision set'))
4509 nodes = [repo[r].node() for r in revs]
4510 nodes = [repo[r].node() for r in revs]
4510 olddata = repo._phasecache.getphaserevs(repo)[:]
4511 olddata = repo._phasecache.getphaserevs(repo)[:]
4511 phases.advanceboundary(repo, targetphase, nodes)
4512 phases.advanceboundary(repo, targetphase, nodes)
4512 if opts['force']:
4513 if opts['force']:
4513 phases.retractboundary(repo, targetphase, nodes)
4514 phases.retractboundary(repo, targetphase, nodes)
4514 finally:
4515 finally:
4515 lock.release()
4516 lock.release()
4516 # moving revision from public to draft may hide them
4517 # moving revision from public to draft may hide them
4517 # We have to check result on an unfiltered repository
4518 # We have to check result on an unfiltered repository
4518 unfi = repo.unfiltered()
4519 unfi = repo.unfiltered()
4519 newdata = repo._phasecache.getphaserevs(unfi)
4520 newdata = repo._phasecache.getphaserevs(unfi)
4520 changes = sum(o != newdata[i] for i, o in enumerate(olddata))
4521 changes = sum(o != newdata[i] for i, o in enumerate(olddata))
4521 cl = unfi.changelog
4522 cl = unfi.changelog
4522 rejected = [n for n in nodes
4523 rejected = [n for n in nodes
4523 if newdata[cl.rev(n)] < targetphase]
4524 if newdata[cl.rev(n)] < targetphase]
4524 if rejected:
4525 if rejected:
4525 ui.warn(_('cannot move %i changesets to a higher '
4526 ui.warn(_('cannot move %i changesets to a higher '
4526 'phase, use --force\n') % len(rejected))
4527 'phase, use --force\n') % len(rejected))
4527 ret = 1
4528 ret = 1
4528 if changes:
4529 if changes:
4529 msg = _('phase changed for %i changesets\n') % changes
4530 msg = _('phase changed for %i changesets\n') % changes
4530 if ret:
4531 if ret:
4531 ui.status(msg)
4532 ui.status(msg)
4532 else:
4533 else:
4533 ui.note(msg)
4534 ui.note(msg)
4534 else:
4535 else:
4535 ui.warn(_('no phases changed\n'))
4536 ui.warn(_('no phases changed\n'))
4536 ret = 1
4537 ret = 1
4537 return ret
4538 return ret
4538
4539
4539 def postincoming(ui, repo, modheads, optupdate, checkout):
4540 def postincoming(ui, repo, modheads, optupdate, checkout):
4540 if modheads == 0:
4541 if modheads == 0:
4541 return
4542 return
4542 if optupdate:
4543 if optupdate:
4543 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
4544 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
4544 try:
4545 try:
4545 ret = hg.update(repo, checkout)
4546 ret = hg.update(repo, checkout)
4546 except util.Abort, inst:
4547 except util.Abort, inst:
4547 ui.warn(_("not updating: %s\n") % str(inst))
4548 ui.warn(_("not updating: %s\n") % str(inst))
4548 if inst.hint:
4549 if inst.hint:
4549 ui.warn(_("(%s)\n") % inst.hint)
4550 ui.warn(_("(%s)\n") % inst.hint)
4550 return 0
4551 return 0
4551 if not ret and not checkout:
4552 if not ret and not checkout:
4552 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
4553 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
4553 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
4554 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
4554 return ret
4555 return ret
4555 if modheads > 1:
4556 if modheads > 1:
4556 currentbranchheads = len(repo.branchheads())
4557 currentbranchheads = len(repo.branchheads())
4557 if currentbranchheads == modheads:
4558 if currentbranchheads == modheads:
4558 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4559 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4559 elif currentbranchheads > 1:
4560 elif currentbranchheads > 1:
4560 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4561 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4561 "merge)\n"))
4562 "merge)\n"))
4562 else:
4563 else:
4563 ui.status(_("(run 'hg heads' to see heads)\n"))
4564 ui.status(_("(run 'hg heads' to see heads)\n"))
4564 else:
4565 else:
4565 ui.status(_("(run 'hg update' to get a working copy)\n"))
4566 ui.status(_("(run 'hg update' to get a working copy)\n"))
4566
4567
4567 @command('^pull',
4568 @command('^pull',
4568 [('u', 'update', None,
4569 [('u', 'update', None,
4569 _('update to new branch head if changesets were pulled')),
4570 _('update to new branch head if changesets were pulled')),
4570 ('f', 'force', None, _('run even when remote repository is unrelated')),
4571 ('f', 'force', None, _('run even when remote repository is unrelated')),
4571 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4572 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4572 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4573 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4573 ('b', 'branch', [], _('a specific branch you would like to pull'),
4574 ('b', 'branch', [], _('a specific branch you would like to pull'),
4574 _('BRANCH')),
4575 _('BRANCH')),
4575 ] + remoteopts,
4576 ] + remoteopts,
4576 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4577 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4577 def pull(ui, repo, source="default", **opts):
4578 def pull(ui, repo, source="default", **opts):
4578 """pull changes from the specified source
4579 """pull changes from the specified source
4579
4580
4580 Pull changes from a remote repository to a local one.
4581 Pull changes from a remote repository to a local one.
4581
4582
4582 This finds all changes from the repository at the specified path
4583 This finds all changes from the repository at the specified path
4583 or URL and adds them to a local repository (the current one unless
4584 or URL and adds them to a local repository (the current one unless
4584 -R is specified). By default, this does not update the copy of the
4585 -R is specified). By default, this does not update the copy of the
4585 project in the working directory.
4586 project in the working directory.
4586
4587
4587 Use :hg:`incoming` if you want to see what would have been added
4588 Use :hg:`incoming` if you want to see what would have been added
4588 by a pull at the time you issued this command. If you then decide
4589 by a pull at the time you issued this command. If you then decide
4589 to add those changes to the repository, you should use :hg:`pull
4590 to add those changes to the repository, you should use :hg:`pull
4590 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4591 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4591
4592
4592 If SOURCE is omitted, the 'default' path will be used.
4593 If SOURCE is omitted, the 'default' path will be used.
4593 See :hg:`help urls` for more information.
4594 See :hg:`help urls` for more information.
4594
4595
4595 Returns 0 on success, 1 if an update had unresolved files.
4596 Returns 0 on success, 1 if an update had unresolved files.
4596 """
4597 """
4597 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4598 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4598 other = hg.peer(repo, opts, source)
4599 other = hg.peer(repo, opts, source)
4599 try:
4600 try:
4600 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4601 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4601 revs, checkout = hg.addbranchrevs(repo, other, branches,
4602 revs, checkout = hg.addbranchrevs(repo, other, branches,
4602 opts.get('rev'))
4603 opts.get('rev'))
4603
4604
4604 remotebookmarks = other.listkeys('bookmarks')
4605 remotebookmarks = other.listkeys('bookmarks')
4605
4606
4606 if opts.get('bookmark'):
4607 if opts.get('bookmark'):
4607 if not revs:
4608 if not revs:
4608 revs = []
4609 revs = []
4609 for b in opts['bookmark']:
4610 for b in opts['bookmark']:
4610 if b not in remotebookmarks:
4611 if b not in remotebookmarks:
4611 raise util.Abort(_('remote bookmark %s not found!') % b)
4612 raise util.Abort(_('remote bookmark %s not found!') % b)
4612 revs.append(remotebookmarks[b])
4613 revs.append(remotebookmarks[b])
4613
4614
4614 if revs:
4615 if revs:
4615 try:
4616 try:
4616 revs = [other.lookup(rev) for rev in revs]
4617 revs = [other.lookup(rev) for rev in revs]
4617 except error.CapabilityError:
4618 except error.CapabilityError:
4618 err = _("other repository doesn't support revision lookup, "
4619 err = _("other repository doesn't support revision lookup, "
4619 "so a rev cannot be specified.")
4620 "so a rev cannot be specified.")
4620 raise util.Abort(err)
4621 raise util.Abort(err)
4621
4622
4622 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4623 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4623 bookmarks.updatefromremote(ui, repo, remotebookmarks, source)
4624 bookmarks.updatefromremote(ui, repo, remotebookmarks, source)
4624 if checkout:
4625 if checkout:
4625 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4626 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4626 repo._subtoppath = source
4627 repo._subtoppath = source
4627 try:
4628 try:
4628 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4629 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4629
4630
4630 finally:
4631 finally:
4631 del repo._subtoppath
4632 del repo._subtoppath
4632
4633
4633 # update specified bookmarks
4634 # update specified bookmarks
4634 if opts.get('bookmark'):
4635 if opts.get('bookmark'):
4635 marks = repo._bookmarks
4636 marks = repo._bookmarks
4636 for b in opts['bookmark']:
4637 for b in opts['bookmark']:
4637 # explicit pull overrides local bookmark if any
4638 # explicit pull overrides local bookmark if any
4638 ui.status(_("importing bookmark %s\n") % b)
4639 ui.status(_("importing bookmark %s\n") % b)
4639 marks[b] = repo[remotebookmarks[b]].node()
4640 marks[b] = repo[remotebookmarks[b]].node()
4640 marks.write()
4641 marks.write()
4641 finally:
4642 finally:
4642 other.close()
4643 other.close()
4643 return ret
4644 return ret
4644
4645
4645 @command('^push',
4646 @command('^push',
4646 [('f', 'force', None, _('force push')),
4647 [('f', 'force', None, _('force push')),
4647 ('r', 'rev', [],
4648 ('r', 'rev', [],
4648 _('a changeset intended to be included in the destination'),
4649 _('a changeset intended to be included in the destination'),
4649 _('REV')),
4650 _('REV')),
4650 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4651 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4651 ('b', 'branch', [],
4652 ('b', 'branch', [],
4652 _('a specific branch you would like to push'), _('BRANCH')),
4653 _('a specific branch you would like to push'), _('BRANCH')),
4653 ('', 'new-branch', False, _('allow pushing a new branch')),
4654 ('', 'new-branch', False, _('allow pushing a new branch')),
4654 ] + remoteopts,
4655 ] + remoteopts,
4655 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4656 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4656 def push(ui, repo, dest=None, **opts):
4657 def push(ui, repo, dest=None, **opts):
4657 """push changes to the specified destination
4658 """push changes to the specified destination
4658
4659
4659 Push changesets from the local repository to the specified
4660 Push changesets from the local repository to the specified
4660 destination.
4661 destination.
4661
4662
4662 This operation is symmetrical to pull: it is identical to a pull
4663 This operation is symmetrical to pull: it is identical to a pull
4663 in the destination repository from the current one.
4664 in the destination repository from the current one.
4664
4665
4665 By default, push will not allow creation of new heads at the
4666 By default, push will not allow creation of new heads at the
4666 destination, since multiple heads would make it unclear which head
4667 destination, since multiple heads would make it unclear which head
4667 to use. In this situation, it is recommended to pull and merge
4668 to use. In this situation, it is recommended to pull and merge
4668 before pushing.
4669 before pushing.
4669
4670
4670 Use --new-branch if you want to allow push to create a new named
4671 Use --new-branch if you want to allow push to create a new named
4671 branch that is not present at the destination. This allows you to
4672 branch that is not present at the destination. This allows you to
4672 only create a new branch without forcing other changes.
4673 only create a new branch without forcing other changes.
4673
4674
4674 .. note::
4675 .. note::
4675
4676
4676 Extra care should be taken with the -f/--force option,
4677 Extra care should be taken with the -f/--force option,
4677 which will push all new heads on all branches, an action which will
4678 which will push all new heads on all branches, an action which will
4678 almost always cause confusion for collaborators.
4679 almost always cause confusion for collaborators.
4679
4680
4680 If -r/--rev is used, the specified revision and all its ancestors
4681 If -r/--rev is used, the specified revision and all its ancestors
4681 will be pushed to the remote repository.
4682 will be pushed to the remote repository.
4682
4683
4683 If -B/--bookmark is used, the specified bookmarked revision, its
4684 If -B/--bookmark is used, the specified bookmarked revision, its
4684 ancestors, and the bookmark will be pushed to the remote
4685 ancestors, and the bookmark will be pushed to the remote
4685 repository.
4686 repository.
4686
4687
4687 Please see :hg:`help urls` for important details about ``ssh://``
4688 Please see :hg:`help urls` for important details about ``ssh://``
4688 URLs. If DESTINATION is omitted, a default path will be used.
4689 URLs. If DESTINATION is omitted, a default path will be used.
4689
4690
4690 Returns 0 if push was successful, 1 if nothing to push.
4691 Returns 0 if push was successful, 1 if nothing to push.
4691 """
4692 """
4692
4693
4693 if opts.get('bookmark'):
4694 if opts.get('bookmark'):
4694 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4695 ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
4695 for b in opts['bookmark']:
4696 for b in opts['bookmark']:
4696 # translate -B options to -r so changesets get pushed
4697 # translate -B options to -r so changesets get pushed
4697 if b in repo._bookmarks:
4698 if b in repo._bookmarks:
4698 opts.setdefault('rev', []).append(b)
4699 opts.setdefault('rev', []).append(b)
4699 else:
4700 else:
4700 # if we try to push a deleted bookmark, translate it to null
4701 # if we try to push a deleted bookmark, translate it to null
4701 # this lets simultaneous -r, -b options continue working
4702 # this lets simultaneous -r, -b options continue working
4702 opts.setdefault('rev', []).append("null")
4703 opts.setdefault('rev', []).append("null")
4703
4704
4704 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4705 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4705 dest, branches = hg.parseurl(dest, opts.get('branch'))
4706 dest, branches = hg.parseurl(dest, opts.get('branch'))
4706 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4707 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4707 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4708 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4708 try:
4709 try:
4709 other = hg.peer(repo, opts, dest)
4710 other = hg.peer(repo, opts, dest)
4710 except error.RepoError:
4711 except error.RepoError:
4711 if dest == "default-push":
4712 if dest == "default-push":
4712 raise util.Abort(_("default repository not configured!"),
4713 raise util.Abort(_("default repository not configured!"),
4713 hint=_('see the "path" section in "hg help config"'))
4714 hint=_('see the "path" section in "hg help config"'))
4714 else:
4715 else:
4715 raise
4716 raise
4716
4717
4717 if revs:
4718 if revs:
4718 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
4719 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
4719
4720
4720 repo._subtoppath = dest
4721 repo._subtoppath = dest
4721 try:
4722 try:
4722 # push subrepos depth-first for coherent ordering
4723 # push subrepos depth-first for coherent ordering
4723 c = repo['']
4724 c = repo['']
4724 subs = c.substate # only repos that are committed
4725 subs = c.substate # only repos that are committed
4725 for s in sorted(subs):
4726 for s in sorted(subs):
4726 result = c.sub(s).push(opts)
4727 result = c.sub(s).push(opts)
4727 if result == 0:
4728 if result == 0:
4728 return not result
4729 return not result
4729 finally:
4730 finally:
4730 del repo._subtoppath
4731 del repo._subtoppath
4731 result = repo.push(other, opts.get('force'), revs=revs,
4732 result = repo.push(other, opts.get('force'), revs=revs,
4732 newbranch=opts.get('new_branch'))
4733 newbranch=opts.get('new_branch'))
4733
4734
4734 result = not result
4735 result = not result
4735
4736
4736 if opts.get('bookmark'):
4737 if opts.get('bookmark'):
4737 bresult = bookmarks.pushtoremote(ui, repo, other, opts['bookmark'])
4738 bresult = bookmarks.pushtoremote(ui, repo, other, opts['bookmark'])
4738 if bresult == 2:
4739 if bresult == 2:
4739 return 2
4740 return 2
4740 if not result and bresult:
4741 if not result and bresult:
4741 result = 2
4742 result = 2
4742
4743
4743 return result
4744 return result
4744
4745
4745 @command('recover', [])
4746 @command('recover', [])
4746 def recover(ui, repo):
4747 def recover(ui, repo):
4747 """roll back an interrupted transaction
4748 """roll back an interrupted transaction
4748
4749
4749 Recover from an interrupted commit or pull.
4750 Recover from an interrupted commit or pull.
4750
4751
4751 This command tries to fix the repository status after an
4752 This command tries to fix the repository status after an
4752 interrupted operation. It should only be necessary when Mercurial
4753 interrupted operation. It should only be necessary when Mercurial
4753 suggests it.
4754 suggests it.
4754
4755
4755 Returns 0 if successful, 1 if nothing to recover or verify fails.
4756 Returns 0 if successful, 1 if nothing to recover or verify fails.
4756 """
4757 """
4757 if repo.recover():
4758 if repo.recover():
4758 return hg.verify(repo)
4759 return hg.verify(repo)
4759 return 1
4760 return 1
4760
4761
4761 @command('^remove|rm',
4762 @command('^remove|rm',
4762 [('A', 'after', None, _('record delete for missing files')),
4763 [('A', 'after', None, _('record delete for missing files')),
4763 ('f', 'force', None,
4764 ('f', 'force', None,
4764 _('remove (and delete) file even if added or modified')),
4765 _('remove (and delete) file even if added or modified')),
4765 ] + walkopts,
4766 ] + walkopts,
4766 _('[OPTION]... FILE...'))
4767 _('[OPTION]... FILE...'))
4767 def remove(ui, repo, *pats, **opts):
4768 def remove(ui, repo, *pats, **opts):
4768 """remove the specified files on the next commit
4769 """remove the specified files on the next commit
4769
4770
4770 Schedule the indicated files for removal from the current branch.
4771 Schedule the indicated files for removal from the current branch.
4771
4772
4772 This command schedules the files to be removed at the next commit.
4773 This command schedules the files to be removed at the next commit.
4773 To undo a remove before that, see :hg:`revert`. To undo added
4774 To undo a remove before that, see :hg:`revert`. To undo added
4774 files, see :hg:`forget`.
4775 files, see :hg:`forget`.
4775
4776
4776 .. container:: verbose
4777 .. container:: verbose
4777
4778
4778 -A/--after can be used to remove only files that have already
4779 -A/--after can be used to remove only files that have already
4779 been deleted, -f/--force can be used to force deletion, and -Af
4780 been deleted, -f/--force can be used to force deletion, and -Af
4780 can be used to remove files from the next revision without
4781 can be used to remove files from the next revision without
4781 deleting them from the working directory.
4782 deleting them from the working directory.
4782
4783
4783 The following table details the behavior of remove for different
4784 The following table details the behavior of remove for different
4784 file states (columns) and option combinations (rows). The file
4785 file states (columns) and option combinations (rows). The file
4785 states are Added [A], Clean [C], Modified [M] and Missing [!]
4786 states are Added [A], Clean [C], Modified [M] and Missing [!]
4786 (as reported by :hg:`status`). The actions are Warn, Remove
4787 (as reported by :hg:`status`). The actions are Warn, Remove
4787 (from branch) and Delete (from disk):
4788 (from branch) and Delete (from disk):
4788
4789
4789 ========= == == == ==
4790 ========= == == == ==
4790 opt/state A C M !
4791 opt/state A C M !
4791 ========= == == == ==
4792 ========= == == == ==
4792 none W RD W R
4793 none W RD W R
4793 -f R RD RD R
4794 -f R RD RD R
4794 -A W W W R
4795 -A W W W R
4795 -Af R R R R
4796 -Af R R R R
4796 ========= == == == ==
4797 ========= == == == ==
4797
4798
4798 Note that remove never deletes files in Added [A] state from the
4799 Note that remove never deletes files in Added [A] state from the
4799 working directory, not even if option --force is specified.
4800 working directory, not even if option --force is specified.
4800
4801
4801 Returns 0 on success, 1 if any warnings encountered.
4802 Returns 0 on success, 1 if any warnings encountered.
4802 """
4803 """
4803
4804
4804 ret = 0
4805 ret = 0
4805 after, force = opts.get('after'), opts.get('force')
4806 after, force = opts.get('after'), opts.get('force')
4806 if not pats and not after:
4807 if not pats and not after:
4807 raise util.Abort(_('no files specified'))
4808 raise util.Abort(_('no files specified'))
4808
4809
4809 m = scmutil.match(repo[None], pats, opts)
4810 m = scmutil.match(repo[None], pats, opts)
4810 s = repo.status(match=m, clean=True)
4811 s = repo.status(match=m, clean=True)
4811 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4812 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4812
4813
4813 # warn about failure to delete explicit files/dirs
4814 # warn about failure to delete explicit files/dirs
4814 wctx = repo[None]
4815 wctx = repo[None]
4815 for f in m.files():
4816 for f in m.files():
4816 if f in repo.dirstate or f in wctx.dirs():
4817 if f in repo.dirstate or f in wctx.dirs():
4817 continue
4818 continue
4818 if os.path.exists(m.rel(f)):
4819 if os.path.exists(m.rel(f)):
4819 if os.path.isdir(m.rel(f)):
4820 if os.path.isdir(m.rel(f)):
4820 ui.warn(_('not removing %s: no tracked files\n') % m.rel(f))
4821 ui.warn(_('not removing %s: no tracked files\n') % m.rel(f))
4821 else:
4822 else:
4822 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4823 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4823 # missing files will generate a warning elsewhere
4824 # missing files will generate a warning elsewhere
4824 ret = 1
4825 ret = 1
4825
4826
4826 if force:
4827 if force:
4827 list = modified + deleted + clean + added
4828 list = modified + deleted + clean + added
4828 elif after:
4829 elif after:
4829 list = deleted
4830 list = deleted
4830 for f in modified + added + clean:
4831 for f in modified + added + clean:
4831 ui.warn(_('not removing %s: file still exists\n') % m.rel(f))
4832 ui.warn(_('not removing %s: file still exists\n') % m.rel(f))
4832 ret = 1
4833 ret = 1
4833 else:
4834 else:
4834 list = deleted + clean
4835 list = deleted + clean
4835 for f in modified:
4836 for f in modified:
4836 ui.warn(_('not removing %s: file is modified (use -f'
4837 ui.warn(_('not removing %s: file is modified (use -f'
4837 ' to force removal)\n') % m.rel(f))
4838 ' to force removal)\n') % m.rel(f))
4838 ret = 1
4839 ret = 1
4839 for f in added:
4840 for f in added:
4840 ui.warn(_('not removing %s: file has been marked for add'
4841 ui.warn(_('not removing %s: file has been marked for add'
4841 ' (use forget to undo)\n') % m.rel(f))
4842 ' (use forget to undo)\n') % m.rel(f))
4842 ret = 1
4843 ret = 1
4843
4844
4844 for f in sorted(list):
4845 for f in sorted(list):
4845 if ui.verbose or not m.exact(f):
4846 if ui.verbose or not m.exact(f):
4846 ui.status(_('removing %s\n') % m.rel(f))
4847 ui.status(_('removing %s\n') % m.rel(f))
4847
4848
4848 wlock = repo.wlock()
4849 wlock = repo.wlock()
4849 try:
4850 try:
4850 if not after:
4851 if not after:
4851 for f in list:
4852 for f in list:
4852 if f in added:
4853 if f in added:
4853 continue # we never unlink added files on remove
4854 continue # we never unlink added files on remove
4854 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
4855 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
4855 repo[None].forget(list)
4856 repo[None].forget(list)
4856 finally:
4857 finally:
4857 wlock.release()
4858 wlock.release()
4858
4859
4859 return ret
4860 return ret
4860
4861
4861 @command('rename|move|mv',
4862 @command('rename|move|mv',
4862 [('A', 'after', None, _('record a rename that has already occurred')),
4863 [('A', 'after', None, _('record a rename that has already occurred')),
4863 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4864 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4864 ] + walkopts + dryrunopts,
4865 ] + walkopts + dryrunopts,
4865 _('[OPTION]... SOURCE... DEST'))
4866 _('[OPTION]... SOURCE... DEST'))
4866 def rename(ui, repo, *pats, **opts):
4867 def rename(ui, repo, *pats, **opts):
4867 """rename files; equivalent of copy + remove
4868 """rename files; equivalent of copy + remove
4868
4869
4869 Mark dest as copies of sources; mark sources for deletion. If dest
4870 Mark dest as copies of sources; mark sources for deletion. If dest
4870 is a directory, copies are put in that directory. If dest is a
4871 is a directory, copies are put in that directory. If dest is a
4871 file, there can only be one source.
4872 file, there can only be one source.
4872
4873
4873 By default, this command copies the contents of files as they
4874 By default, this command copies the contents of files as they
4874 exist in the working directory. If invoked with -A/--after, the
4875 exist in the working directory. If invoked with -A/--after, the
4875 operation is recorded, but no copying is performed.
4876 operation is recorded, but no copying is performed.
4876
4877
4877 This command takes effect at the next commit. To undo a rename
4878 This command takes effect at the next commit. To undo a rename
4878 before that, see :hg:`revert`.
4879 before that, see :hg:`revert`.
4879
4880
4880 Returns 0 on success, 1 if errors are encountered.
4881 Returns 0 on success, 1 if errors are encountered.
4881 """
4882 """
4882 wlock = repo.wlock(False)
4883 wlock = repo.wlock(False)
4883 try:
4884 try:
4884 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4885 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4885 finally:
4886 finally:
4886 wlock.release()
4887 wlock.release()
4887
4888
4888 @command('resolve',
4889 @command('resolve',
4889 [('a', 'all', None, _('select all unresolved files')),
4890 [('a', 'all', None, _('select all unresolved files')),
4890 ('l', 'list', None, _('list state of files needing merge')),
4891 ('l', 'list', None, _('list state of files needing merge')),
4891 ('m', 'mark', None, _('mark files as resolved')),
4892 ('m', 'mark', None, _('mark files as resolved')),
4892 ('u', 'unmark', None, _('mark files as unresolved')),
4893 ('u', 'unmark', None, _('mark files as unresolved')),
4893 ('n', 'no-status', None, _('hide status prefix'))]
4894 ('n', 'no-status', None, _('hide status prefix'))]
4894 + mergetoolopts + walkopts,
4895 + mergetoolopts + walkopts,
4895 _('[OPTION]... [FILE]...'))
4896 _('[OPTION]... [FILE]...'))
4896 def resolve(ui, repo, *pats, **opts):
4897 def resolve(ui, repo, *pats, **opts):
4897 """redo merges or set/view the merge status of files
4898 """redo merges or set/view the merge status of files
4898
4899
4899 Merges with unresolved conflicts are often the result of
4900 Merges with unresolved conflicts are often the result of
4900 non-interactive merging using the ``internal:merge`` configuration
4901 non-interactive merging using the ``internal:merge`` configuration
4901 setting, or a command-line merge tool like ``diff3``. The resolve
4902 setting, or a command-line merge tool like ``diff3``. The resolve
4902 command is used to manage the files involved in a merge, after
4903 command is used to manage the files involved in a merge, after
4903 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4904 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4904 working directory must have two parents). See :hg:`help
4905 working directory must have two parents). See :hg:`help
4905 merge-tools` for information on configuring merge tools.
4906 merge-tools` for information on configuring merge tools.
4906
4907
4907 The resolve command can be used in the following ways:
4908 The resolve command can be used in the following ways:
4908
4909
4909 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4910 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4910 files, discarding any previous merge attempts. Re-merging is not
4911 files, discarding any previous merge attempts. Re-merging is not
4911 performed for files already marked as resolved. Use ``--all/-a``
4912 performed for files already marked as resolved. Use ``--all/-a``
4912 to select all unresolved files. ``--tool`` can be used to specify
4913 to select all unresolved files. ``--tool`` can be used to specify
4913 the merge tool used for the given files. It overrides the HGMERGE
4914 the merge tool used for the given files. It overrides the HGMERGE
4914 environment variable and your configuration files. Previous file
4915 environment variable and your configuration files. Previous file
4915 contents are saved with a ``.orig`` suffix.
4916 contents are saved with a ``.orig`` suffix.
4916
4917
4917 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4918 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4918 (e.g. after having manually fixed-up the files). The default is
4919 (e.g. after having manually fixed-up the files). The default is
4919 to mark all unresolved files.
4920 to mark all unresolved files.
4920
4921
4921 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4922 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4922 default is to mark all resolved files.
4923 default is to mark all resolved files.
4923
4924
4924 - :hg:`resolve -l`: list files which had or still have conflicts.
4925 - :hg:`resolve -l`: list files which had or still have conflicts.
4925 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4926 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4926
4927
4927 Note that Mercurial will not let you commit files with unresolved
4928 Note that Mercurial will not let you commit files with unresolved
4928 merge conflicts. You must use :hg:`resolve -m ...` before you can
4929 merge conflicts. You must use :hg:`resolve -m ...` before you can
4929 commit after a conflicting merge.
4930 commit after a conflicting merge.
4930
4931
4931 Returns 0 on success, 1 if any files fail a resolve attempt.
4932 Returns 0 on success, 1 if any files fail a resolve attempt.
4932 """
4933 """
4933
4934
4934 all, mark, unmark, show, nostatus = \
4935 all, mark, unmark, show, nostatus = \
4935 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4936 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4936
4937
4937 if (show and (mark or unmark)) or (mark and unmark):
4938 if (show and (mark or unmark)) or (mark and unmark):
4938 raise util.Abort(_("too many options specified"))
4939 raise util.Abort(_("too many options specified"))
4939 if pats and all:
4940 if pats and all:
4940 raise util.Abort(_("can't specify --all and patterns"))
4941 raise util.Abort(_("can't specify --all and patterns"))
4941 if not (all or pats or show or mark or unmark):
4942 if not (all or pats or show or mark or unmark):
4942 raise util.Abort(_('no files or directories specified; '
4943 raise util.Abort(_('no files or directories specified; '
4943 'use --all to remerge all files'))
4944 'use --all to remerge all files'))
4944
4945
4945 ms = mergemod.mergestate(repo)
4946 ms = mergemod.mergestate(repo)
4946
4947
4947 if not ms.active() and not show:
4948 if not ms.active() and not show:
4948 raise util.Abort(_('resolve command not applicable when not merging'))
4949 raise util.Abort(_('resolve command not applicable when not merging'))
4949
4950
4950 m = scmutil.match(repo[None], pats, opts)
4951 m = scmutil.match(repo[None], pats, opts)
4951 ret = 0
4952 ret = 0
4952
4953
4953 didwork = False
4954 didwork = False
4954 for f in ms:
4955 for f in ms:
4955 if not m(f):
4956 if not m(f):
4956 continue
4957 continue
4957
4958
4958 didwork = True
4959 didwork = True
4959
4960
4960 if show:
4961 if show:
4961 if nostatus:
4962 if nostatus:
4962 ui.write("%s\n" % f)
4963 ui.write("%s\n" % f)
4963 else:
4964 else:
4964 ui.write("%s %s\n" % (ms[f].upper(), f),
4965 ui.write("%s %s\n" % (ms[f].upper(), f),
4965 label='resolve.' +
4966 label='resolve.' +
4966 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4967 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4967 elif mark:
4968 elif mark:
4968 ms.mark(f, "r")
4969 ms.mark(f, "r")
4969 elif unmark:
4970 elif unmark:
4970 ms.mark(f, "u")
4971 ms.mark(f, "u")
4971 else:
4972 else:
4972 wctx = repo[None]
4973 wctx = repo[None]
4973
4974
4974 # backup pre-resolve (merge uses .orig for its own purposes)
4975 # backup pre-resolve (merge uses .orig for its own purposes)
4975 a = repo.wjoin(f)
4976 a = repo.wjoin(f)
4976 util.copyfile(a, a + ".resolve")
4977 util.copyfile(a, a + ".resolve")
4977
4978
4978 try:
4979 try:
4979 # resolve file
4980 # resolve file
4980 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4981 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
4981 'resolve')
4982 'resolve')
4982 if ms.resolve(f, wctx):
4983 if ms.resolve(f, wctx):
4983 ret = 1
4984 ret = 1
4984 finally:
4985 finally:
4985 ui.setconfig('ui', 'forcemerge', '', 'resolve')
4986 ui.setconfig('ui', 'forcemerge', '', 'resolve')
4986 ms.commit()
4987 ms.commit()
4987
4988
4988 # replace filemerge's .orig file with our resolve file
4989 # replace filemerge's .orig file with our resolve file
4989 util.rename(a + ".resolve", a + ".orig")
4990 util.rename(a + ".resolve", a + ".orig")
4990
4991
4991 ms.commit()
4992 ms.commit()
4992
4993
4993 if not didwork and pats:
4994 if not didwork and pats:
4994 ui.warn(_("arguments do not match paths that need resolved\n"))
4995 ui.warn(_("arguments do not match paths that need resolved\n"))
4995
4996
4996 # Nudge users into finishing an unfinished operation. We don't print
4997 # Nudge users into finishing an unfinished operation. We don't print
4997 # this with the list/show operation because we want list/show to remain
4998 # this with the list/show operation because we want list/show to remain
4998 # machine readable.
4999 # machine readable.
4999 if not list(ms.unresolved()) and not show:
5000 if not list(ms.unresolved()) and not show:
5000 ui.status(_('no more unresolved files\n'))
5001 ui.status(_('no more unresolved files\n'))
5001
5002
5002 return ret
5003 return ret
5003
5004
5004 @command('revert',
5005 @command('revert',
5005 [('a', 'all', None, _('revert all changes when no arguments given')),
5006 [('a', 'all', None, _('revert all changes when no arguments given')),
5006 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5007 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5007 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5008 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
5008 ('C', 'no-backup', None, _('do not save backup copies of files')),
5009 ('C', 'no-backup', None, _('do not save backup copies of files')),
5009 ] + walkopts + dryrunopts,
5010 ] + walkopts + dryrunopts,
5010 _('[OPTION]... [-r REV] [NAME]...'))
5011 _('[OPTION]... [-r REV] [NAME]...'))
5011 def revert(ui, repo, *pats, **opts):
5012 def revert(ui, repo, *pats, **opts):
5012 """restore files to their checkout state
5013 """restore files to their checkout state
5013
5014
5014 .. note::
5015 .. note::
5015
5016
5016 To check out earlier revisions, you should use :hg:`update REV`.
5017 To check out earlier revisions, you should use :hg:`update REV`.
5017 To cancel an uncommitted merge (and lose your changes),
5018 To cancel an uncommitted merge (and lose your changes),
5018 use :hg:`update --clean .`.
5019 use :hg:`update --clean .`.
5019
5020
5020 With no revision specified, revert the specified files or directories
5021 With no revision specified, revert the specified files or directories
5021 to the contents they had in the parent of the working directory.
5022 to the contents they had in the parent of the working directory.
5022 This restores the contents of files to an unmodified
5023 This restores the contents of files to an unmodified
5023 state and unschedules adds, removes, copies, and renames. If the
5024 state and unschedules adds, removes, copies, and renames. If the
5024 working directory has two parents, you must explicitly specify a
5025 working directory has two parents, you must explicitly specify a
5025 revision.
5026 revision.
5026
5027
5027 Using the -r/--rev or -d/--date options, revert the given files or
5028 Using the -r/--rev or -d/--date options, revert the given files or
5028 directories to their states as of a specific revision. Because
5029 directories to their states as of a specific revision. Because
5029 revert does not change the working directory parents, this will
5030 revert does not change the working directory parents, this will
5030 cause these files to appear modified. This can be helpful to "back
5031 cause these files to appear modified. This can be helpful to "back
5031 out" some or all of an earlier change. See :hg:`backout` for a
5032 out" some or all of an earlier change. See :hg:`backout` for a
5032 related method.
5033 related method.
5033
5034
5034 Modified files are saved with a .orig suffix before reverting.
5035 Modified files are saved with a .orig suffix before reverting.
5035 To disable these backups, use --no-backup.
5036 To disable these backups, use --no-backup.
5036
5037
5037 See :hg:`help dates` for a list of formats valid for -d/--date.
5038 See :hg:`help dates` for a list of formats valid for -d/--date.
5038
5039
5039 Returns 0 on success.
5040 Returns 0 on success.
5040 """
5041 """
5041
5042
5042 if opts.get("date"):
5043 if opts.get("date"):
5043 if opts.get("rev"):
5044 if opts.get("rev"):
5044 raise util.Abort(_("you can't specify a revision and a date"))
5045 raise util.Abort(_("you can't specify a revision and a date"))
5045 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5046 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5046
5047
5047 parent, p2 = repo.dirstate.parents()
5048 parent, p2 = repo.dirstate.parents()
5048 if not opts.get('rev') and p2 != nullid:
5049 if not opts.get('rev') and p2 != nullid:
5049 # revert after merge is a trap for new users (issue2915)
5050 # revert after merge is a trap for new users (issue2915)
5050 raise util.Abort(_('uncommitted merge with no revision specified'),
5051 raise util.Abort(_('uncommitted merge with no revision specified'),
5051 hint=_('use "hg update" or see "hg help revert"'))
5052 hint=_('use "hg update" or see "hg help revert"'))
5052
5053
5053 ctx = scmutil.revsingle(repo, opts.get('rev'))
5054 ctx = scmutil.revsingle(repo, opts.get('rev'))
5054
5055
5055 if not pats and not opts.get('all'):
5056 if not pats and not opts.get('all'):
5056 msg = _("no files or directories specified")
5057 msg = _("no files or directories specified")
5057 if p2 != nullid:
5058 if p2 != nullid:
5058 hint = _("uncommitted merge, use --all to discard all changes,"
5059 hint = _("uncommitted merge, use --all to discard all changes,"
5059 " or 'hg update -C .' to abort the merge")
5060 " or 'hg update -C .' to abort the merge")
5060 raise util.Abort(msg, hint=hint)
5061 raise util.Abort(msg, hint=hint)
5061 dirty = util.any(repo.status())
5062 dirty = util.any(repo.status())
5062 node = ctx.node()
5063 node = ctx.node()
5063 if node != parent:
5064 if node != parent:
5064 if dirty:
5065 if dirty:
5065 hint = _("uncommitted changes, use --all to discard all"
5066 hint = _("uncommitted changes, use --all to discard all"
5066 " changes, or 'hg update %s' to update") % ctx.rev()
5067 " changes, or 'hg update %s' to update") % ctx.rev()
5067 else:
5068 else:
5068 hint = _("use --all to revert all files,"
5069 hint = _("use --all to revert all files,"
5069 " or 'hg update %s' to update") % ctx.rev()
5070 " or 'hg update %s' to update") % ctx.rev()
5070 elif dirty:
5071 elif dirty:
5071 hint = _("uncommitted changes, use --all to discard all changes")
5072 hint = _("uncommitted changes, use --all to discard all changes")
5072 else:
5073 else:
5073 hint = _("use --all to revert all files")
5074 hint = _("use --all to revert all files")
5074 raise util.Abort(msg, hint=hint)
5075 raise util.Abort(msg, hint=hint)
5075
5076
5076 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5077 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5077
5078
5078 @command('rollback', dryrunopts +
5079 @command('rollback', dryrunopts +
5079 [('f', 'force', False, _('ignore safety measures'))])
5080 [('f', 'force', False, _('ignore safety measures'))])
5080 def rollback(ui, repo, **opts):
5081 def rollback(ui, repo, **opts):
5081 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5082 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5082
5083
5083 Please use :hg:`commit --amend` instead of rollback to correct
5084 Please use :hg:`commit --amend` instead of rollback to correct
5084 mistakes in the last commit.
5085 mistakes in the last commit.
5085
5086
5086 This command should be used with care. There is only one level of
5087 This command should be used with care. There is only one level of
5087 rollback, and there is no way to undo a rollback. It will also
5088 rollback, and there is no way to undo a rollback. It will also
5088 restore the dirstate at the time of the last transaction, losing
5089 restore the dirstate at the time of the last transaction, losing
5089 any dirstate changes since that time. This command does not alter
5090 any dirstate changes since that time. This command does not alter
5090 the working directory.
5091 the working directory.
5091
5092
5092 Transactions are used to encapsulate the effects of all commands
5093 Transactions are used to encapsulate the effects of all commands
5093 that create new changesets or propagate existing changesets into a
5094 that create new changesets or propagate existing changesets into a
5094 repository.
5095 repository.
5095
5096
5096 .. container:: verbose
5097 .. container:: verbose
5097
5098
5098 For example, the following commands are transactional, and their
5099 For example, the following commands are transactional, and their
5099 effects can be rolled back:
5100 effects can be rolled back:
5100
5101
5101 - commit
5102 - commit
5102 - import
5103 - import
5103 - pull
5104 - pull
5104 - push (with this repository as the destination)
5105 - push (with this repository as the destination)
5105 - unbundle
5106 - unbundle
5106
5107
5107 To avoid permanent data loss, rollback will refuse to rollback a
5108 To avoid permanent data loss, rollback will refuse to rollback a
5108 commit transaction if it isn't checked out. Use --force to
5109 commit transaction if it isn't checked out. Use --force to
5109 override this protection.
5110 override this protection.
5110
5111
5111 This command is not intended for use on public repositories. Once
5112 This command is not intended for use on public repositories. Once
5112 changes are visible for pull by other users, rolling a transaction
5113 changes are visible for pull by other users, rolling a transaction
5113 back locally is ineffective (someone else may already have pulled
5114 back locally is ineffective (someone else may already have pulled
5114 the changes). Furthermore, a race is possible with readers of the
5115 the changes). Furthermore, a race is possible with readers of the
5115 repository; for example an in-progress pull from the repository
5116 repository; for example an in-progress pull from the repository
5116 may fail if a rollback is performed.
5117 may fail if a rollback is performed.
5117
5118
5118 Returns 0 on success, 1 if no rollback data is available.
5119 Returns 0 on success, 1 if no rollback data is available.
5119 """
5120 """
5120 return repo.rollback(dryrun=opts.get('dry_run'),
5121 return repo.rollback(dryrun=opts.get('dry_run'),
5121 force=opts.get('force'))
5122 force=opts.get('force'))
5122
5123
5123 @command('root', [])
5124 @command('root', [])
5124 def root(ui, repo):
5125 def root(ui, repo):
5125 """print the root (top) of the current working directory
5126 """print the root (top) of the current working directory
5126
5127
5127 Print the root directory of the current repository.
5128 Print the root directory of the current repository.
5128
5129
5129 Returns 0 on success.
5130 Returns 0 on success.
5130 """
5131 """
5131 ui.write(repo.root + "\n")
5132 ui.write(repo.root + "\n")
5132
5133
5133 @command('^serve',
5134 @command('^serve',
5134 [('A', 'accesslog', '', _('name of access log file to write to'),
5135 [('A', 'accesslog', '', _('name of access log file to write to'),
5135 _('FILE')),
5136 _('FILE')),
5136 ('d', 'daemon', None, _('run server in background')),
5137 ('d', 'daemon', None, _('run server in background')),
5137 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
5138 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
5138 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5139 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5139 # use string type, then we can check if something was passed
5140 # use string type, then we can check if something was passed
5140 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5141 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5141 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5142 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5142 _('ADDR')),
5143 _('ADDR')),
5143 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5144 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5144 _('PREFIX')),
5145 _('PREFIX')),
5145 ('n', 'name', '',
5146 ('n', 'name', '',
5146 _('name to show in web pages (default: working directory)'), _('NAME')),
5147 _('name to show in web pages (default: working directory)'), _('NAME')),
5147 ('', 'web-conf', '',
5148 ('', 'web-conf', '',
5148 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5149 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5149 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5150 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5150 _('FILE')),
5151 _('FILE')),
5151 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5152 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5152 ('', 'stdio', None, _('for remote clients')),
5153 ('', 'stdio', None, _('for remote clients')),
5153 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5154 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5154 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5155 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5155 ('', 'style', '', _('template style to use'), _('STYLE')),
5156 ('', 'style', '', _('template style to use'), _('STYLE')),
5156 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5157 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5157 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5158 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5158 _('[OPTION]...'))
5159 _('[OPTION]...'))
5159 def serve(ui, repo, **opts):
5160 def serve(ui, repo, **opts):
5160 """start stand-alone webserver
5161 """start stand-alone webserver
5161
5162
5162 Start a local HTTP repository browser and pull server. You can use
5163 Start a local HTTP repository browser and pull server. You can use
5163 this for ad-hoc sharing and browsing of repositories. It is
5164 this for ad-hoc sharing and browsing of repositories. It is
5164 recommended to use a real web server to serve a repository for
5165 recommended to use a real web server to serve a repository for
5165 longer periods of time.
5166 longer periods of time.
5166
5167
5167 Please note that the server does not implement access control.
5168 Please note that the server does not implement access control.
5168 This means that, by default, anybody can read from the server and
5169 This means that, by default, anybody can read from the server and
5169 nobody can write to it by default. Set the ``web.allow_push``
5170 nobody can write to it by default. Set the ``web.allow_push``
5170 option to ``*`` to allow everybody to push to the server. You
5171 option to ``*`` to allow everybody to push to the server. You
5171 should use a real web server if you need to authenticate users.
5172 should use a real web server if you need to authenticate users.
5172
5173
5173 By default, the server logs accesses to stdout and errors to
5174 By default, the server logs accesses to stdout and errors to
5174 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5175 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5175 files.
5176 files.
5176
5177
5177 To have the server choose a free port number to listen on, specify
5178 To have the server choose a free port number to listen on, specify
5178 a port number of 0; in this case, the server will print the port
5179 a port number of 0; in this case, the server will print the port
5179 number it uses.
5180 number it uses.
5180
5181
5181 Returns 0 on success.
5182 Returns 0 on success.
5182 """
5183 """
5183
5184
5184 if opts["stdio"] and opts["cmdserver"]:
5185 if opts["stdio"] and opts["cmdserver"]:
5185 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5186 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5186
5187
5187 def checkrepo():
5188 def checkrepo():
5188 if repo is None:
5189 if repo is None:
5189 raise error.RepoError(_("there is no Mercurial repository here"
5190 raise error.RepoError(_("there is no Mercurial repository here"
5190 " (.hg not found)"))
5191 " (.hg not found)"))
5191
5192
5192 if opts["stdio"]:
5193 if opts["stdio"]:
5193 checkrepo()
5194 checkrepo()
5194 s = sshserver.sshserver(ui, repo)
5195 s = sshserver.sshserver(ui, repo)
5195 s.serve_forever()
5196 s.serve_forever()
5196
5197
5197 if opts["cmdserver"]:
5198 if opts["cmdserver"]:
5198 s = commandserver.server(ui, repo, opts["cmdserver"])
5199 s = commandserver.server(ui, repo, opts["cmdserver"])
5199 return s.serve()
5200 return s.serve()
5200
5201
5201 # this way we can check if something was given in the command-line
5202 # this way we can check if something was given in the command-line
5202 if opts.get('port'):
5203 if opts.get('port'):
5203 opts['port'] = util.getport(opts.get('port'))
5204 opts['port'] = util.getport(opts.get('port'))
5204
5205
5205 baseui = repo and repo.baseui or ui
5206 baseui = repo and repo.baseui or ui
5206 optlist = ("name templates style address port prefix ipv6"
5207 optlist = ("name templates style address port prefix ipv6"
5207 " accesslog errorlog certificate encoding")
5208 " accesslog errorlog certificate encoding")
5208 for o in optlist.split():
5209 for o in optlist.split():
5209 val = opts.get(o, '')
5210 val = opts.get(o, '')
5210 if val in (None, ''): # should check against default options instead
5211 if val in (None, ''): # should check against default options instead
5211 continue
5212 continue
5212 baseui.setconfig("web", o, val, 'serve')
5213 baseui.setconfig("web", o, val, 'serve')
5213 if repo and repo.ui != baseui:
5214 if repo and repo.ui != baseui:
5214 repo.ui.setconfig("web", o, val, 'serve')
5215 repo.ui.setconfig("web", o, val, 'serve')
5215
5216
5216 o = opts.get('web_conf') or opts.get('webdir_conf')
5217 o = opts.get('web_conf') or opts.get('webdir_conf')
5217 if not o:
5218 if not o:
5218 if not repo:
5219 if not repo:
5219 raise error.RepoError(_("there is no Mercurial repository"
5220 raise error.RepoError(_("there is no Mercurial repository"
5220 " here (.hg not found)"))
5221 " here (.hg not found)"))
5221 o = repo
5222 o = repo
5222
5223
5223 app = hgweb.hgweb(o, baseui=baseui)
5224 app = hgweb.hgweb(o, baseui=baseui)
5224 service = httpservice(ui, app, opts)
5225 service = httpservice(ui, app, opts)
5225 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5226 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5226
5227
5227 class httpservice(object):
5228 class httpservice(object):
5228 def __init__(self, ui, app, opts):
5229 def __init__(self, ui, app, opts):
5229 self.ui = ui
5230 self.ui = ui
5230 self.app = app
5231 self.app = app
5231 self.opts = opts
5232 self.opts = opts
5232
5233
5233 def init(self):
5234 def init(self):
5234 util.setsignalhandler()
5235 util.setsignalhandler()
5235 self.httpd = hgweb_server.create_server(self.ui, self.app)
5236 self.httpd = hgweb_server.create_server(self.ui, self.app)
5236
5237
5237 if self.opts['port'] and not self.ui.verbose:
5238 if self.opts['port'] and not self.ui.verbose:
5238 return
5239 return
5239
5240
5240 if self.httpd.prefix:
5241 if self.httpd.prefix:
5241 prefix = self.httpd.prefix.strip('/') + '/'
5242 prefix = self.httpd.prefix.strip('/') + '/'
5242 else:
5243 else:
5243 prefix = ''
5244 prefix = ''
5244
5245
5245 port = ':%d' % self.httpd.port
5246 port = ':%d' % self.httpd.port
5246 if port == ':80':
5247 if port == ':80':
5247 port = ''
5248 port = ''
5248
5249
5249 bindaddr = self.httpd.addr
5250 bindaddr = self.httpd.addr
5250 if bindaddr == '0.0.0.0':
5251 if bindaddr == '0.0.0.0':
5251 bindaddr = '*'
5252 bindaddr = '*'
5252 elif ':' in bindaddr: # IPv6
5253 elif ':' in bindaddr: # IPv6
5253 bindaddr = '[%s]' % bindaddr
5254 bindaddr = '[%s]' % bindaddr
5254
5255
5255 fqaddr = self.httpd.fqaddr
5256 fqaddr = self.httpd.fqaddr
5256 if ':' in fqaddr:
5257 if ':' in fqaddr:
5257 fqaddr = '[%s]' % fqaddr
5258 fqaddr = '[%s]' % fqaddr
5258 if self.opts['port']:
5259 if self.opts['port']:
5259 write = self.ui.status
5260 write = self.ui.status
5260 else:
5261 else:
5261 write = self.ui.write
5262 write = self.ui.write
5262 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5263 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5263 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5264 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5264
5265
5265 def run(self):
5266 def run(self):
5266 self.httpd.serve_forever()
5267 self.httpd.serve_forever()
5267
5268
5268
5269
5269 @command('^status|st',
5270 @command('^status|st',
5270 [('A', 'all', None, _('show status of all files')),
5271 [('A', 'all', None, _('show status of all files')),
5271 ('m', 'modified', None, _('show only modified files')),
5272 ('m', 'modified', None, _('show only modified files')),
5272 ('a', 'added', None, _('show only added files')),
5273 ('a', 'added', None, _('show only added files')),
5273 ('r', 'removed', None, _('show only removed files')),
5274 ('r', 'removed', None, _('show only removed files')),
5274 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5275 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5275 ('c', 'clean', None, _('show only files without changes')),
5276 ('c', 'clean', None, _('show only files without changes')),
5276 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5277 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5277 ('i', 'ignored', None, _('show only ignored files')),
5278 ('i', 'ignored', None, _('show only ignored files')),
5278 ('n', 'no-status', None, _('hide status prefix')),
5279 ('n', 'no-status', None, _('hide status prefix')),
5279 ('C', 'copies', None, _('show source of copied files')),
5280 ('C', 'copies', None, _('show source of copied files')),
5280 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5281 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5281 ('', 'rev', [], _('show difference from revision'), _('REV')),
5282 ('', 'rev', [], _('show difference from revision'), _('REV')),
5282 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5283 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5283 ] + walkopts + subrepoopts,
5284 ] + walkopts + subrepoopts,
5284 _('[OPTION]... [FILE]...'))
5285 _('[OPTION]... [FILE]...'))
5285 def status(ui, repo, *pats, **opts):
5286 def status(ui, repo, *pats, **opts):
5286 """show changed files in the working directory
5287 """show changed files in the working directory
5287
5288
5288 Show status of files in the repository. If names are given, only
5289 Show status of files in the repository. If names are given, only
5289 files that match are shown. Files that are clean or ignored or
5290 files that match are shown. Files that are clean or ignored or
5290 the source of a copy/move operation, are not listed unless
5291 the source of a copy/move operation, are not listed unless
5291 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5292 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5292 Unless options described with "show only ..." are given, the
5293 Unless options described with "show only ..." are given, the
5293 options -mardu are used.
5294 options -mardu are used.
5294
5295
5295 Option -q/--quiet hides untracked (unknown and ignored) files
5296 Option -q/--quiet hides untracked (unknown and ignored) files
5296 unless explicitly requested with -u/--unknown or -i/--ignored.
5297 unless explicitly requested with -u/--unknown or -i/--ignored.
5297
5298
5298 .. note::
5299 .. note::
5299
5300
5300 status may appear to disagree with diff if permissions have
5301 status may appear to disagree with diff if permissions have
5301 changed or a merge has occurred. The standard diff format does
5302 changed or a merge has occurred. The standard diff format does
5302 not report permission changes and diff only reports changes
5303 not report permission changes and diff only reports changes
5303 relative to one merge parent.
5304 relative to one merge parent.
5304
5305
5305 If one revision is given, it is used as the base revision.
5306 If one revision is given, it is used as the base revision.
5306 If two revisions are given, the differences between them are
5307 If two revisions are given, the differences between them are
5307 shown. The --change option can also be used as a shortcut to list
5308 shown. The --change option can also be used as a shortcut to list
5308 the changed files of a revision from its first parent.
5309 the changed files of a revision from its first parent.
5309
5310
5310 The codes used to show the status of files are::
5311 The codes used to show the status of files are::
5311
5312
5312 M = modified
5313 M = modified
5313 A = added
5314 A = added
5314 R = removed
5315 R = removed
5315 C = clean
5316 C = clean
5316 ! = missing (deleted by non-hg command, but still tracked)
5317 ! = missing (deleted by non-hg command, but still tracked)
5317 ? = not tracked
5318 ? = not tracked
5318 I = ignored
5319 I = ignored
5319 = origin of the previous file (with --copies)
5320 = origin of the previous file (with --copies)
5320
5321
5321 .. container:: verbose
5322 .. container:: verbose
5322
5323
5323 Examples:
5324 Examples:
5324
5325
5325 - show changes in the working directory relative to a
5326 - show changes in the working directory relative to a
5326 changeset::
5327 changeset::
5327
5328
5328 hg status --rev 9353
5329 hg status --rev 9353
5329
5330
5330 - show all changes including copies in an existing changeset::
5331 - show all changes including copies in an existing changeset::
5331
5332
5332 hg status --copies --change 9353
5333 hg status --copies --change 9353
5333
5334
5334 - get a NUL separated list of added files, suitable for xargs::
5335 - get a NUL separated list of added files, suitable for xargs::
5335
5336
5336 hg status -an0
5337 hg status -an0
5337
5338
5338 Returns 0 on success.
5339 Returns 0 on success.
5339 """
5340 """
5340
5341
5341 revs = opts.get('rev')
5342 revs = opts.get('rev')
5342 change = opts.get('change')
5343 change = opts.get('change')
5343
5344
5344 if revs and change:
5345 if revs and change:
5345 msg = _('cannot specify --rev and --change at the same time')
5346 msg = _('cannot specify --rev and --change at the same time')
5346 raise util.Abort(msg)
5347 raise util.Abort(msg)
5347 elif change:
5348 elif change:
5348 node2 = scmutil.revsingle(repo, change, None).node()
5349 node2 = scmutil.revsingle(repo, change, None).node()
5349 node1 = repo[node2].p1().node()
5350 node1 = repo[node2].p1().node()
5350 else:
5351 else:
5351 node1, node2 = scmutil.revpair(repo, revs)
5352 node1, node2 = scmutil.revpair(repo, revs)
5352
5353
5353 cwd = (pats and repo.getcwd()) or ''
5354 cwd = (pats and repo.getcwd()) or ''
5354 end = opts.get('print0') and '\0' or '\n'
5355 end = opts.get('print0') and '\0' or '\n'
5355 copy = {}
5356 copy = {}
5356 states = 'modified added removed deleted unknown ignored clean'.split()
5357 states = 'modified added removed deleted unknown ignored clean'.split()
5357 show = [k for k in states if opts.get(k)]
5358 show = [k for k in states if opts.get(k)]
5358 if opts.get('all'):
5359 if opts.get('all'):
5359 show += ui.quiet and (states[:4] + ['clean']) or states
5360 show += ui.quiet and (states[:4] + ['clean']) or states
5360 if not show:
5361 if not show:
5361 show = ui.quiet and states[:4] or states[:5]
5362 show = ui.quiet and states[:4] or states[:5]
5362
5363
5363 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5364 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5364 'ignored' in show, 'clean' in show, 'unknown' in show,
5365 'ignored' in show, 'clean' in show, 'unknown' in show,
5365 opts.get('subrepos'))
5366 opts.get('subrepos'))
5366 changestates = zip(states, 'MAR!?IC', stat)
5367 changestates = zip(states, 'MAR!?IC', stat)
5367
5368
5368 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5369 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5369 copy = copies.pathcopies(repo[node1], repo[node2])
5370 copy = copies.pathcopies(repo[node1], repo[node2])
5370
5371
5371 fm = ui.formatter('status', opts)
5372 fm = ui.formatter('status', opts)
5372 fmt = '%s' + end
5373 fmt = '%s' + end
5373 showchar = not opts.get('no_status')
5374 showchar = not opts.get('no_status')
5374
5375
5375 for state, char, files in changestates:
5376 for state, char, files in changestates:
5376 if state in show:
5377 if state in show:
5377 label = 'status.' + state
5378 label = 'status.' + state
5378 for f in files:
5379 for f in files:
5379 fm.startitem()
5380 fm.startitem()
5380 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5381 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5381 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5382 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5382 if f in copy:
5383 if f in copy:
5383 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5384 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5384 label='status.copied')
5385 label='status.copied')
5385 fm.end()
5386 fm.end()
5386
5387
5387 @command('^summary|sum',
5388 @command('^summary|sum',
5388 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5389 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5389 def summary(ui, repo, **opts):
5390 def summary(ui, repo, **opts):
5390 """summarize working directory state
5391 """summarize working directory state
5391
5392
5392 This generates a brief summary of the working directory state,
5393 This generates a brief summary of the working directory state,
5393 including parents, branch, commit status, and available updates.
5394 including parents, branch, commit status, and available updates.
5394
5395
5395 With the --remote option, this will check the default paths for
5396 With the --remote option, this will check the default paths for
5396 incoming and outgoing changes. This can be time-consuming.
5397 incoming and outgoing changes. This can be time-consuming.
5397
5398
5398 Returns 0 on success.
5399 Returns 0 on success.
5399 """
5400 """
5400
5401
5401 ctx = repo[None]
5402 ctx = repo[None]
5402 parents = ctx.parents()
5403 parents = ctx.parents()
5403 pnode = parents[0].node()
5404 pnode = parents[0].node()
5404 marks = []
5405 marks = []
5405
5406
5406 for p in parents:
5407 for p in parents:
5407 # label with log.changeset (instead of log.parent) since this
5408 # label with log.changeset (instead of log.parent) since this
5408 # shows a working directory parent *changeset*:
5409 # shows a working directory parent *changeset*:
5409 # i18n: column positioning for "hg summary"
5410 # i18n: column positioning for "hg summary"
5410 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5411 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5411 label='log.changeset changeset.%s' % p.phasestr())
5412 label='log.changeset changeset.%s' % p.phasestr())
5412 ui.write(' '.join(p.tags()), label='log.tag')
5413 ui.write(' '.join(p.tags()), label='log.tag')
5413 if p.bookmarks():
5414 if p.bookmarks():
5414 marks.extend(p.bookmarks())
5415 marks.extend(p.bookmarks())
5415 if p.rev() == -1:
5416 if p.rev() == -1:
5416 if not len(repo):
5417 if not len(repo):
5417 ui.write(_(' (empty repository)'))
5418 ui.write(_(' (empty repository)'))
5418 else:
5419 else:
5419 ui.write(_(' (no revision checked out)'))
5420 ui.write(_(' (no revision checked out)'))
5420 ui.write('\n')
5421 ui.write('\n')
5421 if p.description():
5422 if p.description():
5422 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5423 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5423 label='log.summary')
5424 label='log.summary')
5424
5425
5425 branch = ctx.branch()
5426 branch = ctx.branch()
5426 bheads = repo.branchheads(branch)
5427 bheads = repo.branchheads(branch)
5427 # i18n: column positioning for "hg summary"
5428 # i18n: column positioning for "hg summary"
5428 m = _('branch: %s\n') % branch
5429 m = _('branch: %s\n') % branch
5429 if branch != 'default':
5430 if branch != 'default':
5430 ui.write(m, label='log.branch')
5431 ui.write(m, label='log.branch')
5431 else:
5432 else:
5432 ui.status(m, label='log.branch')
5433 ui.status(m, label='log.branch')
5433
5434
5434 if marks:
5435 if marks:
5435 current = repo._bookmarkcurrent
5436 current = repo._bookmarkcurrent
5436 # i18n: column positioning for "hg summary"
5437 # i18n: column positioning for "hg summary"
5437 ui.write(_('bookmarks:'), label='log.bookmark')
5438 ui.write(_('bookmarks:'), label='log.bookmark')
5438 if current is not None:
5439 if current is not None:
5439 if current in marks:
5440 if current in marks:
5440 ui.write(' *' + current, label='bookmarks.current')
5441 ui.write(' *' + current, label='bookmarks.current')
5441 marks.remove(current)
5442 marks.remove(current)
5442 else:
5443 else:
5443 ui.write(' [%s]' % current, label='bookmarks.current')
5444 ui.write(' [%s]' % current, label='bookmarks.current')
5444 for m in marks:
5445 for m in marks:
5445 ui.write(' ' + m, label='log.bookmark')
5446 ui.write(' ' + m, label='log.bookmark')
5446 ui.write('\n', label='log.bookmark')
5447 ui.write('\n', label='log.bookmark')
5447
5448
5448 st = list(repo.status(unknown=True))[:6]
5449 st = list(repo.status(unknown=True))[:6]
5449
5450
5450 c = repo.dirstate.copies()
5451 c = repo.dirstate.copies()
5451 copied, renamed = [], []
5452 copied, renamed = [], []
5452 for d, s in c.iteritems():
5453 for d, s in c.iteritems():
5453 if s in st[2]:
5454 if s in st[2]:
5454 st[2].remove(s)
5455 st[2].remove(s)
5455 renamed.append(d)
5456 renamed.append(d)
5456 else:
5457 else:
5457 copied.append(d)
5458 copied.append(d)
5458 if d in st[1]:
5459 if d in st[1]:
5459 st[1].remove(d)
5460 st[1].remove(d)
5460 st.insert(3, renamed)
5461 st.insert(3, renamed)
5461 st.insert(4, copied)
5462 st.insert(4, copied)
5462
5463
5463 ms = mergemod.mergestate(repo)
5464 ms = mergemod.mergestate(repo)
5464 st.append([f for f in ms if ms[f] == 'u'])
5465 st.append([f for f in ms if ms[f] == 'u'])
5465
5466
5466 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5467 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5467 st.append(subs)
5468 st.append(subs)
5468
5469
5469 labels = [ui.label(_('%d modified'), 'status.modified'),
5470 labels = [ui.label(_('%d modified'), 'status.modified'),
5470 ui.label(_('%d added'), 'status.added'),
5471 ui.label(_('%d added'), 'status.added'),
5471 ui.label(_('%d removed'), 'status.removed'),
5472 ui.label(_('%d removed'), 'status.removed'),
5472 ui.label(_('%d renamed'), 'status.copied'),
5473 ui.label(_('%d renamed'), 'status.copied'),
5473 ui.label(_('%d copied'), 'status.copied'),
5474 ui.label(_('%d copied'), 'status.copied'),
5474 ui.label(_('%d deleted'), 'status.deleted'),
5475 ui.label(_('%d deleted'), 'status.deleted'),
5475 ui.label(_('%d unknown'), 'status.unknown'),
5476 ui.label(_('%d unknown'), 'status.unknown'),
5476 ui.label(_('%d ignored'), 'status.ignored'),
5477 ui.label(_('%d ignored'), 'status.ignored'),
5477 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5478 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5478 ui.label(_('%d subrepos'), 'status.modified')]
5479 ui.label(_('%d subrepos'), 'status.modified')]
5479 t = []
5480 t = []
5480 for s, l in zip(st, labels):
5481 for s, l in zip(st, labels):
5481 if s:
5482 if s:
5482 t.append(l % len(s))
5483 t.append(l % len(s))
5483
5484
5484 t = ', '.join(t)
5485 t = ', '.join(t)
5485 cleanworkdir = False
5486 cleanworkdir = False
5486
5487
5487 if repo.vfs.exists('updatestate'):
5488 if repo.vfs.exists('updatestate'):
5488 t += _(' (interrupted update)')
5489 t += _(' (interrupted update)')
5489 elif len(parents) > 1:
5490 elif len(parents) > 1:
5490 t += _(' (merge)')
5491 t += _(' (merge)')
5491 elif branch != parents[0].branch():
5492 elif branch != parents[0].branch():
5492 t += _(' (new branch)')
5493 t += _(' (new branch)')
5493 elif (parents[0].closesbranch() and
5494 elif (parents[0].closesbranch() and
5494 pnode in repo.branchheads(branch, closed=True)):
5495 pnode in repo.branchheads(branch, closed=True)):
5495 t += _(' (head closed)')
5496 t += _(' (head closed)')
5496 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5497 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5497 t += _(' (clean)')
5498 t += _(' (clean)')
5498 cleanworkdir = True
5499 cleanworkdir = True
5499 elif pnode not in bheads:
5500 elif pnode not in bheads:
5500 t += _(' (new branch head)')
5501 t += _(' (new branch head)')
5501
5502
5502 if cleanworkdir:
5503 if cleanworkdir:
5503 # i18n: column positioning for "hg summary"
5504 # i18n: column positioning for "hg summary"
5504 ui.status(_('commit: %s\n') % t.strip())
5505 ui.status(_('commit: %s\n') % t.strip())
5505 else:
5506 else:
5506 # i18n: column positioning for "hg summary"
5507 # i18n: column positioning for "hg summary"
5507 ui.write(_('commit: %s\n') % t.strip())
5508 ui.write(_('commit: %s\n') % t.strip())
5508
5509
5509 # all ancestors of branch heads - all ancestors of parent = new csets
5510 # all ancestors of branch heads - all ancestors of parent = new csets
5510 new = len(repo.changelog.findmissing([ctx.node() for ctx in parents],
5511 new = len(repo.changelog.findmissing([ctx.node() for ctx in parents],
5511 bheads))
5512 bheads))
5512
5513
5513 if new == 0:
5514 if new == 0:
5514 # i18n: column positioning for "hg summary"
5515 # i18n: column positioning for "hg summary"
5515 ui.status(_('update: (current)\n'))
5516 ui.status(_('update: (current)\n'))
5516 elif pnode not in bheads:
5517 elif pnode not in bheads:
5517 # i18n: column positioning for "hg summary"
5518 # i18n: column positioning for "hg summary"
5518 ui.write(_('update: %d new changesets (update)\n') % new)
5519 ui.write(_('update: %d new changesets (update)\n') % new)
5519 else:
5520 else:
5520 # i18n: column positioning for "hg summary"
5521 # i18n: column positioning for "hg summary"
5521 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5522 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5522 (new, len(bheads)))
5523 (new, len(bheads)))
5523
5524
5524 cmdutil.summaryhooks(ui, repo)
5525 cmdutil.summaryhooks(ui, repo)
5525
5526
5526 if opts.get('remote'):
5527 if opts.get('remote'):
5527 needsincoming, needsoutgoing = True, True
5528 needsincoming, needsoutgoing = True, True
5528 else:
5529 else:
5529 needsincoming, needsoutgoing = False, False
5530 needsincoming, needsoutgoing = False, False
5530 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5531 for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
5531 if i:
5532 if i:
5532 needsincoming = True
5533 needsincoming = True
5533 if o:
5534 if o:
5534 needsoutgoing = True
5535 needsoutgoing = True
5535 if not needsincoming and not needsoutgoing:
5536 if not needsincoming and not needsoutgoing:
5536 return
5537 return
5537
5538
5538 def getincoming():
5539 def getincoming():
5539 source, branches = hg.parseurl(ui.expandpath('default'))
5540 source, branches = hg.parseurl(ui.expandpath('default'))
5540 sbranch = branches[0]
5541 sbranch = branches[0]
5541 try:
5542 try:
5542 other = hg.peer(repo, {}, source)
5543 other = hg.peer(repo, {}, source)
5543 except error.RepoError:
5544 except error.RepoError:
5544 if opts.get('remote'):
5545 if opts.get('remote'):
5545 raise
5546 raise
5546 return source, sbranch, None, None, None
5547 return source, sbranch, None, None, None
5547 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5548 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5548 if revs:
5549 if revs:
5549 revs = [other.lookup(rev) for rev in revs]
5550 revs = [other.lookup(rev) for rev in revs]
5550 ui.debug('comparing with %s\n' % util.hidepassword(source))
5551 ui.debug('comparing with %s\n' % util.hidepassword(source))
5551 repo.ui.pushbuffer()
5552 repo.ui.pushbuffer()
5552 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5553 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5553 repo.ui.popbuffer()
5554 repo.ui.popbuffer()
5554 return source, sbranch, other, commoninc, commoninc[1]
5555 return source, sbranch, other, commoninc, commoninc[1]
5555
5556
5556 if needsincoming:
5557 if needsincoming:
5557 source, sbranch, sother, commoninc, incoming = getincoming()
5558 source, sbranch, sother, commoninc, incoming = getincoming()
5558 else:
5559 else:
5559 source = sbranch = sother = commoninc = incoming = None
5560 source = sbranch = sother = commoninc = incoming = None
5560
5561
5561 def getoutgoing():
5562 def getoutgoing():
5562 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5563 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5563 dbranch = branches[0]
5564 dbranch = branches[0]
5564 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5565 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5565 if source != dest:
5566 if source != dest:
5566 try:
5567 try:
5567 dother = hg.peer(repo, {}, dest)
5568 dother = hg.peer(repo, {}, dest)
5568 except error.RepoError:
5569 except error.RepoError:
5569 if opts.get('remote'):
5570 if opts.get('remote'):
5570 raise
5571 raise
5571 return dest, dbranch, None, None
5572 return dest, dbranch, None, None
5572 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5573 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5573 elif sother is None:
5574 elif sother is None:
5574 # there is no explicit destination peer, but source one is invalid
5575 # there is no explicit destination peer, but source one is invalid
5575 return dest, dbranch, None, None
5576 return dest, dbranch, None, None
5576 else:
5577 else:
5577 dother = sother
5578 dother = sother
5578 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5579 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5579 common = None
5580 common = None
5580 else:
5581 else:
5581 common = commoninc
5582 common = commoninc
5582 if revs:
5583 if revs:
5583 revs = [repo.lookup(rev) for rev in revs]
5584 revs = [repo.lookup(rev) for rev in revs]
5584 repo.ui.pushbuffer()
5585 repo.ui.pushbuffer()
5585 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5586 outgoing = discovery.findcommonoutgoing(repo, dother, onlyheads=revs,
5586 commoninc=common)
5587 commoninc=common)
5587 repo.ui.popbuffer()
5588 repo.ui.popbuffer()
5588 return dest, dbranch, dother, outgoing
5589 return dest, dbranch, dother, outgoing
5589
5590
5590 if needsoutgoing:
5591 if needsoutgoing:
5591 dest, dbranch, dother, outgoing = getoutgoing()
5592 dest, dbranch, dother, outgoing = getoutgoing()
5592 else:
5593 else:
5593 dest = dbranch = dother = outgoing = None
5594 dest = dbranch = dother = outgoing = None
5594
5595
5595 if opts.get('remote'):
5596 if opts.get('remote'):
5596 t = []
5597 t = []
5597 if incoming:
5598 if incoming:
5598 t.append(_('1 or more incoming'))
5599 t.append(_('1 or more incoming'))
5599 o = outgoing.missing
5600 o = outgoing.missing
5600 if o:
5601 if o:
5601 t.append(_('%d outgoing') % len(o))
5602 t.append(_('%d outgoing') % len(o))
5602 other = dother or sother
5603 other = dother or sother
5603 if 'bookmarks' in other.listkeys('namespaces'):
5604 if 'bookmarks' in other.listkeys('namespaces'):
5604 lmarks = repo.listkeys('bookmarks')
5605 lmarks = repo.listkeys('bookmarks')
5605 rmarks = other.listkeys('bookmarks')
5606 rmarks = other.listkeys('bookmarks')
5606 diff = set(rmarks) - set(lmarks)
5607 diff = set(rmarks) - set(lmarks)
5607 if len(diff) > 0:
5608 if len(diff) > 0:
5608 t.append(_('%d incoming bookmarks') % len(diff))
5609 t.append(_('%d incoming bookmarks') % len(diff))
5609 diff = set(lmarks) - set(rmarks)
5610 diff = set(lmarks) - set(rmarks)
5610 if len(diff) > 0:
5611 if len(diff) > 0:
5611 t.append(_('%d outgoing bookmarks') % len(diff))
5612 t.append(_('%d outgoing bookmarks') % len(diff))
5612
5613
5613 if t:
5614 if t:
5614 # i18n: column positioning for "hg summary"
5615 # i18n: column positioning for "hg summary"
5615 ui.write(_('remote: %s\n') % (', '.join(t)))
5616 ui.write(_('remote: %s\n') % (', '.join(t)))
5616 else:
5617 else:
5617 # i18n: column positioning for "hg summary"
5618 # i18n: column positioning for "hg summary"
5618 ui.status(_('remote: (synced)\n'))
5619 ui.status(_('remote: (synced)\n'))
5619
5620
5620 cmdutil.summaryremotehooks(ui, repo, opts,
5621 cmdutil.summaryremotehooks(ui, repo, opts,
5621 ((source, sbranch, sother, commoninc),
5622 ((source, sbranch, sother, commoninc),
5622 (dest, dbranch, dother, outgoing)))
5623 (dest, dbranch, dother, outgoing)))
5623
5624
5624 @command('tag',
5625 @command('tag',
5625 [('f', 'force', None, _('force tag')),
5626 [('f', 'force', None, _('force tag')),
5626 ('l', 'local', None, _('make the tag local')),
5627 ('l', 'local', None, _('make the tag local')),
5627 ('r', 'rev', '', _('revision to tag'), _('REV')),
5628 ('r', 'rev', '', _('revision to tag'), _('REV')),
5628 ('', 'remove', None, _('remove a tag')),
5629 ('', 'remove', None, _('remove a tag')),
5629 # -l/--local is already there, commitopts cannot be used
5630 # -l/--local is already there, commitopts cannot be used
5630 ('e', 'edit', None, _('edit commit message')),
5631 ('e', 'edit', None, _('edit commit message')),
5631 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5632 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5632 ] + commitopts2,
5633 ] + commitopts2,
5633 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5634 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5634 def tag(ui, repo, name1, *names, **opts):
5635 def tag(ui, repo, name1, *names, **opts):
5635 """add one or more tags for the current or given revision
5636 """add one or more tags for the current or given revision
5636
5637
5637 Name a particular revision using <name>.
5638 Name a particular revision using <name>.
5638
5639
5639 Tags are used to name particular revisions of the repository and are
5640 Tags are used to name particular revisions of the repository and are
5640 very useful to compare different revisions, to go back to significant
5641 very useful to compare different revisions, to go back to significant
5641 earlier versions or to mark branch points as releases, etc. Changing
5642 earlier versions or to mark branch points as releases, etc. Changing
5642 an existing tag is normally disallowed; use -f/--force to override.
5643 an existing tag is normally disallowed; use -f/--force to override.
5643
5644
5644 If no revision is given, the parent of the working directory is
5645 If no revision is given, the parent of the working directory is
5645 used.
5646 used.
5646
5647
5647 To facilitate version control, distribution, and merging of tags,
5648 To facilitate version control, distribution, and merging of tags,
5648 they are stored as a file named ".hgtags" which is managed similarly
5649 they are stored as a file named ".hgtags" which is managed similarly
5649 to other project files and can be hand-edited if necessary. This
5650 to other project files and can be hand-edited if necessary. This
5650 also means that tagging creates a new commit. The file
5651 also means that tagging creates a new commit. The file
5651 ".hg/localtags" is used for local tags (not shared among
5652 ".hg/localtags" is used for local tags (not shared among
5652 repositories).
5653 repositories).
5653
5654
5654 Tag commits are usually made at the head of a branch. If the parent
5655 Tag commits are usually made at the head of a branch. If the parent
5655 of the working directory is not a branch head, :hg:`tag` aborts; use
5656 of the working directory is not a branch head, :hg:`tag` aborts; use
5656 -f/--force to force the tag commit to be based on a non-head
5657 -f/--force to force the tag commit to be based on a non-head
5657 changeset.
5658 changeset.
5658
5659
5659 See :hg:`help dates` for a list of formats valid for -d/--date.
5660 See :hg:`help dates` for a list of formats valid for -d/--date.
5660
5661
5661 Since tag names have priority over branch names during revision
5662 Since tag names have priority over branch names during revision
5662 lookup, using an existing branch name as a tag name is discouraged.
5663 lookup, using an existing branch name as a tag name is discouraged.
5663
5664
5664 Returns 0 on success.
5665 Returns 0 on success.
5665 """
5666 """
5666 wlock = lock = None
5667 wlock = lock = None
5667 try:
5668 try:
5668 wlock = repo.wlock()
5669 wlock = repo.wlock()
5669 lock = repo.lock()
5670 lock = repo.lock()
5670 rev_ = "."
5671 rev_ = "."
5671 names = [t.strip() for t in (name1,) + names]
5672 names = [t.strip() for t in (name1,) + names]
5672 if len(names) != len(set(names)):
5673 if len(names) != len(set(names)):
5673 raise util.Abort(_('tag names must be unique'))
5674 raise util.Abort(_('tag names must be unique'))
5674 for n in names:
5675 for n in names:
5675 scmutil.checknewlabel(repo, n, 'tag')
5676 scmutil.checknewlabel(repo, n, 'tag')
5676 if not n:
5677 if not n:
5677 raise util.Abort(_('tag names cannot consist entirely of '
5678 raise util.Abort(_('tag names cannot consist entirely of '
5678 'whitespace'))
5679 'whitespace'))
5679 if opts.get('rev') and opts.get('remove'):
5680 if opts.get('rev') and opts.get('remove'):
5680 raise util.Abort(_("--rev and --remove are incompatible"))
5681 raise util.Abort(_("--rev and --remove are incompatible"))
5681 if opts.get('rev'):
5682 if opts.get('rev'):
5682 rev_ = opts['rev']
5683 rev_ = opts['rev']
5683 message = opts.get('message')
5684 message = opts.get('message')
5684 if opts.get('remove'):
5685 if opts.get('remove'):
5685 expectedtype = opts.get('local') and 'local' or 'global'
5686 expectedtype = opts.get('local') and 'local' or 'global'
5686 for n in names:
5687 for n in names:
5687 if not repo.tagtype(n):
5688 if not repo.tagtype(n):
5688 raise util.Abort(_("tag '%s' does not exist") % n)
5689 raise util.Abort(_("tag '%s' does not exist") % n)
5689 if repo.tagtype(n) != expectedtype:
5690 if repo.tagtype(n) != expectedtype:
5690 if expectedtype == 'global':
5691 if expectedtype == 'global':
5691 raise util.Abort(_("tag '%s' is not a global tag") % n)
5692 raise util.Abort(_("tag '%s' is not a global tag") % n)
5692 else:
5693 else:
5693 raise util.Abort(_("tag '%s' is not a local tag") % n)
5694 raise util.Abort(_("tag '%s' is not a local tag") % n)
5694 rev_ = nullid
5695 rev_ = nullid
5695 if not message:
5696 if not message:
5696 # we don't translate commit messages
5697 # we don't translate commit messages
5697 message = 'Removed tag %s' % ', '.join(names)
5698 message = 'Removed tag %s' % ', '.join(names)
5698 elif not opts.get('force'):
5699 elif not opts.get('force'):
5699 for n in names:
5700 for n in names:
5700 if n in repo.tags():
5701 if n in repo.tags():
5701 raise util.Abort(_("tag '%s' already exists "
5702 raise util.Abort(_("tag '%s' already exists "
5702 "(use -f to force)") % n)
5703 "(use -f to force)") % n)
5703 if not opts.get('local'):
5704 if not opts.get('local'):
5704 p1, p2 = repo.dirstate.parents()
5705 p1, p2 = repo.dirstate.parents()
5705 if p2 != nullid:
5706 if p2 != nullid:
5706 raise util.Abort(_('uncommitted merge'))
5707 raise util.Abort(_('uncommitted merge'))
5707 bheads = repo.branchheads()
5708 bheads = repo.branchheads()
5708 if not opts.get('force') and bheads and p1 not in bheads:
5709 if not opts.get('force') and bheads and p1 not in bheads:
5709 raise util.Abort(_('not at a branch head (use -f to force)'))
5710 raise util.Abort(_('not at a branch head (use -f to force)'))
5710 r = scmutil.revsingle(repo, rev_).node()
5711 r = scmutil.revsingle(repo, rev_).node()
5711
5712
5712 if not message:
5713 if not message:
5713 # we don't translate commit messages
5714 # we don't translate commit messages
5714 message = ('Added tag %s for changeset %s' %
5715 message = ('Added tag %s for changeset %s' %
5715 (', '.join(names), short(r)))
5716 (', '.join(names), short(r)))
5716
5717
5717 date = opts.get('date')
5718 date = opts.get('date')
5718 if date:
5719 if date:
5719 date = util.parsedate(date)
5720 date = util.parsedate(date)
5720
5721
5721 editor = cmdutil.getcommiteditor(**opts)
5722 editor = cmdutil.getcommiteditor(**opts)
5722
5723
5723 # don't allow tagging the null rev
5724 # don't allow tagging the null rev
5724 if (not opts.get('remove') and
5725 if (not opts.get('remove') and
5725 scmutil.revsingle(repo, rev_).rev() == nullrev):
5726 scmutil.revsingle(repo, rev_).rev() == nullrev):
5726 raise util.Abort(_("cannot tag null revision"))
5727 raise util.Abort(_("cannot tag null revision"))
5727
5728
5728 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
5729 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date,
5729 editor=editor)
5730 editor=editor)
5730 finally:
5731 finally:
5731 release(lock, wlock)
5732 release(lock, wlock)
5732
5733
5733 @command('tags', [], '')
5734 @command('tags', [], '')
5734 def tags(ui, repo, **opts):
5735 def tags(ui, repo, **opts):
5735 """list repository tags
5736 """list repository tags
5736
5737
5737 This lists both regular and local tags. When the -v/--verbose
5738 This lists both regular and local tags. When the -v/--verbose
5738 switch is used, a third column "local" is printed for local tags.
5739 switch is used, a third column "local" is printed for local tags.
5739
5740
5740 Returns 0 on success.
5741 Returns 0 on success.
5741 """
5742 """
5742
5743
5743 fm = ui.formatter('tags', opts)
5744 fm = ui.formatter('tags', opts)
5744 hexfunc = ui.debugflag and hex or short
5745 hexfunc = ui.debugflag and hex or short
5745 tagtype = ""
5746 tagtype = ""
5746
5747
5747 for t, n in reversed(repo.tagslist()):
5748 for t, n in reversed(repo.tagslist()):
5748 hn = hexfunc(n)
5749 hn = hexfunc(n)
5749 label = 'tags.normal'
5750 label = 'tags.normal'
5750 tagtype = ''
5751 tagtype = ''
5751 if repo.tagtype(t) == 'local':
5752 if repo.tagtype(t) == 'local':
5752 label = 'tags.local'
5753 label = 'tags.local'
5753 tagtype = 'local'
5754 tagtype = 'local'
5754
5755
5755 fm.startitem()
5756 fm.startitem()
5756 fm.write('tag', '%s', t, label=label)
5757 fm.write('tag', '%s', t, label=label)
5757 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5758 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5758 fm.condwrite(not ui.quiet, 'rev id', fmt,
5759 fm.condwrite(not ui.quiet, 'rev id', fmt,
5759 repo.changelog.rev(n), hn, label=label)
5760 repo.changelog.rev(n), hn, label=label)
5760 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5761 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5761 tagtype, label=label)
5762 tagtype, label=label)
5762 fm.plain('\n')
5763 fm.plain('\n')
5763 fm.end()
5764 fm.end()
5764
5765
5765 @command('tip',
5766 @command('tip',
5766 [('p', 'patch', None, _('show patch')),
5767 [('p', 'patch', None, _('show patch')),
5767 ('g', 'git', None, _('use git extended diff format')),
5768 ('g', 'git', None, _('use git extended diff format')),
5768 ] + templateopts,
5769 ] + templateopts,
5769 _('[-p] [-g]'))
5770 _('[-p] [-g]'))
5770 def tip(ui, repo, **opts):
5771 def tip(ui, repo, **opts):
5771 """show the tip revision (DEPRECATED)
5772 """show the tip revision (DEPRECATED)
5772
5773
5773 The tip revision (usually just called the tip) is the changeset
5774 The tip revision (usually just called the tip) is the changeset
5774 most recently added to the repository (and therefore the most
5775 most recently added to the repository (and therefore the most
5775 recently changed head).
5776 recently changed head).
5776
5777
5777 If you have just made a commit, that commit will be the tip. If
5778 If you have just made a commit, that commit will be the tip. If
5778 you have just pulled changes from another repository, the tip of
5779 you have just pulled changes from another repository, the tip of
5779 that repository becomes the current tip. The "tip" tag is special
5780 that repository becomes the current tip. The "tip" tag is special
5780 and cannot be renamed or assigned to a different changeset.
5781 and cannot be renamed or assigned to a different changeset.
5781
5782
5782 This command is deprecated, please use :hg:`heads` instead.
5783 This command is deprecated, please use :hg:`heads` instead.
5783
5784
5784 Returns 0 on success.
5785 Returns 0 on success.
5785 """
5786 """
5786 displayer = cmdutil.show_changeset(ui, repo, opts)
5787 displayer = cmdutil.show_changeset(ui, repo, opts)
5787 displayer.show(repo['tip'])
5788 displayer.show(repo['tip'])
5788 displayer.close()
5789 displayer.close()
5789
5790
5790 @command('unbundle',
5791 @command('unbundle',
5791 [('u', 'update', None,
5792 [('u', 'update', None,
5792 _('update to new branch head if changesets were unbundled'))],
5793 _('update to new branch head if changesets were unbundled'))],
5793 _('[-u] FILE...'))
5794 _('[-u] FILE...'))
5794 def unbundle(ui, repo, fname1, *fnames, **opts):
5795 def unbundle(ui, repo, fname1, *fnames, **opts):
5795 """apply one or more changegroup files
5796 """apply one or more changegroup files
5796
5797
5797 Apply one or more compressed changegroup files generated by the
5798 Apply one or more compressed changegroup files generated by the
5798 bundle command.
5799 bundle command.
5799
5800
5800 Returns 0 on success, 1 if an update has unresolved files.
5801 Returns 0 on success, 1 if an update has unresolved files.
5801 """
5802 """
5802 fnames = (fname1,) + fnames
5803 fnames = (fname1,) + fnames
5803
5804
5804 lock = repo.lock()
5805 lock = repo.lock()
5805 wc = repo['.']
5806 wc = repo['.']
5806 try:
5807 try:
5807 for fname in fnames:
5808 for fname in fnames:
5808 f = hg.openpath(ui, fname)
5809 f = hg.openpath(ui, fname)
5809 gen = exchange.readbundle(ui, f, fname)
5810 gen = exchange.readbundle(ui, f, fname)
5810 modheads = changegroup.addchangegroup(repo, gen, 'unbundle',
5811 modheads = changegroup.addchangegroup(repo, gen, 'unbundle',
5811 'bundle:' + fname)
5812 'bundle:' + fname)
5812 finally:
5813 finally:
5813 lock.release()
5814 lock.release()
5814 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5815 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5815 return postincoming(ui, repo, modheads, opts.get('update'), None)
5816 return postincoming(ui, repo, modheads, opts.get('update'), None)
5816
5817
5817 @command('^update|up|checkout|co',
5818 @command('^update|up|checkout|co',
5818 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5819 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5819 ('c', 'check', None,
5820 ('c', 'check', None,
5820 _('update across branches if no uncommitted changes')),
5821 _('update across branches if no uncommitted changes')),
5821 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5822 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5822 ('r', 'rev', '', _('revision'), _('REV'))
5823 ('r', 'rev', '', _('revision'), _('REV'))
5823 ] + mergetoolopts,
5824 ] + mergetoolopts,
5824 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5825 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5825 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
5826 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False,
5826 tool=None):
5827 tool=None):
5827 """update working directory (or switch revisions)
5828 """update working directory (or switch revisions)
5828
5829
5829 Update the repository's working directory to the specified
5830 Update the repository's working directory to the specified
5830 changeset. If no changeset is specified, update to the tip of the
5831 changeset. If no changeset is specified, update to the tip of the
5831 current named branch and move the current bookmark (see :hg:`help
5832 current named branch and move the current bookmark (see :hg:`help
5832 bookmarks`).
5833 bookmarks`).
5833
5834
5834 Update sets the working directory's parent revision to the specified
5835 Update sets the working directory's parent revision to the specified
5835 changeset (see :hg:`help parents`).
5836 changeset (see :hg:`help parents`).
5836
5837
5837 If the changeset is not a descendant or ancestor of the working
5838 If the changeset is not a descendant or ancestor of the working
5838 directory's parent, the update is aborted. With the -c/--check
5839 directory's parent, the update is aborted. With the -c/--check
5839 option, the working directory is checked for uncommitted changes; if
5840 option, the working directory is checked for uncommitted changes; if
5840 none are found, the working directory is updated to the specified
5841 none are found, the working directory is updated to the specified
5841 changeset.
5842 changeset.
5842
5843
5843 .. container:: verbose
5844 .. container:: verbose
5844
5845
5845 The following rules apply when the working directory contains
5846 The following rules apply when the working directory contains
5846 uncommitted changes:
5847 uncommitted changes:
5847
5848
5848 1. If neither -c/--check nor -C/--clean is specified, and if
5849 1. If neither -c/--check nor -C/--clean is specified, and if
5849 the requested changeset is an ancestor or descendant of
5850 the requested changeset is an ancestor or descendant of
5850 the working directory's parent, the uncommitted changes
5851 the working directory's parent, the uncommitted changes
5851 are merged into the requested changeset and the merged
5852 are merged into the requested changeset and the merged
5852 result is left uncommitted. If the requested changeset is
5853 result is left uncommitted. If the requested changeset is
5853 not an ancestor or descendant (that is, it is on another
5854 not an ancestor or descendant (that is, it is on another
5854 branch), the update is aborted and the uncommitted changes
5855 branch), the update is aborted and the uncommitted changes
5855 are preserved.
5856 are preserved.
5856
5857
5857 2. With the -c/--check option, the update is aborted and the
5858 2. With the -c/--check option, the update is aborted and the
5858 uncommitted changes are preserved.
5859 uncommitted changes are preserved.
5859
5860
5860 3. With the -C/--clean option, uncommitted changes are discarded and
5861 3. With the -C/--clean option, uncommitted changes are discarded and
5861 the working directory is updated to the requested changeset.
5862 the working directory is updated to the requested changeset.
5862
5863
5863 To cancel an uncommitted merge (and lose your changes), use
5864 To cancel an uncommitted merge (and lose your changes), use
5864 :hg:`update --clean .`.
5865 :hg:`update --clean .`.
5865
5866
5866 Use null as the changeset to remove the working directory (like
5867 Use null as the changeset to remove the working directory (like
5867 :hg:`clone -U`).
5868 :hg:`clone -U`).
5868
5869
5869 If you want to revert just one file to an older revision, use
5870 If you want to revert just one file to an older revision, use
5870 :hg:`revert [-r REV] NAME`.
5871 :hg:`revert [-r REV] NAME`.
5871
5872
5872 See :hg:`help dates` for a list of formats valid for -d/--date.
5873 See :hg:`help dates` for a list of formats valid for -d/--date.
5873
5874
5874 Returns 0 on success, 1 if there are unresolved files.
5875 Returns 0 on success, 1 if there are unresolved files.
5875 """
5876 """
5876 if rev and node:
5877 if rev and node:
5877 raise util.Abort(_("please specify just one revision"))
5878 raise util.Abort(_("please specify just one revision"))
5878
5879
5879 if rev is None or rev == '':
5880 if rev is None or rev == '':
5880 rev = node
5881 rev = node
5881
5882
5882 cmdutil.clearunfinished(repo)
5883 cmdutil.clearunfinished(repo)
5883
5884
5884 # with no argument, we also move the current bookmark, if any
5885 # with no argument, we also move the current bookmark, if any
5885 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
5886 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
5886
5887
5887 # if we defined a bookmark, we have to remember the original bookmark name
5888 # if we defined a bookmark, we have to remember the original bookmark name
5888 brev = rev
5889 brev = rev
5889 rev = scmutil.revsingle(repo, rev, rev).rev()
5890 rev = scmutil.revsingle(repo, rev, rev).rev()
5890
5891
5891 if check and clean:
5892 if check and clean:
5892 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5893 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5893
5894
5894 if date:
5895 if date:
5895 if rev is not None:
5896 if rev is not None:
5896 raise util.Abort(_("you can't specify a revision and a date"))
5897 raise util.Abort(_("you can't specify a revision and a date"))
5897 rev = cmdutil.finddate(ui, repo, date)
5898 rev = cmdutil.finddate(ui, repo, date)
5898
5899
5899 if check:
5900 if check:
5900 c = repo[None]
5901 c = repo[None]
5901 if c.dirty(merge=False, branch=False, missing=True):
5902 if c.dirty(merge=False, branch=False, missing=True):
5902 raise util.Abort(_("uncommitted changes"))
5903 raise util.Abort(_("uncommitted changes"))
5903 if rev is None:
5904 if rev is None:
5904 rev = repo[repo[None].branch()].rev()
5905 rev = repo[repo[None].branch()].rev()
5905 mergemod._checkunknown(repo, repo[None], repo[rev])
5906 mergemod._checkunknown(repo, repo[None], repo[rev])
5906
5907
5907 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
5908 repo.ui.setconfig('ui', 'forcemerge', tool, 'update')
5908
5909
5909 if clean:
5910 if clean:
5910 ret = hg.clean(repo, rev)
5911 ret = hg.clean(repo, rev)
5911 else:
5912 else:
5912 ret = hg.update(repo, rev)
5913 ret = hg.update(repo, rev)
5913
5914
5914 if not ret and movemarkfrom:
5915 if not ret and movemarkfrom:
5915 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5916 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5916 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
5917 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
5917 elif brev in repo._bookmarks:
5918 elif brev in repo._bookmarks:
5918 bookmarks.setcurrent(repo, brev)
5919 bookmarks.setcurrent(repo, brev)
5919 ui.status(_("(activating bookmark %s)\n") % brev)
5920 ui.status(_("(activating bookmark %s)\n") % brev)
5920 elif brev:
5921 elif brev:
5921 if repo._bookmarkcurrent:
5922 if repo._bookmarkcurrent:
5922 ui.status(_("(leaving bookmark %s)\n") %
5923 ui.status(_("(leaving bookmark %s)\n") %
5923 repo._bookmarkcurrent)
5924 repo._bookmarkcurrent)
5924 bookmarks.unsetcurrent(repo)
5925 bookmarks.unsetcurrent(repo)
5925
5926
5926 return ret
5927 return ret
5927
5928
5928 @command('verify', [])
5929 @command('verify', [])
5929 def verify(ui, repo):
5930 def verify(ui, repo):
5930 """verify the integrity of the repository
5931 """verify the integrity of the repository
5931
5932
5932 Verify the integrity of the current repository.
5933 Verify the integrity of the current repository.
5933
5934
5934 This will perform an extensive check of the repository's
5935 This will perform an extensive check of the repository's
5935 integrity, validating the hashes and checksums of each entry in
5936 integrity, validating the hashes and checksums of each entry in
5936 the changelog, manifest, and tracked files, as well as the
5937 the changelog, manifest, and tracked files, as well as the
5937 integrity of their crosslinks and indices.
5938 integrity of their crosslinks and indices.
5938
5939
5939 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
5940 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
5940 for more information about recovery from corruption of the
5941 for more information about recovery from corruption of the
5941 repository.
5942 repository.
5942
5943
5943 Returns 0 on success, 1 if errors are encountered.
5944 Returns 0 on success, 1 if errors are encountered.
5944 """
5945 """
5945 return hg.verify(repo)
5946 return hg.verify(repo)
5946
5947
5947 @command('version', [])
5948 @command('version', [])
5948 def version_(ui):
5949 def version_(ui):
5949 """output version and copyright information"""
5950 """output version and copyright information"""
5950 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5951 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5951 % util.version())
5952 % util.version())
5952 ui.status(_(
5953 ui.status(_(
5953 "(see http://mercurial.selenic.com for more information)\n"
5954 "(see http://mercurial.selenic.com for more information)\n"
5954 "\nCopyright (C) 2005-2014 Matt Mackall and others\n"
5955 "\nCopyright (C) 2005-2014 Matt Mackall and others\n"
5955 "This is free software; see the source for copying conditions. "
5956 "This is free software; see the source for copying conditions. "
5956 "There is NO\nwarranty; "
5957 "There is NO\nwarranty; "
5957 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5958 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5958 ))
5959 ))
5959
5960
5960 norepo = ("clone init version help debugcommands debugcomplete"
5961 norepo = ("clone init version help debugcommands debugcomplete"
5961 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5962 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5962 " debugknown debuggetbundle debugbundle")
5963 " debugknown debuggetbundle debugbundle")
5963 optionalrepo = ("identify paths serve config showconfig debugancestor debugdag"
5964 optionalrepo = ("identify paths serve config showconfig debugancestor debugdag"
5964 " debugdata debugindex debugindexdot debugrevlog")
5965 " debugdata debugindex debugindexdot debugrevlog")
5965 inferrepo = ("add addremove annotate cat commit diff grep forget log parents"
5966 inferrepo = ("add addremove annotate cat commit diff grep forget log parents"
5966 " remove resolve status debugwalk")
5967 " remove resolve status debugwalk")
@@ -1,532 +1,544 b''
1 $ hg init basic
1 $ hg init basic
2 $ cd basic
2 $ cd basic
3
3
4 should complain
4 should complain
5
5
6 $ hg backout
6 $ hg backout
7 abort: please specify a revision to backout
7 abort: please specify a revision to backout
8 [255]
8 [255]
9 $ hg backout -r 0 0
9 $ hg backout -r 0 0
10 abort: please specify just one revision
10 abort: please specify just one revision
11 [255]
11 [255]
12
12
13 basic operation
13 basic operation
14 (this also tests that editor is invoked if the commit message is not
14 (this also tests that editor is invoked if the commit message is not
15 specified explicitly)
15 specified explicitly)
16
16
17 $ echo a > a
17 $ echo a > a
18 $ hg commit -d '0 0' -A -m a
18 $ hg commit -d '0 0' -A -m a
19 adding a
19 adding a
20 $ echo b >> a
20 $ echo b >> a
21 $ hg commit -d '1 0' -m b
21 $ hg commit -d '1 0' -m b
22
22
23 $ hg status --rev tip --rev "tip^1"
23 $ hg status --rev tip --rev "tip^1"
24 M a
24 M a
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
25 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true
26 reverting a
26 reverting a
27 Backed out changeset a820f4f40a57
27 Backed out changeset a820f4f40a57
28
28
29
29
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
30 HG: Enter commit message. Lines beginning with 'HG:' are removed.
31 HG: Leave message empty to abort commit.
31 HG: Leave message empty to abort commit.
32 HG: --
32 HG: --
33 HG: user: test
33 HG: user: test
34 HG: branch 'default'
34 HG: branch 'default'
35 HG: changed a
35 HG: changed a
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
36 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
37 $ cat a
37 $ cat a
38 a
38 a
39 $ hg summary
39 $ hg summary
40 parent: 2:2929462c3dff tip
40 parent: 2:2929462c3dff tip
41 Backed out changeset a820f4f40a57
41 Backed out changeset a820f4f40a57
42 branch: default
42 branch: default
43 commit: (clean)
43 commit: (clean)
44 update: (current)
44 update: (current)
45
45
46 file that was removed is recreated
46 file that was removed is recreated
47 (this also tests that editor is not invoked if the commit message is
47 (this also tests that editor is not invoked if the commit message is
48 specified explicitly)
48 specified explicitly)
49
49
50 $ cd ..
50 $ cd ..
51 $ hg init remove
51 $ hg init remove
52 $ cd remove
52 $ cd remove
53
53
54 $ echo content > a
54 $ echo content > a
55 $ hg commit -d '0 0' -A -m a
55 $ hg commit -d '0 0' -A -m a
56 adding a
56 adding a
57
57
58 $ hg rm a
58 $ hg rm a
59 $ hg commit -d '1 0' -m b
59 $ hg commit -d '1 0' -m b
60
60
61 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
61 $ HGEDITOR=cat hg backout -d '2 0' tip --tool=true -m "Backed out changeset 76862dcce372"
62 adding a
62 adding a
63 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
63 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
64 $ cat a
64 $ cat a
65 content
65 content
66 $ hg summary
66 $ hg summary
67 parent: 2:de31bdc76c0d tip
67 parent: 2:de31bdc76c0d tip
68 Backed out changeset 76862dcce372
68 Backed out changeset 76862dcce372
69 branch: default
69 branch: default
70 commit: (clean)
70 commit: (clean)
71 update: (current)
71 update: (current)
72
72
73 backout of backout is as if nothing happened
73 backout of backout is as if nothing happened
74
74
75 $ hg backout -d '3 0' --merge tip --tool=true
75 $ hg backout -d '3 0' --merge tip --tool=true
76 removing a
76 removing a
77 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
77 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
78 $ test -f a
78 $ test -f a
79 [1]
79 [1]
80 $ hg summary
80 $ hg summary
81 parent: 3:7f6d0f120113 tip
81 parent: 3:7f6d0f120113 tip
82 Backed out changeset de31bdc76c0d
82 Backed out changeset de31bdc76c0d
83 branch: default
83 branch: default
84 commit: (clean)
84 commit: (clean)
85 update: (current)
85 update: (current)
86
86
87 across branch
87 across branch
88
88
89 $ cd ..
89 $ cd ..
90 $ hg init branch
90 $ hg init branch
91 $ cd branch
91 $ cd branch
92 $ echo a > a
92 $ echo a > a
93 $ hg ci -Am0
93 $ hg ci -Am0
94 adding a
94 adding a
95 $ echo b > b
95 $ echo b > b
96 $ hg ci -Am1
96 $ hg ci -Am1
97 adding b
97 adding b
98 $ hg co -C 0
98 $ hg co -C 0
99 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
99 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
100 $ hg summary
100 $ hg summary
101 parent: 0:f7b1eb17ad24
101 parent: 0:f7b1eb17ad24
102 0
102 0
103 branch: default
103 branch: default
104 commit: (clean)
104 commit: (clean)
105 update: 1 new changesets (update)
105 update: 1 new changesets (update)
106
106
107 should fail
107 should fail
108
108
109 $ hg backout 1
109 $ hg backout 1
110 abort: cannot backout change that is not an ancestor
110 abort: cannot backout change that is not an ancestor
111 [255]
111 [255]
112 $ echo c > c
112 $ echo c > c
113 $ hg ci -Am2
113 $ hg ci -Am2
114 adding c
114 adding c
115 created new head
115 created new head
116 $ hg summary
116 $ hg summary
117 parent: 2:db815d6d32e6 tip
117 parent: 2:db815d6d32e6 tip
118 2
118 2
119 branch: default
119 branch: default
120 commit: (clean)
120 commit: (clean)
121 update: 1 new changesets, 2 branch heads (merge)
121 update: 1 new changesets, 2 branch heads (merge)
122
122
123 should fail
123 should fail
124
124
125 $ hg backout 1
125 $ hg backout 1
126 abort: cannot backout change that is not an ancestor
126 abort: cannot backout change that is not an ancestor
127 [255]
127 [255]
128 $ hg summary
128 $ hg summary
129 parent: 2:db815d6d32e6 tip
129 parent: 2:db815d6d32e6 tip
130 2
130 2
131 branch: default
131 branch: default
132 commit: (clean)
132 commit: (clean)
133 update: 1 new changesets, 2 branch heads (merge)
133 update: 1 new changesets, 2 branch heads (merge)
134
134
135 backout with merge
135 backout with merge
136
136
137 $ cd ..
137 $ cd ..
138 $ hg init merge
138 $ hg init merge
139 $ cd merge
139 $ cd merge
140
140
141 $ echo line 1 > a
141 $ echo line 1 > a
142 $ echo line 2 >> a
142 $ echo line 2 >> a
143 $ hg commit -d '0 0' -A -m a
143 $ hg commit -d '0 0' -A -m a
144 adding a
144 adding a
145 $ hg summary
145 $ hg summary
146 parent: 0:59395513a13a tip
146 parent: 0:59395513a13a tip
147 a
147 a
148 branch: default
148 branch: default
149 commit: (clean)
149 commit: (clean)
150 update: (current)
150 update: (current)
151
151
152 remove line 1
152 remove line 1
153
153
154 $ echo line 2 > a
154 $ echo line 2 > a
155 $ hg commit -d '1 0' -m b
155 $ hg commit -d '1 0' -m b
156
156
157 $ echo line 3 >> a
157 $ echo line 3 >> a
158 $ hg commit -d '2 0' -m c
158 $ hg commit -d '2 0' -m c
159
159
160 $ hg backout --merge -d '3 0' 1 --tool=true
160 $ hg backout --merge -d '3 0' 1 --tool=true
161 reverting a
161 reverting a
162 created new head
162 created new head
163 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
163 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
164 merging with changeset 3:26b8ccb9ad91
164 merging with changeset 3:26b8ccb9ad91
165 merging a
165 merging a
166 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
166 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
167 (branch merge, don't forget to commit)
167 (branch merge, don't forget to commit)
168 $ hg commit -d '4 0' -m d
168 $ hg commit -d '4 0' -m d
169 $ hg summary
169 $ hg summary
170 parent: 4:c7df5e0b9c09 tip
170 parent: 4:c7df5e0b9c09 tip
171 d
171 d
172 branch: default
172 branch: default
173 commit: (clean)
173 commit: (clean)
174 update: (current)
174 update: (current)
175
175
176 check line 1 is back
176 check line 1 is back
177
177
178 $ cat a
178 $ cat a
179 line 1
179 line 1
180 line 2
180 line 2
181 line 3
181 line 3
182
182
183 $ cd ..
183 $ cd ..
184
184
185 backout should not back out subsequent changesets
185 backout should not back out subsequent changesets
186
186
187 $ hg init onecs
187 $ hg init onecs
188 $ cd onecs
188 $ cd onecs
189 $ echo 1 > a
189 $ echo 1 > a
190 $ hg commit -d '0 0' -A -m a
190 $ hg commit -d '0 0' -A -m a
191 adding a
191 adding a
192 $ echo 2 >> a
192 $ echo 2 >> a
193 $ hg commit -d '1 0' -m b
193 $ hg commit -d '1 0' -m b
194 $ echo 1 > b
194 $ echo 1 > b
195 $ hg commit -d '2 0' -A -m c
195 $ hg commit -d '2 0' -A -m c
196 adding b
196 adding b
197 $ hg summary
197 $ hg summary
198 parent: 2:882396649954 tip
198 parent: 2:882396649954 tip
199 c
199 c
200 branch: default
200 branch: default
201 commit: (clean)
201 commit: (clean)
202 update: (current)
202 update: (current)
203
203
204 without --merge
204 without --merge
205 $ hg backout -d '3 0' 1 --tool=true
205 $ hg backout -d '3 0' 1 --tool=true
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 changeset 22bca4c721e5 backed out, don't forget to commit.
207 changeset 22bca4c721e5 backed out, don't forget to commit.
208 $ hg locate b
208 $ hg locate b
209 b
209 b
210 $ hg update -C tip
210 $ hg update -C tip
211 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
211 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 $ hg locate b
212 $ hg locate b
213 b
213 b
214 $ hg summary
214 $ hg summary
215 parent: 2:882396649954 tip
215 parent: 2:882396649954 tip
216 c
216 c
217 branch: default
217 branch: default
218 commit: (clean)
218 commit: (clean)
219 update: (current)
219 update: (current)
220
220
221 with --merge
221 with --merge
222 $ hg backout --merge -d '3 0' 1 --tool=true
222 $ hg backout --merge -d '3 0' 1 --tool=true
223 reverting a
223 reverting a
224 created new head
224 created new head
225 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
225 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
226 merging with changeset 3:3202beb76721
226 merging with changeset 3:3202beb76721
227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
228 (branch merge, don't forget to commit)
228 (branch merge, don't forget to commit)
229 $ hg locate b
229 $ hg locate b
230 b
230 b
231 $ hg update -C tip
231 $ hg update -C tip
232 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
232 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
233 $ hg locate b
233 $ hg locate b
234 [1]
234 [1]
235
235
236 $ cd ..
236 $ cd ..
237 $ hg init m
237 $ hg init m
238 $ cd m
238 $ cd m
239 $ echo a > a
239 $ echo a > a
240 $ hg commit -d '0 0' -A -m a
240 $ hg commit -d '0 0' -A -m a
241 adding a
241 adding a
242 $ echo b > b
242 $ echo b > b
243 $ hg commit -d '1 0' -A -m b
243 $ hg commit -d '1 0' -A -m b
244 adding b
244 adding b
245 $ echo c > c
245 $ echo c > c
246 $ hg commit -d '2 0' -A -m b
246 $ hg commit -d '2 0' -A -m b
247 adding c
247 adding c
248 $ hg update 1
248 $ hg update 1
249 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
249 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
250 $ echo d > d
250 $ echo d > d
251 $ hg commit -d '3 0' -A -m c
251 $ hg commit -d '3 0' -A -m c
252 adding d
252 adding d
253 created new head
253 created new head
254 $ hg merge 2
254 $ hg merge 2
255 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
255 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 (branch merge, don't forget to commit)
256 (branch merge, don't forget to commit)
257 $ hg commit -d '4 0' -A -m d
257 $ hg commit -d '4 0' -A -m d
258 $ hg summary
258 $ hg summary
259 parent: 4:b2f3bb92043e tip
259 parent: 4:b2f3bb92043e tip
260 d
260 d
261 branch: default
261 branch: default
262 commit: (clean)
262 commit: (clean)
263 update: (current)
263 update: (current)
264
264
265 backout of merge should fail
265 backout of merge should fail
266
266
267 $ hg backout 4
267 $ hg backout 4
268 abort: cannot backout a merge changeset
268 abort: cannot backout a merge changeset
269 [255]
269 [255]
270
270
271 backout of merge with bad parent should fail
271 backout of merge with bad parent should fail
272
272
273 $ hg backout --parent 0 4
273 $ hg backout --parent 0 4
274 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
274 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
275 [255]
275 [255]
276
276
277 backout of non-merge with parent should fail
277 backout of non-merge with parent should fail
278
278
279 $ hg backout --parent 0 3
279 $ hg backout --parent 0 3
280 abort: cannot use --parent on non-merge changeset
280 abort: cannot use --parent on non-merge changeset
281 [255]
281 [255]
282
282
283 backout with valid parent should be ok
283 backout with valid parent should be ok
284
284
285 $ hg backout -d '5 0' --parent 2 4 --tool=true
285 $ hg backout -d '5 0' --parent 2 4 --tool=true
286 removing d
286 removing d
287 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
287 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
288 $ hg summary
288 $ hg summary
289 parent: 5:10e5328c8435 tip
289 parent: 5:10e5328c8435 tip
290 Backed out changeset b2f3bb92043e
290 Backed out changeset b2f3bb92043e
291 branch: default
291 branch: default
292 commit: (clean)
292 commit: (clean)
293 update: (current)
293 update: (current)
294
294
295 $ hg rollback
295 $ hg rollback
296 repository tip rolled back to revision 4 (undo commit)
296 repository tip rolled back to revision 4 (undo commit)
297 working directory now based on revision 4
297 working directory now based on revision 4
298 $ hg update -C
298 $ hg update -C
299 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
299 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
300 $ hg summary
300 $ hg summary
301 parent: 4:b2f3bb92043e tip
301 parent: 4:b2f3bb92043e tip
302 d
302 d
303 branch: default
303 branch: default
304 commit: (clean)
304 commit: (clean)
305 update: (current)
305 update: (current)
306
306
307 $ hg backout -d '6 0' --parent 3 4 --tool=true
307 $ hg backout -d '6 0' --parent 3 4 --tool=true
308 removing c
308 removing c
309 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
309 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
310 $ hg summary
310 $ hg summary
311 parent: 5:033590168430 tip
311 parent: 5:033590168430 tip
312 Backed out changeset b2f3bb92043e
312 Backed out changeset b2f3bb92043e
313 branch: default
313 branch: default
314 commit: (clean)
314 commit: (clean)
315 update: (current)
315 update: (current)
316
316
317 $ cd ..
317 $ cd ..
318
318
319 named branches
319 named branches
320
320
321 $ hg init named_branches
321 $ hg init named_branches
322 $ cd named_branches
322 $ cd named_branches
323
323
324 $ echo default > default
324 $ echo default > default
325 $ hg ci -d '0 0' -Am default
325 $ hg ci -d '0 0' -Am default
326 adding default
326 adding default
327 $ hg branch branch1
327 $ hg branch branch1
328 marked working directory as branch branch1
328 marked working directory as branch branch1
329 (branches are permanent and global, did you want a bookmark?)
329 (branches are permanent and global, did you want a bookmark?)
330 $ echo branch1 > file1
330 $ echo branch1 > file1
331 $ hg ci -d '1 0' -Am file1
331 $ hg ci -d '1 0' -Am file1
332 adding file1
332 adding file1
333 $ hg branch branch2
333 $ hg branch branch2
334 marked working directory as branch branch2
334 marked working directory as branch branch2
335 (branches are permanent and global, did you want a bookmark?)
335 (branches are permanent and global, did you want a bookmark?)
336 $ echo branch2 > file2
336 $ echo branch2 > file2
337 $ hg ci -d '2 0' -Am file2
337 $ hg ci -d '2 0' -Am file2
338 adding file2
338 adding file2
339
339
340 without --merge
340 without --merge
341 $ hg backout -r 1 --tool=true
341 $ hg backout -r 1 --tool=true
342 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
342 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
343 changeset bf1602f437f3 backed out, don't forget to commit.
343 changeset bf1602f437f3 backed out, don't forget to commit.
344 $ hg branch
344 $ hg branch
345 branch2
345 branch2
346 $ hg status -A
346 $ hg status -A
347 R file1
347 R file1
348 C default
348 C default
349 C file2
349 C file2
350 $ hg summary
350 $ hg summary
351 parent: 2:45bbcd363bf0 tip
351 parent: 2:45bbcd363bf0 tip
352 file2
352 file2
353 branch: branch2
353 branch: branch2
354 commit: 1 removed
354 commit: 1 removed
355 update: (current)
355 update: (current)
356
356
357 with --merge
357 with --merge
358 (this also tests that editor is invoked if '--edit' is specified
359 explicitly regardless of '--message')
360
358 $ hg update -qC
361 $ hg update -qC
359 $ hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true
362 $ HGEDITOR=cat hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true --edit
360 removing file1
363 removing file1
364 backout on branch1
365
366
367 HG: Enter commit message. Lines beginning with 'HG:' are removed.
368 HG: Leave message empty to abort commit.
369 HG: --
370 HG: user: test
371 HG: branch 'branch2'
372 HG: removed file1
361 created new head
373 created new head
362 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
374 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
363 merging with changeset 3:d4e8f6db59fb
375 merging with changeset 3:d4e8f6db59fb
364 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
376 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
365 (branch merge, don't forget to commit)
377 (branch merge, don't forget to commit)
366 $ hg summary
378 $ hg summary
367 parent: 2:45bbcd363bf0
379 parent: 2:45bbcd363bf0
368 file2
380 file2
369 parent: 3:d4e8f6db59fb tip
381 parent: 3:d4e8f6db59fb tip
370 backout on branch1
382 backout on branch1
371 branch: branch2
383 branch: branch2
372 commit: 1 removed (merge)
384 commit: 1 removed (merge)
373 update: (current)
385 update: (current)
374 $ hg update -q -C 2
386 $ hg update -q -C 2
375
387
376 on branch2 with branch1 not merged, so file1 should still exist:
388 on branch2 with branch1 not merged, so file1 should still exist:
377
389
378 $ hg id
390 $ hg id
379 45bbcd363bf0 (branch2)
391 45bbcd363bf0 (branch2)
380 $ hg st -A
392 $ hg st -A
381 C default
393 C default
382 C file1
394 C file1
383 C file2
395 C file2
384 $ hg summary
396 $ hg summary
385 parent: 2:45bbcd363bf0
397 parent: 2:45bbcd363bf0
386 file2
398 file2
387 branch: branch2
399 branch: branch2
388 commit: (clean)
400 commit: (clean)
389 update: 1 new changesets, 2 branch heads (merge)
401 update: 1 new changesets, 2 branch heads (merge)
390
402
391 on branch2 with branch1 merged, so file1 should be gone:
403 on branch2 with branch1 merged, so file1 should be gone:
392
404
393 $ hg merge
405 $ hg merge
394 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
406 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
395 (branch merge, don't forget to commit)
407 (branch merge, don't forget to commit)
396 $ hg ci -d '4 0' -m 'merge backout of branch1'
408 $ hg ci -d '4 0' -m 'merge backout of branch1'
397 $ hg id
409 $ hg id
398 22149cdde76d (branch2) tip
410 22149cdde76d (branch2) tip
399 $ hg st -A
411 $ hg st -A
400 C default
412 C default
401 C file2
413 C file2
402 $ hg summary
414 $ hg summary
403 parent: 4:22149cdde76d tip
415 parent: 4:22149cdde76d tip
404 merge backout of branch1
416 merge backout of branch1
405 branch: branch2
417 branch: branch2
406 commit: (clean)
418 commit: (clean)
407 update: (current)
419 update: (current)
408
420
409 on branch1, so no file1 and file2:
421 on branch1, so no file1 and file2:
410
422
411 $ hg co -C branch1
423 $ hg co -C branch1
412 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
424 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
413 $ hg id
425 $ hg id
414 bf1602f437f3 (branch1)
426 bf1602f437f3 (branch1)
415 $ hg st -A
427 $ hg st -A
416 C default
428 C default
417 C file1
429 C file1
418 $ hg summary
430 $ hg summary
419 parent: 1:bf1602f437f3
431 parent: 1:bf1602f437f3
420 file1
432 file1
421 branch: branch1
433 branch: branch1
422 commit: (clean)
434 commit: (clean)
423 update: (current)
435 update: (current)
424
436
425 $ cd ..
437 $ cd ..
426
438
427 backout of empty changeset (issue4190)
439 backout of empty changeset (issue4190)
428
440
429 $ hg init emptycommit
441 $ hg init emptycommit
430 $ cd emptycommit
442 $ cd emptycommit
431
443
432 $ touch file1
444 $ touch file1
433 $ hg ci -Aqm file1
445 $ hg ci -Aqm file1
434 $ hg branch -q branch1
446 $ hg branch -q branch1
435 $ hg ci -qm branch1
447 $ hg ci -qm branch1
436 $ hg backout -v 1
448 $ hg backout -v 1
437 resolving manifests
449 resolving manifests
438 nothing changed
450 nothing changed
439 [1]
451 [1]
440
452
441 $ cd ..
453 $ cd ..
442
454
443
455
444 Test usage of `hg resolve` in case of conflict
456 Test usage of `hg resolve` in case of conflict
445 (issue4163)
457 (issue4163)
446
458
447 $ hg init issue4163
459 $ hg init issue4163
448 $ cd issue4163
460 $ cd issue4163
449 $ touch foo
461 $ touch foo
450 $ hg add foo
462 $ hg add foo
451 $ cat > foo << EOF
463 $ cat > foo << EOF
452 > one
464 > one
453 > two
465 > two
454 > three
466 > three
455 > four
467 > four
456 > five
468 > five
457 > six
469 > six
458 > seven
470 > seven
459 > height
471 > height
460 > nine
472 > nine
461 > ten
473 > ten
462 > EOF
474 > EOF
463 $ hg ci -m 'initial'
475 $ hg ci -m 'initial'
464 $ cat > foo << EOF
476 $ cat > foo << EOF
465 > one
477 > one
466 > two
478 > two
467 > THREE
479 > THREE
468 > four
480 > four
469 > five
481 > five
470 > six
482 > six
471 > seven
483 > seven
472 > height
484 > height
473 > nine
485 > nine
474 > ten
486 > ten
475 > EOF
487 > EOF
476 $ hg ci -m 'capital three'
488 $ hg ci -m 'capital three'
477 $ cat > foo << EOF
489 $ cat > foo << EOF
478 > one
490 > one
479 > two
491 > two
480 > THREE
492 > THREE
481 > four
493 > four
482 > five
494 > five
483 > six
495 > six
484 > seven
496 > seven
485 > height
497 > height
486 > nine
498 > nine
487 > TEN
499 > TEN
488 > EOF
500 > EOF
489 $ hg ci -m 'capital ten'
501 $ hg ci -m 'capital ten'
490 $ hg backout -r 'desc("capital three")' --tool internal:fail
502 $ hg backout -r 'desc("capital three")' --tool internal:fail
491 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
503 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
492 use 'hg resolve' to retry unresolved file merges
504 use 'hg resolve' to retry unresolved file merges
493 [1]
505 [1]
494 $ hg status
506 $ hg status
495 $ hg resolve -l # still unresolved
507 $ hg resolve -l # still unresolved
496 U foo
508 U foo
497 $ hg summary
509 $ hg summary
498 parent: 2:b71750c4b0fd tip
510 parent: 2:b71750c4b0fd tip
499 capital ten
511 capital ten
500 branch: default
512 branch: default
501 commit: 1 unresolved (clean)
513 commit: 1 unresolved (clean)
502 update: (current)
514 update: (current)
503 $ hg resolve --all --debug
515 $ hg resolve --all --debug
504 picked tool 'internal:merge' for foo (binary False symlink False)
516 picked tool 'internal:merge' for foo (binary False symlink False)
505 merging foo
517 merging foo
506 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
518 my foo@b71750c4b0fd+ other foo@a30dd8addae3 ancestor foo@913609522437
507 premerge successful
519 premerge successful
508 no more unresolved files
520 no more unresolved files
509 $ hg status
521 $ hg status
510 M foo
522 M foo
511 ? foo.orig
523 ? foo.orig
512 $ hg resolve -l
524 $ hg resolve -l
513 R foo
525 R foo
514 $ hg summary
526 $ hg summary
515 parent: 2:b71750c4b0fd tip
527 parent: 2:b71750c4b0fd tip
516 capital ten
528 capital ten
517 branch: default
529 branch: default
518 commit: 1 modified, 1 unknown
530 commit: 1 modified, 1 unknown
519 update: (current)
531 update: (current)
520 $ cat foo
532 $ cat foo
521 one
533 one
522 two
534 two
523 three
535 three
524 four
536 four
525 five
537 five
526 six
538 six
527 seven
539 seven
528 height
540 height
529 nine
541 nine
530 TEN
542 TEN
531
543
532
544
@@ -1,332 +1,332 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 forget
20 forget
21 graft
21 graft
22 grep
22 grep
23 heads
23 heads
24 help
24 help
25 identify
25 identify
26 import
26 import
27 incoming
27 incoming
28 init
28 init
29 locate
29 locate
30 log
30 log
31 manifest
31 manifest
32 merge
32 merge
33 outgoing
33 outgoing
34 parents
34 parents
35 paths
35 paths
36 phase
36 phase
37 pull
37 pull
38 push
38 push
39 recover
39 recover
40 remove
40 remove
41 rename
41 rename
42 resolve
42 resolve
43 revert
43 revert
44 rollback
44 rollback
45 root
45 root
46 serve
46 serve
47 status
47 status
48 summary
48 summary
49 tag
49 tag
50 tags
50 tags
51 tip
51 tip
52 unbundle
52 unbundle
53 update
53 update
54 verify
54 verify
55 version
55 version
56
56
57 Show all commands that start with "a"
57 Show all commands that start with "a"
58 $ hg debugcomplete a
58 $ hg debugcomplete a
59 add
59 add
60 addremove
60 addremove
61 annotate
61 annotate
62 archive
62 archive
63
63
64 Do not show debug commands if there are other candidates
64 Do not show debug commands if there are other candidates
65 $ hg debugcomplete d
65 $ hg debugcomplete d
66 diff
66 diff
67
67
68 Show debug commands if there are no other candidates
68 Show debug commands if there are no other candidates
69 $ hg debugcomplete debug
69 $ hg debugcomplete debug
70 debugancestor
70 debugancestor
71 debugbuilddag
71 debugbuilddag
72 debugbundle
72 debugbundle
73 debugcheckstate
73 debugcheckstate
74 debugcommands
74 debugcommands
75 debugcomplete
75 debugcomplete
76 debugconfig
76 debugconfig
77 debugdag
77 debugdag
78 debugdata
78 debugdata
79 debugdate
79 debugdate
80 debugdirstate
80 debugdirstate
81 debugdiscovery
81 debugdiscovery
82 debugfileset
82 debugfileset
83 debugfsinfo
83 debugfsinfo
84 debuggetbundle
84 debuggetbundle
85 debugignore
85 debugignore
86 debugindex
86 debugindex
87 debugindexdot
87 debugindexdot
88 debuginstall
88 debuginstall
89 debugknown
89 debugknown
90 debuglabelcomplete
90 debuglabelcomplete
91 debugobsolete
91 debugobsolete
92 debugpathcomplete
92 debugpathcomplete
93 debugpushkey
93 debugpushkey
94 debugpvec
94 debugpvec
95 debugrebuilddirstate
95 debugrebuilddirstate
96 debugrename
96 debugrename
97 debugrevlog
97 debugrevlog
98 debugrevspec
98 debugrevspec
99 debugsetparents
99 debugsetparents
100 debugsub
100 debugsub
101 debugsuccessorssets
101 debugsuccessorssets
102 debugwalk
102 debugwalk
103 debugwireargs
103 debugwireargs
104
104
105 Do not show the alias of a debug command if there are other candidates
105 Do not show the alias of a debug command if there are other candidates
106 (this should hide rawcommit)
106 (this should hide rawcommit)
107 $ hg debugcomplete r
107 $ hg debugcomplete r
108 recover
108 recover
109 remove
109 remove
110 rename
110 rename
111 resolve
111 resolve
112 revert
112 revert
113 rollback
113 rollback
114 root
114 root
115 Show the alias of a debug command if there are no other candidates
115 Show the alias of a debug command if there are no other candidates
116 $ hg debugcomplete rawc
116 $ hg debugcomplete rawc
117
117
118
118
119 Show the global options
119 Show the global options
120 $ hg debugcomplete --options | sort
120 $ hg debugcomplete --options | sort
121 --config
121 --config
122 --cwd
122 --cwd
123 --debug
123 --debug
124 --debugger
124 --debugger
125 --encoding
125 --encoding
126 --encodingmode
126 --encodingmode
127 --help
127 --help
128 --hidden
128 --hidden
129 --noninteractive
129 --noninteractive
130 --profile
130 --profile
131 --quiet
131 --quiet
132 --repository
132 --repository
133 --time
133 --time
134 --traceback
134 --traceback
135 --verbose
135 --verbose
136 --version
136 --version
137 -R
137 -R
138 -h
138 -h
139 -q
139 -q
140 -v
140 -v
141 -y
141 -y
142
142
143 Show the options for the "serve" command
143 Show the options for the "serve" command
144 $ hg debugcomplete --options serve | sort
144 $ hg debugcomplete --options serve | sort
145 --accesslog
145 --accesslog
146 --address
146 --address
147 --certificate
147 --certificate
148 --cmdserver
148 --cmdserver
149 --config
149 --config
150 --cwd
150 --cwd
151 --daemon
151 --daemon
152 --daemon-pipefds
152 --daemon-pipefds
153 --debug
153 --debug
154 --debugger
154 --debugger
155 --encoding
155 --encoding
156 --encodingmode
156 --encodingmode
157 --errorlog
157 --errorlog
158 --help
158 --help
159 --hidden
159 --hidden
160 --ipv6
160 --ipv6
161 --name
161 --name
162 --noninteractive
162 --noninteractive
163 --pid-file
163 --pid-file
164 --port
164 --port
165 --prefix
165 --prefix
166 --profile
166 --profile
167 --quiet
167 --quiet
168 --repository
168 --repository
169 --stdio
169 --stdio
170 --style
170 --style
171 --templates
171 --templates
172 --time
172 --time
173 --traceback
173 --traceback
174 --verbose
174 --verbose
175 --version
175 --version
176 --web-conf
176 --web-conf
177 -6
177 -6
178 -A
178 -A
179 -E
179 -E
180 -R
180 -R
181 -a
181 -a
182 -d
182 -d
183 -h
183 -h
184 -n
184 -n
185 -p
185 -p
186 -q
186 -q
187 -t
187 -t
188 -v
188 -v
189 -y
189 -y
190
190
191 Show an error if we use --options with an ambiguous abbreviation
191 Show an error if we use --options with an ambiguous abbreviation
192 $ hg debugcomplete --options s
192 $ hg debugcomplete --options s
193 hg: command 's' is ambiguous:
193 hg: command 's' is ambiguous:
194 serve showconfig status summary
194 serve showconfig status summary
195 [255]
195 [255]
196
196
197 Show all commands + options
197 Show all commands + options
198 $ hg debugcommands
198 $ hg debugcommands
199 add: include, exclude, subrepos, dry-run
199 add: include, exclude, subrepos, dry-run
200 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude
200 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude
201 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
201 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
202 commit: addremove, close-branch, amend, secret, edit, include, exclude, message, logfile, date, user, subrepos
202 commit: addremove, close-branch, amend, secret, edit, include, exclude, message, logfile, date, user, subrepos
203 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
203 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
204 export: output, switch-parent, rev, text, git, nodates
204 export: output, switch-parent, rev, text, git, nodates
205 forget: include, exclude
205 forget: include, exclude
206 init: ssh, remotecmd, insecure
206 init: ssh, remotecmd, insecure
207 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
207 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
208 merge: force, rev, preview, tool
208 merge: force, rev, preview, tool
209 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
209 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
210 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
210 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
211 remove: after, force, include, exclude
211 remove: after, force, include, exclude
212 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
212 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
213 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
213 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
214 summary: remote
214 summary: remote
215 update: clean, check, date, rev, tool
215 update: clean, check, date, rev, tool
216 addremove: similarity, include, exclude, dry-run
216 addremove: similarity, include, exclude, dry-run
217 archive: no-decode, prefix, rev, type, subrepos, include, exclude
217 archive: no-decode, prefix, rev, type, subrepos, include, exclude
218 backout: merge, parent, rev, tool, include, exclude, message, logfile, date, user
218 backout: merge, parent, rev, edit, tool, include, exclude, message, logfile, date, user
219 bisect: reset, good, bad, skip, extend, command, noupdate
219 bisect: reset, good, bad, skip, extend, command, noupdate
220 bookmarks: force, rev, delete, rename, inactive
220 bookmarks: force, rev, delete, rename, inactive
221 branch: force, clean
221 branch: force, clean
222 branches: active, closed
222 branches: active, closed
223 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
223 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
224 cat: output, rev, decode, include, exclude
224 cat: output, rev, decode, include, exclude
225 config: untrusted, edit, local, global
225 config: untrusted, edit, local, global
226 copy: after, force, include, exclude, dry-run
226 copy: after, force, include, exclude, dry-run
227 debugancestor:
227 debugancestor:
228 debugbuilddag: mergeable-file, overwritten-file, new-file
228 debugbuilddag: mergeable-file, overwritten-file, new-file
229 debugbundle: all
229 debugbundle: all
230 debugcheckstate:
230 debugcheckstate:
231 debugcommands:
231 debugcommands:
232 debugcomplete: options
232 debugcomplete: options
233 debugdag: tags, branches, dots, spaces
233 debugdag: tags, branches, dots, spaces
234 debugdata: changelog, manifest
234 debugdata: changelog, manifest
235 debugdate: extended
235 debugdate: extended
236 debugdirstate: nodates, datesort
236 debugdirstate: nodates, datesort
237 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
237 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
238 debugfileset: rev
238 debugfileset: rev
239 debugfsinfo:
239 debugfsinfo:
240 debuggetbundle: head, common, type
240 debuggetbundle: head, common, type
241 debugignore:
241 debugignore:
242 debugindex: changelog, manifest, format
242 debugindex: changelog, manifest, format
243 debugindexdot:
243 debugindexdot:
244 debuginstall:
244 debuginstall:
245 debugknown:
245 debugknown:
246 debuglabelcomplete:
246 debuglabelcomplete:
247 debugobsolete: flags, date, user
247 debugobsolete: flags, date, user
248 debugpathcomplete: full, normal, added, removed
248 debugpathcomplete: full, normal, added, removed
249 debugpushkey:
249 debugpushkey:
250 debugpvec:
250 debugpvec:
251 debugrebuilddirstate: rev
251 debugrebuilddirstate: rev
252 debugrename: rev
252 debugrename: rev
253 debugrevlog: changelog, manifest, dump
253 debugrevlog: changelog, manifest, dump
254 debugrevspec: optimize
254 debugrevspec: optimize
255 debugsetparents:
255 debugsetparents:
256 debugsub: rev
256 debugsub: rev
257 debugsuccessorssets:
257 debugsuccessorssets:
258 debugwalk: include, exclude
258 debugwalk: include, exclude
259 debugwireargs: three, four, five, ssh, remotecmd, insecure
259 debugwireargs: three, four, five, ssh, remotecmd, insecure
260 graft: rev, continue, edit, log, currentdate, currentuser, date, user, tool, dry-run
260 graft: rev, continue, edit, log, currentdate, currentuser, date, user, tool, dry-run
261 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
261 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
262 heads: rev, topo, active, closed, style, template
262 heads: rev, topo, active, closed, style, template
263 help: extension, command, keyword
263 help: extension, command, keyword
264 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
264 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
265 import: strip, base, edit, force, no-commit, bypass, partial, exact, import-branch, message, logfile, date, user, similarity
265 import: strip, base, edit, force, no-commit, bypass, partial, exact, import-branch, message, logfile, date, user, similarity
266 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
266 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
267 locate: rev, print0, fullpath, include, exclude
267 locate: rev, print0, fullpath, include, exclude
268 manifest: rev, all
268 manifest: rev, all
269 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
269 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
270 parents: rev, style, template
270 parents: rev, style, template
271 paths:
271 paths:
272 phase: public, draft, secret, force, rev
272 phase: public, draft, secret, force, rev
273 recover:
273 recover:
274 rename: after, force, include, exclude, dry-run
274 rename: after, force, include, exclude, dry-run
275 resolve: all, list, mark, unmark, no-status, tool, include, exclude
275 resolve: all, list, mark, unmark, no-status, tool, include, exclude
276 revert: all, date, rev, no-backup, include, exclude, dry-run
276 revert: all, date, rev, no-backup, include, exclude, dry-run
277 rollback: dry-run, force
277 rollback: dry-run, force
278 root:
278 root:
279 tag: force, local, rev, remove, edit, message, date, user
279 tag: force, local, rev, remove, edit, message, date, user
280 tags:
280 tags:
281 tip: patch, git, style, template
281 tip: patch, git, style, template
282 unbundle: update
282 unbundle: update
283 verify:
283 verify:
284 version:
284 version:
285
285
286 $ hg init a
286 $ hg init a
287 $ cd a
287 $ cd a
288 $ echo fee > fee
288 $ echo fee > fee
289 $ hg ci -q -Amfee
289 $ hg ci -q -Amfee
290 $ hg tag fee
290 $ hg tag fee
291 $ mkdir fie
291 $ mkdir fie
292 $ echo dead > fie/dead
292 $ echo dead > fie/dead
293 $ echo live > fie/live
293 $ echo live > fie/live
294 $ hg bookmark fo
294 $ hg bookmark fo
295 $ hg branch -q fie
295 $ hg branch -q fie
296 $ hg ci -q -Amfie
296 $ hg ci -q -Amfie
297 $ echo fo > fo
297 $ echo fo > fo
298 $ hg branch -qf default
298 $ hg branch -qf default
299 $ hg ci -q -Amfo
299 $ hg ci -q -Amfo
300 $ echo Fum > Fum
300 $ echo Fum > Fum
301 $ hg ci -q -AmFum
301 $ hg ci -q -AmFum
302 $ hg bookmark Fum
302 $ hg bookmark Fum
303
303
304 Test debugpathcomplete
304 Test debugpathcomplete
305
305
306 $ hg debugpathcomplete f
306 $ hg debugpathcomplete f
307 fee
307 fee
308 fie
308 fie
309 fo
309 fo
310 $ hg debugpathcomplete -f f
310 $ hg debugpathcomplete -f f
311 fee
311 fee
312 fie/dead
312 fie/dead
313 fie/live
313 fie/live
314 fo
314 fo
315
315
316 $ hg rm Fum
316 $ hg rm Fum
317 $ hg debugpathcomplete -r F
317 $ hg debugpathcomplete -r F
318 Fum
318 Fum
319
319
320 Test debuglabelcomplete
320 Test debuglabelcomplete
321
321
322 $ hg debuglabelcomplete
322 $ hg debuglabelcomplete
323 Fum
323 Fum
324 default
324 default
325 fee
325 fee
326 fie
326 fie
327 fo
327 fo
328 tip
328 tip
329 $ hg debuglabelcomplete f
329 $ hg debuglabelcomplete f
330 fee
330 fee
331 fie
331 fie
332 fo
332 fo
General Comments 0
You need to be logged in to leave comments. Login now