##// END OF EJS Templates
branch: warn on branching
Matt Mackall -
r15615:41885892 stable
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,5672 +1,5674 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 _, gettext
10 from i18n import _, gettext
11 import os, re, difflib, time, tempfile, errno
11 import os, re, difflib, time, tempfile, errno
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
13 import patch, help, url, encoding, templatekw, discovery
13 import patch, help, url, encoding, templatekw, discovery
14 import archival, changegroup, cmdutil, hbisect
14 import archival, changegroup, cmdutil, hbisect
15 import sshserver, hgweb, hgweb.server, commandserver
15 import sshserver, hgweb, hgweb.server, commandserver
16 import merge as mergemod
16 import merge as mergemod
17 import minirst, revset, fileset
17 import minirst, revset, fileset
18 import dagparser, context, simplemerge
18 import dagparser, context, simplemerge
19 import random, setdiscovery, treediscovery, dagutil
19 import random, setdiscovery, treediscovery, dagutil
20
20
21 table = {}
21 table = {}
22
22
23 command = cmdutil.command(table)
23 command = cmdutil.command(table)
24
24
25 # common command options
25 # common command options
26
26
27 globalopts = [
27 globalopts = [
28 ('R', 'repository', '',
28 ('R', 'repository', '',
29 _('repository root directory or name of overlay bundle file'),
29 _('repository root directory or name of overlay bundle file'),
30 _('REPO')),
30 _('REPO')),
31 ('', 'cwd', '',
31 ('', 'cwd', '',
32 _('change working directory'), _('DIR')),
32 _('change working directory'), _('DIR')),
33 ('y', 'noninteractive', None,
33 ('y', 'noninteractive', None,
34 _('do not prompt, automatically pick the first choice for all prompts')),
34 _('do not prompt, automatically pick the first choice for all prompts')),
35 ('q', 'quiet', None, _('suppress output')),
35 ('q', 'quiet', None, _('suppress output')),
36 ('v', 'verbose', None, _('enable additional output')),
36 ('v', 'verbose', None, _('enable additional output')),
37 ('', 'config', [],
37 ('', 'config', [],
38 _('set/override config option (use \'section.name=value\')'),
38 _('set/override config option (use \'section.name=value\')'),
39 _('CONFIG')),
39 _('CONFIG')),
40 ('', 'debug', None, _('enable debugging output')),
40 ('', 'debug', None, _('enable debugging output')),
41 ('', 'debugger', None, _('start debugger')),
41 ('', 'debugger', None, _('start debugger')),
42 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
42 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
43 _('ENCODE')),
43 _('ENCODE')),
44 ('', 'encodingmode', encoding.encodingmode,
44 ('', 'encodingmode', encoding.encodingmode,
45 _('set the charset encoding mode'), _('MODE')),
45 _('set the charset encoding mode'), _('MODE')),
46 ('', 'traceback', None, _('always print a traceback on exception')),
46 ('', 'traceback', None, _('always print a traceback on exception')),
47 ('', 'time', None, _('time how long the command takes')),
47 ('', 'time', None, _('time how long the command takes')),
48 ('', 'profile', None, _('print command execution profile')),
48 ('', 'profile', None, _('print command execution profile')),
49 ('', 'version', None, _('output version information and exit')),
49 ('', 'version', None, _('output version information and exit')),
50 ('h', 'help', None, _('display help and exit')),
50 ('h', 'help', None, _('display help and exit')),
51 ]
51 ]
52
52
53 dryrunopts = [('n', 'dry-run', None,
53 dryrunopts = [('n', 'dry-run', None,
54 _('do not perform actions, just print output'))]
54 _('do not perform actions, just print output'))]
55
55
56 remoteopts = [
56 remoteopts = [
57 ('e', 'ssh', '',
57 ('e', 'ssh', '',
58 _('specify ssh command to use'), _('CMD')),
58 _('specify ssh command to use'), _('CMD')),
59 ('', 'remotecmd', '',
59 ('', 'remotecmd', '',
60 _('specify hg command to run on the remote side'), _('CMD')),
60 _('specify hg command to run on the remote side'), _('CMD')),
61 ('', 'insecure', None,
61 ('', 'insecure', None,
62 _('do not verify server certificate (ignoring web.cacerts config)')),
62 _('do not verify server certificate (ignoring web.cacerts config)')),
63 ]
63 ]
64
64
65 walkopts = [
65 walkopts = [
66 ('I', 'include', [],
66 ('I', 'include', [],
67 _('include names matching the given patterns'), _('PATTERN')),
67 _('include names matching the given patterns'), _('PATTERN')),
68 ('X', 'exclude', [],
68 ('X', 'exclude', [],
69 _('exclude names matching the given patterns'), _('PATTERN')),
69 _('exclude names matching the given patterns'), _('PATTERN')),
70 ]
70 ]
71
71
72 commitopts = [
72 commitopts = [
73 ('m', 'message', '',
73 ('m', 'message', '',
74 _('use text as commit message'), _('TEXT')),
74 _('use text as commit message'), _('TEXT')),
75 ('l', 'logfile', '',
75 ('l', 'logfile', '',
76 _('read commit message from file'), _('FILE')),
76 _('read commit message from file'), _('FILE')),
77 ]
77 ]
78
78
79 commitopts2 = [
79 commitopts2 = [
80 ('d', 'date', '',
80 ('d', 'date', '',
81 _('record the specified date as commit date'), _('DATE')),
81 _('record the specified date as commit date'), _('DATE')),
82 ('u', 'user', '',
82 ('u', 'user', '',
83 _('record the specified user as committer'), _('USER')),
83 _('record the specified user as committer'), _('USER')),
84 ]
84 ]
85
85
86 templateopts = [
86 templateopts = [
87 ('', 'style', '',
87 ('', 'style', '',
88 _('display using template map file'), _('STYLE')),
88 _('display using template map file'), _('STYLE')),
89 ('', 'template', '',
89 ('', 'template', '',
90 _('display with template'), _('TEMPLATE')),
90 _('display with template'), _('TEMPLATE')),
91 ]
91 ]
92
92
93 logopts = [
93 logopts = [
94 ('p', 'patch', None, _('show patch')),
94 ('p', 'patch', None, _('show patch')),
95 ('g', 'git', None, _('use git extended diff format')),
95 ('g', 'git', None, _('use git extended diff format')),
96 ('l', 'limit', '',
96 ('l', 'limit', '',
97 _('limit number of changes displayed'), _('NUM')),
97 _('limit number of changes displayed'), _('NUM')),
98 ('M', 'no-merges', None, _('do not show merges')),
98 ('M', 'no-merges', None, _('do not show merges')),
99 ('', 'stat', None, _('output diffstat-style summary of changes')),
99 ('', 'stat', None, _('output diffstat-style summary of changes')),
100 ] + templateopts
100 ] + templateopts
101
101
102 diffopts = [
102 diffopts = [
103 ('a', 'text', None, _('treat all files as text')),
103 ('a', 'text', None, _('treat all files as text')),
104 ('g', 'git', None, _('use git extended diff format')),
104 ('g', 'git', None, _('use git extended diff format')),
105 ('', 'nodates', None, _('omit dates from diff headers'))
105 ('', 'nodates', None, _('omit dates from diff headers'))
106 ]
106 ]
107
107
108 diffopts2 = [
108 diffopts2 = [
109 ('p', 'show-function', None, _('show which function each change is in')),
109 ('p', 'show-function', None, _('show which function each change is in')),
110 ('', 'reverse', None, _('produce a diff that undoes the changes')),
110 ('', 'reverse', None, _('produce a diff that undoes the changes')),
111 ('w', 'ignore-all-space', None,
111 ('w', 'ignore-all-space', None,
112 _('ignore white space when comparing lines')),
112 _('ignore white space when comparing lines')),
113 ('b', 'ignore-space-change', None,
113 ('b', 'ignore-space-change', None,
114 _('ignore changes in the amount of white space')),
114 _('ignore changes in the amount of white space')),
115 ('B', 'ignore-blank-lines', None,
115 ('B', 'ignore-blank-lines', None,
116 _('ignore changes whose lines are all blank')),
116 _('ignore changes whose lines are all blank')),
117 ('U', 'unified', '',
117 ('U', 'unified', '',
118 _('number of lines of context to show'), _('NUM')),
118 _('number of lines of context to show'), _('NUM')),
119 ('', 'stat', None, _('output diffstat-style summary of changes')),
119 ('', 'stat', None, _('output diffstat-style summary of changes')),
120 ]
120 ]
121
121
122 mergetoolopts = [
122 mergetoolopts = [
123 ('t', 'tool', '', _('specify merge tool')),
123 ('t', 'tool', '', _('specify merge tool')),
124 ]
124 ]
125
125
126 similarityopts = [
126 similarityopts = [
127 ('s', 'similarity', '',
127 ('s', 'similarity', '',
128 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
128 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
129 ]
129 ]
130
130
131 subrepoopts = [
131 subrepoopts = [
132 ('S', 'subrepos', None,
132 ('S', 'subrepos', None,
133 _('recurse into subrepositories'))
133 _('recurse into subrepositories'))
134 ]
134 ]
135
135
136 # Commands start here, listed alphabetically
136 # Commands start here, listed alphabetically
137
137
138 @command('^add',
138 @command('^add',
139 walkopts + subrepoopts + dryrunopts,
139 walkopts + subrepoopts + dryrunopts,
140 _('[OPTION]... [FILE]...'))
140 _('[OPTION]... [FILE]...'))
141 def add(ui, repo, *pats, **opts):
141 def add(ui, repo, *pats, **opts):
142 """add the specified files on the next commit
142 """add the specified files on the next commit
143
143
144 Schedule files to be version controlled and added to the
144 Schedule files to be version controlled and added to the
145 repository.
145 repository.
146
146
147 The files will be added to the repository at the next commit. To
147 The files will be added to the repository at the next commit. To
148 undo an add before that, see :hg:`forget`.
148 undo an add before that, see :hg:`forget`.
149
149
150 If no names are given, add all files to the repository.
150 If no names are given, add all files to the repository.
151
151
152 .. container:: verbose
152 .. container:: verbose
153
153
154 An example showing how new (unknown) files are added
154 An example showing how new (unknown) files are added
155 automatically by :hg:`add`::
155 automatically by :hg:`add`::
156
156
157 $ ls
157 $ ls
158 foo.c
158 foo.c
159 $ hg status
159 $ hg status
160 ? foo.c
160 ? foo.c
161 $ hg add
161 $ hg add
162 adding foo.c
162 adding foo.c
163 $ hg status
163 $ hg status
164 A foo.c
164 A foo.c
165
165
166 Returns 0 if all files are successfully added.
166 Returns 0 if all files are successfully added.
167 """
167 """
168
168
169 m = scmutil.match(repo[None], pats, opts)
169 m = scmutil.match(repo[None], pats, opts)
170 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
170 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
171 opts.get('subrepos'), prefix="")
171 opts.get('subrepos'), prefix="")
172 return rejected and 1 or 0
172 return rejected and 1 or 0
173
173
174 @command('addremove',
174 @command('addremove',
175 similarityopts + walkopts + dryrunopts,
175 similarityopts + walkopts + dryrunopts,
176 _('[OPTION]... [FILE]...'))
176 _('[OPTION]... [FILE]...'))
177 def addremove(ui, repo, *pats, **opts):
177 def addremove(ui, repo, *pats, **opts):
178 """add all new files, delete all missing files
178 """add all new files, delete all missing files
179
179
180 Add all new files and remove all missing files from the
180 Add all new files and remove all missing files from the
181 repository.
181 repository.
182
182
183 New files are ignored if they match any of the patterns in
183 New files are ignored if they match any of the patterns in
184 ``.hgignore``. As with add, these changes take effect at the next
184 ``.hgignore``. As with add, these changes take effect at the next
185 commit.
185 commit.
186
186
187 Use the -s/--similarity option to detect renamed files. With a
187 Use the -s/--similarity option to detect renamed files. With a
188 parameter greater than 0, this compares every removed file with
188 parameter greater than 0, this compares every removed file with
189 every added file and records those similar enough as renames. This
189 every added file and records those similar enough as renames. This
190 option takes a percentage between 0 (disabled) and 100 (files must
190 option takes a percentage between 0 (disabled) and 100 (files must
191 be identical) as its parameter. Detecting renamed files this way
191 be identical) as its parameter. Detecting renamed files this way
192 can be expensive. After using this option, :hg:`status -C` can be
192 can be expensive. After using this option, :hg:`status -C` can be
193 used to check which files were identified as moved or renamed.
193 used to check which files were identified as moved or renamed.
194
194
195 Returns 0 if all files are successfully added.
195 Returns 0 if all files are successfully added.
196 """
196 """
197 try:
197 try:
198 sim = float(opts.get('similarity') or 100)
198 sim = float(opts.get('similarity') or 100)
199 except ValueError:
199 except ValueError:
200 raise util.Abort(_('similarity must be a number'))
200 raise util.Abort(_('similarity must be a number'))
201 if sim < 0 or sim > 100:
201 if sim < 0 or sim > 100:
202 raise util.Abort(_('similarity must be between 0 and 100'))
202 raise util.Abort(_('similarity must be between 0 and 100'))
203 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
203 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
204
204
205 @command('^annotate|blame',
205 @command('^annotate|blame',
206 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
206 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
207 ('', 'follow', None,
207 ('', 'follow', None,
208 _('follow copies/renames and list the filename (DEPRECATED)')),
208 _('follow copies/renames and list the filename (DEPRECATED)')),
209 ('', 'no-follow', None, _("don't follow copies and renames")),
209 ('', 'no-follow', None, _("don't follow copies and renames")),
210 ('a', 'text', None, _('treat all files as text')),
210 ('a', 'text', None, _('treat all files as text')),
211 ('u', 'user', None, _('list the author (long with -v)')),
211 ('u', 'user', None, _('list the author (long with -v)')),
212 ('f', 'file', None, _('list the filename')),
212 ('f', 'file', None, _('list the filename')),
213 ('d', 'date', None, _('list the date (short with -q)')),
213 ('d', 'date', None, _('list the date (short with -q)')),
214 ('n', 'number', None, _('list the revision number (default)')),
214 ('n', 'number', None, _('list the revision number (default)')),
215 ('c', 'changeset', None, _('list the changeset')),
215 ('c', 'changeset', None, _('list the changeset')),
216 ('l', 'line-number', None, _('show line number at the first appearance'))
216 ('l', 'line-number', None, _('show line number at the first appearance'))
217 ] + walkopts,
217 ] + walkopts,
218 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
218 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
219 def annotate(ui, repo, *pats, **opts):
219 def annotate(ui, repo, *pats, **opts):
220 """show changeset information by line for each file
220 """show changeset information by line for each file
221
221
222 List changes in files, showing the revision id responsible for
222 List changes in files, showing the revision id responsible for
223 each line
223 each line
224
224
225 This command is useful for discovering when a change was made and
225 This command is useful for discovering when a change was made and
226 by whom.
226 by whom.
227
227
228 Without the -a/--text option, annotate will avoid processing files
228 Without the -a/--text option, annotate will avoid processing files
229 it detects as binary. With -a, annotate will annotate the file
229 it detects as binary. With -a, annotate will annotate the file
230 anyway, although the results will probably be neither useful
230 anyway, although the results will probably be neither useful
231 nor desirable.
231 nor desirable.
232
232
233 Returns 0 on success.
233 Returns 0 on success.
234 """
234 """
235 if opts.get('follow'):
235 if opts.get('follow'):
236 # --follow is deprecated and now just an alias for -f/--file
236 # --follow is deprecated and now just an alias for -f/--file
237 # to mimic the behavior of Mercurial before version 1.5
237 # to mimic the behavior of Mercurial before version 1.5
238 opts['file'] = True
238 opts['file'] = True
239
239
240 datefunc = ui.quiet and util.shortdate or util.datestr
240 datefunc = ui.quiet and util.shortdate or util.datestr
241 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
241 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
242
242
243 if not pats:
243 if not pats:
244 raise util.Abort(_('at least one filename or pattern is required'))
244 raise util.Abort(_('at least one filename or pattern is required'))
245
245
246 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
246 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
247 ('number', ' ', lambda x: str(x[0].rev())),
247 ('number', ' ', lambda x: str(x[0].rev())),
248 ('changeset', ' ', lambda x: short(x[0].node())),
248 ('changeset', ' ', lambda x: short(x[0].node())),
249 ('date', ' ', getdate),
249 ('date', ' ', getdate),
250 ('file', ' ', lambda x: x[0].path()),
250 ('file', ' ', lambda x: x[0].path()),
251 ('line_number', ':', lambda x: str(x[1])),
251 ('line_number', ':', lambda x: str(x[1])),
252 ]
252 ]
253
253
254 if (not opts.get('user') and not opts.get('changeset')
254 if (not opts.get('user') and not opts.get('changeset')
255 and not opts.get('date') and not opts.get('file')):
255 and not opts.get('date') and not opts.get('file')):
256 opts['number'] = True
256 opts['number'] = True
257
257
258 linenumber = opts.get('line_number') is not None
258 linenumber = opts.get('line_number') is not None
259 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
259 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
260 raise util.Abort(_('at least one of -n/-c is required for -l'))
260 raise util.Abort(_('at least one of -n/-c is required for -l'))
261
261
262 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
262 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
263 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
263 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
264
264
265 def bad(x, y):
265 def bad(x, y):
266 raise util.Abort("%s: %s" % (x, y))
266 raise util.Abort("%s: %s" % (x, y))
267
267
268 ctx = scmutil.revsingle(repo, opts.get('rev'))
268 ctx = scmutil.revsingle(repo, opts.get('rev'))
269 m = scmutil.match(ctx, pats, opts)
269 m = scmutil.match(ctx, pats, opts)
270 m.bad = bad
270 m.bad = bad
271 follow = not opts.get('no_follow')
271 follow = not opts.get('no_follow')
272 for abs in ctx.walk(m):
272 for abs in ctx.walk(m):
273 fctx = ctx[abs]
273 fctx = ctx[abs]
274 if not opts.get('text') and util.binary(fctx.data()):
274 if not opts.get('text') and util.binary(fctx.data()):
275 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
275 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
276 continue
276 continue
277
277
278 lines = fctx.annotate(follow=follow, linenumber=linenumber)
278 lines = fctx.annotate(follow=follow, linenumber=linenumber)
279 pieces = []
279 pieces = []
280
280
281 for f, sep in funcmap:
281 for f, sep in funcmap:
282 l = [f(n) for n, dummy in lines]
282 l = [f(n) for n, dummy in lines]
283 if l:
283 if l:
284 sized = [(x, encoding.colwidth(x)) for x in l]
284 sized = [(x, encoding.colwidth(x)) for x in l]
285 ml = max([w for x, w in sized])
285 ml = max([w for x, w in sized])
286 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
286 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
287 for x, w in sized])
287 for x, w in sized])
288
288
289 if pieces:
289 if pieces:
290 for p, l in zip(zip(*pieces), lines):
290 for p, l in zip(zip(*pieces), lines):
291 ui.write("%s: %s" % ("".join(p), l[1]))
291 ui.write("%s: %s" % ("".join(p), l[1]))
292
292
293 @command('archive',
293 @command('archive',
294 [('', 'no-decode', None, _('do not pass files through decoders')),
294 [('', 'no-decode', None, _('do not pass files through decoders')),
295 ('p', 'prefix', '', _('directory prefix for files in archive'),
295 ('p', 'prefix', '', _('directory prefix for files in archive'),
296 _('PREFIX')),
296 _('PREFIX')),
297 ('r', 'rev', '', _('revision to distribute'), _('REV')),
297 ('r', 'rev', '', _('revision to distribute'), _('REV')),
298 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
298 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
299 ] + subrepoopts + walkopts,
299 ] + subrepoopts + walkopts,
300 _('[OPTION]... DEST'))
300 _('[OPTION]... DEST'))
301 def archive(ui, repo, dest, **opts):
301 def archive(ui, repo, dest, **opts):
302 '''create an unversioned archive of a repository revision
302 '''create an unversioned archive of a repository revision
303
303
304 By default, the revision used is the parent of the working
304 By default, the revision used is the parent of the working
305 directory; use -r/--rev to specify a different revision.
305 directory; use -r/--rev to specify a different revision.
306
306
307 The archive type is automatically detected based on file
307 The archive type is automatically detected based on file
308 extension (or override using -t/--type).
308 extension (or override using -t/--type).
309
309
310 .. container:: verbose
310 .. container:: verbose
311
311
312 Examples:
312 Examples:
313
313
314 - create a zip file containing the 1.0 release::
314 - create a zip file containing the 1.0 release::
315
315
316 hg archive -r 1.0 project-1.0.zip
316 hg archive -r 1.0 project-1.0.zip
317
317
318 - create a tarball excluding .hg files::
318 - create a tarball excluding .hg files::
319
319
320 hg archive project.tar.gz -X ".hg*"
320 hg archive project.tar.gz -X ".hg*"
321
321
322 Valid types are:
322 Valid types are:
323
323
324 :``files``: a directory full of files (default)
324 :``files``: a directory full of files (default)
325 :``tar``: tar archive, uncompressed
325 :``tar``: tar archive, uncompressed
326 :``tbz2``: tar archive, compressed using bzip2
326 :``tbz2``: tar archive, compressed using bzip2
327 :``tgz``: tar archive, compressed using gzip
327 :``tgz``: tar archive, compressed using gzip
328 :``uzip``: zip archive, uncompressed
328 :``uzip``: zip archive, uncompressed
329 :``zip``: zip archive, compressed using deflate
329 :``zip``: zip archive, compressed using deflate
330
330
331 The exact name of the destination archive or directory is given
331 The exact name of the destination archive or directory is given
332 using a format string; see :hg:`help export` for details.
332 using a format string; see :hg:`help export` for details.
333
333
334 Each member added to an archive file has a directory prefix
334 Each member added to an archive file has a directory prefix
335 prepended. Use -p/--prefix to specify a format string for the
335 prepended. Use -p/--prefix to specify a format string for the
336 prefix. The default is the basename of the archive, with suffixes
336 prefix. The default is the basename of the archive, with suffixes
337 removed.
337 removed.
338
338
339 Returns 0 on success.
339 Returns 0 on success.
340 '''
340 '''
341
341
342 ctx = scmutil.revsingle(repo, opts.get('rev'))
342 ctx = scmutil.revsingle(repo, opts.get('rev'))
343 if not ctx:
343 if not ctx:
344 raise util.Abort(_('no working directory: please specify a revision'))
344 raise util.Abort(_('no working directory: please specify a revision'))
345 node = ctx.node()
345 node = ctx.node()
346 dest = cmdutil.makefilename(repo, dest, node)
346 dest = cmdutil.makefilename(repo, dest, node)
347 if os.path.realpath(dest) == repo.root:
347 if os.path.realpath(dest) == repo.root:
348 raise util.Abort(_('repository root cannot be destination'))
348 raise util.Abort(_('repository root cannot be destination'))
349
349
350 kind = opts.get('type') or archival.guesskind(dest) or 'files'
350 kind = opts.get('type') or archival.guesskind(dest) or 'files'
351 prefix = opts.get('prefix')
351 prefix = opts.get('prefix')
352
352
353 if dest == '-':
353 if dest == '-':
354 if kind == 'files':
354 if kind == 'files':
355 raise util.Abort(_('cannot archive plain files to stdout'))
355 raise util.Abort(_('cannot archive plain files to stdout'))
356 dest = cmdutil.makefileobj(repo, dest)
356 dest = cmdutil.makefileobj(repo, dest)
357 if not prefix:
357 if not prefix:
358 prefix = os.path.basename(repo.root) + '-%h'
358 prefix = os.path.basename(repo.root) + '-%h'
359
359
360 prefix = cmdutil.makefilename(repo, prefix, node)
360 prefix = cmdutil.makefilename(repo, prefix, node)
361 matchfn = scmutil.match(ctx, [], opts)
361 matchfn = scmutil.match(ctx, [], opts)
362 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
362 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
363 matchfn, prefix, subrepos=opts.get('subrepos'))
363 matchfn, prefix, subrepos=opts.get('subrepos'))
364
364
365 @command('backout',
365 @command('backout',
366 [('', 'merge', None, _('merge with old dirstate parent after backout')),
366 [('', 'merge', None, _('merge with old dirstate parent after backout')),
367 ('', 'parent', '',
367 ('', 'parent', '',
368 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
368 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
369 ('r', 'rev', '', _('revision to backout'), _('REV')),
369 ('r', 'rev', '', _('revision to backout'), _('REV')),
370 ] + mergetoolopts + walkopts + commitopts + commitopts2,
370 ] + mergetoolopts + walkopts + commitopts + commitopts2,
371 _('[OPTION]... [-r] REV'))
371 _('[OPTION]... [-r] REV'))
372 def backout(ui, repo, node=None, rev=None, **opts):
372 def backout(ui, repo, node=None, rev=None, **opts):
373 '''reverse effect of earlier changeset
373 '''reverse effect of earlier changeset
374
374
375 Prepare a new changeset with the effect of REV undone in the
375 Prepare a new changeset with the effect of REV undone in the
376 current working directory.
376 current working directory.
377
377
378 If REV is the parent of the working directory, then this new changeset
378 If REV is the parent of the working directory, then this new changeset
379 is committed automatically. Otherwise, hg needs to merge the
379 is committed automatically. Otherwise, hg needs to merge the
380 changes and the merged result is left uncommitted.
380 changes and the merged result is left uncommitted.
381
381
382 .. note::
382 .. note::
383 backout cannot be used to fix either an unwanted or
383 backout cannot be used to fix either an unwanted or
384 incorrect merge.
384 incorrect merge.
385
385
386 .. container:: verbose
386 .. container:: verbose
387
387
388 By default, the pending changeset will have one parent,
388 By default, the pending changeset will have one parent,
389 maintaining a linear history. With --merge, the pending
389 maintaining a linear history. With --merge, the pending
390 changeset will instead have two parents: the old parent of the
390 changeset will instead have two parents: the old parent of the
391 working directory and a new child of REV that simply undoes REV.
391 working directory and a new child of REV that simply undoes REV.
392
392
393 Before version 1.7, the behavior without --merge was equivalent
393 Before version 1.7, the behavior without --merge was equivalent
394 to specifying --merge followed by :hg:`update --clean .` to
394 to specifying --merge followed by :hg:`update --clean .` to
395 cancel the merge and leave the child of REV as a head to be
395 cancel the merge and leave the child of REV as a head to be
396 merged separately.
396 merged separately.
397
397
398 See :hg:`help dates` for a list of formats valid for -d/--date.
398 See :hg:`help dates` for a list of formats valid for -d/--date.
399
399
400 Returns 0 on success.
400 Returns 0 on success.
401 '''
401 '''
402 if rev and node:
402 if rev and node:
403 raise util.Abort(_("please specify just one revision"))
403 raise util.Abort(_("please specify just one revision"))
404
404
405 if not rev:
405 if not rev:
406 rev = node
406 rev = node
407
407
408 if not rev:
408 if not rev:
409 raise util.Abort(_("please specify a revision to backout"))
409 raise util.Abort(_("please specify a revision to backout"))
410
410
411 date = opts.get('date')
411 date = opts.get('date')
412 if date:
412 if date:
413 opts['date'] = util.parsedate(date)
413 opts['date'] = util.parsedate(date)
414
414
415 cmdutil.bailifchanged(repo)
415 cmdutil.bailifchanged(repo)
416 node = scmutil.revsingle(repo, rev).node()
416 node = scmutil.revsingle(repo, rev).node()
417
417
418 op1, op2 = repo.dirstate.parents()
418 op1, op2 = repo.dirstate.parents()
419 a = repo.changelog.ancestor(op1, node)
419 a = repo.changelog.ancestor(op1, node)
420 if a != node:
420 if a != node:
421 raise util.Abort(_('cannot backout change on a different branch'))
421 raise util.Abort(_('cannot backout change on a different branch'))
422
422
423 p1, p2 = repo.changelog.parents(node)
423 p1, p2 = repo.changelog.parents(node)
424 if p1 == nullid:
424 if p1 == nullid:
425 raise util.Abort(_('cannot backout a change with no parents'))
425 raise util.Abort(_('cannot backout a change with no parents'))
426 if p2 != nullid:
426 if p2 != nullid:
427 if not opts.get('parent'):
427 if not opts.get('parent'):
428 raise util.Abort(_('cannot backout a merge changeset'))
428 raise util.Abort(_('cannot backout a merge changeset'))
429 p = repo.lookup(opts['parent'])
429 p = repo.lookup(opts['parent'])
430 if p not in (p1, p2):
430 if p not in (p1, p2):
431 raise util.Abort(_('%s is not a parent of %s') %
431 raise util.Abort(_('%s is not a parent of %s') %
432 (short(p), short(node)))
432 (short(p), short(node)))
433 parent = p
433 parent = p
434 else:
434 else:
435 if opts.get('parent'):
435 if opts.get('parent'):
436 raise util.Abort(_('cannot use --parent on non-merge changeset'))
436 raise util.Abort(_('cannot use --parent on non-merge changeset'))
437 parent = p1
437 parent = p1
438
438
439 # the backout should appear on the same branch
439 # the backout should appear on the same branch
440 branch = repo.dirstate.branch()
440 branch = repo.dirstate.branch()
441 hg.clean(repo, node, show_stats=False)
441 hg.clean(repo, node, show_stats=False)
442 repo.dirstate.setbranch(branch)
442 repo.dirstate.setbranch(branch)
443 revert_opts = opts.copy()
443 revert_opts = opts.copy()
444 revert_opts['date'] = None
444 revert_opts['date'] = None
445 revert_opts['all'] = True
445 revert_opts['all'] = True
446 revert_opts['rev'] = hex(parent)
446 revert_opts['rev'] = hex(parent)
447 revert_opts['no_backup'] = None
447 revert_opts['no_backup'] = None
448 revert(ui, repo, **revert_opts)
448 revert(ui, repo, **revert_opts)
449 if not opts.get('merge') and op1 != node:
449 if not opts.get('merge') and op1 != node:
450 try:
450 try:
451 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
451 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
452 return hg.update(repo, op1)
452 return hg.update(repo, op1)
453 finally:
453 finally:
454 ui.setconfig('ui', 'forcemerge', '')
454 ui.setconfig('ui', 'forcemerge', '')
455
455
456 commit_opts = opts.copy()
456 commit_opts = opts.copy()
457 commit_opts['addremove'] = False
457 commit_opts['addremove'] = False
458 if not commit_opts['message'] and not commit_opts['logfile']:
458 if not commit_opts['message'] and not commit_opts['logfile']:
459 # we don't translate commit messages
459 # we don't translate commit messages
460 commit_opts['message'] = "Backed out changeset %s" % short(node)
460 commit_opts['message'] = "Backed out changeset %s" % short(node)
461 commit_opts['force_editor'] = True
461 commit_opts['force_editor'] = True
462 commit(ui, repo, **commit_opts)
462 commit(ui, repo, **commit_opts)
463 def nice(node):
463 def nice(node):
464 return '%d:%s' % (repo.changelog.rev(node), short(node))
464 return '%d:%s' % (repo.changelog.rev(node), short(node))
465 ui.status(_('changeset %s backs out changeset %s\n') %
465 ui.status(_('changeset %s backs out changeset %s\n') %
466 (nice(repo.changelog.tip()), nice(node)))
466 (nice(repo.changelog.tip()), nice(node)))
467 if opts.get('merge') and op1 != node:
467 if opts.get('merge') and op1 != node:
468 hg.clean(repo, op1, show_stats=False)
468 hg.clean(repo, op1, show_stats=False)
469 ui.status(_('merging with changeset %s\n')
469 ui.status(_('merging with changeset %s\n')
470 % nice(repo.changelog.tip()))
470 % nice(repo.changelog.tip()))
471 try:
471 try:
472 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
472 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
473 return hg.merge(repo, hex(repo.changelog.tip()))
473 return hg.merge(repo, hex(repo.changelog.tip()))
474 finally:
474 finally:
475 ui.setconfig('ui', 'forcemerge', '')
475 ui.setconfig('ui', 'forcemerge', '')
476 return 0
476 return 0
477
477
478 @command('bisect',
478 @command('bisect',
479 [('r', 'reset', False, _('reset bisect state')),
479 [('r', 'reset', False, _('reset bisect state')),
480 ('g', 'good', False, _('mark changeset good')),
480 ('g', 'good', False, _('mark changeset good')),
481 ('b', 'bad', False, _('mark changeset bad')),
481 ('b', 'bad', False, _('mark changeset bad')),
482 ('s', 'skip', False, _('skip testing changeset')),
482 ('s', 'skip', False, _('skip testing changeset')),
483 ('e', 'extend', False, _('extend the bisect range')),
483 ('e', 'extend', False, _('extend the bisect range')),
484 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
484 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
485 ('U', 'noupdate', False, _('do not update to target'))],
485 ('U', 'noupdate', False, _('do not update to target'))],
486 _("[-gbsr] [-U] [-c CMD] [REV]"))
486 _("[-gbsr] [-U] [-c CMD] [REV]"))
487 def bisect(ui, repo, rev=None, extra=None, command=None,
487 def bisect(ui, repo, rev=None, extra=None, command=None,
488 reset=None, good=None, bad=None, skip=None, extend=None,
488 reset=None, good=None, bad=None, skip=None, extend=None,
489 noupdate=None):
489 noupdate=None):
490 """subdivision search of changesets
490 """subdivision search of changesets
491
491
492 This command helps to find changesets which introduce problems. To
492 This command helps to find changesets which introduce problems. To
493 use, mark the earliest changeset you know exhibits the problem as
493 use, mark the earliest changeset you know exhibits the problem as
494 bad, then mark the latest changeset which is free from the problem
494 bad, then mark the latest changeset which is free from the problem
495 as good. Bisect will update your working directory to a revision
495 as good. Bisect will update your working directory to a revision
496 for testing (unless the -U/--noupdate option is specified). Once
496 for testing (unless the -U/--noupdate option is specified). Once
497 you have performed tests, mark the working directory as good or
497 you have performed tests, mark the working directory as good or
498 bad, and bisect will either update to another candidate changeset
498 bad, and bisect will either update to another candidate changeset
499 or announce that it has found the bad revision.
499 or announce that it has found the bad revision.
500
500
501 As a shortcut, you can also use the revision argument to mark a
501 As a shortcut, you can also use the revision argument to mark a
502 revision as good or bad without checking it out first.
502 revision as good or bad without checking it out first.
503
503
504 If you supply a command, it will be used for automatic bisection.
504 If you supply a command, it will be used for automatic bisection.
505 Its exit status will be used to mark revisions as good or bad:
505 Its exit status will be used to mark revisions as good or bad:
506 status 0 means good, 125 means to skip the revision, 127
506 status 0 means good, 125 means to skip the revision, 127
507 (command not found) will abort the bisection, and any other
507 (command not found) will abort the bisection, and any other
508 non-zero exit status means the revision is bad.
508 non-zero exit status means the revision is bad.
509
509
510 .. container:: verbose
510 .. container:: verbose
511
511
512 Some examples:
512 Some examples:
513
513
514 - start a bisection with known bad revision 12, and good revision 34::
514 - start a bisection with known bad revision 12, and good revision 34::
515
515
516 hg bisect --bad 34
516 hg bisect --bad 34
517 hg bisect --good 12
517 hg bisect --good 12
518
518
519 - advance the current bisection by marking current revision as good or
519 - advance the current bisection by marking current revision as good or
520 bad::
520 bad::
521
521
522 hg bisect --good
522 hg bisect --good
523 hg bisect --bad
523 hg bisect --bad
524
524
525 - mark the current revision, or a known revision, to be skipped (eg. if
525 - mark the current revision, or a known revision, to be skipped (eg. if
526 that revision is not usable because of another issue)::
526 that revision is not usable because of another issue)::
527
527
528 hg bisect --skip
528 hg bisect --skip
529 hg bisect --skip 23
529 hg bisect --skip 23
530
530
531 - forget the current bisection::
531 - forget the current bisection::
532
532
533 hg bisect --reset
533 hg bisect --reset
534
534
535 - use 'make && make tests' to automatically find the first broken
535 - use 'make && make tests' to automatically find the first broken
536 revision::
536 revision::
537
537
538 hg bisect --reset
538 hg bisect --reset
539 hg bisect --bad 34
539 hg bisect --bad 34
540 hg bisect --good 12
540 hg bisect --good 12
541 hg bisect --command 'make && make tests'
541 hg bisect --command 'make && make tests'
542
542
543 - see all changesets whose states are already known in the current
543 - see all changesets whose states are already known in the current
544 bisection::
544 bisection::
545
545
546 hg log -r "bisect(pruned)"
546 hg log -r "bisect(pruned)"
547
547
548 - see all changesets that took part in the current bisection::
548 - see all changesets that took part in the current bisection::
549
549
550 hg log -r "bisect(range)"
550 hg log -r "bisect(range)"
551
551
552 - with the graphlog extension, you can even get a nice graph::
552 - with the graphlog extension, you can even get a nice graph::
553
553
554 hg log --graph -r "bisect(range)"
554 hg log --graph -r "bisect(range)"
555
555
556 See :hg:`help revsets` for more about the `bisect()` keyword.
556 See :hg:`help revsets` for more about the `bisect()` keyword.
557
557
558 Returns 0 on success.
558 Returns 0 on success.
559 """
559 """
560 def extendbisectrange(nodes, good):
560 def extendbisectrange(nodes, good):
561 # bisect is incomplete when it ends on a merge node and
561 # bisect is incomplete when it ends on a merge node and
562 # one of the parent was not checked.
562 # one of the parent was not checked.
563 parents = repo[nodes[0]].parents()
563 parents = repo[nodes[0]].parents()
564 if len(parents) > 1:
564 if len(parents) > 1:
565 side = good and state['bad'] or state['good']
565 side = good and state['bad'] or state['good']
566 num = len(set(i.node() for i in parents) & set(side))
566 num = len(set(i.node() for i in parents) & set(side))
567 if num == 1:
567 if num == 1:
568 return parents[0].ancestor(parents[1])
568 return parents[0].ancestor(parents[1])
569 return None
569 return None
570
570
571 def print_result(nodes, good):
571 def print_result(nodes, good):
572 displayer = cmdutil.show_changeset(ui, repo, {})
572 displayer = cmdutil.show_changeset(ui, repo, {})
573 if len(nodes) == 1:
573 if len(nodes) == 1:
574 # narrowed it down to a single revision
574 # narrowed it down to a single revision
575 if good:
575 if good:
576 ui.write(_("The first good revision is:\n"))
576 ui.write(_("The first good revision is:\n"))
577 else:
577 else:
578 ui.write(_("The first bad revision is:\n"))
578 ui.write(_("The first bad revision is:\n"))
579 displayer.show(repo[nodes[0]])
579 displayer.show(repo[nodes[0]])
580 extendnode = extendbisectrange(nodes, good)
580 extendnode = extendbisectrange(nodes, good)
581 if extendnode is not None:
581 if extendnode is not None:
582 ui.write(_('Not all ancestors of this changeset have been'
582 ui.write(_('Not all ancestors of this changeset have been'
583 ' checked.\nUse bisect --extend to continue the '
583 ' checked.\nUse bisect --extend to continue the '
584 'bisection from\nthe common ancestor, %s.\n')
584 'bisection from\nthe common ancestor, %s.\n')
585 % extendnode)
585 % extendnode)
586 else:
586 else:
587 # multiple possible revisions
587 # multiple possible revisions
588 if good:
588 if good:
589 ui.write(_("Due to skipped revisions, the first "
589 ui.write(_("Due to skipped revisions, the first "
590 "good revision could be any of:\n"))
590 "good revision could be any of:\n"))
591 else:
591 else:
592 ui.write(_("Due to skipped revisions, the first "
592 ui.write(_("Due to skipped revisions, the first "
593 "bad revision could be any of:\n"))
593 "bad revision could be any of:\n"))
594 for n in nodes:
594 for n in nodes:
595 displayer.show(repo[n])
595 displayer.show(repo[n])
596 displayer.close()
596 displayer.close()
597
597
598 def check_state(state, interactive=True):
598 def check_state(state, interactive=True):
599 if not state['good'] or not state['bad']:
599 if not state['good'] or not state['bad']:
600 if (good or bad or skip or reset) and interactive:
600 if (good or bad or skip or reset) and interactive:
601 return
601 return
602 if not state['good']:
602 if not state['good']:
603 raise util.Abort(_('cannot bisect (no known good revisions)'))
603 raise util.Abort(_('cannot bisect (no known good revisions)'))
604 else:
604 else:
605 raise util.Abort(_('cannot bisect (no known bad revisions)'))
605 raise util.Abort(_('cannot bisect (no known bad revisions)'))
606 return True
606 return True
607
607
608 # backward compatibility
608 # backward compatibility
609 if rev in "good bad reset init".split():
609 if rev in "good bad reset init".split():
610 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
610 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
611 cmd, rev, extra = rev, extra, None
611 cmd, rev, extra = rev, extra, None
612 if cmd == "good":
612 if cmd == "good":
613 good = True
613 good = True
614 elif cmd == "bad":
614 elif cmd == "bad":
615 bad = True
615 bad = True
616 else:
616 else:
617 reset = True
617 reset = True
618 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
618 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
619 raise util.Abort(_('incompatible arguments'))
619 raise util.Abort(_('incompatible arguments'))
620
620
621 if reset:
621 if reset:
622 p = repo.join("bisect.state")
622 p = repo.join("bisect.state")
623 if os.path.exists(p):
623 if os.path.exists(p):
624 os.unlink(p)
624 os.unlink(p)
625 return
625 return
626
626
627 state = hbisect.load_state(repo)
627 state = hbisect.load_state(repo)
628
628
629 if command:
629 if command:
630 changesets = 1
630 changesets = 1
631 try:
631 try:
632 while changesets:
632 while changesets:
633 # update state
633 # update state
634 status = util.system(command, out=ui.fout)
634 status = util.system(command, out=ui.fout)
635 if status == 125:
635 if status == 125:
636 transition = "skip"
636 transition = "skip"
637 elif status == 0:
637 elif status == 0:
638 transition = "good"
638 transition = "good"
639 # status < 0 means process was killed
639 # status < 0 means process was killed
640 elif status == 127:
640 elif status == 127:
641 raise util.Abort(_("failed to execute %s") % command)
641 raise util.Abort(_("failed to execute %s") % command)
642 elif status < 0:
642 elif status < 0:
643 raise util.Abort(_("%s killed") % command)
643 raise util.Abort(_("%s killed") % command)
644 else:
644 else:
645 transition = "bad"
645 transition = "bad"
646 ctx = scmutil.revsingle(repo, rev)
646 ctx = scmutil.revsingle(repo, rev)
647 rev = None # clear for future iterations
647 rev = None # clear for future iterations
648 state[transition].append(ctx.node())
648 state[transition].append(ctx.node())
649 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
649 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
650 check_state(state, interactive=False)
650 check_state(state, interactive=False)
651 # bisect
651 # bisect
652 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
652 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
653 # update to next check
653 # update to next check
654 cmdutil.bailifchanged(repo)
654 cmdutil.bailifchanged(repo)
655 hg.clean(repo, nodes[0], show_stats=False)
655 hg.clean(repo, nodes[0], show_stats=False)
656 finally:
656 finally:
657 hbisect.save_state(repo, state)
657 hbisect.save_state(repo, state)
658 print_result(nodes, good)
658 print_result(nodes, good)
659 return
659 return
660
660
661 # update state
661 # update state
662
662
663 if rev:
663 if rev:
664 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
664 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
665 else:
665 else:
666 nodes = [repo.lookup('.')]
666 nodes = [repo.lookup('.')]
667
667
668 if good or bad or skip:
668 if good or bad or skip:
669 if good:
669 if good:
670 state['good'] += nodes
670 state['good'] += nodes
671 elif bad:
671 elif bad:
672 state['bad'] += nodes
672 state['bad'] += nodes
673 elif skip:
673 elif skip:
674 state['skip'] += nodes
674 state['skip'] += nodes
675 hbisect.save_state(repo, state)
675 hbisect.save_state(repo, state)
676
676
677 if not check_state(state):
677 if not check_state(state):
678 return
678 return
679
679
680 # actually bisect
680 # actually bisect
681 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
681 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
682 if extend:
682 if extend:
683 if not changesets:
683 if not changesets:
684 extendnode = extendbisectrange(nodes, good)
684 extendnode = extendbisectrange(nodes, good)
685 if extendnode is not None:
685 if extendnode is not None:
686 ui.write(_("Extending search to changeset %d:%s\n"
686 ui.write(_("Extending search to changeset %d:%s\n"
687 % (extendnode.rev(), extendnode)))
687 % (extendnode.rev(), extendnode)))
688 if noupdate:
688 if noupdate:
689 return
689 return
690 cmdutil.bailifchanged(repo)
690 cmdutil.bailifchanged(repo)
691 return hg.clean(repo, extendnode.node())
691 return hg.clean(repo, extendnode.node())
692 raise util.Abort(_("nothing to extend"))
692 raise util.Abort(_("nothing to extend"))
693
693
694 if changesets == 0:
694 if changesets == 0:
695 print_result(nodes, good)
695 print_result(nodes, good)
696 else:
696 else:
697 assert len(nodes) == 1 # only a single node can be tested next
697 assert len(nodes) == 1 # only a single node can be tested next
698 node = nodes[0]
698 node = nodes[0]
699 # compute the approximate number of remaining tests
699 # compute the approximate number of remaining tests
700 tests, size = 0, 2
700 tests, size = 0, 2
701 while size <= changesets:
701 while size <= changesets:
702 tests, size = tests + 1, size * 2
702 tests, size = tests + 1, size * 2
703 rev = repo.changelog.rev(node)
703 rev = repo.changelog.rev(node)
704 ui.write(_("Testing changeset %d:%s "
704 ui.write(_("Testing changeset %d:%s "
705 "(%d changesets remaining, ~%d tests)\n")
705 "(%d changesets remaining, ~%d tests)\n")
706 % (rev, short(node), changesets, tests))
706 % (rev, short(node), changesets, tests))
707 if not noupdate:
707 if not noupdate:
708 cmdutil.bailifchanged(repo)
708 cmdutil.bailifchanged(repo)
709 return hg.clean(repo, node)
709 return hg.clean(repo, node)
710
710
711 @command('bookmarks',
711 @command('bookmarks',
712 [('f', 'force', False, _('force')),
712 [('f', 'force', False, _('force')),
713 ('r', 'rev', '', _('revision'), _('REV')),
713 ('r', 'rev', '', _('revision'), _('REV')),
714 ('d', 'delete', False, _('delete a given bookmark')),
714 ('d', 'delete', False, _('delete a given bookmark')),
715 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
715 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
716 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
716 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
717 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]'))
717 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]'))
718 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
718 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
719 rename=None, inactive=False):
719 rename=None, inactive=False):
720 '''track a line of development with movable markers
720 '''track a line of development with movable markers
721
721
722 Bookmarks are pointers to certain commits that move when
722 Bookmarks are pointers to certain commits that move when
723 committing. Bookmarks are local. They can be renamed, copied and
723 committing. Bookmarks are local. They can be renamed, copied and
724 deleted. It is possible to use bookmark names in :hg:`merge` and
724 deleted. It is possible to use bookmark names in :hg:`merge` and
725 :hg:`update` to merge and update respectively to a given bookmark.
725 :hg:`update` to merge and update respectively to a given bookmark.
726
726
727 You can use :hg:`bookmark NAME` to set a bookmark on the working
727 You can use :hg:`bookmark NAME` to set a bookmark on the working
728 directory's parent revision with the given name. If you specify
728 directory's parent revision with the given name. If you specify
729 a revision using -r REV (where REV may be an existing bookmark),
729 a revision using -r REV (where REV may be an existing bookmark),
730 the bookmark is assigned to that revision.
730 the bookmark is assigned to that revision.
731
731
732 Bookmarks can be pushed and pulled between repositories (see :hg:`help
732 Bookmarks can be pushed and pulled between repositories (see :hg:`help
733 push` and :hg:`help pull`). This requires both the local and remote
733 push` and :hg:`help pull`). This requires both the local and remote
734 repositories to support bookmarks. For versions prior to 1.8, this means
734 repositories to support bookmarks. For versions prior to 1.8, this means
735 the bookmarks extension must be enabled.
735 the bookmarks extension must be enabled.
736 '''
736 '''
737 hexfn = ui.debugflag and hex or short
737 hexfn = ui.debugflag and hex or short
738 marks = repo._bookmarks
738 marks = repo._bookmarks
739 cur = repo.changectx('.').node()
739 cur = repo.changectx('.').node()
740
740
741 if rename:
741 if rename:
742 if rename not in marks:
742 if rename not in marks:
743 raise util.Abort(_("bookmark '%s' does not exist") % rename)
743 raise util.Abort(_("bookmark '%s' does not exist") % rename)
744 if mark in marks and not force:
744 if mark in marks and not force:
745 raise util.Abort(_("bookmark '%s' already exists "
745 raise util.Abort(_("bookmark '%s' already exists "
746 "(use -f to force)") % mark)
746 "(use -f to force)") % mark)
747 if mark is None:
747 if mark is None:
748 raise util.Abort(_("new bookmark name required"))
748 raise util.Abort(_("new bookmark name required"))
749 marks[mark] = marks[rename]
749 marks[mark] = marks[rename]
750 if repo._bookmarkcurrent == rename and not inactive:
750 if repo._bookmarkcurrent == rename and not inactive:
751 bookmarks.setcurrent(repo, mark)
751 bookmarks.setcurrent(repo, mark)
752 del marks[rename]
752 del marks[rename]
753 bookmarks.write(repo)
753 bookmarks.write(repo)
754 return
754 return
755
755
756 if delete:
756 if delete:
757 if mark is None:
757 if mark is None:
758 raise util.Abort(_("bookmark name required"))
758 raise util.Abort(_("bookmark name required"))
759 if mark not in marks:
759 if mark not in marks:
760 raise util.Abort(_("bookmark '%s' does not exist") % mark)
760 raise util.Abort(_("bookmark '%s' does not exist") % mark)
761 if mark == repo._bookmarkcurrent:
761 if mark == repo._bookmarkcurrent:
762 bookmarks.setcurrent(repo, None)
762 bookmarks.setcurrent(repo, None)
763 del marks[mark]
763 del marks[mark]
764 bookmarks.write(repo)
764 bookmarks.write(repo)
765 return
765 return
766
766
767 if mark is not None:
767 if mark is not None:
768 if "\n" in mark:
768 if "\n" in mark:
769 raise util.Abort(_("bookmark name cannot contain newlines"))
769 raise util.Abort(_("bookmark name cannot contain newlines"))
770 mark = mark.strip()
770 mark = mark.strip()
771 if not mark:
771 if not mark:
772 raise util.Abort(_("bookmark names cannot consist entirely of "
772 raise util.Abort(_("bookmark names cannot consist entirely of "
773 "whitespace"))
773 "whitespace"))
774 if inactive and mark == repo._bookmarkcurrent:
774 if inactive and mark == repo._bookmarkcurrent:
775 bookmarks.setcurrent(repo, None)
775 bookmarks.setcurrent(repo, None)
776 return
776 return
777 if mark in marks and not force:
777 if mark in marks and not force:
778 raise util.Abort(_("bookmark '%s' already exists "
778 raise util.Abort(_("bookmark '%s' already exists "
779 "(use -f to force)") % mark)
779 "(use -f to force)") % mark)
780 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
780 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
781 and not force):
781 and not force):
782 raise util.Abort(
782 raise util.Abort(
783 _("a bookmark cannot have the name of an existing branch"))
783 _("a bookmark cannot have the name of an existing branch"))
784 if rev:
784 if rev:
785 marks[mark] = repo.lookup(rev)
785 marks[mark] = repo.lookup(rev)
786 else:
786 else:
787 marks[mark] = repo.changectx('.').node()
787 marks[mark] = repo.changectx('.').node()
788 if not inactive and repo.changectx('.').node() == marks[mark]:
788 if not inactive and repo.changectx('.').node() == marks[mark]:
789 bookmarks.setcurrent(repo, mark)
789 bookmarks.setcurrent(repo, mark)
790 bookmarks.write(repo)
790 bookmarks.write(repo)
791 return
791 return
792
792
793 if mark is None:
793 if mark is None:
794 if rev:
794 if rev:
795 raise util.Abort(_("bookmark name required"))
795 raise util.Abort(_("bookmark name required"))
796 if len(marks) == 0:
796 if len(marks) == 0:
797 ui.status(_("no bookmarks set\n"))
797 ui.status(_("no bookmarks set\n"))
798 else:
798 else:
799 for bmark, n in sorted(marks.iteritems()):
799 for bmark, n in sorted(marks.iteritems()):
800 current = repo._bookmarkcurrent
800 current = repo._bookmarkcurrent
801 if bmark == current and n == cur:
801 if bmark == current and n == cur:
802 prefix, label = '*', 'bookmarks.current'
802 prefix, label = '*', 'bookmarks.current'
803 else:
803 else:
804 prefix, label = ' ', ''
804 prefix, label = ' ', ''
805
805
806 if ui.quiet:
806 if ui.quiet:
807 ui.write("%s\n" % bmark, label=label)
807 ui.write("%s\n" % bmark, label=label)
808 else:
808 else:
809 ui.write(" %s %-25s %d:%s\n" % (
809 ui.write(" %s %-25s %d:%s\n" % (
810 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
810 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
811 label=label)
811 label=label)
812 return
812 return
813
813
814 @command('branch',
814 @command('branch',
815 [('f', 'force', None,
815 [('f', 'force', None,
816 _('set branch name even if it shadows an existing branch')),
816 _('set branch name even if it shadows an existing branch')),
817 ('C', 'clean', None, _('reset branch name to parent branch name'))],
817 ('C', 'clean', None, _('reset branch name to parent branch name'))],
818 _('[-fC] [NAME]'))
818 _('[-fC] [NAME]'))
819 def branch(ui, repo, label=None, **opts):
819 def branch(ui, repo, label=None, **opts):
820 """set or show the current branch name
820 """set or show the current branch name
821
821
822 .. note::
822 .. note::
823 Branch names are permanent and global. Use :hg:`bookmark` to create a
823 Branch names are permanent and global. Use :hg:`bookmark` to create a
824 light-weight bookmark instead. See :hg:`help glossary` for more
824 light-weight bookmark instead. See :hg:`help glossary` for more
825 information about named branches and bookmarks.
825 information about named branches and bookmarks.
826
826
827 With no argument, show the current branch name. With one argument,
827 With no argument, show the current branch name. With one argument,
828 set the working directory branch name (the branch will not exist
828 set the working directory branch name (the branch will not exist
829 in the repository until the next commit). Standard practice
829 in the repository until the next commit). Standard practice
830 recommends that primary development take place on the 'default'
830 recommends that primary development take place on the 'default'
831 branch.
831 branch.
832
832
833 Unless -f/--force is specified, branch will not let you set a
833 Unless -f/--force is specified, branch will not let you set a
834 branch name that already exists, even if it's inactive.
834 branch name that already exists, even if it's inactive.
835
835
836 Use -C/--clean to reset the working directory branch to that of
836 Use -C/--clean to reset the working directory branch to that of
837 the parent of the working directory, negating a previous branch
837 the parent of the working directory, negating a previous branch
838 change.
838 change.
839
839
840 Use the command :hg:`update` to switch to an existing branch. Use
840 Use the command :hg:`update` to switch to an existing branch. Use
841 :hg:`commit --close-branch` to mark this branch as closed.
841 :hg:`commit --close-branch` to mark this branch as closed.
842
842
843 Returns 0 on success.
843 Returns 0 on success.
844 """
844 """
845
845
846 if opts.get('clean'):
846 if opts.get('clean'):
847 label = repo[None].p1().branch()
847 label = repo[None].p1().branch()
848 repo.dirstate.setbranch(label)
848 repo.dirstate.setbranch(label)
849 ui.status(_('reset working directory to branch %s\n') % label)
849 ui.status(_('reset working directory to branch %s\n') % label)
850 elif label:
850 elif label:
851 if not opts.get('force') and label in repo.branchtags():
851 if not opts.get('force') and label in repo.branchtags():
852 if label not in [p.branch() for p in repo.parents()]:
852 if label not in [p.branch() for p in repo.parents()]:
853 raise util.Abort(_('a branch of the same name already exists'),
853 raise util.Abort(_('a branch of the same name already exists'),
854 # i18n: "it" refers to an existing branch
854 # i18n: "it" refers to an existing branch
855 hint=_("use 'hg update' to switch to it"))
855 hint=_("use 'hg update' to switch to it"))
856 repo.dirstate.setbranch(label)
856 repo.dirstate.setbranch(label)
857 ui.status(_('marked working directory as branch %s\n') % label)
857 ui.status(_('marked working directory as branch %s\n') % label)
858 ui.status(_('(branches are permanent and global, '
859 'did you want a bookmark?)\n'))
858 else:
860 else:
859 ui.write("%s\n" % repo.dirstate.branch())
861 ui.write("%s\n" % repo.dirstate.branch())
860
862
861 @command('branches',
863 @command('branches',
862 [('a', 'active', False, _('show only branches that have unmerged heads')),
864 [('a', 'active', False, _('show only branches that have unmerged heads')),
863 ('c', 'closed', False, _('show normal and closed branches'))],
865 ('c', 'closed', False, _('show normal and closed branches'))],
864 _('[-ac]'))
866 _('[-ac]'))
865 def branches(ui, repo, active=False, closed=False):
867 def branches(ui, repo, active=False, closed=False):
866 """list repository named branches
868 """list repository named branches
867
869
868 List the repository's named branches, indicating which ones are
870 List the repository's named branches, indicating which ones are
869 inactive. If -c/--closed is specified, also list branches which have
871 inactive. If -c/--closed is specified, also list branches which have
870 been marked closed (see :hg:`commit --close-branch`).
872 been marked closed (see :hg:`commit --close-branch`).
871
873
872 If -a/--active is specified, only show active branches. A branch
874 If -a/--active is specified, only show active branches. A branch
873 is considered active if it contains repository heads.
875 is considered active if it contains repository heads.
874
876
875 Use the command :hg:`update` to switch to an existing branch.
877 Use the command :hg:`update` to switch to an existing branch.
876
878
877 Returns 0.
879 Returns 0.
878 """
880 """
879
881
880 hexfunc = ui.debugflag and hex or short
882 hexfunc = ui.debugflag and hex or short
881 activebranches = [repo[n].branch() for n in repo.heads()]
883 activebranches = [repo[n].branch() for n in repo.heads()]
882 def testactive(tag, node):
884 def testactive(tag, node):
883 realhead = tag in activebranches
885 realhead = tag in activebranches
884 open = node in repo.branchheads(tag, closed=False)
886 open = node in repo.branchheads(tag, closed=False)
885 return realhead and open
887 return realhead and open
886 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
888 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
887 for tag, node in repo.branchtags().items()],
889 for tag, node in repo.branchtags().items()],
888 reverse=True)
890 reverse=True)
889
891
890 for isactive, node, tag in branches:
892 for isactive, node, tag in branches:
891 if (not active) or isactive:
893 if (not active) or isactive:
892 if ui.quiet:
894 if ui.quiet:
893 ui.write("%s\n" % tag)
895 ui.write("%s\n" % tag)
894 else:
896 else:
895 hn = repo.lookup(node)
897 hn = repo.lookup(node)
896 if isactive:
898 if isactive:
897 label = 'branches.active'
899 label = 'branches.active'
898 notice = ''
900 notice = ''
899 elif hn not in repo.branchheads(tag, closed=False):
901 elif hn not in repo.branchheads(tag, closed=False):
900 if not closed:
902 if not closed:
901 continue
903 continue
902 label = 'branches.closed'
904 label = 'branches.closed'
903 notice = _(' (closed)')
905 notice = _(' (closed)')
904 else:
906 else:
905 label = 'branches.inactive'
907 label = 'branches.inactive'
906 notice = _(' (inactive)')
908 notice = _(' (inactive)')
907 if tag == repo.dirstate.branch():
909 if tag == repo.dirstate.branch():
908 label = 'branches.current'
910 label = 'branches.current'
909 rev = str(node).rjust(31 - encoding.colwidth(tag))
911 rev = str(node).rjust(31 - encoding.colwidth(tag))
910 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
912 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
911 tag = ui.label(tag, label)
913 tag = ui.label(tag, label)
912 ui.write("%s %s%s\n" % (tag, rev, notice))
914 ui.write("%s %s%s\n" % (tag, rev, notice))
913
915
914 @command('bundle',
916 @command('bundle',
915 [('f', 'force', None, _('run even when the destination is unrelated')),
917 [('f', 'force', None, _('run even when the destination is unrelated')),
916 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
918 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
917 _('REV')),
919 _('REV')),
918 ('b', 'branch', [], _('a specific branch you would like to bundle'),
920 ('b', 'branch', [], _('a specific branch you would like to bundle'),
919 _('BRANCH')),
921 _('BRANCH')),
920 ('', 'base', [],
922 ('', 'base', [],
921 _('a base changeset assumed to be available at the destination'),
923 _('a base changeset assumed to be available at the destination'),
922 _('REV')),
924 _('REV')),
923 ('a', 'all', None, _('bundle all changesets in the repository')),
925 ('a', 'all', None, _('bundle all changesets in the repository')),
924 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
926 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
925 ] + remoteopts,
927 ] + remoteopts,
926 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
928 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
927 def bundle(ui, repo, fname, dest=None, **opts):
929 def bundle(ui, repo, fname, dest=None, **opts):
928 """create a changegroup file
930 """create a changegroup file
929
931
930 Generate a compressed changegroup file collecting changesets not
932 Generate a compressed changegroup file collecting changesets not
931 known to be in another repository.
933 known to be in another repository.
932
934
933 If you omit the destination repository, then hg assumes the
935 If you omit the destination repository, then hg assumes the
934 destination will have all the nodes you specify with --base
936 destination will have all the nodes you specify with --base
935 parameters. To create a bundle containing all changesets, use
937 parameters. To create a bundle containing all changesets, use
936 -a/--all (or --base null).
938 -a/--all (or --base null).
937
939
938 You can change compression method with the -t/--type option.
940 You can change compression method with the -t/--type option.
939 The available compression methods are: none, bzip2, and
941 The available compression methods are: none, bzip2, and
940 gzip (by default, bundles are compressed using bzip2).
942 gzip (by default, bundles are compressed using bzip2).
941
943
942 The bundle file can then be transferred using conventional means
944 The bundle file can then be transferred using conventional means
943 and applied to another repository with the unbundle or pull
945 and applied to another repository with the unbundle or pull
944 command. This is useful when direct push and pull are not
946 command. This is useful when direct push and pull are not
945 available or when exporting an entire repository is undesirable.
947 available or when exporting an entire repository is undesirable.
946
948
947 Applying bundles preserves all changeset contents including
949 Applying bundles preserves all changeset contents including
948 permissions, copy/rename information, and revision history.
950 permissions, copy/rename information, and revision history.
949
951
950 Returns 0 on success, 1 if no changes found.
952 Returns 0 on success, 1 if no changes found.
951 """
953 """
952 revs = None
954 revs = None
953 if 'rev' in opts:
955 if 'rev' in opts:
954 revs = scmutil.revrange(repo, opts['rev'])
956 revs = scmutil.revrange(repo, opts['rev'])
955
957
956 if opts.get('all'):
958 if opts.get('all'):
957 base = ['null']
959 base = ['null']
958 else:
960 else:
959 base = scmutil.revrange(repo, opts.get('base'))
961 base = scmutil.revrange(repo, opts.get('base'))
960 if base:
962 if base:
961 if dest:
963 if dest:
962 raise util.Abort(_("--base is incompatible with specifying "
964 raise util.Abort(_("--base is incompatible with specifying "
963 "a destination"))
965 "a destination"))
964 common = [repo.lookup(rev) for rev in base]
966 common = [repo.lookup(rev) for rev in base]
965 heads = revs and map(repo.lookup, revs) or revs
967 heads = revs and map(repo.lookup, revs) or revs
966 else:
968 else:
967 dest = ui.expandpath(dest or 'default-push', dest or 'default')
969 dest = ui.expandpath(dest or 'default-push', dest or 'default')
968 dest, branches = hg.parseurl(dest, opts.get('branch'))
970 dest, branches = hg.parseurl(dest, opts.get('branch'))
969 other = hg.peer(repo, opts, dest)
971 other = hg.peer(repo, opts, dest)
970 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
972 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
971 heads = revs and map(repo.lookup, revs) or revs
973 heads = revs and map(repo.lookup, revs) or revs
972 common, outheads = discovery.findcommonoutgoing(repo, other,
974 common, outheads = discovery.findcommonoutgoing(repo, other,
973 onlyheads=heads,
975 onlyheads=heads,
974 force=opts.get('force'))
976 force=opts.get('force'))
975
977
976 cg = repo.getbundle('bundle', common=common, heads=heads)
978 cg = repo.getbundle('bundle', common=common, heads=heads)
977 if not cg:
979 if not cg:
978 ui.status(_("no changes found\n"))
980 ui.status(_("no changes found\n"))
979 return 1
981 return 1
980
982
981 bundletype = opts.get('type', 'bzip2').lower()
983 bundletype = opts.get('type', 'bzip2').lower()
982 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
984 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
983 bundletype = btypes.get(bundletype)
985 bundletype = btypes.get(bundletype)
984 if bundletype not in changegroup.bundletypes:
986 if bundletype not in changegroup.bundletypes:
985 raise util.Abort(_('unknown bundle type specified with --type'))
987 raise util.Abort(_('unknown bundle type specified with --type'))
986
988
987 changegroup.writebundle(cg, fname, bundletype)
989 changegroup.writebundle(cg, fname, bundletype)
988
990
989 @command('cat',
991 @command('cat',
990 [('o', 'output', '',
992 [('o', 'output', '',
991 _('print output to file with formatted name'), _('FORMAT')),
993 _('print output to file with formatted name'), _('FORMAT')),
992 ('r', 'rev', '', _('print the given revision'), _('REV')),
994 ('r', 'rev', '', _('print the given revision'), _('REV')),
993 ('', 'decode', None, _('apply any matching decode filter')),
995 ('', 'decode', None, _('apply any matching decode filter')),
994 ] + walkopts,
996 ] + walkopts,
995 _('[OPTION]... FILE...'))
997 _('[OPTION]... FILE...'))
996 def cat(ui, repo, file1, *pats, **opts):
998 def cat(ui, repo, file1, *pats, **opts):
997 """output the current or given revision of files
999 """output the current or given revision of files
998
1000
999 Print the specified files as they were at the given revision. If
1001 Print the specified files as they were at the given revision. If
1000 no revision is given, the parent of the working directory is used,
1002 no revision is given, the parent of the working directory is used,
1001 or tip if no revision is checked out.
1003 or tip if no revision is checked out.
1002
1004
1003 Output may be to a file, in which case the name of the file is
1005 Output may be to a file, in which case the name of the file is
1004 given using a format string. The formatting rules are the same as
1006 given using a format string. The formatting rules are the same as
1005 for the export command, with the following additions:
1007 for the export command, with the following additions:
1006
1008
1007 :``%s``: basename of file being printed
1009 :``%s``: basename of file being printed
1008 :``%d``: dirname of file being printed, or '.' if in repository root
1010 :``%d``: dirname of file being printed, or '.' if in repository root
1009 :``%p``: root-relative path name of file being printed
1011 :``%p``: root-relative path name of file being printed
1010
1012
1011 Returns 0 on success.
1013 Returns 0 on success.
1012 """
1014 """
1013 ctx = scmutil.revsingle(repo, opts.get('rev'))
1015 ctx = scmutil.revsingle(repo, opts.get('rev'))
1014 err = 1
1016 err = 1
1015 m = scmutil.match(ctx, (file1,) + pats, opts)
1017 m = scmutil.match(ctx, (file1,) + pats, opts)
1016 for abs in ctx.walk(m):
1018 for abs in ctx.walk(m):
1017 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1019 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1018 pathname=abs)
1020 pathname=abs)
1019 data = ctx[abs].data()
1021 data = ctx[abs].data()
1020 if opts.get('decode'):
1022 if opts.get('decode'):
1021 data = repo.wwritedata(abs, data)
1023 data = repo.wwritedata(abs, data)
1022 fp.write(data)
1024 fp.write(data)
1023 fp.close()
1025 fp.close()
1024 err = 0
1026 err = 0
1025 return err
1027 return err
1026
1028
1027 @command('^clone',
1029 @command('^clone',
1028 [('U', 'noupdate', None,
1030 [('U', 'noupdate', None,
1029 _('the clone will include an empty working copy (only a repository)')),
1031 _('the clone will include an empty working copy (only a repository)')),
1030 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1032 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1031 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1033 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1032 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1034 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1033 ('', 'pull', None, _('use pull protocol to copy metadata')),
1035 ('', 'pull', None, _('use pull protocol to copy metadata')),
1034 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1036 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1035 ] + remoteopts,
1037 ] + remoteopts,
1036 _('[OPTION]... SOURCE [DEST]'))
1038 _('[OPTION]... SOURCE [DEST]'))
1037 def clone(ui, source, dest=None, **opts):
1039 def clone(ui, source, dest=None, **opts):
1038 """make a copy of an existing repository
1040 """make a copy of an existing repository
1039
1041
1040 Create a copy of an existing repository in a new directory.
1042 Create a copy of an existing repository in a new directory.
1041
1043
1042 If no destination directory name is specified, it defaults to the
1044 If no destination directory name is specified, it defaults to the
1043 basename of the source.
1045 basename of the source.
1044
1046
1045 The location of the source is added to the new repository's
1047 The location of the source is added to the new repository's
1046 ``.hg/hgrc`` file, as the default to be used for future pulls.
1048 ``.hg/hgrc`` file, as the default to be used for future pulls.
1047
1049
1048 Only local paths and ``ssh://`` URLs are supported as
1050 Only local paths and ``ssh://`` URLs are supported as
1049 destinations. For ``ssh://`` destinations, no working directory or
1051 destinations. For ``ssh://`` destinations, no working directory or
1050 ``.hg/hgrc`` will be created on the remote side.
1052 ``.hg/hgrc`` will be created on the remote side.
1051
1053
1052 To pull only a subset of changesets, specify one or more revisions
1054 To pull only a subset of changesets, specify one or more revisions
1053 identifiers with -r/--rev or branches with -b/--branch. The
1055 identifiers with -r/--rev or branches with -b/--branch. The
1054 resulting clone will contain only the specified changesets and
1056 resulting clone will contain only the specified changesets and
1055 their ancestors. These options (or 'clone src#rev dest') imply
1057 their ancestors. These options (or 'clone src#rev dest') imply
1056 --pull, even for local source repositories. Note that specifying a
1058 --pull, even for local source repositories. Note that specifying a
1057 tag will include the tagged changeset but not the changeset
1059 tag will include the tagged changeset but not the changeset
1058 containing the tag.
1060 containing the tag.
1059
1061
1060 To check out a particular version, use -u/--update, or
1062 To check out a particular version, use -u/--update, or
1061 -U/--noupdate to create a clone with no working directory.
1063 -U/--noupdate to create a clone with no working directory.
1062
1064
1063 .. container:: verbose
1065 .. container:: verbose
1064
1066
1065 For efficiency, hardlinks are used for cloning whenever the
1067 For efficiency, hardlinks are used for cloning whenever the
1066 source and destination are on the same filesystem (note this
1068 source and destination are on the same filesystem (note this
1067 applies only to the repository data, not to the working
1069 applies only to the repository data, not to the working
1068 directory). Some filesystems, such as AFS, implement hardlinking
1070 directory). Some filesystems, such as AFS, implement hardlinking
1069 incorrectly, but do not report errors. In these cases, use the
1071 incorrectly, but do not report errors. In these cases, use the
1070 --pull option to avoid hardlinking.
1072 --pull option to avoid hardlinking.
1071
1073
1072 In some cases, you can clone repositories and the working
1074 In some cases, you can clone repositories and the working
1073 directory using full hardlinks with ::
1075 directory using full hardlinks with ::
1074
1076
1075 $ cp -al REPO REPOCLONE
1077 $ cp -al REPO REPOCLONE
1076
1078
1077 This is the fastest way to clone, but it is not always safe. The
1079 This is the fastest way to clone, but it is not always safe. The
1078 operation is not atomic (making sure REPO is not modified during
1080 operation is not atomic (making sure REPO is not modified during
1079 the operation is up to you) and you have to make sure your
1081 the operation is up to you) and you have to make sure your
1080 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1082 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1081 so). Also, this is not compatible with certain extensions that
1083 so). Also, this is not compatible with certain extensions that
1082 place their metadata under the .hg directory, such as mq.
1084 place their metadata under the .hg directory, such as mq.
1083
1085
1084 Mercurial will update the working directory to the first applicable
1086 Mercurial will update the working directory to the first applicable
1085 revision from this list:
1087 revision from this list:
1086
1088
1087 a) null if -U or the source repository has no changesets
1089 a) null if -U or the source repository has no changesets
1088 b) if -u . and the source repository is local, the first parent of
1090 b) if -u . and the source repository is local, the first parent of
1089 the source repository's working directory
1091 the source repository's working directory
1090 c) the changeset specified with -u (if a branch name, this means the
1092 c) the changeset specified with -u (if a branch name, this means the
1091 latest head of that branch)
1093 latest head of that branch)
1092 d) the changeset specified with -r
1094 d) the changeset specified with -r
1093 e) the tipmost head specified with -b
1095 e) the tipmost head specified with -b
1094 f) the tipmost head specified with the url#branch source syntax
1096 f) the tipmost head specified with the url#branch source syntax
1095 g) the tipmost head of the default branch
1097 g) the tipmost head of the default branch
1096 h) tip
1098 h) tip
1097
1099
1098 Examples:
1100 Examples:
1099
1101
1100 - clone a remote repository to a new directory named hg/::
1102 - clone a remote repository to a new directory named hg/::
1101
1103
1102 hg clone http://selenic.com/hg
1104 hg clone http://selenic.com/hg
1103
1105
1104 - create a lightweight local clone::
1106 - create a lightweight local clone::
1105
1107
1106 hg clone project/ project-feature/
1108 hg clone project/ project-feature/
1107
1109
1108 - clone from an absolute path on an ssh server (note double-slash)::
1110 - clone from an absolute path on an ssh server (note double-slash)::
1109
1111
1110 hg clone ssh://user@server//home/projects/alpha/
1112 hg clone ssh://user@server//home/projects/alpha/
1111
1113
1112 - do a high-speed clone over a LAN while checking out a
1114 - do a high-speed clone over a LAN while checking out a
1113 specified version::
1115 specified version::
1114
1116
1115 hg clone --uncompressed http://server/repo -u 1.5
1117 hg clone --uncompressed http://server/repo -u 1.5
1116
1118
1117 - create a repository without changesets after a particular revision::
1119 - create a repository without changesets after a particular revision::
1118
1120
1119 hg clone -r 04e544 experimental/ good/
1121 hg clone -r 04e544 experimental/ good/
1120
1122
1121 - clone (and track) a particular named branch::
1123 - clone (and track) a particular named branch::
1122
1124
1123 hg clone http://selenic.com/hg#stable
1125 hg clone http://selenic.com/hg#stable
1124
1126
1125 See :hg:`help urls` for details on specifying URLs.
1127 See :hg:`help urls` for details on specifying URLs.
1126
1128
1127 Returns 0 on success.
1129 Returns 0 on success.
1128 """
1130 """
1129 if opts.get('noupdate') and opts.get('updaterev'):
1131 if opts.get('noupdate') and opts.get('updaterev'):
1130 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1132 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1131
1133
1132 r = hg.clone(ui, opts, source, dest,
1134 r = hg.clone(ui, opts, source, dest,
1133 pull=opts.get('pull'),
1135 pull=opts.get('pull'),
1134 stream=opts.get('uncompressed'),
1136 stream=opts.get('uncompressed'),
1135 rev=opts.get('rev'),
1137 rev=opts.get('rev'),
1136 update=opts.get('updaterev') or not opts.get('noupdate'),
1138 update=opts.get('updaterev') or not opts.get('noupdate'),
1137 branch=opts.get('branch'))
1139 branch=opts.get('branch'))
1138
1140
1139 return r is None
1141 return r is None
1140
1142
1141 @command('^commit|ci',
1143 @command('^commit|ci',
1142 [('A', 'addremove', None,
1144 [('A', 'addremove', None,
1143 _('mark new/missing files as added/removed before committing')),
1145 _('mark new/missing files as added/removed before committing')),
1144 ('', 'close-branch', None,
1146 ('', 'close-branch', None,
1145 _('mark a branch as closed, hiding it from the branch list')),
1147 _('mark a branch as closed, hiding it from the branch list')),
1146 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1148 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1147 _('[OPTION]... [FILE]...'))
1149 _('[OPTION]... [FILE]...'))
1148 def commit(ui, repo, *pats, **opts):
1150 def commit(ui, repo, *pats, **opts):
1149 """commit the specified files or all outstanding changes
1151 """commit the specified files or all outstanding changes
1150
1152
1151 Commit changes to the given files into the repository. Unlike a
1153 Commit changes to the given files into the repository. Unlike a
1152 centralized SCM, this operation is a local operation. See
1154 centralized SCM, this operation is a local operation. See
1153 :hg:`push` for a way to actively distribute your changes.
1155 :hg:`push` for a way to actively distribute your changes.
1154
1156
1155 If a list of files is omitted, all changes reported by :hg:`status`
1157 If a list of files is omitted, all changes reported by :hg:`status`
1156 will be committed.
1158 will be committed.
1157
1159
1158 If you are committing the result of a merge, do not provide any
1160 If you are committing the result of a merge, do not provide any
1159 filenames or -I/-X filters.
1161 filenames or -I/-X filters.
1160
1162
1161 If no commit message is specified, Mercurial starts your
1163 If no commit message is specified, Mercurial starts your
1162 configured editor where you can enter a message. In case your
1164 configured editor where you can enter a message. In case your
1163 commit fails, you will find a backup of your message in
1165 commit fails, you will find a backup of your message in
1164 ``.hg/last-message.txt``.
1166 ``.hg/last-message.txt``.
1165
1167
1166 See :hg:`help dates` for a list of formats valid for -d/--date.
1168 See :hg:`help dates` for a list of formats valid for -d/--date.
1167
1169
1168 Returns 0 on success, 1 if nothing changed.
1170 Returns 0 on success, 1 if nothing changed.
1169 """
1171 """
1170 if opts.get('subrepos'):
1172 if opts.get('subrepos'):
1171 # Let --subrepos on the command line overide config setting.
1173 # Let --subrepos on the command line overide config setting.
1172 ui.setconfig('ui', 'commitsubrepos', True)
1174 ui.setconfig('ui', 'commitsubrepos', True)
1173
1175
1174 extra = {}
1176 extra = {}
1175 if opts.get('close_branch'):
1177 if opts.get('close_branch'):
1176 if repo['.'].node() not in repo.branchheads():
1178 if repo['.'].node() not in repo.branchheads():
1177 # The topo heads set is included in the branch heads set of the
1179 # The topo heads set is included in the branch heads set of the
1178 # current branch, so it's sufficient to test branchheads
1180 # current branch, so it's sufficient to test branchheads
1179 raise util.Abort(_('can only close branch heads'))
1181 raise util.Abort(_('can only close branch heads'))
1180 extra['close'] = 1
1182 extra['close'] = 1
1181 e = cmdutil.commiteditor
1183 e = cmdutil.commiteditor
1182 if opts.get('force_editor'):
1184 if opts.get('force_editor'):
1183 e = cmdutil.commitforceeditor
1185 e = cmdutil.commitforceeditor
1184
1186
1185 def commitfunc(ui, repo, message, match, opts):
1187 def commitfunc(ui, repo, message, match, opts):
1186 return repo.commit(message, opts.get('user'), opts.get('date'), match,
1188 return repo.commit(message, opts.get('user'), opts.get('date'), match,
1187 editor=e, extra=extra)
1189 editor=e, extra=extra)
1188
1190
1189 branch = repo[None].branch()
1191 branch = repo[None].branch()
1190 bheads = repo.branchheads(branch)
1192 bheads = repo.branchheads(branch)
1191
1193
1192 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1194 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1193 if not node:
1195 if not node:
1194 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1196 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1195 if stat[3]:
1197 if stat[3]:
1196 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
1198 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
1197 % len(stat[3]))
1199 % len(stat[3]))
1198 else:
1200 else:
1199 ui.status(_("nothing changed\n"))
1201 ui.status(_("nothing changed\n"))
1200 return 1
1202 return 1
1201
1203
1202 ctx = repo[node]
1204 ctx = repo[node]
1203 parents = ctx.parents()
1205 parents = ctx.parents()
1204
1206
1205 if (bheads and node not in bheads and not
1207 if (bheads and node not in bheads and not
1206 [x for x in parents if x.node() in bheads and x.branch() == branch]):
1208 [x for x in parents if x.node() in bheads and x.branch() == branch]):
1207 ui.status(_('created new head\n'))
1209 ui.status(_('created new head\n'))
1208 # The message is not printed for initial roots. For the other
1210 # The message is not printed for initial roots. For the other
1209 # changesets, it is printed in the following situations:
1211 # changesets, it is printed in the following situations:
1210 #
1212 #
1211 # Par column: for the 2 parents with ...
1213 # Par column: for the 2 parents with ...
1212 # N: null or no parent
1214 # N: null or no parent
1213 # B: parent is on another named branch
1215 # B: parent is on another named branch
1214 # C: parent is a regular non head changeset
1216 # C: parent is a regular non head changeset
1215 # H: parent was a branch head of the current branch
1217 # H: parent was a branch head of the current branch
1216 # Msg column: whether we print "created new head" message
1218 # Msg column: whether we print "created new head" message
1217 # In the following, it is assumed that there already exists some
1219 # In the following, it is assumed that there already exists some
1218 # initial branch heads of the current branch, otherwise nothing is
1220 # initial branch heads of the current branch, otherwise nothing is
1219 # printed anyway.
1221 # printed anyway.
1220 #
1222 #
1221 # Par Msg Comment
1223 # Par Msg Comment
1222 # NN y additional topo root
1224 # NN y additional topo root
1223 #
1225 #
1224 # BN y additional branch root
1226 # BN y additional branch root
1225 # CN y additional topo head
1227 # CN y additional topo head
1226 # HN n usual case
1228 # HN n usual case
1227 #
1229 #
1228 # BB y weird additional branch root
1230 # BB y weird additional branch root
1229 # CB y branch merge
1231 # CB y branch merge
1230 # HB n merge with named branch
1232 # HB n merge with named branch
1231 #
1233 #
1232 # CC y additional head from merge
1234 # CC y additional head from merge
1233 # CH n merge with a head
1235 # CH n merge with a head
1234 #
1236 #
1235 # HH n head merge: head count decreases
1237 # HH n head merge: head count decreases
1236
1238
1237 if not opts.get('close_branch'):
1239 if not opts.get('close_branch'):
1238 for r in parents:
1240 for r in parents:
1239 if r.extra().get('close') and r.branch() == branch:
1241 if r.extra().get('close') and r.branch() == branch:
1240 ui.status(_('reopening closed branch head %d\n') % r)
1242 ui.status(_('reopening closed branch head %d\n') % r)
1241
1243
1242 if ui.debugflag:
1244 if ui.debugflag:
1243 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
1245 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
1244 elif ui.verbose:
1246 elif ui.verbose:
1245 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
1247 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
1246
1248
1247 @command('copy|cp',
1249 @command('copy|cp',
1248 [('A', 'after', None, _('record a copy that has already occurred')),
1250 [('A', 'after', None, _('record a copy that has already occurred')),
1249 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1251 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1250 ] + walkopts + dryrunopts,
1252 ] + walkopts + dryrunopts,
1251 _('[OPTION]... [SOURCE]... DEST'))
1253 _('[OPTION]... [SOURCE]... DEST'))
1252 def copy(ui, repo, *pats, **opts):
1254 def copy(ui, repo, *pats, **opts):
1253 """mark files as copied for the next commit
1255 """mark files as copied for the next commit
1254
1256
1255 Mark dest as having copies of source files. If dest is a
1257 Mark dest as having copies of source files. If dest is a
1256 directory, copies are put in that directory. If dest is a file,
1258 directory, copies are put in that directory. If dest is a file,
1257 the source must be a single file.
1259 the source must be a single file.
1258
1260
1259 By default, this command copies the contents of files as they
1261 By default, this command copies the contents of files as they
1260 exist in the working directory. If invoked with -A/--after, the
1262 exist in the working directory. If invoked with -A/--after, the
1261 operation is recorded, but no copying is performed.
1263 operation is recorded, but no copying is performed.
1262
1264
1263 This command takes effect with the next commit. To undo a copy
1265 This command takes effect with the next commit. To undo a copy
1264 before that, see :hg:`revert`.
1266 before that, see :hg:`revert`.
1265
1267
1266 Returns 0 on success, 1 if errors are encountered.
1268 Returns 0 on success, 1 if errors are encountered.
1267 """
1269 """
1268 wlock = repo.wlock(False)
1270 wlock = repo.wlock(False)
1269 try:
1271 try:
1270 return cmdutil.copy(ui, repo, pats, opts)
1272 return cmdutil.copy(ui, repo, pats, opts)
1271 finally:
1273 finally:
1272 wlock.release()
1274 wlock.release()
1273
1275
1274 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1276 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1275 def debugancestor(ui, repo, *args):
1277 def debugancestor(ui, repo, *args):
1276 """find the ancestor revision of two revisions in a given index"""
1278 """find the ancestor revision of two revisions in a given index"""
1277 if len(args) == 3:
1279 if len(args) == 3:
1278 index, rev1, rev2 = args
1280 index, rev1, rev2 = args
1279 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1281 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1280 lookup = r.lookup
1282 lookup = r.lookup
1281 elif len(args) == 2:
1283 elif len(args) == 2:
1282 if not repo:
1284 if not repo:
1283 raise util.Abort(_("there is no Mercurial repository here "
1285 raise util.Abort(_("there is no Mercurial repository here "
1284 "(.hg not found)"))
1286 "(.hg not found)"))
1285 rev1, rev2 = args
1287 rev1, rev2 = args
1286 r = repo.changelog
1288 r = repo.changelog
1287 lookup = repo.lookup
1289 lookup = repo.lookup
1288 else:
1290 else:
1289 raise util.Abort(_('either two or three arguments required'))
1291 raise util.Abort(_('either two or three arguments required'))
1290 a = r.ancestor(lookup(rev1), lookup(rev2))
1292 a = r.ancestor(lookup(rev1), lookup(rev2))
1291 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1293 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1292
1294
1293 @command('debugbuilddag',
1295 @command('debugbuilddag',
1294 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1296 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1295 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1297 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1296 ('n', 'new-file', None, _('add new file at each rev'))],
1298 ('n', 'new-file', None, _('add new file at each rev'))],
1297 _('[OPTION]... [TEXT]'))
1299 _('[OPTION]... [TEXT]'))
1298 def debugbuilddag(ui, repo, text=None,
1300 def debugbuilddag(ui, repo, text=None,
1299 mergeable_file=False,
1301 mergeable_file=False,
1300 overwritten_file=False,
1302 overwritten_file=False,
1301 new_file=False):
1303 new_file=False):
1302 """builds a repo with a given DAG from scratch in the current empty repo
1304 """builds a repo with a given DAG from scratch in the current empty repo
1303
1305
1304 The description of the DAG is read from stdin if not given on the
1306 The description of the DAG is read from stdin if not given on the
1305 command line.
1307 command line.
1306
1308
1307 Elements:
1309 Elements:
1308
1310
1309 - "+n" is a linear run of n nodes based on the current default parent
1311 - "+n" is a linear run of n nodes based on the current default parent
1310 - "." is a single node based on the current default parent
1312 - "." is a single node based on the current default parent
1311 - "$" resets the default parent to null (implied at the start);
1313 - "$" resets the default parent to null (implied at the start);
1312 otherwise the default parent is always the last node created
1314 otherwise the default parent is always the last node created
1313 - "<p" sets the default parent to the backref p
1315 - "<p" sets the default parent to the backref p
1314 - "*p" is a fork at parent p, which is a backref
1316 - "*p" is a fork at parent p, which is a backref
1315 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1317 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1316 - "/p2" is a merge of the preceding node and p2
1318 - "/p2" is a merge of the preceding node and p2
1317 - ":tag" defines a local tag for the preceding node
1319 - ":tag" defines a local tag for the preceding node
1318 - "@branch" sets the named branch for subsequent nodes
1320 - "@branch" sets the named branch for subsequent nodes
1319 - "#...\\n" is a comment up to the end of the line
1321 - "#...\\n" is a comment up to the end of the line
1320
1322
1321 Whitespace between the above elements is ignored.
1323 Whitespace between the above elements is ignored.
1322
1324
1323 A backref is either
1325 A backref is either
1324
1326
1325 - a number n, which references the node curr-n, where curr is the current
1327 - a number n, which references the node curr-n, where curr is the current
1326 node, or
1328 node, or
1327 - the name of a local tag you placed earlier using ":tag", or
1329 - the name of a local tag you placed earlier using ":tag", or
1328 - empty to denote the default parent.
1330 - empty to denote the default parent.
1329
1331
1330 All string valued-elements are either strictly alphanumeric, or must
1332 All string valued-elements are either strictly alphanumeric, or must
1331 be enclosed in double quotes ("..."), with "\\" as escape character.
1333 be enclosed in double quotes ("..."), with "\\" as escape character.
1332 """
1334 """
1333
1335
1334 if text is None:
1336 if text is None:
1335 ui.status(_("reading DAG from stdin\n"))
1337 ui.status(_("reading DAG from stdin\n"))
1336 text = ui.fin.read()
1338 text = ui.fin.read()
1337
1339
1338 cl = repo.changelog
1340 cl = repo.changelog
1339 if len(cl) > 0:
1341 if len(cl) > 0:
1340 raise util.Abort(_('repository is not empty'))
1342 raise util.Abort(_('repository is not empty'))
1341
1343
1342 # determine number of revs in DAG
1344 # determine number of revs in DAG
1343 total = 0
1345 total = 0
1344 for type, data in dagparser.parsedag(text):
1346 for type, data in dagparser.parsedag(text):
1345 if type == 'n':
1347 if type == 'n':
1346 total += 1
1348 total += 1
1347
1349
1348 if mergeable_file:
1350 if mergeable_file:
1349 linesperrev = 2
1351 linesperrev = 2
1350 # make a file with k lines per rev
1352 # make a file with k lines per rev
1351 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1353 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1352 initialmergedlines.append("")
1354 initialmergedlines.append("")
1353
1355
1354 tags = []
1356 tags = []
1355
1357
1356 tr = repo.transaction("builddag")
1358 tr = repo.transaction("builddag")
1357 try:
1359 try:
1358
1360
1359 at = -1
1361 at = -1
1360 atbranch = 'default'
1362 atbranch = 'default'
1361 nodeids = []
1363 nodeids = []
1362 ui.progress(_('building'), 0, unit=_('revisions'), total=total)
1364 ui.progress(_('building'), 0, unit=_('revisions'), total=total)
1363 for type, data in dagparser.parsedag(text):
1365 for type, data in dagparser.parsedag(text):
1364 if type == 'n':
1366 if type == 'n':
1365 ui.note('node %s\n' % str(data))
1367 ui.note('node %s\n' % str(data))
1366 id, ps = data
1368 id, ps = data
1367
1369
1368 files = []
1370 files = []
1369 fctxs = {}
1371 fctxs = {}
1370
1372
1371 p2 = None
1373 p2 = None
1372 if mergeable_file:
1374 if mergeable_file:
1373 fn = "mf"
1375 fn = "mf"
1374 p1 = repo[ps[0]]
1376 p1 = repo[ps[0]]
1375 if len(ps) > 1:
1377 if len(ps) > 1:
1376 p2 = repo[ps[1]]
1378 p2 = repo[ps[1]]
1377 pa = p1.ancestor(p2)
1379 pa = p1.ancestor(p2)
1378 base, local, other = [x[fn].data() for x in pa, p1, p2]
1380 base, local, other = [x[fn].data() for x in pa, p1, p2]
1379 m3 = simplemerge.Merge3Text(base, local, other)
1381 m3 = simplemerge.Merge3Text(base, local, other)
1380 ml = [l.strip() for l in m3.merge_lines()]
1382 ml = [l.strip() for l in m3.merge_lines()]
1381 ml.append("")
1383 ml.append("")
1382 elif at > 0:
1384 elif at > 0:
1383 ml = p1[fn].data().split("\n")
1385 ml = p1[fn].data().split("\n")
1384 else:
1386 else:
1385 ml = initialmergedlines
1387 ml = initialmergedlines
1386 ml[id * linesperrev] += " r%i" % id
1388 ml[id * linesperrev] += " r%i" % id
1387 mergedtext = "\n".join(ml)
1389 mergedtext = "\n".join(ml)
1388 files.append(fn)
1390 files.append(fn)
1389 fctxs[fn] = context.memfilectx(fn, mergedtext)
1391 fctxs[fn] = context.memfilectx(fn, mergedtext)
1390
1392
1391 if overwritten_file:
1393 if overwritten_file:
1392 fn = "of"
1394 fn = "of"
1393 files.append(fn)
1395 files.append(fn)
1394 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1396 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1395
1397
1396 if new_file:
1398 if new_file:
1397 fn = "nf%i" % id
1399 fn = "nf%i" % id
1398 files.append(fn)
1400 files.append(fn)
1399 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1401 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1400 if len(ps) > 1:
1402 if len(ps) > 1:
1401 if not p2:
1403 if not p2:
1402 p2 = repo[ps[1]]
1404 p2 = repo[ps[1]]
1403 for fn in p2:
1405 for fn in p2:
1404 if fn.startswith("nf"):
1406 if fn.startswith("nf"):
1405 files.append(fn)
1407 files.append(fn)
1406 fctxs[fn] = p2[fn]
1408 fctxs[fn] = p2[fn]
1407
1409
1408 def fctxfn(repo, cx, path):
1410 def fctxfn(repo, cx, path):
1409 return fctxs.get(path)
1411 return fctxs.get(path)
1410
1412
1411 if len(ps) == 0 or ps[0] < 0:
1413 if len(ps) == 0 or ps[0] < 0:
1412 pars = [None, None]
1414 pars = [None, None]
1413 elif len(ps) == 1:
1415 elif len(ps) == 1:
1414 pars = [nodeids[ps[0]], None]
1416 pars = [nodeids[ps[0]], None]
1415 else:
1417 else:
1416 pars = [nodeids[p] for p in ps]
1418 pars = [nodeids[p] for p in ps]
1417 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1419 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1418 date=(id, 0),
1420 date=(id, 0),
1419 user="debugbuilddag",
1421 user="debugbuilddag",
1420 extra={'branch': atbranch})
1422 extra={'branch': atbranch})
1421 nodeid = repo.commitctx(cx)
1423 nodeid = repo.commitctx(cx)
1422 nodeids.append(nodeid)
1424 nodeids.append(nodeid)
1423 at = id
1425 at = id
1424 elif type == 'l':
1426 elif type == 'l':
1425 id, name = data
1427 id, name = data
1426 ui.note('tag %s\n' % name)
1428 ui.note('tag %s\n' % name)
1427 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1429 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1428 elif type == 'a':
1430 elif type == 'a':
1429 ui.note('branch %s\n' % data)
1431 ui.note('branch %s\n' % data)
1430 atbranch = data
1432 atbranch = data
1431 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1433 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1432 tr.close()
1434 tr.close()
1433 finally:
1435 finally:
1434 ui.progress(_('building'), None)
1436 ui.progress(_('building'), None)
1435 tr.release()
1437 tr.release()
1436
1438
1437 if tags:
1439 if tags:
1438 repo.opener.write("localtags", "".join(tags))
1440 repo.opener.write("localtags", "".join(tags))
1439
1441
1440 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1442 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1441 def debugbundle(ui, bundlepath, all=None, **opts):
1443 def debugbundle(ui, bundlepath, all=None, **opts):
1442 """lists the contents of a bundle"""
1444 """lists the contents of a bundle"""
1443 f = url.open(ui, bundlepath)
1445 f = url.open(ui, bundlepath)
1444 try:
1446 try:
1445 gen = changegroup.readbundle(f, bundlepath)
1447 gen = changegroup.readbundle(f, bundlepath)
1446 if all:
1448 if all:
1447 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1449 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1448
1450
1449 def showchunks(named):
1451 def showchunks(named):
1450 ui.write("\n%s\n" % named)
1452 ui.write("\n%s\n" % named)
1451 chain = None
1453 chain = None
1452 while True:
1454 while True:
1453 chunkdata = gen.deltachunk(chain)
1455 chunkdata = gen.deltachunk(chain)
1454 if not chunkdata:
1456 if not chunkdata:
1455 break
1457 break
1456 node = chunkdata['node']
1458 node = chunkdata['node']
1457 p1 = chunkdata['p1']
1459 p1 = chunkdata['p1']
1458 p2 = chunkdata['p2']
1460 p2 = chunkdata['p2']
1459 cs = chunkdata['cs']
1461 cs = chunkdata['cs']
1460 deltabase = chunkdata['deltabase']
1462 deltabase = chunkdata['deltabase']
1461 delta = chunkdata['delta']
1463 delta = chunkdata['delta']
1462 ui.write("%s %s %s %s %s %s\n" %
1464 ui.write("%s %s %s %s %s %s\n" %
1463 (hex(node), hex(p1), hex(p2),
1465 (hex(node), hex(p1), hex(p2),
1464 hex(cs), hex(deltabase), len(delta)))
1466 hex(cs), hex(deltabase), len(delta)))
1465 chain = node
1467 chain = node
1466
1468
1467 chunkdata = gen.changelogheader()
1469 chunkdata = gen.changelogheader()
1468 showchunks("changelog")
1470 showchunks("changelog")
1469 chunkdata = gen.manifestheader()
1471 chunkdata = gen.manifestheader()
1470 showchunks("manifest")
1472 showchunks("manifest")
1471 while True:
1473 while True:
1472 chunkdata = gen.filelogheader()
1474 chunkdata = gen.filelogheader()
1473 if not chunkdata:
1475 if not chunkdata:
1474 break
1476 break
1475 fname = chunkdata['filename']
1477 fname = chunkdata['filename']
1476 showchunks(fname)
1478 showchunks(fname)
1477 else:
1479 else:
1478 chunkdata = gen.changelogheader()
1480 chunkdata = gen.changelogheader()
1479 chain = None
1481 chain = None
1480 while True:
1482 while True:
1481 chunkdata = gen.deltachunk(chain)
1483 chunkdata = gen.deltachunk(chain)
1482 if not chunkdata:
1484 if not chunkdata:
1483 break
1485 break
1484 node = chunkdata['node']
1486 node = chunkdata['node']
1485 ui.write("%s\n" % hex(node))
1487 ui.write("%s\n" % hex(node))
1486 chain = node
1488 chain = node
1487 finally:
1489 finally:
1488 f.close()
1490 f.close()
1489
1491
1490 @command('debugcheckstate', [], '')
1492 @command('debugcheckstate', [], '')
1491 def debugcheckstate(ui, repo):
1493 def debugcheckstate(ui, repo):
1492 """validate the correctness of the current dirstate"""
1494 """validate the correctness of the current dirstate"""
1493 parent1, parent2 = repo.dirstate.parents()
1495 parent1, parent2 = repo.dirstate.parents()
1494 m1 = repo[parent1].manifest()
1496 m1 = repo[parent1].manifest()
1495 m2 = repo[parent2].manifest()
1497 m2 = repo[parent2].manifest()
1496 errors = 0
1498 errors = 0
1497 for f in repo.dirstate:
1499 for f in repo.dirstate:
1498 state = repo.dirstate[f]
1500 state = repo.dirstate[f]
1499 if state in "nr" and f not in m1:
1501 if state in "nr" and f not in m1:
1500 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1502 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1501 errors += 1
1503 errors += 1
1502 if state in "a" and f in m1:
1504 if state in "a" and f in m1:
1503 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1505 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1504 errors += 1
1506 errors += 1
1505 if state in "m" and f not in m1 and f not in m2:
1507 if state in "m" and f not in m1 and f not in m2:
1506 ui.warn(_("%s in state %s, but not in either manifest\n") %
1508 ui.warn(_("%s in state %s, but not in either manifest\n") %
1507 (f, state))
1509 (f, state))
1508 errors += 1
1510 errors += 1
1509 for f in m1:
1511 for f in m1:
1510 state = repo.dirstate[f]
1512 state = repo.dirstate[f]
1511 if state not in "nrm":
1513 if state not in "nrm":
1512 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1514 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1513 errors += 1
1515 errors += 1
1514 if errors:
1516 if errors:
1515 error = _(".hg/dirstate inconsistent with current parent's manifest")
1517 error = _(".hg/dirstate inconsistent with current parent's manifest")
1516 raise util.Abort(error)
1518 raise util.Abort(error)
1517
1519
1518 @command('debugcommands', [], _('[COMMAND]'))
1520 @command('debugcommands', [], _('[COMMAND]'))
1519 def debugcommands(ui, cmd='', *args):
1521 def debugcommands(ui, cmd='', *args):
1520 """list all available commands and options"""
1522 """list all available commands and options"""
1521 for cmd, vals in sorted(table.iteritems()):
1523 for cmd, vals in sorted(table.iteritems()):
1522 cmd = cmd.split('|')[0].strip('^')
1524 cmd = cmd.split('|')[0].strip('^')
1523 opts = ', '.join([i[1] for i in vals[1]])
1525 opts = ', '.join([i[1] for i in vals[1]])
1524 ui.write('%s: %s\n' % (cmd, opts))
1526 ui.write('%s: %s\n' % (cmd, opts))
1525
1527
1526 @command('debugcomplete',
1528 @command('debugcomplete',
1527 [('o', 'options', None, _('show the command options'))],
1529 [('o', 'options', None, _('show the command options'))],
1528 _('[-o] CMD'))
1530 _('[-o] CMD'))
1529 def debugcomplete(ui, cmd='', **opts):
1531 def debugcomplete(ui, cmd='', **opts):
1530 """returns the completion list associated with the given command"""
1532 """returns the completion list associated with the given command"""
1531
1533
1532 if opts.get('options'):
1534 if opts.get('options'):
1533 options = []
1535 options = []
1534 otables = [globalopts]
1536 otables = [globalopts]
1535 if cmd:
1537 if cmd:
1536 aliases, entry = cmdutil.findcmd(cmd, table, False)
1538 aliases, entry = cmdutil.findcmd(cmd, table, False)
1537 otables.append(entry[1])
1539 otables.append(entry[1])
1538 for t in otables:
1540 for t in otables:
1539 for o in t:
1541 for o in t:
1540 if "(DEPRECATED)" in o[3]:
1542 if "(DEPRECATED)" in o[3]:
1541 continue
1543 continue
1542 if o[0]:
1544 if o[0]:
1543 options.append('-%s' % o[0])
1545 options.append('-%s' % o[0])
1544 options.append('--%s' % o[1])
1546 options.append('--%s' % o[1])
1545 ui.write("%s\n" % "\n".join(options))
1547 ui.write("%s\n" % "\n".join(options))
1546 return
1548 return
1547
1549
1548 cmdlist = cmdutil.findpossible(cmd, table)
1550 cmdlist = cmdutil.findpossible(cmd, table)
1549 if ui.verbose:
1551 if ui.verbose:
1550 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1552 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1551 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1553 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1552
1554
1553 @command('debugdag',
1555 @command('debugdag',
1554 [('t', 'tags', None, _('use tags as labels')),
1556 [('t', 'tags', None, _('use tags as labels')),
1555 ('b', 'branches', None, _('annotate with branch names')),
1557 ('b', 'branches', None, _('annotate with branch names')),
1556 ('', 'dots', None, _('use dots for runs')),
1558 ('', 'dots', None, _('use dots for runs')),
1557 ('s', 'spaces', None, _('separate elements by spaces'))],
1559 ('s', 'spaces', None, _('separate elements by spaces'))],
1558 _('[OPTION]... [FILE [REV]...]'))
1560 _('[OPTION]... [FILE [REV]...]'))
1559 def debugdag(ui, repo, file_=None, *revs, **opts):
1561 def debugdag(ui, repo, file_=None, *revs, **opts):
1560 """format the changelog or an index DAG as a concise textual description
1562 """format the changelog or an index DAG as a concise textual description
1561
1563
1562 If you pass a revlog index, the revlog's DAG is emitted. If you list
1564 If you pass a revlog index, the revlog's DAG is emitted. If you list
1563 revision numbers, they get labelled in the output as rN.
1565 revision numbers, they get labelled in the output as rN.
1564
1566
1565 Otherwise, the changelog DAG of the current repo is emitted.
1567 Otherwise, the changelog DAG of the current repo is emitted.
1566 """
1568 """
1567 spaces = opts.get('spaces')
1569 spaces = opts.get('spaces')
1568 dots = opts.get('dots')
1570 dots = opts.get('dots')
1569 if file_:
1571 if file_:
1570 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1572 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1571 revs = set((int(r) for r in revs))
1573 revs = set((int(r) for r in revs))
1572 def events():
1574 def events():
1573 for r in rlog:
1575 for r in rlog:
1574 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1576 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1575 if r in revs:
1577 if r in revs:
1576 yield 'l', (r, "r%i" % r)
1578 yield 'l', (r, "r%i" % r)
1577 elif repo:
1579 elif repo:
1578 cl = repo.changelog
1580 cl = repo.changelog
1579 tags = opts.get('tags')
1581 tags = opts.get('tags')
1580 branches = opts.get('branches')
1582 branches = opts.get('branches')
1581 if tags:
1583 if tags:
1582 labels = {}
1584 labels = {}
1583 for l, n in repo.tags().items():
1585 for l, n in repo.tags().items():
1584 labels.setdefault(cl.rev(n), []).append(l)
1586 labels.setdefault(cl.rev(n), []).append(l)
1585 def events():
1587 def events():
1586 b = "default"
1588 b = "default"
1587 for r in cl:
1589 for r in cl:
1588 if branches:
1590 if branches:
1589 newb = cl.read(cl.node(r))[5]['branch']
1591 newb = cl.read(cl.node(r))[5]['branch']
1590 if newb != b:
1592 if newb != b:
1591 yield 'a', newb
1593 yield 'a', newb
1592 b = newb
1594 b = newb
1593 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1595 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1594 if tags:
1596 if tags:
1595 ls = labels.get(r)
1597 ls = labels.get(r)
1596 if ls:
1598 if ls:
1597 for l in ls:
1599 for l in ls:
1598 yield 'l', (r, l)
1600 yield 'l', (r, l)
1599 else:
1601 else:
1600 raise util.Abort(_('need repo for changelog dag'))
1602 raise util.Abort(_('need repo for changelog dag'))
1601
1603
1602 for line in dagparser.dagtextlines(events(),
1604 for line in dagparser.dagtextlines(events(),
1603 addspaces=spaces,
1605 addspaces=spaces,
1604 wraplabels=True,
1606 wraplabels=True,
1605 wrapannotations=True,
1607 wrapannotations=True,
1606 wrapnonlinear=dots,
1608 wrapnonlinear=dots,
1607 usedots=dots,
1609 usedots=dots,
1608 maxlinewidth=70):
1610 maxlinewidth=70):
1609 ui.write(line)
1611 ui.write(line)
1610 ui.write("\n")
1612 ui.write("\n")
1611
1613
1612 @command('debugdata',
1614 @command('debugdata',
1613 [('c', 'changelog', False, _('open changelog')),
1615 [('c', 'changelog', False, _('open changelog')),
1614 ('m', 'manifest', False, _('open manifest'))],
1616 ('m', 'manifest', False, _('open manifest'))],
1615 _('-c|-m|FILE REV'))
1617 _('-c|-m|FILE REV'))
1616 def debugdata(ui, repo, file_, rev = None, **opts):
1618 def debugdata(ui, repo, file_, rev = None, **opts):
1617 """dump the contents of a data file revision"""
1619 """dump the contents of a data file revision"""
1618 if opts.get('changelog') or opts.get('manifest'):
1620 if opts.get('changelog') or opts.get('manifest'):
1619 file_, rev = None, file_
1621 file_, rev = None, file_
1620 elif rev is None:
1622 elif rev is None:
1621 raise error.CommandError('debugdata', _('invalid arguments'))
1623 raise error.CommandError('debugdata', _('invalid arguments'))
1622 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1624 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1623 try:
1625 try:
1624 ui.write(r.revision(r.lookup(rev)))
1626 ui.write(r.revision(r.lookup(rev)))
1625 except KeyError:
1627 except KeyError:
1626 raise util.Abort(_('invalid revision identifier %s') % rev)
1628 raise util.Abort(_('invalid revision identifier %s') % rev)
1627
1629
1628 @command('debugdate',
1630 @command('debugdate',
1629 [('e', 'extended', None, _('try extended date formats'))],
1631 [('e', 'extended', None, _('try extended date formats'))],
1630 _('[-e] DATE [RANGE]'))
1632 _('[-e] DATE [RANGE]'))
1631 def debugdate(ui, date, range=None, **opts):
1633 def debugdate(ui, date, range=None, **opts):
1632 """parse and display a date"""
1634 """parse and display a date"""
1633 if opts["extended"]:
1635 if opts["extended"]:
1634 d = util.parsedate(date, util.extendeddateformats)
1636 d = util.parsedate(date, util.extendeddateformats)
1635 else:
1637 else:
1636 d = util.parsedate(date)
1638 d = util.parsedate(date)
1637 ui.write("internal: %s %s\n" % d)
1639 ui.write("internal: %s %s\n" % d)
1638 ui.write("standard: %s\n" % util.datestr(d))
1640 ui.write("standard: %s\n" % util.datestr(d))
1639 if range:
1641 if range:
1640 m = util.matchdate(range)
1642 m = util.matchdate(range)
1641 ui.write("match: %s\n" % m(d[0]))
1643 ui.write("match: %s\n" % m(d[0]))
1642
1644
1643 @command('debugdiscovery',
1645 @command('debugdiscovery',
1644 [('', 'old', None, _('use old-style discovery')),
1646 [('', 'old', None, _('use old-style discovery')),
1645 ('', 'nonheads', None,
1647 ('', 'nonheads', None,
1646 _('use old-style discovery with non-heads included')),
1648 _('use old-style discovery with non-heads included')),
1647 ] + remoteopts,
1649 ] + remoteopts,
1648 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1650 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1649 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1651 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1650 """runs the changeset discovery protocol in isolation"""
1652 """runs the changeset discovery protocol in isolation"""
1651 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1653 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1652 remote = hg.peer(repo, opts, remoteurl)
1654 remote = hg.peer(repo, opts, remoteurl)
1653 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1655 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1654
1656
1655 # make sure tests are repeatable
1657 # make sure tests are repeatable
1656 random.seed(12323)
1658 random.seed(12323)
1657
1659
1658 def doit(localheads, remoteheads):
1660 def doit(localheads, remoteheads):
1659 if opts.get('old'):
1661 if opts.get('old'):
1660 if localheads:
1662 if localheads:
1661 raise util.Abort('cannot use localheads with old style discovery')
1663 raise util.Abort('cannot use localheads with old style discovery')
1662 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1664 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1663 force=True)
1665 force=True)
1664 common = set(common)
1666 common = set(common)
1665 if not opts.get('nonheads'):
1667 if not opts.get('nonheads'):
1666 ui.write("unpruned common: %s\n" % " ".join([short(n)
1668 ui.write("unpruned common: %s\n" % " ".join([short(n)
1667 for n in common]))
1669 for n in common]))
1668 dag = dagutil.revlogdag(repo.changelog)
1670 dag = dagutil.revlogdag(repo.changelog)
1669 all = dag.ancestorset(dag.internalizeall(common))
1671 all = dag.ancestorset(dag.internalizeall(common))
1670 common = dag.externalizeall(dag.headsetofconnecteds(all))
1672 common = dag.externalizeall(dag.headsetofconnecteds(all))
1671 else:
1673 else:
1672 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1674 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1673 common = set(common)
1675 common = set(common)
1674 rheads = set(hds)
1676 rheads = set(hds)
1675 lheads = set(repo.heads())
1677 lheads = set(repo.heads())
1676 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1678 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1677 if lheads <= common:
1679 if lheads <= common:
1678 ui.write("local is subset\n")
1680 ui.write("local is subset\n")
1679 elif rheads <= common:
1681 elif rheads <= common:
1680 ui.write("remote is subset\n")
1682 ui.write("remote is subset\n")
1681
1683
1682 serverlogs = opts.get('serverlog')
1684 serverlogs = opts.get('serverlog')
1683 if serverlogs:
1685 if serverlogs:
1684 for filename in serverlogs:
1686 for filename in serverlogs:
1685 logfile = open(filename, 'r')
1687 logfile = open(filename, 'r')
1686 try:
1688 try:
1687 line = logfile.readline()
1689 line = logfile.readline()
1688 while line:
1690 while line:
1689 parts = line.strip().split(';')
1691 parts = line.strip().split(';')
1690 op = parts[1]
1692 op = parts[1]
1691 if op == 'cg':
1693 if op == 'cg':
1692 pass
1694 pass
1693 elif op == 'cgss':
1695 elif op == 'cgss':
1694 doit(parts[2].split(' '), parts[3].split(' '))
1696 doit(parts[2].split(' '), parts[3].split(' '))
1695 elif op == 'unb':
1697 elif op == 'unb':
1696 doit(parts[3].split(' '), parts[2].split(' '))
1698 doit(parts[3].split(' '), parts[2].split(' '))
1697 line = logfile.readline()
1699 line = logfile.readline()
1698 finally:
1700 finally:
1699 logfile.close()
1701 logfile.close()
1700
1702
1701 else:
1703 else:
1702 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1704 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1703 opts.get('remote_head'))
1705 opts.get('remote_head'))
1704 localrevs = opts.get('local_head')
1706 localrevs = opts.get('local_head')
1705 doit(localrevs, remoterevs)
1707 doit(localrevs, remoterevs)
1706
1708
1707 @command('debugfileset', [], ('REVSPEC'))
1709 @command('debugfileset', [], ('REVSPEC'))
1708 def debugfileset(ui, repo, expr):
1710 def debugfileset(ui, repo, expr):
1709 '''parse and apply a fileset specification'''
1711 '''parse and apply a fileset specification'''
1710 if ui.verbose:
1712 if ui.verbose:
1711 tree = fileset.parse(expr)[0]
1713 tree = fileset.parse(expr)[0]
1712 ui.note(tree, "\n")
1714 ui.note(tree, "\n")
1713
1715
1714 for f in fileset.getfileset(repo[None], expr):
1716 for f in fileset.getfileset(repo[None], expr):
1715 ui.write("%s\n" % f)
1717 ui.write("%s\n" % f)
1716
1718
1717 @command('debugfsinfo', [], _('[PATH]'))
1719 @command('debugfsinfo', [], _('[PATH]'))
1718 def debugfsinfo(ui, path = "."):
1720 def debugfsinfo(ui, path = "."):
1719 """show information detected about current filesystem"""
1721 """show information detected about current filesystem"""
1720 util.writefile('.debugfsinfo', '')
1722 util.writefile('.debugfsinfo', '')
1721 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1723 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1722 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1724 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1723 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1725 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1724 and 'yes' or 'no'))
1726 and 'yes' or 'no'))
1725 os.unlink('.debugfsinfo')
1727 os.unlink('.debugfsinfo')
1726
1728
1727 @command('debuggetbundle',
1729 @command('debuggetbundle',
1728 [('H', 'head', [], _('id of head node'), _('ID')),
1730 [('H', 'head', [], _('id of head node'), _('ID')),
1729 ('C', 'common', [], _('id of common node'), _('ID')),
1731 ('C', 'common', [], _('id of common node'), _('ID')),
1730 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
1732 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
1731 _('REPO FILE [-H|-C ID]...'))
1733 _('REPO FILE [-H|-C ID]...'))
1732 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1734 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1733 """retrieves a bundle from a repo
1735 """retrieves a bundle from a repo
1734
1736
1735 Every ID must be a full-length hex node id string. Saves the bundle to the
1737 Every ID must be a full-length hex node id string. Saves the bundle to the
1736 given file.
1738 given file.
1737 """
1739 """
1738 repo = hg.peer(ui, opts, repopath)
1740 repo = hg.peer(ui, opts, repopath)
1739 if not repo.capable('getbundle'):
1741 if not repo.capable('getbundle'):
1740 raise util.Abort("getbundle() not supported by target repository")
1742 raise util.Abort("getbundle() not supported by target repository")
1741 args = {}
1743 args = {}
1742 if common:
1744 if common:
1743 args['common'] = [bin(s) for s in common]
1745 args['common'] = [bin(s) for s in common]
1744 if head:
1746 if head:
1745 args['heads'] = [bin(s) for s in head]
1747 args['heads'] = [bin(s) for s in head]
1746 bundle = repo.getbundle('debug', **args)
1748 bundle = repo.getbundle('debug', **args)
1747
1749
1748 bundletype = opts.get('type', 'bzip2').lower()
1750 bundletype = opts.get('type', 'bzip2').lower()
1749 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1751 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1750 bundletype = btypes.get(bundletype)
1752 bundletype = btypes.get(bundletype)
1751 if bundletype not in changegroup.bundletypes:
1753 if bundletype not in changegroup.bundletypes:
1752 raise util.Abort(_('unknown bundle type specified with --type'))
1754 raise util.Abort(_('unknown bundle type specified with --type'))
1753 changegroup.writebundle(bundle, bundlepath, bundletype)
1755 changegroup.writebundle(bundle, bundlepath, bundletype)
1754
1756
1755 @command('debugignore', [], '')
1757 @command('debugignore', [], '')
1756 def debugignore(ui, repo, *values, **opts):
1758 def debugignore(ui, repo, *values, **opts):
1757 """display the combined ignore pattern"""
1759 """display the combined ignore pattern"""
1758 ignore = repo.dirstate._ignore
1760 ignore = repo.dirstate._ignore
1759 includepat = getattr(ignore, 'includepat', None)
1761 includepat = getattr(ignore, 'includepat', None)
1760 if includepat is not None:
1762 if includepat is not None:
1761 ui.write("%s\n" % includepat)
1763 ui.write("%s\n" % includepat)
1762 else:
1764 else:
1763 raise util.Abort(_("no ignore patterns found"))
1765 raise util.Abort(_("no ignore patterns found"))
1764
1766
1765 @command('debugindex',
1767 @command('debugindex',
1766 [('c', 'changelog', False, _('open changelog')),
1768 [('c', 'changelog', False, _('open changelog')),
1767 ('m', 'manifest', False, _('open manifest')),
1769 ('m', 'manifest', False, _('open manifest')),
1768 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1770 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1769 _('[-f FORMAT] -c|-m|FILE'))
1771 _('[-f FORMAT] -c|-m|FILE'))
1770 def debugindex(ui, repo, file_ = None, **opts):
1772 def debugindex(ui, repo, file_ = None, **opts):
1771 """dump the contents of an index file"""
1773 """dump the contents of an index file"""
1772 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1774 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1773 format = opts.get('format', 0)
1775 format = opts.get('format', 0)
1774 if format not in (0, 1):
1776 if format not in (0, 1):
1775 raise util.Abort(_("unknown format %d") % format)
1777 raise util.Abort(_("unknown format %d") % format)
1776
1778
1777 generaldelta = r.version & revlog.REVLOGGENERALDELTA
1779 generaldelta = r.version & revlog.REVLOGGENERALDELTA
1778 if generaldelta:
1780 if generaldelta:
1779 basehdr = ' delta'
1781 basehdr = ' delta'
1780 else:
1782 else:
1781 basehdr = ' base'
1783 basehdr = ' base'
1782
1784
1783 if format == 0:
1785 if format == 0:
1784 ui.write(" rev offset length " + basehdr + " linkrev"
1786 ui.write(" rev offset length " + basehdr + " linkrev"
1785 " nodeid p1 p2\n")
1787 " nodeid p1 p2\n")
1786 elif format == 1:
1788 elif format == 1:
1787 ui.write(" rev flag offset length"
1789 ui.write(" rev flag offset length"
1788 " size " + basehdr + " link p1 p2 nodeid\n")
1790 " size " + basehdr + " link p1 p2 nodeid\n")
1789
1791
1790 for i in r:
1792 for i in r:
1791 node = r.node(i)
1793 node = r.node(i)
1792 if generaldelta:
1794 if generaldelta:
1793 base = r.deltaparent(i)
1795 base = r.deltaparent(i)
1794 else:
1796 else:
1795 base = r.chainbase(i)
1797 base = r.chainbase(i)
1796 if format == 0:
1798 if format == 0:
1797 try:
1799 try:
1798 pp = r.parents(node)
1800 pp = r.parents(node)
1799 except:
1801 except:
1800 pp = [nullid, nullid]
1802 pp = [nullid, nullid]
1801 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1803 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1802 i, r.start(i), r.length(i), base, r.linkrev(i),
1804 i, r.start(i), r.length(i), base, r.linkrev(i),
1803 short(node), short(pp[0]), short(pp[1])))
1805 short(node), short(pp[0]), short(pp[1])))
1804 elif format == 1:
1806 elif format == 1:
1805 pr = r.parentrevs(i)
1807 pr = r.parentrevs(i)
1806 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1808 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1807 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1809 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1808 base, r.linkrev(i), pr[0], pr[1], short(node)))
1810 base, r.linkrev(i), pr[0], pr[1], short(node)))
1809
1811
1810 @command('debugindexdot', [], _('FILE'))
1812 @command('debugindexdot', [], _('FILE'))
1811 def debugindexdot(ui, repo, file_):
1813 def debugindexdot(ui, repo, file_):
1812 """dump an index DAG as a graphviz dot file"""
1814 """dump an index DAG as a graphviz dot file"""
1813 r = None
1815 r = None
1814 if repo:
1816 if repo:
1815 filelog = repo.file(file_)
1817 filelog = repo.file(file_)
1816 if len(filelog):
1818 if len(filelog):
1817 r = filelog
1819 r = filelog
1818 if not r:
1820 if not r:
1819 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1821 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1820 ui.write("digraph G {\n")
1822 ui.write("digraph G {\n")
1821 for i in r:
1823 for i in r:
1822 node = r.node(i)
1824 node = r.node(i)
1823 pp = r.parents(node)
1825 pp = r.parents(node)
1824 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1826 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1825 if pp[1] != nullid:
1827 if pp[1] != nullid:
1826 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1828 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1827 ui.write("}\n")
1829 ui.write("}\n")
1828
1830
1829 @command('debuginstall', [], '')
1831 @command('debuginstall', [], '')
1830 def debuginstall(ui):
1832 def debuginstall(ui):
1831 '''test Mercurial installation
1833 '''test Mercurial installation
1832
1834
1833 Returns 0 on success.
1835 Returns 0 on success.
1834 '''
1836 '''
1835
1837
1836 def writetemp(contents):
1838 def writetemp(contents):
1837 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1839 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1838 f = os.fdopen(fd, "wb")
1840 f = os.fdopen(fd, "wb")
1839 f.write(contents)
1841 f.write(contents)
1840 f.close()
1842 f.close()
1841 return name
1843 return name
1842
1844
1843 problems = 0
1845 problems = 0
1844
1846
1845 # encoding
1847 # encoding
1846 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1848 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1847 try:
1849 try:
1848 encoding.fromlocal("test")
1850 encoding.fromlocal("test")
1849 except util.Abort, inst:
1851 except util.Abort, inst:
1850 ui.write(" %s\n" % inst)
1852 ui.write(" %s\n" % inst)
1851 ui.write(_(" (check that your locale is properly set)\n"))
1853 ui.write(_(" (check that your locale is properly set)\n"))
1852 problems += 1
1854 problems += 1
1853
1855
1854 # compiled modules
1856 # compiled modules
1855 ui.status(_("Checking installed modules (%s)...\n")
1857 ui.status(_("Checking installed modules (%s)...\n")
1856 % os.path.dirname(__file__))
1858 % os.path.dirname(__file__))
1857 try:
1859 try:
1858 import bdiff, mpatch, base85, osutil
1860 import bdiff, mpatch, base85, osutil
1859 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1861 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1860 except Exception, inst:
1862 except Exception, inst:
1861 ui.write(" %s\n" % inst)
1863 ui.write(" %s\n" % inst)
1862 ui.write(_(" One or more extensions could not be found"))
1864 ui.write(_(" One or more extensions could not be found"))
1863 ui.write(_(" (check that you compiled the extensions)\n"))
1865 ui.write(_(" (check that you compiled the extensions)\n"))
1864 problems += 1
1866 problems += 1
1865
1867
1866 # templates
1868 # templates
1867 import templater
1869 import templater
1868 p = templater.templatepath()
1870 p = templater.templatepath()
1869 ui.status(_("Checking templates (%s)...\n") % ' '.join(p))
1871 ui.status(_("Checking templates (%s)...\n") % ' '.join(p))
1870 try:
1872 try:
1871 templater.templater(templater.templatepath("map-cmdline.default"))
1873 templater.templater(templater.templatepath("map-cmdline.default"))
1872 except Exception, inst:
1874 except Exception, inst:
1873 ui.write(" %s\n" % inst)
1875 ui.write(" %s\n" % inst)
1874 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1876 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1875 problems += 1
1877 problems += 1
1876
1878
1877 # editor
1879 # editor
1878 ui.status(_("Checking commit editor...\n"))
1880 ui.status(_("Checking commit editor...\n"))
1879 editor = ui.geteditor()
1881 editor = ui.geteditor()
1880 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
1882 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
1881 if not cmdpath:
1883 if not cmdpath:
1882 if editor == 'vi':
1884 if editor == 'vi':
1883 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1885 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1884 ui.write(_(" (specify a commit editor in your configuration"
1886 ui.write(_(" (specify a commit editor in your configuration"
1885 " file)\n"))
1887 " file)\n"))
1886 else:
1888 else:
1887 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1889 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1888 ui.write(_(" (specify a commit editor in your configuration"
1890 ui.write(_(" (specify a commit editor in your configuration"
1889 " file)\n"))
1891 " file)\n"))
1890 problems += 1
1892 problems += 1
1891
1893
1892 # check username
1894 # check username
1893 ui.status(_("Checking username...\n"))
1895 ui.status(_("Checking username...\n"))
1894 try:
1896 try:
1895 ui.username()
1897 ui.username()
1896 except util.Abort, e:
1898 except util.Abort, e:
1897 ui.write(" %s\n" % e)
1899 ui.write(" %s\n" % e)
1898 ui.write(_(" (specify a username in your configuration file)\n"))
1900 ui.write(_(" (specify a username in your configuration file)\n"))
1899 problems += 1
1901 problems += 1
1900
1902
1901 if not problems:
1903 if not problems:
1902 ui.status(_("No problems detected\n"))
1904 ui.status(_("No problems detected\n"))
1903 else:
1905 else:
1904 ui.write(_("%s problems detected,"
1906 ui.write(_("%s problems detected,"
1905 " please check your install!\n") % problems)
1907 " please check your install!\n") % problems)
1906
1908
1907 return problems
1909 return problems
1908
1910
1909 @command('debugknown', [], _('REPO ID...'))
1911 @command('debugknown', [], _('REPO ID...'))
1910 def debugknown(ui, repopath, *ids, **opts):
1912 def debugknown(ui, repopath, *ids, **opts):
1911 """test whether node ids are known to a repo
1913 """test whether node ids are known to a repo
1912
1914
1913 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1915 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1914 indicating unknown/known.
1916 indicating unknown/known.
1915 """
1917 """
1916 repo = hg.peer(ui, opts, repopath)
1918 repo = hg.peer(ui, opts, repopath)
1917 if not repo.capable('known'):
1919 if not repo.capable('known'):
1918 raise util.Abort("known() not supported by target repository")
1920 raise util.Abort("known() not supported by target repository")
1919 flags = repo.known([bin(s) for s in ids])
1921 flags = repo.known([bin(s) for s in ids])
1920 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1922 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1921
1923
1922 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
1924 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
1923 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1925 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1924 '''access the pushkey key/value protocol
1926 '''access the pushkey key/value protocol
1925
1927
1926 With two args, list the keys in the given namespace.
1928 With two args, list the keys in the given namespace.
1927
1929
1928 With five args, set a key to new if it currently is set to old.
1930 With five args, set a key to new if it currently is set to old.
1929 Reports success or failure.
1931 Reports success or failure.
1930 '''
1932 '''
1931
1933
1932 target = hg.peer(ui, {}, repopath)
1934 target = hg.peer(ui, {}, repopath)
1933 if keyinfo:
1935 if keyinfo:
1934 key, old, new = keyinfo
1936 key, old, new = keyinfo
1935 r = target.pushkey(namespace, key, old, new)
1937 r = target.pushkey(namespace, key, old, new)
1936 ui.status(str(r) + '\n')
1938 ui.status(str(r) + '\n')
1937 return not r
1939 return not r
1938 else:
1940 else:
1939 for k, v in target.listkeys(namespace).iteritems():
1941 for k, v in target.listkeys(namespace).iteritems():
1940 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1942 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1941 v.encode('string-escape')))
1943 v.encode('string-escape')))
1942
1944
1943 @command('debugrebuildstate',
1945 @command('debugrebuildstate',
1944 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
1946 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
1945 _('[-r REV] [REV]'))
1947 _('[-r REV] [REV]'))
1946 def debugrebuildstate(ui, repo, rev="tip"):
1948 def debugrebuildstate(ui, repo, rev="tip"):
1947 """rebuild the dirstate as it would look like for the given revision"""
1949 """rebuild the dirstate as it would look like for the given revision"""
1948 ctx = scmutil.revsingle(repo, rev)
1950 ctx = scmutil.revsingle(repo, rev)
1949 wlock = repo.wlock()
1951 wlock = repo.wlock()
1950 try:
1952 try:
1951 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1953 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1952 finally:
1954 finally:
1953 wlock.release()
1955 wlock.release()
1954
1956
1955 @command('debugrename',
1957 @command('debugrename',
1956 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1958 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1957 _('[-r REV] FILE'))
1959 _('[-r REV] FILE'))
1958 def debugrename(ui, repo, file1, *pats, **opts):
1960 def debugrename(ui, repo, file1, *pats, **opts):
1959 """dump rename information"""
1961 """dump rename information"""
1960
1962
1961 ctx = scmutil.revsingle(repo, opts.get('rev'))
1963 ctx = scmutil.revsingle(repo, opts.get('rev'))
1962 m = scmutil.match(ctx, (file1,) + pats, opts)
1964 m = scmutil.match(ctx, (file1,) + pats, opts)
1963 for abs in ctx.walk(m):
1965 for abs in ctx.walk(m):
1964 fctx = ctx[abs]
1966 fctx = ctx[abs]
1965 o = fctx.filelog().renamed(fctx.filenode())
1967 o = fctx.filelog().renamed(fctx.filenode())
1966 rel = m.rel(abs)
1968 rel = m.rel(abs)
1967 if o:
1969 if o:
1968 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1970 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1969 else:
1971 else:
1970 ui.write(_("%s not renamed\n") % rel)
1972 ui.write(_("%s not renamed\n") % rel)
1971
1973
1972 @command('debugrevlog',
1974 @command('debugrevlog',
1973 [('c', 'changelog', False, _('open changelog')),
1975 [('c', 'changelog', False, _('open changelog')),
1974 ('m', 'manifest', False, _('open manifest')),
1976 ('m', 'manifest', False, _('open manifest')),
1975 ('d', 'dump', False, _('dump index data'))],
1977 ('d', 'dump', False, _('dump index data'))],
1976 _('-c|-m|FILE'))
1978 _('-c|-m|FILE'))
1977 def debugrevlog(ui, repo, file_ = None, **opts):
1979 def debugrevlog(ui, repo, file_ = None, **opts):
1978 """show data and statistics about a revlog"""
1980 """show data and statistics about a revlog"""
1979 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1981 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1980
1982
1981 if opts.get("dump"):
1983 if opts.get("dump"):
1982 numrevs = len(r)
1984 numrevs = len(r)
1983 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
1985 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
1984 " rawsize totalsize compression heads\n")
1986 " rawsize totalsize compression heads\n")
1985 ts = 0
1987 ts = 0
1986 heads = set()
1988 heads = set()
1987 for rev in xrange(numrevs):
1989 for rev in xrange(numrevs):
1988 dbase = r.deltaparent(rev)
1990 dbase = r.deltaparent(rev)
1989 if dbase == -1:
1991 if dbase == -1:
1990 dbase = rev
1992 dbase = rev
1991 cbase = r.chainbase(rev)
1993 cbase = r.chainbase(rev)
1992 p1, p2 = r.parentrevs(rev)
1994 p1, p2 = r.parentrevs(rev)
1993 rs = r.rawsize(rev)
1995 rs = r.rawsize(rev)
1994 ts = ts + rs
1996 ts = ts + rs
1995 heads -= set(r.parentrevs(rev))
1997 heads -= set(r.parentrevs(rev))
1996 heads.add(rev)
1998 heads.add(rev)
1997 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
1999 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
1998 (rev, p1, p2, r.start(rev), r.end(rev),
2000 (rev, p1, p2, r.start(rev), r.end(rev),
1999 r.start(dbase), r.start(cbase),
2001 r.start(dbase), r.start(cbase),
2000 r.start(p1), r.start(p2),
2002 r.start(p1), r.start(p2),
2001 rs, ts, ts / r.end(rev), len(heads)))
2003 rs, ts, ts / r.end(rev), len(heads)))
2002 return 0
2004 return 0
2003
2005
2004 v = r.version
2006 v = r.version
2005 format = v & 0xFFFF
2007 format = v & 0xFFFF
2006 flags = []
2008 flags = []
2007 gdelta = False
2009 gdelta = False
2008 if v & revlog.REVLOGNGINLINEDATA:
2010 if v & revlog.REVLOGNGINLINEDATA:
2009 flags.append('inline')
2011 flags.append('inline')
2010 if v & revlog.REVLOGGENERALDELTA:
2012 if v & revlog.REVLOGGENERALDELTA:
2011 gdelta = True
2013 gdelta = True
2012 flags.append('generaldelta')
2014 flags.append('generaldelta')
2013 if not flags:
2015 if not flags:
2014 flags = ['(none)']
2016 flags = ['(none)']
2015
2017
2016 nummerges = 0
2018 nummerges = 0
2017 numfull = 0
2019 numfull = 0
2018 numprev = 0
2020 numprev = 0
2019 nump1 = 0
2021 nump1 = 0
2020 nump2 = 0
2022 nump2 = 0
2021 numother = 0
2023 numother = 0
2022 nump1prev = 0
2024 nump1prev = 0
2023 nump2prev = 0
2025 nump2prev = 0
2024 chainlengths = []
2026 chainlengths = []
2025
2027
2026 datasize = [None, 0, 0L]
2028 datasize = [None, 0, 0L]
2027 fullsize = [None, 0, 0L]
2029 fullsize = [None, 0, 0L]
2028 deltasize = [None, 0, 0L]
2030 deltasize = [None, 0, 0L]
2029
2031
2030 def addsize(size, l):
2032 def addsize(size, l):
2031 if l[0] is None or size < l[0]:
2033 if l[0] is None or size < l[0]:
2032 l[0] = size
2034 l[0] = size
2033 if size > l[1]:
2035 if size > l[1]:
2034 l[1] = size
2036 l[1] = size
2035 l[2] += size
2037 l[2] += size
2036
2038
2037 numrevs = len(r)
2039 numrevs = len(r)
2038 for rev in xrange(numrevs):
2040 for rev in xrange(numrevs):
2039 p1, p2 = r.parentrevs(rev)
2041 p1, p2 = r.parentrevs(rev)
2040 delta = r.deltaparent(rev)
2042 delta = r.deltaparent(rev)
2041 if format > 0:
2043 if format > 0:
2042 addsize(r.rawsize(rev), datasize)
2044 addsize(r.rawsize(rev), datasize)
2043 if p2 != nullrev:
2045 if p2 != nullrev:
2044 nummerges += 1
2046 nummerges += 1
2045 size = r.length(rev)
2047 size = r.length(rev)
2046 if delta == nullrev:
2048 if delta == nullrev:
2047 chainlengths.append(0)
2049 chainlengths.append(0)
2048 numfull += 1
2050 numfull += 1
2049 addsize(size, fullsize)
2051 addsize(size, fullsize)
2050 else:
2052 else:
2051 chainlengths.append(chainlengths[delta] + 1)
2053 chainlengths.append(chainlengths[delta] + 1)
2052 addsize(size, deltasize)
2054 addsize(size, deltasize)
2053 if delta == rev - 1:
2055 if delta == rev - 1:
2054 numprev += 1
2056 numprev += 1
2055 if delta == p1:
2057 if delta == p1:
2056 nump1prev += 1
2058 nump1prev += 1
2057 elif delta == p2:
2059 elif delta == p2:
2058 nump2prev += 1
2060 nump2prev += 1
2059 elif delta == p1:
2061 elif delta == p1:
2060 nump1 += 1
2062 nump1 += 1
2061 elif delta == p2:
2063 elif delta == p2:
2062 nump2 += 1
2064 nump2 += 1
2063 elif delta != nullrev:
2065 elif delta != nullrev:
2064 numother += 1
2066 numother += 1
2065
2067
2066 numdeltas = numrevs - numfull
2068 numdeltas = numrevs - numfull
2067 numoprev = numprev - nump1prev - nump2prev
2069 numoprev = numprev - nump1prev - nump2prev
2068 totalrawsize = datasize[2]
2070 totalrawsize = datasize[2]
2069 datasize[2] /= numrevs
2071 datasize[2] /= numrevs
2070 fulltotal = fullsize[2]
2072 fulltotal = fullsize[2]
2071 fullsize[2] /= numfull
2073 fullsize[2] /= numfull
2072 deltatotal = deltasize[2]
2074 deltatotal = deltasize[2]
2073 deltasize[2] /= numrevs - numfull
2075 deltasize[2] /= numrevs - numfull
2074 totalsize = fulltotal + deltatotal
2076 totalsize = fulltotal + deltatotal
2075 avgchainlen = sum(chainlengths) / numrevs
2077 avgchainlen = sum(chainlengths) / numrevs
2076 compratio = totalrawsize / totalsize
2078 compratio = totalrawsize / totalsize
2077
2079
2078 basedfmtstr = '%%%dd\n'
2080 basedfmtstr = '%%%dd\n'
2079 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2081 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2080
2082
2081 def dfmtstr(max):
2083 def dfmtstr(max):
2082 return basedfmtstr % len(str(max))
2084 return basedfmtstr % len(str(max))
2083 def pcfmtstr(max, padding=0):
2085 def pcfmtstr(max, padding=0):
2084 return basepcfmtstr % (len(str(max)), ' ' * padding)
2086 return basepcfmtstr % (len(str(max)), ' ' * padding)
2085
2087
2086 def pcfmt(value, total):
2088 def pcfmt(value, total):
2087 return (value, 100 * float(value) / total)
2089 return (value, 100 * float(value) / total)
2088
2090
2089 ui.write('format : %d\n' % format)
2091 ui.write('format : %d\n' % format)
2090 ui.write('flags : %s\n' % ', '.join(flags))
2092 ui.write('flags : %s\n' % ', '.join(flags))
2091
2093
2092 ui.write('\n')
2094 ui.write('\n')
2093 fmt = pcfmtstr(totalsize)
2095 fmt = pcfmtstr(totalsize)
2094 fmt2 = dfmtstr(totalsize)
2096 fmt2 = dfmtstr(totalsize)
2095 ui.write('revisions : ' + fmt2 % numrevs)
2097 ui.write('revisions : ' + fmt2 % numrevs)
2096 ui.write(' merges : ' + fmt % pcfmt(nummerges, numrevs))
2098 ui.write(' merges : ' + fmt % pcfmt(nummerges, numrevs))
2097 ui.write(' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs))
2099 ui.write(' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs))
2098 ui.write('revisions : ' + fmt2 % numrevs)
2100 ui.write('revisions : ' + fmt2 % numrevs)
2099 ui.write(' full : ' + fmt % pcfmt(numfull, numrevs))
2101 ui.write(' full : ' + fmt % pcfmt(numfull, numrevs))
2100 ui.write(' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2102 ui.write(' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2101 ui.write('revision size : ' + fmt2 % totalsize)
2103 ui.write('revision size : ' + fmt2 % totalsize)
2102 ui.write(' full : ' + fmt % pcfmt(fulltotal, totalsize))
2104 ui.write(' full : ' + fmt % pcfmt(fulltotal, totalsize))
2103 ui.write(' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2105 ui.write(' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2104
2106
2105 ui.write('\n')
2107 ui.write('\n')
2106 fmt = dfmtstr(max(avgchainlen, compratio))
2108 fmt = dfmtstr(max(avgchainlen, compratio))
2107 ui.write('avg chain length : ' + fmt % avgchainlen)
2109 ui.write('avg chain length : ' + fmt % avgchainlen)
2108 ui.write('compression ratio : ' + fmt % compratio)
2110 ui.write('compression ratio : ' + fmt % compratio)
2109
2111
2110 if format > 0:
2112 if format > 0:
2111 ui.write('\n')
2113 ui.write('\n')
2112 ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
2114 ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
2113 % tuple(datasize))
2115 % tuple(datasize))
2114 ui.write('full revision size (min/max/avg) : %d / %d / %d\n'
2116 ui.write('full revision size (min/max/avg) : %d / %d / %d\n'
2115 % tuple(fullsize))
2117 % tuple(fullsize))
2116 ui.write('delta size (min/max/avg) : %d / %d / %d\n'
2118 ui.write('delta size (min/max/avg) : %d / %d / %d\n'
2117 % tuple(deltasize))
2119 % tuple(deltasize))
2118
2120
2119 if numdeltas > 0:
2121 if numdeltas > 0:
2120 ui.write('\n')
2122 ui.write('\n')
2121 fmt = pcfmtstr(numdeltas)
2123 fmt = pcfmtstr(numdeltas)
2122 fmt2 = pcfmtstr(numdeltas, 4)
2124 fmt2 = pcfmtstr(numdeltas, 4)
2123 ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas))
2125 ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas))
2124 if numprev > 0:
2126 if numprev > 0:
2125 ui.write(' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev))
2127 ui.write(' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev))
2126 ui.write(' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev))
2128 ui.write(' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev))
2127 ui.write(' other : ' + fmt2 % pcfmt(numoprev, numprev))
2129 ui.write(' other : ' + fmt2 % pcfmt(numoprev, numprev))
2128 if gdelta:
2130 if gdelta:
2129 ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas))
2131 ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas))
2130 ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas))
2132 ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas))
2131 ui.write('deltas against other : ' + fmt % pcfmt(numother, numdeltas))
2133 ui.write('deltas against other : ' + fmt % pcfmt(numother, numdeltas))
2132
2134
2133 @command('debugrevspec', [], ('REVSPEC'))
2135 @command('debugrevspec', [], ('REVSPEC'))
2134 def debugrevspec(ui, repo, expr):
2136 def debugrevspec(ui, repo, expr):
2135 '''parse and apply a revision specification'''
2137 '''parse and apply a revision specification'''
2136 if ui.verbose:
2138 if ui.verbose:
2137 tree = revset.parse(expr)[0]
2139 tree = revset.parse(expr)[0]
2138 ui.note(tree, "\n")
2140 ui.note(tree, "\n")
2139 newtree = revset.findaliases(ui, tree)
2141 newtree = revset.findaliases(ui, tree)
2140 if newtree != tree:
2142 if newtree != tree:
2141 ui.note(newtree, "\n")
2143 ui.note(newtree, "\n")
2142 func = revset.match(ui, expr)
2144 func = revset.match(ui, expr)
2143 for c in func(repo, range(len(repo))):
2145 for c in func(repo, range(len(repo))):
2144 ui.write("%s\n" % c)
2146 ui.write("%s\n" % c)
2145
2147
2146 @command('debugsetparents', [], _('REV1 [REV2]'))
2148 @command('debugsetparents', [], _('REV1 [REV2]'))
2147 def debugsetparents(ui, repo, rev1, rev2=None):
2149 def debugsetparents(ui, repo, rev1, rev2=None):
2148 """manually set the parents of the current working directory
2150 """manually set the parents of the current working directory
2149
2151
2150 This is useful for writing repository conversion tools, but should
2152 This is useful for writing repository conversion tools, but should
2151 be used with care.
2153 be used with care.
2152
2154
2153 Returns 0 on success.
2155 Returns 0 on success.
2154 """
2156 """
2155
2157
2156 r1 = scmutil.revsingle(repo, rev1).node()
2158 r1 = scmutil.revsingle(repo, rev1).node()
2157 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2159 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2158
2160
2159 wlock = repo.wlock()
2161 wlock = repo.wlock()
2160 try:
2162 try:
2161 repo.dirstate.setparents(r1, r2)
2163 repo.dirstate.setparents(r1, r2)
2162 finally:
2164 finally:
2163 wlock.release()
2165 wlock.release()
2164
2166
2165 @command('debugstate',
2167 @command('debugstate',
2166 [('', 'nodates', None, _('do not display the saved mtime')),
2168 [('', 'nodates', None, _('do not display the saved mtime')),
2167 ('', 'datesort', None, _('sort by saved mtime'))],
2169 ('', 'datesort', None, _('sort by saved mtime'))],
2168 _('[OPTION]...'))
2170 _('[OPTION]...'))
2169 def debugstate(ui, repo, nodates=None, datesort=None):
2171 def debugstate(ui, repo, nodates=None, datesort=None):
2170 """show the contents of the current dirstate"""
2172 """show the contents of the current dirstate"""
2171 timestr = ""
2173 timestr = ""
2172 showdate = not nodates
2174 showdate = not nodates
2173 if datesort:
2175 if datesort:
2174 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2176 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2175 else:
2177 else:
2176 keyfunc = None # sort by filename
2178 keyfunc = None # sort by filename
2177 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2179 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2178 if showdate:
2180 if showdate:
2179 if ent[3] == -1:
2181 if ent[3] == -1:
2180 # Pad or slice to locale representation
2182 # Pad or slice to locale representation
2181 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2183 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2182 time.localtime(0)))
2184 time.localtime(0)))
2183 timestr = 'unset'
2185 timestr = 'unset'
2184 timestr = (timestr[:locale_len] +
2186 timestr = (timestr[:locale_len] +
2185 ' ' * (locale_len - len(timestr)))
2187 ' ' * (locale_len - len(timestr)))
2186 else:
2188 else:
2187 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2189 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2188 time.localtime(ent[3]))
2190 time.localtime(ent[3]))
2189 if ent[1] & 020000:
2191 if ent[1] & 020000:
2190 mode = 'lnk'
2192 mode = 'lnk'
2191 else:
2193 else:
2192 mode = '%3o' % (ent[1] & 0777)
2194 mode = '%3o' % (ent[1] & 0777)
2193 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2195 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2194 for f in repo.dirstate.copies():
2196 for f in repo.dirstate.copies():
2195 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2197 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2196
2198
2197 @command('debugsub',
2199 @command('debugsub',
2198 [('r', 'rev', '',
2200 [('r', 'rev', '',
2199 _('revision to check'), _('REV'))],
2201 _('revision to check'), _('REV'))],
2200 _('[-r REV] [REV]'))
2202 _('[-r REV] [REV]'))
2201 def debugsub(ui, repo, rev=None):
2203 def debugsub(ui, repo, rev=None):
2202 ctx = scmutil.revsingle(repo, rev, None)
2204 ctx = scmutil.revsingle(repo, rev, None)
2203 for k, v in sorted(ctx.substate.items()):
2205 for k, v in sorted(ctx.substate.items()):
2204 ui.write('path %s\n' % k)
2206 ui.write('path %s\n' % k)
2205 ui.write(' source %s\n' % v[0])
2207 ui.write(' source %s\n' % v[0])
2206 ui.write(' revision %s\n' % v[1])
2208 ui.write(' revision %s\n' % v[1])
2207
2209
2208 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2210 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2209 def debugwalk(ui, repo, *pats, **opts):
2211 def debugwalk(ui, repo, *pats, **opts):
2210 """show how files match on given patterns"""
2212 """show how files match on given patterns"""
2211 m = scmutil.match(repo[None], pats, opts)
2213 m = scmutil.match(repo[None], pats, opts)
2212 items = list(repo.walk(m))
2214 items = list(repo.walk(m))
2213 if not items:
2215 if not items:
2214 return
2216 return
2215 fmt = 'f %%-%ds %%-%ds %%s' % (
2217 fmt = 'f %%-%ds %%-%ds %%s' % (
2216 max([len(abs) for abs in items]),
2218 max([len(abs) for abs in items]),
2217 max([len(m.rel(abs)) for abs in items]))
2219 max([len(m.rel(abs)) for abs in items]))
2218 for abs in items:
2220 for abs in items:
2219 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
2221 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
2220 ui.write("%s\n" % line.rstrip())
2222 ui.write("%s\n" % line.rstrip())
2221
2223
2222 @command('debugwireargs',
2224 @command('debugwireargs',
2223 [('', 'three', '', 'three'),
2225 [('', 'three', '', 'three'),
2224 ('', 'four', '', 'four'),
2226 ('', 'four', '', 'four'),
2225 ('', 'five', '', 'five'),
2227 ('', 'five', '', 'five'),
2226 ] + remoteopts,
2228 ] + remoteopts,
2227 _('REPO [OPTIONS]... [ONE [TWO]]'))
2229 _('REPO [OPTIONS]... [ONE [TWO]]'))
2228 def debugwireargs(ui, repopath, *vals, **opts):
2230 def debugwireargs(ui, repopath, *vals, **opts):
2229 repo = hg.peer(ui, opts, repopath)
2231 repo = hg.peer(ui, opts, repopath)
2230 for opt in remoteopts:
2232 for opt in remoteopts:
2231 del opts[opt[1]]
2233 del opts[opt[1]]
2232 args = {}
2234 args = {}
2233 for k, v in opts.iteritems():
2235 for k, v in opts.iteritems():
2234 if v:
2236 if v:
2235 args[k] = v
2237 args[k] = v
2236 # run twice to check that we don't mess up the stream for the next command
2238 # run twice to check that we don't mess up the stream for the next command
2237 res1 = repo.debugwireargs(*vals, **args)
2239 res1 = repo.debugwireargs(*vals, **args)
2238 res2 = repo.debugwireargs(*vals, **args)
2240 res2 = repo.debugwireargs(*vals, **args)
2239 ui.write("%s\n" % res1)
2241 ui.write("%s\n" % res1)
2240 if res1 != res2:
2242 if res1 != res2:
2241 ui.warn("%s\n" % res2)
2243 ui.warn("%s\n" % res2)
2242
2244
2243 @command('^diff',
2245 @command('^diff',
2244 [('r', 'rev', [], _('revision'), _('REV')),
2246 [('r', 'rev', [], _('revision'), _('REV')),
2245 ('c', 'change', '', _('change made by revision'), _('REV'))
2247 ('c', 'change', '', _('change made by revision'), _('REV'))
2246 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2248 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2247 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2249 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2248 def diff(ui, repo, *pats, **opts):
2250 def diff(ui, repo, *pats, **opts):
2249 """diff repository (or selected files)
2251 """diff repository (or selected files)
2250
2252
2251 Show differences between revisions for the specified files.
2253 Show differences between revisions for the specified files.
2252
2254
2253 Differences between files are shown using the unified diff format.
2255 Differences between files are shown using the unified diff format.
2254
2256
2255 .. note::
2257 .. note::
2256 diff may generate unexpected results for merges, as it will
2258 diff may generate unexpected results for merges, as it will
2257 default to comparing against the working directory's first
2259 default to comparing against the working directory's first
2258 parent changeset if no revisions are specified.
2260 parent changeset if no revisions are specified.
2259
2261
2260 When two revision arguments are given, then changes are shown
2262 When two revision arguments are given, then changes are shown
2261 between those revisions. If only one revision is specified then
2263 between those revisions. If only one revision is specified then
2262 that revision is compared to the working directory, and, when no
2264 that revision is compared to the working directory, and, when no
2263 revisions are specified, the working directory files are compared
2265 revisions are specified, the working directory files are compared
2264 to its parent.
2266 to its parent.
2265
2267
2266 Alternatively you can specify -c/--change with a revision to see
2268 Alternatively you can specify -c/--change with a revision to see
2267 the changes in that changeset relative to its first parent.
2269 the changes in that changeset relative to its first parent.
2268
2270
2269 Without the -a/--text option, diff will avoid generating diffs of
2271 Without the -a/--text option, diff will avoid generating diffs of
2270 files it detects as binary. With -a, diff will generate a diff
2272 files it detects as binary. With -a, diff will generate a diff
2271 anyway, probably with undesirable results.
2273 anyway, probably with undesirable results.
2272
2274
2273 Use the -g/--git option to generate diffs in the git extended diff
2275 Use the -g/--git option to generate diffs in the git extended diff
2274 format. For more information, read :hg:`help diffs`.
2276 format. For more information, read :hg:`help diffs`.
2275
2277
2276 .. container:: verbose
2278 .. container:: verbose
2277
2279
2278 Examples:
2280 Examples:
2279
2281
2280 - compare a file in the current working directory to its parent::
2282 - compare a file in the current working directory to its parent::
2281
2283
2282 hg diff foo.c
2284 hg diff foo.c
2283
2285
2284 - compare two historical versions of a directory, with rename info::
2286 - compare two historical versions of a directory, with rename info::
2285
2287
2286 hg diff --git -r 1.0:1.2 lib/
2288 hg diff --git -r 1.0:1.2 lib/
2287
2289
2288 - get change stats relative to the last change on some date::
2290 - get change stats relative to the last change on some date::
2289
2291
2290 hg diff --stat -r "date('may 2')"
2292 hg diff --stat -r "date('may 2')"
2291
2293
2292 - diff all newly-added files that contain a keyword::
2294 - diff all newly-added files that contain a keyword::
2293
2295
2294 hg diff "set:added() and grep(GNU)"
2296 hg diff "set:added() and grep(GNU)"
2295
2297
2296 - compare a revision and its parents::
2298 - compare a revision and its parents::
2297
2299
2298 hg diff -c 9353 # compare against first parent
2300 hg diff -c 9353 # compare against first parent
2299 hg diff -r 9353^:9353 # same using revset syntax
2301 hg diff -r 9353^:9353 # same using revset syntax
2300 hg diff -r 9353^2:9353 # compare against the second parent
2302 hg diff -r 9353^2:9353 # compare against the second parent
2301
2303
2302 Returns 0 on success.
2304 Returns 0 on success.
2303 """
2305 """
2304
2306
2305 revs = opts.get('rev')
2307 revs = opts.get('rev')
2306 change = opts.get('change')
2308 change = opts.get('change')
2307 stat = opts.get('stat')
2309 stat = opts.get('stat')
2308 reverse = opts.get('reverse')
2310 reverse = opts.get('reverse')
2309
2311
2310 if revs and change:
2312 if revs and change:
2311 msg = _('cannot specify --rev and --change at the same time')
2313 msg = _('cannot specify --rev and --change at the same time')
2312 raise util.Abort(msg)
2314 raise util.Abort(msg)
2313 elif change:
2315 elif change:
2314 node2 = scmutil.revsingle(repo, change, None).node()
2316 node2 = scmutil.revsingle(repo, change, None).node()
2315 node1 = repo[node2].p1().node()
2317 node1 = repo[node2].p1().node()
2316 else:
2318 else:
2317 node1, node2 = scmutil.revpair(repo, revs)
2319 node1, node2 = scmutil.revpair(repo, revs)
2318
2320
2319 if reverse:
2321 if reverse:
2320 node1, node2 = node2, node1
2322 node1, node2 = node2, node1
2321
2323
2322 diffopts = patch.diffopts(ui, opts)
2324 diffopts = patch.diffopts(ui, opts)
2323 m = scmutil.match(repo[node2], pats, opts)
2325 m = scmutil.match(repo[node2], pats, opts)
2324 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2326 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2325 listsubrepos=opts.get('subrepos'))
2327 listsubrepos=opts.get('subrepos'))
2326
2328
2327 @command('^export',
2329 @command('^export',
2328 [('o', 'output', '',
2330 [('o', 'output', '',
2329 _('print output to file with formatted name'), _('FORMAT')),
2331 _('print output to file with formatted name'), _('FORMAT')),
2330 ('', 'switch-parent', None, _('diff against the second parent')),
2332 ('', 'switch-parent', None, _('diff against the second parent')),
2331 ('r', 'rev', [], _('revisions to export'), _('REV')),
2333 ('r', 'rev', [], _('revisions to export'), _('REV')),
2332 ] + diffopts,
2334 ] + diffopts,
2333 _('[OPTION]... [-o OUTFILESPEC] REV...'))
2335 _('[OPTION]... [-o OUTFILESPEC] REV...'))
2334 def export(ui, repo, *changesets, **opts):
2336 def export(ui, repo, *changesets, **opts):
2335 """dump the header and diffs for one or more changesets
2337 """dump the header and diffs for one or more changesets
2336
2338
2337 Print the changeset header and diffs for one or more revisions.
2339 Print the changeset header and diffs for one or more revisions.
2338
2340
2339 The information shown in the changeset header is: author, date,
2341 The information shown in the changeset header is: author, date,
2340 branch name (if non-default), changeset hash, parent(s) and commit
2342 branch name (if non-default), changeset hash, parent(s) and commit
2341 comment.
2343 comment.
2342
2344
2343 .. note::
2345 .. note::
2344 export may generate unexpected diff output for merge
2346 export may generate unexpected diff output for merge
2345 changesets, as it will compare the merge changeset against its
2347 changesets, as it will compare the merge changeset against its
2346 first parent only.
2348 first parent only.
2347
2349
2348 Output may be to a file, in which case the name of the file is
2350 Output may be to a file, in which case the name of the file is
2349 given using a format string. The formatting rules are as follows:
2351 given using a format string. The formatting rules are as follows:
2350
2352
2351 :``%%``: literal "%" character
2353 :``%%``: literal "%" character
2352 :``%H``: changeset hash (40 hexadecimal digits)
2354 :``%H``: changeset hash (40 hexadecimal digits)
2353 :``%N``: number of patches being generated
2355 :``%N``: number of patches being generated
2354 :``%R``: changeset revision number
2356 :``%R``: changeset revision number
2355 :``%b``: basename of the exporting repository
2357 :``%b``: basename of the exporting repository
2356 :``%h``: short-form changeset hash (12 hexadecimal digits)
2358 :``%h``: short-form changeset hash (12 hexadecimal digits)
2357 :``%m``: first line of the commit message (only alphanumeric characters)
2359 :``%m``: first line of the commit message (only alphanumeric characters)
2358 :``%n``: zero-padded sequence number, starting at 1
2360 :``%n``: zero-padded sequence number, starting at 1
2359 :``%r``: zero-padded changeset revision number
2361 :``%r``: zero-padded changeset revision number
2360
2362
2361 Without the -a/--text option, export will avoid generating diffs
2363 Without the -a/--text option, export will avoid generating diffs
2362 of files it detects as binary. With -a, export will generate a
2364 of files it detects as binary. With -a, export will generate a
2363 diff anyway, probably with undesirable results.
2365 diff anyway, probably with undesirable results.
2364
2366
2365 Use the -g/--git option to generate diffs in the git extended diff
2367 Use the -g/--git option to generate diffs in the git extended diff
2366 format. See :hg:`help diffs` for more information.
2368 format. See :hg:`help diffs` for more information.
2367
2369
2368 With the --switch-parent option, the diff will be against the
2370 With the --switch-parent option, the diff will be against the
2369 second parent. It can be useful to review a merge.
2371 second parent. It can be useful to review a merge.
2370
2372
2371 .. container:: verbose
2373 .. container:: verbose
2372
2374
2373 Examples:
2375 Examples:
2374
2376
2375 - use export and import to transplant a bugfix to the current
2377 - use export and import to transplant a bugfix to the current
2376 branch::
2378 branch::
2377
2379
2378 hg export -r 9353 | hg import -
2380 hg export -r 9353 | hg import -
2379
2381
2380 - export all the changesets between two revisions to a file with
2382 - export all the changesets between two revisions to a file with
2381 rename information::
2383 rename information::
2382
2384
2383 hg export --git -r 123:150 > changes.txt
2385 hg export --git -r 123:150 > changes.txt
2384
2386
2385 - split outgoing changes into a series of patches with
2387 - split outgoing changes into a series of patches with
2386 descriptive names::
2388 descriptive names::
2387
2389
2388 hg export -r "outgoing()" -o "%n-%m.patch"
2390 hg export -r "outgoing()" -o "%n-%m.patch"
2389
2391
2390 Returns 0 on success.
2392 Returns 0 on success.
2391 """
2393 """
2392 changesets += tuple(opts.get('rev', []))
2394 changesets += tuple(opts.get('rev', []))
2393 if not changesets:
2395 if not changesets:
2394 raise util.Abort(_("export requires at least one changeset"))
2396 raise util.Abort(_("export requires at least one changeset"))
2395 revs = scmutil.revrange(repo, changesets)
2397 revs = scmutil.revrange(repo, changesets)
2396 if len(revs) > 1:
2398 if len(revs) > 1:
2397 ui.note(_('exporting patches:\n'))
2399 ui.note(_('exporting patches:\n'))
2398 else:
2400 else:
2399 ui.note(_('exporting patch:\n'))
2401 ui.note(_('exporting patch:\n'))
2400 cmdutil.export(repo, revs, template=opts.get('output'),
2402 cmdutil.export(repo, revs, template=opts.get('output'),
2401 switch_parent=opts.get('switch_parent'),
2403 switch_parent=opts.get('switch_parent'),
2402 opts=patch.diffopts(ui, opts))
2404 opts=patch.diffopts(ui, opts))
2403
2405
2404 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2406 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2405 def forget(ui, repo, *pats, **opts):
2407 def forget(ui, repo, *pats, **opts):
2406 """forget the specified files on the next commit
2408 """forget the specified files on the next commit
2407
2409
2408 Mark the specified files so they will no longer be tracked
2410 Mark the specified files so they will no longer be tracked
2409 after the next commit.
2411 after the next commit.
2410
2412
2411 This only removes files from the current branch, not from the
2413 This only removes files from the current branch, not from the
2412 entire project history, and it does not delete them from the
2414 entire project history, and it does not delete them from the
2413 working directory.
2415 working directory.
2414
2416
2415 To undo a forget before the next commit, see :hg:`add`.
2417 To undo a forget before the next commit, see :hg:`add`.
2416
2418
2417 .. container:: verbose
2419 .. container:: verbose
2418
2420
2419 Examples:
2421 Examples:
2420
2422
2421 - forget newly-added binary files::
2423 - forget newly-added binary files::
2422
2424
2423 hg forget "set:added() and binary()"
2425 hg forget "set:added() and binary()"
2424
2426
2425 - forget files that would be excluded by .hgignore::
2427 - forget files that would be excluded by .hgignore::
2426
2428
2427 hg forget "set:hgignore()"
2429 hg forget "set:hgignore()"
2428
2430
2429 Returns 0 on success.
2431 Returns 0 on success.
2430 """
2432 """
2431
2433
2432 if not pats:
2434 if not pats:
2433 raise util.Abort(_('no files specified'))
2435 raise util.Abort(_('no files specified'))
2434
2436
2435 m = scmutil.match(repo[None], pats, opts)
2437 m = scmutil.match(repo[None], pats, opts)
2436 s = repo.status(match=m, clean=True)
2438 s = repo.status(match=m, clean=True)
2437 forget = sorted(s[0] + s[1] + s[3] + s[6])
2439 forget = sorted(s[0] + s[1] + s[3] + s[6])
2438 errs = 0
2440 errs = 0
2439
2441
2440 for f in m.files():
2442 for f in m.files():
2441 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2443 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2442 if os.path.exists(m.rel(f)):
2444 if os.path.exists(m.rel(f)):
2443 ui.warn(_('not removing %s: file is already untracked\n')
2445 ui.warn(_('not removing %s: file is already untracked\n')
2444 % m.rel(f))
2446 % m.rel(f))
2445 errs = 1
2447 errs = 1
2446
2448
2447 for f in forget:
2449 for f in forget:
2448 if ui.verbose or not m.exact(f):
2450 if ui.verbose or not m.exact(f):
2449 ui.status(_('removing %s\n') % m.rel(f))
2451 ui.status(_('removing %s\n') % m.rel(f))
2450
2452
2451 repo[None].forget(forget)
2453 repo[None].forget(forget)
2452 return errs
2454 return errs
2453
2455
2454 @command(
2456 @command(
2455 'graft',
2457 'graft',
2456 [('c', 'continue', False, _('resume interrupted graft')),
2458 [('c', 'continue', False, _('resume interrupted graft')),
2457 ('e', 'edit', False, _('invoke editor on commit messages')),
2459 ('e', 'edit', False, _('invoke editor on commit messages')),
2458 ('D', 'currentdate', False,
2460 ('D', 'currentdate', False,
2459 _('record the current date as commit date')),
2461 _('record the current date as commit date')),
2460 ('U', 'currentuser', False,
2462 ('U', 'currentuser', False,
2461 _('record the current user as committer'), _('DATE'))]
2463 _('record the current user as committer'), _('DATE'))]
2462 + commitopts2 + mergetoolopts,
2464 + commitopts2 + mergetoolopts,
2463 _('[OPTION]... REVISION...'))
2465 _('[OPTION]... REVISION...'))
2464 def graft(ui, repo, *revs, **opts):
2466 def graft(ui, repo, *revs, **opts):
2465 '''copy changes from other branches onto the current branch
2467 '''copy changes from other branches onto the current branch
2466
2468
2467 This command uses Mercurial's merge logic to copy individual
2469 This command uses Mercurial's merge logic to copy individual
2468 changes from other branches without merging branches in the
2470 changes from other branches without merging branches in the
2469 history graph. This is sometimes known as 'backporting' or
2471 history graph. This is sometimes known as 'backporting' or
2470 'cherry-picking'. By default, graft will copy user, date, and
2472 'cherry-picking'. By default, graft will copy user, date, and
2471 description from the source changesets.
2473 description from the source changesets.
2472
2474
2473 Changesets that are ancestors of the current revision, that have
2475 Changesets that are ancestors of the current revision, that have
2474 already been grafted, or that are merges will be skipped.
2476 already been grafted, or that are merges will be skipped.
2475
2477
2476 If a graft merge results in conflicts, the graft process is
2478 If a graft merge results in conflicts, the graft process is
2477 aborted so that the current merge can be manually resolved. Once
2479 aborted so that the current merge can be manually resolved. Once
2478 all conflicts are addressed, the graft process can be continued
2480 all conflicts are addressed, the graft process can be continued
2479 with the -c/--continue option.
2481 with the -c/--continue option.
2480
2482
2481 .. note::
2483 .. note::
2482 The -c/--continue option does not reapply earlier options.
2484 The -c/--continue option does not reapply earlier options.
2483
2485
2484 .. container:: verbose
2486 .. container:: verbose
2485
2487
2486 Examples:
2488 Examples:
2487
2489
2488 - copy a single change to the stable branch and edit its description::
2490 - copy a single change to the stable branch and edit its description::
2489
2491
2490 hg update stable
2492 hg update stable
2491 hg graft --edit 9393
2493 hg graft --edit 9393
2492
2494
2493 - graft a range of changesets with one exception, updating dates::
2495 - graft a range of changesets with one exception, updating dates::
2494
2496
2495 hg graft -D "2085::2093 and not 2091"
2497 hg graft -D "2085::2093 and not 2091"
2496
2498
2497 - continue a graft after resolving conflicts::
2499 - continue a graft after resolving conflicts::
2498
2500
2499 hg graft -c
2501 hg graft -c
2500
2502
2501 - show the source of a grafted changeset::
2503 - show the source of a grafted changeset::
2502
2504
2503 hg log --debug -r tip
2505 hg log --debug -r tip
2504
2506
2505 Returns 0 on successful completion.
2507 Returns 0 on successful completion.
2506 '''
2508 '''
2507
2509
2508 if not opts.get('user') and opts.get('currentuser'):
2510 if not opts.get('user') and opts.get('currentuser'):
2509 opts['user'] = ui.username()
2511 opts['user'] = ui.username()
2510 if not opts.get('date') and opts.get('currentdate'):
2512 if not opts.get('date') and opts.get('currentdate'):
2511 opts['date'] = "%d %d" % util.makedate()
2513 opts['date'] = "%d %d" % util.makedate()
2512
2514
2513 editor = None
2515 editor = None
2514 if opts.get('edit'):
2516 if opts.get('edit'):
2515 editor = cmdutil.commitforceeditor
2517 editor = cmdutil.commitforceeditor
2516
2518
2517 cont = False
2519 cont = False
2518 if opts['continue']:
2520 if opts['continue']:
2519 cont = True
2521 cont = True
2520 if revs:
2522 if revs:
2521 raise util.Abort(_("can't specify --continue and revisions"))
2523 raise util.Abort(_("can't specify --continue and revisions"))
2522 # read in unfinished revisions
2524 # read in unfinished revisions
2523 try:
2525 try:
2524 nodes = repo.opener.read('graftstate').splitlines()
2526 nodes = repo.opener.read('graftstate').splitlines()
2525 revs = [repo[node].rev() for node in nodes]
2527 revs = [repo[node].rev() for node in nodes]
2526 except IOError, inst:
2528 except IOError, inst:
2527 if inst.errno != errno.ENOENT:
2529 if inst.errno != errno.ENOENT:
2528 raise
2530 raise
2529 raise util.Abort(_("no graft state found, can't continue"))
2531 raise util.Abort(_("no graft state found, can't continue"))
2530 else:
2532 else:
2531 cmdutil.bailifchanged(repo)
2533 cmdutil.bailifchanged(repo)
2532 if not revs:
2534 if not revs:
2533 raise util.Abort(_('no revisions specified'))
2535 raise util.Abort(_('no revisions specified'))
2534 revs = scmutil.revrange(repo, revs)
2536 revs = scmutil.revrange(repo, revs)
2535
2537
2536 # check for merges
2538 # check for merges
2537 for ctx in repo.set('%ld and merge()', revs):
2539 for ctx in repo.set('%ld and merge()', revs):
2538 ui.warn(_('skipping ungraftable merge revision %s\n') % ctx.rev())
2540 ui.warn(_('skipping ungraftable merge revision %s\n') % ctx.rev())
2539 revs.remove(ctx.rev())
2541 revs.remove(ctx.rev())
2540 if not revs:
2542 if not revs:
2541 return -1
2543 return -1
2542
2544
2543 # check for ancestors of dest branch
2545 # check for ancestors of dest branch
2544 for ctx in repo.set('::. and %ld', revs):
2546 for ctx in repo.set('::. and %ld', revs):
2545 ui.warn(_('skipping ancestor revision %s\n') % ctx.rev())
2547 ui.warn(_('skipping ancestor revision %s\n') % ctx.rev())
2546 revs.remove(ctx.rev())
2548 revs.remove(ctx.rev())
2547 if not revs:
2549 if not revs:
2548 return -1
2550 return -1
2549
2551
2550 # analyze revs for earlier grafts
2552 # analyze revs for earlier grafts
2551 ids = {}
2553 ids = {}
2552 for ctx in repo.set("%ld", revs):
2554 for ctx in repo.set("%ld", revs):
2553 ids[ctx.hex()] = ctx.rev()
2555 ids[ctx.hex()] = ctx.rev()
2554 n = ctx.extra().get('source')
2556 n = ctx.extra().get('source')
2555 if n:
2557 if n:
2556 ids[n] = ctx.rev()
2558 ids[n] = ctx.rev()
2557
2559
2558 # check ancestors for earlier grafts
2560 # check ancestors for earlier grafts
2559 ui.debug('scanning for duplicate grafts\n')
2561 ui.debug('scanning for duplicate grafts\n')
2560 for ctx in repo.set("::. - ::%ld", revs):
2562 for ctx in repo.set("::. - ::%ld", revs):
2561 n = ctx.extra().get('source')
2563 n = ctx.extra().get('source')
2562 if n in ids:
2564 if n in ids:
2563 r = repo[n].rev()
2565 r = repo[n].rev()
2564 if r in revs:
2566 if r in revs:
2565 ui.warn(_('skipping already grafted revision %s\n') % r)
2567 ui.warn(_('skipping already grafted revision %s\n') % r)
2566 revs.remove(r)
2568 revs.remove(r)
2567 elif ids[n] in revs:
2569 elif ids[n] in revs:
2568 ui.warn(_('skipping already grafted revision %s '
2570 ui.warn(_('skipping already grafted revision %s '
2569 '(same origin %d)\n') % (ids[n], r))
2571 '(same origin %d)\n') % (ids[n], r))
2570 revs.remove(ids[n])
2572 revs.remove(ids[n])
2571 elif ctx.hex() in ids:
2573 elif ctx.hex() in ids:
2572 r = ids[ctx.hex()]
2574 r = ids[ctx.hex()]
2573 ui.warn(_('skipping already grafted revision %s '
2575 ui.warn(_('skipping already grafted revision %s '
2574 '(was grafted from %d)\n') % (r, ctx.rev()))
2576 '(was grafted from %d)\n') % (r, ctx.rev()))
2575 revs.remove(r)
2577 revs.remove(r)
2576 if not revs:
2578 if not revs:
2577 return -1
2579 return -1
2578
2580
2579 for pos, ctx in enumerate(repo.set("%ld", revs)):
2581 for pos, ctx in enumerate(repo.set("%ld", revs)):
2580 current = repo['.']
2582 current = repo['.']
2581 ui.status(_('grafting revision %s\n') % ctx.rev())
2583 ui.status(_('grafting revision %s\n') % ctx.rev())
2582
2584
2583 # we don't merge the first commit when continuing
2585 # we don't merge the first commit when continuing
2584 if not cont:
2586 if not cont:
2585 # perform the graft merge with p1(rev) as 'ancestor'
2587 # perform the graft merge with p1(rev) as 'ancestor'
2586 try:
2588 try:
2587 # ui.forcemerge is an internal variable, do not document
2589 # ui.forcemerge is an internal variable, do not document
2588 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2590 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2589 stats = mergemod.update(repo, ctx.node(), True, True, False,
2591 stats = mergemod.update(repo, ctx.node(), True, True, False,
2590 ctx.p1().node())
2592 ctx.p1().node())
2591 finally:
2593 finally:
2592 ui.setconfig('ui', 'forcemerge', '')
2594 ui.setconfig('ui', 'forcemerge', '')
2593 # drop the second merge parent
2595 # drop the second merge parent
2594 repo.dirstate.setparents(current.node(), nullid)
2596 repo.dirstate.setparents(current.node(), nullid)
2595 repo.dirstate.write()
2597 repo.dirstate.write()
2596 # fix up dirstate for copies and renames
2598 # fix up dirstate for copies and renames
2597 cmdutil.duplicatecopies(repo, ctx.rev(), current.node(), nullid)
2599 cmdutil.duplicatecopies(repo, ctx.rev(), current.node(), nullid)
2598 # report any conflicts
2600 # report any conflicts
2599 if stats and stats[3] > 0:
2601 if stats and stats[3] > 0:
2600 # write out state for --continue
2602 # write out state for --continue
2601 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
2603 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
2602 repo.opener.write('graftstate', ''.join(nodelines))
2604 repo.opener.write('graftstate', ''.join(nodelines))
2603 raise util.Abort(
2605 raise util.Abort(
2604 _("unresolved conflicts, can't continue"),
2606 _("unresolved conflicts, can't continue"),
2605 hint=_('use hg resolve and hg graft --continue'))
2607 hint=_('use hg resolve and hg graft --continue'))
2606 else:
2608 else:
2607 cont = False
2609 cont = False
2608
2610
2609 # commit
2611 # commit
2610 source = ctx.extra().get('source')
2612 source = ctx.extra().get('source')
2611 if not source:
2613 if not source:
2612 source = ctx.hex()
2614 source = ctx.hex()
2613 extra = {'source': source}
2615 extra = {'source': source}
2614 user = ctx.user()
2616 user = ctx.user()
2615 if opts.get('user'):
2617 if opts.get('user'):
2616 user = opts['user']
2618 user = opts['user']
2617 date = ctx.date()
2619 date = ctx.date()
2618 if opts.get('date'):
2620 if opts.get('date'):
2619 date = opts['date']
2621 date = opts['date']
2620 repo.commit(text=ctx.description(), user=user,
2622 repo.commit(text=ctx.description(), user=user,
2621 date=date, extra=extra, editor=editor)
2623 date=date, extra=extra, editor=editor)
2622
2624
2623 # remove state when we complete successfully
2625 # remove state when we complete successfully
2624 if os.path.exists(repo.join('graftstate')):
2626 if os.path.exists(repo.join('graftstate')):
2625 util.unlinkpath(repo.join('graftstate'))
2627 util.unlinkpath(repo.join('graftstate'))
2626
2628
2627 return 0
2629 return 0
2628
2630
2629 @command('grep',
2631 @command('grep',
2630 [('0', 'print0', None, _('end fields with NUL')),
2632 [('0', 'print0', None, _('end fields with NUL')),
2631 ('', 'all', None, _('print all revisions that match')),
2633 ('', 'all', None, _('print all revisions that match')),
2632 ('a', 'text', None, _('treat all files as text')),
2634 ('a', 'text', None, _('treat all files as text')),
2633 ('f', 'follow', None,
2635 ('f', 'follow', None,
2634 _('follow changeset history,'
2636 _('follow changeset history,'
2635 ' or file history across copies and renames')),
2637 ' or file history across copies and renames')),
2636 ('i', 'ignore-case', None, _('ignore case when matching')),
2638 ('i', 'ignore-case', None, _('ignore case when matching')),
2637 ('l', 'files-with-matches', None,
2639 ('l', 'files-with-matches', None,
2638 _('print only filenames and revisions that match')),
2640 _('print only filenames and revisions that match')),
2639 ('n', 'line-number', None, _('print matching line numbers')),
2641 ('n', 'line-number', None, _('print matching line numbers')),
2640 ('r', 'rev', [],
2642 ('r', 'rev', [],
2641 _('only search files changed within revision range'), _('REV')),
2643 _('only search files changed within revision range'), _('REV')),
2642 ('u', 'user', None, _('list the author (long with -v)')),
2644 ('u', 'user', None, _('list the author (long with -v)')),
2643 ('d', 'date', None, _('list the date (short with -q)')),
2645 ('d', 'date', None, _('list the date (short with -q)')),
2644 ] + walkopts,
2646 ] + walkopts,
2645 _('[OPTION]... PATTERN [FILE]...'))
2647 _('[OPTION]... PATTERN [FILE]...'))
2646 def grep(ui, repo, pattern, *pats, **opts):
2648 def grep(ui, repo, pattern, *pats, **opts):
2647 """search for a pattern in specified files and revisions
2649 """search for a pattern in specified files and revisions
2648
2650
2649 Search revisions of files for a regular expression.
2651 Search revisions of files for a regular expression.
2650
2652
2651 This command behaves differently than Unix grep. It only accepts
2653 This command behaves differently than Unix grep. It only accepts
2652 Python/Perl regexps. It searches repository history, not the
2654 Python/Perl regexps. It searches repository history, not the
2653 working directory. It always prints the revision number in which a
2655 working directory. It always prints the revision number in which a
2654 match appears.
2656 match appears.
2655
2657
2656 By default, grep only prints output for the first revision of a
2658 By default, grep only prints output for the first revision of a
2657 file in which it finds a match. To get it to print every revision
2659 file in which it finds a match. To get it to print every revision
2658 that contains a change in match status ("-" for a match that
2660 that contains a change in match status ("-" for a match that
2659 becomes a non-match, or "+" for a non-match that becomes a match),
2661 becomes a non-match, or "+" for a non-match that becomes a match),
2660 use the --all flag.
2662 use the --all flag.
2661
2663
2662 Returns 0 if a match is found, 1 otherwise.
2664 Returns 0 if a match is found, 1 otherwise.
2663 """
2665 """
2664 reflags = 0
2666 reflags = 0
2665 if opts.get('ignore_case'):
2667 if opts.get('ignore_case'):
2666 reflags |= re.I
2668 reflags |= re.I
2667 try:
2669 try:
2668 regexp = re.compile(pattern, reflags)
2670 regexp = re.compile(pattern, reflags)
2669 except re.error, inst:
2671 except re.error, inst:
2670 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
2672 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
2671 return 1
2673 return 1
2672 sep, eol = ':', '\n'
2674 sep, eol = ':', '\n'
2673 if opts.get('print0'):
2675 if opts.get('print0'):
2674 sep = eol = '\0'
2676 sep = eol = '\0'
2675
2677
2676 getfile = util.lrucachefunc(repo.file)
2678 getfile = util.lrucachefunc(repo.file)
2677
2679
2678 def matchlines(body):
2680 def matchlines(body):
2679 begin = 0
2681 begin = 0
2680 linenum = 0
2682 linenum = 0
2681 while True:
2683 while True:
2682 match = regexp.search(body, begin)
2684 match = regexp.search(body, begin)
2683 if not match:
2685 if not match:
2684 break
2686 break
2685 mstart, mend = match.span()
2687 mstart, mend = match.span()
2686 linenum += body.count('\n', begin, mstart) + 1
2688 linenum += body.count('\n', begin, mstart) + 1
2687 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2689 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2688 begin = body.find('\n', mend) + 1 or len(body) + 1
2690 begin = body.find('\n', mend) + 1 or len(body) + 1
2689 lend = begin - 1
2691 lend = begin - 1
2690 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2692 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2691
2693
2692 class linestate(object):
2694 class linestate(object):
2693 def __init__(self, line, linenum, colstart, colend):
2695 def __init__(self, line, linenum, colstart, colend):
2694 self.line = line
2696 self.line = line
2695 self.linenum = linenum
2697 self.linenum = linenum
2696 self.colstart = colstart
2698 self.colstart = colstart
2697 self.colend = colend
2699 self.colend = colend
2698
2700
2699 def __hash__(self):
2701 def __hash__(self):
2700 return hash((self.linenum, self.line))
2702 return hash((self.linenum, self.line))
2701
2703
2702 def __eq__(self, other):
2704 def __eq__(self, other):
2703 return self.line == other.line
2705 return self.line == other.line
2704
2706
2705 matches = {}
2707 matches = {}
2706 copies = {}
2708 copies = {}
2707 def grepbody(fn, rev, body):
2709 def grepbody(fn, rev, body):
2708 matches[rev].setdefault(fn, [])
2710 matches[rev].setdefault(fn, [])
2709 m = matches[rev][fn]
2711 m = matches[rev][fn]
2710 for lnum, cstart, cend, line in matchlines(body):
2712 for lnum, cstart, cend, line in matchlines(body):
2711 s = linestate(line, lnum, cstart, cend)
2713 s = linestate(line, lnum, cstart, cend)
2712 m.append(s)
2714 m.append(s)
2713
2715
2714 def difflinestates(a, b):
2716 def difflinestates(a, b):
2715 sm = difflib.SequenceMatcher(None, a, b)
2717 sm = difflib.SequenceMatcher(None, a, b)
2716 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2718 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2717 if tag == 'insert':
2719 if tag == 'insert':
2718 for i in xrange(blo, bhi):
2720 for i in xrange(blo, bhi):
2719 yield ('+', b[i])
2721 yield ('+', b[i])
2720 elif tag == 'delete':
2722 elif tag == 'delete':
2721 for i in xrange(alo, ahi):
2723 for i in xrange(alo, ahi):
2722 yield ('-', a[i])
2724 yield ('-', a[i])
2723 elif tag == 'replace':
2725 elif tag == 'replace':
2724 for i in xrange(alo, ahi):
2726 for i in xrange(alo, ahi):
2725 yield ('-', a[i])
2727 yield ('-', a[i])
2726 for i in xrange(blo, bhi):
2728 for i in xrange(blo, bhi):
2727 yield ('+', b[i])
2729 yield ('+', b[i])
2728
2730
2729 def display(fn, ctx, pstates, states):
2731 def display(fn, ctx, pstates, states):
2730 rev = ctx.rev()
2732 rev = ctx.rev()
2731 datefunc = ui.quiet and util.shortdate or util.datestr
2733 datefunc = ui.quiet and util.shortdate or util.datestr
2732 found = False
2734 found = False
2733 filerevmatches = {}
2735 filerevmatches = {}
2734 def binary():
2736 def binary():
2735 flog = getfile(fn)
2737 flog = getfile(fn)
2736 return util.binary(flog.read(ctx.filenode(fn)))
2738 return util.binary(flog.read(ctx.filenode(fn)))
2737
2739
2738 if opts.get('all'):
2740 if opts.get('all'):
2739 iter = difflinestates(pstates, states)
2741 iter = difflinestates(pstates, states)
2740 else:
2742 else:
2741 iter = [('', l) for l in states]
2743 iter = [('', l) for l in states]
2742 for change, l in iter:
2744 for change, l in iter:
2743 cols = [fn, str(rev)]
2745 cols = [fn, str(rev)]
2744 before, match, after = None, None, None
2746 before, match, after = None, None, None
2745 if opts.get('line_number'):
2747 if opts.get('line_number'):
2746 cols.append(str(l.linenum))
2748 cols.append(str(l.linenum))
2747 if opts.get('all'):
2749 if opts.get('all'):
2748 cols.append(change)
2750 cols.append(change)
2749 if opts.get('user'):
2751 if opts.get('user'):
2750 cols.append(ui.shortuser(ctx.user()))
2752 cols.append(ui.shortuser(ctx.user()))
2751 if opts.get('date'):
2753 if opts.get('date'):
2752 cols.append(datefunc(ctx.date()))
2754 cols.append(datefunc(ctx.date()))
2753 if opts.get('files_with_matches'):
2755 if opts.get('files_with_matches'):
2754 c = (fn, rev)
2756 c = (fn, rev)
2755 if c in filerevmatches:
2757 if c in filerevmatches:
2756 continue
2758 continue
2757 filerevmatches[c] = 1
2759 filerevmatches[c] = 1
2758 else:
2760 else:
2759 before = l.line[:l.colstart]
2761 before = l.line[:l.colstart]
2760 match = l.line[l.colstart:l.colend]
2762 match = l.line[l.colstart:l.colend]
2761 after = l.line[l.colend:]
2763 after = l.line[l.colend:]
2762 ui.write(sep.join(cols))
2764 ui.write(sep.join(cols))
2763 if before is not None:
2765 if before is not None:
2764 if not opts.get('text') and binary():
2766 if not opts.get('text') and binary():
2765 ui.write(sep + " Binary file matches")
2767 ui.write(sep + " Binary file matches")
2766 else:
2768 else:
2767 ui.write(sep + before)
2769 ui.write(sep + before)
2768 ui.write(match, label='grep.match')
2770 ui.write(match, label='grep.match')
2769 ui.write(after)
2771 ui.write(after)
2770 ui.write(eol)
2772 ui.write(eol)
2771 found = True
2773 found = True
2772 return found
2774 return found
2773
2775
2774 skip = {}
2776 skip = {}
2775 revfiles = {}
2777 revfiles = {}
2776 matchfn = scmutil.match(repo[None], pats, opts)
2778 matchfn = scmutil.match(repo[None], pats, opts)
2777 found = False
2779 found = False
2778 follow = opts.get('follow')
2780 follow = opts.get('follow')
2779
2781
2780 def prep(ctx, fns):
2782 def prep(ctx, fns):
2781 rev = ctx.rev()
2783 rev = ctx.rev()
2782 pctx = ctx.p1()
2784 pctx = ctx.p1()
2783 parent = pctx.rev()
2785 parent = pctx.rev()
2784 matches.setdefault(rev, {})
2786 matches.setdefault(rev, {})
2785 matches.setdefault(parent, {})
2787 matches.setdefault(parent, {})
2786 files = revfiles.setdefault(rev, [])
2788 files = revfiles.setdefault(rev, [])
2787 for fn in fns:
2789 for fn in fns:
2788 flog = getfile(fn)
2790 flog = getfile(fn)
2789 try:
2791 try:
2790 fnode = ctx.filenode(fn)
2792 fnode = ctx.filenode(fn)
2791 except error.LookupError:
2793 except error.LookupError:
2792 continue
2794 continue
2793
2795
2794 copied = flog.renamed(fnode)
2796 copied = flog.renamed(fnode)
2795 copy = follow and copied and copied[0]
2797 copy = follow and copied and copied[0]
2796 if copy:
2798 if copy:
2797 copies.setdefault(rev, {})[fn] = copy
2799 copies.setdefault(rev, {})[fn] = copy
2798 if fn in skip:
2800 if fn in skip:
2799 if copy:
2801 if copy:
2800 skip[copy] = True
2802 skip[copy] = True
2801 continue
2803 continue
2802 files.append(fn)
2804 files.append(fn)
2803
2805
2804 if fn not in matches[rev]:
2806 if fn not in matches[rev]:
2805 grepbody(fn, rev, flog.read(fnode))
2807 grepbody(fn, rev, flog.read(fnode))
2806
2808
2807 pfn = copy or fn
2809 pfn = copy or fn
2808 if pfn not in matches[parent]:
2810 if pfn not in matches[parent]:
2809 try:
2811 try:
2810 fnode = pctx.filenode(pfn)
2812 fnode = pctx.filenode(pfn)
2811 grepbody(pfn, parent, flog.read(fnode))
2813 grepbody(pfn, parent, flog.read(fnode))
2812 except error.LookupError:
2814 except error.LookupError:
2813 pass
2815 pass
2814
2816
2815 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2817 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2816 rev = ctx.rev()
2818 rev = ctx.rev()
2817 parent = ctx.p1().rev()
2819 parent = ctx.p1().rev()
2818 for fn in sorted(revfiles.get(rev, [])):
2820 for fn in sorted(revfiles.get(rev, [])):
2819 states = matches[rev][fn]
2821 states = matches[rev][fn]
2820 copy = copies.get(rev, {}).get(fn)
2822 copy = copies.get(rev, {}).get(fn)
2821 if fn in skip:
2823 if fn in skip:
2822 if copy:
2824 if copy:
2823 skip[copy] = True
2825 skip[copy] = True
2824 continue
2826 continue
2825 pstates = matches.get(parent, {}).get(copy or fn, [])
2827 pstates = matches.get(parent, {}).get(copy or fn, [])
2826 if pstates or states:
2828 if pstates or states:
2827 r = display(fn, ctx, pstates, states)
2829 r = display(fn, ctx, pstates, states)
2828 found = found or r
2830 found = found or r
2829 if r and not opts.get('all'):
2831 if r and not opts.get('all'):
2830 skip[fn] = True
2832 skip[fn] = True
2831 if copy:
2833 if copy:
2832 skip[copy] = True
2834 skip[copy] = True
2833 del matches[rev]
2835 del matches[rev]
2834 del revfiles[rev]
2836 del revfiles[rev]
2835
2837
2836 return not found
2838 return not found
2837
2839
2838 @command('heads',
2840 @command('heads',
2839 [('r', 'rev', '',
2841 [('r', 'rev', '',
2840 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2842 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2841 ('t', 'topo', False, _('show topological heads only')),
2843 ('t', 'topo', False, _('show topological heads only')),
2842 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2844 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2843 ('c', 'closed', False, _('show normal and closed branch heads')),
2845 ('c', 'closed', False, _('show normal and closed branch heads')),
2844 ] + templateopts,
2846 ] + templateopts,
2845 _('[-ac] [-r STARTREV] [REV]...'))
2847 _('[-ac] [-r STARTREV] [REV]...'))
2846 def heads(ui, repo, *branchrevs, **opts):
2848 def heads(ui, repo, *branchrevs, **opts):
2847 """show current repository heads or show branch heads
2849 """show current repository heads or show branch heads
2848
2850
2849 With no arguments, show all repository branch heads.
2851 With no arguments, show all repository branch heads.
2850
2852
2851 Repository "heads" are changesets with no child changesets. They are
2853 Repository "heads" are changesets with no child changesets. They are
2852 where development generally takes place and are the usual targets
2854 where development generally takes place and are the usual targets
2853 for update and merge operations. Branch heads are changesets that have
2855 for update and merge operations. Branch heads are changesets that have
2854 no child changeset on the same branch.
2856 no child changeset on the same branch.
2855
2857
2856 If one or more REVs are given, only branch heads on the branches
2858 If one or more REVs are given, only branch heads on the branches
2857 associated with the specified changesets are shown. This means
2859 associated with the specified changesets are shown. This means
2858 that you can use :hg:`heads foo` to see the heads on a branch
2860 that you can use :hg:`heads foo` to see the heads on a branch
2859 named ``foo``.
2861 named ``foo``.
2860
2862
2861 If -c/--closed is specified, also show branch heads marked closed
2863 If -c/--closed is specified, also show branch heads marked closed
2862 (see :hg:`commit --close-branch`).
2864 (see :hg:`commit --close-branch`).
2863
2865
2864 If STARTREV is specified, only those heads that are descendants of
2866 If STARTREV is specified, only those heads that are descendants of
2865 STARTREV will be displayed.
2867 STARTREV will be displayed.
2866
2868
2867 If -t/--topo is specified, named branch mechanics will be ignored and only
2869 If -t/--topo is specified, named branch mechanics will be ignored and only
2868 changesets without children will be shown.
2870 changesets without children will be shown.
2869
2871
2870 Returns 0 if matching heads are found, 1 if not.
2872 Returns 0 if matching heads are found, 1 if not.
2871 """
2873 """
2872
2874
2873 start = None
2875 start = None
2874 if 'rev' in opts:
2876 if 'rev' in opts:
2875 start = scmutil.revsingle(repo, opts['rev'], None).node()
2877 start = scmutil.revsingle(repo, opts['rev'], None).node()
2876
2878
2877 if opts.get('topo'):
2879 if opts.get('topo'):
2878 heads = [repo[h] for h in repo.heads(start)]
2880 heads = [repo[h] for h in repo.heads(start)]
2879 else:
2881 else:
2880 heads = []
2882 heads = []
2881 for branch in repo.branchmap():
2883 for branch in repo.branchmap():
2882 heads += repo.branchheads(branch, start, opts.get('closed'))
2884 heads += repo.branchheads(branch, start, opts.get('closed'))
2883 heads = [repo[h] for h in heads]
2885 heads = [repo[h] for h in heads]
2884
2886
2885 if branchrevs:
2887 if branchrevs:
2886 branches = set(repo[br].branch() for br in branchrevs)
2888 branches = set(repo[br].branch() for br in branchrevs)
2887 heads = [h for h in heads if h.branch() in branches]
2889 heads = [h for h in heads if h.branch() in branches]
2888
2890
2889 if opts.get('active') and branchrevs:
2891 if opts.get('active') and branchrevs:
2890 dagheads = repo.heads(start)
2892 dagheads = repo.heads(start)
2891 heads = [h for h in heads if h.node() in dagheads]
2893 heads = [h for h in heads if h.node() in dagheads]
2892
2894
2893 if branchrevs:
2895 if branchrevs:
2894 haveheads = set(h.branch() for h in heads)
2896 haveheads = set(h.branch() for h in heads)
2895 if branches - haveheads:
2897 if branches - haveheads:
2896 headless = ', '.join(b for b in branches - haveheads)
2898 headless = ', '.join(b for b in branches - haveheads)
2897 msg = _('no open branch heads found on branches %s')
2899 msg = _('no open branch heads found on branches %s')
2898 if opts.get('rev'):
2900 if opts.get('rev'):
2899 msg += _(' (started at %s)' % opts['rev'])
2901 msg += _(' (started at %s)' % opts['rev'])
2900 ui.warn((msg + '\n') % headless)
2902 ui.warn((msg + '\n') % headless)
2901
2903
2902 if not heads:
2904 if not heads:
2903 return 1
2905 return 1
2904
2906
2905 heads = sorted(heads, key=lambda x: -x.rev())
2907 heads = sorted(heads, key=lambda x: -x.rev())
2906 displayer = cmdutil.show_changeset(ui, repo, opts)
2908 displayer = cmdutil.show_changeset(ui, repo, opts)
2907 for ctx in heads:
2909 for ctx in heads:
2908 displayer.show(ctx)
2910 displayer.show(ctx)
2909 displayer.close()
2911 displayer.close()
2910
2912
2911 @command('help',
2913 @command('help',
2912 [('e', 'extension', None, _('show only help for extensions')),
2914 [('e', 'extension', None, _('show only help for extensions')),
2913 ('c', 'command', None, _('show only help for commands'))],
2915 ('c', 'command', None, _('show only help for commands'))],
2914 _('[-ec] [TOPIC]'))
2916 _('[-ec] [TOPIC]'))
2915 def help_(ui, name=None, unknowncmd=False, full=True, **opts):
2917 def help_(ui, name=None, unknowncmd=False, full=True, **opts):
2916 """show help for a given topic or a help overview
2918 """show help for a given topic or a help overview
2917
2919
2918 With no arguments, print a list of commands with short help messages.
2920 With no arguments, print a list of commands with short help messages.
2919
2921
2920 Given a topic, extension, or command name, print help for that
2922 Given a topic, extension, or command name, print help for that
2921 topic.
2923 topic.
2922
2924
2923 Returns 0 if successful.
2925 Returns 0 if successful.
2924 """
2926 """
2925
2927
2926 textwidth = min(ui.termwidth(), 80) - 2
2928 textwidth = min(ui.termwidth(), 80) - 2
2927
2929
2928 def optrst(options):
2930 def optrst(options):
2929 data = []
2931 data = []
2930 multioccur = False
2932 multioccur = False
2931 for option in options:
2933 for option in options:
2932 if len(option) == 5:
2934 if len(option) == 5:
2933 shortopt, longopt, default, desc, optlabel = option
2935 shortopt, longopt, default, desc, optlabel = option
2934 else:
2936 else:
2935 shortopt, longopt, default, desc = option
2937 shortopt, longopt, default, desc = option
2936 optlabel = _("VALUE") # default label
2938 optlabel = _("VALUE") # default label
2937
2939
2938 if _("DEPRECATED") in desc and not ui.verbose:
2940 if _("DEPRECATED") in desc and not ui.verbose:
2939 continue
2941 continue
2940
2942
2941 so = ''
2943 so = ''
2942 if shortopt:
2944 if shortopt:
2943 so = '-' + shortopt
2945 so = '-' + shortopt
2944 lo = '--' + longopt
2946 lo = '--' + longopt
2945 if default:
2947 if default:
2946 desc += _(" (default: %s)") % default
2948 desc += _(" (default: %s)") % default
2947
2949
2948 if isinstance(default, list):
2950 if isinstance(default, list):
2949 lo += " %s [+]" % optlabel
2951 lo += " %s [+]" % optlabel
2950 multioccur = True
2952 multioccur = True
2951 elif (default is not None) and not isinstance(default, bool):
2953 elif (default is not None) and not isinstance(default, bool):
2952 lo += " %s" % optlabel
2954 lo += " %s" % optlabel
2953
2955
2954 data.append((so, lo, desc))
2956 data.append((so, lo, desc))
2955
2957
2956 rst = minirst.maketable(data, 1)
2958 rst = minirst.maketable(data, 1)
2957
2959
2958 if multioccur:
2960 if multioccur:
2959 rst += _("\n[+] marked option can be specified multiple times\n")
2961 rst += _("\n[+] marked option can be specified multiple times\n")
2960
2962
2961 return rst
2963 return rst
2962
2964
2963 # list all option lists
2965 # list all option lists
2964 def opttext(optlist, width):
2966 def opttext(optlist, width):
2965 rst = ''
2967 rst = ''
2966 if not optlist:
2968 if not optlist:
2967 return ''
2969 return ''
2968
2970
2969 for title, options in optlist:
2971 for title, options in optlist:
2970 rst += '\n%s\n' % title
2972 rst += '\n%s\n' % title
2971 if options:
2973 if options:
2972 rst += "\n"
2974 rst += "\n"
2973 rst += optrst(options)
2975 rst += optrst(options)
2974 rst += '\n'
2976 rst += '\n'
2975
2977
2976 return '\n' + minirst.format(rst, width)
2978 return '\n' + minirst.format(rst, width)
2977
2979
2978 def addglobalopts(optlist, aliases):
2980 def addglobalopts(optlist, aliases):
2979 if ui.quiet:
2981 if ui.quiet:
2980 return []
2982 return []
2981
2983
2982 if ui.verbose:
2984 if ui.verbose:
2983 optlist.append((_("global options:"), globalopts))
2985 optlist.append((_("global options:"), globalopts))
2984 if name == 'shortlist':
2986 if name == 'shortlist':
2985 optlist.append((_('use "hg help" for the full list '
2987 optlist.append((_('use "hg help" for the full list '
2986 'of commands'), ()))
2988 'of commands'), ()))
2987 else:
2989 else:
2988 if name == 'shortlist':
2990 if name == 'shortlist':
2989 msg = _('use "hg help" for the full list of commands '
2991 msg = _('use "hg help" for the full list of commands '
2990 'or "hg -v" for details')
2992 'or "hg -v" for details')
2991 elif name and not full:
2993 elif name and not full:
2992 msg = _('use "hg help %s" to show the full help text' % name)
2994 msg = _('use "hg help %s" to show the full help text' % name)
2993 elif aliases:
2995 elif aliases:
2994 msg = _('use "hg -v help%s" to show builtin aliases and '
2996 msg = _('use "hg -v help%s" to show builtin aliases and '
2995 'global options') % (name and " " + name or "")
2997 'global options') % (name and " " + name or "")
2996 else:
2998 else:
2997 msg = _('use "hg -v help %s" to show more info') % name
2999 msg = _('use "hg -v help %s" to show more info') % name
2998 optlist.append((msg, ()))
3000 optlist.append((msg, ()))
2999
3001
3000 def helpcmd(name):
3002 def helpcmd(name):
3001 try:
3003 try:
3002 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
3004 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
3003 except error.AmbiguousCommand, inst:
3005 except error.AmbiguousCommand, inst:
3004 # py3k fix: except vars can't be used outside the scope of the
3006 # py3k fix: except vars can't be used outside the scope of the
3005 # except block, nor can be used inside a lambda. python issue4617
3007 # except block, nor can be used inside a lambda. python issue4617
3006 prefix = inst.args[0]
3008 prefix = inst.args[0]
3007 select = lambda c: c.lstrip('^').startswith(prefix)
3009 select = lambda c: c.lstrip('^').startswith(prefix)
3008 helplist(select)
3010 helplist(select)
3009 return
3011 return
3010
3012
3011 # check if it's an invalid alias and display its error if it is
3013 # check if it's an invalid alias and display its error if it is
3012 if getattr(entry[0], 'badalias', False):
3014 if getattr(entry[0], 'badalias', False):
3013 if not unknowncmd:
3015 if not unknowncmd:
3014 entry[0](ui)
3016 entry[0](ui)
3015 return
3017 return
3016
3018
3017 rst = ""
3019 rst = ""
3018
3020
3019 # synopsis
3021 # synopsis
3020 if len(entry) > 2:
3022 if len(entry) > 2:
3021 if entry[2].startswith('hg'):
3023 if entry[2].startswith('hg'):
3022 rst += "%s\n" % entry[2]
3024 rst += "%s\n" % entry[2]
3023 else:
3025 else:
3024 rst += 'hg %s %s\n' % (aliases[0], entry[2])
3026 rst += 'hg %s %s\n' % (aliases[0], entry[2])
3025 else:
3027 else:
3026 rst += 'hg %s\n' % aliases[0]
3028 rst += 'hg %s\n' % aliases[0]
3027
3029
3028 # aliases
3030 # aliases
3029 if full and not ui.quiet and len(aliases) > 1:
3031 if full and not ui.quiet and len(aliases) > 1:
3030 rst += _("\naliases: %s\n") % ', '.join(aliases[1:])
3032 rst += _("\naliases: %s\n") % ', '.join(aliases[1:])
3031
3033
3032 # description
3034 # description
3033 doc = gettext(entry[0].__doc__)
3035 doc = gettext(entry[0].__doc__)
3034 if not doc:
3036 if not doc:
3035 doc = _("(no help text available)")
3037 doc = _("(no help text available)")
3036 if util.safehasattr(entry[0], 'definition'): # aliased command
3038 if util.safehasattr(entry[0], 'definition'): # aliased command
3037 if entry[0].definition.startswith('!'): # shell alias
3039 if entry[0].definition.startswith('!'): # shell alias
3038 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
3040 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
3039 else:
3041 else:
3040 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
3042 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
3041 if ui.quiet or not full:
3043 if ui.quiet or not full:
3042 doc = doc.splitlines()[0]
3044 doc = doc.splitlines()[0]
3043 rst += "\n" + doc + "\n"
3045 rst += "\n" + doc + "\n"
3044
3046
3045 # check if this command shadows a non-trivial (multi-line)
3047 # check if this command shadows a non-trivial (multi-line)
3046 # extension help text
3048 # extension help text
3047 try:
3049 try:
3048 mod = extensions.find(name)
3050 mod = extensions.find(name)
3049 doc = gettext(mod.__doc__) or ''
3051 doc = gettext(mod.__doc__) or ''
3050 if '\n' in doc.strip():
3052 if '\n' in doc.strip():
3051 msg = _('use "hg help -e %s" to show help for '
3053 msg = _('use "hg help -e %s" to show help for '
3052 'the %s extension') % (name, name)
3054 'the %s extension') % (name, name)
3053 rst += '\n%s\n' % msg
3055 rst += '\n%s\n' % msg
3054 except KeyError:
3056 except KeyError:
3055 pass
3057 pass
3056
3058
3057 # options
3059 # options
3058 if not ui.quiet and entry[1]:
3060 if not ui.quiet and entry[1]:
3059 rst += '\noptions:\n\n'
3061 rst += '\noptions:\n\n'
3060 rst += optrst(entry[1])
3062 rst += optrst(entry[1])
3061
3063
3062 if ui.verbose:
3064 if ui.verbose:
3063 rst += '\nglobal options:\n\n'
3065 rst += '\nglobal options:\n\n'
3064 rst += optrst(globalopts)
3066 rst += optrst(globalopts)
3065
3067
3066 keep = ui.verbose and ['verbose'] or []
3068 keep = ui.verbose and ['verbose'] or []
3067 formatted, pruned = minirst.format(rst, textwidth, keep=keep)
3069 formatted, pruned = minirst.format(rst, textwidth, keep=keep)
3068 ui.write(formatted)
3070 ui.write(formatted)
3069
3071
3070 if not ui.verbose:
3072 if not ui.verbose:
3071 if not full:
3073 if not full:
3072 ui.write(_('\nuse "hg help %s" to show the full help text\n')
3074 ui.write(_('\nuse "hg help %s" to show the full help text\n')
3073 % name)
3075 % name)
3074 elif not ui.quiet:
3076 elif not ui.quiet:
3075 ui.write(_('\nuse "hg -v help %s" to show more info\n') % name)
3077 ui.write(_('\nuse "hg -v help %s" to show more info\n') % name)
3076
3078
3077
3079
3078 def helplist(select=None):
3080 def helplist(select=None):
3079 # list of commands
3081 # list of commands
3080 if name == "shortlist":
3082 if name == "shortlist":
3081 header = _('basic commands:\n\n')
3083 header = _('basic commands:\n\n')
3082 else:
3084 else:
3083 header = _('list of commands:\n\n')
3085 header = _('list of commands:\n\n')
3084
3086
3085 h = {}
3087 h = {}
3086 cmds = {}
3088 cmds = {}
3087 for c, e in table.iteritems():
3089 for c, e in table.iteritems():
3088 f = c.split("|", 1)[0]
3090 f = c.split("|", 1)[0]
3089 if select and not select(f):
3091 if select and not select(f):
3090 continue
3092 continue
3091 if (not select and name != 'shortlist' and
3093 if (not select and name != 'shortlist' and
3092 e[0].__module__ != __name__):
3094 e[0].__module__ != __name__):
3093 continue
3095 continue
3094 if name == "shortlist" and not f.startswith("^"):
3096 if name == "shortlist" and not f.startswith("^"):
3095 continue
3097 continue
3096 f = f.lstrip("^")
3098 f = f.lstrip("^")
3097 if not ui.debugflag and f.startswith("debug"):
3099 if not ui.debugflag and f.startswith("debug"):
3098 continue
3100 continue
3099 doc = e[0].__doc__
3101 doc = e[0].__doc__
3100 if doc and 'DEPRECATED' in doc and not ui.verbose:
3102 if doc and 'DEPRECATED' in doc and not ui.verbose:
3101 continue
3103 continue
3102 doc = gettext(doc)
3104 doc = gettext(doc)
3103 if not doc:
3105 if not doc:
3104 doc = _("(no help text available)")
3106 doc = _("(no help text available)")
3105 h[f] = doc.splitlines()[0].rstrip()
3107 h[f] = doc.splitlines()[0].rstrip()
3106 cmds[f] = c.lstrip("^")
3108 cmds[f] = c.lstrip("^")
3107
3109
3108 if not h:
3110 if not h:
3109 ui.status(_('no commands defined\n'))
3111 ui.status(_('no commands defined\n'))
3110 return
3112 return
3111
3113
3112 ui.status(header)
3114 ui.status(header)
3113 fns = sorted(h)
3115 fns = sorted(h)
3114 m = max(map(len, fns))
3116 m = max(map(len, fns))
3115 for f in fns:
3117 for f in fns:
3116 if ui.verbose:
3118 if ui.verbose:
3117 commands = cmds[f].replace("|",", ")
3119 commands = cmds[f].replace("|",", ")
3118 ui.write(" %s:\n %s\n"%(commands, h[f]))
3120 ui.write(" %s:\n %s\n"%(commands, h[f]))
3119 else:
3121 else:
3120 ui.write('%s\n' % (util.wrap(h[f], textwidth,
3122 ui.write('%s\n' % (util.wrap(h[f], textwidth,
3121 initindent=' %-*s ' % (m, f),
3123 initindent=' %-*s ' % (m, f),
3122 hangindent=' ' * (m + 4))))
3124 hangindent=' ' * (m + 4))))
3123
3125
3124 if not name:
3126 if not name:
3125 text = help.listexts(_('enabled extensions:'), extensions.enabled())
3127 text = help.listexts(_('enabled extensions:'), extensions.enabled())
3126 if text:
3128 if text:
3127 ui.write("\n%s" % minirst.format(text, textwidth))
3129 ui.write("\n%s" % minirst.format(text, textwidth))
3128
3130
3129 ui.write(_("\nadditional help topics:\n\n"))
3131 ui.write(_("\nadditional help topics:\n\n"))
3130 topics = []
3132 topics = []
3131 for names, header, doc in help.helptable:
3133 for names, header, doc in help.helptable:
3132 topics.append((sorted(names, key=len, reverse=True)[0], header))
3134 topics.append((sorted(names, key=len, reverse=True)[0], header))
3133 topics_len = max([len(s[0]) for s in topics])
3135 topics_len = max([len(s[0]) for s in topics])
3134 for t, desc in topics:
3136 for t, desc in topics:
3135 ui.write(" %-*s %s\n" % (topics_len, t, desc))
3137 ui.write(" %-*s %s\n" % (topics_len, t, desc))
3136
3138
3137 optlist = []
3139 optlist = []
3138 addglobalopts(optlist, True)
3140 addglobalopts(optlist, True)
3139 ui.write(opttext(optlist, textwidth))
3141 ui.write(opttext(optlist, textwidth))
3140
3142
3141 def helptopic(name):
3143 def helptopic(name):
3142 for names, header, doc in help.helptable:
3144 for names, header, doc in help.helptable:
3143 if name in names:
3145 if name in names:
3144 break
3146 break
3145 else:
3147 else:
3146 raise error.UnknownCommand(name)
3148 raise error.UnknownCommand(name)
3147
3149
3148 # description
3150 # description
3149 if not doc:
3151 if not doc:
3150 doc = _("(no help text available)")
3152 doc = _("(no help text available)")
3151 if util.safehasattr(doc, '__call__'):
3153 if util.safehasattr(doc, '__call__'):
3152 doc = doc()
3154 doc = doc()
3153
3155
3154 ui.write("%s\n\n" % header)
3156 ui.write("%s\n\n" % header)
3155 ui.write("%s" % minirst.format(doc, textwidth, indent=4))
3157 ui.write("%s" % minirst.format(doc, textwidth, indent=4))
3156 try:
3158 try:
3157 cmdutil.findcmd(name, table)
3159 cmdutil.findcmd(name, table)
3158 ui.write(_('\nuse "hg help -c %s" to see help for '
3160 ui.write(_('\nuse "hg help -c %s" to see help for '
3159 'the %s command\n') % (name, name))
3161 'the %s command\n') % (name, name))
3160 except error.UnknownCommand:
3162 except error.UnknownCommand:
3161 pass
3163 pass
3162
3164
3163 def helpext(name):
3165 def helpext(name):
3164 try:
3166 try:
3165 mod = extensions.find(name)
3167 mod = extensions.find(name)
3166 doc = gettext(mod.__doc__) or _('no help text available')
3168 doc = gettext(mod.__doc__) or _('no help text available')
3167 except KeyError:
3169 except KeyError:
3168 mod = None
3170 mod = None
3169 doc = extensions.disabledext(name)
3171 doc = extensions.disabledext(name)
3170 if not doc:
3172 if not doc:
3171 raise error.UnknownCommand(name)
3173 raise error.UnknownCommand(name)
3172
3174
3173 if '\n' not in doc:
3175 if '\n' not in doc:
3174 head, tail = doc, ""
3176 head, tail = doc, ""
3175 else:
3177 else:
3176 head, tail = doc.split('\n', 1)
3178 head, tail = doc.split('\n', 1)
3177 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
3179 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
3178 if tail:
3180 if tail:
3179 ui.write(minirst.format(tail, textwidth))
3181 ui.write(minirst.format(tail, textwidth))
3180 ui.status('\n')
3182 ui.status('\n')
3181
3183
3182 if mod:
3184 if mod:
3183 try:
3185 try:
3184 ct = mod.cmdtable
3186 ct = mod.cmdtable
3185 except AttributeError:
3187 except AttributeError:
3186 ct = {}
3188 ct = {}
3187 modcmds = set([c.split('|', 1)[0] for c in ct])
3189 modcmds = set([c.split('|', 1)[0] for c in ct])
3188 helplist(modcmds.__contains__)
3190 helplist(modcmds.__contains__)
3189 else:
3191 else:
3190 ui.write(_('use "hg help extensions" for information on enabling '
3192 ui.write(_('use "hg help extensions" for information on enabling '
3191 'extensions\n'))
3193 'extensions\n'))
3192
3194
3193 def helpextcmd(name):
3195 def helpextcmd(name):
3194 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
3196 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
3195 doc = gettext(mod.__doc__).splitlines()[0]
3197 doc = gettext(mod.__doc__).splitlines()[0]
3196
3198
3197 msg = help.listexts(_("'%s' is provided by the following "
3199 msg = help.listexts(_("'%s' is provided by the following "
3198 "extension:") % cmd, {ext: doc}, indent=4)
3200 "extension:") % cmd, {ext: doc}, indent=4)
3199 ui.write(minirst.format(msg, textwidth))
3201 ui.write(minirst.format(msg, textwidth))
3200 ui.write('\n')
3202 ui.write('\n')
3201 ui.write(_('use "hg help extensions" for information on enabling '
3203 ui.write(_('use "hg help extensions" for information on enabling '
3202 'extensions\n'))
3204 'extensions\n'))
3203
3205
3204 if name and name != 'shortlist':
3206 if name and name != 'shortlist':
3205 i = None
3207 i = None
3206 if unknowncmd:
3208 if unknowncmd:
3207 queries = (helpextcmd,)
3209 queries = (helpextcmd,)
3208 elif opts.get('extension'):
3210 elif opts.get('extension'):
3209 queries = (helpext,)
3211 queries = (helpext,)
3210 elif opts.get('command'):
3212 elif opts.get('command'):
3211 queries = (helpcmd,)
3213 queries = (helpcmd,)
3212 else:
3214 else:
3213 queries = (helptopic, helpcmd, helpext, helpextcmd)
3215 queries = (helptopic, helpcmd, helpext, helpextcmd)
3214 for f in queries:
3216 for f in queries:
3215 try:
3217 try:
3216 f(name)
3218 f(name)
3217 i = None
3219 i = None
3218 break
3220 break
3219 except error.UnknownCommand, inst:
3221 except error.UnknownCommand, inst:
3220 i = inst
3222 i = inst
3221 if i:
3223 if i:
3222 raise i
3224 raise i
3223 else:
3225 else:
3224 # program name
3226 # program name
3225 ui.status(_("Mercurial Distributed SCM\n"))
3227 ui.status(_("Mercurial Distributed SCM\n"))
3226 ui.status('\n')
3228 ui.status('\n')
3227 helplist()
3229 helplist()
3228
3230
3229
3231
3230 @command('identify|id',
3232 @command('identify|id',
3231 [('r', 'rev', '',
3233 [('r', 'rev', '',
3232 _('identify the specified revision'), _('REV')),
3234 _('identify the specified revision'), _('REV')),
3233 ('n', 'num', None, _('show local revision number')),
3235 ('n', 'num', None, _('show local revision number')),
3234 ('i', 'id', None, _('show global revision id')),
3236 ('i', 'id', None, _('show global revision id')),
3235 ('b', 'branch', None, _('show branch')),
3237 ('b', 'branch', None, _('show branch')),
3236 ('t', 'tags', None, _('show tags')),
3238 ('t', 'tags', None, _('show tags')),
3237 ('B', 'bookmarks', None, _('show bookmarks'))],
3239 ('B', 'bookmarks', None, _('show bookmarks'))],
3238 _('[-nibtB] [-r REV] [SOURCE]'))
3240 _('[-nibtB] [-r REV] [SOURCE]'))
3239 def identify(ui, repo, source=None, rev=None,
3241 def identify(ui, repo, source=None, rev=None,
3240 num=None, id=None, branch=None, tags=None, bookmarks=None):
3242 num=None, id=None, branch=None, tags=None, bookmarks=None):
3241 """identify the working copy or specified revision
3243 """identify the working copy or specified revision
3242
3244
3243 Print a summary identifying the repository state at REV using one or
3245 Print a summary identifying the repository state at REV using one or
3244 two parent hash identifiers, followed by a "+" if the working
3246 two parent hash identifiers, followed by a "+" if the working
3245 directory has uncommitted changes, the branch name (if not default),
3247 directory has uncommitted changes, the branch name (if not default),
3246 a list of tags, and a list of bookmarks.
3248 a list of tags, and a list of bookmarks.
3247
3249
3248 When REV is not given, print a summary of the current state of the
3250 When REV is not given, print a summary of the current state of the
3249 repository.
3251 repository.
3250
3252
3251 Specifying a path to a repository root or Mercurial bundle will
3253 Specifying a path to a repository root or Mercurial bundle will
3252 cause lookup to operate on that repository/bundle.
3254 cause lookup to operate on that repository/bundle.
3253
3255
3254 .. container:: verbose
3256 .. container:: verbose
3255
3257
3256 Examples:
3258 Examples:
3257
3259
3258 - generate a build identifier for the working directory::
3260 - generate a build identifier for the working directory::
3259
3261
3260 hg id --id > build-id.dat
3262 hg id --id > build-id.dat
3261
3263
3262 - find the revision corresponding to a tag::
3264 - find the revision corresponding to a tag::
3263
3265
3264 hg id -n -r 1.3
3266 hg id -n -r 1.3
3265
3267
3266 - check the most recent revision of a remote repository::
3268 - check the most recent revision of a remote repository::
3267
3269
3268 hg id -r tip http://selenic.com/hg/
3270 hg id -r tip http://selenic.com/hg/
3269
3271
3270 Returns 0 if successful.
3272 Returns 0 if successful.
3271 """
3273 """
3272
3274
3273 if not repo and not source:
3275 if not repo and not source:
3274 raise util.Abort(_("there is no Mercurial repository here "
3276 raise util.Abort(_("there is no Mercurial repository here "
3275 "(.hg not found)"))
3277 "(.hg not found)"))
3276
3278
3277 hexfunc = ui.debugflag and hex or short
3279 hexfunc = ui.debugflag and hex or short
3278 default = not (num or id or branch or tags or bookmarks)
3280 default = not (num or id or branch or tags or bookmarks)
3279 output = []
3281 output = []
3280 revs = []
3282 revs = []
3281
3283
3282 if source:
3284 if source:
3283 source, branches = hg.parseurl(ui.expandpath(source))
3285 source, branches = hg.parseurl(ui.expandpath(source))
3284 repo = hg.peer(ui, {}, source)
3286 repo = hg.peer(ui, {}, source)
3285 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3287 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3286
3288
3287 if not repo.local():
3289 if not repo.local():
3288 if num or branch or tags:
3290 if num or branch or tags:
3289 raise util.Abort(
3291 raise util.Abort(
3290 _("can't query remote revision number, branch, or tags"))
3292 _("can't query remote revision number, branch, or tags"))
3291 if not rev and revs:
3293 if not rev and revs:
3292 rev = revs[0]
3294 rev = revs[0]
3293 if not rev:
3295 if not rev:
3294 rev = "tip"
3296 rev = "tip"
3295
3297
3296 remoterev = repo.lookup(rev)
3298 remoterev = repo.lookup(rev)
3297 if default or id:
3299 if default or id:
3298 output = [hexfunc(remoterev)]
3300 output = [hexfunc(remoterev)]
3299
3301
3300 def getbms():
3302 def getbms():
3301 bms = []
3303 bms = []
3302
3304
3303 if 'bookmarks' in repo.listkeys('namespaces'):
3305 if 'bookmarks' in repo.listkeys('namespaces'):
3304 hexremoterev = hex(remoterev)
3306 hexremoterev = hex(remoterev)
3305 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
3307 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
3306 if bmr == hexremoterev]
3308 if bmr == hexremoterev]
3307
3309
3308 return bms
3310 return bms
3309
3311
3310 if bookmarks:
3312 if bookmarks:
3311 output.extend(getbms())
3313 output.extend(getbms())
3312 elif default and not ui.quiet:
3314 elif default and not ui.quiet:
3313 # multiple bookmarks for a single parent separated by '/'
3315 # multiple bookmarks for a single parent separated by '/'
3314 bm = '/'.join(getbms())
3316 bm = '/'.join(getbms())
3315 if bm:
3317 if bm:
3316 output.append(bm)
3318 output.append(bm)
3317 else:
3319 else:
3318 if not rev:
3320 if not rev:
3319 ctx = repo[None]
3321 ctx = repo[None]
3320 parents = ctx.parents()
3322 parents = ctx.parents()
3321 changed = ""
3323 changed = ""
3322 if default or id or num:
3324 if default or id or num:
3323 changed = util.any(repo.status()) and "+" or ""
3325 changed = util.any(repo.status()) and "+" or ""
3324 if default or id:
3326 if default or id:
3325 output = ["%s%s" %
3327 output = ["%s%s" %
3326 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3328 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3327 if num:
3329 if num:
3328 output.append("%s%s" %
3330 output.append("%s%s" %
3329 ('+'.join([str(p.rev()) for p in parents]), changed))
3331 ('+'.join([str(p.rev()) for p in parents]), changed))
3330 else:
3332 else:
3331 ctx = scmutil.revsingle(repo, rev)
3333 ctx = scmutil.revsingle(repo, rev)
3332 if default or id:
3334 if default or id:
3333 output = [hexfunc(ctx.node())]
3335 output = [hexfunc(ctx.node())]
3334 if num:
3336 if num:
3335 output.append(str(ctx.rev()))
3337 output.append(str(ctx.rev()))
3336
3338
3337 if default and not ui.quiet:
3339 if default and not ui.quiet:
3338 b = ctx.branch()
3340 b = ctx.branch()
3339 if b != 'default':
3341 if b != 'default':
3340 output.append("(%s)" % b)
3342 output.append("(%s)" % b)
3341
3343
3342 # multiple tags for a single parent separated by '/'
3344 # multiple tags for a single parent separated by '/'
3343 t = '/'.join(ctx.tags())
3345 t = '/'.join(ctx.tags())
3344 if t:
3346 if t:
3345 output.append(t)
3347 output.append(t)
3346
3348
3347 # multiple bookmarks for a single parent separated by '/'
3349 # multiple bookmarks for a single parent separated by '/'
3348 bm = '/'.join(ctx.bookmarks())
3350 bm = '/'.join(ctx.bookmarks())
3349 if bm:
3351 if bm:
3350 output.append(bm)
3352 output.append(bm)
3351 else:
3353 else:
3352 if branch:
3354 if branch:
3353 output.append(ctx.branch())
3355 output.append(ctx.branch())
3354
3356
3355 if tags:
3357 if tags:
3356 output.extend(ctx.tags())
3358 output.extend(ctx.tags())
3357
3359
3358 if bookmarks:
3360 if bookmarks:
3359 output.extend(ctx.bookmarks())
3361 output.extend(ctx.bookmarks())
3360
3362
3361 ui.write("%s\n" % ' '.join(output))
3363 ui.write("%s\n" % ' '.join(output))
3362
3364
3363 @command('import|patch',
3365 @command('import|patch',
3364 [('p', 'strip', 1,
3366 [('p', 'strip', 1,
3365 _('directory strip option for patch. This has the same '
3367 _('directory strip option for patch. This has the same '
3366 'meaning as the corresponding patch option'), _('NUM')),
3368 'meaning as the corresponding patch option'), _('NUM')),
3367 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3369 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3368 ('e', 'edit', False, _('invoke editor on commit messages')),
3370 ('e', 'edit', False, _('invoke editor on commit messages')),
3369 ('f', 'force', None, _('skip check for outstanding uncommitted changes')),
3371 ('f', 'force', None, _('skip check for outstanding uncommitted changes')),
3370 ('', 'no-commit', None,
3372 ('', 'no-commit', None,
3371 _("don't commit, just update the working directory")),
3373 _("don't commit, just update the working directory")),
3372 ('', 'bypass', None,
3374 ('', 'bypass', None,
3373 _("apply patch without touching the working directory")),
3375 _("apply patch without touching the working directory")),
3374 ('', 'exact', None,
3376 ('', 'exact', None,
3375 _('apply patch to the nodes from which it was generated')),
3377 _('apply patch to the nodes from which it was generated')),
3376 ('', 'import-branch', None,
3378 ('', 'import-branch', None,
3377 _('use any branch information in patch (implied by --exact)'))] +
3379 _('use any branch information in patch (implied by --exact)'))] +
3378 commitopts + commitopts2 + similarityopts,
3380 commitopts + commitopts2 + similarityopts,
3379 _('[OPTION]... PATCH...'))
3381 _('[OPTION]... PATCH...'))
3380 def import_(ui, repo, patch1=None, *patches, **opts):
3382 def import_(ui, repo, patch1=None, *patches, **opts):
3381 """import an ordered set of patches
3383 """import an ordered set of patches
3382
3384
3383 Import a list of patches and commit them individually (unless
3385 Import a list of patches and commit them individually (unless
3384 --no-commit is specified).
3386 --no-commit is specified).
3385
3387
3386 If there are outstanding changes in the working directory, import
3388 If there are outstanding changes in the working directory, import
3387 will abort unless given the -f/--force flag.
3389 will abort unless given the -f/--force flag.
3388
3390
3389 You can import a patch straight from a mail message. Even patches
3391 You can import a patch straight from a mail message. Even patches
3390 as attachments work (to use the body part, it must have type
3392 as attachments work (to use the body part, it must have type
3391 text/plain or text/x-patch). From and Subject headers of email
3393 text/plain or text/x-patch). From and Subject headers of email
3392 message are used as default committer and commit message. All
3394 message are used as default committer and commit message. All
3393 text/plain body parts before first diff are added to commit
3395 text/plain body parts before first diff are added to commit
3394 message.
3396 message.
3395
3397
3396 If the imported patch was generated by :hg:`export`, user and
3398 If the imported patch was generated by :hg:`export`, user and
3397 description from patch override values from message headers and
3399 description from patch override values from message headers and
3398 body. Values given on command line with -m/--message and -u/--user
3400 body. Values given on command line with -m/--message and -u/--user
3399 override these.
3401 override these.
3400
3402
3401 If --exact is specified, import will set the working directory to
3403 If --exact is specified, import will set the working directory to
3402 the parent of each patch before applying it, and will abort if the
3404 the parent of each patch before applying it, and will abort if the
3403 resulting changeset has a different ID than the one recorded in
3405 resulting changeset has a different ID than the one recorded in
3404 the patch. This may happen due to character set problems or other
3406 the patch. This may happen due to character set problems or other
3405 deficiencies in the text patch format.
3407 deficiencies in the text patch format.
3406
3408
3407 Use --bypass to apply and commit patches directly to the
3409 Use --bypass to apply and commit patches directly to the
3408 repository, not touching the working directory. Without --exact,
3410 repository, not touching the working directory. Without --exact,
3409 patches will be applied on top of the working directory parent
3411 patches will be applied on top of the working directory parent
3410 revision.
3412 revision.
3411
3413
3412 With -s/--similarity, hg will attempt to discover renames and
3414 With -s/--similarity, hg will attempt to discover renames and
3413 copies in the patch in the same way as 'addremove'.
3415 copies in the patch in the same way as 'addremove'.
3414
3416
3415 To read a patch from standard input, use "-" as the patch name. If
3417 To read a patch from standard input, use "-" as the patch name. If
3416 a URL is specified, the patch will be downloaded from it.
3418 a URL is specified, the patch will be downloaded from it.
3417 See :hg:`help dates` for a list of formats valid for -d/--date.
3419 See :hg:`help dates` for a list of formats valid for -d/--date.
3418
3420
3419 .. container:: verbose
3421 .. container:: verbose
3420
3422
3421 Examples:
3423 Examples:
3422
3424
3423 - import a traditional patch from a website and detect renames::
3425 - import a traditional patch from a website and detect renames::
3424
3426
3425 hg import -s 80 http://example.com/bugfix.patch
3427 hg import -s 80 http://example.com/bugfix.patch
3426
3428
3427 - import a changeset from an hgweb server::
3429 - import a changeset from an hgweb server::
3428
3430
3429 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3431 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3430
3432
3431 - import all the patches in an Unix-style mbox::
3433 - import all the patches in an Unix-style mbox::
3432
3434
3433 hg import incoming-patches.mbox
3435 hg import incoming-patches.mbox
3434
3436
3435 - attempt to exactly restore an exported changeset (not always
3437 - attempt to exactly restore an exported changeset (not always
3436 possible)::
3438 possible)::
3437
3439
3438 hg import --exact proposed-fix.patch
3440 hg import --exact proposed-fix.patch
3439
3441
3440 Returns 0 on success.
3442 Returns 0 on success.
3441 """
3443 """
3442
3444
3443 if not patch1:
3445 if not patch1:
3444 raise util.Abort(_('need at least one patch to import'))
3446 raise util.Abort(_('need at least one patch to import'))
3445
3447
3446 patches = (patch1,) + patches
3448 patches = (patch1,) + patches
3447
3449
3448 date = opts.get('date')
3450 date = opts.get('date')
3449 if date:
3451 if date:
3450 opts['date'] = util.parsedate(date)
3452 opts['date'] = util.parsedate(date)
3451
3453
3452 editor = cmdutil.commiteditor
3454 editor = cmdutil.commiteditor
3453 if opts.get('edit'):
3455 if opts.get('edit'):
3454 editor = cmdutil.commitforceeditor
3456 editor = cmdutil.commitforceeditor
3455
3457
3456 update = not opts.get('bypass')
3458 update = not opts.get('bypass')
3457 if not update and opts.get('no_commit'):
3459 if not update and opts.get('no_commit'):
3458 raise util.Abort(_('cannot use --no-commit with --bypass'))
3460 raise util.Abort(_('cannot use --no-commit with --bypass'))
3459 try:
3461 try:
3460 sim = float(opts.get('similarity') or 0)
3462 sim = float(opts.get('similarity') or 0)
3461 except ValueError:
3463 except ValueError:
3462 raise util.Abort(_('similarity must be a number'))
3464 raise util.Abort(_('similarity must be a number'))
3463 if sim < 0 or sim > 100:
3465 if sim < 0 or sim > 100:
3464 raise util.Abort(_('similarity must be between 0 and 100'))
3466 raise util.Abort(_('similarity must be between 0 and 100'))
3465 if sim and not update:
3467 if sim and not update:
3466 raise util.Abort(_('cannot use --similarity with --bypass'))
3468 raise util.Abort(_('cannot use --similarity with --bypass'))
3467
3469
3468 if (opts.get('exact') or not opts.get('force')) and update:
3470 if (opts.get('exact') or not opts.get('force')) and update:
3469 cmdutil.bailifchanged(repo)
3471 cmdutil.bailifchanged(repo)
3470
3472
3471 base = opts["base"]
3473 base = opts["base"]
3472 strip = opts["strip"]
3474 strip = opts["strip"]
3473 wlock = lock = tr = None
3475 wlock = lock = tr = None
3474 msgs = []
3476 msgs = []
3475
3477
3476 def checkexact(repo, n, nodeid):
3478 def checkexact(repo, n, nodeid):
3477 if opts.get('exact') and hex(n) != nodeid:
3479 if opts.get('exact') and hex(n) != nodeid:
3478 repo.rollback()
3480 repo.rollback()
3479 raise util.Abort(_('patch is damaged or loses information'))
3481 raise util.Abort(_('patch is damaged or loses information'))
3480
3482
3481 def tryone(ui, hunk, parents):
3483 def tryone(ui, hunk, parents):
3482 tmpname, message, user, date, branch, nodeid, p1, p2 = \
3484 tmpname, message, user, date, branch, nodeid, p1, p2 = \
3483 patch.extract(ui, hunk)
3485 patch.extract(ui, hunk)
3484
3486
3485 if not tmpname:
3487 if not tmpname:
3486 return (None, None)
3488 return (None, None)
3487 msg = _('applied to working directory')
3489 msg = _('applied to working directory')
3488
3490
3489 try:
3491 try:
3490 cmdline_message = cmdutil.logmessage(ui, opts)
3492 cmdline_message = cmdutil.logmessage(ui, opts)
3491 if cmdline_message:
3493 if cmdline_message:
3492 # pickup the cmdline msg
3494 # pickup the cmdline msg
3493 message = cmdline_message
3495 message = cmdline_message
3494 elif message:
3496 elif message:
3495 # pickup the patch msg
3497 # pickup the patch msg
3496 message = message.strip()
3498 message = message.strip()
3497 else:
3499 else:
3498 # launch the editor
3500 # launch the editor
3499 message = None
3501 message = None
3500 ui.debug('message:\n%s\n' % message)
3502 ui.debug('message:\n%s\n' % message)
3501
3503
3502 if len(parents) == 1:
3504 if len(parents) == 1:
3503 parents.append(repo[nullid])
3505 parents.append(repo[nullid])
3504 if opts.get('exact'):
3506 if opts.get('exact'):
3505 if not nodeid or not p1:
3507 if not nodeid or not p1:
3506 raise util.Abort(_('not a Mercurial patch'))
3508 raise util.Abort(_('not a Mercurial patch'))
3507 p1 = repo[p1]
3509 p1 = repo[p1]
3508 p2 = repo[p2 or nullid]
3510 p2 = repo[p2 or nullid]
3509 elif p2:
3511 elif p2:
3510 try:
3512 try:
3511 p1 = repo[p1]
3513 p1 = repo[p1]
3512 p2 = repo[p2]
3514 p2 = repo[p2]
3513 # Without any options, consider p2 only if the
3515 # Without any options, consider p2 only if the
3514 # patch is being applied on top of the recorded
3516 # patch is being applied on top of the recorded
3515 # first parent.
3517 # first parent.
3516 if p1 != parents[0]:
3518 if p1 != parents[0]:
3517 p1 = parents[0]
3519 p1 = parents[0]
3518 p2 = repo[nullid]
3520 p2 = repo[nullid]
3519 except error.RepoError:
3521 except error.RepoError:
3520 p1, p2 = parents
3522 p1, p2 = parents
3521 else:
3523 else:
3522 p1, p2 = parents
3524 p1, p2 = parents
3523
3525
3524 n = None
3526 n = None
3525 if update:
3527 if update:
3526 if p1 != parents[0]:
3528 if p1 != parents[0]:
3527 hg.clean(repo, p1.node())
3529 hg.clean(repo, p1.node())
3528 if p2 != parents[1]:
3530 if p2 != parents[1]:
3529 repo.dirstate.setparents(p1.node(), p2.node())
3531 repo.dirstate.setparents(p1.node(), p2.node())
3530
3532
3531 if opts.get('exact') or opts.get('import_branch'):
3533 if opts.get('exact') or opts.get('import_branch'):
3532 repo.dirstate.setbranch(branch or 'default')
3534 repo.dirstate.setbranch(branch or 'default')
3533
3535
3534 files = set()
3536 files = set()
3535 patch.patch(ui, repo, tmpname, strip=strip, files=files,
3537 patch.patch(ui, repo, tmpname, strip=strip, files=files,
3536 eolmode=None, similarity=sim / 100.0)
3538 eolmode=None, similarity=sim / 100.0)
3537 files = list(files)
3539 files = list(files)
3538 if opts.get('no_commit'):
3540 if opts.get('no_commit'):
3539 if message:
3541 if message:
3540 msgs.append(message)
3542 msgs.append(message)
3541 else:
3543 else:
3542 if opts.get('exact') or p2:
3544 if opts.get('exact') or p2:
3543 # If you got here, you either use --force and know what
3545 # If you got here, you either use --force and know what
3544 # you are doing or used --exact or a merge patch while
3546 # you are doing or used --exact or a merge patch while
3545 # being updated to its first parent.
3547 # being updated to its first parent.
3546 m = None
3548 m = None
3547 else:
3549 else:
3548 m = scmutil.matchfiles(repo, files or [])
3550 m = scmutil.matchfiles(repo, files or [])
3549 n = repo.commit(message, opts.get('user') or user,
3551 n = repo.commit(message, opts.get('user') or user,
3550 opts.get('date') or date, match=m,
3552 opts.get('date') or date, match=m,
3551 editor=editor)
3553 editor=editor)
3552 checkexact(repo, n, nodeid)
3554 checkexact(repo, n, nodeid)
3553 else:
3555 else:
3554 if opts.get('exact') or opts.get('import_branch'):
3556 if opts.get('exact') or opts.get('import_branch'):
3555 branch = branch or 'default'
3557 branch = branch or 'default'
3556 else:
3558 else:
3557 branch = p1.branch()
3559 branch = p1.branch()
3558 store = patch.filestore()
3560 store = patch.filestore()
3559 try:
3561 try:
3560 files = set()
3562 files = set()
3561 try:
3563 try:
3562 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
3564 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
3563 files, eolmode=None)
3565 files, eolmode=None)
3564 except patch.PatchError, e:
3566 except patch.PatchError, e:
3565 raise util.Abort(str(e))
3567 raise util.Abort(str(e))
3566 memctx = patch.makememctx(repo, (p1.node(), p2.node()),
3568 memctx = patch.makememctx(repo, (p1.node(), p2.node()),
3567 message,
3569 message,
3568 opts.get('user') or user,
3570 opts.get('user') or user,
3569 opts.get('date') or date,
3571 opts.get('date') or date,
3570 branch, files, store,
3572 branch, files, store,
3571 editor=cmdutil.commiteditor)
3573 editor=cmdutil.commiteditor)
3572 repo.savecommitmessage(memctx.description())
3574 repo.savecommitmessage(memctx.description())
3573 n = memctx.commit()
3575 n = memctx.commit()
3574 checkexact(repo, n, nodeid)
3576 checkexact(repo, n, nodeid)
3575 finally:
3577 finally:
3576 store.close()
3578 store.close()
3577 if n:
3579 if n:
3578 # i18n: refers to a short changeset id
3580 # i18n: refers to a short changeset id
3579 msg = _('created %s') % short(n)
3581 msg = _('created %s') % short(n)
3580 return (msg, n)
3582 return (msg, n)
3581 finally:
3583 finally:
3582 os.unlink(tmpname)
3584 os.unlink(tmpname)
3583
3585
3584 try:
3586 try:
3585 try:
3587 try:
3586 wlock = repo.wlock()
3588 wlock = repo.wlock()
3587 lock = repo.lock()
3589 lock = repo.lock()
3588 tr = repo.transaction('import')
3590 tr = repo.transaction('import')
3589 parents = repo.parents()
3591 parents = repo.parents()
3590 for patchurl in patches:
3592 for patchurl in patches:
3591 if patchurl == '-':
3593 if patchurl == '-':
3592 ui.status(_('applying patch from stdin\n'))
3594 ui.status(_('applying patch from stdin\n'))
3593 patchfile = ui.fin
3595 patchfile = ui.fin
3594 patchurl = 'stdin' # for error message
3596 patchurl = 'stdin' # for error message
3595 else:
3597 else:
3596 patchurl = os.path.join(base, patchurl)
3598 patchurl = os.path.join(base, patchurl)
3597 ui.status(_('applying %s\n') % patchurl)
3599 ui.status(_('applying %s\n') % patchurl)
3598 patchfile = url.open(ui, patchurl)
3600 patchfile = url.open(ui, patchurl)
3599
3601
3600 haspatch = False
3602 haspatch = False
3601 for hunk in patch.split(patchfile):
3603 for hunk in patch.split(patchfile):
3602 (msg, node) = tryone(ui, hunk, parents)
3604 (msg, node) = tryone(ui, hunk, parents)
3603 if msg:
3605 if msg:
3604 haspatch = True
3606 haspatch = True
3605 ui.note(msg + '\n')
3607 ui.note(msg + '\n')
3606 if update or opts.get('exact'):
3608 if update or opts.get('exact'):
3607 parents = repo.parents()
3609 parents = repo.parents()
3608 else:
3610 else:
3609 parents = [repo[node]]
3611 parents = [repo[node]]
3610
3612
3611 if not haspatch:
3613 if not haspatch:
3612 raise util.Abort(_('%s: no diffs found') % patchurl)
3614 raise util.Abort(_('%s: no diffs found') % patchurl)
3613
3615
3614 tr.close()
3616 tr.close()
3615 if msgs:
3617 if msgs:
3616 repo.savecommitmessage('\n* * *\n'.join(msgs))
3618 repo.savecommitmessage('\n* * *\n'.join(msgs))
3617 except:
3619 except:
3618 # wlock.release() indirectly calls dirstate.write(): since
3620 # wlock.release() indirectly calls dirstate.write(): since
3619 # we're crashing, we do not want to change the working dir
3621 # we're crashing, we do not want to change the working dir
3620 # parent after all, so make sure it writes nothing
3622 # parent after all, so make sure it writes nothing
3621 repo.dirstate.invalidate()
3623 repo.dirstate.invalidate()
3622 raise
3624 raise
3623 finally:
3625 finally:
3624 if tr:
3626 if tr:
3625 tr.release()
3627 tr.release()
3626 release(lock, wlock)
3628 release(lock, wlock)
3627
3629
3628 @command('incoming|in',
3630 @command('incoming|in',
3629 [('f', 'force', None,
3631 [('f', 'force', None,
3630 _('run even if remote repository is unrelated')),
3632 _('run even if remote repository is unrelated')),
3631 ('n', 'newest-first', None, _('show newest record first')),
3633 ('n', 'newest-first', None, _('show newest record first')),
3632 ('', 'bundle', '',
3634 ('', 'bundle', '',
3633 _('file to store the bundles into'), _('FILE')),
3635 _('file to store the bundles into'), _('FILE')),
3634 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3636 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3635 ('B', 'bookmarks', False, _("compare bookmarks")),
3637 ('B', 'bookmarks', False, _("compare bookmarks")),
3636 ('b', 'branch', [],
3638 ('b', 'branch', [],
3637 _('a specific branch you would like to pull'), _('BRANCH')),
3639 _('a specific branch you would like to pull'), _('BRANCH')),
3638 ] + logopts + remoteopts + subrepoopts,
3640 ] + logopts + remoteopts + subrepoopts,
3639 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3641 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3640 def incoming(ui, repo, source="default", **opts):
3642 def incoming(ui, repo, source="default", **opts):
3641 """show new changesets found in source
3643 """show new changesets found in source
3642
3644
3643 Show new changesets found in the specified path/URL or the default
3645 Show new changesets found in the specified path/URL or the default
3644 pull location. These are the changesets that would have been pulled
3646 pull location. These are the changesets that would have been pulled
3645 if a pull at the time you issued this command.
3647 if a pull at the time you issued this command.
3646
3648
3647 For remote repository, using --bundle avoids downloading the
3649 For remote repository, using --bundle avoids downloading the
3648 changesets twice if the incoming is followed by a pull.
3650 changesets twice if the incoming is followed by a pull.
3649
3651
3650 See pull for valid source format details.
3652 See pull for valid source format details.
3651
3653
3652 Returns 0 if there are incoming changes, 1 otherwise.
3654 Returns 0 if there are incoming changes, 1 otherwise.
3653 """
3655 """
3654 if opts.get('bundle') and opts.get('subrepos'):
3656 if opts.get('bundle') and opts.get('subrepos'):
3655 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3657 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3656
3658
3657 if opts.get('bookmarks'):
3659 if opts.get('bookmarks'):
3658 source, branches = hg.parseurl(ui.expandpath(source),
3660 source, branches = hg.parseurl(ui.expandpath(source),
3659 opts.get('branch'))
3661 opts.get('branch'))
3660 other = hg.peer(repo, opts, source)
3662 other = hg.peer(repo, opts, source)
3661 if 'bookmarks' not in other.listkeys('namespaces'):
3663 if 'bookmarks' not in other.listkeys('namespaces'):
3662 ui.warn(_("remote doesn't support bookmarks\n"))
3664 ui.warn(_("remote doesn't support bookmarks\n"))
3663 return 0
3665 return 0
3664 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3666 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3665 return bookmarks.diff(ui, repo, other)
3667 return bookmarks.diff(ui, repo, other)
3666
3668
3667 repo._subtoppath = ui.expandpath(source)
3669 repo._subtoppath = ui.expandpath(source)
3668 try:
3670 try:
3669 return hg.incoming(ui, repo, source, opts)
3671 return hg.incoming(ui, repo, source, opts)
3670 finally:
3672 finally:
3671 del repo._subtoppath
3673 del repo._subtoppath
3672
3674
3673
3675
3674 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3676 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3675 def init(ui, dest=".", **opts):
3677 def init(ui, dest=".", **opts):
3676 """create a new repository in the given directory
3678 """create a new repository in the given directory
3677
3679
3678 Initialize a new repository in the given directory. If the given
3680 Initialize a new repository in the given directory. If the given
3679 directory does not exist, it will be created.
3681 directory does not exist, it will be created.
3680
3682
3681 If no directory is given, the current directory is used.
3683 If no directory is given, the current directory is used.
3682
3684
3683 It is possible to specify an ``ssh://`` URL as the destination.
3685 It is possible to specify an ``ssh://`` URL as the destination.
3684 See :hg:`help urls` for more information.
3686 See :hg:`help urls` for more information.
3685
3687
3686 Returns 0 on success.
3688 Returns 0 on success.
3687 """
3689 """
3688 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3690 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3689
3691
3690 @command('locate',
3692 @command('locate',
3691 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3693 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3692 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3694 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3693 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3695 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3694 ] + walkopts,
3696 ] + walkopts,
3695 _('[OPTION]... [PATTERN]...'))
3697 _('[OPTION]... [PATTERN]...'))
3696 def locate(ui, repo, *pats, **opts):
3698 def locate(ui, repo, *pats, **opts):
3697 """locate files matching specific patterns
3699 """locate files matching specific patterns
3698
3700
3699 Print files under Mercurial control in the working directory whose
3701 Print files under Mercurial control in the working directory whose
3700 names match the given patterns.
3702 names match the given patterns.
3701
3703
3702 By default, this command searches all directories in the working
3704 By default, this command searches all directories in the working
3703 directory. To search just the current directory and its
3705 directory. To search just the current directory and its
3704 subdirectories, use "--include .".
3706 subdirectories, use "--include .".
3705
3707
3706 If no patterns are given to match, this command prints the names
3708 If no patterns are given to match, this command prints the names
3707 of all files under Mercurial control in the working directory.
3709 of all files under Mercurial control in the working directory.
3708
3710
3709 If you want to feed the output of this command into the "xargs"
3711 If you want to feed the output of this command into the "xargs"
3710 command, use the -0 option to both this command and "xargs". This
3712 command, use the -0 option to both this command and "xargs". This
3711 will avoid the problem of "xargs" treating single filenames that
3713 will avoid the problem of "xargs" treating single filenames that
3712 contain whitespace as multiple filenames.
3714 contain whitespace as multiple filenames.
3713
3715
3714 Returns 0 if a match is found, 1 otherwise.
3716 Returns 0 if a match is found, 1 otherwise.
3715 """
3717 """
3716 end = opts.get('print0') and '\0' or '\n'
3718 end = opts.get('print0') and '\0' or '\n'
3717 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3719 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3718
3720
3719 ret = 1
3721 ret = 1
3720 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3722 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3721 m.bad = lambda x, y: False
3723 m.bad = lambda x, y: False
3722 for abs in repo[rev].walk(m):
3724 for abs in repo[rev].walk(m):
3723 if not rev and abs not in repo.dirstate:
3725 if not rev and abs not in repo.dirstate:
3724 continue
3726 continue
3725 if opts.get('fullpath'):
3727 if opts.get('fullpath'):
3726 ui.write(repo.wjoin(abs), end)
3728 ui.write(repo.wjoin(abs), end)
3727 else:
3729 else:
3728 ui.write(((pats and m.rel(abs)) or abs), end)
3730 ui.write(((pats and m.rel(abs)) or abs), end)
3729 ret = 0
3731 ret = 0
3730
3732
3731 return ret
3733 return ret
3732
3734
3733 @command('^log|history',
3735 @command('^log|history',
3734 [('f', 'follow', None,
3736 [('f', 'follow', None,
3735 _('follow changeset history, or file history across copies and renames')),
3737 _('follow changeset history, or file history across copies and renames')),
3736 ('', 'follow-first', None,
3738 ('', 'follow-first', None,
3737 _('only follow the first parent of merge changesets')),
3739 _('only follow the first parent of merge changesets')),
3738 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3740 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3739 ('C', 'copies', None, _('show copied files')),
3741 ('C', 'copies', None, _('show copied files')),
3740 ('k', 'keyword', [],
3742 ('k', 'keyword', [],
3741 _('do case-insensitive search for a given text'), _('TEXT')),
3743 _('do case-insensitive search for a given text'), _('TEXT')),
3742 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3744 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3743 ('', 'removed', None, _('include revisions where files were removed')),
3745 ('', 'removed', None, _('include revisions where files were removed')),
3744 ('m', 'only-merges', None, _('show only merges')),
3746 ('m', 'only-merges', None, _('show only merges')),
3745 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3747 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3746 ('', 'only-branch', [],
3748 ('', 'only-branch', [],
3747 _('show only changesets within the given named branch (DEPRECATED)'),
3749 _('show only changesets within the given named branch (DEPRECATED)'),
3748 _('BRANCH')),
3750 _('BRANCH')),
3749 ('b', 'branch', [],
3751 ('b', 'branch', [],
3750 _('show changesets within the given named branch'), _('BRANCH')),
3752 _('show changesets within the given named branch'), _('BRANCH')),
3751 ('P', 'prune', [],
3753 ('P', 'prune', [],
3752 _('do not display revision or any of its ancestors'), _('REV')),
3754 _('do not display revision or any of its ancestors'), _('REV')),
3753 ('', 'hidden', False, _('show hidden changesets')),
3755 ('', 'hidden', False, _('show hidden changesets')),
3754 ] + logopts + walkopts,
3756 ] + logopts + walkopts,
3755 _('[OPTION]... [FILE]'))
3757 _('[OPTION]... [FILE]'))
3756 def log(ui, repo, *pats, **opts):
3758 def log(ui, repo, *pats, **opts):
3757 """show revision history of entire repository or files
3759 """show revision history of entire repository or files
3758
3760
3759 Print the revision history of the specified files or the entire
3761 Print the revision history of the specified files or the entire
3760 project.
3762 project.
3761
3763
3762 If no revision range is specified, the default is ``tip:0`` unless
3764 If no revision range is specified, the default is ``tip:0`` unless
3763 --follow is set, in which case the working directory parent is
3765 --follow is set, in which case the working directory parent is
3764 used as the starting revision.
3766 used as the starting revision.
3765
3767
3766 File history is shown without following rename or copy history of
3768 File history is shown without following rename or copy history of
3767 files. Use -f/--follow with a filename to follow history across
3769 files. Use -f/--follow with a filename to follow history across
3768 renames and copies. --follow without a filename will only show
3770 renames and copies. --follow without a filename will only show
3769 ancestors or descendants of the starting revision.
3771 ancestors or descendants of the starting revision.
3770
3772
3771 By default this command prints revision number and changeset id,
3773 By default this command prints revision number and changeset id,
3772 tags, non-trivial parents, user, date and time, and a summary for
3774 tags, non-trivial parents, user, date and time, and a summary for
3773 each commit. When the -v/--verbose switch is used, the list of
3775 each commit. When the -v/--verbose switch is used, the list of
3774 changed files and full commit message are shown.
3776 changed files and full commit message are shown.
3775
3777
3776 .. note::
3778 .. note::
3777 log -p/--patch may generate unexpected diff output for merge
3779 log -p/--patch may generate unexpected diff output for merge
3778 changesets, as it will only compare the merge changeset against
3780 changesets, as it will only compare the merge changeset against
3779 its first parent. Also, only files different from BOTH parents
3781 its first parent. Also, only files different from BOTH parents
3780 will appear in files:.
3782 will appear in files:.
3781
3783
3782 .. note::
3784 .. note::
3783 for performance reasons, log FILE may omit duplicate changes
3785 for performance reasons, log FILE may omit duplicate changes
3784 made on branches and will not show deletions. To see all
3786 made on branches and will not show deletions. To see all
3785 changes including duplicates and deletions, use the --removed
3787 changes including duplicates and deletions, use the --removed
3786 switch.
3788 switch.
3787
3789
3788 .. container:: verbose
3790 .. container:: verbose
3789
3791
3790 Some examples:
3792 Some examples:
3791
3793
3792 - changesets with full descriptions and file lists::
3794 - changesets with full descriptions and file lists::
3793
3795
3794 hg log -v
3796 hg log -v
3795
3797
3796 - changesets ancestral to the working directory::
3798 - changesets ancestral to the working directory::
3797
3799
3798 hg log -f
3800 hg log -f
3799
3801
3800 - last 10 commits on the current branch::
3802 - last 10 commits on the current branch::
3801
3803
3802 hg log -l 10 -b .
3804 hg log -l 10 -b .
3803
3805
3804 - changesets showing all modifications of a file, including removals::
3806 - changesets showing all modifications of a file, including removals::
3805
3807
3806 hg log --removed file.c
3808 hg log --removed file.c
3807
3809
3808 - all changesets that touch a directory, with diffs, excluding merges::
3810 - all changesets that touch a directory, with diffs, excluding merges::
3809
3811
3810 hg log -Mp lib/
3812 hg log -Mp lib/
3811
3813
3812 - all revision numbers that match a keyword::
3814 - all revision numbers that match a keyword::
3813
3815
3814 hg log -k bug --template "{rev}\\n"
3816 hg log -k bug --template "{rev}\\n"
3815
3817
3816 - check if a given changeset is included is a tagged release::
3818 - check if a given changeset is included is a tagged release::
3817
3819
3818 hg log -r "a21ccf and ancestor(1.9)"
3820 hg log -r "a21ccf and ancestor(1.9)"
3819
3821
3820 - find all changesets by some user in a date range::
3822 - find all changesets by some user in a date range::
3821
3823
3822 hg log -k alice -d "may 2008 to jul 2008"
3824 hg log -k alice -d "may 2008 to jul 2008"
3823
3825
3824 - summary of all changesets after the last tag::
3826 - summary of all changesets after the last tag::
3825
3827
3826 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3828 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3827
3829
3828 See :hg:`help dates` for a list of formats valid for -d/--date.
3830 See :hg:`help dates` for a list of formats valid for -d/--date.
3829
3831
3830 See :hg:`help revisions` and :hg:`help revsets` for more about
3832 See :hg:`help revisions` and :hg:`help revsets` for more about
3831 specifying revisions.
3833 specifying revisions.
3832
3834
3833 Returns 0 on success.
3835 Returns 0 on success.
3834 """
3836 """
3835
3837
3836 matchfn = scmutil.match(repo[None], pats, opts)
3838 matchfn = scmutil.match(repo[None], pats, opts)
3837 limit = cmdutil.loglimit(opts)
3839 limit = cmdutil.loglimit(opts)
3838 count = 0
3840 count = 0
3839
3841
3840 endrev = None
3842 endrev = None
3841 if opts.get('copies') and opts.get('rev'):
3843 if opts.get('copies') and opts.get('rev'):
3842 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
3844 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
3843
3845
3844 df = False
3846 df = False
3845 if opts["date"]:
3847 if opts["date"]:
3846 df = util.matchdate(opts["date"])
3848 df = util.matchdate(opts["date"])
3847
3849
3848 branches = opts.get('branch', []) + opts.get('only_branch', [])
3850 branches = opts.get('branch', []) + opts.get('only_branch', [])
3849 opts['branch'] = [repo.lookupbranch(b) for b in branches]
3851 opts['branch'] = [repo.lookupbranch(b) for b in branches]
3850
3852
3851 displayer = cmdutil.show_changeset(ui, repo, opts, True)
3853 displayer = cmdutil.show_changeset(ui, repo, opts, True)
3852 def prep(ctx, fns):
3854 def prep(ctx, fns):
3853 rev = ctx.rev()
3855 rev = ctx.rev()
3854 parents = [p for p in repo.changelog.parentrevs(rev)
3856 parents = [p for p in repo.changelog.parentrevs(rev)
3855 if p != nullrev]
3857 if p != nullrev]
3856 if opts.get('no_merges') and len(parents) == 2:
3858 if opts.get('no_merges') and len(parents) == 2:
3857 return
3859 return
3858 if opts.get('only_merges') and len(parents) != 2:
3860 if opts.get('only_merges') and len(parents) != 2:
3859 return
3861 return
3860 if opts.get('branch') and ctx.branch() not in opts['branch']:
3862 if opts.get('branch') and ctx.branch() not in opts['branch']:
3861 return
3863 return
3862 if not opts.get('hidden') and ctx.hidden():
3864 if not opts.get('hidden') and ctx.hidden():
3863 return
3865 return
3864 if df and not df(ctx.date()[0]):
3866 if df and not df(ctx.date()[0]):
3865 return
3867 return
3866 if opts['user'] and not [k for k in opts['user']
3868 if opts['user'] and not [k for k in opts['user']
3867 if k.lower() in ctx.user().lower()]:
3869 if k.lower() in ctx.user().lower()]:
3868 return
3870 return
3869 if opts.get('keyword'):
3871 if opts.get('keyword'):
3870 for k in [kw.lower() for kw in opts['keyword']]:
3872 for k in [kw.lower() for kw in opts['keyword']]:
3871 if (k in ctx.user().lower() or
3873 if (k in ctx.user().lower() or
3872 k in ctx.description().lower() or
3874 k in ctx.description().lower() or
3873 k in " ".join(ctx.files()).lower()):
3875 k in " ".join(ctx.files()).lower()):
3874 break
3876 break
3875 else:
3877 else:
3876 return
3878 return
3877
3879
3878 copies = None
3880 copies = None
3879 if opts.get('copies') and rev:
3881 if opts.get('copies') and rev:
3880 copies = []
3882 copies = []
3881 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3883 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3882 for fn in ctx.files():
3884 for fn in ctx.files():
3883 rename = getrenamed(fn, rev)
3885 rename = getrenamed(fn, rev)
3884 if rename:
3886 if rename:
3885 copies.append((fn, rename[0]))
3887 copies.append((fn, rename[0]))
3886
3888
3887 revmatchfn = None
3889 revmatchfn = None
3888 if opts.get('patch') or opts.get('stat'):
3890 if opts.get('patch') or opts.get('stat'):
3889 if opts.get('follow') or opts.get('follow_first'):
3891 if opts.get('follow') or opts.get('follow_first'):
3890 # note: this might be wrong when following through merges
3892 # note: this might be wrong when following through merges
3891 revmatchfn = scmutil.match(repo[None], fns, default='path')
3893 revmatchfn = scmutil.match(repo[None], fns, default='path')
3892 else:
3894 else:
3893 revmatchfn = matchfn
3895 revmatchfn = matchfn
3894
3896
3895 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3897 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3896
3898
3897 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3899 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3898 if count == limit:
3900 if count == limit:
3899 break
3901 break
3900 if displayer.flush(ctx.rev()):
3902 if displayer.flush(ctx.rev()):
3901 count += 1
3903 count += 1
3902 displayer.close()
3904 displayer.close()
3903
3905
3904 @command('manifest',
3906 @command('manifest',
3905 [('r', 'rev', '', _('revision to display'), _('REV')),
3907 [('r', 'rev', '', _('revision to display'), _('REV')),
3906 ('', 'all', False, _("list files from all revisions"))],
3908 ('', 'all', False, _("list files from all revisions"))],
3907 _('[-r REV]'))
3909 _('[-r REV]'))
3908 def manifest(ui, repo, node=None, rev=None, **opts):
3910 def manifest(ui, repo, node=None, rev=None, **opts):
3909 """output the current or given revision of the project manifest
3911 """output the current or given revision of the project manifest
3910
3912
3911 Print a list of version controlled files for the given revision.
3913 Print a list of version controlled files for the given revision.
3912 If no revision is given, the first parent of the working directory
3914 If no revision is given, the first parent of the working directory
3913 is used, or the null revision if no revision is checked out.
3915 is used, or the null revision if no revision is checked out.
3914
3916
3915 With -v, print file permissions, symlink and executable bits.
3917 With -v, print file permissions, symlink and executable bits.
3916 With --debug, print file revision hashes.
3918 With --debug, print file revision hashes.
3917
3919
3918 If option --all is specified, the list of all files from all revisions
3920 If option --all is specified, the list of all files from all revisions
3919 is printed. This includes deleted and renamed files.
3921 is printed. This includes deleted and renamed files.
3920
3922
3921 Returns 0 on success.
3923 Returns 0 on success.
3922 """
3924 """
3923 if opts.get('all'):
3925 if opts.get('all'):
3924 if rev or node:
3926 if rev or node:
3925 raise util.Abort(_("can't specify a revision with --all"))
3927 raise util.Abort(_("can't specify a revision with --all"))
3926
3928
3927 res = []
3929 res = []
3928 prefix = "data/"
3930 prefix = "data/"
3929 suffix = ".i"
3931 suffix = ".i"
3930 plen = len(prefix)
3932 plen = len(prefix)
3931 slen = len(suffix)
3933 slen = len(suffix)
3932 lock = repo.lock()
3934 lock = repo.lock()
3933 try:
3935 try:
3934 for fn, b, size in repo.store.datafiles():
3936 for fn, b, size in repo.store.datafiles():
3935 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
3937 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
3936 res.append(fn[plen:-slen])
3938 res.append(fn[plen:-slen])
3937 finally:
3939 finally:
3938 lock.release()
3940 lock.release()
3939 for f in sorted(res):
3941 for f in sorted(res):
3940 ui.write("%s\n" % f)
3942 ui.write("%s\n" % f)
3941 return
3943 return
3942
3944
3943 if rev and node:
3945 if rev and node:
3944 raise util.Abort(_("please specify just one revision"))
3946 raise util.Abort(_("please specify just one revision"))
3945
3947
3946 if not node:
3948 if not node:
3947 node = rev
3949 node = rev
3948
3950
3949 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
3951 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
3950 ctx = scmutil.revsingle(repo, node)
3952 ctx = scmutil.revsingle(repo, node)
3951 for f in ctx:
3953 for f in ctx:
3952 if ui.debugflag:
3954 if ui.debugflag:
3953 ui.write("%40s " % hex(ctx.manifest()[f]))
3955 ui.write("%40s " % hex(ctx.manifest()[f]))
3954 if ui.verbose:
3956 if ui.verbose:
3955 ui.write(decor[ctx.flags(f)])
3957 ui.write(decor[ctx.flags(f)])
3956 ui.write("%s\n" % f)
3958 ui.write("%s\n" % f)
3957
3959
3958 @command('^merge',
3960 @command('^merge',
3959 [('f', 'force', None, _('force a merge with outstanding changes')),
3961 [('f', 'force', None, _('force a merge with outstanding changes')),
3960 ('r', 'rev', '', _('revision to merge'), _('REV')),
3962 ('r', 'rev', '', _('revision to merge'), _('REV')),
3961 ('P', 'preview', None,
3963 ('P', 'preview', None,
3962 _('review revisions to merge (no merge is performed)'))
3964 _('review revisions to merge (no merge is performed)'))
3963 ] + mergetoolopts,
3965 ] + mergetoolopts,
3964 _('[-P] [-f] [[-r] REV]'))
3966 _('[-P] [-f] [[-r] REV]'))
3965 def merge(ui, repo, node=None, **opts):
3967 def merge(ui, repo, node=None, **opts):
3966 """merge working directory with another revision
3968 """merge working directory with another revision
3967
3969
3968 The current working directory is updated with all changes made in
3970 The current working directory is updated with all changes made in
3969 the requested revision since the last common predecessor revision.
3971 the requested revision since the last common predecessor revision.
3970
3972
3971 Files that changed between either parent are marked as changed for
3973 Files that changed between either parent are marked as changed for
3972 the next commit and a commit must be performed before any further
3974 the next commit and a commit must be performed before any further
3973 updates to the repository are allowed. The next commit will have
3975 updates to the repository are allowed. The next commit will have
3974 two parents.
3976 two parents.
3975
3977
3976 ``--tool`` can be used to specify the merge tool used for file
3978 ``--tool`` can be used to specify the merge tool used for file
3977 merges. It overrides the HGMERGE environment variable and your
3979 merges. It overrides the HGMERGE environment variable and your
3978 configuration files. See :hg:`help merge-tools` for options.
3980 configuration files. See :hg:`help merge-tools` for options.
3979
3981
3980 If no revision is specified, the working directory's parent is a
3982 If no revision is specified, the working directory's parent is a
3981 head revision, and the current branch contains exactly one other
3983 head revision, and the current branch contains exactly one other
3982 head, the other head is merged with by default. Otherwise, an
3984 head, the other head is merged with by default. Otherwise, an
3983 explicit revision with which to merge with must be provided.
3985 explicit revision with which to merge with must be provided.
3984
3986
3985 :hg:`resolve` must be used to resolve unresolved files.
3987 :hg:`resolve` must be used to resolve unresolved files.
3986
3988
3987 To undo an uncommitted merge, use :hg:`update --clean .` which
3989 To undo an uncommitted merge, use :hg:`update --clean .` which
3988 will check out a clean copy of the original merge parent, losing
3990 will check out a clean copy of the original merge parent, losing
3989 all changes.
3991 all changes.
3990
3992
3991 Returns 0 on success, 1 if there are unresolved files.
3993 Returns 0 on success, 1 if there are unresolved files.
3992 """
3994 """
3993
3995
3994 if opts.get('rev') and node:
3996 if opts.get('rev') and node:
3995 raise util.Abort(_("please specify just one revision"))
3997 raise util.Abort(_("please specify just one revision"))
3996 if not node:
3998 if not node:
3997 node = opts.get('rev')
3999 node = opts.get('rev')
3998
4000
3999 if not node:
4001 if not node:
4000 branch = repo[None].branch()
4002 branch = repo[None].branch()
4001 bheads = repo.branchheads(branch)
4003 bheads = repo.branchheads(branch)
4002 if len(bheads) > 2:
4004 if len(bheads) > 2:
4003 raise util.Abort(_("branch '%s' has %d heads - "
4005 raise util.Abort(_("branch '%s' has %d heads - "
4004 "please merge with an explicit rev")
4006 "please merge with an explicit rev")
4005 % (branch, len(bheads)),
4007 % (branch, len(bheads)),
4006 hint=_("run 'hg heads .' to see heads"))
4008 hint=_("run 'hg heads .' to see heads"))
4007
4009
4008 parent = repo.dirstate.p1()
4010 parent = repo.dirstate.p1()
4009 if len(bheads) == 1:
4011 if len(bheads) == 1:
4010 if len(repo.heads()) > 1:
4012 if len(repo.heads()) > 1:
4011 raise util.Abort(_("branch '%s' has one head - "
4013 raise util.Abort(_("branch '%s' has one head - "
4012 "please merge with an explicit rev")
4014 "please merge with an explicit rev")
4013 % branch,
4015 % branch,
4014 hint=_("run 'hg heads' to see all heads"))
4016 hint=_("run 'hg heads' to see all heads"))
4015 msg = _('there is nothing to merge')
4017 msg = _('there is nothing to merge')
4016 if parent != repo.lookup(repo[None].branch()):
4018 if parent != repo.lookup(repo[None].branch()):
4017 msg = _('%s - use "hg update" instead') % msg
4019 msg = _('%s - use "hg update" instead') % msg
4018 raise util.Abort(msg)
4020 raise util.Abort(msg)
4019
4021
4020 if parent not in bheads:
4022 if parent not in bheads:
4021 raise util.Abort(_('working directory not at a head revision'),
4023 raise util.Abort(_('working directory not at a head revision'),
4022 hint=_("use 'hg update' or merge with an "
4024 hint=_("use 'hg update' or merge with an "
4023 "explicit revision"))
4025 "explicit revision"))
4024 node = parent == bheads[0] and bheads[-1] or bheads[0]
4026 node = parent == bheads[0] and bheads[-1] or bheads[0]
4025 else:
4027 else:
4026 node = scmutil.revsingle(repo, node).node()
4028 node = scmutil.revsingle(repo, node).node()
4027
4029
4028 if opts.get('preview'):
4030 if opts.get('preview'):
4029 # find nodes that are ancestors of p2 but not of p1
4031 # find nodes that are ancestors of p2 but not of p1
4030 p1 = repo.lookup('.')
4032 p1 = repo.lookup('.')
4031 p2 = repo.lookup(node)
4033 p2 = repo.lookup(node)
4032 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4034 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4033
4035
4034 displayer = cmdutil.show_changeset(ui, repo, opts)
4036 displayer = cmdutil.show_changeset(ui, repo, opts)
4035 for node in nodes:
4037 for node in nodes:
4036 displayer.show(repo[node])
4038 displayer.show(repo[node])
4037 displayer.close()
4039 displayer.close()
4038 return 0
4040 return 0
4039
4041
4040 try:
4042 try:
4041 # ui.forcemerge is an internal variable, do not document
4043 # ui.forcemerge is an internal variable, do not document
4042 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4044 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4043 return hg.merge(repo, node, force=opts.get('force'))
4045 return hg.merge(repo, node, force=opts.get('force'))
4044 finally:
4046 finally:
4045 ui.setconfig('ui', 'forcemerge', '')
4047 ui.setconfig('ui', 'forcemerge', '')
4046
4048
4047 @command('outgoing|out',
4049 @command('outgoing|out',
4048 [('f', 'force', None, _('run even when the destination is unrelated')),
4050 [('f', 'force', None, _('run even when the destination is unrelated')),
4049 ('r', 'rev', [],
4051 ('r', 'rev', [],
4050 _('a changeset intended to be included in the destination'), _('REV')),
4052 _('a changeset intended to be included in the destination'), _('REV')),
4051 ('n', 'newest-first', None, _('show newest record first')),
4053 ('n', 'newest-first', None, _('show newest record first')),
4052 ('B', 'bookmarks', False, _('compare bookmarks')),
4054 ('B', 'bookmarks', False, _('compare bookmarks')),
4053 ('b', 'branch', [], _('a specific branch you would like to push'),
4055 ('b', 'branch', [], _('a specific branch you would like to push'),
4054 _('BRANCH')),
4056 _('BRANCH')),
4055 ] + logopts + remoteopts + subrepoopts,
4057 ] + logopts + remoteopts + subrepoopts,
4056 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4058 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4057 def outgoing(ui, repo, dest=None, **opts):
4059 def outgoing(ui, repo, dest=None, **opts):
4058 """show changesets not found in the destination
4060 """show changesets not found in the destination
4059
4061
4060 Show changesets not found in the specified destination repository
4062 Show changesets not found in the specified destination repository
4061 or the default push location. These are the changesets that would
4063 or the default push location. These are the changesets that would
4062 be pushed if a push was requested.
4064 be pushed if a push was requested.
4063
4065
4064 See pull for details of valid destination formats.
4066 See pull for details of valid destination formats.
4065
4067
4066 Returns 0 if there are outgoing changes, 1 otherwise.
4068 Returns 0 if there are outgoing changes, 1 otherwise.
4067 """
4069 """
4068
4070
4069 if opts.get('bookmarks'):
4071 if opts.get('bookmarks'):
4070 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4072 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4071 dest, branches = hg.parseurl(dest, opts.get('branch'))
4073 dest, branches = hg.parseurl(dest, opts.get('branch'))
4072 other = hg.peer(repo, opts, dest)
4074 other = hg.peer(repo, opts, dest)
4073 if 'bookmarks' not in other.listkeys('namespaces'):
4075 if 'bookmarks' not in other.listkeys('namespaces'):
4074 ui.warn(_("remote doesn't support bookmarks\n"))
4076 ui.warn(_("remote doesn't support bookmarks\n"))
4075 return 0
4077 return 0
4076 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4078 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4077 return bookmarks.diff(ui, other, repo)
4079 return bookmarks.diff(ui, other, repo)
4078
4080
4079 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4081 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4080 try:
4082 try:
4081 return hg.outgoing(ui, repo, dest, opts)
4083 return hg.outgoing(ui, repo, dest, opts)
4082 finally:
4084 finally:
4083 del repo._subtoppath
4085 del repo._subtoppath
4084
4086
4085 @command('parents',
4087 @command('parents',
4086 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4088 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4087 ] + templateopts,
4089 ] + templateopts,
4088 _('[-r REV] [FILE]'))
4090 _('[-r REV] [FILE]'))
4089 def parents(ui, repo, file_=None, **opts):
4091 def parents(ui, repo, file_=None, **opts):
4090 """show the parents of the working directory or revision
4092 """show the parents of the working directory or revision
4091
4093
4092 Print the working directory's parent revisions. If a revision is
4094 Print the working directory's parent revisions. If a revision is
4093 given via -r/--rev, the parent of that revision will be printed.
4095 given via -r/--rev, the parent of that revision will be printed.
4094 If a file argument is given, the revision in which the file was
4096 If a file argument is given, the revision in which the file was
4095 last changed (before the working directory revision or the
4097 last changed (before the working directory revision or the
4096 argument to --rev if given) is printed.
4098 argument to --rev if given) is printed.
4097
4099
4098 Returns 0 on success.
4100 Returns 0 on success.
4099 """
4101 """
4100
4102
4101 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4103 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4102
4104
4103 if file_:
4105 if file_:
4104 m = scmutil.match(ctx, (file_,), opts)
4106 m = scmutil.match(ctx, (file_,), opts)
4105 if m.anypats() or len(m.files()) != 1:
4107 if m.anypats() or len(m.files()) != 1:
4106 raise util.Abort(_('can only specify an explicit filename'))
4108 raise util.Abort(_('can only specify an explicit filename'))
4107 file_ = m.files()[0]
4109 file_ = m.files()[0]
4108 filenodes = []
4110 filenodes = []
4109 for cp in ctx.parents():
4111 for cp in ctx.parents():
4110 if not cp:
4112 if not cp:
4111 continue
4113 continue
4112 try:
4114 try:
4113 filenodes.append(cp.filenode(file_))
4115 filenodes.append(cp.filenode(file_))
4114 except error.LookupError:
4116 except error.LookupError:
4115 pass
4117 pass
4116 if not filenodes:
4118 if not filenodes:
4117 raise util.Abort(_("'%s' not found in manifest!") % file_)
4119 raise util.Abort(_("'%s' not found in manifest!") % file_)
4118 fl = repo.file(file_)
4120 fl = repo.file(file_)
4119 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
4121 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
4120 else:
4122 else:
4121 p = [cp.node() for cp in ctx.parents()]
4123 p = [cp.node() for cp in ctx.parents()]
4122
4124
4123 displayer = cmdutil.show_changeset(ui, repo, opts)
4125 displayer = cmdutil.show_changeset(ui, repo, opts)
4124 for n in p:
4126 for n in p:
4125 if n != nullid:
4127 if n != nullid:
4126 displayer.show(repo[n])
4128 displayer.show(repo[n])
4127 displayer.close()
4129 displayer.close()
4128
4130
4129 @command('paths', [], _('[NAME]'))
4131 @command('paths', [], _('[NAME]'))
4130 def paths(ui, repo, search=None):
4132 def paths(ui, repo, search=None):
4131 """show aliases for remote repositories
4133 """show aliases for remote repositories
4132
4134
4133 Show definition of symbolic path name NAME. If no name is given,
4135 Show definition of symbolic path name NAME. If no name is given,
4134 show definition of all available names.
4136 show definition of all available names.
4135
4137
4136 Option -q/--quiet suppresses all output when searching for NAME
4138 Option -q/--quiet suppresses all output when searching for NAME
4137 and shows only the path names when listing all definitions.
4139 and shows only the path names when listing all definitions.
4138
4140
4139 Path names are defined in the [paths] section of your
4141 Path names are defined in the [paths] section of your
4140 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4142 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4141 repository, ``.hg/hgrc`` is used, too.
4143 repository, ``.hg/hgrc`` is used, too.
4142
4144
4143 The path names ``default`` and ``default-push`` have a special
4145 The path names ``default`` and ``default-push`` have a special
4144 meaning. When performing a push or pull operation, they are used
4146 meaning. When performing a push or pull operation, they are used
4145 as fallbacks if no location is specified on the command-line.
4147 as fallbacks if no location is specified on the command-line.
4146 When ``default-push`` is set, it will be used for push and
4148 When ``default-push`` is set, it will be used for push and
4147 ``default`` will be used for pull; otherwise ``default`` is used
4149 ``default`` will be used for pull; otherwise ``default`` is used
4148 as the fallback for both. When cloning a repository, the clone
4150 as the fallback for both. When cloning a repository, the clone
4149 source is written as ``default`` in ``.hg/hgrc``. Note that
4151 source is written as ``default`` in ``.hg/hgrc``. Note that
4150 ``default`` and ``default-push`` apply to all inbound (e.g.
4152 ``default`` and ``default-push`` apply to all inbound (e.g.
4151 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4153 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4152 :hg:`bundle`) operations.
4154 :hg:`bundle`) operations.
4153
4155
4154 See :hg:`help urls` for more information.
4156 See :hg:`help urls` for more information.
4155
4157
4156 Returns 0 on success.
4158 Returns 0 on success.
4157 """
4159 """
4158 if search:
4160 if search:
4159 for name, path in ui.configitems("paths"):
4161 for name, path in ui.configitems("paths"):
4160 if name == search:
4162 if name == search:
4161 ui.status("%s\n" % util.hidepassword(path))
4163 ui.status("%s\n" % util.hidepassword(path))
4162 return
4164 return
4163 if not ui.quiet:
4165 if not ui.quiet:
4164 ui.warn(_("not found!\n"))
4166 ui.warn(_("not found!\n"))
4165 return 1
4167 return 1
4166 else:
4168 else:
4167 for name, path in ui.configitems("paths"):
4169 for name, path in ui.configitems("paths"):
4168 if ui.quiet:
4170 if ui.quiet:
4169 ui.write("%s\n" % name)
4171 ui.write("%s\n" % name)
4170 else:
4172 else:
4171 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4173 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4172
4174
4173 def postincoming(ui, repo, modheads, optupdate, checkout):
4175 def postincoming(ui, repo, modheads, optupdate, checkout):
4174 if modheads == 0:
4176 if modheads == 0:
4175 return
4177 return
4176 if optupdate:
4178 if optupdate:
4177 try:
4179 try:
4178 return hg.update(repo, checkout)
4180 return hg.update(repo, checkout)
4179 except util.Abort, inst:
4181 except util.Abort, inst:
4180 ui.warn(_("not updating: %s\n" % str(inst)))
4182 ui.warn(_("not updating: %s\n" % str(inst)))
4181 return 0
4183 return 0
4182 if modheads > 1:
4184 if modheads > 1:
4183 currentbranchheads = len(repo.branchheads())
4185 currentbranchheads = len(repo.branchheads())
4184 if currentbranchheads == modheads:
4186 if currentbranchheads == modheads:
4185 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4187 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4186 elif currentbranchheads > 1:
4188 elif currentbranchheads > 1:
4187 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
4189 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
4188 else:
4190 else:
4189 ui.status(_("(run 'hg heads' to see heads)\n"))
4191 ui.status(_("(run 'hg heads' to see heads)\n"))
4190 else:
4192 else:
4191 ui.status(_("(run 'hg update' to get a working copy)\n"))
4193 ui.status(_("(run 'hg update' to get a working copy)\n"))
4192
4194
4193 @command('^pull',
4195 @command('^pull',
4194 [('u', 'update', None,
4196 [('u', 'update', None,
4195 _('update to new branch head if changesets were pulled')),
4197 _('update to new branch head if changesets were pulled')),
4196 ('f', 'force', None, _('run even when remote repository is unrelated')),
4198 ('f', 'force', None, _('run even when remote repository is unrelated')),
4197 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4199 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4198 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4200 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4199 ('b', 'branch', [], _('a specific branch you would like to pull'),
4201 ('b', 'branch', [], _('a specific branch you would like to pull'),
4200 _('BRANCH')),
4202 _('BRANCH')),
4201 ] + remoteopts,
4203 ] + remoteopts,
4202 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4204 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4203 def pull(ui, repo, source="default", **opts):
4205 def pull(ui, repo, source="default", **opts):
4204 """pull changes from the specified source
4206 """pull changes from the specified source
4205
4207
4206 Pull changes from a remote repository to a local one.
4208 Pull changes from a remote repository to a local one.
4207
4209
4208 This finds all changes from the repository at the specified path
4210 This finds all changes from the repository at the specified path
4209 or URL and adds them to a local repository (the current one unless
4211 or URL and adds them to a local repository (the current one unless
4210 -R is specified). By default, this does not update the copy of the
4212 -R is specified). By default, this does not update the copy of the
4211 project in the working directory.
4213 project in the working directory.
4212
4214
4213 Use :hg:`incoming` if you want to see what would have been added
4215 Use :hg:`incoming` if you want to see what would have been added
4214 by a pull at the time you issued this command. If you then decide
4216 by a pull at the time you issued this command. If you then decide
4215 to add those changes to the repository, you should use :hg:`pull
4217 to add those changes to the repository, you should use :hg:`pull
4216 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4218 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4217
4219
4218 If SOURCE is omitted, the 'default' path will be used.
4220 If SOURCE is omitted, the 'default' path will be used.
4219 See :hg:`help urls` for more information.
4221 See :hg:`help urls` for more information.
4220
4222
4221 Returns 0 on success, 1 if an update had unresolved files.
4223 Returns 0 on success, 1 if an update had unresolved files.
4222 """
4224 """
4223 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4225 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4224 other = hg.peer(repo, opts, source)
4226 other = hg.peer(repo, opts, source)
4225 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4227 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4226 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4228 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4227
4229
4228 if opts.get('bookmark'):
4230 if opts.get('bookmark'):
4229 if not revs:
4231 if not revs:
4230 revs = []
4232 revs = []
4231 rb = other.listkeys('bookmarks')
4233 rb = other.listkeys('bookmarks')
4232 for b in opts['bookmark']:
4234 for b in opts['bookmark']:
4233 if b not in rb:
4235 if b not in rb:
4234 raise util.Abort(_('remote bookmark %s not found!') % b)
4236 raise util.Abort(_('remote bookmark %s not found!') % b)
4235 revs.append(rb[b])
4237 revs.append(rb[b])
4236
4238
4237 if revs:
4239 if revs:
4238 try:
4240 try:
4239 revs = [other.lookup(rev) for rev in revs]
4241 revs = [other.lookup(rev) for rev in revs]
4240 except error.CapabilityError:
4242 except error.CapabilityError:
4241 err = _("other repository doesn't support revision lookup, "
4243 err = _("other repository doesn't support revision lookup, "
4242 "so a rev cannot be specified.")
4244 "so a rev cannot be specified.")
4243 raise util.Abort(err)
4245 raise util.Abort(err)
4244
4246
4245 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4247 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4246 bookmarks.updatefromremote(ui, repo, other)
4248 bookmarks.updatefromremote(ui, repo, other)
4247 if checkout:
4249 if checkout:
4248 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4250 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4249 repo._subtoppath = source
4251 repo._subtoppath = source
4250 try:
4252 try:
4251 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4253 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4252
4254
4253 finally:
4255 finally:
4254 del repo._subtoppath
4256 del repo._subtoppath
4255
4257
4256 # update specified bookmarks
4258 # update specified bookmarks
4257 if opts.get('bookmark'):
4259 if opts.get('bookmark'):
4258 for b in opts['bookmark']:
4260 for b in opts['bookmark']:
4259 # explicit pull overrides local bookmark if any
4261 # explicit pull overrides local bookmark if any
4260 ui.status(_("importing bookmark %s\n") % b)
4262 ui.status(_("importing bookmark %s\n") % b)
4261 repo._bookmarks[b] = repo[rb[b]].node()
4263 repo._bookmarks[b] = repo[rb[b]].node()
4262 bookmarks.write(repo)
4264 bookmarks.write(repo)
4263
4265
4264 return ret
4266 return ret
4265
4267
4266 @command('^push',
4268 @command('^push',
4267 [('f', 'force', None, _('force push')),
4269 [('f', 'force', None, _('force push')),
4268 ('r', 'rev', [],
4270 ('r', 'rev', [],
4269 _('a changeset intended to be included in the destination'),
4271 _('a changeset intended to be included in the destination'),
4270 _('REV')),
4272 _('REV')),
4271 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4273 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4272 ('b', 'branch', [],
4274 ('b', 'branch', [],
4273 _('a specific branch you would like to push'), _('BRANCH')),
4275 _('a specific branch you would like to push'), _('BRANCH')),
4274 ('', 'new-branch', False, _('allow pushing a new branch')),
4276 ('', 'new-branch', False, _('allow pushing a new branch')),
4275 ] + remoteopts,
4277 ] + remoteopts,
4276 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4278 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4277 def push(ui, repo, dest=None, **opts):
4279 def push(ui, repo, dest=None, **opts):
4278 """push changes to the specified destination
4280 """push changes to the specified destination
4279
4281
4280 Push changesets from the local repository to the specified
4282 Push changesets from the local repository to the specified
4281 destination.
4283 destination.
4282
4284
4283 This operation is symmetrical to pull: it is identical to a pull
4285 This operation is symmetrical to pull: it is identical to a pull
4284 in the destination repository from the current one.
4286 in the destination repository from the current one.
4285
4287
4286 By default, push will not allow creation of new heads at the
4288 By default, push will not allow creation of new heads at the
4287 destination, since multiple heads would make it unclear which head
4289 destination, since multiple heads would make it unclear which head
4288 to use. In this situation, it is recommended to pull and merge
4290 to use. In this situation, it is recommended to pull and merge
4289 before pushing.
4291 before pushing.
4290
4292
4291 Use --new-branch if you want to allow push to create a new named
4293 Use --new-branch if you want to allow push to create a new named
4292 branch that is not present at the destination. This allows you to
4294 branch that is not present at the destination. This allows you to
4293 only create a new branch without forcing other changes.
4295 only create a new branch without forcing other changes.
4294
4296
4295 Use -f/--force to override the default behavior and push all
4297 Use -f/--force to override the default behavior and push all
4296 changesets on all branches.
4298 changesets on all branches.
4297
4299
4298 If -r/--rev is used, the specified revision and all its ancestors
4300 If -r/--rev is used, the specified revision and all its ancestors
4299 will be pushed to the remote repository.
4301 will be pushed to the remote repository.
4300
4302
4301 Please see :hg:`help urls` for important details about ``ssh://``
4303 Please see :hg:`help urls` for important details about ``ssh://``
4302 URLs. If DESTINATION is omitted, a default path will be used.
4304 URLs. If DESTINATION is omitted, a default path will be used.
4303
4305
4304 Returns 0 if push was successful, 1 if nothing to push.
4306 Returns 0 if push was successful, 1 if nothing to push.
4305 """
4307 """
4306
4308
4307 if opts.get('bookmark'):
4309 if opts.get('bookmark'):
4308 for b in opts['bookmark']:
4310 for b in opts['bookmark']:
4309 # translate -B options to -r so changesets get pushed
4311 # translate -B options to -r so changesets get pushed
4310 if b in repo._bookmarks:
4312 if b in repo._bookmarks:
4311 opts.setdefault('rev', []).append(b)
4313 opts.setdefault('rev', []).append(b)
4312 else:
4314 else:
4313 # if we try to push a deleted bookmark, translate it to null
4315 # if we try to push a deleted bookmark, translate it to null
4314 # this lets simultaneous -r, -b options continue working
4316 # this lets simultaneous -r, -b options continue working
4315 opts.setdefault('rev', []).append("null")
4317 opts.setdefault('rev', []).append("null")
4316
4318
4317 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4319 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4318 dest, branches = hg.parseurl(dest, opts.get('branch'))
4320 dest, branches = hg.parseurl(dest, opts.get('branch'))
4319 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4321 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4320 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4322 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4321 other = hg.peer(repo, opts, dest)
4323 other = hg.peer(repo, opts, dest)
4322 if revs:
4324 if revs:
4323 revs = [repo.lookup(rev) for rev in revs]
4325 revs = [repo.lookup(rev) for rev in revs]
4324
4326
4325 repo._subtoppath = dest
4327 repo._subtoppath = dest
4326 try:
4328 try:
4327 # push subrepos depth-first for coherent ordering
4329 # push subrepos depth-first for coherent ordering
4328 c = repo['']
4330 c = repo['']
4329 subs = c.substate # only repos that are committed
4331 subs = c.substate # only repos that are committed
4330 for s in sorted(subs):
4332 for s in sorted(subs):
4331 if not c.sub(s).push(opts.get('force')):
4333 if not c.sub(s).push(opts.get('force')):
4332 return False
4334 return False
4333 finally:
4335 finally:
4334 del repo._subtoppath
4336 del repo._subtoppath
4335 result = repo.push(other, opts.get('force'), revs=revs,
4337 result = repo.push(other, opts.get('force'), revs=revs,
4336 newbranch=opts.get('new_branch'))
4338 newbranch=opts.get('new_branch'))
4337
4339
4338 result = (result == 0)
4340 result = (result == 0)
4339
4341
4340 if opts.get('bookmark'):
4342 if opts.get('bookmark'):
4341 rb = other.listkeys('bookmarks')
4343 rb = other.listkeys('bookmarks')
4342 for b in opts['bookmark']:
4344 for b in opts['bookmark']:
4343 # explicit push overrides remote bookmark if any
4345 # explicit push overrides remote bookmark if any
4344 if b in repo._bookmarks:
4346 if b in repo._bookmarks:
4345 ui.status(_("exporting bookmark %s\n") % b)
4347 ui.status(_("exporting bookmark %s\n") % b)
4346 new = repo[b].hex()
4348 new = repo[b].hex()
4347 elif b in rb:
4349 elif b in rb:
4348 ui.status(_("deleting remote bookmark %s\n") % b)
4350 ui.status(_("deleting remote bookmark %s\n") % b)
4349 new = '' # delete
4351 new = '' # delete
4350 else:
4352 else:
4351 ui.warn(_('bookmark %s does not exist on the local '
4353 ui.warn(_('bookmark %s does not exist on the local '
4352 'or remote repository!\n') % b)
4354 'or remote repository!\n') % b)
4353 return 2
4355 return 2
4354 old = rb.get(b, '')
4356 old = rb.get(b, '')
4355 r = other.pushkey('bookmarks', b, old, new)
4357 r = other.pushkey('bookmarks', b, old, new)
4356 if not r:
4358 if not r:
4357 ui.warn(_('updating bookmark %s failed!\n') % b)
4359 ui.warn(_('updating bookmark %s failed!\n') % b)
4358 if not result:
4360 if not result:
4359 result = 2
4361 result = 2
4360
4362
4361 return result
4363 return result
4362
4364
4363 @command('recover', [])
4365 @command('recover', [])
4364 def recover(ui, repo):
4366 def recover(ui, repo):
4365 """roll back an interrupted transaction
4367 """roll back an interrupted transaction
4366
4368
4367 Recover from an interrupted commit or pull.
4369 Recover from an interrupted commit or pull.
4368
4370
4369 This command tries to fix the repository status after an
4371 This command tries to fix the repository status after an
4370 interrupted operation. It should only be necessary when Mercurial
4372 interrupted operation. It should only be necessary when Mercurial
4371 suggests it.
4373 suggests it.
4372
4374
4373 Returns 0 if successful, 1 if nothing to recover or verify fails.
4375 Returns 0 if successful, 1 if nothing to recover or verify fails.
4374 """
4376 """
4375 if repo.recover():
4377 if repo.recover():
4376 return hg.verify(repo)
4378 return hg.verify(repo)
4377 return 1
4379 return 1
4378
4380
4379 @command('^remove|rm',
4381 @command('^remove|rm',
4380 [('A', 'after', None, _('record delete for missing files')),
4382 [('A', 'after', None, _('record delete for missing files')),
4381 ('f', 'force', None,
4383 ('f', 'force', None,
4382 _('remove (and delete) file even if added or modified')),
4384 _('remove (and delete) file even if added or modified')),
4383 ] + walkopts,
4385 ] + walkopts,
4384 _('[OPTION]... FILE...'))
4386 _('[OPTION]... FILE...'))
4385 def remove(ui, repo, *pats, **opts):
4387 def remove(ui, repo, *pats, **opts):
4386 """remove the specified files on the next commit
4388 """remove the specified files on the next commit
4387
4389
4388 Schedule the indicated files for removal from the current branch.
4390 Schedule the indicated files for removal from the current branch.
4389
4391
4390 This command schedules the files to be removed at the next commit.
4392 This command schedules the files to be removed at the next commit.
4391 To undo a remove before that, see :hg:`revert`. To undo added
4393 To undo a remove before that, see :hg:`revert`. To undo added
4392 files, see :hg:`forget`.
4394 files, see :hg:`forget`.
4393
4395
4394 .. container:: verbose
4396 .. container:: verbose
4395
4397
4396 -A/--after can be used to remove only files that have already
4398 -A/--after can be used to remove only files that have already
4397 been deleted, -f/--force can be used to force deletion, and -Af
4399 been deleted, -f/--force can be used to force deletion, and -Af
4398 can be used to remove files from the next revision without
4400 can be used to remove files from the next revision without
4399 deleting them from the working directory.
4401 deleting them from the working directory.
4400
4402
4401 The following table details the behavior of remove for different
4403 The following table details the behavior of remove for different
4402 file states (columns) and option combinations (rows). The file
4404 file states (columns) and option combinations (rows). The file
4403 states are Added [A], Clean [C], Modified [M] and Missing [!]
4405 states are Added [A], Clean [C], Modified [M] and Missing [!]
4404 (as reported by :hg:`status`). The actions are Warn, Remove
4406 (as reported by :hg:`status`). The actions are Warn, Remove
4405 (from branch) and Delete (from disk):
4407 (from branch) and Delete (from disk):
4406
4408
4407 ======= == == == ==
4409 ======= == == == ==
4408 A C M !
4410 A C M !
4409 ======= == == == ==
4411 ======= == == == ==
4410 none W RD W R
4412 none W RD W R
4411 -f R RD RD R
4413 -f R RD RD R
4412 -A W W W R
4414 -A W W W R
4413 -Af R R R R
4415 -Af R R R R
4414 ======= == == == ==
4416 ======= == == == ==
4415
4417
4416 Note that remove never deletes files in Added [A] state from the
4418 Note that remove never deletes files in Added [A] state from the
4417 working directory, not even if option --force is specified.
4419 working directory, not even if option --force is specified.
4418
4420
4419 Returns 0 on success, 1 if any warnings encountered.
4421 Returns 0 on success, 1 if any warnings encountered.
4420 """
4422 """
4421
4423
4422 ret = 0
4424 ret = 0
4423 after, force = opts.get('after'), opts.get('force')
4425 after, force = opts.get('after'), opts.get('force')
4424 if not pats and not after:
4426 if not pats and not after:
4425 raise util.Abort(_('no files specified'))
4427 raise util.Abort(_('no files specified'))
4426
4428
4427 m = scmutil.match(repo[None], pats, opts)
4429 m = scmutil.match(repo[None], pats, opts)
4428 s = repo.status(match=m, clean=True)
4430 s = repo.status(match=m, clean=True)
4429 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4431 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4430
4432
4431 for f in m.files():
4433 for f in m.files():
4432 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
4434 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
4433 if os.path.exists(m.rel(f)):
4435 if os.path.exists(m.rel(f)):
4434 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4436 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4435 ret = 1
4437 ret = 1
4436
4438
4437 if force:
4439 if force:
4438 list = modified + deleted + clean + added
4440 list = modified + deleted + clean + added
4439 elif after:
4441 elif after:
4440 list = deleted
4442 list = deleted
4441 for f in modified + added + clean:
4443 for f in modified + added + clean:
4442 ui.warn(_('not removing %s: file still exists (use -f'
4444 ui.warn(_('not removing %s: file still exists (use -f'
4443 ' to force removal)\n') % m.rel(f))
4445 ' to force removal)\n') % m.rel(f))
4444 ret = 1
4446 ret = 1
4445 else:
4447 else:
4446 list = deleted + clean
4448 list = deleted + clean
4447 for f in modified:
4449 for f in modified:
4448 ui.warn(_('not removing %s: file is modified (use -f'
4450 ui.warn(_('not removing %s: file is modified (use -f'
4449 ' to force removal)\n') % m.rel(f))
4451 ' to force removal)\n') % m.rel(f))
4450 ret = 1
4452 ret = 1
4451 for f in added:
4453 for f in added:
4452 ui.warn(_('not removing %s: file has been marked for add'
4454 ui.warn(_('not removing %s: file has been marked for add'
4453 ' (use forget to undo)\n') % m.rel(f))
4455 ' (use forget to undo)\n') % m.rel(f))
4454 ret = 1
4456 ret = 1
4455
4457
4456 for f in sorted(list):
4458 for f in sorted(list):
4457 if ui.verbose or not m.exact(f):
4459 if ui.verbose or not m.exact(f):
4458 ui.status(_('removing %s\n') % m.rel(f))
4460 ui.status(_('removing %s\n') % m.rel(f))
4459
4461
4460 wlock = repo.wlock()
4462 wlock = repo.wlock()
4461 try:
4463 try:
4462 if not after:
4464 if not after:
4463 for f in list:
4465 for f in list:
4464 if f in added:
4466 if f in added:
4465 continue # we never unlink added files on remove
4467 continue # we never unlink added files on remove
4466 try:
4468 try:
4467 util.unlinkpath(repo.wjoin(f))
4469 util.unlinkpath(repo.wjoin(f))
4468 except OSError, inst:
4470 except OSError, inst:
4469 if inst.errno != errno.ENOENT:
4471 if inst.errno != errno.ENOENT:
4470 raise
4472 raise
4471 repo[None].forget(list)
4473 repo[None].forget(list)
4472 finally:
4474 finally:
4473 wlock.release()
4475 wlock.release()
4474
4476
4475 return ret
4477 return ret
4476
4478
4477 @command('rename|move|mv',
4479 @command('rename|move|mv',
4478 [('A', 'after', None, _('record a rename that has already occurred')),
4480 [('A', 'after', None, _('record a rename that has already occurred')),
4479 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4481 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4480 ] + walkopts + dryrunopts,
4482 ] + walkopts + dryrunopts,
4481 _('[OPTION]... SOURCE... DEST'))
4483 _('[OPTION]... SOURCE... DEST'))
4482 def rename(ui, repo, *pats, **opts):
4484 def rename(ui, repo, *pats, **opts):
4483 """rename files; equivalent of copy + remove
4485 """rename files; equivalent of copy + remove
4484
4486
4485 Mark dest as copies of sources; mark sources for deletion. If dest
4487 Mark dest as copies of sources; mark sources for deletion. If dest
4486 is a directory, copies are put in that directory. If dest is a
4488 is a directory, copies are put in that directory. If dest is a
4487 file, there can only be one source.
4489 file, there can only be one source.
4488
4490
4489 By default, this command copies the contents of files as they
4491 By default, this command copies the contents of files as they
4490 exist in the working directory. If invoked with -A/--after, the
4492 exist in the working directory. If invoked with -A/--after, the
4491 operation is recorded, but no copying is performed.
4493 operation is recorded, but no copying is performed.
4492
4494
4493 This command takes effect at the next commit. To undo a rename
4495 This command takes effect at the next commit. To undo a rename
4494 before that, see :hg:`revert`.
4496 before that, see :hg:`revert`.
4495
4497
4496 Returns 0 on success, 1 if errors are encountered.
4498 Returns 0 on success, 1 if errors are encountered.
4497 """
4499 """
4498 wlock = repo.wlock(False)
4500 wlock = repo.wlock(False)
4499 try:
4501 try:
4500 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4502 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4501 finally:
4503 finally:
4502 wlock.release()
4504 wlock.release()
4503
4505
4504 @command('resolve',
4506 @command('resolve',
4505 [('a', 'all', None, _('select all unresolved files')),
4507 [('a', 'all', None, _('select all unresolved files')),
4506 ('l', 'list', None, _('list state of files needing merge')),
4508 ('l', 'list', None, _('list state of files needing merge')),
4507 ('m', 'mark', None, _('mark files as resolved')),
4509 ('m', 'mark', None, _('mark files as resolved')),
4508 ('u', 'unmark', None, _('mark files as unresolved')),
4510 ('u', 'unmark', None, _('mark files as unresolved')),
4509 ('n', 'no-status', None, _('hide status prefix'))]
4511 ('n', 'no-status', None, _('hide status prefix'))]
4510 + mergetoolopts + walkopts,
4512 + mergetoolopts + walkopts,
4511 _('[OPTION]... [FILE]...'))
4513 _('[OPTION]... [FILE]...'))
4512 def resolve(ui, repo, *pats, **opts):
4514 def resolve(ui, repo, *pats, **opts):
4513 """redo merges or set/view the merge status of files
4515 """redo merges or set/view the merge status of files
4514
4516
4515 Merges with unresolved conflicts are often the result of
4517 Merges with unresolved conflicts are often the result of
4516 non-interactive merging using the ``internal:merge`` configuration
4518 non-interactive merging using the ``internal:merge`` configuration
4517 setting, or a command-line merge tool like ``diff3``. The resolve
4519 setting, or a command-line merge tool like ``diff3``. The resolve
4518 command is used to manage the files involved in a merge, after
4520 command is used to manage the files involved in a merge, after
4519 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4521 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4520 working directory must have two parents).
4522 working directory must have two parents).
4521
4523
4522 The resolve command can be used in the following ways:
4524 The resolve command can be used in the following ways:
4523
4525
4524 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4526 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4525 files, discarding any previous merge attempts. Re-merging is not
4527 files, discarding any previous merge attempts. Re-merging is not
4526 performed for files already marked as resolved. Use ``--all/-a``
4528 performed for files already marked as resolved. Use ``--all/-a``
4527 to select all unresolved files. ``--tool`` can be used to specify
4529 to select all unresolved files. ``--tool`` can be used to specify
4528 the merge tool used for the given files. It overrides the HGMERGE
4530 the merge tool used for the given files. It overrides the HGMERGE
4529 environment variable and your configuration files. Previous file
4531 environment variable and your configuration files. Previous file
4530 contents are saved with a ``.orig`` suffix.
4532 contents are saved with a ``.orig`` suffix.
4531
4533
4532 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4534 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4533 (e.g. after having manually fixed-up the files). The default is
4535 (e.g. after having manually fixed-up the files). The default is
4534 to mark all unresolved files.
4536 to mark all unresolved files.
4535
4537
4536 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4538 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4537 default is to mark all resolved files.
4539 default is to mark all resolved files.
4538
4540
4539 - :hg:`resolve -l`: list files which had or still have conflicts.
4541 - :hg:`resolve -l`: list files which had or still have conflicts.
4540 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4542 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4541
4543
4542 Note that Mercurial will not let you commit files with unresolved
4544 Note that Mercurial will not let you commit files with unresolved
4543 merge conflicts. You must use :hg:`resolve -m ...` before you can
4545 merge conflicts. You must use :hg:`resolve -m ...` before you can
4544 commit after a conflicting merge.
4546 commit after a conflicting merge.
4545
4547
4546 Returns 0 on success, 1 if any files fail a resolve attempt.
4548 Returns 0 on success, 1 if any files fail a resolve attempt.
4547 """
4549 """
4548
4550
4549 all, mark, unmark, show, nostatus = \
4551 all, mark, unmark, show, nostatus = \
4550 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4552 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4551
4553
4552 if (show and (mark or unmark)) or (mark and unmark):
4554 if (show and (mark or unmark)) or (mark and unmark):
4553 raise util.Abort(_("too many options specified"))
4555 raise util.Abort(_("too many options specified"))
4554 if pats and all:
4556 if pats and all:
4555 raise util.Abort(_("can't specify --all and patterns"))
4557 raise util.Abort(_("can't specify --all and patterns"))
4556 if not (all or pats or show or mark or unmark):
4558 if not (all or pats or show or mark or unmark):
4557 raise util.Abort(_('no files or directories specified; '
4559 raise util.Abort(_('no files or directories specified; '
4558 'use --all to remerge all files'))
4560 'use --all to remerge all files'))
4559
4561
4560 ms = mergemod.mergestate(repo)
4562 ms = mergemod.mergestate(repo)
4561 m = scmutil.match(repo[None], pats, opts)
4563 m = scmutil.match(repo[None], pats, opts)
4562 ret = 0
4564 ret = 0
4563
4565
4564 for f in ms:
4566 for f in ms:
4565 if m(f):
4567 if m(f):
4566 if show:
4568 if show:
4567 if nostatus:
4569 if nostatus:
4568 ui.write("%s\n" % f)
4570 ui.write("%s\n" % f)
4569 else:
4571 else:
4570 ui.write("%s %s\n" % (ms[f].upper(), f),
4572 ui.write("%s %s\n" % (ms[f].upper(), f),
4571 label='resolve.' +
4573 label='resolve.' +
4572 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4574 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4573 elif mark:
4575 elif mark:
4574 ms.mark(f, "r")
4576 ms.mark(f, "r")
4575 elif unmark:
4577 elif unmark:
4576 ms.mark(f, "u")
4578 ms.mark(f, "u")
4577 else:
4579 else:
4578 wctx = repo[None]
4580 wctx = repo[None]
4579 mctx = wctx.parents()[-1]
4581 mctx = wctx.parents()[-1]
4580
4582
4581 # backup pre-resolve (merge uses .orig for its own purposes)
4583 # backup pre-resolve (merge uses .orig for its own purposes)
4582 a = repo.wjoin(f)
4584 a = repo.wjoin(f)
4583 util.copyfile(a, a + ".resolve")
4585 util.copyfile(a, a + ".resolve")
4584
4586
4585 try:
4587 try:
4586 # resolve file
4588 # resolve file
4587 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4589 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4588 if ms.resolve(f, wctx, mctx):
4590 if ms.resolve(f, wctx, mctx):
4589 ret = 1
4591 ret = 1
4590 finally:
4592 finally:
4591 ui.setconfig('ui', 'forcemerge', '')
4593 ui.setconfig('ui', 'forcemerge', '')
4592
4594
4593 # replace filemerge's .orig file with our resolve file
4595 # replace filemerge's .orig file with our resolve file
4594 util.rename(a + ".resolve", a + ".orig")
4596 util.rename(a + ".resolve", a + ".orig")
4595
4597
4596 ms.commit()
4598 ms.commit()
4597 return ret
4599 return ret
4598
4600
4599 @command('revert',
4601 @command('revert',
4600 [('a', 'all', None, _('revert all changes when no arguments given')),
4602 [('a', 'all', None, _('revert all changes when no arguments given')),
4601 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4603 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4602 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4604 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4603 ('C', 'no-backup', None, _('do not save backup copies of files')),
4605 ('C', 'no-backup', None, _('do not save backup copies of files')),
4604 ] + walkopts + dryrunopts,
4606 ] + walkopts + dryrunopts,
4605 _('[OPTION]... [-r REV] [NAME]...'))
4607 _('[OPTION]... [-r REV] [NAME]...'))
4606 def revert(ui, repo, *pats, **opts):
4608 def revert(ui, repo, *pats, **opts):
4607 """restore files to their checkout state
4609 """restore files to their checkout state
4608
4610
4609 .. note::
4611 .. note::
4610 To check out earlier revisions, you should use :hg:`update REV`.
4612 To check out earlier revisions, you should use :hg:`update REV`.
4611 To cancel a merge (and lose your changes), use :hg:`update --clean .`.
4613 To cancel a merge (and lose your changes), use :hg:`update --clean .`.
4612
4614
4613 With no revision specified, revert the specified files or directories
4615 With no revision specified, revert the specified files or directories
4614 to the contents they had in the parent of the working directory.
4616 to the contents they had in the parent of the working directory.
4615 This restores the contents of files to an unmodified
4617 This restores the contents of files to an unmodified
4616 state and unschedules adds, removes, copies, and renames. If the
4618 state and unschedules adds, removes, copies, and renames. If the
4617 working directory has two parents, you must explicitly specify a
4619 working directory has two parents, you must explicitly specify a
4618 revision.
4620 revision.
4619
4621
4620 Using the -r/--rev or -d/--date options, revert the given files or
4622 Using the -r/--rev or -d/--date options, revert the given files or
4621 directories to their states as of a specific revision. Because
4623 directories to their states as of a specific revision. Because
4622 revert does not change the working directory parents, this will
4624 revert does not change the working directory parents, this will
4623 cause these files to appear modified. This can be helpful to "back
4625 cause these files to appear modified. This can be helpful to "back
4624 out" some or all of an earlier change. See :hg:`backout` for a
4626 out" some or all of an earlier change. See :hg:`backout` for a
4625 related method.
4627 related method.
4626
4628
4627 Modified files are saved with a .orig suffix before reverting.
4629 Modified files are saved with a .orig suffix before reverting.
4628 To disable these backups, use --no-backup.
4630 To disable these backups, use --no-backup.
4629
4631
4630 See :hg:`help dates` for a list of formats valid for -d/--date.
4632 See :hg:`help dates` for a list of formats valid for -d/--date.
4631
4633
4632 Returns 0 on success.
4634 Returns 0 on success.
4633 """
4635 """
4634
4636
4635 if opts.get("date"):
4637 if opts.get("date"):
4636 if opts.get("rev"):
4638 if opts.get("rev"):
4637 raise util.Abort(_("you can't specify a revision and a date"))
4639 raise util.Abort(_("you can't specify a revision and a date"))
4638 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
4640 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
4639
4641
4640 parent, p2 = repo.dirstate.parents()
4642 parent, p2 = repo.dirstate.parents()
4641 if not opts.get('rev') and p2 != nullid:
4643 if not opts.get('rev') and p2 != nullid:
4642 # revert after merge is a trap for new users (issue2915)
4644 # revert after merge is a trap for new users (issue2915)
4643 raise util.Abort(_('uncommitted merge with no revision specified'),
4645 raise util.Abort(_('uncommitted merge with no revision specified'),
4644 hint=_('use "hg update" or see "hg help revert"'))
4646 hint=_('use "hg update" or see "hg help revert"'))
4645
4647
4646 ctx = scmutil.revsingle(repo, opts.get('rev'))
4648 ctx = scmutil.revsingle(repo, opts.get('rev'))
4647 node = ctx.node()
4649 node = ctx.node()
4648
4650
4649 if not pats and not opts.get('all'):
4651 if not pats and not opts.get('all'):
4650 msg = _("no files or directories specified")
4652 msg = _("no files or directories specified")
4651 if p2 != nullid:
4653 if p2 != nullid:
4652 hint = _("uncommitted merge, use --all to discard all changes,"
4654 hint = _("uncommitted merge, use --all to discard all changes,"
4653 " or 'hg update -C .' to abort the merge")
4655 " or 'hg update -C .' to abort the merge")
4654 raise util.Abort(msg, hint=hint)
4656 raise util.Abort(msg, hint=hint)
4655 dirty = util.any(repo.status())
4657 dirty = util.any(repo.status())
4656 if node != parent:
4658 if node != parent:
4657 if dirty:
4659 if dirty:
4658 hint = _("uncommitted changes, use --all to discard all"
4660 hint = _("uncommitted changes, use --all to discard all"
4659 " changes, or 'hg update %s' to update") % ctx.rev()
4661 " changes, or 'hg update %s' to update") % ctx.rev()
4660 else:
4662 else:
4661 hint = _("use --all to revert all files,"
4663 hint = _("use --all to revert all files,"
4662 " or 'hg update %s' to update") % ctx.rev()
4664 " or 'hg update %s' to update") % ctx.rev()
4663 elif dirty:
4665 elif dirty:
4664 hint = _("uncommitted changes, use --all to discard all changes")
4666 hint = _("uncommitted changes, use --all to discard all changes")
4665 else:
4667 else:
4666 hint = _("use --all to revert all files")
4668 hint = _("use --all to revert all files")
4667 raise util.Abort(msg, hint=hint)
4669 raise util.Abort(msg, hint=hint)
4668
4670
4669 mf = ctx.manifest()
4671 mf = ctx.manifest()
4670 if node == parent:
4672 if node == parent:
4671 pmf = mf
4673 pmf = mf
4672 else:
4674 else:
4673 pmf = None
4675 pmf = None
4674
4676
4675 # need all matching names in dirstate and manifest of target rev,
4677 # need all matching names in dirstate and manifest of target rev,
4676 # so have to walk both. do not print errors if files exist in one
4678 # so have to walk both. do not print errors if files exist in one
4677 # but not other.
4679 # but not other.
4678
4680
4679 names = {}
4681 names = {}
4680
4682
4681 wlock = repo.wlock()
4683 wlock = repo.wlock()
4682 try:
4684 try:
4683 # walk dirstate.
4685 # walk dirstate.
4684
4686
4685 m = scmutil.match(repo[None], pats, opts)
4687 m = scmutil.match(repo[None], pats, opts)
4686 m.bad = lambda x, y: False
4688 m.bad = lambda x, y: False
4687 for abs in repo.walk(m):
4689 for abs in repo.walk(m):
4688 names[abs] = m.rel(abs), m.exact(abs)
4690 names[abs] = m.rel(abs), m.exact(abs)
4689
4691
4690 # walk target manifest.
4692 # walk target manifest.
4691
4693
4692 def badfn(path, msg):
4694 def badfn(path, msg):
4693 if path in names:
4695 if path in names:
4694 return
4696 return
4695 if path in repo[node].substate:
4697 if path in repo[node].substate:
4696 ui.warn("%s: %s\n" % (m.rel(path),
4698 ui.warn("%s: %s\n" % (m.rel(path),
4697 'reverting subrepos is unsupported'))
4699 'reverting subrepos is unsupported'))
4698 return
4700 return
4699 path_ = path + '/'
4701 path_ = path + '/'
4700 for f in names:
4702 for f in names:
4701 if f.startswith(path_):
4703 if f.startswith(path_):
4702 return
4704 return
4703 ui.warn("%s: %s\n" % (m.rel(path), msg))
4705 ui.warn("%s: %s\n" % (m.rel(path), msg))
4704
4706
4705 m = scmutil.match(repo[node], pats, opts)
4707 m = scmutil.match(repo[node], pats, opts)
4706 m.bad = badfn
4708 m.bad = badfn
4707 for abs in repo[node].walk(m):
4709 for abs in repo[node].walk(m):
4708 if abs not in names:
4710 if abs not in names:
4709 names[abs] = m.rel(abs), m.exact(abs)
4711 names[abs] = m.rel(abs), m.exact(abs)
4710
4712
4711 m = scmutil.matchfiles(repo, names)
4713 m = scmutil.matchfiles(repo, names)
4712 changes = repo.status(match=m)[:4]
4714 changes = repo.status(match=m)[:4]
4713 modified, added, removed, deleted = map(set, changes)
4715 modified, added, removed, deleted = map(set, changes)
4714
4716
4715 # if f is a rename, also revert the source
4717 # if f is a rename, also revert the source
4716 cwd = repo.getcwd()
4718 cwd = repo.getcwd()
4717 for f in added:
4719 for f in added:
4718 src = repo.dirstate.copied(f)
4720 src = repo.dirstate.copied(f)
4719 if src and src not in names and repo.dirstate[src] == 'r':
4721 if src and src not in names and repo.dirstate[src] == 'r':
4720 removed.add(src)
4722 removed.add(src)
4721 names[src] = (repo.pathto(src, cwd), True)
4723 names[src] = (repo.pathto(src, cwd), True)
4722
4724
4723 def removeforget(abs):
4725 def removeforget(abs):
4724 if repo.dirstate[abs] == 'a':
4726 if repo.dirstate[abs] == 'a':
4725 return _('forgetting %s\n')
4727 return _('forgetting %s\n')
4726 return _('removing %s\n')
4728 return _('removing %s\n')
4727
4729
4728 revert = ([], _('reverting %s\n'))
4730 revert = ([], _('reverting %s\n'))
4729 add = ([], _('adding %s\n'))
4731 add = ([], _('adding %s\n'))
4730 remove = ([], removeforget)
4732 remove = ([], removeforget)
4731 undelete = ([], _('undeleting %s\n'))
4733 undelete = ([], _('undeleting %s\n'))
4732
4734
4733 disptable = (
4735 disptable = (
4734 # dispatch table:
4736 # dispatch table:
4735 # file state
4737 # file state
4736 # action if in target manifest
4738 # action if in target manifest
4737 # action if not in target manifest
4739 # action if not in target manifest
4738 # make backup if in target manifest
4740 # make backup if in target manifest
4739 # make backup if not in target manifest
4741 # make backup if not in target manifest
4740 (modified, revert, remove, True, True),
4742 (modified, revert, remove, True, True),
4741 (added, revert, remove, True, False),
4743 (added, revert, remove, True, False),
4742 (removed, undelete, None, False, False),
4744 (removed, undelete, None, False, False),
4743 (deleted, revert, remove, False, False),
4745 (deleted, revert, remove, False, False),
4744 )
4746 )
4745
4747
4746 for abs, (rel, exact) in sorted(names.items()):
4748 for abs, (rel, exact) in sorted(names.items()):
4747 mfentry = mf.get(abs)
4749 mfentry = mf.get(abs)
4748 target = repo.wjoin(abs)
4750 target = repo.wjoin(abs)
4749 def handle(xlist, dobackup):
4751 def handle(xlist, dobackup):
4750 xlist[0].append(abs)
4752 xlist[0].append(abs)
4751 if (dobackup and not opts.get('no_backup') and
4753 if (dobackup and not opts.get('no_backup') and
4752 os.path.lexists(target)):
4754 os.path.lexists(target)):
4753 bakname = "%s.orig" % rel
4755 bakname = "%s.orig" % rel
4754 ui.note(_('saving current version of %s as %s\n') %
4756 ui.note(_('saving current version of %s as %s\n') %
4755 (rel, bakname))
4757 (rel, bakname))
4756 if not opts.get('dry_run'):
4758 if not opts.get('dry_run'):
4757 util.rename(target, bakname)
4759 util.rename(target, bakname)
4758 if ui.verbose or not exact:
4760 if ui.verbose or not exact:
4759 msg = xlist[1]
4761 msg = xlist[1]
4760 if not isinstance(msg, basestring):
4762 if not isinstance(msg, basestring):
4761 msg = msg(abs)
4763 msg = msg(abs)
4762 ui.status(msg % rel)
4764 ui.status(msg % rel)
4763 for table, hitlist, misslist, backuphit, backupmiss in disptable:
4765 for table, hitlist, misslist, backuphit, backupmiss in disptable:
4764 if abs not in table:
4766 if abs not in table:
4765 continue
4767 continue
4766 # file has changed in dirstate
4768 # file has changed in dirstate
4767 if mfentry:
4769 if mfentry:
4768 handle(hitlist, backuphit)
4770 handle(hitlist, backuphit)
4769 elif misslist is not None:
4771 elif misslist is not None:
4770 handle(misslist, backupmiss)
4772 handle(misslist, backupmiss)
4771 break
4773 break
4772 else:
4774 else:
4773 if abs not in repo.dirstate:
4775 if abs not in repo.dirstate:
4774 if mfentry:
4776 if mfentry:
4775 handle(add, True)
4777 handle(add, True)
4776 elif exact:
4778 elif exact:
4777 ui.warn(_('file not managed: %s\n') % rel)
4779 ui.warn(_('file not managed: %s\n') % rel)
4778 continue
4780 continue
4779 # file has not changed in dirstate
4781 # file has not changed in dirstate
4780 if node == parent:
4782 if node == parent:
4781 if exact:
4783 if exact:
4782 ui.warn(_('no changes needed to %s\n') % rel)
4784 ui.warn(_('no changes needed to %s\n') % rel)
4783 continue
4785 continue
4784 if pmf is None:
4786 if pmf is None:
4785 # only need parent manifest in this unlikely case,
4787 # only need parent manifest in this unlikely case,
4786 # so do not read by default
4788 # so do not read by default
4787 pmf = repo[parent].manifest()
4789 pmf = repo[parent].manifest()
4788 if abs in pmf and mfentry:
4790 if abs in pmf and mfentry:
4789 # if version of file is same in parent and target
4791 # if version of file is same in parent and target
4790 # manifests, do nothing
4792 # manifests, do nothing
4791 if (pmf[abs] != mfentry or
4793 if (pmf[abs] != mfentry or
4792 pmf.flags(abs) != mf.flags(abs)):
4794 pmf.flags(abs) != mf.flags(abs)):
4793 handle(revert, False)
4795 handle(revert, False)
4794 else:
4796 else:
4795 handle(remove, False)
4797 handle(remove, False)
4796
4798
4797 if not opts.get('dry_run'):
4799 if not opts.get('dry_run'):
4798 def checkout(f):
4800 def checkout(f):
4799 fc = ctx[f]
4801 fc = ctx[f]
4800 repo.wwrite(f, fc.data(), fc.flags())
4802 repo.wwrite(f, fc.data(), fc.flags())
4801
4803
4802 audit_path = scmutil.pathauditor(repo.root)
4804 audit_path = scmutil.pathauditor(repo.root)
4803 for f in remove[0]:
4805 for f in remove[0]:
4804 if repo.dirstate[f] == 'a':
4806 if repo.dirstate[f] == 'a':
4805 repo.dirstate.drop(f)
4807 repo.dirstate.drop(f)
4806 continue
4808 continue
4807 audit_path(f)
4809 audit_path(f)
4808 try:
4810 try:
4809 util.unlinkpath(repo.wjoin(f))
4811 util.unlinkpath(repo.wjoin(f))
4810 except OSError:
4812 except OSError:
4811 pass
4813 pass
4812 repo.dirstate.remove(f)
4814 repo.dirstate.remove(f)
4813
4815
4814 normal = None
4816 normal = None
4815 if node == parent:
4817 if node == parent:
4816 # We're reverting to our parent. If possible, we'd like status
4818 # We're reverting to our parent. If possible, we'd like status
4817 # to report the file as clean. We have to use normallookup for
4819 # to report the file as clean. We have to use normallookup for
4818 # merges to avoid losing information about merged/dirty files.
4820 # merges to avoid losing information about merged/dirty files.
4819 if p2 != nullid:
4821 if p2 != nullid:
4820 normal = repo.dirstate.normallookup
4822 normal = repo.dirstate.normallookup
4821 else:
4823 else:
4822 normal = repo.dirstate.normal
4824 normal = repo.dirstate.normal
4823 for f in revert[0]:
4825 for f in revert[0]:
4824 checkout(f)
4826 checkout(f)
4825 if normal:
4827 if normal:
4826 normal(f)
4828 normal(f)
4827
4829
4828 for f in add[0]:
4830 for f in add[0]:
4829 checkout(f)
4831 checkout(f)
4830 repo.dirstate.add(f)
4832 repo.dirstate.add(f)
4831
4833
4832 normal = repo.dirstate.normallookup
4834 normal = repo.dirstate.normallookup
4833 if node == parent and p2 == nullid:
4835 if node == parent and p2 == nullid:
4834 normal = repo.dirstate.normal
4836 normal = repo.dirstate.normal
4835 for f in undelete[0]:
4837 for f in undelete[0]:
4836 checkout(f)
4838 checkout(f)
4837 normal(f)
4839 normal(f)
4838
4840
4839 finally:
4841 finally:
4840 wlock.release()
4842 wlock.release()
4841
4843
4842 @command('rollback', dryrunopts +
4844 @command('rollback', dryrunopts +
4843 [('f', 'force', False, _('ignore safety measures'))])
4845 [('f', 'force', False, _('ignore safety measures'))])
4844 def rollback(ui, repo, **opts):
4846 def rollback(ui, repo, **opts):
4845 """roll back the last transaction (dangerous)
4847 """roll back the last transaction (dangerous)
4846
4848
4847 This command should be used with care. There is only one level of
4849 This command should be used with care. There is only one level of
4848 rollback, and there is no way to undo a rollback. It will also
4850 rollback, and there is no way to undo a rollback. It will also
4849 restore the dirstate at the time of the last transaction, losing
4851 restore the dirstate at the time of the last transaction, losing
4850 any dirstate changes since that time. This command does not alter
4852 any dirstate changes since that time. This command does not alter
4851 the working directory.
4853 the working directory.
4852
4854
4853 Transactions are used to encapsulate the effects of all commands
4855 Transactions are used to encapsulate the effects of all commands
4854 that create new changesets or propagate existing changesets into a
4856 that create new changesets or propagate existing changesets into a
4855 repository. For example, the following commands are transactional,
4857 repository. For example, the following commands are transactional,
4856 and their effects can be rolled back:
4858 and their effects can be rolled back:
4857
4859
4858 - commit
4860 - commit
4859 - import
4861 - import
4860 - pull
4862 - pull
4861 - push (with this repository as the destination)
4863 - push (with this repository as the destination)
4862 - unbundle
4864 - unbundle
4863
4865
4864 It's possible to lose data with rollback: commit, update back to
4866 It's possible to lose data with rollback: commit, update back to
4865 an older changeset, and then rollback. The update removes the
4867 an older changeset, and then rollback. The update removes the
4866 changes you committed from the working directory, and rollback
4868 changes you committed from the working directory, and rollback
4867 removes them from history. To avoid data loss, you must pass
4869 removes them from history. To avoid data loss, you must pass
4868 --force in this case.
4870 --force in this case.
4869
4871
4870 This command is not intended for use on public repositories. Once
4872 This command is not intended for use on public repositories. Once
4871 changes are visible for pull by other users, rolling a transaction
4873 changes are visible for pull by other users, rolling a transaction
4872 back locally is ineffective (someone else may already have pulled
4874 back locally is ineffective (someone else may already have pulled
4873 the changes). Furthermore, a race is possible with readers of the
4875 the changes). Furthermore, a race is possible with readers of the
4874 repository; for example an in-progress pull from the repository
4876 repository; for example an in-progress pull from the repository
4875 may fail if a rollback is performed.
4877 may fail if a rollback is performed.
4876
4878
4877 Returns 0 on success, 1 if no rollback data is available.
4879 Returns 0 on success, 1 if no rollback data is available.
4878 """
4880 """
4879 return repo.rollback(dryrun=opts.get('dry_run'),
4881 return repo.rollback(dryrun=opts.get('dry_run'),
4880 force=opts.get('force'))
4882 force=opts.get('force'))
4881
4883
4882 @command('root', [])
4884 @command('root', [])
4883 def root(ui, repo):
4885 def root(ui, repo):
4884 """print the root (top) of the current working directory
4886 """print the root (top) of the current working directory
4885
4887
4886 Print the root directory of the current repository.
4888 Print the root directory of the current repository.
4887
4889
4888 Returns 0 on success.
4890 Returns 0 on success.
4889 """
4891 """
4890 ui.write(repo.root + "\n")
4892 ui.write(repo.root + "\n")
4891
4893
4892 @command('^serve',
4894 @command('^serve',
4893 [('A', 'accesslog', '', _('name of access log file to write to'),
4895 [('A', 'accesslog', '', _('name of access log file to write to'),
4894 _('FILE')),
4896 _('FILE')),
4895 ('d', 'daemon', None, _('run server in background')),
4897 ('d', 'daemon', None, _('run server in background')),
4896 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
4898 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
4897 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
4899 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
4898 # use string type, then we can check if something was passed
4900 # use string type, then we can check if something was passed
4899 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
4901 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
4900 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
4902 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
4901 _('ADDR')),
4903 _('ADDR')),
4902 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
4904 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
4903 _('PREFIX')),
4905 _('PREFIX')),
4904 ('n', 'name', '',
4906 ('n', 'name', '',
4905 _('name to show in web pages (default: working directory)'), _('NAME')),
4907 _('name to show in web pages (default: working directory)'), _('NAME')),
4906 ('', 'web-conf', '',
4908 ('', 'web-conf', '',
4907 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
4909 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
4908 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
4910 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
4909 _('FILE')),
4911 _('FILE')),
4910 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
4912 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
4911 ('', 'stdio', None, _('for remote clients')),
4913 ('', 'stdio', None, _('for remote clients')),
4912 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
4914 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
4913 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
4915 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
4914 ('', 'style', '', _('template style to use'), _('STYLE')),
4916 ('', 'style', '', _('template style to use'), _('STYLE')),
4915 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4917 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4916 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
4918 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
4917 _('[OPTION]...'))
4919 _('[OPTION]...'))
4918 def serve(ui, repo, **opts):
4920 def serve(ui, repo, **opts):
4919 """start stand-alone webserver
4921 """start stand-alone webserver
4920
4922
4921 Start a local HTTP repository browser and pull server. You can use
4923 Start a local HTTP repository browser and pull server. You can use
4922 this for ad-hoc sharing and browsing of repositories. It is
4924 this for ad-hoc sharing and browsing of repositories. It is
4923 recommended to use a real web server to serve a repository for
4925 recommended to use a real web server to serve a repository for
4924 longer periods of time.
4926 longer periods of time.
4925
4927
4926 Please note that the server does not implement access control.
4928 Please note that the server does not implement access control.
4927 This means that, by default, anybody can read from the server and
4929 This means that, by default, anybody can read from the server and
4928 nobody can write to it by default. Set the ``web.allow_push``
4930 nobody can write to it by default. Set the ``web.allow_push``
4929 option to ``*`` to allow everybody to push to the server. You
4931 option to ``*`` to allow everybody to push to the server. You
4930 should use a real web server if you need to authenticate users.
4932 should use a real web server if you need to authenticate users.
4931
4933
4932 By default, the server logs accesses to stdout and errors to
4934 By default, the server logs accesses to stdout and errors to
4933 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
4935 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
4934 files.
4936 files.
4935
4937
4936 To have the server choose a free port number to listen on, specify
4938 To have the server choose a free port number to listen on, specify
4937 a port number of 0; in this case, the server will print the port
4939 a port number of 0; in this case, the server will print the port
4938 number it uses.
4940 number it uses.
4939
4941
4940 Returns 0 on success.
4942 Returns 0 on success.
4941 """
4943 """
4942
4944
4943 if opts["stdio"] and opts["cmdserver"]:
4945 if opts["stdio"] and opts["cmdserver"]:
4944 raise util.Abort(_("cannot use --stdio with --cmdserver"))
4946 raise util.Abort(_("cannot use --stdio with --cmdserver"))
4945
4947
4946 def checkrepo():
4948 def checkrepo():
4947 if repo is None:
4949 if repo is None:
4948 raise error.RepoError(_("There is no Mercurial repository here"
4950 raise error.RepoError(_("There is no Mercurial repository here"
4949 " (.hg not found)"))
4951 " (.hg not found)"))
4950
4952
4951 if opts["stdio"]:
4953 if opts["stdio"]:
4952 checkrepo()
4954 checkrepo()
4953 s = sshserver.sshserver(ui, repo)
4955 s = sshserver.sshserver(ui, repo)
4954 s.serve_forever()
4956 s.serve_forever()
4955
4957
4956 if opts["cmdserver"]:
4958 if opts["cmdserver"]:
4957 checkrepo()
4959 checkrepo()
4958 s = commandserver.server(ui, repo, opts["cmdserver"])
4960 s = commandserver.server(ui, repo, opts["cmdserver"])
4959 return s.serve()
4961 return s.serve()
4960
4962
4961 # this way we can check if something was given in the command-line
4963 # this way we can check if something was given in the command-line
4962 if opts.get('port'):
4964 if opts.get('port'):
4963 opts['port'] = util.getport(opts.get('port'))
4965 opts['port'] = util.getport(opts.get('port'))
4964
4966
4965 baseui = repo and repo.baseui or ui
4967 baseui = repo and repo.baseui or ui
4966 optlist = ("name templates style address port prefix ipv6"
4968 optlist = ("name templates style address port prefix ipv6"
4967 " accesslog errorlog certificate encoding")
4969 " accesslog errorlog certificate encoding")
4968 for o in optlist.split():
4970 for o in optlist.split():
4969 val = opts.get(o, '')
4971 val = opts.get(o, '')
4970 if val in (None, ''): # should check against default options instead
4972 if val in (None, ''): # should check against default options instead
4971 continue
4973 continue
4972 baseui.setconfig("web", o, val)
4974 baseui.setconfig("web", o, val)
4973 if repo and repo.ui != baseui:
4975 if repo and repo.ui != baseui:
4974 repo.ui.setconfig("web", o, val)
4976 repo.ui.setconfig("web", o, val)
4975
4977
4976 o = opts.get('web_conf') or opts.get('webdir_conf')
4978 o = opts.get('web_conf') or opts.get('webdir_conf')
4977 if not o:
4979 if not o:
4978 if not repo:
4980 if not repo:
4979 raise error.RepoError(_("There is no Mercurial repository"
4981 raise error.RepoError(_("There is no Mercurial repository"
4980 " here (.hg not found)"))
4982 " here (.hg not found)"))
4981 o = repo.root
4983 o = repo.root
4982
4984
4983 app = hgweb.hgweb(o, baseui=ui)
4985 app = hgweb.hgweb(o, baseui=ui)
4984
4986
4985 class service(object):
4987 class service(object):
4986 def init(self):
4988 def init(self):
4987 util.setsignalhandler()
4989 util.setsignalhandler()
4988 self.httpd = hgweb.server.create_server(ui, app)
4990 self.httpd = hgweb.server.create_server(ui, app)
4989
4991
4990 if opts['port'] and not ui.verbose:
4992 if opts['port'] and not ui.verbose:
4991 return
4993 return
4992
4994
4993 if self.httpd.prefix:
4995 if self.httpd.prefix:
4994 prefix = self.httpd.prefix.strip('/') + '/'
4996 prefix = self.httpd.prefix.strip('/') + '/'
4995 else:
4997 else:
4996 prefix = ''
4998 prefix = ''
4997
4999
4998 port = ':%d' % self.httpd.port
5000 port = ':%d' % self.httpd.port
4999 if port == ':80':
5001 if port == ':80':
5000 port = ''
5002 port = ''
5001
5003
5002 bindaddr = self.httpd.addr
5004 bindaddr = self.httpd.addr
5003 if bindaddr == '0.0.0.0':
5005 if bindaddr == '0.0.0.0':
5004 bindaddr = '*'
5006 bindaddr = '*'
5005 elif ':' in bindaddr: # IPv6
5007 elif ':' in bindaddr: # IPv6
5006 bindaddr = '[%s]' % bindaddr
5008 bindaddr = '[%s]' % bindaddr
5007
5009
5008 fqaddr = self.httpd.fqaddr
5010 fqaddr = self.httpd.fqaddr
5009 if ':' in fqaddr:
5011 if ':' in fqaddr:
5010 fqaddr = '[%s]' % fqaddr
5012 fqaddr = '[%s]' % fqaddr
5011 if opts['port']:
5013 if opts['port']:
5012 write = ui.status
5014 write = ui.status
5013 else:
5015 else:
5014 write = ui.write
5016 write = ui.write
5015 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5017 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5016 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5018 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5017
5019
5018 def run(self):
5020 def run(self):
5019 self.httpd.serve_forever()
5021 self.httpd.serve_forever()
5020
5022
5021 service = service()
5023 service = service()
5022
5024
5023 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5025 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5024
5026
5025 @command('showconfig|debugconfig',
5027 @command('showconfig|debugconfig',
5026 [('u', 'untrusted', None, _('show untrusted configuration options'))],
5028 [('u', 'untrusted', None, _('show untrusted configuration options'))],
5027 _('[-u] [NAME]...'))
5029 _('[-u] [NAME]...'))
5028 def showconfig(ui, repo, *values, **opts):
5030 def showconfig(ui, repo, *values, **opts):
5029 """show combined config settings from all hgrc files
5031 """show combined config settings from all hgrc files
5030
5032
5031 With no arguments, print names and values of all config items.
5033 With no arguments, print names and values of all config items.
5032
5034
5033 With one argument of the form section.name, print just the value
5035 With one argument of the form section.name, print just the value
5034 of that config item.
5036 of that config item.
5035
5037
5036 With multiple arguments, print names and values of all config
5038 With multiple arguments, print names and values of all config
5037 items with matching section names.
5039 items with matching section names.
5038
5040
5039 With --debug, the source (filename and line number) is printed
5041 With --debug, the source (filename and line number) is printed
5040 for each config item.
5042 for each config item.
5041
5043
5042 Returns 0 on success.
5044 Returns 0 on success.
5043 """
5045 """
5044
5046
5045 for f in scmutil.rcpath():
5047 for f in scmutil.rcpath():
5046 ui.debug('read config from: %s\n' % f)
5048 ui.debug('read config from: %s\n' % f)
5047 untrusted = bool(opts.get('untrusted'))
5049 untrusted = bool(opts.get('untrusted'))
5048 if values:
5050 if values:
5049 sections = [v for v in values if '.' not in v]
5051 sections = [v for v in values if '.' not in v]
5050 items = [v for v in values if '.' in v]
5052 items = [v for v in values if '.' in v]
5051 if len(items) > 1 or items and sections:
5053 if len(items) > 1 or items and sections:
5052 raise util.Abort(_('only one config item permitted'))
5054 raise util.Abort(_('only one config item permitted'))
5053 for section, name, value in ui.walkconfig(untrusted=untrusted):
5055 for section, name, value in ui.walkconfig(untrusted=untrusted):
5054 value = str(value).replace('\n', '\\n')
5056 value = str(value).replace('\n', '\\n')
5055 sectname = section + '.' + name
5057 sectname = section + '.' + name
5056 if values:
5058 if values:
5057 for v in values:
5059 for v in values:
5058 if v == section:
5060 if v == section:
5059 ui.debug('%s: ' %
5061 ui.debug('%s: ' %
5060 ui.configsource(section, name, untrusted))
5062 ui.configsource(section, name, untrusted))
5061 ui.write('%s=%s\n' % (sectname, value))
5063 ui.write('%s=%s\n' % (sectname, value))
5062 elif v == sectname:
5064 elif v == sectname:
5063 ui.debug('%s: ' %
5065 ui.debug('%s: ' %
5064 ui.configsource(section, name, untrusted))
5066 ui.configsource(section, name, untrusted))
5065 ui.write(value, '\n')
5067 ui.write(value, '\n')
5066 else:
5068 else:
5067 ui.debug('%s: ' %
5069 ui.debug('%s: ' %
5068 ui.configsource(section, name, untrusted))
5070 ui.configsource(section, name, untrusted))
5069 ui.write('%s=%s\n' % (sectname, value))
5071 ui.write('%s=%s\n' % (sectname, value))
5070
5072
5071 @command('^status|st',
5073 @command('^status|st',
5072 [('A', 'all', None, _('show status of all files')),
5074 [('A', 'all', None, _('show status of all files')),
5073 ('m', 'modified', None, _('show only modified files')),
5075 ('m', 'modified', None, _('show only modified files')),
5074 ('a', 'added', None, _('show only added files')),
5076 ('a', 'added', None, _('show only added files')),
5075 ('r', 'removed', None, _('show only removed files')),
5077 ('r', 'removed', None, _('show only removed files')),
5076 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5078 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5077 ('c', 'clean', None, _('show only files without changes')),
5079 ('c', 'clean', None, _('show only files without changes')),
5078 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5080 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5079 ('i', 'ignored', None, _('show only ignored files')),
5081 ('i', 'ignored', None, _('show only ignored files')),
5080 ('n', 'no-status', None, _('hide status prefix')),
5082 ('n', 'no-status', None, _('hide status prefix')),
5081 ('C', 'copies', None, _('show source of copied files')),
5083 ('C', 'copies', None, _('show source of copied files')),
5082 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5084 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5083 ('', 'rev', [], _('show difference from revision'), _('REV')),
5085 ('', 'rev', [], _('show difference from revision'), _('REV')),
5084 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5086 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5085 ] + walkopts + subrepoopts,
5087 ] + walkopts + subrepoopts,
5086 _('[OPTION]... [FILE]...'))
5088 _('[OPTION]... [FILE]...'))
5087 def status(ui, repo, *pats, **opts):
5089 def status(ui, repo, *pats, **opts):
5088 """show changed files in the working directory
5090 """show changed files in the working directory
5089
5091
5090 Show status of files in the repository. If names are given, only
5092 Show status of files in the repository. If names are given, only
5091 files that match are shown. Files that are clean or ignored or
5093 files that match are shown. Files that are clean or ignored or
5092 the source of a copy/move operation, are not listed unless
5094 the source of a copy/move operation, are not listed unless
5093 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5095 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5094 Unless options described with "show only ..." are given, the
5096 Unless options described with "show only ..." are given, the
5095 options -mardu are used.
5097 options -mardu are used.
5096
5098
5097 Option -q/--quiet hides untracked (unknown and ignored) files
5099 Option -q/--quiet hides untracked (unknown and ignored) files
5098 unless explicitly requested with -u/--unknown or -i/--ignored.
5100 unless explicitly requested with -u/--unknown or -i/--ignored.
5099
5101
5100 .. note::
5102 .. note::
5101 status may appear to disagree with diff if permissions have
5103 status may appear to disagree with diff if permissions have
5102 changed or a merge has occurred. The standard diff format does
5104 changed or a merge has occurred. The standard diff format does
5103 not report permission changes and diff only reports changes
5105 not report permission changes and diff only reports changes
5104 relative to one merge parent.
5106 relative to one merge parent.
5105
5107
5106 If one revision is given, it is used as the base revision.
5108 If one revision is given, it is used as the base revision.
5107 If two revisions are given, the differences between them are
5109 If two revisions are given, the differences between them are
5108 shown. The --change option can also be used as a shortcut to list
5110 shown. The --change option can also be used as a shortcut to list
5109 the changed files of a revision from its first parent.
5111 the changed files of a revision from its first parent.
5110
5112
5111 The codes used to show the status of files are::
5113 The codes used to show the status of files are::
5112
5114
5113 M = modified
5115 M = modified
5114 A = added
5116 A = added
5115 R = removed
5117 R = removed
5116 C = clean
5118 C = clean
5117 ! = missing (deleted by non-hg command, but still tracked)
5119 ! = missing (deleted by non-hg command, but still tracked)
5118 ? = not tracked
5120 ? = not tracked
5119 I = ignored
5121 I = ignored
5120 = origin of the previous file listed as A (added)
5122 = origin of the previous file listed as A (added)
5121
5123
5122 .. container:: verbose
5124 .. container:: verbose
5123
5125
5124 Examples:
5126 Examples:
5125
5127
5126 - show changes in the working directory relative to a changeset:
5128 - show changes in the working directory relative to a changeset:
5127
5129
5128 hg status --rev 9353
5130 hg status --rev 9353
5129
5131
5130 - show all changes including copies in an existing changeset::
5132 - show all changes including copies in an existing changeset::
5131
5133
5132 hg status --copies --change 9353
5134 hg status --copies --change 9353
5133
5135
5134 - get a NUL separated list of added files, suitable for xargs::
5136 - get a NUL separated list of added files, suitable for xargs::
5135
5137
5136 hg status -an0
5138 hg status -an0
5137
5139
5138 Returns 0 on success.
5140 Returns 0 on success.
5139 """
5141 """
5140
5142
5141 revs = opts.get('rev')
5143 revs = opts.get('rev')
5142 change = opts.get('change')
5144 change = opts.get('change')
5143
5145
5144 if revs and change:
5146 if revs and change:
5145 msg = _('cannot specify --rev and --change at the same time')
5147 msg = _('cannot specify --rev and --change at the same time')
5146 raise util.Abort(msg)
5148 raise util.Abort(msg)
5147 elif change:
5149 elif change:
5148 node2 = repo.lookup(change)
5150 node2 = repo.lookup(change)
5149 node1 = repo[node2].p1().node()
5151 node1 = repo[node2].p1().node()
5150 else:
5152 else:
5151 node1, node2 = scmutil.revpair(repo, revs)
5153 node1, node2 = scmutil.revpair(repo, revs)
5152
5154
5153 cwd = (pats and repo.getcwd()) or ''
5155 cwd = (pats and repo.getcwd()) or ''
5154 end = opts.get('print0') and '\0' or '\n'
5156 end = opts.get('print0') and '\0' or '\n'
5155 copy = {}
5157 copy = {}
5156 states = 'modified added removed deleted unknown ignored clean'.split()
5158 states = 'modified added removed deleted unknown ignored clean'.split()
5157 show = [k for k in states if opts.get(k)]
5159 show = [k for k in states if opts.get(k)]
5158 if opts.get('all'):
5160 if opts.get('all'):
5159 show += ui.quiet and (states[:4] + ['clean']) or states
5161 show += ui.quiet and (states[:4] + ['clean']) or states
5160 if not show:
5162 if not show:
5161 show = ui.quiet and states[:4] or states[:5]
5163 show = ui.quiet and states[:4] or states[:5]
5162
5164
5163 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5165 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5164 'ignored' in show, 'clean' in show, 'unknown' in show,
5166 'ignored' in show, 'clean' in show, 'unknown' in show,
5165 opts.get('subrepos'))
5167 opts.get('subrepos'))
5166 changestates = zip(states, 'MAR!?IC', stat)
5168 changestates = zip(states, 'MAR!?IC', stat)
5167
5169
5168 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5170 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5169 ctxn = repo[nullid]
5171 ctxn = repo[nullid]
5170 ctx1 = repo[node1]
5172 ctx1 = repo[node1]
5171 ctx2 = repo[node2]
5173 ctx2 = repo[node2]
5172 added = stat[1]
5174 added = stat[1]
5173 if node2 is None:
5175 if node2 is None:
5174 added = stat[0] + stat[1] # merged?
5176 added = stat[0] + stat[1] # merged?
5175
5177
5176 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
5178 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
5177 if k in added:
5179 if k in added:
5178 copy[k] = v
5180 copy[k] = v
5179 elif v in added:
5181 elif v in added:
5180 copy[v] = k
5182 copy[v] = k
5181
5183
5182 for state, char, files in changestates:
5184 for state, char, files in changestates:
5183 if state in show:
5185 if state in show:
5184 format = "%s %%s%s" % (char, end)
5186 format = "%s %%s%s" % (char, end)
5185 if opts.get('no_status'):
5187 if opts.get('no_status'):
5186 format = "%%s%s" % end
5188 format = "%%s%s" % end
5187
5189
5188 for f in files:
5190 for f in files:
5189 ui.write(format % repo.pathto(f, cwd),
5191 ui.write(format % repo.pathto(f, cwd),
5190 label='status.' + state)
5192 label='status.' + state)
5191 if f in copy:
5193 if f in copy:
5192 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
5194 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
5193 label='status.copied')
5195 label='status.copied')
5194
5196
5195 @command('^summary|sum',
5197 @command('^summary|sum',
5196 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5198 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5197 def summary(ui, repo, **opts):
5199 def summary(ui, repo, **opts):
5198 """summarize working directory state
5200 """summarize working directory state
5199
5201
5200 This generates a brief summary of the working directory state,
5202 This generates a brief summary of the working directory state,
5201 including parents, branch, commit status, and available updates.
5203 including parents, branch, commit status, and available updates.
5202
5204
5203 With the --remote option, this will check the default paths for
5205 With the --remote option, this will check the default paths for
5204 incoming and outgoing changes. This can be time-consuming.
5206 incoming and outgoing changes. This can be time-consuming.
5205
5207
5206 Returns 0 on success.
5208 Returns 0 on success.
5207 """
5209 """
5208
5210
5209 ctx = repo[None]
5211 ctx = repo[None]
5210 parents = ctx.parents()
5212 parents = ctx.parents()
5211 pnode = parents[0].node()
5213 pnode = parents[0].node()
5212 marks = []
5214 marks = []
5213
5215
5214 for p in parents:
5216 for p in parents:
5215 # label with log.changeset (instead of log.parent) since this
5217 # label with log.changeset (instead of log.parent) since this
5216 # shows a working directory parent *changeset*:
5218 # shows a working directory parent *changeset*:
5217 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5219 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5218 label='log.changeset')
5220 label='log.changeset')
5219 ui.write(' '.join(p.tags()), label='log.tag')
5221 ui.write(' '.join(p.tags()), label='log.tag')
5220 if p.bookmarks():
5222 if p.bookmarks():
5221 marks.extend(p.bookmarks())
5223 marks.extend(p.bookmarks())
5222 if p.rev() == -1:
5224 if p.rev() == -1:
5223 if not len(repo):
5225 if not len(repo):
5224 ui.write(_(' (empty repository)'))
5226 ui.write(_(' (empty repository)'))
5225 else:
5227 else:
5226 ui.write(_(' (no revision checked out)'))
5228 ui.write(_(' (no revision checked out)'))
5227 ui.write('\n')
5229 ui.write('\n')
5228 if p.description():
5230 if p.description():
5229 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5231 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5230 label='log.summary')
5232 label='log.summary')
5231
5233
5232 branch = ctx.branch()
5234 branch = ctx.branch()
5233 bheads = repo.branchheads(branch)
5235 bheads = repo.branchheads(branch)
5234 m = _('branch: %s\n') % branch
5236 m = _('branch: %s\n') % branch
5235 if branch != 'default':
5237 if branch != 'default':
5236 ui.write(m, label='log.branch')
5238 ui.write(m, label='log.branch')
5237 else:
5239 else:
5238 ui.status(m, label='log.branch')
5240 ui.status(m, label='log.branch')
5239
5241
5240 if marks:
5242 if marks:
5241 current = repo._bookmarkcurrent
5243 current = repo._bookmarkcurrent
5242 ui.write(_('bookmarks:'), label='log.bookmark')
5244 ui.write(_('bookmarks:'), label='log.bookmark')
5243 if current is not None:
5245 if current is not None:
5244 try:
5246 try:
5245 marks.remove(current)
5247 marks.remove(current)
5246 ui.write(' *' + current, label='bookmarks.current')
5248 ui.write(' *' + current, label='bookmarks.current')
5247 except ValueError:
5249 except ValueError:
5248 # current bookmark not in parent ctx marks
5250 # current bookmark not in parent ctx marks
5249 pass
5251 pass
5250 for m in marks:
5252 for m in marks:
5251 ui.write(' ' + m, label='log.bookmark')
5253 ui.write(' ' + m, label='log.bookmark')
5252 ui.write('\n', label='log.bookmark')
5254 ui.write('\n', label='log.bookmark')
5253
5255
5254 st = list(repo.status(unknown=True))[:6]
5256 st = list(repo.status(unknown=True))[:6]
5255
5257
5256 c = repo.dirstate.copies()
5258 c = repo.dirstate.copies()
5257 copied, renamed = [], []
5259 copied, renamed = [], []
5258 for d, s in c.iteritems():
5260 for d, s in c.iteritems():
5259 if s in st[2]:
5261 if s in st[2]:
5260 st[2].remove(s)
5262 st[2].remove(s)
5261 renamed.append(d)
5263 renamed.append(d)
5262 else:
5264 else:
5263 copied.append(d)
5265 copied.append(d)
5264 if d in st[1]:
5266 if d in st[1]:
5265 st[1].remove(d)
5267 st[1].remove(d)
5266 st.insert(3, renamed)
5268 st.insert(3, renamed)
5267 st.insert(4, copied)
5269 st.insert(4, copied)
5268
5270
5269 ms = mergemod.mergestate(repo)
5271 ms = mergemod.mergestate(repo)
5270 st.append([f for f in ms if ms[f] == 'u'])
5272 st.append([f for f in ms if ms[f] == 'u'])
5271
5273
5272 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5274 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5273 st.append(subs)
5275 st.append(subs)
5274
5276
5275 labels = [ui.label(_('%d modified'), 'status.modified'),
5277 labels = [ui.label(_('%d modified'), 'status.modified'),
5276 ui.label(_('%d added'), 'status.added'),
5278 ui.label(_('%d added'), 'status.added'),
5277 ui.label(_('%d removed'), 'status.removed'),
5279 ui.label(_('%d removed'), 'status.removed'),
5278 ui.label(_('%d renamed'), 'status.copied'),
5280 ui.label(_('%d renamed'), 'status.copied'),
5279 ui.label(_('%d copied'), 'status.copied'),
5281 ui.label(_('%d copied'), 'status.copied'),
5280 ui.label(_('%d deleted'), 'status.deleted'),
5282 ui.label(_('%d deleted'), 'status.deleted'),
5281 ui.label(_('%d unknown'), 'status.unknown'),
5283 ui.label(_('%d unknown'), 'status.unknown'),
5282 ui.label(_('%d ignored'), 'status.ignored'),
5284 ui.label(_('%d ignored'), 'status.ignored'),
5283 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5285 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5284 ui.label(_('%d subrepos'), 'status.modified')]
5286 ui.label(_('%d subrepos'), 'status.modified')]
5285 t = []
5287 t = []
5286 for s, l in zip(st, labels):
5288 for s, l in zip(st, labels):
5287 if s:
5289 if s:
5288 t.append(l % len(s))
5290 t.append(l % len(s))
5289
5291
5290 t = ', '.join(t)
5292 t = ', '.join(t)
5291 cleanworkdir = False
5293 cleanworkdir = False
5292
5294
5293 if len(parents) > 1:
5295 if len(parents) > 1:
5294 t += _(' (merge)')
5296 t += _(' (merge)')
5295 elif branch != parents[0].branch():
5297 elif branch != parents[0].branch():
5296 t += _(' (new branch)')
5298 t += _(' (new branch)')
5297 elif (parents[0].extra().get('close') and
5299 elif (parents[0].extra().get('close') and
5298 pnode in repo.branchheads(branch, closed=True)):
5300 pnode in repo.branchheads(branch, closed=True)):
5299 t += _(' (head closed)')
5301 t += _(' (head closed)')
5300 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5302 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5301 t += _(' (clean)')
5303 t += _(' (clean)')
5302 cleanworkdir = True
5304 cleanworkdir = True
5303 elif pnode not in bheads:
5305 elif pnode not in bheads:
5304 t += _(' (new branch head)')
5306 t += _(' (new branch head)')
5305
5307
5306 if cleanworkdir:
5308 if cleanworkdir:
5307 ui.status(_('commit: %s\n') % t.strip())
5309 ui.status(_('commit: %s\n') % t.strip())
5308 else:
5310 else:
5309 ui.write(_('commit: %s\n') % t.strip())
5311 ui.write(_('commit: %s\n') % t.strip())
5310
5312
5311 # all ancestors of branch heads - all ancestors of parent = new csets
5313 # all ancestors of branch heads - all ancestors of parent = new csets
5312 new = [0] * len(repo)
5314 new = [0] * len(repo)
5313 cl = repo.changelog
5315 cl = repo.changelog
5314 for a in [cl.rev(n) for n in bheads]:
5316 for a in [cl.rev(n) for n in bheads]:
5315 new[a] = 1
5317 new[a] = 1
5316 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
5318 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
5317 new[a] = 1
5319 new[a] = 1
5318 for a in [p.rev() for p in parents]:
5320 for a in [p.rev() for p in parents]:
5319 if a >= 0:
5321 if a >= 0:
5320 new[a] = 0
5322 new[a] = 0
5321 for a in cl.ancestors(*[p.rev() for p in parents]):
5323 for a in cl.ancestors(*[p.rev() for p in parents]):
5322 new[a] = 0
5324 new[a] = 0
5323 new = sum(new)
5325 new = sum(new)
5324
5326
5325 if new == 0:
5327 if new == 0:
5326 ui.status(_('update: (current)\n'))
5328 ui.status(_('update: (current)\n'))
5327 elif pnode not in bheads:
5329 elif pnode not in bheads:
5328 ui.write(_('update: %d new changesets (update)\n') % new)
5330 ui.write(_('update: %d new changesets (update)\n') % new)
5329 else:
5331 else:
5330 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5332 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5331 (new, len(bheads)))
5333 (new, len(bheads)))
5332
5334
5333 if opts.get('remote'):
5335 if opts.get('remote'):
5334 t = []
5336 t = []
5335 source, branches = hg.parseurl(ui.expandpath('default'))
5337 source, branches = hg.parseurl(ui.expandpath('default'))
5336 other = hg.peer(repo, {}, source)
5338 other = hg.peer(repo, {}, source)
5337 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
5339 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
5338 ui.debug('comparing with %s\n' % util.hidepassword(source))
5340 ui.debug('comparing with %s\n' % util.hidepassword(source))
5339 repo.ui.pushbuffer()
5341 repo.ui.pushbuffer()
5340 commoninc = discovery.findcommonincoming(repo, other)
5342 commoninc = discovery.findcommonincoming(repo, other)
5341 _common, incoming, _rheads = commoninc
5343 _common, incoming, _rheads = commoninc
5342 repo.ui.popbuffer()
5344 repo.ui.popbuffer()
5343 if incoming:
5345 if incoming:
5344 t.append(_('1 or more incoming'))
5346 t.append(_('1 or more incoming'))
5345
5347
5346 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5348 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5347 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5349 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5348 if source != dest:
5350 if source != dest:
5349 other = hg.peer(repo, {}, dest)
5351 other = hg.peer(repo, {}, dest)
5350 commoninc = None
5352 commoninc = None
5351 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5353 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5352 repo.ui.pushbuffer()
5354 repo.ui.pushbuffer()
5353 common, outheads = discovery.findcommonoutgoing(repo, other,
5355 common, outheads = discovery.findcommonoutgoing(repo, other,
5354 commoninc=commoninc)
5356 commoninc=commoninc)
5355 repo.ui.popbuffer()
5357 repo.ui.popbuffer()
5356 o = repo.changelog.findmissing(common=common, heads=outheads)
5358 o = repo.changelog.findmissing(common=common, heads=outheads)
5357 if o:
5359 if o:
5358 t.append(_('%d outgoing') % len(o))
5360 t.append(_('%d outgoing') % len(o))
5359 if 'bookmarks' in other.listkeys('namespaces'):
5361 if 'bookmarks' in other.listkeys('namespaces'):
5360 lmarks = repo.listkeys('bookmarks')
5362 lmarks = repo.listkeys('bookmarks')
5361 rmarks = other.listkeys('bookmarks')
5363 rmarks = other.listkeys('bookmarks')
5362 diff = set(rmarks) - set(lmarks)
5364 diff = set(rmarks) - set(lmarks)
5363 if len(diff) > 0:
5365 if len(diff) > 0:
5364 t.append(_('%d incoming bookmarks') % len(diff))
5366 t.append(_('%d incoming bookmarks') % len(diff))
5365 diff = set(lmarks) - set(rmarks)
5367 diff = set(lmarks) - set(rmarks)
5366 if len(diff) > 0:
5368 if len(diff) > 0:
5367 t.append(_('%d outgoing bookmarks') % len(diff))
5369 t.append(_('%d outgoing bookmarks') % len(diff))
5368
5370
5369 if t:
5371 if t:
5370 ui.write(_('remote: %s\n') % (', '.join(t)))
5372 ui.write(_('remote: %s\n') % (', '.join(t)))
5371 else:
5373 else:
5372 ui.status(_('remote: (synced)\n'))
5374 ui.status(_('remote: (synced)\n'))
5373
5375
5374 @command('tag',
5376 @command('tag',
5375 [('f', 'force', None, _('force tag')),
5377 [('f', 'force', None, _('force tag')),
5376 ('l', 'local', None, _('make the tag local')),
5378 ('l', 'local', None, _('make the tag local')),
5377 ('r', 'rev', '', _('revision to tag'), _('REV')),
5379 ('r', 'rev', '', _('revision to tag'), _('REV')),
5378 ('', 'remove', None, _('remove a tag')),
5380 ('', 'remove', None, _('remove a tag')),
5379 # -l/--local is already there, commitopts cannot be used
5381 # -l/--local is already there, commitopts cannot be used
5380 ('e', 'edit', None, _('edit commit message')),
5382 ('e', 'edit', None, _('edit commit message')),
5381 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5383 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5382 ] + commitopts2,
5384 ] + commitopts2,
5383 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5385 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5384 def tag(ui, repo, name1, *names, **opts):
5386 def tag(ui, repo, name1, *names, **opts):
5385 """add one or more tags for the current or given revision
5387 """add one or more tags for the current or given revision
5386
5388
5387 Name a particular revision using <name>.
5389 Name a particular revision using <name>.
5388
5390
5389 Tags are used to name particular revisions of the repository and are
5391 Tags are used to name particular revisions of the repository and are
5390 very useful to compare different revisions, to go back to significant
5392 very useful to compare different revisions, to go back to significant
5391 earlier versions or to mark branch points as releases, etc. Changing
5393 earlier versions or to mark branch points as releases, etc. Changing
5392 an existing tag is normally disallowed; use -f/--force to override.
5394 an existing tag is normally disallowed; use -f/--force to override.
5393
5395
5394 If no revision is given, the parent of the working directory is
5396 If no revision is given, the parent of the working directory is
5395 used, or tip if no revision is checked out.
5397 used, or tip if no revision is checked out.
5396
5398
5397 To facilitate version control, distribution, and merging of tags,
5399 To facilitate version control, distribution, and merging of tags,
5398 they are stored as a file named ".hgtags" which is managed similarly
5400 they are stored as a file named ".hgtags" which is managed similarly
5399 to other project files and can be hand-edited if necessary. This
5401 to other project files and can be hand-edited if necessary. This
5400 also means that tagging creates a new commit. The file
5402 also means that tagging creates a new commit. The file
5401 ".hg/localtags" is used for local tags (not shared among
5403 ".hg/localtags" is used for local tags (not shared among
5402 repositories).
5404 repositories).
5403
5405
5404 Tag commits are usually made at the head of a branch. If the parent
5406 Tag commits are usually made at the head of a branch. If the parent
5405 of the working directory is not a branch head, :hg:`tag` aborts; use
5407 of the working directory is not a branch head, :hg:`tag` aborts; use
5406 -f/--force to force the tag commit to be based on a non-head
5408 -f/--force to force the tag commit to be based on a non-head
5407 changeset.
5409 changeset.
5408
5410
5409 See :hg:`help dates` for a list of formats valid for -d/--date.
5411 See :hg:`help dates` for a list of formats valid for -d/--date.
5410
5412
5411 Since tag names have priority over branch names during revision
5413 Since tag names have priority over branch names during revision
5412 lookup, using an existing branch name as a tag name is discouraged.
5414 lookup, using an existing branch name as a tag name is discouraged.
5413
5415
5414 Returns 0 on success.
5416 Returns 0 on success.
5415 """
5417 """
5416
5418
5417 rev_ = "."
5419 rev_ = "."
5418 names = [t.strip() for t in (name1,) + names]
5420 names = [t.strip() for t in (name1,) + names]
5419 if len(names) != len(set(names)):
5421 if len(names) != len(set(names)):
5420 raise util.Abort(_('tag names must be unique'))
5422 raise util.Abort(_('tag names must be unique'))
5421 for n in names:
5423 for n in names:
5422 if n in ['tip', '.', 'null']:
5424 if n in ['tip', '.', 'null']:
5423 raise util.Abort(_("the name '%s' is reserved") % n)
5425 raise util.Abort(_("the name '%s' is reserved") % n)
5424 if not n:
5426 if not n:
5425 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
5427 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
5426 if opts.get('rev') and opts.get('remove'):
5428 if opts.get('rev') and opts.get('remove'):
5427 raise util.Abort(_("--rev and --remove are incompatible"))
5429 raise util.Abort(_("--rev and --remove are incompatible"))
5428 if opts.get('rev'):
5430 if opts.get('rev'):
5429 rev_ = opts['rev']
5431 rev_ = opts['rev']
5430 message = opts.get('message')
5432 message = opts.get('message')
5431 if opts.get('remove'):
5433 if opts.get('remove'):
5432 expectedtype = opts.get('local') and 'local' or 'global'
5434 expectedtype = opts.get('local') and 'local' or 'global'
5433 for n in names:
5435 for n in names:
5434 if not repo.tagtype(n):
5436 if not repo.tagtype(n):
5435 raise util.Abort(_("tag '%s' does not exist") % n)
5437 raise util.Abort(_("tag '%s' does not exist") % n)
5436 if repo.tagtype(n) != expectedtype:
5438 if repo.tagtype(n) != expectedtype:
5437 if expectedtype == 'global':
5439 if expectedtype == 'global':
5438 raise util.Abort(_("tag '%s' is not a global tag") % n)
5440 raise util.Abort(_("tag '%s' is not a global tag") % n)
5439 else:
5441 else:
5440 raise util.Abort(_("tag '%s' is not a local tag") % n)
5442 raise util.Abort(_("tag '%s' is not a local tag") % n)
5441 rev_ = nullid
5443 rev_ = nullid
5442 if not message:
5444 if not message:
5443 # we don't translate commit messages
5445 # we don't translate commit messages
5444 message = 'Removed tag %s' % ', '.join(names)
5446 message = 'Removed tag %s' % ', '.join(names)
5445 elif not opts.get('force'):
5447 elif not opts.get('force'):
5446 for n in names:
5448 for n in names:
5447 if n in repo.tags():
5449 if n in repo.tags():
5448 raise util.Abort(_("tag '%s' already exists "
5450 raise util.Abort(_("tag '%s' already exists "
5449 "(use -f to force)") % n)
5451 "(use -f to force)") % n)
5450 if not opts.get('local'):
5452 if not opts.get('local'):
5451 p1, p2 = repo.dirstate.parents()
5453 p1, p2 = repo.dirstate.parents()
5452 if p2 != nullid:
5454 if p2 != nullid:
5453 raise util.Abort(_('uncommitted merge'))
5455 raise util.Abort(_('uncommitted merge'))
5454 bheads = repo.branchheads()
5456 bheads = repo.branchheads()
5455 if not opts.get('force') and bheads and p1 not in bheads:
5457 if not opts.get('force') and bheads and p1 not in bheads:
5456 raise util.Abort(_('not at a branch head (use -f to force)'))
5458 raise util.Abort(_('not at a branch head (use -f to force)'))
5457 r = scmutil.revsingle(repo, rev_).node()
5459 r = scmutil.revsingle(repo, rev_).node()
5458
5460
5459 if not message:
5461 if not message:
5460 # we don't translate commit messages
5462 # we don't translate commit messages
5461 message = ('Added tag %s for changeset %s' %
5463 message = ('Added tag %s for changeset %s' %
5462 (', '.join(names), short(r)))
5464 (', '.join(names), short(r)))
5463
5465
5464 date = opts.get('date')
5466 date = opts.get('date')
5465 if date:
5467 if date:
5466 date = util.parsedate(date)
5468 date = util.parsedate(date)
5467
5469
5468 if opts.get('edit'):
5470 if opts.get('edit'):
5469 message = ui.edit(message, ui.username())
5471 message = ui.edit(message, ui.username())
5470
5472
5471 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5473 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5472
5474
5473 @command('tags', [], '')
5475 @command('tags', [], '')
5474 def tags(ui, repo):
5476 def tags(ui, repo):
5475 """list repository tags
5477 """list repository tags
5476
5478
5477 This lists both regular and local tags. When the -v/--verbose
5479 This lists both regular and local tags. When the -v/--verbose
5478 switch is used, a third column "local" is printed for local tags.
5480 switch is used, a third column "local" is printed for local tags.
5479
5481
5480 Returns 0 on success.
5482 Returns 0 on success.
5481 """
5483 """
5482
5484
5483 hexfunc = ui.debugflag and hex or short
5485 hexfunc = ui.debugflag and hex or short
5484 tagtype = ""
5486 tagtype = ""
5485
5487
5486 for t, n in reversed(repo.tagslist()):
5488 for t, n in reversed(repo.tagslist()):
5487 if ui.quiet:
5489 if ui.quiet:
5488 ui.write("%s\n" % t, label='tags.normal')
5490 ui.write("%s\n" % t, label='tags.normal')
5489 continue
5491 continue
5490
5492
5491 hn = hexfunc(n)
5493 hn = hexfunc(n)
5492 r = "%5d:%s" % (repo.changelog.rev(n), hn)
5494 r = "%5d:%s" % (repo.changelog.rev(n), hn)
5493 rev = ui.label(r, 'log.changeset')
5495 rev = ui.label(r, 'log.changeset')
5494 spaces = " " * (30 - encoding.colwidth(t))
5496 spaces = " " * (30 - encoding.colwidth(t))
5495
5497
5496 tag = ui.label(t, 'tags.normal')
5498 tag = ui.label(t, 'tags.normal')
5497 if ui.verbose:
5499 if ui.verbose:
5498 if repo.tagtype(t) == 'local':
5500 if repo.tagtype(t) == 'local':
5499 tagtype = " local"
5501 tagtype = " local"
5500 tag = ui.label(t, 'tags.local')
5502 tag = ui.label(t, 'tags.local')
5501 else:
5503 else:
5502 tagtype = ""
5504 tagtype = ""
5503 ui.write("%s%s %s%s\n" % (tag, spaces, rev, tagtype))
5505 ui.write("%s%s %s%s\n" % (tag, spaces, rev, tagtype))
5504
5506
5505 @command('tip',
5507 @command('tip',
5506 [('p', 'patch', None, _('show patch')),
5508 [('p', 'patch', None, _('show patch')),
5507 ('g', 'git', None, _('use git extended diff format')),
5509 ('g', 'git', None, _('use git extended diff format')),
5508 ] + templateopts,
5510 ] + templateopts,
5509 _('[-p] [-g]'))
5511 _('[-p] [-g]'))
5510 def tip(ui, repo, **opts):
5512 def tip(ui, repo, **opts):
5511 """show the tip revision
5513 """show the tip revision
5512
5514
5513 The tip revision (usually just called the tip) is the changeset
5515 The tip revision (usually just called the tip) is the changeset
5514 most recently added to the repository (and therefore the most
5516 most recently added to the repository (and therefore the most
5515 recently changed head).
5517 recently changed head).
5516
5518
5517 If you have just made a commit, that commit will be the tip. If
5519 If you have just made a commit, that commit will be the tip. If
5518 you have just pulled changes from another repository, the tip of
5520 you have just pulled changes from another repository, the tip of
5519 that repository becomes the current tip. The "tip" tag is special
5521 that repository becomes the current tip. The "tip" tag is special
5520 and cannot be renamed or assigned to a different changeset.
5522 and cannot be renamed or assigned to a different changeset.
5521
5523
5522 Returns 0 on success.
5524 Returns 0 on success.
5523 """
5525 """
5524 displayer = cmdutil.show_changeset(ui, repo, opts)
5526 displayer = cmdutil.show_changeset(ui, repo, opts)
5525 displayer.show(repo[len(repo) - 1])
5527 displayer.show(repo[len(repo) - 1])
5526 displayer.close()
5528 displayer.close()
5527
5529
5528 @command('unbundle',
5530 @command('unbundle',
5529 [('u', 'update', None,
5531 [('u', 'update', None,
5530 _('update to new branch head if changesets were unbundled'))],
5532 _('update to new branch head if changesets were unbundled'))],
5531 _('[-u] FILE...'))
5533 _('[-u] FILE...'))
5532 def unbundle(ui, repo, fname1, *fnames, **opts):
5534 def unbundle(ui, repo, fname1, *fnames, **opts):
5533 """apply one or more changegroup files
5535 """apply one or more changegroup files
5534
5536
5535 Apply one or more compressed changegroup files generated by the
5537 Apply one or more compressed changegroup files generated by the
5536 bundle command.
5538 bundle command.
5537
5539
5538 Returns 0 on success, 1 if an update has unresolved files.
5540 Returns 0 on success, 1 if an update has unresolved files.
5539 """
5541 """
5540 fnames = (fname1,) + fnames
5542 fnames = (fname1,) + fnames
5541
5543
5542 lock = repo.lock()
5544 lock = repo.lock()
5543 wc = repo['.']
5545 wc = repo['.']
5544 try:
5546 try:
5545 for fname in fnames:
5547 for fname in fnames:
5546 f = url.open(ui, fname)
5548 f = url.open(ui, fname)
5547 gen = changegroup.readbundle(f, fname)
5549 gen = changegroup.readbundle(f, fname)
5548 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
5550 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
5549 lock=lock)
5551 lock=lock)
5550 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5552 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5551 finally:
5553 finally:
5552 lock.release()
5554 lock.release()
5553 return postincoming(ui, repo, modheads, opts.get('update'), None)
5555 return postincoming(ui, repo, modheads, opts.get('update'), None)
5554
5556
5555 @command('^update|up|checkout|co',
5557 @command('^update|up|checkout|co',
5556 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5558 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5557 ('c', 'check', None,
5559 ('c', 'check', None,
5558 _('update across branches if no uncommitted changes')),
5560 _('update across branches if no uncommitted changes')),
5559 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5561 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5560 ('r', 'rev', '', _('revision'), _('REV'))],
5562 ('r', 'rev', '', _('revision'), _('REV'))],
5561 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5563 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5562 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5564 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5563 """update working directory (or switch revisions)
5565 """update working directory (or switch revisions)
5564
5566
5565 Update the repository's working directory to the specified
5567 Update the repository's working directory to the specified
5566 changeset. If no changeset is specified, update to the tip of the
5568 changeset. If no changeset is specified, update to the tip of the
5567 current named branch.
5569 current named branch.
5568
5570
5569 If the changeset is not a descendant of the working directory's
5571 If the changeset is not a descendant of the working directory's
5570 parent, the update is aborted. With the -c/--check option, the
5572 parent, the update is aborted. With the -c/--check option, the
5571 working directory is checked for uncommitted changes; if none are
5573 working directory is checked for uncommitted changes; if none are
5572 found, the working directory is updated to the specified
5574 found, the working directory is updated to the specified
5573 changeset.
5575 changeset.
5574
5576
5575 Update sets the working directory's parent revison to the specified
5577 Update sets the working directory's parent revison to the specified
5576 changeset (see :hg:`help parents`).
5578 changeset (see :hg:`help parents`).
5577
5579
5578 The following rules apply when the working directory contains
5580 The following rules apply when the working directory contains
5579 uncommitted changes:
5581 uncommitted changes:
5580
5582
5581 1. If neither -c/--check nor -C/--clean is specified, and if
5583 1. If neither -c/--check nor -C/--clean is specified, and if
5582 the requested changeset is an ancestor or descendant of
5584 the requested changeset is an ancestor or descendant of
5583 the working directory's parent, the uncommitted changes
5585 the working directory's parent, the uncommitted changes
5584 are merged into the requested changeset and the merged
5586 are merged into the requested changeset and the merged
5585 result is left uncommitted. If the requested changeset is
5587 result is left uncommitted. If the requested changeset is
5586 not an ancestor or descendant (that is, it is on another
5588 not an ancestor or descendant (that is, it is on another
5587 branch), the update is aborted and the uncommitted changes
5589 branch), the update is aborted and the uncommitted changes
5588 are preserved.
5590 are preserved.
5589
5591
5590 2. With the -c/--check option, the update is aborted and the
5592 2. With the -c/--check option, the update is aborted and the
5591 uncommitted changes are preserved.
5593 uncommitted changes are preserved.
5592
5594
5593 3. With the -C/--clean option, uncommitted changes are discarded and
5595 3. With the -C/--clean option, uncommitted changes are discarded and
5594 the working directory is updated to the requested changeset.
5596 the working directory is updated to the requested changeset.
5595
5597
5596 Use null as the changeset to remove the working directory (like
5598 Use null as the changeset to remove the working directory (like
5597 :hg:`clone -U`).
5599 :hg:`clone -U`).
5598
5600
5599 If you want to revert just one file to an older revision, use
5601 If you want to revert just one file to an older revision, use
5600 :hg:`revert [-r REV] NAME`.
5602 :hg:`revert [-r REV] NAME`.
5601
5603
5602 See :hg:`help dates` for a list of formats valid for -d/--date.
5604 See :hg:`help dates` for a list of formats valid for -d/--date.
5603
5605
5604 Returns 0 on success, 1 if there are unresolved files.
5606 Returns 0 on success, 1 if there are unresolved files.
5605 """
5607 """
5606 if rev and node:
5608 if rev and node:
5607 raise util.Abort(_("please specify just one revision"))
5609 raise util.Abort(_("please specify just one revision"))
5608
5610
5609 if rev is None or rev == '':
5611 if rev is None or rev == '':
5610 rev = node
5612 rev = node
5611
5613
5612 # if we defined a bookmark, we have to remember the original bookmark name
5614 # if we defined a bookmark, we have to remember the original bookmark name
5613 brev = rev
5615 brev = rev
5614 rev = scmutil.revsingle(repo, rev, rev).rev()
5616 rev = scmutil.revsingle(repo, rev, rev).rev()
5615
5617
5616 if check and clean:
5618 if check and clean:
5617 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5619 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5618
5620
5619 if check:
5621 if check:
5620 # we could use dirty() but we can ignore merge and branch trivia
5622 # we could use dirty() but we can ignore merge and branch trivia
5621 c = repo[None]
5623 c = repo[None]
5622 if c.modified() or c.added() or c.removed():
5624 if c.modified() or c.added() or c.removed():
5623 raise util.Abort(_("uncommitted local changes"))
5625 raise util.Abort(_("uncommitted local changes"))
5624
5626
5625 if date:
5627 if date:
5626 if rev is not None:
5628 if rev is not None:
5627 raise util.Abort(_("you can't specify a revision and a date"))
5629 raise util.Abort(_("you can't specify a revision and a date"))
5628 rev = cmdutil.finddate(ui, repo, date)
5630 rev = cmdutil.finddate(ui, repo, date)
5629
5631
5630 if clean or check:
5632 if clean or check:
5631 ret = hg.clean(repo, rev)
5633 ret = hg.clean(repo, rev)
5632 else:
5634 else:
5633 ret = hg.update(repo, rev)
5635 ret = hg.update(repo, rev)
5634
5636
5635 if brev in repo._bookmarks:
5637 if brev in repo._bookmarks:
5636 bookmarks.setcurrent(repo, brev)
5638 bookmarks.setcurrent(repo, brev)
5637
5639
5638 return ret
5640 return ret
5639
5641
5640 @command('verify', [])
5642 @command('verify', [])
5641 def verify(ui, repo):
5643 def verify(ui, repo):
5642 """verify the integrity of the repository
5644 """verify the integrity of the repository
5643
5645
5644 Verify the integrity of the current repository.
5646 Verify the integrity of the current repository.
5645
5647
5646 This will perform an extensive check of the repository's
5648 This will perform an extensive check of the repository's
5647 integrity, validating the hashes and checksums of each entry in
5649 integrity, validating the hashes and checksums of each entry in
5648 the changelog, manifest, and tracked files, as well as the
5650 the changelog, manifest, and tracked files, as well as the
5649 integrity of their crosslinks and indices.
5651 integrity of their crosslinks and indices.
5650
5652
5651 Returns 0 on success, 1 if errors are encountered.
5653 Returns 0 on success, 1 if errors are encountered.
5652 """
5654 """
5653 return hg.verify(repo)
5655 return hg.verify(repo)
5654
5656
5655 @command('version', [])
5657 @command('version', [])
5656 def version_(ui):
5658 def version_(ui):
5657 """output version and copyright information"""
5659 """output version and copyright information"""
5658 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5660 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5659 % util.version())
5661 % util.version())
5660 ui.status(_(
5662 ui.status(_(
5661 "(see http://mercurial.selenic.com for more information)\n"
5663 "(see http://mercurial.selenic.com for more information)\n"
5662 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
5664 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
5663 "This is free software; see the source for copying conditions. "
5665 "This is free software; see the source for copying conditions. "
5664 "There is NO\nwarranty; "
5666 "There is NO\nwarranty; "
5665 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5667 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5666 ))
5668 ))
5667
5669
5668 norepo = ("clone init version help debugcommands debugcomplete"
5670 norepo = ("clone init version help debugcommands debugcomplete"
5669 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5671 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5670 " debugknown debuggetbundle debugbundle")
5672 " debugknown debuggetbundle debugbundle")
5671 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
5673 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
5672 " debugdata debugindex debugindexdot debugrevlog")
5674 " debugdata debugindex debugindexdot debugrevlog")
@@ -1,1923 +1,1924 b''
1 > do_push()
1 > do_push()
2 > {
2 > {
3 > user=$1
3 > user=$1
4 > shift
4 > shift
5 > echo "Pushing as user $user"
5 > echo "Pushing as user $user"
6 > echo 'hgrc = """'
6 > echo 'hgrc = """'
7 > sed -e 1,2d b/.hg/hgrc | grep -v fakegroups.py
7 > sed -e 1,2d b/.hg/hgrc | grep -v fakegroups.py
8 > echo '"""'
8 > echo '"""'
9 > if test -f acl.config; then
9 > if test -f acl.config; then
10 > echo 'acl.config = """'
10 > echo 'acl.config = """'
11 > cat acl.config
11 > cat acl.config
12 > echo '"""'
12 > echo '"""'
13 > fi
13 > fi
14 > # On AIX /etc/profile sets LOGNAME read-only. So
14 > # On AIX /etc/profile sets LOGNAME read-only. So
15 > # LOGNAME=$user hg --cws a --debug push ../b
15 > # LOGNAME=$user hg --cws a --debug push ../b
16 > # fails with "This variable is read only."
16 > # fails with "This variable is read only."
17 > # Use env to work around this.
17 > # Use env to work around this.
18 > env LOGNAME=$user hg --cwd a --debug push ../b
18 > env LOGNAME=$user hg --cwd a --debug push ../b
19 > hg --cwd b rollback
19 > hg --cwd b rollback
20 > hg --cwd b --quiet tip
20 > hg --cwd b --quiet tip
21 > echo
21 > echo
22 > }
22 > }
23
23
24 > init_config()
24 > init_config()
25 > {
25 > {
26 > cat > fakegroups.py <<EOF
26 > cat > fakegroups.py <<EOF
27 > from hgext import acl
27 > from hgext import acl
28 > def fakegetusers(ui, group):
28 > def fakegetusers(ui, group):
29 > try:
29 > try:
30 > return acl._getusersorig(ui, group)
30 > return acl._getusersorig(ui, group)
31 > except:
31 > except:
32 > return ["fred", "betty"]
32 > return ["fred", "betty"]
33 > acl._getusersorig = acl._getusers
33 > acl._getusersorig = acl._getusers
34 > acl._getusers = fakegetusers
34 > acl._getusers = fakegetusers
35 > EOF
35 > EOF
36 > rm -f acl.config
36 > rm -f acl.config
37 > cat > $config <<EOF
37 > cat > $config <<EOF
38 > [hooks]
38 > [hooks]
39 > pretxnchangegroup.acl = python:hgext.acl.hook
39 > pretxnchangegroup.acl = python:hgext.acl.hook
40 > [acl]
40 > [acl]
41 > sources = push
41 > sources = push
42 > [extensions]
42 > [extensions]
43 > f=`pwd`/fakegroups.py
43 > f=`pwd`/fakegroups.py
44 > EOF
44 > EOF
45 > }
45 > }
46
46
47 $ hg init a
47 $ hg init a
48 $ cd a
48 $ cd a
49 $ mkdir foo foo/Bar quux
49 $ mkdir foo foo/Bar quux
50 $ echo 'in foo' > foo/file.txt
50 $ echo 'in foo' > foo/file.txt
51 $ echo 'in foo/Bar' > foo/Bar/file.txt
51 $ echo 'in foo/Bar' > foo/Bar/file.txt
52 $ echo 'in quux' > quux/file.py
52 $ echo 'in quux' > quux/file.py
53 $ hg add -q
53 $ hg add -q
54 $ hg ci -m 'add files' -d '1000000 0'
54 $ hg ci -m 'add files' -d '1000000 0'
55 $ echo >> foo/file.txt
55 $ echo >> foo/file.txt
56 $ hg ci -m 'change foo/file' -d '1000001 0'
56 $ hg ci -m 'change foo/file' -d '1000001 0'
57 $ echo >> foo/Bar/file.txt
57 $ echo >> foo/Bar/file.txt
58 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
58 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
59 $ echo >> quux/file.py
59 $ echo >> quux/file.py
60 $ hg ci -m 'change quux/file' -d '1000003 0'
60 $ hg ci -m 'change quux/file' -d '1000003 0'
61 $ hg tip --quiet
61 $ hg tip --quiet
62 3:911600dab2ae
62 3:911600dab2ae
63
63
64 $ cd ..
64 $ cd ..
65 $ hg clone -r 0 a b
65 $ hg clone -r 0 a b
66 adding changesets
66 adding changesets
67 adding manifests
67 adding manifests
68 adding file changes
68 adding file changes
69 added 1 changesets with 3 changes to 3 files
69 added 1 changesets with 3 changes to 3 files
70 updating to branch default
70 updating to branch default
71 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
72
72
73 $ echo '[extensions]' >> $HGRCPATH
73 $ echo '[extensions]' >> $HGRCPATH
74 $ echo 'acl =' >> $HGRCPATH
74 $ echo 'acl =' >> $HGRCPATH
75
75
76 $ config=b/.hg/hgrc
76 $ config=b/.hg/hgrc
77
77
78 Extension disabled for lack of a hook
78 Extension disabled for lack of a hook
79
79
80 $ do_push fred
80 $ do_push fred
81 Pushing as user fred
81 Pushing as user fred
82 hgrc = """
82 hgrc = """
83 """
83 """
84 pushing to ../b
84 pushing to ../b
85 query 1; heads
85 query 1; heads
86 searching for changes
86 searching for changes
87 all remote heads known locally
87 all remote heads known locally
88 3 changesets found
88 3 changesets found
89 list of changesets:
89 list of changesets:
90 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
90 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
91 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
91 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
92 911600dab2ae7a9baff75958b84fe606851ce955
92 911600dab2ae7a9baff75958b84fe606851ce955
93 adding changesets
93 adding changesets
94 bundling: 1/3 changesets (33.33%)
94 bundling: 1/3 changesets (33.33%)
95 bundling: 2/3 changesets (66.67%)
95 bundling: 2/3 changesets (66.67%)
96 bundling: 3/3 changesets (100.00%)
96 bundling: 3/3 changesets (100.00%)
97 bundling: 1/3 manifests (33.33%)
97 bundling: 1/3 manifests (33.33%)
98 bundling: 2/3 manifests (66.67%)
98 bundling: 2/3 manifests (66.67%)
99 bundling: 3/3 manifests (100.00%)
99 bundling: 3/3 manifests (100.00%)
100 bundling: foo/Bar/file.txt 1/3 files (33.33%)
100 bundling: foo/Bar/file.txt 1/3 files (33.33%)
101 bundling: foo/file.txt 2/3 files (66.67%)
101 bundling: foo/file.txt 2/3 files (66.67%)
102 bundling: quux/file.py 3/3 files (100.00%)
102 bundling: quux/file.py 3/3 files (100.00%)
103 changesets: 1 chunks
103 changesets: 1 chunks
104 add changeset ef1ea85a6374
104 add changeset ef1ea85a6374
105 changesets: 2 chunks
105 changesets: 2 chunks
106 add changeset f9cafe1212c8
106 add changeset f9cafe1212c8
107 changesets: 3 chunks
107 changesets: 3 chunks
108 add changeset 911600dab2ae
108 add changeset 911600dab2ae
109 adding manifests
109 adding manifests
110 manifests: 1/3 chunks (33.33%)
110 manifests: 1/3 chunks (33.33%)
111 manifests: 2/3 chunks (66.67%)
111 manifests: 2/3 chunks (66.67%)
112 manifests: 3/3 chunks (100.00%)
112 manifests: 3/3 chunks (100.00%)
113 adding file changes
113 adding file changes
114 adding foo/Bar/file.txt revisions
114 adding foo/Bar/file.txt revisions
115 files: 1/3 chunks (33.33%)
115 files: 1/3 chunks (33.33%)
116 adding foo/file.txt revisions
116 adding foo/file.txt revisions
117 files: 2/3 chunks (66.67%)
117 files: 2/3 chunks (66.67%)
118 adding quux/file.py revisions
118 adding quux/file.py revisions
119 files: 3/3 chunks (100.00%)
119 files: 3/3 chunks (100.00%)
120 added 3 changesets with 3 changes to 3 files
120 added 3 changesets with 3 changes to 3 files
121 updating the branch cache
121 updating the branch cache
122 checking for updated bookmarks
122 checking for updated bookmarks
123 repository tip rolled back to revision 0 (undo push)
123 repository tip rolled back to revision 0 (undo push)
124 0:6675d58eff77
124 0:6675d58eff77
125
125
126
126
127 $ echo '[hooks]' >> $config
127 $ echo '[hooks]' >> $config
128 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
128 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
129
129
130 Extension disabled for lack of acl.sources
130 Extension disabled for lack of acl.sources
131
131
132 $ do_push fred
132 $ do_push fred
133 Pushing as user fred
133 Pushing as user fred
134 hgrc = """
134 hgrc = """
135 [hooks]
135 [hooks]
136 pretxnchangegroup.acl = python:hgext.acl.hook
136 pretxnchangegroup.acl = python:hgext.acl.hook
137 """
137 """
138 pushing to ../b
138 pushing to ../b
139 query 1; heads
139 query 1; heads
140 searching for changes
140 searching for changes
141 all remote heads known locally
141 all remote heads known locally
142 invalidating branch cache (tip differs)
142 invalidating branch cache (tip differs)
143 3 changesets found
143 3 changesets found
144 list of changesets:
144 list of changesets:
145 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
145 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
146 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
146 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
147 911600dab2ae7a9baff75958b84fe606851ce955
147 911600dab2ae7a9baff75958b84fe606851ce955
148 adding changesets
148 adding changesets
149 bundling: 1/3 changesets (33.33%)
149 bundling: 1/3 changesets (33.33%)
150 bundling: 2/3 changesets (66.67%)
150 bundling: 2/3 changesets (66.67%)
151 bundling: 3/3 changesets (100.00%)
151 bundling: 3/3 changesets (100.00%)
152 bundling: 1/3 manifests (33.33%)
152 bundling: 1/3 manifests (33.33%)
153 bundling: 2/3 manifests (66.67%)
153 bundling: 2/3 manifests (66.67%)
154 bundling: 3/3 manifests (100.00%)
154 bundling: 3/3 manifests (100.00%)
155 bundling: foo/Bar/file.txt 1/3 files (33.33%)
155 bundling: foo/Bar/file.txt 1/3 files (33.33%)
156 bundling: foo/file.txt 2/3 files (66.67%)
156 bundling: foo/file.txt 2/3 files (66.67%)
157 bundling: quux/file.py 3/3 files (100.00%)
157 bundling: quux/file.py 3/3 files (100.00%)
158 changesets: 1 chunks
158 changesets: 1 chunks
159 add changeset ef1ea85a6374
159 add changeset ef1ea85a6374
160 changesets: 2 chunks
160 changesets: 2 chunks
161 add changeset f9cafe1212c8
161 add changeset f9cafe1212c8
162 changesets: 3 chunks
162 changesets: 3 chunks
163 add changeset 911600dab2ae
163 add changeset 911600dab2ae
164 adding manifests
164 adding manifests
165 manifests: 1/3 chunks (33.33%)
165 manifests: 1/3 chunks (33.33%)
166 manifests: 2/3 chunks (66.67%)
166 manifests: 2/3 chunks (66.67%)
167 manifests: 3/3 chunks (100.00%)
167 manifests: 3/3 chunks (100.00%)
168 adding file changes
168 adding file changes
169 adding foo/Bar/file.txt revisions
169 adding foo/Bar/file.txt revisions
170 files: 1/3 chunks (33.33%)
170 files: 1/3 chunks (33.33%)
171 adding foo/file.txt revisions
171 adding foo/file.txt revisions
172 files: 2/3 chunks (66.67%)
172 files: 2/3 chunks (66.67%)
173 adding quux/file.py revisions
173 adding quux/file.py revisions
174 files: 3/3 chunks (100.00%)
174 files: 3/3 chunks (100.00%)
175 added 3 changesets with 3 changes to 3 files
175 added 3 changesets with 3 changes to 3 files
176 calling hook pretxnchangegroup.acl: hgext.acl.hook
176 calling hook pretxnchangegroup.acl: hgext.acl.hook
177 acl: changes have source "push" - skipping
177 acl: changes have source "push" - skipping
178 updating the branch cache
178 updating the branch cache
179 checking for updated bookmarks
179 checking for updated bookmarks
180 repository tip rolled back to revision 0 (undo push)
180 repository tip rolled back to revision 0 (undo push)
181 0:6675d58eff77
181 0:6675d58eff77
182
182
183
183
184 No [acl.allow]/[acl.deny]
184 No [acl.allow]/[acl.deny]
185
185
186 $ echo '[acl]' >> $config
186 $ echo '[acl]' >> $config
187 $ echo 'sources = push' >> $config
187 $ echo 'sources = push' >> $config
188 $ do_push fred
188 $ do_push fred
189 Pushing as user fred
189 Pushing as user fred
190 hgrc = """
190 hgrc = """
191 [hooks]
191 [hooks]
192 pretxnchangegroup.acl = python:hgext.acl.hook
192 pretxnchangegroup.acl = python:hgext.acl.hook
193 [acl]
193 [acl]
194 sources = push
194 sources = push
195 """
195 """
196 pushing to ../b
196 pushing to ../b
197 query 1; heads
197 query 1; heads
198 searching for changes
198 searching for changes
199 all remote heads known locally
199 all remote heads known locally
200 invalidating branch cache (tip differs)
200 invalidating branch cache (tip differs)
201 3 changesets found
201 3 changesets found
202 list of changesets:
202 list of changesets:
203 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
203 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
204 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
204 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
205 911600dab2ae7a9baff75958b84fe606851ce955
205 911600dab2ae7a9baff75958b84fe606851ce955
206 adding changesets
206 adding changesets
207 bundling: 1/3 changesets (33.33%)
207 bundling: 1/3 changesets (33.33%)
208 bundling: 2/3 changesets (66.67%)
208 bundling: 2/3 changesets (66.67%)
209 bundling: 3/3 changesets (100.00%)
209 bundling: 3/3 changesets (100.00%)
210 bundling: 1/3 manifests (33.33%)
210 bundling: 1/3 manifests (33.33%)
211 bundling: 2/3 manifests (66.67%)
211 bundling: 2/3 manifests (66.67%)
212 bundling: 3/3 manifests (100.00%)
212 bundling: 3/3 manifests (100.00%)
213 bundling: foo/Bar/file.txt 1/3 files (33.33%)
213 bundling: foo/Bar/file.txt 1/3 files (33.33%)
214 bundling: foo/file.txt 2/3 files (66.67%)
214 bundling: foo/file.txt 2/3 files (66.67%)
215 bundling: quux/file.py 3/3 files (100.00%)
215 bundling: quux/file.py 3/3 files (100.00%)
216 changesets: 1 chunks
216 changesets: 1 chunks
217 add changeset ef1ea85a6374
217 add changeset ef1ea85a6374
218 changesets: 2 chunks
218 changesets: 2 chunks
219 add changeset f9cafe1212c8
219 add changeset f9cafe1212c8
220 changesets: 3 chunks
220 changesets: 3 chunks
221 add changeset 911600dab2ae
221 add changeset 911600dab2ae
222 adding manifests
222 adding manifests
223 manifests: 1/3 chunks (33.33%)
223 manifests: 1/3 chunks (33.33%)
224 manifests: 2/3 chunks (66.67%)
224 manifests: 2/3 chunks (66.67%)
225 manifests: 3/3 chunks (100.00%)
225 manifests: 3/3 chunks (100.00%)
226 adding file changes
226 adding file changes
227 adding foo/Bar/file.txt revisions
227 adding foo/Bar/file.txt revisions
228 files: 1/3 chunks (33.33%)
228 files: 1/3 chunks (33.33%)
229 adding foo/file.txt revisions
229 adding foo/file.txt revisions
230 files: 2/3 chunks (66.67%)
230 files: 2/3 chunks (66.67%)
231 adding quux/file.py revisions
231 adding quux/file.py revisions
232 files: 3/3 chunks (100.00%)
232 files: 3/3 chunks (100.00%)
233 added 3 changesets with 3 changes to 3 files
233 added 3 changesets with 3 changes to 3 files
234 calling hook pretxnchangegroup.acl: hgext.acl.hook
234 calling hook pretxnchangegroup.acl: hgext.acl.hook
235 acl: checking access for user "fred"
235 acl: checking access for user "fred"
236 acl: acl.allow.branches not enabled
236 acl: acl.allow.branches not enabled
237 acl: acl.deny.branches not enabled
237 acl: acl.deny.branches not enabled
238 acl: acl.allow not enabled
238 acl: acl.allow not enabled
239 acl: acl.deny not enabled
239 acl: acl.deny not enabled
240 acl: branch access granted: "ef1ea85a6374" on branch "default"
240 acl: branch access granted: "ef1ea85a6374" on branch "default"
241 acl: path access granted: "ef1ea85a6374"
241 acl: path access granted: "ef1ea85a6374"
242 acl: branch access granted: "f9cafe1212c8" on branch "default"
242 acl: branch access granted: "f9cafe1212c8" on branch "default"
243 acl: path access granted: "f9cafe1212c8"
243 acl: path access granted: "f9cafe1212c8"
244 acl: branch access granted: "911600dab2ae" on branch "default"
244 acl: branch access granted: "911600dab2ae" on branch "default"
245 acl: path access granted: "911600dab2ae"
245 acl: path access granted: "911600dab2ae"
246 updating the branch cache
246 updating the branch cache
247 checking for updated bookmarks
247 checking for updated bookmarks
248 repository tip rolled back to revision 0 (undo push)
248 repository tip rolled back to revision 0 (undo push)
249 0:6675d58eff77
249 0:6675d58eff77
250
250
251
251
252 Empty [acl.allow]
252 Empty [acl.allow]
253
253
254 $ echo '[acl.allow]' >> $config
254 $ echo '[acl.allow]' >> $config
255 $ do_push fred
255 $ do_push fred
256 Pushing as user fred
256 Pushing as user fred
257 hgrc = """
257 hgrc = """
258 [hooks]
258 [hooks]
259 pretxnchangegroup.acl = python:hgext.acl.hook
259 pretxnchangegroup.acl = python:hgext.acl.hook
260 [acl]
260 [acl]
261 sources = push
261 sources = push
262 [acl.allow]
262 [acl.allow]
263 """
263 """
264 pushing to ../b
264 pushing to ../b
265 query 1; heads
265 query 1; heads
266 searching for changes
266 searching for changes
267 all remote heads known locally
267 all remote heads known locally
268 invalidating branch cache (tip differs)
268 invalidating branch cache (tip differs)
269 3 changesets found
269 3 changesets found
270 list of changesets:
270 list of changesets:
271 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
271 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
272 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
272 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
273 911600dab2ae7a9baff75958b84fe606851ce955
273 911600dab2ae7a9baff75958b84fe606851ce955
274 adding changesets
274 adding changesets
275 bundling: 1/3 changesets (33.33%)
275 bundling: 1/3 changesets (33.33%)
276 bundling: 2/3 changesets (66.67%)
276 bundling: 2/3 changesets (66.67%)
277 bundling: 3/3 changesets (100.00%)
277 bundling: 3/3 changesets (100.00%)
278 bundling: 1/3 manifests (33.33%)
278 bundling: 1/3 manifests (33.33%)
279 bundling: 2/3 manifests (66.67%)
279 bundling: 2/3 manifests (66.67%)
280 bundling: 3/3 manifests (100.00%)
280 bundling: 3/3 manifests (100.00%)
281 bundling: foo/Bar/file.txt 1/3 files (33.33%)
281 bundling: foo/Bar/file.txt 1/3 files (33.33%)
282 bundling: foo/file.txt 2/3 files (66.67%)
282 bundling: foo/file.txt 2/3 files (66.67%)
283 bundling: quux/file.py 3/3 files (100.00%)
283 bundling: quux/file.py 3/3 files (100.00%)
284 changesets: 1 chunks
284 changesets: 1 chunks
285 add changeset ef1ea85a6374
285 add changeset ef1ea85a6374
286 changesets: 2 chunks
286 changesets: 2 chunks
287 add changeset f9cafe1212c8
287 add changeset f9cafe1212c8
288 changesets: 3 chunks
288 changesets: 3 chunks
289 add changeset 911600dab2ae
289 add changeset 911600dab2ae
290 adding manifests
290 adding manifests
291 manifests: 1/3 chunks (33.33%)
291 manifests: 1/3 chunks (33.33%)
292 manifests: 2/3 chunks (66.67%)
292 manifests: 2/3 chunks (66.67%)
293 manifests: 3/3 chunks (100.00%)
293 manifests: 3/3 chunks (100.00%)
294 adding file changes
294 adding file changes
295 adding foo/Bar/file.txt revisions
295 adding foo/Bar/file.txt revisions
296 files: 1/3 chunks (33.33%)
296 files: 1/3 chunks (33.33%)
297 adding foo/file.txt revisions
297 adding foo/file.txt revisions
298 files: 2/3 chunks (66.67%)
298 files: 2/3 chunks (66.67%)
299 adding quux/file.py revisions
299 adding quux/file.py revisions
300 files: 3/3 chunks (100.00%)
300 files: 3/3 chunks (100.00%)
301 added 3 changesets with 3 changes to 3 files
301 added 3 changesets with 3 changes to 3 files
302 calling hook pretxnchangegroup.acl: hgext.acl.hook
302 calling hook pretxnchangegroup.acl: hgext.acl.hook
303 acl: checking access for user "fred"
303 acl: checking access for user "fred"
304 acl: acl.allow.branches not enabled
304 acl: acl.allow.branches not enabled
305 acl: acl.deny.branches not enabled
305 acl: acl.deny.branches not enabled
306 acl: acl.allow enabled, 0 entries for user fred
306 acl: acl.allow enabled, 0 entries for user fred
307 acl: acl.deny not enabled
307 acl: acl.deny not enabled
308 acl: branch access granted: "ef1ea85a6374" on branch "default"
308 acl: branch access granted: "ef1ea85a6374" on branch "default"
309 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
309 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
310 transaction abort!
310 transaction abort!
311 rollback completed
311 rollback completed
312 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
312 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
313 no rollback information available
313 no rollback information available
314 0:6675d58eff77
314 0:6675d58eff77
315
315
316
316
317 fred is allowed inside foo/
317 fred is allowed inside foo/
318
318
319 $ echo 'foo/** = fred' >> $config
319 $ echo 'foo/** = fred' >> $config
320 $ do_push fred
320 $ do_push fred
321 Pushing as user fred
321 Pushing as user fred
322 hgrc = """
322 hgrc = """
323 [hooks]
323 [hooks]
324 pretxnchangegroup.acl = python:hgext.acl.hook
324 pretxnchangegroup.acl = python:hgext.acl.hook
325 [acl]
325 [acl]
326 sources = push
326 sources = push
327 [acl.allow]
327 [acl.allow]
328 foo/** = fred
328 foo/** = fred
329 """
329 """
330 pushing to ../b
330 pushing to ../b
331 query 1; heads
331 query 1; heads
332 searching for changes
332 searching for changes
333 all remote heads known locally
333 all remote heads known locally
334 3 changesets found
334 3 changesets found
335 list of changesets:
335 list of changesets:
336 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
336 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
337 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
337 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
338 911600dab2ae7a9baff75958b84fe606851ce955
338 911600dab2ae7a9baff75958b84fe606851ce955
339 adding changesets
339 adding changesets
340 bundling: 1/3 changesets (33.33%)
340 bundling: 1/3 changesets (33.33%)
341 bundling: 2/3 changesets (66.67%)
341 bundling: 2/3 changesets (66.67%)
342 bundling: 3/3 changesets (100.00%)
342 bundling: 3/3 changesets (100.00%)
343 bundling: 1/3 manifests (33.33%)
343 bundling: 1/3 manifests (33.33%)
344 bundling: 2/3 manifests (66.67%)
344 bundling: 2/3 manifests (66.67%)
345 bundling: 3/3 manifests (100.00%)
345 bundling: 3/3 manifests (100.00%)
346 bundling: foo/Bar/file.txt 1/3 files (33.33%)
346 bundling: foo/Bar/file.txt 1/3 files (33.33%)
347 bundling: foo/file.txt 2/3 files (66.67%)
347 bundling: foo/file.txt 2/3 files (66.67%)
348 bundling: quux/file.py 3/3 files (100.00%)
348 bundling: quux/file.py 3/3 files (100.00%)
349 changesets: 1 chunks
349 changesets: 1 chunks
350 add changeset ef1ea85a6374
350 add changeset ef1ea85a6374
351 changesets: 2 chunks
351 changesets: 2 chunks
352 add changeset f9cafe1212c8
352 add changeset f9cafe1212c8
353 changesets: 3 chunks
353 changesets: 3 chunks
354 add changeset 911600dab2ae
354 add changeset 911600dab2ae
355 adding manifests
355 adding manifests
356 manifests: 1/3 chunks (33.33%)
356 manifests: 1/3 chunks (33.33%)
357 manifests: 2/3 chunks (66.67%)
357 manifests: 2/3 chunks (66.67%)
358 manifests: 3/3 chunks (100.00%)
358 manifests: 3/3 chunks (100.00%)
359 adding file changes
359 adding file changes
360 adding foo/Bar/file.txt revisions
360 adding foo/Bar/file.txt revisions
361 files: 1/3 chunks (33.33%)
361 files: 1/3 chunks (33.33%)
362 adding foo/file.txt revisions
362 adding foo/file.txt revisions
363 files: 2/3 chunks (66.67%)
363 files: 2/3 chunks (66.67%)
364 adding quux/file.py revisions
364 adding quux/file.py revisions
365 files: 3/3 chunks (100.00%)
365 files: 3/3 chunks (100.00%)
366 added 3 changesets with 3 changes to 3 files
366 added 3 changesets with 3 changes to 3 files
367 calling hook pretxnchangegroup.acl: hgext.acl.hook
367 calling hook pretxnchangegroup.acl: hgext.acl.hook
368 acl: checking access for user "fred"
368 acl: checking access for user "fred"
369 acl: acl.allow.branches not enabled
369 acl: acl.allow.branches not enabled
370 acl: acl.deny.branches not enabled
370 acl: acl.deny.branches not enabled
371 acl: acl.allow enabled, 1 entries for user fred
371 acl: acl.allow enabled, 1 entries for user fred
372 acl: acl.deny not enabled
372 acl: acl.deny not enabled
373 acl: branch access granted: "ef1ea85a6374" on branch "default"
373 acl: branch access granted: "ef1ea85a6374" on branch "default"
374 acl: path access granted: "ef1ea85a6374"
374 acl: path access granted: "ef1ea85a6374"
375 acl: branch access granted: "f9cafe1212c8" on branch "default"
375 acl: branch access granted: "f9cafe1212c8" on branch "default"
376 acl: path access granted: "f9cafe1212c8"
376 acl: path access granted: "f9cafe1212c8"
377 acl: branch access granted: "911600dab2ae" on branch "default"
377 acl: branch access granted: "911600dab2ae" on branch "default"
378 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
378 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
379 transaction abort!
379 transaction abort!
380 rollback completed
380 rollback completed
381 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
381 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
382 no rollback information available
382 no rollback information available
383 0:6675d58eff77
383 0:6675d58eff77
384
384
385
385
386 Empty [acl.deny]
386 Empty [acl.deny]
387
387
388 $ echo '[acl.deny]' >> $config
388 $ echo '[acl.deny]' >> $config
389 $ do_push barney
389 $ do_push barney
390 Pushing as user barney
390 Pushing as user barney
391 hgrc = """
391 hgrc = """
392 [hooks]
392 [hooks]
393 pretxnchangegroup.acl = python:hgext.acl.hook
393 pretxnchangegroup.acl = python:hgext.acl.hook
394 [acl]
394 [acl]
395 sources = push
395 sources = push
396 [acl.allow]
396 [acl.allow]
397 foo/** = fred
397 foo/** = fred
398 [acl.deny]
398 [acl.deny]
399 """
399 """
400 pushing to ../b
400 pushing to ../b
401 query 1; heads
401 query 1; heads
402 searching for changes
402 searching for changes
403 all remote heads known locally
403 all remote heads known locally
404 3 changesets found
404 3 changesets found
405 list of changesets:
405 list of changesets:
406 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
406 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
407 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
407 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
408 911600dab2ae7a9baff75958b84fe606851ce955
408 911600dab2ae7a9baff75958b84fe606851ce955
409 adding changesets
409 adding changesets
410 bundling: 1/3 changesets (33.33%)
410 bundling: 1/3 changesets (33.33%)
411 bundling: 2/3 changesets (66.67%)
411 bundling: 2/3 changesets (66.67%)
412 bundling: 3/3 changesets (100.00%)
412 bundling: 3/3 changesets (100.00%)
413 bundling: 1/3 manifests (33.33%)
413 bundling: 1/3 manifests (33.33%)
414 bundling: 2/3 manifests (66.67%)
414 bundling: 2/3 manifests (66.67%)
415 bundling: 3/3 manifests (100.00%)
415 bundling: 3/3 manifests (100.00%)
416 bundling: foo/Bar/file.txt 1/3 files (33.33%)
416 bundling: foo/Bar/file.txt 1/3 files (33.33%)
417 bundling: foo/file.txt 2/3 files (66.67%)
417 bundling: foo/file.txt 2/3 files (66.67%)
418 bundling: quux/file.py 3/3 files (100.00%)
418 bundling: quux/file.py 3/3 files (100.00%)
419 changesets: 1 chunks
419 changesets: 1 chunks
420 add changeset ef1ea85a6374
420 add changeset ef1ea85a6374
421 changesets: 2 chunks
421 changesets: 2 chunks
422 add changeset f9cafe1212c8
422 add changeset f9cafe1212c8
423 changesets: 3 chunks
423 changesets: 3 chunks
424 add changeset 911600dab2ae
424 add changeset 911600dab2ae
425 adding manifests
425 adding manifests
426 manifests: 1/3 chunks (33.33%)
426 manifests: 1/3 chunks (33.33%)
427 manifests: 2/3 chunks (66.67%)
427 manifests: 2/3 chunks (66.67%)
428 manifests: 3/3 chunks (100.00%)
428 manifests: 3/3 chunks (100.00%)
429 adding file changes
429 adding file changes
430 adding foo/Bar/file.txt revisions
430 adding foo/Bar/file.txt revisions
431 files: 1/3 chunks (33.33%)
431 files: 1/3 chunks (33.33%)
432 adding foo/file.txt revisions
432 adding foo/file.txt revisions
433 files: 2/3 chunks (66.67%)
433 files: 2/3 chunks (66.67%)
434 adding quux/file.py revisions
434 adding quux/file.py revisions
435 files: 3/3 chunks (100.00%)
435 files: 3/3 chunks (100.00%)
436 added 3 changesets with 3 changes to 3 files
436 added 3 changesets with 3 changes to 3 files
437 calling hook pretxnchangegroup.acl: hgext.acl.hook
437 calling hook pretxnchangegroup.acl: hgext.acl.hook
438 acl: checking access for user "barney"
438 acl: checking access for user "barney"
439 acl: acl.allow.branches not enabled
439 acl: acl.allow.branches not enabled
440 acl: acl.deny.branches not enabled
440 acl: acl.deny.branches not enabled
441 acl: acl.allow enabled, 0 entries for user barney
441 acl: acl.allow enabled, 0 entries for user barney
442 acl: acl.deny enabled, 0 entries for user barney
442 acl: acl.deny enabled, 0 entries for user barney
443 acl: branch access granted: "ef1ea85a6374" on branch "default"
443 acl: branch access granted: "ef1ea85a6374" on branch "default"
444 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
444 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
445 transaction abort!
445 transaction abort!
446 rollback completed
446 rollback completed
447 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
447 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
448 no rollback information available
448 no rollback information available
449 0:6675d58eff77
449 0:6675d58eff77
450
450
451
451
452 fred is allowed inside foo/, but not foo/bar/ (case matters)
452 fred is allowed inside foo/, but not foo/bar/ (case matters)
453
453
454 $ echo 'foo/bar/** = fred' >> $config
454 $ echo 'foo/bar/** = fred' >> $config
455 $ do_push fred
455 $ do_push fred
456 Pushing as user fred
456 Pushing as user fred
457 hgrc = """
457 hgrc = """
458 [hooks]
458 [hooks]
459 pretxnchangegroup.acl = python:hgext.acl.hook
459 pretxnchangegroup.acl = python:hgext.acl.hook
460 [acl]
460 [acl]
461 sources = push
461 sources = push
462 [acl.allow]
462 [acl.allow]
463 foo/** = fred
463 foo/** = fred
464 [acl.deny]
464 [acl.deny]
465 foo/bar/** = fred
465 foo/bar/** = fred
466 """
466 """
467 pushing to ../b
467 pushing to ../b
468 query 1; heads
468 query 1; heads
469 searching for changes
469 searching for changes
470 all remote heads known locally
470 all remote heads known locally
471 3 changesets found
471 3 changesets found
472 list of changesets:
472 list of changesets:
473 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
473 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
474 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
474 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
475 911600dab2ae7a9baff75958b84fe606851ce955
475 911600dab2ae7a9baff75958b84fe606851ce955
476 adding changesets
476 adding changesets
477 bundling: 1/3 changesets (33.33%)
477 bundling: 1/3 changesets (33.33%)
478 bundling: 2/3 changesets (66.67%)
478 bundling: 2/3 changesets (66.67%)
479 bundling: 3/3 changesets (100.00%)
479 bundling: 3/3 changesets (100.00%)
480 bundling: 1/3 manifests (33.33%)
480 bundling: 1/3 manifests (33.33%)
481 bundling: 2/3 manifests (66.67%)
481 bundling: 2/3 manifests (66.67%)
482 bundling: 3/3 manifests (100.00%)
482 bundling: 3/3 manifests (100.00%)
483 bundling: foo/Bar/file.txt 1/3 files (33.33%)
483 bundling: foo/Bar/file.txt 1/3 files (33.33%)
484 bundling: foo/file.txt 2/3 files (66.67%)
484 bundling: foo/file.txt 2/3 files (66.67%)
485 bundling: quux/file.py 3/3 files (100.00%)
485 bundling: quux/file.py 3/3 files (100.00%)
486 changesets: 1 chunks
486 changesets: 1 chunks
487 add changeset ef1ea85a6374
487 add changeset ef1ea85a6374
488 changesets: 2 chunks
488 changesets: 2 chunks
489 add changeset f9cafe1212c8
489 add changeset f9cafe1212c8
490 changesets: 3 chunks
490 changesets: 3 chunks
491 add changeset 911600dab2ae
491 add changeset 911600dab2ae
492 adding manifests
492 adding manifests
493 manifests: 1/3 chunks (33.33%)
493 manifests: 1/3 chunks (33.33%)
494 manifests: 2/3 chunks (66.67%)
494 manifests: 2/3 chunks (66.67%)
495 manifests: 3/3 chunks (100.00%)
495 manifests: 3/3 chunks (100.00%)
496 adding file changes
496 adding file changes
497 adding foo/Bar/file.txt revisions
497 adding foo/Bar/file.txt revisions
498 files: 1/3 chunks (33.33%)
498 files: 1/3 chunks (33.33%)
499 adding foo/file.txt revisions
499 adding foo/file.txt revisions
500 files: 2/3 chunks (66.67%)
500 files: 2/3 chunks (66.67%)
501 adding quux/file.py revisions
501 adding quux/file.py revisions
502 files: 3/3 chunks (100.00%)
502 files: 3/3 chunks (100.00%)
503 added 3 changesets with 3 changes to 3 files
503 added 3 changesets with 3 changes to 3 files
504 calling hook pretxnchangegroup.acl: hgext.acl.hook
504 calling hook pretxnchangegroup.acl: hgext.acl.hook
505 acl: checking access for user "fred"
505 acl: checking access for user "fred"
506 acl: acl.allow.branches not enabled
506 acl: acl.allow.branches not enabled
507 acl: acl.deny.branches not enabled
507 acl: acl.deny.branches not enabled
508 acl: acl.allow enabled, 1 entries for user fred
508 acl: acl.allow enabled, 1 entries for user fred
509 acl: acl.deny enabled, 1 entries for user fred
509 acl: acl.deny enabled, 1 entries for user fred
510 acl: branch access granted: "ef1ea85a6374" on branch "default"
510 acl: branch access granted: "ef1ea85a6374" on branch "default"
511 acl: path access granted: "ef1ea85a6374"
511 acl: path access granted: "ef1ea85a6374"
512 acl: branch access granted: "f9cafe1212c8" on branch "default"
512 acl: branch access granted: "f9cafe1212c8" on branch "default"
513 acl: path access granted: "f9cafe1212c8"
513 acl: path access granted: "f9cafe1212c8"
514 acl: branch access granted: "911600dab2ae" on branch "default"
514 acl: branch access granted: "911600dab2ae" on branch "default"
515 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
515 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
516 transaction abort!
516 transaction abort!
517 rollback completed
517 rollback completed
518 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
518 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
519 no rollback information available
519 no rollback information available
520 0:6675d58eff77
520 0:6675d58eff77
521
521
522
522
523 fred is allowed inside foo/, but not foo/Bar/
523 fred is allowed inside foo/, but not foo/Bar/
524
524
525 $ echo 'foo/Bar/** = fred' >> $config
525 $ echo 'foo/Bar/** = fred' >> $config
526 $ do_push fred
526 $ do_push fred
527 Pushing as user fred
527 Pushing as user fred
528 hgrc = """
528 hgrc = """
529 [hooks]
529 [hooks]
530 pretxnchangegroup.acl = python:hgext.acl.hook
530 pretxnchangegroup.acl = python:hgext.acl.hook
531 [acl]
531 [acl]
532 sources = push
532 sources = push
533 [acl.allow]
533 [acl.allow]
534 foo/** = fred
534 foo/** = fred
535 [acl.deny]
535 [acl.deny]
536 foo/bar/** = fred
536 foo/bar/** = fred
537 foo/Bar/** = fred
537 foo/Bar/** = fred
538 """
538 """
539 pushing to ../b
539 pushing to ../b
540 query 1; heads
540 query 1; heads
541 searching for changes
541 searching for changes
542 all remote heads known locally
542 all remote heads known locally
543 3 changesets found
543 3 changesets found
544 list of changesets:
544 list of changesets:
545 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
545 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
546 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
546 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
547 911600dab2ae7a9baff75958b84fe606851ce955
547 911600dab2ae7a9baff75958b84fe606851ce955
548 adding changesets
548 adding changesets
549 bundling: 1/3 changesets (33.33%)
549 bundling: 1/3 changesets (33.33%)
550 bundling: 2/3 changesets (66.67%)
550 bundling: 2/3 changesets (66.67%)
551 bundling: 3/3 changesets (100.00%)
551 bundling: 3/3 changesets (100.00%)
552 bundling: 1/3 manifests (33.33%)
552 bundling: 1/3 manifests (33.33%)
553 bundling: 2/3 manifests (66.67%)
553 bundling: 2/3 manifests (66.67%)
554 bundling: 3/3 manifests (100.00%)
554 bundling: 3/3 manifests (100.00%)
555 bundling: foo/Bar/file.txt 1/3 files (33.33%)
555 bundling: foo/Bar/file.txt 1/3 files (33.33%)
556 bundling: foo/file.txt 2/3 files (66.67%)
556 bundling: foo/file.txt 2/3 files (66.67%)
557 bundling: quux/file.py 3/3 files (100.00%)
557 bundling: quux/file.py 3/3 files (100.00%)
558 changesets: 1 chunks
558 changesets: 1 chunks
559 add changeset ef1ea85a6374
559 add changeset ef1ea85a6374
560 changesets: 2 chunks
560 changesets: 2 chunks
561 add changeset f9cafe1212c8
561 add changeset f9cafe1212c8
562 changesets: 3 chunks
562 changesets: 3 chunks
563 add changeset 911600dab2ae
563 add changeset 911600dab2ae
564 adding manifests
564 adding manifests
565 manifests: 1/3 chunks (33.33%)
565 manifests: 1/3 chunks (33.33%)
566 manifests: 2/3 chunks (66.67%)
566 manifests: 2/3 chunks (66.67%)
567 manifests: 3/3 chunks (100.00%)
567 manifests: 3/3 chunks (100.00%)
568 adding file changes
568 adding file changes
569 adding foo/Bar/file.txt revisions
569 adding foo/Bar/file.txt revisions
570 files: 1/3 chunks (33.33%)
570 files: 1/3 chunks (33.33%)
571 adding foo/file.txt revisions
571 adding foo/file.txt revisions
572 files: 2/3 chunks (66.67%)
572 files: 2/3 chunks (66.67%)
573 adding quux/file.py revisions
573 adding quux/file.py revisions
574 files: 3/3 chunks (100.00%)
574 files: 3/3 chunks (100.00%)
575 added 3 changesets with 3 changes to 3 files
575 added 3 changesets with 3 changes to 3 files
576 calling hook pretxnchangegroup.acl: hgext.acl.hook
576 calling hook pretxnchangegroup.acl: hgext.acl.hook
577 acl: checking access for user "fred"
577 acl: checking access for user "fred"
578 acl: acl.allow.branches not enabled
578 acl: acl.allow.branches not enabled
579 acl: acl.deny.branches not enabled
579 acl: acl.deny.branches not enabled
580 acl: acl.allow enabled, 1 entries for user fred
580 acl: acl.allow enabled, 1 entries for user fred
581 acl: acl.deny enabled, 2 entries for user fred
581 acl: acl.deny enabled, 2 entries for user fred
582 acl: branch access granted: "ef1ea85a6374" on branch "default"
582 acl: branch access granted: "ef1ea85a6374" on branch "default"
583 acl: path access granted: "ef1ea85a6374"
583 acl: path access granted: "ef1ea85a6374"
584 acl: branch access granted: "f9cafe1212c8" on branch "default"
584 acl: branch access granted: "f9cafe1212c8" on branch "default"
585 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
585 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
586 transaction abort!
586 transaction abort!
587 rollback completed
587 rollback completed
588 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
588 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
589 no rollback information available
589 no rollback information available
590 0:6675d58eff77
590 0:6675d58eff77
591
591
592
592
593 $ echo 'barney is not mentioned => not allowed anywhere'
593 $ echo 'barney is not mentioned => not allowed anywhere'
594 barney is not mentioned => not allowed anywhere
594 barney is not mentioned => not allowed anywhere
595 $ do_push barney
595 $ do_push barney
596 Pushing as user barney
596 Pushing as user barney
597 hgrc = """
597 hgrc = """
598 [hooks]
598 [hooks]
599 pretxnchangegroup.acl = python:hgext.acl.hook
599 pretxnchangegroup.acl = python:hgext.acl.hook
600 [acl]
600 [acl]
601 sources = push
601 sources = push
602 [acl.allow]
602 [acl.allow]
603 foo/** = fred
603 foo/** = fred
604 [acl.deny]
604 [acl.deny]
605 foo/bar/** = fred
605 foo/bar/** = fred
606 foo/Bar/** = fred
606 foo/Bar/** = fred
607 """
607 """
608 pushing to ../b
608 pushing to ../b
609 query 1; heads
609 query 1; heads
610 searching for changes
610 searching for changes
611 all remote heads known locally
611 all remote heads known locally
612 3 changesets found
612 3 changesets found
613 list of changesets:
613 list of changesets:
614 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
614 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
615 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
615 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
616 911600dab2ae7a9baff75958b84fe606851ce955
616 911600dab2ae7a9baff75958b84fe606851ce955
617 adding changesets
617 adding changesets
618 bundling: 1/3 changesets (33.33%)
618 bundling: 1/3 changesets (33.33%)
619 bundling: 2/3 changesets (66.67%)
619 bundling: 2/3 changesets (66.67%)
620 bundling: 3/3 changesets (100.00%)
620 bundling: 3/3 changesets (100.00%)
621 bundling: 1/3 manifests (33.33%)
621 bundling: 1/3 manifests (33.33%)
622 bundling: 2/3 manifests (66.67%)
622 bundling: 2/3 manifests (66.67%)
623 bundling: 3/3 manifests (100.00%)
623 bundling: 3/3 manifests (100.00%)
624 bundling: foo/Bar/file.txt 1/3 files (33.33%)
624 bundling: foo/Bar/file.txt 1/3 files (33.33%)
625 bundling: foo/file.txt 2/3 files (66.67%)
625 bundling: foo/file.txt 2/3 files (66.67%)
626 bundling: quux/file.py 3/3 files (100.00%)
626 bundling: quux/file.py 3/3 files (100.00%)
627 changesets: 1 chunks
627 changesets: 1 chunks
628 add changeset ef1ea85a6374
628 add changeset ef1ea85a6374
629 changesets: 2 chunks
629 changesets: 2 chunks
630 add changeset f9cafe1212c8
630 add changeset f9cafe1212c8
631 changesets: 3 chunks
631 changesets: 3 chunks
632 add changeset 911600dab2ae
632 add changeset 911600dab2ae
633 adding manifests
633 adding manifests
634 manifests: 1/3 chunks (33.33%)
634 manifests: 1/3 chunks (33.33%)
635 manifests: 2/3 chunks (66.67%)
635 manifests: 2/3 chunks (66.67%)
636 manifests: 3/3 chunks (100.00%)
636 manifests: 3/3 chunks (100.00%)
637 adding file changes
637 adding file changes
638 adding foo/Bar/file.txt revisions
638 adding foo/Bar/file.txt revisions
639 files: 1/3 chunks (33.33%)
639 files: 1/3 chunks (33.33%)
640 adding foo/file.txt revisions
640 adding foo/file.txt revisions
641 files: 2/3 chunks (66.67%)
641 files: 2/3 chunks (66.67%)
642 adding quux/file.py revisions
642 adding quux/file.py revisions
643 files: 3/3 chunks (100.00%)
643 files: 3/3 chunks (100.00%)
644 added 3 changesets with 3 changes to 3 files
644 added 3 changesets with 3 changes to 3 files
645 calling hook pretxnchangegroup.acl: hgext.acl.hook
645 calling hook pretxnchangegroup.acl: hgext.acl.hook
646 acl: checking access for user "barney"
646 acl: checking access for user "barney"
647 acl: acl.allow.branches not enabled
647 acl: acl.allow.branches not enabled
648 acl: acl.deny.branches not enabled
648 acl: acl.deny.branches not enabled
649 acl: acl.allow enabled, 0 entries for user barney
649 acl: acl.allow enabled, 0 entries for user barney
650 acl: acl.deny enabled, 0 entries for user barney
650 acl: acl.deny enabled, 0 entries for user barney
651 acl: branch access granted: "ef1ea85a6374" on branch "default"
651 acl: branch access granted: "ef1ea85a6374" on branch "default"
652 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
652 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
653 transaction abort!
653 transaction abort!
654 rollback completed
654 rollback completed
655 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
655 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
656 no rollback information available
656 no rollback information available
657 0:6675d58eff77
657 0:6675d58eff77
658
658
659
659
660 barney is allowed everywhere
660 barney is allowed everywhere
661
661
662 $ echo '[acl.allow]' >> $config
662 $ echo '[acl.allow]' >> $config
663 $ echo '** = barney' >> $config
663 $ echo '** = barney' >> $config
664 $ do_push barney
664 $ do_push barney
665 Pushing as user barney
665 Pushing as user barney
666 hgrc = """
666 hgrc = """
667 [hooks]
667 [hooks]
668 pretxnchangegroup.acl = python:hgext.acl.hook
668 pretxnchangegroup.acl = python:hgext.acl.hook
669 [acl]
669 [acl]
670 sources = push
670 sources = push
671 [acl.allow]
671 [acl.allow]
672 foo/** = fred
672 foo/** = fred
673 [acl.deny]
673 [acl.deny]
674 foo/bar/** = fred
674 foo/bar/** = fred
675 foo/Bar/** = fred
675 foo/Bar/** = fred
676 [acl.allow]
676 [acl.allow]
677 ** = barney
677 ** = barney
678 """
678 """
679 pushing to ../b
679 pushing to ../b
680 query 1; heads
680 query 1; heads
681 searching for changes
681 searching for changes
682 all remote heads known locally
682 all remote heads known locally
683 3 changesets found
683 3 changesets found
684 list of changesets:
684 list of changesets:
685 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
685 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
686 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
686 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
687 911600dab2ae7a9baff75958b84fe606851ce955
687 911600dab2ae7a9baff75958b84fe606851ce955
688 adding changesets
688 adding changesets
689 bundling: 1/3 changesets (33.33%)
689 bundling: 1/3 changesets (33.33%)
690 bundling: 2/3 changesets (66.67%)
690 bundling: 2/3 changesets (66.67%)
691 bundling: 3/3 changesets (100.00%)
691 bundling: 3/3 changesets (100.00%)
692 bundling: 1/3 manifests (33.33%)
692 bundling: 1/3 manifests (33.33%)
693 bundling: 2/3 manifests (66.67%)
693 bundling: 2/3 manifests (66.67%)
694 bundling: 3/3 manifests (100.00%)
694 bundling: 3/3 manifests (100.00%)
695 bundling: foo/Bar/file.txt 1/3 files (33.33%)
695 bundling: foo/Bar/file.txt 1/3 files (33.33%)
696 bundling: foo/file.txt 2/3 files (66.67%)
696 bundling: foo/file.txt 2/3 files (66.67%)
697 bundling: quux/file.py 3/3 files (100.00%)
697 bundling: quux/file.py 3/3 files (100.00%)
698 changesets: 1 chunks
698 changesets: 1 chunks
699 add changeset ef1ea85a6374
699 add changeset ef1ea85a6374
700 changesets: 2 chunks
700 changesets: 2 chunks
701 add changeset f9cafe1212c8
701 add changeset f9cafe1212c8
702 changesets: 3 chunks
702 changesets: 3 chunks
703 add changeset 911600dab2ae
703 add changeset 911600dab2ae
704 adding manifests
704 adding manifests
705 manifests: 1/3 chunks (33.33%)
705 manifests: 1/3 chunks (33.33%)
706 manifests: 2/3 chunks (66.67%)
706 manifests: 2/3 chunks (66.67%)
707 manifests: 3/3 chunks (100.00%)
707 manifests: 3/3 chunks (100.00%)
708 adding file changes
708 adding file changes
709 adding foo/Bar/file.txt revisions
709 adding foo/Bar/file.txt revisions
710 files: 1/3 chunks (33.33%)
710 files: 1/3 chunks (33.33%)
711 adding foo/file.txt revisions
711 adding foo/file.txt revisions
712 files: 2/3 chunks (66.67%)
712 files: 2/3 chunks (66.67%)
713 adding quux/file.py revisions
713 adding quux/file.py revisions
714 files: 3/3 chunks (100.00%)
714 files: 3/3 chunks (100.00%)
715 added 3 changesets with 3 changes to 3 files
715 added 3 changesets with 3 changes to 3 files
716 calling hook pretxnchangegroup.acl: hgext.acl.hook
716 calling hook pretxnchangegroup.acl: hgext.acl.hook
717 acl: checking access for user "barney"
717 acl: checking access for user "barney"
718 acl: acl.allow.branches not enabled
718 acl: acl.allow.branches not enabled
719 acl: acl.deny.branches not enabled
719 acl: acl.deny.branches not enabled
720 acl: acl.allow enabled, 1 entries for user barney
720 acl: acl.allow enabled, 1 entries for user barney
721 acl: acl.deny enabled, 0 entries for user barney
721 acl: acl.deny enabled, 0 entries for user barney
722 acl: branch access granted: "ef1ea85a6374" on branch "default"
722 acl: branch access granted: "ef1ea85a6374" on branch "default"
723 acl: path access granted: "ef1ea85a6374"
723 acl: path access granted: "ef1ea85a6374"
724 acl: branch access granted: "f9cafe1212c8" on branch "default"
724 acl: branch access granted: "f9cafe1212c8" on branch "default"
725 acl: path access granted: "f9cafe1212c8"
725 acl: path access granted: "f9cafe1212c8"
726 acl: branch access granted: "911600dab2ae" on branch "default"
726 acl: branch access granted: "911600dab2ae" on branch "default"
727 acl: path access granted: "911600dab2ae"
727 acl: path access granted: "911600dab2ae"
728 updating the branch cache
728 updating the branch cache
729 checking for updated bookmarks
729 checking for updated bookmarks
730 repository tip rolled back to revision 0 (undo push)
730 repository tip rolled back to revision 0 (undo push)
731 0:6675d58eff77
731 0:6675d58eff77
732
732
733
733
734 wilma can change files with a .txt extension
734 wilma can change files with a .txt extension
735
735
736 $ echo '**/*.txt = wilma' >> $config
736 $ echo '**/*.txt = wilma' >> $config
737 $ do_push wilma
737 $ do_push wilma
738 Pushing as user wilma
738 Pushing as user wilma
739 hgrc = """
739 hgrc = """
740 [hooks]
740 [hooks]
741 pretxnchangegroup.acl = python:hgext.acl.hook
741 pretxnchangegroup.acl = python:hgext.acl.hook
742 [acl]
742 [acl]
743 sources = push
743 sources = push
744 [acl.allow]
744 [acl.allow]
745 foo/** = fred
745 foo/** = fred
746 [acl.deny]
746 [acl.deny]
747 foo/bar/** = fred
747 foo/bar/** = fred
748 foo/Bar/** = fred
748 foo/Bar/** = fred
749 [acl.allow]
749 [acl.allow]
750 ** = barney
750 ** = barney
751 **/*.txt = wilma
751 **/*.txt = wilma
752 """
752 """
753 pushing to ../b
753 pushing to ../b
754 query 1; heads
754 query 1; heads
755 searching for changes
755 searching for changes
756 all remote heads known locally
756 all remote heads known locally
757 invalidating branch cache (tip differs)
757 invalidating branch cache (tip differs)
758 3 changesets found
758 3 changesets found
759 list of changesets:
759 list of changesets:
760 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
760 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
761 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
761 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
762 911600dab2ae7a9baff75958b84fe606851ce955
762 911600dab2ae7a9baff75958b84fe606851ce955
763 adding changesets
763 adding changesets
764 bundling: 1/3 changesets (33.33%)
764 bundling: 1/3 changesets (33.33%)
765 bundling: 2/3 changesets (66.67%)
765 bundling: 2/3 changesets (66.67%)
766 bundling: 3/3 changesets (100.00%)
766 bundling: 3/3 changesets (100.00%)
767 bundling: 1/3 manifests (33.33%)
767 bundling: 1/3 manifests (33.33%)
768 bundling: 2/3 manifests (66.67%)
768 bundling: 2/3 manifests (66.67%)
769 bundling: 3/3 manifests (100.00%)
769 bundling: 3/3 manifests (100.00%)
770 bundling: foo/Bar/file.txt 1/3 files (33.33%)
770 bundling: foo/Bar/file.txt 1/3 files (33.33%)
771 bundling: foo/file.txt 2/3 files (66.67%)
771 bundling: foo/file.txt 2/3 files (66.67%)
772 bundling: quux/file.py 3/3 files (100.00%)
772 bundling: quux/file.py 3/3 files (100.00%)
773 changesets: 1 chunks
773 changesets: 1 chunks
774 add changeset ef1ea85a6374
774 add changeset ef1ea85a6374
775 changesets: 2 chunks
775 changesets: 2 chunks
776 add changeset f9cafe1212c8
776 add changeset f9cafe1212c8
777 changesets: 3 chunks
777 changesets: 3 chunks
778 add changeset 911600dab2ae
778 add changeset 911600dab2ae
779 adding manifests
779 adding manifests
780 manifests: 1/3 chunks (33.33%)
780 manifests: 1/3 chunks (33.33%)
781 manifests: 2/3 chunks (66.67%)
781 manifests: 2/3 chunks (66.67%)
782 manifests: 3/3 chunks (100.00%)
782 manifests: 3/3 chunks (100.00%)
783 adding file changes
783 adding file changes
784 adding foo/Bar/file.txt revisions
784 adding foo/Bar/file.txt revisions
785 files: 1/3 chunks (33.33%)
785 files: 1/3 chunks (33.33%)
786 adding foo/file.txt revisions
786 adding foo/file.txt revisions
787 files: 2/3 chunks (66.67%)
787 files: 2/3 chunks (66.67%)
788 adding quux/file.py revisions
788 adding quux/file.py revisions
789 files: 3/3 chunks (100.00%)
789 files: 3/3 chunks (100.00%)
790 added 3 changesets with 3 changes to 3 files
790 added 3 changesets with 3 changes to 3 files
791 calling hook pretxnchangegroup.acl: hgext.acl.hook
791 calling hook pretxnchangegroup.acl: hgext.acl.hook
792 acl: checking access for user "wilma"
792 acl: checking access for user "wilma"
793 acl: acl.allow.branches not enabled
793 acl: acl.allow.branches not enabled
794 acl: acl.deny.branches not enabled
794 acl: acl.deny.branches not enabled
795 acl: acl.allow enabled, 1 entries for user wilma
795 acl: acl.allow enabled, 1 entries for user wilma
796 acl: acl.deny enabled, 0 entries for user wilma
796 acl: acl.deny enabled, 0 entries for user wilma
797 acl: branch access granted: "ef1ea85a6374" on branch "default"
797 acl: branch access granted: "ef1ea85a6374" on branch "default"
798 acl: path access granted: "ef1ea85a6374"
798 acl: path access granted: "ef1ea85a6374"
799 acl: branch access granted: "f9cafe1212c8" on branch "default"
799 acl: branch access granted: "f9cafe1212c8" on branch "default"
800 acl: path access granted: "f9cafe1212c8"
800 acl: path access granted: "f9cafe1212c8"
801 acl: branch access granted: "911600dab2ae" on branch "default"
801 acl: branch access granted: "911600dab2ae" on branch "default"
802 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
802 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
803 transaction abort!
803 transaction abort!
804 rollback completed
804 rollback completed
805 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
805 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
806 no rollback information available
806 no rollback information available
807 0:6675d58eff77
807 0:6675d58eff77
808
808
809
809
810 file specified by acl.config does not exist
810 file specified by acl.config does not exist
811
811
812 $ echo '[acl]' >> $config
812 $ echo '[acl]' >> $config
813 $ echo 'config = ../acl.config' >> $config
813 $ echo 'config = ../acl.config' >> $config
814 $ do_push barney
814 $ do_push barney
815 Pushing as user barney
815 Pushing as user barney
816 hgrc = """
816 hgrc = """
817 [hooks]
817 [hooks]
818 pretxnchangegroup.acl = python:hgext.acl.hook
818 pretxnchangegroup.acl = python:hgext.acl.hook
819 [acl]
819 [acl]
820 sources = push
820 sources = push
821 [acl.allow]
821 [acl.allow]
822 foo/** = fred
822 foo/** = fred
823 [acl.deny]
823 [acl.deny]
824 foo/bar/** = fred
824 foo/bar/** = fred
825 foo/Bar/** = fred
825 foo/Bar/** = fred
826 [acl.allow]
826 [acl.allow]
827 ** = barney
827 ** = barney
828 **/*.txt = wilma
828 **/*.txt = wilma
829 [acl]
829 [acl]
830 config = ../acl.config
830 config = ../acl.config
831 """
831 """
832 pushing to ../b
832 pushing to ../b
833 query 1; heads
833 query 1; heads
834 searching for changes
834 searching for changes
835 all remote heads known locally
835 all remote heads known locally
836 3 changesets found
836 3 changesets found
837 list of changesets:
837 list of changesets:
838 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
838 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
839 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
839 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
840 911600dab2ae7a9baff75958b84fe606851ce955
840 911600dab2ae7a9baff75958b84fe606851ce955
841 adding changesets
841 adding changesets
842 bundling: 1/3 changesets (33.33%)
842 bundling: 1/3 changesets (33.33%)
843 bundling: 2/3 changesets (66.67%)
843 bundling: 2/3 changesets (66.67%)
844 bundling: 3/3 changesets (100.00%)
844 bundling: 3/3 changesets (100.00%)
845 bundling: 1/3 manifests (33.33%)
845 bundling: 1/3 manifests (33.33%)
846 bundling: 2/3 manifests (66.67%)
846 bundling: 2/3 manifests (66.67%)
847 bundling: 3/3 manifests (100.00%)
847 bundling: 3/3 manifests (100.00%)
848 bundling: foo/Bar/file.txt 1/3 files (33.33%)
848 bundling: foo/Bar/file.txt 1/3 files (33.33%)
849 bundling: foo/file.txt 2/3 files (66.67%)
849 bundling: foo/file.txt 2/3 files (66.67%)
850 bundling: quux/file.py 3/3 files (100.00%)
850 bundling: quux/file.py 3/3 files (100.00%)
851 changesets: 1 chunks
851 changesets: 1 chunks
852 add changeset ef1ea85a6374
852 add changeset ef1ea85a6374
853 changesets: 2 chunks
853 changesets: 2 chunks
854 add changeset f9cafe1212c8
854 add changeset f9cafe1212c8
855 changesets: 3 chunks
855 changesets: 3 chunks
856 add changeset 911600dab2ae
856 add changeset 911600dab2ae
857 adding manifests
857 adding manifests
858 manifests: 1/3 chunks (33.33%)
858 manifests: 1/3 chunks (33.33%)
859 manifests: 2/3 chunks (66.67%)
859 manifests: 2/3 chunks (66.67%)
860 manifests: 3/3 chunks (100.00%)
860 manifests: 3/3 chunks (100.00%)
861 adding file changes
861 adding file changes
862 adding foo/Bar/file.txt revisions
862 adding foo/Bar/file.txt revisions
863 files: 1/3 chunks (33.33%)
863 files: 1/3 chunks (33.33%)
864 adding foo/file.txt revisions
864 adding foo/file.txt revisions
865 files: 2/3 chunks (66.67%)
865 files: 2/3 chunks (66.67%)
866 adding quux/file.py revisions
866 adding quux/file.py revisions
867 files: 3/3 chunks (100.00%)
867 files: 3/3 chunks (100.00%)
868 added 3 changesets with 3 changes to 3 files
868 added 3 changesets with 3 changes to 3 files
869 calling hook pretxnchangegroup.acl: hgext.acl.hook
869 calling hook pretxnchangegroup.acl: hgext.acl.hook
870 acl: checking access for user "barney"
870 acl: checking access for user "barney"
871 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
871 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
872 transaction abort!
872 transaction abort!
873 rollback completed
873 rollback completed
874 abort: No such file or directory: ../acl.config
874 abort: No such file or directory: ../acl.config
875 no rollback information available
875 no rollback information available
876 0:6675d58eff77
876 0:6675d58eff77
877
877
878
878
879 betty is allowed inside foo/ by a acl.config file
879 betty is allowed inside foo/ by a acl.config file
880
880
881 $ echo '[acl.allow]' >> acl.config
881 $ echo '[acl.allow]' >> acl.config
882 $ echo 'foo/** = betty' >> acl.config
882 $ echo 'foo/** = betty' >> acl.config
883 $ do_push betty
883 $ do_push betty
884 Pushing as user betty
884 Pushing as user betty
885 hgrc = """
885 hgrc = """
886 [hooks]
886 [hooks]
887 pretxnchangegroup.acl = python:hgext.acl.hook
887 pretxnchangegroup.acl = python:hgext.acl.hook
888 [acl]
888 [acl]
889 sources = push
889 sources = push
890 [acl.allow]
890 [acl.allow]
891 foo/** = fred
891 foo/** = fred
892 [acl.deny]
892 [acl.deny]
893 foo/bar/** = fred
893 foo/bar/** = fred
894 foo/Bar/** = fred
894 foo/Bar/** = fred
895 [acl.allow]
895 [acl.allow]
896 ** = barney
896 ** = barney
897 **/*.txt = wilma
897 **/*.txt = wilma
898 [acl]
898 [acl]
899 config = ../acl.config
899 config = ../acl.config
900 """
900 """
901 acl.config = """
901 acl.config = """
902 [acl.allow]
902 [acl.allow]
903 foo/** = betty
903 foo/** = betty
904 """
904 """
905 pushing to ../b
905 pushing to ../b
906 query 1; heads
906 query 1; heads
907 searching for changes
907 searching for changes
908 all remote heads known locally
908 all remote heads known locally
909 3 changesets found
909 3 changesets found
910 list of changesets:
910 list of changesets:
911 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
911 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
912 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
912 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
913 911600dab2ae7a9baff75958b84fe606851ce955
913 911600dab2ae7a9baff75958b84fe606851ce955
914 adding changesets
914 adding changesets
915 bundling: 1/3 changesets (33.33%)
915 bundling: 1/3 changesets (33.33%)
916 bundling: 2/3 changesets (66.67%)
916 bundling: 2/3 changesets (66.67%)
917 bundling: 3/3 changesets (100.00%)
917 bundling: 3/3 changesets (100.00%)
918 bundling: 1/3 manifests (33.33%)
918 bundling: 1/3 manifests (33.33%)
919 bundling: 2/3 manifests (66.67%)
919 bundling: 2/3 manifests (66.67%)
920 bundling: 3/3 manifests (100.00%)
920 bundling: 3/3 manifests (100.00%)
921 bundling: foo/Bar/file.txt 1/3 files (33.33%)
921 bundling: foo/Bar/file.txt 1/3 files (33.33%)
922 bundling: foo/file.txt 2/3 files (66.67%)
922 bundling: foo/file.txt 2/3 files (66.67%)
923 bundling: quux/file.py 3/3 files (100.00%)
923 bundling: quux/file.py 3/3 files (100.00%)
924 changesets: 1 chunks
924 changesets: 1 chunks
925 add changeset ef1ea85a6374
925 add changeset ef1ea85a6374
926 changesets: 2 chunks
926 changesets: 2 chunks
927 add changeset f9cafe1212c8
927 add changeset f9cafe1212c8
928 changesets: 3 chunks
928 changesets: 3 chunks
929 add changeset 911600dab2ae
929 add changeset 911600dab2ae
930 adding manifests
930 adding manifests
931 manifests: 1/3 chunks (33.33%)
931 manifests: 1/3 chunks (33.33%)
932 manifests: 2/3 chunks (66.67%)
932 manifests: 2/3 chunks (66.67%)
933 manifests: 3/3 chunks (100.00%)
933 manifests: 3/3 chunks (100.00%)
934 adding file changes
934 adding file changes
935 adding foo/Bar/file.txt revisions
935 adding foo/Bar/file.txt revisions
936 files: 1/3 chunks (33.33%)
936 files: 1/3 chunks (33.33%)
937 adding foo/file.txt revisions
937 adding foo/file.txt revisions
938 files: 2/3 chunks (66.67%)
938 files: 2/3 chunks (66.67%)
939 adding quux/file.py revisions
939 adding quux/file.py revisions
940 files: 3/3 chunks (100.00%)
940 files: 3/3 chunks (100.00%)
941 added 3 changesets with 3 changes to 3 files
941 added 3 changesets with 3 changes to 3 files
942 calling hook pretxnchangegroup.acl: hgext.acl.hook
942 calling hook pretxnchangegroup.acl: hgext.acl.hook
943 acl: checking access for user "betty"
943 acl: checking access for user "betty"
944 acl: acl.allow.branches not enabled
944 acl: acl.allow.branches not enabled
945 acl: acl.deny.branches not enabled
945 acl: acl.deny.branches not enabled
946 acl: acl.allow enabled, 1 entries for user betty
946 acl: acl.allow enabled, 1 entries for user betty
947 acl: acl.deny enabled, 0 entries for user betty
947 acl: acl.deny enabled, 0 entries for user betty
948 acl: branch access granted: "ef1ea85a6374" on branch "default"
948 acl: branch access granted: "ef1ea85a6374" on branch "default"
949 acl: path access granted: "ef1ea85a6374"
949 acl: path access granted: "ef1ea85a6374"
950 acl: branch access granted: "f9cafe1212c8" on branch "default"
950 acl: branch access granted: "f9cafe1212c8" on branch "default"
951 acl: path access granted: "f9cafe1212c8"
951 acl: path access granted: "f9cafe1212c8"
952 acl: branch access granted: "911600dab2ae" on branch "default"
952 acl: branch access granted: "911600dab2ae" on branch "default"
953 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
953 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
954 transaction abort!
954 transaction abort!
955 rollback completed
955 rollback completed
956 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
956 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
957 no rollback information available
957 no rollback information available
958 0:6675d58eff77
958 0:6675d58eff77
959
959
960
960
961 acl.config can set only [acl.allow]/[acl.deny]
961 acl.config can set only [acl.allow]/[acl.deny]
962
962
963 $ echo '[hooks]' >> acl.config
963 $ echo '[hooks]' >> acl.config
964 $ echo 'changegroup.acl = false' >> acl.config
964 $ echo 'changegroup.acl = false' >> acl.config
965 $ do_push barney
965 $ do_push barney
966 Pushing as user barney
966 Pushing as user barney
967 hgrc = """
967 hgrc = """
968 [hooks]
968 [hooks]
969 pretxnchangegroup.acl = python:hgext.acl.hook
969 pretxnchangegroup.acl = python:hgext.acl.hook
970 [acl]
970 [acl]
971 sources = push
971 sources = push
972 [acl.allow]
972 [acl.allow]
973 foo/** = fred
973 foo/** = fred
974 [acl.deny]
974 [acl.deny]
975 foo/bar/** = fred
975 foo/bar/** = fred
976 foo/Bar/** = fred
976 foo/Bar/** = fred
977 [acl.allow]
977 [acl.allow]
978 ** = barney
978 ** = barney
979 **/*.txt = wilma
979 **/*.txt = wilma
980 [acl]
980 [acl]
981 config = ../acl.config
981 config = ../acl.config
982 """
982 """
983 acl.config = """
983 acl.config = """
984 [acl.allow]
984 [acl.allow]
985 foo/** = betty
985 foo/** = betty
986 [hooks]
986 [hooks]
987 changegroup.acl = false
987 changegroup.acl = false
988 """
988 """
989 pushing to ../b
989 pushing to ../b
990 query 1; heads
990 query 1; heads
991 searching for changes
991 searching for changes
992 all remote heads known locally
992 all remote heads known locally
993 3 changesets found
993 3 changesets found
994 list of changesets:
994 list of changesets:
995 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
995 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
996 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
996 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
997 911600dab2ae7a9baff75958b84fe606851ce955
997 911600dab2ae7a9baff75958b84fe606851ce955
998 adding changesets
998 adding changesets
999 bundling: 1/3 changesets (33.33%)
999 bundling: 1/3 changesets (33.33%)
1000 bundling: 2/3 changesets (66.67%)
1000 bundling: 2/3 changesets (66.67%)
1001 bundling: 3/3 changesets (100.00%)
1001 bundling: 3/3 changesets (100.00%)
1002 bundling: 1/3 manifests (33.33%)
1002 bundling: 1/3 manifests (33.33%)
1003 bundling: 2/3 manifests (66.67%)
1003 bundling: 2/3 manifests (66.67%)
1004 bundling: 3/3 manifests (100.00%)
1004 bundling: 3/3 manifests (100.00%)
1005 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1005 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1006 bundling: foo/file.txt 2/3 files (66.67%)
1006 bundling: foo/file.txt 2/3 files (66.67%)
1007 bundling: quux/file.py 3/3 files (100.00%)
1007 bundling: quux/file.py 3/3 files (100.00%)
1008 changesets: 1 chunks
1008 changesets: 1 chunks
1009 add changeset ef1ea85a6374
1009 add changeset ef1ea85a6374
1010 changesets: 2 chunks
1010 changesets: 2 chunks
1011 add changeset f9cafe1212c8
1011 add changeset f9cafe1212c8
1012 changesets: 3 chunks
1012 changesets: 3 chunks
1013 add changeset 911600dab2ae
1013 add changeset 911600dab2ae
1014 adding manifests
1014 adding manifests
1015 manifests: 1/3 chunks (33.33%)
1015 manifests: 1/3 chunks (33.33%)
1016 manifests: 2/3 chunks (66.67%)
1016 manifests: 2/3 chunks (66.67%)
1017 manifests: 3/3 chunks (100.00%)
1017 manifests: 3/3 chunks (100.00%)
1018 adding file changes
1018 adding file changes
1019 adding foo/Bar/file.txt revisions
1019 adding foo/Bar/file.txt revisions
1020 files: 1/3 chunks (33.33%)
1020 files: 1/3 chunks (33.33%)
1021 adding foo/file.txt revisions
1021 adding foo/file.txt revisions
1022 files: 2/3 chunks (66.67%)
1022 files: 2/3 chunks (66.67%)
1023 adding quux/file.py revisions
1023 adding quux/file.py revisions
1024 files: 3/3 chunks (100.00%)
1024 files: 3/3 chunks (100.00%)
1025 added 3 changesets with 3 changes to 3 files
1025 added 3 changesets with 3 changes to 3 files
1026 calling hook pretxnchangegroup.acl: hgext.acl.hook
1026 calling hook pretxnchangegroup.acl: hgext.acl.hook
1027 acl: checking access for user "barney"
1027 acl: checking access for user "barney"
1028 acl: acl.allow.branches not enabled
1028 acl: acl.allow.branches not enabled
1029 acl: acl.deny.branches not enabled
1029 acl: acl.deny.branches not enabled
1030 acl: acl.allow enabled, 1 entries for user barney
1030 acl: acl.allow enabled, 1 entries for user barney
1031 acl: acl.deny enabled, 0 entries for user barney
1031 acl: acl.deny enabled, 0 entries for user barney
1032 acl: branch access granted: "ef1ea85a6374" on branch "default"
1032 acl: branch access granted: "ef1ea85a6374" on branch "default"
1033 acl: path access granted: "ef1ea85a6374"
1033 acl: path access granted: "ef1ea85a6374"
1034 acl: branch access granted: "f9cafe1212c8" on branch "default"
1034 acl: branch access granted: "f9cafe1212c8" on branch "default"
1035 acl: path access granted: "f9cafe1212c8"
1035 acl: path access granted: "f9cafe1212c8"
1036 acl: branch access granted: "911600dab2ae" on branch "default"
1036 acl: branch access granted: "911600dab2ae" on branch "default"
1037 acl: path access granted: "911600dab2ae"
1037 acl: path access granted: "911600dab2ae"
1038 updating the branch cache
1038 updating the branch cache
1039 checking for updated bookmarks
1039 checking for updated bookmarks
1040 repository tip rolled back to revision 0 (undo push)
1040 repository tip rolled back to revision 0 (undo push)
1041 0:6675d58eff77
1041 0:6675d58eff77
1042
1042
1043
1043
1044 asterisk
1044 asterisk
1045
1045
1046 $ init_config
1046 $ init_config
1047
1047
1048 asterisk test
1048 asterisk test
1049
1049
1050 $ echo '[acl.allow]' >> $config
1050 $ echo '[acl.allow]' >> $config
1051 $ echo "** = fred" >> $config
1051 $ echo "** = fred" >> $config
1052
1052
1053 fred is always allowed
1053 fred is always allowed
1054
1054
1055 $ do_push fred
1055 $ do_push fred
1056 Pushing as user fred
1056 Pushing as user fred
1057 hgrc = """
1057 hgrc = """
1058 [acl]
1058 [acl]
1059 sources = push
1059 sources = push
1060 [extensions]
1060 [extensions]
1061 [acl.allow]
1061 [acl.allow]
1062 ** = fred
1062 ** = fred
1063 """
1063 """
1064 pushing to ../b
1064 pushing to ../b
1065 query 1; heads
1065 query 1; heads
1066 searching for changes
1066 searching for changes
1067 all remote heads known locally
1067 all remote heads known locally
1068 invalidating branch cache (tip differs)
1068 invalidating branch cache (tip differs)
1069 3 changesets found
1069 3 changesets found
1070 list of changesets:
1070 list of changesets:
1071 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1071 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1072 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1072 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1073 911600dab2ae7a9baff75958b84fe606851ce955
1073 911600dab2ae7a9baff75958b84fe606851ce955
1074 adding changesets
1074 adding changesets
1075 bundling: 1/3 changesets (33.33%)
1075 bundling: 1/3 changesets (33.33%)
1076 bundling: 2/3 changesets (66.67%)
1076 bundling: 2/3 changesets (66.67%)
1077 bundling: 3/3 changesets (100.00%)
1077 bundling: 3/3 changesets (100.00%)
1078 bundling: 1/3 manifests (33.33%)
1078 bundling: 1/3 manifests (33.33%)
1079 bundling: 2/3 manifests (66.67%)
1079 bundling: 2/3 manifests (66.67%)
1080 bundling: 3/3 manifests (100.00%)
1080 bundling: 3/3 manifests (100.00%)
1081 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1081 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1082 bundling: foo/file.txt 2/3 files (66.67%)
1082 bundling: foo/file.txt 2/3 files (66.67%)
1083 bundling: quux/file.py 3/3 files (100.00%)
1083 bundling: quux/file.py 3/3 files (100.00%)
1084 changesets: 1 chunks
1084 changesets: 1 chunks
1085 add changeset ef1ea85a6374
1085 add changeset ef1ea85a6374
1086 changesets: 2 chunks
1086 changesets: 2 chunks
1087 add changeset f9cafe1212c8
1087 add changeset f9cafe1212c8
1088 changesets: 3 chunks
1088 changesets: 3 chunks
1089 add changeset 911600dab2ae
1089 add changeset 911600dab2ae
1090 adding manifests
1090 adding manifests
1091 manifests: 1/3 chunks (33.33%)
1091 manifests: 1/3 chunks (33.33%)
1092 manifests: 2/3 chunks (66.67%)
1092 manifests: 2/3 chunks (66.67%)
1093 manifests: 3/3 chunks (100.00%)
1093 manifests: 3/3 chunks (100.00%)
1094 adding file changes
1094 adding file changes
1095 adding foo/Bar/file.txt revisions
1095 adding foo/Bar/file.txt revisions
1096 files: 1/3 chunks (33.33%)
1096 files: 1/3 chunks (33.33%)
1097 adding foo/file.txt revisions
1097 adding foo/file.txt revisions
1098 files: 2/3 chunks (66.67%)
1098 files: 2/3 chunks (66.67%)
1099 adding quux/file.py revisions
1099 adding quux/file.py revisions
1100 files: 3/3 chunks (100.00%)
1100 files: 3/3 chunks (100.00%)
1101 added 3 changesets with 3 changes to 3 files
1101 added 3 changesets with 3 changes to 3 files
1102 calling hook pretxnchangegroup.acl: hgext.acl.hook
1102 calling hook pretxnchangegroup.acl: hgext.acl.hook
1103 acl: checking access for user "fred"
1103 acl: checking access for user "fred"
1104 acl: acl.allow.branches not enabled
1104 acl: acl.allow.branches not enabled
1105 acl: acl.deny.branches not enabled
1105 acl: acl.deny.branches not enabled
1106 acl: acl.allow enabled, 1 entries for user fred
1106 acl: acl.allow enabled, 1 entries for user fred
1107 acl: acl.deny not enabled
1107 acl: acl.deny not enabled
1108 acl: branch access granted: "ef1ea85a6374" on branch "default"
1108 acl: branch access granted: "ef1ea85a6374" on branch "default"
1109 acl: path access granted: "ef1ea85a6374"
1109 acl: path access granted: "ef1ea85a6374"
1110 acl: branch access granted: "f9cafe1212c8" on branch "default"
1110 acl: branch access granted: "f9cafe1212c8" on branch "default"
1111 acl: path access granted: "f9cafe1212c8"
1111 acl: path access granted: "f9cafe1212c8"
1112 acl: branch access granted: "911600dab2ae" on branch "default"
1112 acl: branch access granted: "911600dab2ae" on branch "default"
1113 acl: path access granted: "911600dab2ae"
1113 acl: path access granted: "911600dab2ae"
1114 updating the branch cache
1114 updating the branch cache
1115 checking for updated bookmarks
1115 checking for updated bookmarks
1116 repository tip rolled back to revision 0 (undo push)
1116 repository tip rolled back to revision 0 (undo push)
1117 0:6675d58eff77
1117 0:6675d58eff77
1118
1118
1119
1119
1120 $ echo '[acl.deny]' >> $config
1120 $ echo '[acl.deny]' >> $config
1121 $ echo "foo/Bar/** = *" >> $config
1121 $ echo "foo/Bar/** = *" >> $config
1122
1122
1123 no one is allowed inside foo/Bar/
1123 no one is allowed inside foo/Bar/
1124
1124
1125 $ do_push fred
1125 $ do_push fred
1126 Pushing as user fred
1126 Pushing as user fred
1127 hgrc = """
1127 hgrc = """
1128 [acl]
1128 [acl]
1129 sources = push
1129 sources = push
1130 [extensions]
1130 [extensions]
1131 [acl.allow]
1131 [acl.allow]
1132 ** = fred
1132 ** = fred
1133 [acl.deny]
1133 [acl.deny]
1134 foo/Bar/** = *
1134 foo/Bar/** = *
1135 """
1135 """
1136 pushing to ../b
1136 pushing to ../b
1137 query 1; heads
1137 query 1; heads
1138 searching for changes
1138 searching for changes
1139 all remote heads known locally
1139 all remote heads known locally
1140 invalidating branch cache (tip differs)
1140 invalidating branch cache (tip differs)
1141 3 changesets found
1141 3 changesets found
1142 list of changesets:
1142 list of changesets:
1143 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1143 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1144 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1144 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1145 911600dab2ae7a9baff75958b84fe606851ce955
1145 911600dab2ae7a9baff75958b84fe606851ce955
1146 adding changesets
1146 adding changesets
1147 bundling: 1/3 changesets (33.33%)
1147 bundling: 1/3 changesets (33.33%)
1148 bundling: 2/3 changesets (66.67%)
1148 bundling: 2/3 changesets (66.67%)
1149 bundling: 3/3 changesets (100.00%)
1149 bundling: 3/3 changesets (100.00%)
1150 bundling: 1/3 manifests (33.33%)
1150 bundling: 1/3 manifests (33.33%)
1151 bundling: 2/3 manifests (66.67%)
1151 bundling: 2/3 manifests (66.67%)
1152 bundling: 3/3 manifests (100.00%)
1152 bundling: 3/3 manifests (100.00%)
1153 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1153 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1154 bundling: foo/file.txt 2/3 files (66.67%)
1154 bundling: foo/file.txt 2/3 files (66.67%)
1155 bundling: quux/file.py 3/3 files (100.00%)
1155 bundling: quux/file.py 3/3 files (100.00%)
1156 changesets: 1 chunks
1156 changesets: 1 chunks
1157 add changeset ef1ea85a6374
1157 add changeset ef1ea85a6374
1158 changesets: 2 chunks
1158 changesets: 2 chunks
1159 add changeset f9cafe1212c8
1159 add changeset f9cafe1212c8
1160 changesets: 3 chunks
1160 changesets: 3 chunks
1161 add changeset 911600dab2ae
1161 add changeset 911600dab2ae
1162 adding manifests
1162 adding manifests
1163 manifests: 1/3 chunks (33.33%)
1163 manifests: 1/3 chunks (33.33%)
1164 manifests: 2/3 chunks (66.67%)
1164 manifests: 2/3 chunks (66.67%)
1165 manifests: 3/3 chunks (100.00%)
1165 manifests: 3/3 chunks (100.00%)
1166 adding file changes
1166 adding file changes
1167 adding foo/Bar/file.txt revisions
1167 adding foo/Bar/file.txt revisions
1168 files: 1/3 chunks (33.33%)
1168 files: 1/3 chunks (33.33%)
1169 adding foo/file.txt revisions
1169 adding foo/file.txt revisions
1170 files: 2/3 chunks (66.67%)
1170 files: 2/3 chunks (66.67%)
1171 adding quux/file.py revisions
1171 adding quux/file.py revisions
1172 files: 3/3 chunks (100.00%)
1172 files: 3/3 chunks (100.00%)
1173 added 3 changesets with 3 changes to 3 files
1173 added 3 changesets with 3 changes to 3 files
1174 calling hook pretxnchangegroup.acl: hgext.acl.hook
1174 calling hook pretxnchangegroup.acl: hgext.acl.hook
1175 acl: checking access for user "fred"
1175 acl: checking access for user "fred"
1176 acl: acl.allow.branches not enabled
1176 acl: acl.allow.branches not enabled
1177 acl: acl.deny.branches not enabled
1177 acl: acl.deny.branches not enabled
1178 acl: acl.allow enabled, 1 entries for user fred
1178 acl: acl.allow enabled, 1 entries for user fred
1179 acl: acl.deny enabled, 1 entries for user fred
1179 acl: acl.deny enabled, 1 entries for user fred
1180 acl: branch access granted: "ef1ea85a6374" on branch "default"
1180 acl: branch access granted: "ef1ea85a6374" on branch "default"
1181 acl: path access granted: "ef1ea85a6374"
1181 acl: path access granted: "ef1ea85a6374"
1182 acl: branch access granted: "f9cafe1212c8" on branch "default"
1182 acl: branch access granted: "f9cafe1212c8" on branch "default"
1183 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1183 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1184 transaction abort!
1184 transaction abort!
1185 rollback completed
1185 rollback completed
1186 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1186 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1187 no rollback information available
1187 no rollback information available
1188 0:6675d58eff77
1188 0:6675d58eff77
1189
1189
1190
1190
1191 Groups
1191 Groups
1192
1192
1193 $ init_config
1193 $ init_config
1194
1194
1195 OS-level groups
1195 OS-level groups
1196
1196
1197 $ echo '[acl.allow]' >> $config
1197 $ echo '[acl.allow]' >> $config
1198 $ echo "** = @group1" >> $config
1198 $ echo "** = @group1" >> $config
1199
1199
1200 @group1 is always allowed
1200 @group1 is always allowed
1201
1201
1202 $ do_push fred
1202 $ do_push fred
1203 Pushing as user fred
1203 Pushing as user fred
1204 hgrc = """
1204 hgrc = """
1205 [acl]
1205 [acl]
1206 sources = push
1206 sources = push
1207 [extensions]
1207 [extensions]
1208 [acl.allow]
1208 [acl.allow]
1209 ** = @group1
1209 ** = @group1
1210 """
1210 """
1211 pushing to ../b
1211 pushing to ../b
1212 query 1; heads
1212 query 1; heads
1213 searching for changes
1213 searching for changes
1214 all remote heads known locally
1214 all remote heads known locally
1215 3 changesets found
1215 3 changesets found
1216 list of changesets:
1216 list of changesets:
1217 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1217 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1218 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1218 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1219 911600dab2ae7a9baff75958b84fe606851ce955
1219 911600dab2ae7a9baff75958b84fe606851ce955
1220 adding changesets
1220 adding changesets
1221 bundling: 1/3 changesets (33.33%)
1221 bundling: 1/3 changesets (33.33%)
1222 bundling: 2/3 changesets (66.67%)
1222 bundling: 2/3 changesets (66.67%)
1223 bundling: 3/3 changesets (100.00%)
1223 bundling: 3/3 changesets (100.00%)
1224 bundling: 1/3 manifests (33.33%)
1224 bundling: 1/3 manifests (33.33%)
1225 bundling: 2/3 manifests (66.67%)
1225 bundling: 2/3 manifests (66.67%)
1226 bundling: 3/3 manifests (100.00%)
1226 bundling: 3/3 manifests (100.00%)
1227 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1227 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1228 bundling: foo/file.txt 2/3 files (66.67%)
1228 bundling: foo/file.txt 2/3 files (66.67%)
1229 bundling: quux/file.py 3/3 files (100.00%)
1229 bundling: quux/file.py 3/3 files (100.00%)
1230 changesets: 1 chunks
1230 changesets: 1 chunks
1231 add changeset ef1ea85a6374
1231 add changeset ef1ea85a6374
1232 changesets: 2 chunks
1232 changesets: 2 chunks
1233 add changeset f9cafe1212c8
1233 add changeset f9cafe1212c8
1234 changesets: 3 chunks
1234 changesets: 3 chunks
1235 add changeset 911600dab2ae
1235 add changeset 911600dab2ae
1236 adding manifests
1236 adding manifests
1237 manifests: 1/3 chunks (33.33%)
1237 manifests: 1/3 chunks (33.33%)
1238 manifests: 2/3 chunks (66.67%)
1238 manifests: 2/3 chunks (66.67%)
1239 manifests: 3/3 chunks (100.00%)
1239 manifests: 3/3 chunks (100.00%)
1240 adding file changes
1240 adding file changes
1241 adding foo/Bar/file.txt revisions
1241 adding foo/Bar/file.txt revisions
1242 files: 1/3 chunks (33.33%)
1242 files: 1/3 chunks (33.33%)
1243 adding foo/file.txt revisions
1243 adding foo/file.txt revisions
1244 files: 2/3 chunks (66.67%)
1244 files: 2/3 chunks (66.67%)
1245 adding quux/file.py revisions
1245 adding quux/file.py revisions
1246 files: 3/3 chunks (100.00%)
1246 files: 3/3 chunks (100.00%)
1247 added 3 changesets with 3 changes to 3 files
1247 added 3 changesets with 3 changes to 3 files
1248 calling hook pretxnchangegroup.acl: hgext.acl.hook
1248 calling hook pretxnchangegroup.acl: hgext.acl.hook
1249 acl: checking access for user "fred"
1249 acl: checking access for user "fred"
1250 acl: acl.allow.branches not enabled
1250 acl: acl.allow.branches not enabled
1251 acl: acl.deny.branches not enabled
1251 acl: acl.deny.branches not enabled
1252 acl: "group1" not defined in [acl.groups]
1252 acl: "group1" not defined in [acl.groups]
1253 acl: acl.allow enabled, 1 entries for user fred
1253 acl: acl.allow enabled, 1 entries for user fred
1254 acl: acl.deny not enabled
1254 acl: acl.deny not enabled
1255 acl: branch access granted: "ef1ea85a6374" on branch "default"
1255 acl: branch access granted: "ef1ea85a6374" on branch "default"
1256 acl: path access granted: "ef1ea85a6374"
1256 acl: path access granted: "ef1ea85a6374"
1257 acl: branch access granted: "f9cafe1212c8" on branch "default"
1257 acl: branch access granted: "f9cafe1212c8" on branch "default"
1258 acl: path access granted: "f9cafe1212c8"
1258 acl: path access granted: "f9cafe1212c8"
1259 acl: branch access granted: "911600dab2ae" on branch "default"
1259 acl: branch access granted: "911600dab2ae" on branch "default"
1260 acl: path access granted: "911600dab2ae"
1260 acl: path access granted: "911600dab2ae"
1261 updating the branch cache
1261 updating the branch cache
1262 checking for updated bookmarks
1262 checking for updated bookmarks
1263 repository tip rolled back to revision 0 (undo push)
1263 repository tip rolled back to revision 0 (undo push)
1264 0:6675d58eff77
1264 0:6675d58eff77
1265
1265
1266
1266
1267 $ echo '[acl.deny]' >> $config
1267 $ echo '[acl.deny]' >> $config
1268 $ echo "foo/Bar/** = @group1" >> $config
1268 $ echo "foo/Bar/** = @group1" >> $config
1269
1269
1270 @group is allowed inside anything but foo/Bar/
1270 @group is allowed inside anything but foo/Bar/
1271
1271
1272 $ do_push fred
1272 $ do_push fred
1273 Pushing as user fred
1273 Pushing as user fred
1274 hgrc = """
1274 hgrc = """
1275 [acl]
1275 [acl]
1276 sources = push
1276 sources = push
1277 [extensions]
1277 [extensions]
1278 [acl.allow]
1278 [acl.allow]
1279 ** = @group1
1279 ** = @group1
1280 [acl.deny]
1280 [acl.deny]
1281 foo/Bar/** = @group1
1281 foo/Bar/** = @group1
1282 """
1282 """
1283 pushing to ../b
1283 pushing to ../b
1284 query 1; heads
1284 query 1; heads
1285 searching for changes
1285 searching for changes
1286 all remote heads known locally
1286 all remote heads known locally
1287 invalidating branch cache (tip differs)
1287 invalidating branch cache (tip differs)
1288 3 changesets found
1288 3 changesets found
1289 list of changesets:
1289 list of changesets:
1290 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1290 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1291 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1291 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1292 911600dab2ae7a9baff75958b84fe606851ce955
1292 911600dab2ae7a9baff75958b84fe606851ce955
1293 adding changesets
1293 adding changesets
1294 bundling: 1/3 changesets (33.33%)
1294 bundling: 1/3 changesets (33.33%)
1295 bundling: 2/3 changesets (66.67%)
1295 bundling: 2/3 changesets (66.67%)
1296 bundling: 3/3 changesets (100.00%)
1296 bundling: 3/3 changesets (100.00%)
1297 bundling: 1/3 manifests (33.33%)
1297 bundling: 1/3 manifests (33.33%)
1298 bundling: 2/3 manifests (66.67%)
1298 bundling: 2/3 manifests (66.67%)
1299 bundling: 3/3 manifests (100.00%)
1299 bundling: 3/3 manifests (100.00%)
1300 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1300 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1301 bundling: foo/file.txt 2/3 files (66.67%)
1301 bundling: foo/file.txt 2/3 files (66.67%)
1302 bundling: quux/file.py 3/3 files (100.00%)
1302 bundling: quux/file.py 3/3 files (100.00%)
1303 changesets: 1 chunks
1303 changesets: 1 chunks
1304 add changeset ef1ea85a6374
1304 add changeset ef1ea85a6374
1305 changesets: 2 chunks
1305 changesets: 2 chunks
1306 add changeset f9cafe1212c8
1306 add changeset f9cafe1212c8
1307 changesets: 3 chunks
1307 changesets: 3 chunks
1308 add changeset 911600dab2ae
1308 add changeset 911600dab2ae
1309 adding manifests
1309 adding manifests
1310 manifests: 1/3 chunks (33.33%)
1310 manifests: 1/3 chunks (33.33%)
1311 manifests: 2/3 chunks (66.67%)
1311 manifests: 2/3 chunks (66.67%)
1312 manifests: 3/3 chunks (100.00%)
1312 manifests: 3/3 chunks (100.00%)
1313 adding file changes
1313 adding file changes
1314 adding foo/Bar/file.txt revisions
1314 adding foo/Bar/file.txt revisions
1315 files: 1/3 chunks (33.33%)
1315 files: 1/3 chunks (33.33%)
1316 adding foo/file.txt revisions
1316 adding foo/file.txt revisions
1317 files: 2/3 chunks (66.67%)
1317 files: 2/3 chunks (66.67%)
1318 adding quux/file.py revisions
1318 adding quux/file.py revisions
1319 files: 3/3 chunks (100.00%)
1319 files: 3/3 chunks (100.00%)
1320 added 3 changesets with 3 changes to 3 files
1320 added 3 changesets with 3 changes to 3 files
1321 calling hook pretxnchangegroup.acl: hgext.acl.hook
1321 calling hook pretxnchangegroup.acl: hgext.acl.hook
1322 acl: checking access for user "fred"
1322 acl: checking access for user "fred"
1323 acl: acl.allow.branches not enabled
1323 acl: acl.allow.branches not enabled
1324 acl: acl.deny.branches not enabled
1324 acl: acl.deny.branches not enabled
1325 acl: "group1" not defined in [acl.groups]
1325 acl: "group1" not defined in [acl.groups]
1326 acl: acl.allow enabled, 1 entries for user fred
1326 acl: acl.allow enabled, 1 entries for user fred
1327 acl: "group1" not defined in [acl.groups]
1327 acl: "group1" not defined in [acl.groups]
1328 acl: acl.deny enabled, 1 entries for user fred
1328 acl: acl.deny enabled, 1 entries for user fred
1329 acl: branch access granted: "ef1ea85a6374" on branch "default"
1329 acl: branch access granted: "ef1ea85a6374" on branch "default"
1330 acl: path access granted: "ef1ea85a6374"
1330 acl: path access granted: "ef1ea85a6374"
1331 acl: branch access granted: "f9cafe1212c8" on branch "default"
1331 acl: branch access granted: "f9cafe1212c8" on branch "default"
1332 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1332 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1333 transaction abort!
1333 transaction abort!
1334 rollback completed
1334 rollback completed
1335 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1335 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1336 no rollback information available
1336 no rollback information available
1337 0:6675d58eff77
1337 0:6675d58eff77
1338
1338
1339
1339
1340 Invalid group
1340 Invalid group
1341
1341
1342 Disable the fakegroups trick to get real failures
1342 Disable the fakegroups trick to get real failures
1343
1343
1344 $ grep -v fakegroups $config > config.tmp
1344 $ grep -v fakegroups $config > config.tmp
1345 $ mv config.tmp $config
1345 $ mv config.tmp $config
1346 $ echo '[acl.allow]' >> $config
1346 $ echo '[acl.allow]' >> $config
1347 $ echo "** = @unlikelytoexist" >> $config
1347 $ echo "** = @unlikelytoexist" >> $config
1348 $ do_push fred 2>&1 | grep unlikelytoexist
1348 $ do_push fred 2>&1 | grep unlikelytoexist
1349 ** = @unlikelytoexist
1349 ** = @unlikelytoexist
1350 acl: "unlikelytoexist" not defined in [acl.groups]
1350 acl: "unlikelytoexist" not defined in [acl.groups]
1351 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1351 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1352 abort: group 'unlikelytoexist' is undefined
1352 abort: group 'unlikelytoexist' is undefined
1353
1353
1354
1354
1355 Branch acl tests setup
1355 Branch acl tests setup
1356
1356
1357 $ init_config
1357 $ init_config
1358 $ cd b
1358 $ cd b
1359 $ hg up
1359 $ hg up
1360 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1360 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1361 $ hg branch foobar
1361 $ hg branch foobar
1362 marked working directory as branch foobar
1362 marked working directory as branch foobar
1363 (branches are permanent and global, did you want a bookmark?)
1363 $ hg commit -m 'create foobar'
1364 $ hg commit -m 'create foobar'
1364 $ echo 'foo contents' > abc.txt
1365 $ echo 'foo contents' > abc.txt
1365 $ hg add abc.txt
1366 $ hg add abc.txt
1366 $ hg commit -m 'foobar contents'
1367 $ hg commit -m 'foobar contents'
1367 $ cd ..
1368 $ cd ..
1368 $ hg --cwd a pull ../b
1369 $ hg --cwd a pull ../b
1369 pulling from ../b
1370 pulling from ../b
1370 searching for changes
1371 searching for changes
1371 adding changesets
1372 adding changesets
1372 adding manifests
1373 adding manifests
1373 adding file changes
1374 adding file changes
1374 added 2 changesets with 1 changes to 1 files (+1 heads)
1375 added 2 changesets with 1 changes to 1 files (+1 heads)
1375 (run 'hg heads' to see heads)
1376 (run 'hg heads' to see heads)
1376
1377
1377 Create additional changeset on foobar branch
1378 Create additional changeset on foobar branch
1378
1379
1379 $ cd a
1380 $ cd a
1380 $ hg up -C foobar
1381 $ hg up -C foobar
1381 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1382 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1382 $ echo 'foo contents2' > abc.txt
1383 $ echo 'foo contents2' > abc.txt
1383 $ hg commit -m 'foobar contents2'
1384 $ hg commit -m 'foobar contents2'
1384 $ cd ..
1385 $ cd ..
1385
1386
1386
1387
1387 No branch acls specified
1388 No branch acls specified
1388
1389
1389 $ do_push astro
1390 $ do_push astro
1390 Pushing as user astro
1391 Pushing as user astro
1391 hgrc = """
1392 hgrc = """
1392 [acl]
1393 [acl]
1393 sources = push
1394 sources = push
1394 [extensions]
1395 [extensions]
1395 """
1396 """
1396 pushing to ../b
1397 pushing to ../b
1397 query 1; heads
1398 query 1; heads
1398 searching for changes
1399 searching for changes
1399 all remote heads known locally
1400 all remote heads known locally
1400 4 changesets found
1401 4 changesets found
1401 list of changesets:
1402 list of changesets:
1402 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1403 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1403 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1404 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1404 911600dab2ae7a9baff75958b84fe606851ce955
1405 911600dab2ae7a9baff75958b84fe606851ce955
1405 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1406 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1406 adding changesets
1407 adding changesets
1407 bundling: 1/4 changesets (25.00%)
1408 bundling: 1/4 changesets (25.00%)
1408 bundling: 2/4 changesets (50.00%)
1409 bundling: 2/4 changesets (50.00%)
1409 bundling: 3/4 changesets (75.00%)
1410 bundling: 3/4 changesets (75.00%)
1410 bundling: 4/4 changesets (100.00%)
1411 bundling: 4/4 changesets (100.00%)
1411 bundling: 1/4 manifests (25.00%)
1412 bundling: 1/4 manifests (25.00%)
1412 bundling: 2/4 manifests (50.00%)
1413 bundling: 2/4 manifests (50.00%)
1413 bundling: 3/4 manifests (75.00%)
1414 bundling: 3/4 manifests (75.00%)
1414 bundling: 4/4 manifests (100.00%)
1415 bundling: 4/4 manifests (100.00%)
1415 bundling: abc.txt 1/4 files (25.00%)
1416 bundling: abc.txt 1/4 files (25.00%)
1416 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1417 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1417 bundling: foo/file.txt 3/4 files (75.00%)
1418 bundling: foo/file.txt 3/4 files (75.00%)
1418 bundling: quux/file.py 4/4 files (100.00%)
1419 bundling: quux/file.py 4/4 files (100.00%)
1419 changesets: 1 chunks
1420 changesets: 1 chunks
1420 add changeset ef1ea85a6374
1421 add changeset ef1ea85a6374
1421 changesets: 2 chunks
1422 changesets: 2 chunks
1422 add changeset f9cafe1212c8
1423 add changeset f9cafe1212c8
1423 changesets: 3 chunks
1424 changesets: 3 chunks
1424 add changeset 911600dab2ae
1425 add changeset 911600dab2ae
1425 changesets: 4 chunks
1426 changesets: 4 chunks
1426 add changeset e8fc755d4d82
1427 add changeset e8fc755d4d82
1427 adding manifests
1428 adding manifests
1428 manifests: 1/4 chunks (25.00%)
1429 manifests: 1/4 chunks (25.00%)
1429 manifests: 2/4 chunks (50.00%)
1430 manifests: 2/4 chunks (50.00%)
1430 manifests: 3/4 chunks (75.00%)
1431 manifests: 3/4 chunks (75.00%)
1431 manifests: 4/4 chunks (100.00%)
1432 manifests: 4/4 chunks (100.00%)
1432 adding file changes
1433 adding file changes
1433 adding abc.txt revisions
1434 adding abc.txt revisions
1434 files: 1/4 chunks (25.00%)
1435 files: 1/4 chunks (25.00%)
1435 adding foo/Bar/file.txt revisions
1436 adding foo/Bar/file.txt revisions
1436 files: 2/4 chunks (50.00%)
1437 files: 2/4 chunks (50.00%)
1437 adding foo/file.txt revisions
1438 adding foo/file.txt revisions
1438 files: 3/4 chunks (75.00%)
1439 files: 3/4 chunks (75.00%)
1439 adding quux/file.py revisions
1440 adding quux/file.py revisions
1440 files: 4/4 chunks (100.00%)
1441 files: 4/4 chunks (100.00%)
1441 added 4 changesets with 4 changes to 4 files (+1 heads)
1442 added 4 changesets with 4 changes to 4 files (+1 heads)
1442 calling hook pretxnchangegroup.acl: hgext.acl.hook
1443 calling hook pretxnchangegroup.acl: hgext.acl.hook
1443 acl: checking access for user "astro"
1444 acl: checking access for user "astro"
1444 acl: acl.allow.branches not enabled
1445 acl: acl.allow.branches not enabled
1445 acl: acl.deny.branches not enabled
1446 acl: acl.deny.branches not enabled
1446 acl: acl.allow not enabled
1447 acl: acl.allow not enabled
1447 acl: acl.deny not enabled
1448 acl: acl.deny not enabled
1448 acl: branch access granted: "ef1ea85a6374" on branch "default"
1449 acl: branch access granted: "ef1ea85a6374" on branch "default"
1449 acl: path access granted: "ef1ea85a6374"
1450 acl: path access granted: "ef1ea85a6374"
1450 acl: branch access granted: "f9cafe1212c8" on branch "default"
1451 acl: branch access granted: "f9cafe1212c8" on branch "default"
1451 acl: path access granted: "f9cafe1212c8"
1452 acl: path access granted: "f9cafe1212c8"
1452 acl: branch access granted: "911600dab2ae" on branch "default"
1453 acl: branch access granted: "911600dab2ae" on branch "default"
1453 acl: path access granted: "911600dab2ae"
1454 acl: path access granted: "911600dab2ae"
1454 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1455 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1455 acl: path access granted: "e8fc755d4d82"
1456 acl: path access granted: "e8fc755d4d82"
1456 updating the branch cache
1457 updating the branch cache
1457 checking for updated bookmarks
1458 checking for updated bookmarks
1458 repository tip rolled back to revision 2 (undo push)
1459 repository tip rolled back to revision 2 (undo push)
1459 2:fb35475503ef
1460 2:fb35475503ef
1460
1461
1461
1462
1462 Branch acl deny test
1463 Branch acl deny test
1463
1464
1464 $ echo "[acl.deny.branches]" >> $config
1465 $ echo "[acl.deny.branches]" >> $config
1465 $ echo "foobar = *" >> $config
1466 $ echo "foobar = *" >> $config
1466 $ do_push astro
1467 $ do_push astro
1467 Pushing as user astro
1468 Pushing as user astro
1468 hgrc = """
1469 hgrc = """
1469 [acl]
1470 [acl]
1470 sources = push
1471 sources = push
1471 [extensions]
1472 [extensions]
1472 [acl.deny.branches]
1473 [acl.deny.branches]
1473 foobar = *
1474 foobar = *
1474 """
1475 """
1475 pushing to ../b
1476 pushing to ../b
1476 query 1; heads
1477 query 1; heads
1477 searching for changes
1478 searching for changes
1478 all remote heads known locally
1479 all remote heads known locally
1479 invalidating branch cache (tip differs)
1480 invalidating branch cache (tip differs)
1480 4 changesets found
1481 4 changesets found
1481 list of changesets:
1482 list of changesets:
1482 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1483 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1483 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1484 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1484 911600dab2ae7a9baff75958b84fe606851ce955
1485 911600dab2ae7a9baff75958b84fe606851ce955
1485 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1486 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1486 adding changesets
1487 adding changesets
1487 bundling: 1/4 changesets (25.00%)
1488 bundling: 1/4 changesets (25.00%)
1488 bundling: 2/4 changesets (50.00%)
1489 bundling: 2/4 changesets (50.00%)
1489 bundling: 3/4 changesets (75.00%)
1490 bundling: 3/4 changesets (75.00%)
1490 bundling: 4/4 changesets (100.00%)
1491 bundling: 4/4 changesets (100.00%)
1491 bundling: 1/4 manifests (25.00%)
1492 bundling: 1/4 manifests (25.00%)
1492 bundling: 2/4 manifests (50.00%)
1493 bundling: 2/4 manifests (50.00%)
1493 bundling: 3/4 manifests (75.00%)
1494 bundling: 3/4 manifests (75.00%)
1494 bundling: 4/4 manifests (100.00%)
1495 bundling: 4/4 manifests (100.00%)
1495 bundling: abc.txt 1/4 files (25.00%)
1496 bundling: abc.txt 1/4 files (25.00%)
1496 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1497 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1497 bundling: foo/file.txt 3/4 files (75.00%)
1498 bundling: foo/file.txt 3/4 files (75.00%)
1498 bundling: quux/file.py 4/4 files (100.00%)
1499 bundling: quux/file.py 4/4 files (100.00%)
1499 changesets: 1 chunks
1500 changesets: 1 chunks
1500 add changeset ef1ea85a6374
1501 add changeset ef1ea85a6374
1501 changesets: 2 chunks
1502 changesets: 2 chunks
1502 add changeset f9cafe1212c8
1503 add changeset f9cafe1212c8
1503 changesets: 3 chunks
1504 changesets: 3 chunks
1504 add changeset 911600dab2ae
1505 add changeset 911600dab2ae
1505 changesets: 4 chunks
1506 changesets: 4 chunks
1506 add changeset e8fc755d4d82
1507 add changeset e8fc755d4d82
1507 adding manifests
1508 adding manifests
1508 manifests: 1/4 chunks (25.00%)
1509 manifests: 1/4 chunks (25.00%)
1509 manifests: 2/4 chunks (50.00%)
1510 manifests: 2/4 chunks (50.00%)
1510 manifests: 3/4 chunks (75.00%)
1511 manifests: 3/4 chunks (75.00%)
1511 manifests: 4/4 chunks (100.00%)
1512 manifests: 4/4 chunks (100.00%)
1512 adding file changes
1513 adding file changes
1513 adding abc.txt revisions
1514 adding abc.txt revisions
1514 files: 1/4 chunks (25.00%)
1515 files: 1/4 chunks (25.00%)
1515 adding foo/Bar/file.txt revisions
1516 adding foo/Bar/file.txt revisions
1516 files: 2/4 chunks (50.00%)
1517 files: 2/4 chunks (50.00%)
1517 adding foo/file.txt revisions
1518 adding foo/file.txt revisions
1518 files: 3/4 chunks (75.00%)
1519 files: 3/4 chunks (75.00%)
1519 adding quux/file.py revisions
1520 adding quux/file.py revisions
1520 files: 4/4 chunks (100.00%)
1521 files: 4/4 chunks (100.00%)
1521 added 4 changesets with 4 changes to 4 files (+1 heads)
1522 added 4 changesets with 4 changes to 4 files (+1 heads)
1522 calling hook pretxnchangegroup.acl: hgext.acl.hook
1523 calling hook pretxnchangegroup.acl: hgext.acl.hook
1523 acl: checking access for user "astro"
1524 acl: checking access for user "astro"
1524 acl: acl.allow.branches not enabled
1525 acl: acl.allow.branches not enabled
1525 acl: acl.deny.branches enabled, 1 entries for user astro
1526 acl: acl.deny.branches enabled, 1 entries for user astro
1526 acl: acl.allow not enabled
1527 acl: acl.allow not enabled
1527 acl: acl.deny not enabled
1528 acl: acl.deny not enabled
1528 acl: branch access granted: "ef1ea85a6374" on branch "default"
1529 acl: branch access granted: "ef1ea85a6374" on branch "default"
1529 acl: path access granted: "ef1ea85a6374"
1530 acl: path access granted: "ef1ea85a6374"
1530 acl: branch access granted: "f9cafe1212c8" on branch "default"
1531 acl: branch access granted: "f9cafe1212c8" on branch "default"
1531 acl: path access granted: "f9cafe1212c8"
1532 acl: path access granted: "f9cafe1212c8"
1532 acl: branch access granted: "911600dab2ae" on branch "default"
1533 acl: branch access granted: "911600dab2ae" on branch "default"
1533 acl: path access granted: "911600dab2ae"
1534 acl: path access granted: "911600dab2ae"
1534 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1535 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1535 transaction abort!
1536 transaction abort!
1536 rollback completed
1537 rollback completed
1537 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1538 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1538 no rollback information available
1539 no rollback information available
1539 2:fb35475503ef
1540 2:fb35475503ef
1540
1541
1541
1542
1542 Branch acl empty allow test
1543 Branch acl empty allow test
1543
1544
1544 $ init_config
1545 $ init_config
1545 $ echo "[acl.allow.branches]" >> $config
1546 $ echo "[acl.allow.branches]" >> $config
1546 $ do_push astro
1547 $ do_push astro
1547 Pushing as user astro
1548 Pushing as user astro
1548 hgrc = """
1549 hgrc = """
1549 [acl]
1550 [acl]
1550 sources = push
1551 sources = push
1551 [extensions]
1552 [extensions]
1552 [acl.allow.branches]
1553 [acl.allow.branches]
1553 """
1554 """
1554 pushing to ../b
1555 pushing to ../b
1555 query 1; heads
1556 query 1; heads
1556 searching for changes
1557 searching for changes
1557 all remote heads known locally
1558 all remote heads known locally
1558 4 changesets found
1559 4 changesets found
1559 list of changesets:
1560 list of changesets:
1560 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1561 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1561 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1562 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1562 911600dab2ae7a9baff75958b84fe606851ce955
1563 911600dab2ae7a9baff75958b84fe606851ce955
1563 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1564 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1564 adding changesets
1565 adding changesets
1565 bundling: 1/4 changesets (25.00%)
1566 bundling: 1/4 changesets (25.00%)
1566 bundling: 2/4 changesets (50.00%)
1567 bundling: 2/4 changesets (50.00%)
1567 bundling: 3/4 changesets (75.00%)
1568 bundling: 3/4 changesets (75.00%)
1568 bundling: 4/4 changesets (100.00%)
1569 bundling: 4/4 changesets (100.00%)
1569 bundling: 1/4 manifests (25.00%)
1570 bundling: 1/4 manifests (25.00%)
1570 bundling: 2/4 manifests (50.00%)
1571 bundling: 2/4 manifests (50.00%)
1571 bundling: 3/4 manifests (75.00%)
1572 bundling: 3/4 manifests (75.00%)
1572 bundling: 4/4 manifests (100.00%)
1573 bundling: 4/4 manifests (100.00%)
1573 bundling: abc.txt 1/4 files (25.00%)
1574 bundling: abc.txt 1/4 files (25.00%)
1574 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1575 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1575 bundling: foo/file.txt 3/4 files (75.00%)
1576 bundling: foo/file.txt 3/4 files (75.00%)
1576 bundling: quux/file.py 4/4 files (100.00%)
1577 bundling: quux/file.py 4/4 files (100.00%)
1577 changesets: 1 chunks
1578 changesets: 1 chunks
1578 add changeset ef1ea85a6374
1579 add changeset ef1ea85a6374
1579 changesets: 2 chunks
1580 changesets: 2 chunks
1580 add changeset f9cafe1212c8
1581 add changeset f9cafe1212c8
1581 changesets: 3 chunks
1582 changesets: 3 chunks
1582 add changeset 911600dab2ae
1583 add changeset 911600dab2ae
1583 changesets: 4 chunks
1584 changesets: 4 chunks
1584 add changeset e8fc755d4d82
1585 add changeset e8fc755d4d82
1585 adding manifests
1586 adding manifests
1586 manifests: 1/4 chunks (25.00%)
1587 manifests: 1/4 chunks (25.00%)
1587 manifests: 2/4 chunks (50.00%)
1588 manifests: 2/4 chunks (50.00%)
1588 manifests: 3/4 chunks (75.00%)
1589 manifests: 3/4 chunks (75.00%)
1589 manifests: 4/4 chunks (100.00%)
1590 manifests: 4/4 chunks (100.00%)
1590 adding file changes
1591 adding file changes
1591 adding abc.txt revisions
1592 adding abc.txt revisions
1592 files: 1/4 chunks (25.00%)
1593 files: 1/4 chunks (25.00%)
1593 adding foo/Bar/file.txt revisions
1594 adding foo/Bar/file.txt revisions
1594 files: 2/4 chunks (50.00%)
1595 files: 2/4 chunks (50.00%)
1595 adding foo/file.txt revisions
1596 adding foo/file.txt revisions
1596 files: 3/4 chunks (75.00%)
1597 files: 3/4 chunks (75.00%)
1597 adding quux/file.py revisions
1598 adding quux/file.py revisions
1598 files: 4/4 chunks (100.00%)
1599 files: 4/4 chunks (100.00%)
1599 added 4 changesets with 4 changes to 4 files (+1 heads)
1600 added 4 changesets with 4 changes to 4 files (+1 heads)
1600 calling hook pretxnchangegroup.acl: hgext.acl.hook
1601 calling hook pretxnchangegroup.acl: hgext.acl.hook
1601 acl: checking access for user "astro"
1602 acl: checking access for user "astro"
1602 acl: acl.allow.branches enabled, 0 entries for user astro
1603 acl: acl.allow.branches enabled, 0 entries for user astro
1603 acl: acl.deny.branches not enabled
1604 acl: acl.deny.branches not enabled
1604 acl: acl.allow not enabled
1605 acl: acl.allow not enabled
1605 acl: acl.deny not enabled
1606 acl: acl.deny not enabled
1606 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1607 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1607 transaction abort!
1608 transaction abort!
1608 rollback completed
1609 rollback completed
1609 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1610 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1610 no rollback information available
1611 no rollback information available
1611 2:fb35475503ef
1612 2:fb35475503ef
1612
1613
1613
1614
1614 Branch acl allow other
1615 Branch acl allow other
1615
1616
1616 $ init_config
1617 $ init_config
1617 $ echo "[acl.allow.branches]" >> $config
1618 $ echo "[acl.allow.branches]" >> $config
1618 $ echo "* = george" >> $config
1619 $ echo "* = george" >> $config
1619 $ do_push astro
1620 $ do_push astro
1620 Pushing as user astro
1621 Pushing as user astro
1621 hgrc = """
1622 hgrc = """
1622 [acl]
1623 [acl]
1623 sources = push
1624 sources = push
1624 [extensions]
1625 [extensions]
1625 [acl.allow.branches]
1626 [acl.allow.branches]
1626 * = george
1627 * = george
1627 """
1628 """
1628 pushing to ../b
1629 pushing to ../b
1629 query 1; heads
1630 query 1; heads
1630 searching for changes
1631 searching for changes
1631 all remote heads known locally
1632 all remote heads known locally
1632 4 changesets found
1633 4 changesets found
1633 list of changesets:
1634 list of changesets:
1634 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1635 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1635 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1636 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1636 911600dab2ae7a9baff75958b84fe606851ce955
1637 911600dab2ae7a9baff75958b84fe606851ce955
1637 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1638 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1638 adding changesets
1639 adding changesets
1639 bundling: 1/4 changesets (25.00%)
1640 bundling: 1/4 changesets (25.00%)
1640 bundling: 2/4 changesets (50.00%)
1641 bundling: 2/4 changesets (50.00%)
1641 bundling: 3/4 changesets (75.00%)
1642 bundling: 3/4 changesets (75.00%)
1642 bundling: 4/4 changesets (100.00%)
1643 bundling: 4/4 changesets (100.00%)
1643 bundling: 1/4 manifests (25.00%)
1644 bundling: 1/4 manifests (25.00%)
1644 bundling: 2/4 manifests (50.00%)
1645 bundling: 2/4 manifests (50.00%)
1645 bundling: 3/4 manifests (75.00%)
1646 bundling: 3/4 manifests (75.00%)
1646 bundling: 4/4 manifests (100.00%)
1647 bundling: 4/4 manifests (100.00%)
1647 bundling: abc.txt 1/4 files (25.00%)
1648 bundling: abc.txt 1/4 files (25.00%)
1648 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1649 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1649 bundling: foo/file.txt 3/4 files (75.00%)
1650 bundling: foo/file.txt 3/4 files (75.00%)
1650 bundling: quux/file.py 4/4 files (100.00%)
1651 bundling: quux/file.py 4/4 files (100.00%)
1651 changesets: 1 chunks
1652 changesets: 1 chunks
1652 add changeset ef1ea85a6374
1653 add changeset ef1ea85a6374
1653 changesets: 2 chunks
1654 changesets: 2 chunks
1654 add changeset f9cafe1212c8
1655 add changeset f9cafe1212c8
1655 changesets: 3 chunks
1656 changesets: 3 chunks
1656 add changeset 911600dab2ae
1657 add changeset 911600dab2ae
1657 changesets: 4 chunks
1658 changesets: 4 chunks
1658 add changeset e8fc755d4d82
1659 add changeset e8fc755d4d82
1659 adding manifests
1660 adding manifests
1660 manifests: 1/4 chunks (25.00%)
1661 manifests: 1/4 chunks (25.00%)
1661 manifests: 2/4 chunks (50.00%)
1662 manifests: 2/4 chunks (50.00%)
1662 manifests: 3/4 chunks (75.00%)
1663 manifests: 3/4 chunks (75.00%)
1663 manifests: 4/4 chunks (100.00%)
1664 manifests: 4/4 chunks (100.00%)
1664 adding file changes
1665 adding file changes
1665 adding abc.txt revisions
1666 adding abc.txt revisions
1666 files: 1/4 chunks (25.00%)
1667 files: 1/4 chunks (25.00%)
1667 adding foo/Bar/file.txt revisions
1668 adding foo/Bar/file.txt revisions
1668 files: 2/4 chunks (50.00%)
1669 files: 2/4 chunks (50.00%)
1669 adding foo/file.txt revisions
1670 adding foo/file.txt revisions
1670 files: 3/4 chunks (75.00%)
1671 files: 3/4 chunks (75.00%)
1671 adding quux/file.py revisions
1672 adding quux/file.py revisions
1672 files: 4/4 chunks (100.00%)
1673 files: 4/4 chunks (100.00%)
1673 added 4 changesets with 4 changes to 4 files (+1 heads)
1674 added 4 changesets with 4 changes to 4 files (+1 heads)
1674 calling hook pretxnchangegroup.acl: hgext.acl.hook
1675 calling hook pretxnchangegroup.acl: hgext.acl.hook
1675 acl: checking access for user "astro"
1676 acl: checking access for user "astro"
1676 acl: acl.allow.branches enabled, 0 entries for user astro
1677 acl: acl.allow.branches enabled, 0 entries for user astro
1677 acl: acl.deny.branches not enabled
1678 acl: acl.deny.branches not enabled
1678 acl: acl.allow not enabled
1679 acl: acl.allow not enabled
1679 acl: acl.deny not enabled
1680 acl: acl.deny not enabled
1680 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1681 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1681 transaction abort!
1682 transaction abort!
1682 rollback completed
1683 rollback completed
1683 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1684 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1684 no rollback information available
1685 no rollback information available
1685 2:fb35475503ef
1686 2:fb35475503ef
1686
1687
1687 $ do_push george
1688 $ do_push george
1688 Pushing as user george
1689 Pushing as user george
1689 hgrc = """
1690 hgrc = """
1690 [acl]
1691 [acl]
1691 sources = push
1692 sources = push
1692 [extensions]
1693 [extensions]
1693 [acl.allow.branches]
1694 [acl.allow.branches]
1694 * = george
1695 * = george
1695 """
1696 """
1696 pushing to ../b
1697 pushing to ../b
1697 query 1; heads
1698 query 1; heads
1698 searching for changes
1699 searching for changes
1699 all remote heads known locally
1700 all remote heads known locally
1700 4 changesets found
1701 4 changesets found
1701 list of changesets:
1702 list of changesets:
1702 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1703 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1703 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1704 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1704 911600dab2ae7a9baff75958b84fe606851ce955
1705 911600dab2ae7a9baff75958b84fe606851ce955
1705 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1706 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1706 adding changesets
1707 adding changesets
1707 bundling: 1/4 changesets (25.00%)
1708 bundling: 1/4 changesets (25.00%)
1708 bundling: 2/4 changesets (50.00%)
1709 bundling: 2/4 changesets (50.00%)
1709 bundling: 3/4 changesets (75.00%)
1710 bundling: 3/4 changesets (75.00%)
1710 bundling: 4/4 changesets (100.00%)
1711 bundling: 4/4 changesets (100.00%)
1711 bundling: 1/4 manifests (25.00%)
1712 bundling: 1/4 manifests (25.00%)
1712 bundling: 2/4 manifests (50.00%)
1713 bundling: 2/4 manifests (50.00%)
1713 bundling: 3/4 manifests (75.00%)
1714 bundling: 3/4 manifests (75.00%)
1714 bundling: 4/4 manifests (100.00%)
1715 bundling: 4/4 manifests (100.00%)
1715 bundling: abc.txt 1/4 files (25.00%)
1716 bundling: abc.txt 1/4 files (25.00%)
1716 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1717 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1717 bundling: foo/file.txt 3/4 files (75.00%)
1718 bundling: foo/file.txt 3/4 files (75.00%)
1718 bundling: quux/file.py 4/4 files (100.00%)
1719 bundling: quux/file.py 4/4 files (100.00%)
1719 changesets: 1 chunks
1720 changesets: 1 chunks
1720 add changeset ef1ea85a6374
1721 add changeset ef1ea85a6374
1721 changesets: 2 chunks
1722 changesets: 2 chunks
1722 add changeset f9cafe1212c8
1723 add changeset f9cafe1212c8
1723 changesets: 3 chunks
1724 changesets: 3 chunks
1724 add changeset 911600dab2ae
1725 add changeset 911600dab2ae
1725 changesets: 4 chunks
1726 changesets: 4 chunks
1726 add changeset e8fc755d4d82
1727 add changeset e8fc755d4d82
1727 adding manifests
1728 adding manifests
1728 manifests: 1/4 chunks (25.00%)
1729 manifests: 1/4 chunks (25.00%)
1729 manifests: 2/4 chunks (50.00%)
1730 manifests: 2/4 chunks (50.00%)
1730 manifests: 3/4 chunks (75.00%)
1731 manifests: 3/4 chunks (75.00%)
1731 manifests: 4/4 chunks (100.00%)
1732 manifests: 4/4 chunks (100.00%)
1732 adding file changes
1733 adding file changes
1733 adding abc.txt revisions
1734 adding abc.txt revisions
1734 files: 1/4 chunks (25.00%)
1735 files: 1/4 chunks (25.00%)
1735 adding foo/Bar/file.txt revisions
1736 adding foo/Bar/file.txt revisions
1736 files: 2/4 chunks (50.00%)
1737 files: 2/4 chunks (50.00%)
1737 adding foo/file.txt revisions
1738 adding foo/file.txt revisions
1738 files: 3/4 chunks (75.00%)
1739 files: 3/4 chunks (75.00%)
1739 adding quux/file.py revisions
1740 adding quux/file.py revisions
1740 files: 4/4 chunks (100.00%)
1741 files: 4/4 chunks (100.00%)
1741 added 4 changesets with 4 changes to 4 files (+1 heads)
1742 added 4 changesets with 4 changes to 4 files (+1 heads)
1742 calling hook pretxnchangegroup.acl: hgext.acl.hook
1743 calling hook pretxnchangegroup.acl: hgext.acl.hook
1743 acl: checking access for user "george"
1744 acl: checking access for user "george"
1744 acl: acl.allow.branches enabled, 1 entries for user george
1745 acl: acl.allow.branches enabled, 1 entries for user george
1745 acl: acl.deny.branches not enabled
1746 acl: acl.deny.branches not enabled
1746 acl: acl.allow not enabled
1747 acl: acl.allow not enabled
1747 acl: acl.deny not enabled
1748 acl: acl.deny not enabled
1748 acl: branch access granted: "ef1ea85a6374" on branch "default"
1749 acl: branch access granted: "ef1ea85a6374" on branch "default"
1749 acl: path access granted: "ef1ea85a6374"
1750 acl: path access granted: "ef1ea85a6374"
1750 acl: branch access granted: "f9cafe1212c8" on branch "default"
1751 acl: branch access granted: "f9cafe1212c8" on branch "default"
1751 acl: path access granted: "f9cafe1212c8"
1752 acl: path access granted: "f9cafe1212c8"
1752 acl: branch access granted: "911600dab2ae" on branch "default"
1753 acl: branch access granted: "911600dab2ae" on branch "default"
1753 acl: path access granted: "911600dab2ae"
1754 acl: path access granted: "911600dab2ae"
1754 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1755 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1755 acl: path access granted: "e8fc755d4d82"
1756 acl: path access granted: "e8fc755d4d82"
1756 updating the branch cache
1757 updating the branch cache
1757 checking for updated bookmarks
1758 checking for updated bookmarks
1758 repository tip rolled back to revision 2 (undo push)
1759 repository tip rolled back to revision 2 (undo push)
1759 2:fb35475503ef
1760 2:fb35475503ef
1760
1761
1761
1762
1762 Branch acl conflicting allow
1763 Branch acl conflicting allow
1763 asterisk ends up applying to all branches and allowing george to
1764 asterisk ends up applying to all branches and allowing george to
1764 push foobar into the remote
1765 push foobar into the remote
1765
1766
1766 $ init_config
1767 $ init_config
1767 $ echo "[acl.allow.branches]" >> $config
1768 $ echo "[acl.allow.branches]" >> $config
1768 $ echo "foobar = astro" >> $config
1769 $ echo "foobar = astro" >> $config
1769 $ echo "* = george" >> $config
1770 $ echo "* = george" >> $config
1770 $ do_push george
1771 $ do_push george
1771 Pushing as user george
1772 Pushing as user george
1772 hgrc = """
1773 hgrc = """
1773 [acl]
1774 [acl]
1774 sources = push
1775 sources = push
1775 [extensions]
1776 [extensions]
1776 [acl.allow.branches]
1777 [acl.allow.branches]
1777 foobar = astro
1778 foobar = astro
1778 * = george
1779 * = george
1779 """
1780 """
1780 pushing to ../b
1781 pushing to ../b
1781 query 1; heads
1782 query 1; heads
1782 searching for changes
1783 searching for changes
1783 all remote heads known locally
1784 all remote heads known locally
1784 invalidating branch cache (tip differs)
1785 invalidating branch cache (tip differs)
1785 4 changesets found
1786 4 changesets found
1786 list of changesets:
1787 list of changesets:
1787 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1788 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1788 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1789 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1789 911600dab2ae7a9baff75958b84fe606851ce955
1790 911600dab2ae7a9baff75958b84fe606851ce955
1790 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1791 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1791 adding changesets
1792 adding changesets
1792 bundling: 1/4 changesets (25.00%)
1793 bundling: 1/4 changesets (25.00%)
1793 bundling: 2/4 changesets (50.00%)
1794 bundling: 2/4 changesets (50.00%)
1794 bundling: 3/4 changesets (75.00%)
1795 bundling: 3/4 changesets (75.00%)
1795 bundling: 4/4 changesets (100.00%)
1796 bundling: 4/4 changesets (100.00%)
1796 bundling: 1/4 manifests (25.00%)
1797 bundling: 1/4 manifests (25.00%)
1797 bundling: 2/4 manifests (50.00%)
1798 bundling: 2/4 manifests (50.00%)
1798 bundling: 3/4 manifests (75.00%)
1799 bundling: 3/4 manifests (75.00%)
1799 bundling: 4/4 manifests (100.00%)
1800 bundling: 4/4 manifests (100.00%)
1800 bundling: abc.txt 1/4 files (25.00%)
1801 bundling: abc.txt 1/4 files (25.00%)
1801 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1802 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1802 bundling: foo/file.txt 3/4 files (75.00%)
1803 bundling: foo/file.txt 3/4 files (75.00%)
1803 bundling: quux/file.py 4/4 files (100.00%)
1804 bundling: quux/file.py 4/4 files (100.00%)
1804 changesets: 1 chunks
1805 changesets: 1 chunks
1805 add changeset ef1ea85a6374
1806 add changeset ef1ea85a6374
1806 changesets: 2 chunks
1807 changesets: 2 chunks
1807 add changeset f9cafe1212c8
1808 add changeset f9cafe1212c8
1808 changesets: 3 chunks
1809 changesets: 3 chunks
1809 add changeset 911600dab2ae
1810 add changeset 911600dab2ae
1810 changesets: 4 chunks
1811 changesets: 4 chunks
1811 add changeset e8fc755d4d82
1812 add changeset e8fc755d4d82
1812 adding manifests
1813 adding manifests
1813 manifests: 1/4 chunks (25.00%)
1814 manifests: 1/4 chunks (25.00%)
1814 manifests: 2/4 chunks (50.00%)
1815 manifests: 2/4 chunks (50.00%)
1815 manifests: 3/4 chunks (75.00%)
1816 manifests: 3/4 chunks (75.00%)
1816 manifests: 4/4 chunks (100.00%)
1817 manifests: 4/4 chunks (100.00%)
1817 adding file changes
1818 adding file changes
1818 adding abc.txt revisions
1819 adding abc.txt revisions
1819 files: 1/4 chunks (25.00%)
1820 files: 1/4 chunks (25.00%)
1820 adding foo/Bar/file.txt revisions
1821 adding foo/Bar/file.txt revisions
1821 files: 2/4 chunks (50.00%)
1822 files: 2/4 chunks (50.00%)
1822 adding foo/file.txt revisions
1823 adding foo/file.txt revisions
1823 files: 3/4 chunks (75.00%)
1824 files: 3/4 chunks (75.00%)
1824 adding quux/file.py revisions
1825 adding quux/file.py revisions
1825 files: 4/4 chunks (100.00%)
1826 files: 4/4 chunks (100.00%)
1826 added 4 changesets with 4 changes to 4 files (+1 heads)
1827 added 4 changesets with 4 changes to 4 files (+1 heads)
1827 calling hook pretxnchangegroup.acl: hgext.acl.hook
1828 calling hook pretxnchangegroup.acl: hgext.acl.hook
1828 acl: checking access for user "george"
1829 acl: checking access for user "george"
1829 acl: acl.allow.branches enabled, 1 entries for user george
1830 acl: acl.allow.branches enabled, 1 entries for user george
1830 acl: acl.deny.branches not enabled
1831 acl: acl.deny.branches not enabled
1831 acl: acl.allow not enabled
1832 acl: acl.allow not enabled
1832 acl: acl.deny not enabled
1833 acl: acl.deny not enabled
1833 acl: branch access granted: "ef1ea85a6374" on branch "default"
1834 acl: branch access granted: "ef1ea85a6374" on branch "default"
1834 acl: path access granted: "ef1ea85a6374"
1835 acl: path access granted: "ef1ea85a6374"
1835 acl: branch access granted: "f9cafe1212c8" on branch "default"
1836 acl: branch access granted: "f9cafe1212c8" on branch "default"
1836 acl: path access granted: "f9cafe1212c8"
1837 acl: path access granted: "f9cafe1212c8"
1837 acl: branch access granted: "911600dab2ae" on branch "default"
1838 acl: branch access granted: "911600dab2ae" on branch "default"
1838 acl: path access granted: "911600dab2ae"
1839 acl: path access granted: "911600dab2ae"
1839 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1840 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1840 acl: path access granted: "e8fc755d4d82"
1841 acl: path access granted: "e8fc755d4d82"
1841 updating the branch cache
1842 updating the branch cache
1842 checking for updated bookmarks
1843 checking for updated bookmarks
1843 repository tip rolled back to revision 2 (undo push)
1844 repository tip rolled back to revision 2 (undo push)
1844 2:fb35475503ef
1845 2:fb35475503ef
1845
1846
1846 Branch acl conflicting deny
1847 Branch acl conflicting deny
1847
1848
1848 $ init_config
1849 $ init_config
1849 $ echo "[acl.deny.branches]" >> $config
1850 $ echo "[acl.deny.branches]" >> $config
1850 $ echo "foobar = astro" >> $config
1851 $ echo "foobar = astro" >> $config
1851 $ echo "default = astro" >> $config
1852 $ echo "default = astro" >> $config
1852 $ echo "* = george" >> $config
1853 $ echo "* = george" >> $config
1853 $ do_push george
1854 $ do_push george
1854 Pushing as user george
1855 Pushing as user george
1855 hgrc = """
1856 hgrc = """
1856 [acl]
1857 [acl]
1857 sources = push
1858 sources = push
1858 [extensions]
1859 [extensions]
1859 [acl.deny.branches]
1860 [acl.deny.branches]
1860 foobar = astro
1861 foobar = astro
1861 default = astro
1862 default = astro
1862 * = george
1863 * = george
1863 """
1864 """
1864 pushing to ../b
1865 pushing to ../b
1865 query 1; heads
1866 query 1; heads
1866 searching for changes
1867 searching for changes
1867 all remote heads known locally
1868 all remote heads known locally
1868 invalidating branch cache (tip differs)
1869 invalidating branch cache (tip differs)
1869 4 changesets found
1870 4 changesets found
1870 list of changesets:
1871 list of changesets:
1871 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1872 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1872 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1873 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1873 911600dab2ae7a9baff75958b84fe606851ce955
1874 911600dab2ae7a9baff75958b84fe606851ce955
1874 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1875 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1875 adding changesets
1876 adding changesets
1876 bundling: 1/4 changesets (25.00%)
1877 bundling: 1/4 changesets (25.00%)
1877 bundling: 2/4 changesets (50.00%)
1878 bundling: 2/4 changesets (50.00%)
1878 bundling: 3/4 changesets (75.00%)
1879 bundling: 3/4 changesets (75.00%)
1879 bundling: 4/4 changesets (100.00%)
1880 bundling: 4/4 changesets (100.00%)
1880 bundling: 1/4 manifests (25.00%)
1881 bundling: 1/4 manifests (25.00%)
1881 bundling: 2/4 manifests (50.00%)
1882 bundling: 2/4 manifests (50.00%)
1882 bundling: 3/4 manifests (75.00%)
1883 bundling: 3/4 manifests (75.00%)
1883 bundling: 4/4 manifests (100.00%)
1884 bundling: 4/4 manifests (100.00%)
1884 bundling: abc.txt 1/4 files (25.00%)
1885 bundling: abc.txt 1/4 files (25.00%)
1885 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1886 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1886 bundling: foo/file.txt 3/4 files (75.00%)
1887 bundling: foo/file.txt 3/4 files (75.00%)
1887 bundling: quux/file.py 4/4 files (100.00%)
1888 bundling: quux/file.py 4/4 files (100.00%)
1888 changesets: 1 chunks
1889 changesets: 1 chunks
1889 add changeset ef1ea85a6374
1890 add changeset ef1ea85a6374
1890 changesets: 2 chunks
1891 changesets: 2 chunks
1891 add changeset f9cafe1212c8
1892 add changeset f9cafe1212c8
1892 changesets: 3 chunks
1893 changesets: 3 chunks
1893 add changeset 911600dab2ae
1894 add changeset 911600dab2ae
1894 changesets: 4 chunks
1895 changesets: 4 chunks
1895 add changeset e8fc755d4d82
1896 add changeset e8fc755d4d82
1896 adding manifests
1897 adding manifests
1897 manifests: 1/4 chunks (25.00%)
1898 manifests: 1/4 chunks (25.00%)
1898 manifests: 2/4 chunks (50.00%)
1899 manifests: 2/4 chunks (50.00%)
1899 manifests: 3/4 chunks (75.00%)
1900 manifests: 3/4 chunks (75.00%)
1900 manifests: 4/4 chunks (100.00%)
1901 manifests: 4/4 chunks (100.00%)
1901 adding file changes
1902 adding file changes
1902 adding abc.txt revisions
1903 adding abc.txt revisions
1903 files: 1/4 chunks (25.00%)
1904 files: 1/4 chunks (25.00%)
1904 adding foo/Bar/file.txt revisions
1905 adding foo/Bar/file.txt revisions
1905 files: 2/4 chunks (50.00%)
1906 files: 2/4 chunks (50.00%)
1906 adding foo/file.txt revisions
1907 adding foo/file.txt revisions
1907 files: 3/4 chunks (75.00%)
1908 files: 3/4 chunks (75.00%)
1908 adding quux/file.py revisions
1909 adding quux/file.py revisions
1909 files: 4/4 chunks (100.00%)
1910 files: 4/4 chunks (100.00%)
1910 added 4 changesets with 4 changes to 4 files (+1 heads)
1911 added 4 changesets with 4 changes to 4 files (+1 heads)
1911 calling hook pretxnchangegroup.acl: hgext.acl.hook
1912 calling hook pretxnchangegroup.acl: hgext.acl.hook
1912 acl: checking access for user "george"
1913 acl: checking access for user "george"
1913 acl: acl.allow.branches not enabled
1914 acl: acl.allow.branches not enabled
1914 acl: acl.deny.branches enabled, 1 entries for user george
1915 acl: acl.deny.branches enabled, 1 entries for user george
1915 acl: acl.allow not enabled
1916 acl: acl.allow not enabled
1916 acl: acl.deny not enabled
1917 acl: acl.deny not enabled
1917 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1918 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1918 transaction abort!
1919 transaction abort!
1919 rollback completed
1920 rollback completed
1920 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1921 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1921 no rollback information available
1922 no rollback information available
1922 2:fb35475503ef
1923 2:fb35475503ef
1923
1924
@@ -1,288 +1,290 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
14
15 $ echo a > a
15 $ echo a > a
16 $ hg commit -d '0 0' -A -m a
16 $ hg commit -d '0 0' -A -m a
17 adding a
17 adding a
18 $ echo b >> a
18 $ echo b >> a
19 $ hg commit -d '1 0' -m b
19 $ hg commit -d '1 0' -m b
20
20
21 $ hg backout -d '2 0' tip --tool=true
21 $ hg backout -d '2 0' tip --tool=true
22 reverting a
22 reverting a
23 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
23 changeset 2:2929462c3dff backs out changeset 1:a820f4f40a57
24 $ cat a
24 $ cat a
25 a
25 a
26
26
27 file that was removed is recreated
27 file that was removed is recreated
28
28
29 $ cd ..
29 $ cd ..
30 $ hg init remove
30 $ hg init remove
31 $ cd remove
31 $ cd remove
32
32
33 $ echo content > a
33 $ echo content > a
34 $ hg commit -d '0 0' -A -m a
34 $ hg commit -d '0 0' -A -m a
35 adding a
35 adding a
36
36
37 $ hg rm a
37 $ hg rm a
38 $ hg commit -d '1 0' -m b
38 $ hg commit -d '1 0' -m b
39
39
40 $ hg backout -d '2 0' tip --tool=true
40 $ hg backout -d '2 0' tip --tool=true
41 adding a
41 adding a
42 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
42 changeset 2:de31bdc76c0d backs out changeset 1:76862dcce372
43 $ cat a
43 $ cat a
44 content
44 content
45
45
46 backout of backout is as if nothing happened
46 backout of backout is as if nothing happened
47
47
48 $ hg backout -d '3 0' --merge tip --tool=true
48 $ hg backout -d '3 0' --merge tip --tool=true
49 removing a
49 removing a
50 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
50 changeset 3:7f6d0f120113 backs out changeset 2:de31bdc76c0d
51 $ cat a 2>/dev/null || echo cat: a: No such file or directory
51 $ cat a 2>/dev/null || echo cat: a: No such file or directory
52 cat: a: No such file or directory
52 cat: a: No such file or directory
53
53
54 across branch
54 across branch
55
55
56 $ cd ..
56 $ cd ..
57 $ hg init branch
57 $ hg init branch
58 $ cd branch
58 $ cd branch
59 $ echo a > a
59 $ echo a > a
60 $ hg ci -Am0
60 $ hg ci -Am0
61 adding a
61 adding a
62 $ echo b > b
62 $ echo b > b
63 $ hg ci -Am1
63 $ hg ci -Am1
64 adding b
64 adding b
65 $ hg co -C 0
65 $ hg co -C 0
66 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
67
67
68 should fail
68 should fail
69
69
70 $ hg backout 1
70 $ hg backout 1
71 abort: cannot backout change on a different branch
71 abort: cannot backout change on a different branch
72 [255]
72 [255]
73 $ echo c > c
73 $ echo c > c
74 $ hg ci -Am2
74 $ hg ci -Am2
75 adding c
75 adding c
76 created new head
76 created new head
77
77
78 should fail
78 should fail
79
79
80 $ hg backout 1
80 $ hg backout 1
81 abort: cannot backout change on a different branch
81 abort: cannot backout change on a different branch
82 [255]
82 [255]
83
83
84 backout with merge
84 backout with merge
85
85
86 $ cd ..
86 $ cd ..
87 $ hg init merge
87 $ hg init merge
88 $ cd merge
88 $ cd merge
89
89
90 $ echo line 1 > a
90 $ echo line 1 > a
91 $ echo line 2 >> a
91 $ echo line 2 >> a
92 $ hg commit -d '0 0' -A -m a
92 $ hg commit -d '0 0' -A -m a
93 adding a
93 adding a
94
94
95 remove line 1
95 remove line 1
96
96
97 $ echo line 2 > a
97 $ echo line 2 > a
98 $ hg commit -d '1 0' -m b
98 $ hg commit -d '1 0' -m b
99
99
100 $ echo line 3 >> a
100 $ echo line 3 >> a
101 $ hg commit -d '2 0' -m c
101 $ hg commit -d '2 0' -m c
102
102
103 $ hg backout --merge -d '3 0' 1 --tool=true
103 $ hg backout --merge -d '3 0' 1 --tool=true
104 reverting a
104 reverting a
105 created new head
105 created new head
106 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
106 changeset 3:26b8ccb9ad91 backs out changeset 1:5a50a024c182
107 merging with changeset 3:26b8ccb9ad91
107 merging with changeset 3:26b8ccb9ad91
108 merging a
108 merging a
109 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
109 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
110 (branch merge, don't forget to commit)
110 (branch merge, don't forget to commit)
111 $ hg commit -d '4 0' -m d
111 $ hg commit -d '4 0' -m d
112
112
113 check line 1 is back
113 check line 1 is back
114
114
115 $ cat a
115 $ cat a
116 line 1
116 line 1
117 line 2
117 line 2
118 line 3
118 line 3
119
119
120 backout should not back out subsequent changesets
120 backout should not back out subsequent changesets
121
121
122 $ hg init onecs
122 $ hg init onecs
123 $ cd onecs
123 $ cd onecs
124 $ echo 1 > a
124 $ echo 1 > a
125 $ hg commit -d '0 0' -A -m a
125 $ hg commit -d '0 0' -A -m a
126 adding a
126 adding a
127 $ echo 2 >> a
127 $ echo 2 >> a
128 $ hg commit -d '1 0' -m b
128 $ hg commit -d '1 0' -m b
129 $ echo 1 > b
129 $ echo 1 > b
130 $ hg commit -d '2 0' -A -m c
130 $ hg commit -d '2 0' -A -m c
131 adding b
131 adding b
132
132
133 without --merge
133 without --merge
134 $ hg backout -d '3 0' 1 --tool=true
134 $ hg backout -d '3 0' 1 --tool=true
135 reverting a
135 reverting a
136 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
136 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
137 $ hg locate b
137 $ hg locate b
138 b
138 b
139 $ hg update -C tip
139 $ hg update -C tip
140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 $ hg locate b
141 $ hg locate b
142 b
142 b
143
143
144 with --merge
144 with --merge
145 $ hg backout --merge -d '3 0' 1 --tool=true
145 $ hg backout --merge -d '3 0' 1 --tool=true
146 reverting a
146 reverting a
147 created new head
147 created new head
148 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
148 changeset 3:3202beb76721 backs out changeset 1:22bca4c721e5
149 merging with changeset 3:3202beb76721
149 merging with changeset 3:3202beb76721
150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 (branch merge, don't forget to commit)
151 (branch merge, don't forget to commit)
152 $ hg locate b
152 $ hg locate b
153 b
153 b
154 $ hg update -C tip
154 $ hg update -C tip
155 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
155 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
156 $ hg locate b
156 $ hg locate b
157 [1]
157 [1]
158
158
159 $ cd ..
159 $ cd ..
160 $ hg init m
160 $ hg init m
161 $ cd m
161 $ cd m
162 $ echo a > a
162 $ echo a > a
163 $ hg commit -d '0 0' -A -m a
163 $ hg commit -d '0 0' -A -m a
164 adding a
164 adding a
165 $ echo b > b
165 $ echo b > b
166 $ hg commit -d '1 0' -A -m b
166 $ hg commit -d '1 0' -A -m b
167 adding b
167 adding b
168 $ echo c > c
168 $ echo c > c
169 $ hg commit -d '2 0' -A -m b
169 $ hg commit -d '2 0' -A -m b
170 adding c
170 adding c
171 $ hg update 1
171 $ hg update 1
172 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
172 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
173 $ echo d > d
173 $ echo d > d
174 $ hg commit -d '3 0' -A -m c
174 $ hg commit -d '3 0' -A -m c
175 adding d
175 adding d
176 created new head
176 created new head
177 $ hg merge 2
177 $ hg merge 2
178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
178 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
179 (branch merge, don't forget to commit)
179 (branch merge, don't forget to commit)
180 $ hg commit -d '4 0' -A -m d
180 $ hg commit -d '4 0' -A -m d
181
181
182 backout of merge should fail
182 backout of merge should fail
183
183
184 $ hg backout 4
184 $ hg backout 4
185 abort: cannot backout a merge changeset
185 abort: cannot backout a merge changeset
186 [255]
186 [255]
187
187
188 backout of merge with bad parent should fail
188 backout of merge with bad parent should fail
189
189
190 $ hg backout --parent 0 4
190 $ hg backout --parent 0 4
191 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
191 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
192 [255]
192 [255]
193
193
194 backout of non-merge with parent should fail
194 backout of non-merge with parent should fail
195
195
196 $ hg backout --parent 0 3
196 $ hg backout --parent 0 3
197 abort: cannot use --parent on non-merge changeset
197 abort: cannot use --parent on non-merge changeset
198 [255]
198 [255]
199
199
200 backout with valid parent should be ok
200 backout with valid parent should be ok
201
201
202 $ hg backout -d '5 0' --parent 2 4 --tool=true
202 $ hg backout -d '5 0' --parent 2 4 --tool=true
203 removing d
203 removing d
204 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
204 changeset 5:10e5328c8435 backs out changeset 4:b2f3bb92043e
205
205
206 $ hg rollback
206 $ hg rollback
207 repository tip rolled back to revision 4 (undo commit)
207 repository tip rolled back to revision 4 (undo commit)
208 working directory now based on revision 4
208 working directory now based on revision 4
209 $ hg update -C
209 $ hg update -C
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
211
211
212 $ hg backout -d '6 0' --parent 3 4 --tool=true
212 $ hg backout -d '6 0' --parent 3 4 --tool=true
213 removing c
213 removing c
214 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
214 changeset 5:033590168430 backs out changeset 4:b2f3bb92043e
215
215
216 $ cd ..
216 $ cd ..
217
217
218 named branches
218 named branches
219
219
220 $ hg init named_branches
220 $ hg init named_branches
221 $ cd named_branches
221 $ cd named_branches
222
222
223 $ echo default > default
223 $ echo default > default
224 $ hg ci -d '0 0' -Am default
224 $ hg ci -d '0 0' -Am default
225 adding default
225 adding default
226 $ hg branch branch1
226 $ hg branch branch1
227 marked working directory as branch branch1
227 marked working directory as branch branch1
228 (branches are permanent and global, did you want a bookmark?)
228 $ echo branch1 > file1
229 $ echo branch1 > file1
229 $ hg ci -d '1 0' -Am file1
230 $ hg ci -d '1 0' -Am file1
230 adding file1
231 adding file1
231 $ hg branch branch2
232 $ hg branch branch2
232 marked working directory as branch branch2
233 marked working directory as branch branch2
234 (branches are permanent and global, did you want a bookmark?)
233 $ echo branch2 > file2
235 $ echo branch2 > file2
234 $ hg ci -d '2 0' -Am file2
236 $ hg ci -d '2 0' -Am file2
235 adding file2
237 adding file2
236
238
237 without --merge
239 without --merge
238 $ hg backout -r 1 --tool=true
240 $ hg backout -r 1 --tool=true
239 removing file1
241 removing file1
240 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
242 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
241 $ hg branch
243 $ hg branch
242 branch2
244 branch2
243 $ hg status -A
245 $ hg status -A
244 R file1
246 R file1
245 C default
247 C default
246 C file2
248 C file2
247
249
248 with --merge
250 with --merge
249 $ hg update -qC
251 $ hg update -qC
250 $ hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true
252 $ hg backout --merge -d '3 0' -r 1 -m 'backout on branch1' --tool=true
251 removing file1
253 removing file1
252 created new head
254 created new head
253 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
255 changeset 3:d4e8f6db59fb backs out changeset 1:bf1602f437f3
254 merging with changeset 3:d4e8f6db59fb
256 merging with changeset 3:d4e8f6db59fb
255 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
257 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
256 (branch merge, don't forget to commit)
258 (branch merge, don't forget to commit)
257 $ hg update -q -C 2
259 $ hg update -q -C 2
258
260
259 on branch2 with branch1 not merged, so file1 should still exist:
261 on branch2 with branch1 not merged, so file1 should still exist:
260
262
261 $ hg id
263 $ hg id
262 45bbcd363bf0 (branch2)
264 45bbcd363bf0 (branch2)
263 $ hg st -A
265 $ hg st -A
264 C default
266 C default
265 C file1
267 C file1
266 C file2
268 C file2
267
269
268 on branch2 with branch1 merged, so file1 should be gone:
270 on branch2 with branch1 merged, so file1 should be gone:
269
271
270 $ hg merge
272 $ hg merge
271 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
273 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
272 (branch merge, don't forget to commit)
274 (branch merge, don't forget to commit)
273 $ hg ci -d '4 0' -m 'merge backout of branch1'
275 $ hg ci -d '4 0' -m 'merge backout of branch1'
274 $ hg id
276 $ hg id
275 22149cdde76d (branch2) tip
277 22149cdde76d (branch2) tip
276 $ hg st -A
278 $ hg st -A
277 C default
279 C default
278 C file2
280 C file2
279
281
280 on branch1, so no file1 and file2:
282 on branch1, so no file1 and file2:
281
283
282 $ hg co -C branch1
284 $ hg co -C branch1
283 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
285 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
284 $ hg id
286 $ hg id
285 bf1602f437f3 (branch1)
287 bf1602f437f3 (branch1)
286 $ hg st -A
288 $ hg st -A
287 C default
289 C default
288 C file1
290 C file1
@@ -1,367 +1,374 b''
1 $ heads()
1 $ heads()
2 > {
2 > {
3 > hg heads --template '{rev}: {desc|firstline|strip} ({branches})\n' "$@"
3 > hg heads --template '{rev}: {desc|firstline|strip} ({branches})\n' "$@"
4 > }
4 > }
5
5
6 $ hg init a
6 $ hg init a
7 $ cd a
7 $ cd a
8 $ echo 'root' >root
8 $ echo 'root' >root
9 $ hg add root
9 $ hg add root
10 $ hg commit -m "Adding root node"
10 $ hg commit -m "Adding root node"
11 $ heads
11 $ heads
12 0: Adding root node ()
12 0: Adding root node ()
13 -------
13 -------
14 $ heads .
14 $ heads .
15 0: Adding root node ()
15 0: Adding root node ()
16
16
17 =======
17 =======
18
18
19 $ echo 'a' >a
19 $ echo 'a' >a
20 $ hg add a
20 $ hg add a
21 $ hg branch a
21 $ hg branch a
22 marked working directory as branch a
22 marked working directory as branch a
23 (branches are permanent and global, did you want a bookmark?)
23 $ hg commit -m "Adding a branch"
24 $ hg commit -m "Adding a branch"
24 $ heads
25 $ heads
25 1: Adding a branch (a)
26 1: Adding a branch (a)
26 0: Adding root node ()
27 0: Adding root node ()
27 -------
28 -------
28 $ heads .
29 $ heads .
29 1: Adding a branch (a)
30 1: Adding a branch (a)
30
31
31 =======
32 =======
32
33
33 $ hg update -C 0
34 $ hg update -C 0
34 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
35 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
35 $ echo 'b' >b
36 $ echo 'b' >b
36 $ hg add b
37 $ hg add b
37 $ hg branch b
38 $ hg branch b
38 marked working directory as branch b
39 marked working directory as branch b
40 (branches are permanent and global, did you want a bookmark?)
39 $ hg commit -m "Adding b branch"
41 $ hg commit -m "Adding b branch"
40 $ heads
42 $ heads
41 2: Adding b branch (b)
43 2: Adding b branch (b)
42 1: Adding a branch (a)
44 1: Adding a branch (a)
43 0: Adding root node ()
45 0: Adding root node ()
44 -------
46 -------
45 $ heads .
47 $ heads .
46 2: Adding b branch (b)
48 2: Adding b branch (b)
47
49
48 =======
50 =======
49
51
50 $ echo 'bh1' >bh1
52 $ echo 'bh1' >bh1
51 $ hg add bh1
53 $ hg add bh1
52 $ hg commit -m "Adding b branch head 1"
54 $ hg commit -m "Adding b branch head 1"
53 $ heads
55 $ heads
54 3: Adding b branch head 1 (b)
56 3: Adding b branch head 1 (b)
55 1: Adding a branch (a)
57 1: Adding a branch (a)
56 0: Adding root node ()
58 0: Adding root node ()
57 -------
59 -------
58 $ heads .
60 $ heads .
59 3: Adding b branch head 1 (b)
61 3: Adding b branch head 1 (b)
60
62
61 =======
63 =======
62
64
63 $ hg update -C 2
65 $ hg update -C 2
64 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
65 $ echo 'bh2' >bh2
67 $ echo 'bh2' >bh2
66 $ hg add bh2
68 $ hg add bh2
67 $ hg commit -m "Adding b branch head 2"
69 $ hg commit -m "Adding b branch head 2"
68 created new head
70 created new head
69 $ heads
71 $ heads
70 4: Adding b branch head 2 (b)
72 4: Adding b branch head 2 (b)
71 3: Adding b branch head 1 (b)
73 3: Adding b branch head 1 (b)
72 1: Adding a branch (a)
74 1: Adding a branch (a)
73 0: Adding root node ()
75 0: Adding root node ()
74 $ heads .
76 $ heads .
75 4: Adding b branch head 2 (b)
77 4: Adding b branch head 2 (b)
76 3: Adding b branch head 1 (b)
78 3: Adding b branch head 1 (b)
77
79
78 =======
80 =======
79
81
80 $ hg update -C 2
82 $ hg update -C 2
81 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
83 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
82 $ echo 'bh3' >bh3
84 $ echo 'bh3' >bh3
83 $ hg add bh3
85 $ hg add bh3
84 $ hg commit -m "Adding b branch head 3"
86 $ hg commit -m "Adding b branch head 3"
85 created new head
87 created new head
86 $ heads
88 $ heads
87 5: Adding b branch head 3 (b)
89 5: Adding b branch head 3 (b)
88 4: Adding b branch head 2 (b)
90 4: Adding b branch head 2 (b)
89 3: Adding b branch head 1 (b)
91 3: Adding b branch head 1 (b)
90 1: Adding a branch (a)
92 1: Adding a branch (a)
91 0: Adding root node ()
93 0: Adding root node ()
92 -------
94 -------
93 $ heads .
95 $ heads .
94 5: Adding b branch head 3 (b)
96 5: Adding b branch head 3 (b)
95 4: Adding b branch head 2 (b)
97 4: Adding b branch head 2 (b)
96 3: Adding b branch head 1 (b)
98 3: Adding b branch head 1 (b)
97
99
98 =======
100 =======
99
101
100 $ hg merge 4
102 $ hg merge 4
101 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
103 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 (branch merge, don't forget to commit)
104 (branch merge, don't forget to commit)
103 $ hg commit -m "Merging b branch head 2 and b branch head 3"
105 $ hg commit -m "Merging b branch head 2 and b branch head 3"
104 $ heads
106 $ heads
105 6: Merging b branch head 2 and b branch head 3 (b)
107 6: Merging b branch head 2 and b branch head 3 (b)
106 3: Adding b branch head 1 (b)
108 3: Adding b branch head 1 (b)
107 1: Adding a branch (a)
109 1: Adding a branch (a)
108 0: Adding root node ()
110 0: Adding root node ()
109 -------
111 -------
110 $ heads .
112 $ heads .
111 6: Merging b branch head 2 and b branch head 3 (b)
113 6: Merging b branch head 2 and b branch head 3 (b)
112 3: Adding b branch head 1 (b)
114 3: Adding b branch head 1 (b)
113
115
114 =======
116 =======
115
117
116 $ echo 'c' >c
118 $ echo 'c' >c
117 $ hg add c
119 $ hg add c
118 $ hg branch c
120 $ hg branch c
119 marked working directory as branch c
121 marked working directory as branch c
122 (branches are permanent and global, did you want a bookmark?)
120 $ hg commit -m "Adding c branch"
123 $ hg commit -m "Adding c branch"
121 $ heads
124 $ heads
122 7: Adding c branch (c)
125 7: Adding c branch (c)
123 6: Merging b branch head 2 and b branch head 3 (b)
126 6: Merging b branch head 2 and b branch head 3 (b)
124 3: Adding b branch head 1 (b)
127 3: Adding b branch head 1 (b)
125 1: Adding a branch (a)
128 1: Adding a branch (a)
126 0: Adding root node ()
129 0: Adding root node ()
127 -------
130 -------
128 $ heads .
131 $ heads .
129 7: Adding c branch (c)
132 7: Adding c branch (c)
130
133
131 =======
134 =======
132
135
133 $ heads -r 3 .
136 $ heads -r 3 .
134 no open branch heads found on branches c (started at 3)
137 no open branch heads found on branches c (started at 3)
135 [1]
138 [1]
136 $ heads -r 2 .
139 $ heads -r 2 .
137 7: Adding c branch (c)
140 7: Adding c branch (c)
138 -------
141 -------
139 $ hg update -C 4
142 $ hg update -C 4
140 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
143 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
141 -------
144 -------
142 $ heads -r 3 .
145 $ heads -r 3 .
143 3: Adding b branch head 1 (b)
146 3: Adding b branch head 1 (b)
144 -------
147 -------
145 $ heads -r 2 .
148 $ heads -r 2 .
146 6: Merging b branch head 2 and b branch head 3 (b)
149 6: Merging b branch head 2 and b branch head 3 (b)
147 3: Adding b branch head 1 (b)
150 3: Adding b branch head 1 (b)
148 -------
151 -------
149 $ heads -r 7 .
152 $ heads -r 7 .
150 no open branch heads found on branches b (started at 7)
153 no open branch heads found on branches b (started at 7)
151 [1]
154 [1]
152
155
153 =======
156 =======
154
157
155 $ for i in 0 1 2 3 4 5 6 7; do
158 $ for i in 0 1 2 3 4 5 6 7; do
156 > hg update -C "$i"
159 > hg update -C "$i"
157 > heads
160 > heads
158 > echo '-------'
161 > echo '-------'
159 > heads .
162 > heads .
160 > echo '-------'
163 > echo '-------'
161 > done
164 > done
162 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
165 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
163 7: Adding c branch (c)
166 7: Adding c branch (c)
164 6: Merging b branch head 2 and b branch head 3 (b)
167 6: Merging b branch head 2 and b branch head 3 (b)
165 3: Adding b branch head 1 (b)
168 3: Adding b branch head 1 (b)
166 1: Adding a branch (a)
169 1: Adding a branch (a)
167 0: Adding root node ()
170 0: Adding root node ()
168 -------
171 -------
169 0: Adding root node ()
172 0: Adding root node ()
170 -------
173 -------
171 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
172 7: Adding c branch (c)
175 7: Adding c branch (c)
173 6: Merging b branch head 2 and b branch head 3 (b)
176 6: Merging b branch head 2 and b branch head 3 (b)
174 3: Adding b branch head 1 (b)
177 3: Adding b branch head 1 (b)
175 1: Adding a branch (a)
178 1: Adding a branch (a)
176 0: Adding root node ()
179 0: Adding root node ()
177 -------
180 -------
178 1: Adding a branch (a)
181 1: Adding a branch (a)
179 -------
182 -------
180 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
183 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
181 7: Adding c branch (c)
184 7: Adding c branch (c)
182 6: Merging b branch head 2 and b branch head 3 (b)
185 6: Merging b branch head 2 and b branch head 3 (b)
183 3: Adding b branch head 1 (b)
186 3: Adding b branch head 1 (b)
184 1: Adding a branch (a)
187 1: Adding a branch (a)
185 0: Adding root node ()
188 0: Adding root node ()
186 -------
189 -------
187 6: Merging b branch head 2 and b branch head 3 (b)
190 6: Merging b branch head 2 and b branch head 3 (b)
188 3: Adding b branch head 1 (b)
191 3: Adding b branch head 1 (b)
189 -------
192 -------
190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 7: Adding c branch (c)
194 7: Adding c branch (c)
192 6: Merging b branch head 2 and b branch head 3 (b)
195 6: Merging b branch head 2 and b branch head 3 (b)
193 3: Adding b branch head 1 (b)
196 3: Adding b branch head 1 (b)
194 1: Adding a branch (a)
197 1: Adding a branch (a)
195 0: Adding root node ()
198 0: Adding root node ()
196 -------
199 -------
197 6: Merging b branch head 2 and b branch head 3 (b)
200 6: Merging b branch head 2 and b branch head 3 (b)
198 3: Adding b branch head 1 (b)
201 3: Adding b branch head 1 (b)
199 -------
202 -------
200 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
203 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
201 7: Adding c branch (c)
204 7: Adding c branch (c)
202 6: Merging b branch head 2 and b branch head 3 (b)
205 6: Merging b branch head 2 and b branch head 3 (b)
203 3: Adding b branch head 1 (b)
206 3: Adding b branch head 1 (b)
204 1: Adding a branch (a)
207 1: Adding a branch (a)
205 0: Adding root node ()
208 0: Adding root node ()
206 -------
209 -------
207 6: Merging b branch head 2 and b branch head 3 (b)
210 6: Merging b branch head 2 and b branch head 3 (b)
208 3: Adding b branch head 1 (b)
211 3: Adding b branch head 1 (b)
209 -------
212 -------
210 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
213 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
211 7: Adding c branch (c)
214 7: Adding c branch (c)
212 6: Merging b branch head 2 and b branch head 3 (b)
215 6: Merging b branch head 2 and b branch head 3 (b)
213 3: Adding b branch head 1 (b)
216 3: Adding b branch head 1 (b)
214 1: Adding a branch (a)
217 1: Adding a branch (a)
215 0: Adding root node ()
218 0: Adding root node ()
216 -------
219 -------
217 6: Merging b branch head 2 and b branch head 3 (b)
220 6: Merging b branch head 2 and b branch head 3 (b)
218 3: Adding b branch head 1 (b)
221 3: Adding b branch head 1 (b)
219 -------
222 -------
220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
221 7: Adding c branch (c)
224 7: Adding c branch (c)
222 6: Merging b branch head 2 and b branch head 3 (b)
225 6: Merging b branch head 2 and b branch head 3 (b)
223 3: Adding b branch head 1 (b)
226 3: Adding b branch head 1 (b)
224 1: Adding a branch (a)
227 1: Adding a branch (a)
225 0: Adding root node ()
228 0: Adding root node ()
226 -------
229 -------
227 6: Merging b branch head 2 and b branch head 3 (b)
230 6: Merging b branch head 2 and b branch head 3 (b)
228 3: Adding b branch head 1 (b)
231 3: Adding b branch head 1 (b)
229 -------
232 -------
230 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
233 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 7: Adding c branch (c)
234 7: Adding c branch (c)
232 6: Merging b branch head 2 and b branch head 3 (b)
235 6: Merging b branch head 2 and b branch head 3 (b)
233 3: Adding b branch head 1 (b)
236 3: Adding b branch head 1 (b)
234 1: Adding a branch (a)
237 1: Adding a branch (a)
235 0: Adding root node ()
238 0: Adding root node ()
236 -------
239 -------
237 7: Adding c branch (c)
240 7: Adding c branch (c)
238 -------
241 -------
239
242
240 =======
243 =======
241
244
242 $ for i in a b c z; do
245 $ for i in a b c z; do
243 > heads "$i"
246 > heads "$i"
244 > echo '-------'
247 > echo '-------'
245 > done
248 > done
246 1: Adding a branch (a)
249 1: Adding a branch (a)
247 -------
250 -------
248 6: Merging b branch head 2 and b branch head 3 (b)
251 6: Merging b branch head 2 and b branch head 3 (b)
249 3: Adding b branch head 1 (b)
252 3: Adding b branch head 1 (b)
250 -------
253 -------
251 7: Adding c branch (c)
254 7: Adding c branch (c)
252 -------
255 -------
253 abort: unknown revision 'z'!
256 abort: unknown revision 'z'!
254 -------
257 -------
255
258
256 =======
259 =======
257
260
258 $ heads 0 1 2 3 4 5 6 7
261 $ heads 0 1 2 3 4 5 6 7
259 7: Adding c branch (c)
262 7: Adding c branch (c)
260 6: Merging b branch head 2 and b branch head 3 (b)
263 6: Merging b branch head 2 and b branch head 3 (b)
261 3: Adding b branch head 1 (b)
264 3: Adding b branch head 1 (b)
262 1: Adding a branch (a)
265 1: Adding a branch (a)
263 0: Adding root node ()
266 0: Adding root node ()
264
267
265 Topological heads:
268 Topological heads:
266
269
267 $ heads -t
270 $ heads -t
268 7: Adding c branch (c)
271 7: Adding c branch (c)
269 3: Adding b branch head 1 (b)
272 3: Adding b branch head 1 (b)
270 1: Adding a branch (a)
273 1: Adding a branch (a)
271
274
272 $ cd ..
275 $ cd ..
273 ______________
276 ______________
274
277
275 "created new head" message tests
278 "created new head" message tests
276
279
277 $ hg init newheadmsg
280 $ hg init newheadmsg
278 $ cd newheadmsg
281 $ cd newheadmsg
279
282
280 Init: no msg
283 Init: no msg
281
284
282 $ echo 1 > a
285 $ echo 1 > a
283 $ hg ci -Am "a0: Initial root"
286 $ hg ci -Am "a0: Initial root"
284 adding a
287 adding a
285 $ echo 2 >> a
288 $ echo 2 >> a
286 $ hg ci -m "a1 (HN)"
289 $ hg ci -m "a1 (HN)"
287
290
288 $ hg branch b
291 $ hg branch b
289 marked working directory as branch b
292 marked working directory as branch b
293 (branches are permanent and global, did you want a bookmark?)
290 $ echo 1 > b
294 $ echo 1 > b
291 $ hg ci -Am "b2: Initial root for branch b"
295 $ hg ci -Am "b2: Initial root for branch b"
292 adding b
296 adding b
293 $ echo 2 >> b
297 $ echo 2 >> b
294 $ hg ci -m "b3 (HN)"
298 $ hg ci -m "b3 (HN)"
295
299
296 Case NN: msg
300 Case NN: msg
297
301
298 $ hg up -q null
302 $ hg up -q null
299 $ hg branch -f b
303 $ hg branch -f b
300 marked working directory as branch b
304 marked working directory as branch b
305 (branches are permanent and global, did you want a bookmark?)
301 $ echo 1 > bb
306 $ echo 1 > bb
302 $ hg ci -Am "b4 (NN): new topo root for branch b"
307 $ hg ci -Am "b4 (NN): new topo root for branch b"
303 adding bb
308 adding bb
304 created new head
309 created new head
305
310
306 Case HN: no msg
311 Case HN: no msg
307
312
308 $ echo 2 >> bb
313 $ echo 2 >> bb
309 $ hg ci -m "b5 (HN)"
314 $ hg ci -m "b5 (HN)"
310
315
311 Case BN: msg
316 Case BN: msg
312
317
313 $ hg branch -f default
318 $ hg branch -f default
314 marked working directory as branch default
319 marked working directory as branch default
320 (branches are permanent and global, did you want a bookmark?)
315 $ echo 1 > aa
321 $ echo 1 > aa
316 $ hg ci -Am "a6 (BN): new branch root"
322 $ hg ci -Am "a6 (BN): new branch root"
317 adding aa
323 adding aa
318 created new head
324 created new head
319
325
320 Case CN: msg
326 Case CN: msg
321
327
322 $ hg up -q 4
328 $ hg up -q 4
323 $ echo 3 >> bbb
329 $ echo 3 >> bbb
324 $ hg ci -Am "b7 (CN): regular new head"
330 $ hg ci -Am "b7 (CN): regular new head"
325 adding bbb
331 adding bbb
326 created new head
332 created new head
327
333
328 Case BB: msg
334 Case BB: msg
329
335
330 $ hg up -q 4
336 $ hg up -q 4
331 $ hg merge -q 3
337 $ hg merge -q 3
332 $ hg branch -f default
338 $ hg branch -f default
333 marked working directory as branch default
339 marked working directory as branch default
340 (branches are permanent and global, did you want a bookmark?)
334 $ hg ci -m "a8 (BB): weird new branch root"
341 $ hg ci -m "a8 (BB): weird new branch root"
335 created new head
342 created new head
336
343
337 Case CB: msg
344 Case CB: msg
338
345
339 $ hg up -q 4
346 $ hg up -q 4
340 $ hg merge -q 1
347 $ hg merge -q 1
341 $ hg ci -m "b9 (CB): new head from branch merge"
348 $ hg ci -m "b9 (CB): new head from branch merge"
342 created new head
349 created new head
343
350
344 Case HB: no msg
351 Case HB: no msg
345
352
346 $ hg up -q 7
353 $ hg up -q 7
347 $ hg merge -q 6
354 $ hg merge -q 6
348 $ hg ci -m "b10 (HB): continuing head from branch merge"
355 $ hg ci -m "b10 (HB): continuing head from branch merge"
349
356
350 Case CC: msg
357 Case CC: msg
351
358
352 $ hg up -q 4
359 $ hg up -q 4
353 $ hg merge -q 2
360 $ hg merge -q 2
354 $ hg ci -m "b11 (CC): new head from merge"
361 $ hg ci -m "b11 (CC): new head from merge"
355 created new head
362 created new head
356
363
357 Case CH: no msg
364 Case CH: no msg
358
365
359 $ hg up -q 2
366 $ hg up -q 2
360 $ hg merge -q 10
367 $ hg merge -q 10
361 $ hg ci -m "b12 (CH): continuing head from merge"
368 $ hg ci -m "b12 (CH): continuing head from merge"
362
369
363 Case HH: no msg
370 Case HH: no msg
364
371
365 $ hg merge -q 3
372 $ hg merge -q 3
366 $ hg ci -m "b12 (HH): merging two heads"
373 $ hg ci -m "b12 (HH): merging two heads"
367
374
@@ -1,361 +1,362 b''
1 $ hg init
1 $ hg init
2
2
3 no bookmarks
3 no bookmarks
4
4
5 $ hg bookmarks
5 $ hg bookmarks
6 no bookmarks set
6 no bookmarks set
7
7
8 bookmark rev -1
8 bookmark rev -1
9
9
10 $ hg bookmark X
10 $ hg bookmark X
11
11
12 list bookmarks
12 list bookmarks
13
13
14 $ hg bookmarks
14 $ hg bookmarks
15 * X -1:000000000000
15 * X -1:000000000000
16
16
17 list bookmarks with color
17 list bookmarks with color
18
18
19 $ hg --config extensions.color= --config color.mode=ansi \
19 $ hg --config extensions.color= --config color.mode=ansi \
20 > bookmarks --color=always
20 > bookmarks --color=always
21 \x1b[0;32m * X -1:000000000000\x1b[0m (esc)
21 \x1b[0;32m * X -1:000000000000\x1b[0m (esc)
22
22
23 $ echo a > a
23 $ echo a > a
24 $ hg add a
24 $ hg add a
25 $ hg commit -m 0
25 $ hg commit -m 0
26
26
27 bookmark X moved to rev 0
27 bookmark X moved to rev 0
28
28
29 $ hg bookmarks
29 $ hg bookmarks
30 * X 0:f7b1eb17ad24
30 * X 0:f7b1eb17ad24
31
31
32 look up bookmark
32 look up bookmark
33
33
34 $ hg log -r X
34 $ hg log -r X
35 changeset: 0:f7b1eb17ad24
35 changeset: 0:f7b1eb17ad24
36 bookmark: X
36 bookmark: X
37 tag: tip
37 tag: tip
38 user: test
38 user: test
39 date: Thu Jan 01 00:00:00 1970 +0000
39 date: Thu Jan 01 00:00:00 1970 +0000
40 summary: 0
40 summary: 0
41
41
42
42
43 second bookmark for rev 0
43 second bookmark for rev 0
44
44
45 $ hg bookmark X2
45 $ hg bookmark X2
46
46
47 bookmark rev -1 again
47 bookmark rev -1 again
48
48
49 $ hg bookmark -r null Y
49 $ hg bookmark -r null Y
50
50
51 list bookmarks
51 list bookmarks
52
52
53 $ hg bookmarks
53 $ hg bookmarks
54 X 0:f7b1eb17ad24
54 X 0:f7b1eb17ad24
55 * X2 0:f7b1eb17ad24
55 * X2 0:f7b1eb17ad24
56 Y -1:000000000000
56 Y -1:000000000000
57
57
58 $ echo b > b
58 $ echo b > b
59 $ hg add b
59 $ hg add b
60 $ hg commit -m 1
60 $ hg commit -m 1
61
61
62 bookmarks revset
62 bookmarks revset
63
63
64 $ hg log -r 'bookmark()'
64 $ hg log -r 'bookmark()'
65 changeset: 0:f7b1eb17ad24
65 changeset: 0:f7b1eb17ad24
66 bookmark: X
66 bookmark: X
67 user: test
67 user: test
68 date: Thu Jan 01 00:00:00 1970 +0000
68 date: Thu Jan 01 00:00:00 1970 +0000
69 summary: 0
69 summary: 0
70
70
71 changeset: 1:925d80f479bb
71 changeset: 1:925d80f479bb
72 bookmark: X2
72 bookmark: X2
73 tag: tip
73 tag: tip
74 user: test
74 user: test
75 date: Thu Jan 01 00:00:00 1970 +0000
75 date: Thu Jan 01 00:00:00 1970 +0000
76 summary: 1
76 summary: 1
77
77
78 $ hg log -r 'bookmark(Y)'
78 $ hg log -r 'bookmark(Y)'
79 $ hg log -r 'bookmark(X2)'
79 $ hg log -r 'bookmark(X2)'
80 changeset: 1:925d80f479bb
80 changeset: 1:925d80f479bb
81 bookmark: X2
81 bookmark: X2
82 tag: tip
82 tag: tip
83 user: test
83 user: test
84 date: Thu Jan 01 00:00:00 1970 +0000
84 date: Thu Jan 01 00:00:00 1970 +0000
85 summary: 1
85 summary: 1
86
86
87 $ hg log -r 'bookmark(unknown)'
87 $ hg log -r 'bookmark(unknown)'
88 abort: bookmark 'unknown' does not exist
88 abort: bookmark 'unknown' does not exist
89 [255]
89 [255]
90
90
91 $ hg help revsets | grep 'bookmark('
91 $ hg help revsets | grep 'bookmark('
92 "bookmark([name])"
92 "bookmark([name])"
93
93
94 bookmarks X and X2 moved to rev 1, Y at rev -1
94 bookmarks X and X2 moved to rev 1, Y at rev -1
95
95
96 $ hg bookmarks
96 $ hg bookmarks
97 X 0:f7b1eb17ad24
97 X 0:f7b1eb17ad24
98 * X2 1:925d80f479bb
98 * X2 1:925d80f479bb
99 Y -1:000000000000
99 Y -1:000000000000
100
100
101 bookmark rev 0 again
101 bookmark rev 0 again
102
102
103 $ hg bookmark -r 0 Z
103 $ hg bookmark -r 0 Z
104
104
105 $ hg update X
105 $ hg update X
106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
106 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
107 $ echo c > c
107 $ echo c > c
108 $ hg add c
108 $ hg add c
109 $ hg commit -m 2
109 $ hg commit -m 2
110 created new head
110 created new head
111
111
112 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
112 bookmarks X moved to rev 2, Y at rev -1, Z at rev 0
113
113
114 $ hg bookmarks
114 $ hg bookmarks
115 * X 2:db815d6d32e6
115 * X 2:db815d6d32e6
116 X2 1:925d80f479bb
116 X2 1:925d80f479bb
117 Y -1:000000000000
117 Y -1:000000000000
118 Z 0:f7b1eb17ad24
118 Z 0:f7b1eb17ad24
119
119
120 rename nonexistent bookmark
120 rename nonexistent bookmark
121
121
122 $ hg bookmark -m A B
122 $ hg bookmark -m A B
123 abort: bookmark 'A' does not exist
123 abort: bookmark 'A' does not exist
124 [255]
124 [255]
125
125
126 rename to existent bookmark
126 rename to existent bookmark
127
127
128 $ hg bookmark -m X Y
128 $ hg bookmark -m X Y
129 abort: bookmark 'Y' already exists (use -f to force)
129 abort: bookmark 'Y' already exists (use -f to force)
130 [255]
130 [255]
131
131
132 force rename to existent bookmark
132 force rename to existent bookmark
133
133
134 $ hg bookmark -f -m X Y
134 $ hg bookmark -f -m X Y
135
135
136 list bookmarks
136 list bookmarks
137
137
138 $ hg bookmark
138 $ hg bookmark
139 X2 1:925d80f479bb
139 X2 1:925d80f479bb
140 * Y 2:db815d6d32e6
140 * Y 2:db815d6d32e6
141 Z 0:f7b1eb17ad24
141 Z 0:f7b1eb17ad24
142
142
143 rename without new name
143 rename without new name
144
144
145 $ hg bookmark -m Y
145 $ hg bookmark -m Y
146 abort: new bookmark name required
146 abort: new bookmark name required
147 [255]
147 [255]
148
148
149 delete without name
149 delete without name
150
150
151 $ hg bookmark -d
151 $ hg bookmark -d
152 abort: bookmark name required
152 abort: bookmark name required
153 [255]
153 [255]
154
154
155 delete nonexistent bookmark
155 delete nonexistent bookmark
156
156
157 $ hg bookmark -d A
157 $ hg bookmark -d A
158 abort: bookmark 'A' does not exist
158 abort: bookmark 'A' does not exist
159 [255]
159 [255]
160
160
161 bookmark name with spaces should be stripped
161 bookmark name with spaces should be stripped
162
162
163 $ hg bookmark ' x y '
163 $ hg bookmark ' x y '
164
164
165 list bookmarks
165 list bookmarks
166
166
167 $ hg bookmarks
167 $ hg bookmarks
168 X2 1:925d80f479bb
168 X2 1:925d80f479bb
169 Y 2:db815d6d32e6
169 Y 2:db815d6d32e6
170 Z 0:f7b1eb17ad24
170 Z 0:f7b1eb17ad24
171 * x y 2:db815d6d32e6
171 * x y 2:db815d6d32e6
172
172
173 look up stripped bookmark name
173 look up stripped bookmark name
174
174
175 $ hg log -r '"x y"'
175 $ hg log -r '"x y"'
176 changeset: 2:db815d6d32e6
176 changeset: 2:db815d6d32e6
177 bookmark: Y
177 bookmark: Y
178 bookmark: x y
178 bookmark: x y
179 tag: tip
179 tag: tip
180 parent: 0:f7b1eb17ad24
180 parent: 0:f7b1eb17ad24
181 user: test
181 user: test
182 date: Thu Jan 01 00:00:00 1970 +0000
182 date: Thu Jan 01 00:00:00 1970 +0000
183 summary: 2
183 summary: 2
184
184
185
185
186 reject bookmark name with newline
186 reject bookmark name with newline
187
187
188 $ hg bookmark '
188 $ hg bookmark '
189 > '
189 > '
190 abort: bookmark name cannot contain newlines
190 abort: bookmark name cannot contain newlines
191 [255]
191 [255]
192
192
193 bookmark with existing name
193 bookmark with existing name
194
194
195 $ hg bookmark Z
195 $ hg bookmark Z
196 abort: bookmark 'Z' already exists (use -f to force)
196 abort: bookmark 'Z' already exists (use -f to force)
197 [255]
197 [255]
198
198
199 force bookmark with existing name
199 force bookmark with existing name
200
200
201 $ hg bookmark -f Z
201 $ hg bookmark -f Z
202
202
203 list bookmarks
203 list bookmarks
204
204
205 $ hg bookmark
205 $ hg bookmark
206 X2 1:925d80f479bb
206 X2 1:925d80f479bb
207 Y 2:db815d6d32e6
207 Y 2:db815d6d32e6
208 * Z 2:db815d6d32e6
208 * Z 2:db815d6d32e6
209 x y 2:db815d6d32e6
209 x y 2:db815d6d32e6
210
210
211 revision but no bookmark name
211 revision but no bookmark name
212
212
213 $ hg bookmark -r .
213 $ hg bookmark -r .
214 abort: bookmark name required
214 abort: bookmark name required
215 [255]
215 [255]
216
216
217 bookmark name with whitespace only
217 bookmark name with whitespace only
218
218
219 $ hg bookmark ' '
219 $ hg bookmark ' '
220 abort: bookmark names cannot consist entirely of whitespace
220 abort: bookmark names cannot consist entirely of whitespace
221 [255]
221 [255]
222
222
223 invalid bookmark
223 invalid bookmark
224
224
225 $ hg bookmark 'foo:bar'
225 $ hg bookmark 'foo:bar'
226 abort: bookmark 'foo:bar' contains illegal character
226 abort: bookmark 'foo:bar' contains illegal character
227 [255]
227 [255]
228
228
229 the bookmark extension should be ignored now that it is part of core
229 the bookmark extension should be ignored now that it is part of core
230
230
231 $ echo "[extensions]" >> $HGRCPATH
231 $ echo "[extensions]" >> $HGRCPATH
232 $ echo "bookmarks=" >> $HGRCPATH
232 $ echo "bookmarks=" >> $HGRCPATH
233 $ hg bookmarks
233 $ hg bookmarks
234 X2 1:925d80f479bb
234 X2 1:925d80f479bb
235 Y 2:db815d6d32e6
235 Y 2:db815d6d32e6
236 * Z 2:db815d6d32e6
236 * Z 2:db815d6d32e6
237 x y 2:db815d6d32e6
237 x y 2:db815d6d32e6
238
238
239 test summary
239 test summary
240
240
241 $ hg summary
241 $ hg summary
242 parent: 2:db815d6d32e6 tip
242 parent: 2:db815d6d32e6 tip
243 2
243 2
244 branch: default
244 branch: default
245 bookmarks: *Z Y x y
245 bookmarks: *Z Y x y
246 commit: (clean)
246 commit: (clean)
247 update: 1 new changesets, 2 branch heads (merge)
247 update: 1 new changesets, 2 branch heads (merge)
248
248
249 test id
249 test id
250
250
251 $ hg id
251 $ hg id
252 db815d6d32e6 tip Y/Z/x y
252 db815d6d32e6 tip Y/Z/x y
253
253
254 test rollback
254 test rollback
255
255
256 $ echo foo > f1
256 $ echo foo > f1
257 $ hg ci -Amr
257 $ hg ci -Amr
258 adding f1
258 adding f1
259 $ hg bookmark -f Y -r 1
259 $ hg bookmark -f Y -r 1
260 $ hg bookmark -f Z -r 1
260 $ hg bookmark -f Z -r 1
261 $ hg rollback
261 $ hg rollback
262 repository tip rolled back to revision 2 (undo commit)
262 repository tip rolled back to revision 2 (undo commit)
263 working directory now based on revision 2
263 working directory now based on revision 2
264 $ hg bookmarks
264 $ hg bookmarks
265 X2 1:925d80f479bb
265 X2 1:925d80f479bb
266 Y 2:db815d6d32e6
266 Y 2:db815d6d32e6
267 * Z 2:db815d6d32e6
267 * Z 2:db815d6d32e6
268 x y 2:db815d6d32e6
268 x y 2:db815d6d32e6
269
269
270 test clone
270 test clone
271
271
272 $ hg bookmarks
272 $ hg bookmarks
273 X2 1:925d80f479bb
273 X2 1:925d80f479bb
274 Y 2:db815d6d32e6
274 Y 2:db815d6d32e6
275 * Z 2:db815d6d32e6
275 * Z 2:db815d6d32e6
276 x y 2:db815d6d32e6
276 x y 2:db815d6d32e6
277 $ hg clone . cloned-bookmarks
277 $ hg clone . cloned-bookmarks
278 updating to branch default
278 updating to branch default
279 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 $ hg -R cloned-bookmarks bookmarks
280 $ hg -R cloned-bookmarks bookmarks
281 X2 1:925d80f479bb
281 X2 1:925d80f479bb
282 Y 2:db815d6d32e6
282 Y 2:db815d6d32e6
283 Z 2:db815d6d32e6
283 Z 2:db815d6d32e6
284 x y 2:db815d6d32e6
284 x y 2:db815d6d32e6
285
285
286 test clone with pull protocol
286 test clone with pull protocol
287
287
288 $ hg clone --pull . cloned-bookmarks-pull
288 $ hg clone --pull . cloned-bookmarks-pull
289 requesting all changes
289 requesting all changes
290 adding changesets
290 adding changesets
291 adding manifests
291 adding manifests
292 adding file changes
292 adding file changes
293 added 3 changesets with 3 changes to 3 files (+1 heads)
293 added 3 changesets with 3 changes to 3 files (+1 heads)
294 updating to branch default
294 updating to branch default
295 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
295 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 $ hg -R cloned-bookmarks-pull bookmarks
296 $ hg -R cloned-bookmarks-pull bookmarks
297 X2 1:925d80f479bb
297 X2 1:925d80f479bb
298 Y 2:db815d6d32e6
298 Y 2:db815d6d32e6
299 Z 2:db815d6d32e6
299 Z 2:db815d6d32e6
300 x y 2:db815d6d32e6
300 x y 2:db815d6d32e6
301
301
302 test clone with a specific revision
302 test clone with a specific revision
303
303
304 $ hg clone -r 925d80 . cloned-bookmarks-rev
304 $ hg clone -r 925d80 . cloned-bookmarks-rev
305 adding changesets
305 adding changesets
306 adding manifests
306 adding manifests
307 adding file changes
307 adding file changes
308 added 2 changesets with 2 changes to 2 files
308 added 2 changesets with 2 changes to 2 files
309 updating to branch default
309 updating to branch default
310 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
311 $ hg -R cloned-bookmarks-rev bookmarks
311 $ hg -R cloned-bookmarks-rev bookmarks
312 X2 1:925d80f479bb
312 X2 1:925d80f479bb
313
313
314 create bundle with two heads
314 create bundle with two heads
315
315
316 $ hg clone . tobundle
316 $ hg clone . tobundle
317 updating to branch default
317 updating to branch default
318 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
318 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
319 $ echo x > tobundle/x
319 $ echo x > tobundle/x
320 $ hg -R tobundle add tobundle/x
320 $ hg -R tobundle add tobundle/x
321 $ hg -R tobundle commit -m'x'
321 $ hg -R tobundle commit -m'x'
322 $ hg -R tobundle update -r -2
322 $ hg -R tobundle update -r -2
323 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
323 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
324 $ echo y > tobundle/y
324 $ echo y > tobundle/y
325 $ hg -R tobundle branch test
325 $ hg -R tobundle branch test
326 marked working directory as branch test
326 marked working directory as branch test
327 (branches are permanent and global, did you want a bookmark?)
327 $ hg -R tobundle add tobundle/y
328 $ hg -R tobundle add tobundle/y
328 $ hg -R tobundle commit -m'y'
329 $ hg -R tobundle commit -m'y'
329 $ hg -R tobundle bundle tobundle.hg
330 $ hg -R tobundle bundle tobundle.hg
330 searching for changes
331 searching for changes
331 2 changesets found
332 2 changesets found
332 $ hg unbundle tobundle.hg
333 $ hg unbundle tobundle.hg
333 adding changesets
334 adding changesets
334 adding manifests
335 adding manifests
335 adding file changes
336 adding file changes
336 added 2 changesets with 2 changes to 2 files (+1 heads)
337 added 2 changesets with 2 changes to 2 files (+1 heads)
337 (run 'hg heads' to see heads, 'hg merge' to merge)
338 (run 'hg heads' to see heads, 'hg merge' to merge)
338 $ hg update
339 $ hg update
339 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 $ hg bookmarks
341 $ hg bookmarks
341 X2 1:925d80f479bb
342 X2 1:925d80f479bb
342 Y 2:db815d6d32e6
343 Y 2:db815d6d32e6
343 * Z 3:125c9a1d6df6
344 * Z 3:125c9a1d6df6
344 x y 2:db815d6d32e6
345 x y 2:db815d6d32e6
345
346
346 test wrongly formated bookmark
347 test wrongly formated bookmark
347
348
348 $ echo '' >> .hg/bookmarks
349 $ echo '' >> .hg/bookmarks
349 $ hg bookmarks
350 $ hg bookmarks
350 X2 1:925d80f479bb
351 X2 1:925d80f479bb
351 Y 2:db815d6d32e6
352 Y 2:db815d6d32e6
352 * Z 3:125c9a1d6df6
353 * Z 3:125c9a1d6df6
353 x y 2:db815d6d32e6
354 x y 2:db815d6d32e6
354 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
355 $ echo "Ican'thasformatedlines" >> .hg/bookmarks
355 $ hg bookmarks
356 $ hg bookmarks
356 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
357 malformed line in .hg/bookmarks: "Ican'thasformatedlines"
357 X2 1:925d80f479bb
358 X2 1:925d80f479bb
358 Y 2:db815d6d32e6
359 Y 2:db815d6d32e6
359 * Z 3:125c9a1d6df6
360 * Z 3:125c9a1d6df6
360 x y 2:db815d6d32e6
361 x y 2:db815d6d32e6
361
362
@@ -1,126 +1,132 b''
1 test branch selection options
1 test branch selection options
2
2
3 $ hg init branch
3 $ hg init branch
4 $ cd branch
4 $ cd branch
5 $ hg branch a
5 $ hg branch a
6 marked working directory as branch a
6 marked working directory as branch a
7 (branches are permanent and global, did you want a bookmark?)
7 $ echo a > foo
8 $ echo a > foo
8 $ hg ci -d '0 0' -Ama
9 $ hg ci -d '0 0' -Ama
9 adding foo
10 adding foo
10 $ echo a2 > foo
11 $ echo a2 > foo
11 $ hg ci -d '0 0' -ma2
12 $ hg ci -d '0 0' -ma2
12 $ hg up 0
13 $ hg up 0
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 $ hg branch c
15 $ hg branch c
15 marked working directory as branch c
16 marked working directory as branch c
17 (branches are permanent and global, did you want a bookmark?)
16 $ echo c > foo
18 $ echo c > foo
17 $ hg ci -d '0 0' -mc
19 $ hg ci -d '0 0' -mc
18 $ hg tag -l z
20 $ hg tag -l z
19 $ cd ..
21 $ cd ..
20 $ hg clone -r 0 branch branch2
22 $ hg clone -r 0 branch branch2
21 adding changesets
23 adding changesets
22 adding manifests
24 adding manifests
23 adding file changes
25 adding file changes
24 added 1 changesets with 1 changes to 1 files
26 added 1 changesets with 1 changes to 1 files
25 updating to branch a
27 updating to branch a
26 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
27 $ cd branch2
29 $ cd branch2
28 $ hg up 0
30 $ hg up 0
29 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
31 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
30 $ hg branch b
32 $ hg branch b
31 marked working directory as branch b
33 marked working directory as branch b
34 (branches are permanent and global, did you want a bookmark?)
32 $ echo b > foo
35 $ echo b > foo
33 $ hg ci -d '0 0' -mb
36 $ hg ci -d '0 0' -mb
34 $ hg up 0
37 $ hg up 0
35 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 $ hg --encoding utf-8 branch æ
39 $ hg --encoding utf-8 branch æ
37 marked working directory as branch \xc3\xa6 (esc)
40 marked working directory as branch \xc3\xa6 (esc)
41 (branches are permanent and global, did you want a bookmark?)
38 $ echo ae1 > foo
42 $ echo ae1 > foo
39 $ hg ci -d '0 0' -mae1
43 $ hg ci -d '0 0' -mae1
40 $ hg up 0
44 $ hg up 0
41 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 $ hg --encoding utf-8 branch -f æ
46 $ hg --encoding utf-8 branch -f æ
43 marked working directory as branch \xc3\xa6 (esc)
47 marked working directory as branch \xc3\xa6 (esc)
48 (branches are permanent and global, did you want a bookmark?)
44 $ echo ae2 > foo
49 $ echo ae2 > foo
45 $ hg ci -d '0 0' -mae2
50 $ hg ci -d '0 0' -mae2
46 created new head
51 created new head
47 $ hg up 0
52 $ hg up 0
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
53 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 $ hg branch -f b
54 $ hg branch -f b
50 marked working directory as branch b
55 marked working directory as branch b
56 (branches are permanent and global, did you want a bookmark?)
51 $ echo b2 > foo
57 $ echo b2 > foo
52 $ hg ci -d '0 0' -mb2
58 $ hg ci -d '0 0' -mb2
53 created new head
59 created new head
54
60
55 unknown branch and fallback
61 unknown branch and fallback
56
62
57 $ hg in -qbz
63 $ hg in -qbz
58 abort: unknown branch 'z'!
64 abort: unknown branch 'z'!
59 [255]
65 [255]
60 $ hg in -q ../branch#z
66 $ hg in -q ../branch#z
61 2:f25d57ab0566
67 2:f25d57ab0566
62 $ hg out -qbz
68 $ hg out -qbz
63 abort: unknown branch 'z'!
69 abort: unknown branch 'z'!
64 [255]
70 [255]
65
71
66 in rev c branch a
72 in rev c branch a
67
73
68 $ hg in -qr c ../branch#a
74 $ hg in -qr c ../branch#a
69 1:dd6e60a716c6
75 1:dd6e60a716c6
70 2:f25d57ab0566
76 2:f25d57ab0566
71 $ hg in -qr c -b a
77 $ hg in -qr c -b a
72 1:dd6e60a716c6
78 1:dd6e60a716c6
73 2:f25d57ab0566
79 2:f25d57ab0566
74
80
75 out branch .
81 out branch .
76
82
77 $ hg out -q ../branch#.
83 $ hg out -q ../branch#.
78 1:b84708d77ab7
84 1:b84708d77ab7
79 4:65511d0e2b55
85 4:65511d0e2b55
80 $ hg out -q -b .
86 $ hg out -q -b .
81 1:b84708d77ab7
87 1:b84708d77ab7
82 4:65511d0e2b55
88 4:65511d0e2b55
83
89
84 out branch . non-ascii
90 out branch . non-ascii
85
91
86 $ hg --encoding utf-8 up æ
92 $ hg --encoding utf-8 up æ
87 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 $ hg --encoding latin1 out -q ../branch#.
94 $ hg --encoding latin1 out -q ../branch#.
89 2:df5a44224d4e
95 2:df5a44224d4e
90 3:4f4a5125ca10
96 3:4f4a5125ca10
91 $ hg --encoding latin1 out -q -b .
97 $ hg --encoding latin1 out -q -b .
92 2:df5a44224d4e
98 2:df5a44224d4e
93 3:4f4a5125ca10
99 3:4f4a5125ca10
94
100
95 clone branch b
101 clone branch b
96
102
97 $ cd ..
103 $ cd ..
98 $ hg clone branch2#b branch3
104 $ hg clone branch2#b branch3
99 adding changesets
105 adding changesets
100 adding manifests
106 adding manifests
101 adding file changes
107 adding file changes
102 added 3 changesets with 3 changes to 1 files (+1 heads)
108 added 3 changesets with 3 changes to 1 files (+1 heads)
103 updating to branch b
109 updating to branch b
104 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
110 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
105 $ hg -q -R branch3 heads b
111 $ hg -q -R branch3 heads b
106 2:65511d0e2b55
112 2:65511d0e2b55
107 1:b84708d77ab7
113 1:b84708d77ab7
108 $ hg -q -R branch3 parents
114 $ hg -q -R branch3 parents
109 2:65511d0e2b55
115 2:65511d0e2b55
110 $ rm -rf branch3
116 $ rm -rf branch3
111
117
112 clone rev a branch b
118 clone rev a branch b
113
119
114 $ hg clone -r a branch2#b branch3
120 $ hg clone -r a branch2#b branch3
115 adding changesets
121 adding changesets
116 adding manifests
122 adding manifests
117 adding file changes
123 adding file changes
118 added 3 changesets with 3 changes to 1 files (+1 heads)
124 added 3 changesets with 3 changes to 1 files (+1 heads)
119 updating to branch a
125 updating to branch a
120 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 $ hg -q -R branch3 heads b
127 $ hg -q -R branch3 heads b
122 2:65511d0e2b55
128 2:65511d0e2b55
123 1:b84708d77ab7
129 1:b84708d77ab7
124 $ hg -q -R branch3 parents
130 $ hg -q -R branch3 parents
125 0:5b65ba7c951d
131 0:5b65ba7c951d
126 $ rm -rf branch3
132 $ rm -rf branch3
@@ -1,62 +1,63 b''
1 Initial setup.
1 Initial setup.
2
2
3 $ hg init repo
3 $ hg init repo
4 $ cd repo
4 $ cd repo
5 $ touch thefile
5 $ touch thefile
6 $ hg ci -A -m 'Initial commit.'
6 $ hg ci -A -m 'Initial commit.'
7 adding thefile
7 adding thefile
8
8
9 Create a tag.
9 Create a tag.
10
10
11 $ hg tag branchortag
11 $ hg tag branchortag
12
12
13 Create a branch with the same name as the tag.
13 Create a branch with the same name as the tag.
14
14
15 $ hg branch branchortag
15 $ hg branch branchortag
16 marked working directory as branch branchortag
16 marked working directory as branch branchortag
17 (branches are permanent and global, did you want a bookmark?)
17 $ hg ci -m 'Create a branch with the same name as a tag.'
18 $ hg ci -m 'Create a branch with the same name as a tag.'
18
19
19 This is what we have:
20 This is what we have:
20
21
21 $ hg log
22 $ hg log
22 changeset: 2:10519b3f489a
23 changeset: 2:10519b3f489a
23 branch: branchortag
24 branch: branchortag
24 tag: tip
25 tag: tip
25 user: test
26 user: test
26 date: Thu Jan 01 00:00:00 1970 +0000
27 date: Thu Jan 01 00:00:00 1970 +0000
27 summary: Create a branch with the same name as a tag.
28 summary: Create a branch with the same name as a tag.
28
29
29 changeset: 1:2635c45ca99b
30 changeset: 1:2635c45ca99b
30 user: test
31 user: test
31 date: Thu Jan 01 00:00:00 1970 +0000
32 date: Thu Jan 01 00:00:00 1970 +0000
32 summary: Added tag branchortag for changeset f57387372b5d
33 summary: Added tag branchortag for changeset f57387372b5d
33
34
34 changeset: 0:f57387372b5d
35 changeset: 0:f57387372b5d
35 tag: branchortag
36 tag: branchortag
36 user: test
37 user: test
37 date: Thu Jan 01 00:00:00 1970 +0000
38 date: Thu Jan 01 00:00:00 1970 +0000
38 summary: Initial commit.
39 summary: Initial commit.
39
40
40 Update to the tag:
41 Update to the tag:
41
42
42 $ hg up 'tag(branchortag)'
43 $ hg up 'tag(branchortag)'
43 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
44 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
44 $ hg parents
45 $ hg parents
45 changeset: 0:f57387372b5d
46 changeset: 0:f57387372b5d
46 tag: branchortag
47 tag: branchortag
47 user: test
48 user: test
48 date: Thu Jan 01 00:00:00 1970 +0000
49 date: Thu Jan 01 00:00:00 1970 +0000
49 summary: Initial commit.
50 summary: Initial commit.
50
51
51 Updating to the branch:
52 Updating to the branch:
52
53
53 $ hg up 'branch(branchortag)'
54 $ hg up 'branch(branchortag)'
54 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 $ hg parents
56 $ hg parents
56 changeset: 2:10519b3f489a
57 changeset: 2:10519b3f489a
57 branch: branchortag
58 branch: branchortag
58 tag: tip
59 tag: tip
59 user: test
60 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
61 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: Create a branch with the same name as a tag.
62 summary: Create a branch with the same name as a tag.
62
63
@@ -1,400 +1,405 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo 'root' >root
3 $ echo 'root' >root
4 $ hg add root
4 $ hg add root
5 $ hg commit -d '0 0' -m "Adding root node"
5 $ hg commit -d '0 0' -m "Adding root node"
6
6
7 $ echo 'a' >a
7 $ echo 'a' >a
8 $ hg add a
8 $ hg add a
9 $ hg branch a
9 $ hg branch a
10 marked working directory as branch a
10 marked working directory as branch a
11 (branches are permanent and global, did you want a bookmark?)
11 $ hg commit -d '1 0' -m "Adding a branch"
12 $ hg commit -d '1 0' -m "Adding a branch"
12
13
13 $ hg branch q
14 $ hg branch q
14 marked working directory as branch q
15 marked working directory as branch q
16 (branches are permanent and global, did you want a bookmark?)
15 $ echo 'aa' >a
17 $ echo 'aa' >a
16 $ hg branch -C
18 $ hg branch -C
17 reset working directory to branch a
19 reset working directory to branch a
18 $ hg commit -d '2 0' -m "Adding to a branch"
20 $ hg commit -d '2 0' -m "Adding to a branch"
19
21
20 $ hg update -C 0
22 $ hg update -C 0
21 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
23 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
22 $ echo 'b' >b
24 $ echo 'b' >b
23 $ hg add b
25 $ hg add b
24 $ hg branch b
26 $ hg branch b
25 marked working directory as branch b
27 marked working directory as branch b
28 (branches are permanent and global, did you want a bookmark?)
26 $ hg commit -d '2 0' -m "Adding b branch"
29 $ hg commit -d '2 0' -m "Adding b branch"
27
30
28 $ echo 'bh1' >bh1
31 $ echo 'bh1' >bh1
29 $ hg add bh1
32 $ hg add bh1
30 $ hg commit -d '3 0' -m "Adding b branch head 1"
33 $ hg commit -d '3 0' -m "Adding b branch head 1"
31
34
32 $ hg update -C 2
35 $ hg update -C 2
33 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
36 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
34 $ echo 'bh2' >bh2
37 $ echo 'bh2' >bh2
35 $ hg add bh2
38 $ hg add bh2
36 $ hg commit -d '4 0' -m "Adding b branch head 2"
39 $ hg commit -d '4 0' -m "Adding b branch head 2"
37
40
38 $ echo 'c' >c
41 $ echo 'c' >c
39 $ hg add c
42 $ hg add c
40 $ hg branch c
43 $ hg branch c
41 marked working directory as branch c
44 marked working directory as branch c
45 (branches are permanent and global, did you want a bookmark?)
42 $ hg commit -d '5 0' -m "Adding c branch"
46 $ hg commit -d '5 0' -m "Adding c branch"
43
47
44 $ hg branch tip
48 $ hg branch tip
45 abort: the name 'tip' is reserved
49 abort: the name 'tip' is reserved
46 [255]
50 [255]
47 $ hg branch null
51 $ hg branch null
48 abort: the name 'null' is reserved
52 abort: the name 'null' is reserved
49 [255]
53 [255]
50 $ hg branch .
54 $ hg branch .
51 abort: the name '.' is reserved
55 abort: the name '.' is reserved
52 [255]
56 [255]
53
57
54 $ echo 'd' >d
58 $ echo 'd' >d
55 $ hg add d
59 $ hg add d
56 $ hg branch 'a branch name much longer than the default justification used by branches'
60 $ hg branch 'a branch name much longer than the default justification used by branches'
57 marked working directory as branch a branch name much longer than the default justification used by branches
61 marked working directory as branch a branch name much longer than the default justification used by branches
62 (branches are permanent and global, did you want a bookmark?)
58 $ hg commit -d '6 0' -m "Adding d branch"
63 $ hg commit -d '6 0' -m "Adding d branch"
59
64
60 $ hg branches
65 $ hg branches
61 a branch name much longer than the default justification used by branches 7:10ff5895aa57
66 a branch name much longer than the default justification used by branches 7:10ff5895aa57
62 b 4:aee39cd168d0
67 b 4:aee39cd168d0
63 c 6:589736a22561 (inactive)
68 c 6:589736a22561 (inactive)
64 a 5:d8cbc61dbaa6 (inactive)
69 a 5:d8cbc61dbaa6 (inactive)
65 default 0:19709c5a4e75 (inactive)
70 default 0:19709c5a4e75 (inactive)
66
71
67 -------
72 -------
68
73
69 $ hg branches -a
74 $ hg branches -a
70 a branch name much longer than the default justification used by branches 7:10ff5895aa57
75 a branch name much longer than the default justification used by branches 7:10ff5895aa57
71 b 4:aee39cd168d0
76 b 4:aee39cd168d0
72
77
73 --- Branch a
78 --- Branch a
74
79
75 $ hg log -b a
80 $ hg log -b a
76 changeset: 5:d8cbc61dbaa6
81 changeset: 5:d8cbc61dbaa6
77 branch: a
82 branch: a
78 parent: 2:881fe2b92ad0
83 parent: 2:881fe2b92ad0
79 user: test
84 user: test
80 date: Thu Jan 01 00:00:04 1970 +0000
85 date: Thu Jan 01 00:00:04 1970 +0000
81 summary: Adding b branch head 2
86 summary: Adding b branch head 2
82
87
83 changeset: 2:881fe2b92ad0
88 changeset: 2:881fe2b92ad0
84 branch: a
89 branch: a
85 user: test
90 user: test
86 date: Thu Jan 01 00:00:02 1970 +0000
91 date: Thu Jan 01 00:00:02 1970 +0000
87 summary: Adding to a branch
92 summary: Adding to a branch
88
93
89 changeset: 1:dd6b440dd85a
94 changeset: 1:dd6b440dd85a
90 branch: a
95 branch: a
91 user: test
96 user: test
92 date: Thu Jan 01 00:00:01 1970 +0000
97 date: Thu Jan 01 00:00:01 1970 +0000
93 summary: Adding a branch
98 summary: Adding a branch
94
99
95
100
96 ---- Branch b
101 ---- Branch b
97
102
98 $ hg log -b b
103 $ hg log -b b
99 changeset: 4:aee39cd168d0
104 changeset: 4:aee39cd168d0
100 branch: b
105 branch: b
101 user: test
106 user: test
102 date: Thu Jan 01 00:00:03 1970 +0000
107 date: Thu Jan 01 00:00:03 1970 +0000
103 summary: Adding b branch head 1
108 summary: Adding b branch head 1
104
109
105 changeset: 3:ac22033332d1
110 changeset: 3:ac22033332d1
106 branch: b
111 branch: b
107 parent: 0:19709c5a4e75
112 parent: 0:19709c5a4e75
108 user: test
113 user: test
109 date: Thu Jan 01 00:00:02 1970 +0000
114 date: Thu Jan 01 00:00:02 1970 +0000
110 summary: Adding b branch
115 summary: Adding b branch
111
116
112
117
113 ---- going to test branch closing
118 ---- going to test branch closing
114
119
115 $ hg branches
120 $ hg branches
116 a branch name much longer than the default justification used by branches 7:10ff5895aa57
121 a branch name much longer than the default justification used by branches 7:10ff5895aa57
117 b 4:aee39cd168d0
122 b 4:aee39cd168d0
118 c 6:589736a22561 (inactive)
123 c 6:589736a22561 (inactive)
119 a 5:d8cbc61dbaa6 (inactive)
124 a 5:d8cbc61dbaa6 (inactive)
120 default 0:19709c5a4e75 (inactive)
125 default 0:19709c5a4e75 (inactive)
121 $ hg up -C b
126 $ hg up -C b
122 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
127 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
123 $ echo 'xxx1' >> b
128 $ echo 'xxx1' >> b
124 $ hg commit -d '7 0' -m 'adding cset to branch b'
129 $ hg commit -d '7 0' -m 'adding cset to branch b'
125 $ hg up -C aee39cd168d0
130 $ hg up -C aee39cd168d0
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
131 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 $ echo 'xxx2' >> b
132 $ echo 'xxx2' >> b
128 $ hg commit -d '8 0' -m 'adding head to branch b'
133 $ hg commit -d '8 0' -m 'adding head to branch b'
129 created new head
134 created new head
130 $ echo 'xxx3' >> b
135 $ echo 'xxx3' >> b
131 $ hg commit -d '9 0' -m 'adding another cset to branch b'
136 $ hg commit -d '9 0' -m 'adding another cset to branch b'
132 $ hg branches
137 $ hg branches
133 b 10:bfbe841b666e
138 b 10:bfbe841b666e
134 a branch name much longer than the default justification used by branches 7:10ff5895aa57
139 a branch name much longer than the default justification used by branches 7:10ff5895aa57
135 c 6:589736a22561 (inactive)
140 c 6:589736a22561 (inactive)
136 a 5:d8cbc61dbaa6 (inactive)
141 a 5:d8cbc61dbaa6 (inactive)
137 default 0:19709c5a4e75 (inactive)
142 default 0:19709c5a4e75 (inactive)
138 $ hg heads --closed
143 $ hg heads --closed
139 changeset: 10:bfbe841b666e
144 changeset: 10:bfbe841b666e
140 branch: b
145 branch: b
141 tag: tip
146 tag: tip
142 user: test
147 user: test
143 date: Thu Jan 01 00:00:09 1970 +0000
148 date: Thu Jan 01 00:00:09 1970 +0000
144 summary: adding another cset to branch b
149 summary: adding another cset to branch b
145
150
146 changeset: 8:eebb944467c9
151 changeset: 8:eebb944467c9
147 branch: b
152 branch: b
148 parent: 4:aee39cd168d0
153 parent: 4:aee39cd168d0
149 user: test
154 user: test
150 date: Thu Jan 01 00:00:07 1970 +0000
155 date: Thu Jan 01 00:00:07 1970 +0000
151 summary: adding cset to branch b
156 summary: adding cset to branch b
152
157
153 changeset: 7:10ff5895aa57
158 changeset: 7:10ff5895aa57
154 branch: a branch name much longer than the default justification used by branches
159 branch: a branch name much longer than the default justification used by branches
155 user: test
160 user: test
156 date: Thu Jan 01 00:00:06 1970 +0000
161 date: Thu Jan 01 00:00:06 1970 +0000
157 summary: Adding d branch
162 summary: Adding d branch
158
163
159 changeset: 6:589736a22561
164 changeset: 6:589736a22561
160 branch: c
165 branch: c
161 user: test
166 user: test
162 date: Thu Jan 01 00:00:05 1970 +0000
167 date: Thu Jan 01 00:00:05 1970 +0000
163 summary: Adding c branch
168 summary: Adding c branch
164
169
165 changeset: 5:d8cbc61dbaa6
170 changeset: 5:d8cbc61dbaa6
166 branch: a
171 branch: a
167 parent: 2:881fe2b92ad0
172 parent: 2:881fe2b92ad0
168 user: test
173 user: test
169 date: Thu Jan 01 00:00:04 1970 +0000
174 date: Thu Jan 01 00:00:04 1970 +0000
170 summary: Adding b branch head 2
175 summary: Adding b branch head 2
171
176
172 changeset: 0:19709c5a4e75
177 changeset: 0:19709c5a4e75
173 user: test
178 user: test
174 date: Thu Jan 01 00:00:00 1970 +0000
179 date: Thu Jan 01 00:00:00 1970 +0000
175 summary: Adding root node
180 summary: Adding root node
176
181
177 $ hg heads
182 $ hg heads
178 changeset: 10:bfbe841b666e
183 changeset: 10:bfbe841b666e
179 branch: b
184 branch: b
180 tag: tip
185 tag: tip
181 user: test
186 user: test
182 date: Thu Jan 01 00:00:09 1970 +0000
187 date: Thu Jan 01 00:00:09 1970 +0000
183 summary: adding another cset to branch b
188 summary: adding another cset to branch b
184
189
185 changeset: 8:eebb944467c9
190 changeset: 8:eebb944467c9
186 branch: b
191 branch: b
187 parent: 4:aee39cd168d0
192 parent: 4:aee39cd168d0
188 user: test
193 user: test
189 date: Thu Jan 01 00:00:07 1970 +0000
194 date: Thu Jan 01 00:00:07 1970 +0000
190 summary: adding cset to branch b
195 summary: adding cset to branch b
191
196
192 changeset: 7:10ff5895aa57
197 changeset: 7:10ff5895aa57
193 branch: a branch name much longer than the default justification used by branches
198 branch: a branch name much longer than the default justification used by branches
194 user: test
199 user: test
195 date: Thu Jan 01 00:00:06 1970 +0000
200 date: Thu Jan 01 00:00:06 1970 +0000
196 summary: Adding d branch
201 summary: Adding d branch
197
202
198 changeset: 6:589736a22561
203 changeset: 6:589736a22561
199 branch: c
204 branch: c
200 user: test
205 user: test
201 date: Thu Jan 01 00:00:05 1970 +0000
206 date: Thu Jan 01 00:00:05 1970 +0000
202 summary: Adding c branch
207 summary: Adding c branch
203
208
204 changeset: 5:d8cbc61dbaa6
209 changeset: 5:d8cbc61dbaa6
205 branch: a
210 branch: a
206 parent: 2:881fe2b92ad0
211 parent: 2:881fe2b92ad0
207 user: test
212 user: test
208 date: Thu Jan 01 00:00:04 1970 +0000
213 date: Thu Jan 01 00:00:04 1970 +0000
209 summary: Adding b branch head 2
214 summary: Adding b branch head 2
210
215
211 changeset: 0:19709c5a4e75
216 changeset: 0:19709c5a4e75
212 user: test
217 user: test
213 date: Thu Jan 01 00:00:00 1970 +0000
218 date: Thu Jan 01 00:00:00 1970 +0000
214 summary: Adding root node
219 summary: Adding root node
215
220
216 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
221 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
217 $ hg branches -a
222 $ hg branches -a
218 b 8:eebb944467c9
223 b 8:eebb944467c9
219 a branch name much longer than the default justification used by branches 7:10ff5895aa57
224 a branch name much longer than the default justification used by branches 7:10ff5895aa57
220 $ hg up -C b
225 $ hg up -C b
221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
227 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
223
228
224 --- b branch should be inactive
229 --- b branch should be inactive
225
230
226 $ hg branches
231 $ hg branches
227 a branch name much longer than the default justification used by branches 7:10ff5895aa57
232 a branch name much longer than the default justification used by branches 7:10ff5895aa57
228 c 6:589736a22561 (inactive)
233 c 6:589736a22561 (inactive)
229 a 5:d8cbc61dbaa6 (inactive)
234 a 5:d8cbc61dbaa6 (inactive)
230 default 0:19709c5a4e75 (inactive)
235 default 0:19709c5a4e75 (inactive)
231 $ hg branches -c
236 $ hg branches -c
232 a branch name much longer than the default justification used by branches 7:10ff5895aa57
237 a branch name much longer than the default justification used by branches 7:10ff5895aa57
233 b 12:e3d49c0575d8 (closed)
238 b 12:e3d49c0575d8 (closed)
234 c 6:589736a22561 (inactive)
239 c 6:589736a22561 (inactive)
235 a 5:d8cbc61dbaa6 (inactive)
240 a 5:d8cbc61dbaa6 (inactive)
236 default 0:19709c5a4e75 (inactive)
241 default 0:19709c5a4e75 (inactive)
237 $ hg branches -a
242 $ hg branches -a
238 a branch name much longer than the default justification used by branches 7:10ff5895aa57
243 a branch name much longer than the default justification used by branches 7:10ff5895aa57
239 $ hg heads b
244 $ hg heads b
240 no open branch heads found on branches b
245 no open branch heads found on branches b
241 [1]
246 [1]
242 $ hg heads --closed b
247 $ hg heads --closed b
243 changeset: 12:e3d49c0575d8
248 changeset: 12:e3d49c0575d8
244 branch: b
249 branch: b
245 tag: tip
250 tag: tip
246 parent: 8:eebb944467c9
251 parent: 8:eebb944467c9
247 user: test
252 user: test
248 date: Thu Jan 01 00:00:09 1970 +0000
253 date: Thu Jan 01 00:00:09 1970 +0000
249 summary: close this part branch too
254 summary: close this part branch too
250
255
251 changeset: 11:d3f163457ebf
256 changeset: 11:d3f163457ebf
252 branch: b
257 branch: b
253 user: test
258 user: test
254 date: Thu Jan 01 00:00:09 1970 +0000
259 date: Thu Jan 01 00:00:09 1970 +0000
255 summary: prune bad branch
260 summary: prune bad branch
256
261
257 $ echo 'xxx4' >> b
262 $ echo 'xxx4' >> b
258 $ hg commit -d '9 0' -m 'reopen branch with a change'
263 $ hg commit -d '9 0' -m 'reopen branch with a change'
259 reopening closed branch head 12
264 reopening closed branch head 12
260
265
261 --- branch b is back in action
266 --- branch b is back in action
262
267
263 $ hg branches -a
268 $ hg branches -a
264 b 13:e23b5505d1ad
269 b 13:e23b5505d1ad
265 a branch name much longer than the default justification used by branches 7:10ff5895aa57
270 a branch name much longer than the default justification used by branches 7:10ff5895aa57
266
271
267 ---- test heads listings
272 ---- test heads listings
268
273
269 $ hg heads
274 $ hg heads
270 changeset: 13:e23b5505d1ad
275 changeset: 13:e23b5505d1ad
271 branch: b
276 branch: b
272 tag: tip
277 tag: tip
273 user: test
278 user: test
274 date: Thu Jan 01 00:00:09 1970 +0000
279 date: Thu Jan 01 00:00:09 1970 +0000
275 summary: reopen branch with a change
280 summary: reopen branch with a change
276
281
277 changeset: 7:10ff5895aa57
282 changeset: 7:10ff5895aa57
278 branch: a branch name much longer than the default justification used by branches
283 branch: a branch name much longer than the default justification used by branches
279 user: test
284 user: test
280 date: Thu Jan 01 00:00:06 1970 +0000
285 date: Thu Jan 01 00:00:06 1970 +0000
281 summary: Adding d branch
286 summary: Adding d branch
282
287
283 changeset: 6:589736a22561
288 changeset: 6:589736a22561
284 branch: c
289 branch: c
285 user: test
290 user: test
286 date: Thu Jan 01 00:00:05 1970 +0000
291 date: Thu Jan 01 00:00:05 1970 +0000
287 summary: Adding c branch
292 summary: Adding c branch
288
293
289 changeset: 5:d8cbc61dbaa6
294 changeset: 5:d8cbc61dbaa6
290 branch: a
295 branch: a
291 parent: 2:881fe2b92ad0
296 parent: 2:881fe2b92ad0
292 user: test
297 user: test
293 date: Thu Jan 01 00:00:04 1970 +0000
298 date: Thu Jan 01 00:00:04 1970 +0000
294 summary: Adding b branch head 2
299 summary: Adding b branch head 2
295
300
296 changeset: 0:19709c5a4e75
301 changeset: 0:19709c5a4e75
297 user: test
302 user: test
298 date: Thu Jan 01 00:00:00 1970 +0000
303 date: Thu Jan 01 00:00:00 1970 +0000
299 summary: Adding root node
304 summary: Adding root node
300
305
301
306
302 branch default
307 branch default
303
308
304 $ hg heads default
309 $ hg heads default
305 changeset: 0:19709c5a4e75
310 changeset: 0:19709c5a4e75
306 user: test
311 user: test
307 date: Thu Jan 01 00:00:00 1970 +0000
312 date: Thu Jan 01 00:00:00 1970 +0000
308 summary: Adding root node
313 summary: Adding root node
309
314
310
315
311 branch a
316 branch a
312
317
313 $ hg heads a
318 $ hg heads a
314 changeset: 5:d8cbc61dbaa6
319 changeset: 5:d8cbc61dbaa6
315 branch: a
320 branch: a
316 parent: 2:881fe2b92ad0
321 parent: 2:881fe2b92ad0
317 user: test
322 user: test
318 date: Thu Jan 01 00:00:04 1970 +0000
323 date: Thu Jan 01 00:00:04 1970 +0000
319 summary: Adding b branch head 2
324 summary: Adding b branch head 2
320
325
321 $ hg heads --active a
326 $ hg heads --active a
322 no open branch heads found on branches a
327 no open branch heads found on branches a
323 [1]
328 [1]
324
329
325 branch b
330 branch b
326
331
327 $ hg heads b
332 $ hg heads b
328 changeset: 13:e23b5505d1ad
333 changeset: 13:e23b5505d1ad
329 branch: b
334 branch: b
330 tag: tip
335 tag: tip
331 user: test
336 user: test
332 date: Thu Jan 01 00:00:09 1970 +0000
337 date: Thu Jan 01 00:00:09 1970 +0000
333 summary: reopen branch with a change
338 summary: reopen branch with a change
334
339
335 $ hg heads --closed b
340 $ hg heads --closed b
336 changeset: 13:e23b5505d1ad
341 changeset: 13:e23b5505d1ad
337 branch: b
342 branch: b
338 tag: tip
343 tag: tip
339 user: test
344 user: test
340 date: Thu Jan 01 00:00:09 1970 +0000
345 date: Thu Jan 01 00:00:09 1970 +0000
341 summary: reopen branch with a change
346 summary: reopen branch with a change
342
347
343 changeset: 11:d3f163457ebf
348 changeset: 11:d3f163457ebf
344 branch: b
349 branch: b
345 user: test
350 user: test
346 date: Thu Jan 01 00:00:09 1970 +0000
351 date: Thu Jan 01 00:00:09 1970 +0000
347 summary: prune bad branch
352 summary: prune bad branch
348
353
349 default branch colors:
354 default branch colors:
350
355
351 $ echo "[extensions]" >> $HGRCPATH
356 $ echo "[extensions]" >> $HGRCPATH
352 $ echo "color =" >> $HGRCPATH
357 $ echo "color =" >> $HGRCPATH
353 $ echo "[color]" >> $HGRCPATH
358 $ echo "[color]" >> $HGRCPATH
354 $ echo "mode = ansi" >> $HGRCPATH
359 $ echo "mode = ansi" >> $HGRCPATH
355
360
356 $ hg up -C c
361 $ hg up -C c
357 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
362 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
358 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
363 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
359 $ hg up -C b
364 $ hg up -C b
360 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
365 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
361 $ hg branches --color=always
366 $ hg branches --color=always
362 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
367 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
363 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
368 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
364 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
369 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
365 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
370 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
366
371
367 default closed branch color:
372 default closed branch color:
368
373
369 $ hg branches --color=always --closed
374 $ hg branches --color=always --closed
370 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
375 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
371 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
376 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
372 \x1b[0;30;1mc\x1b[0m \x1b[0;33m 14:f894c25619d3\x1b[0m (closed) (esc)
377 \x1b[0;30;1mc\x1b[0m \x1b[0;33m 14:f894c25619d3\x1b[0m (closed) (esc)
373 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
378 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
374 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
379 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
375
380
376 $ echo "[extensions]" >> $HGRCPATH
381 $ echo "[extensions]" >> $HGRCPATH
377 $ echo "color =" >> $HGRCPATH
382 $ echo "color =" >> $HGRCPATH
378 $ echo "[color]" >> $HGRCPATH
383 $ echo "[color]" >> $HGRCPATH
379 $ echo "branches.active = green" >> $HGRCPATH
384 $ echo "branches.active = green" >> $HGRCPATH
380 $ echo "branches.closed = blue" >> $HGRCPATH
385 $ echo "branches.closed = blue" >> $HGRCPATH
381 $ echo "branches.current = red" >> $HGRCPATH
386 $ echo "branches.current = red" >> $HGRCPATH
382 $ echo "branches.inactive = magenta" >> $HGRCPATH
387 $ echo "branches.inactive = magenta" >> $HGRCPATH
383 $ echo "log.changeset = cyan" >> $HGRCPATH
388 $ echo "log.changeset = cyan" >> $HGRCPATH
384
389
385 custom branch colors:
390 custom branch colors:
386
391
387 $ hg branches --color=always
392 $ hg branches --color=always
388 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
393 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
389 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
394 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
390 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
395 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
391 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
396 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
392
397
393 custom closed branch color:
398 custom closed branch color:
394
399
395 $ hg branches --color=always --closed
400 $ hg branches --color=always --closed
396 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
401 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
397 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
402 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
398 \x1b[0;34mc\x1b[0m \x1b[0;36m 14:f894c25619d3\x1b[0m (closed) (esc)
403 \x1b[0;34mc\x1b[0m \x1b[0;36m 14:f894c25619d3\x1b[0m (closed) (esc)
399 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
404 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
400 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
405 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
@@ -1,103 +1,105 b''
1 $ hg init
1 $ hg init
2 $ echo foo > bar
2 $ echo foo > bar
3 $ hg commit -Am default
3 $ hg commit -Am default
4 adding bar
4 adding bar
5 $ hg up -r null
5 $ hg up -r null
6 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
6 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
7 $ hg branch mine
7 $ hg branch mine
8 marked working directory as branch mine
8 marked working directory as branch mine
9 (branches are permanent and global, did you want a bookmark?)
9 $ echo hello > world
10 $ echo hello > world
10 $ hg commit -Am hello
11 $ hg commit -Am hello
11 adding world
12 adding world
12 $ hg up -r null
13 $ hg up -r null
13 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
14 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
14 $ hg branch other
15 $ hg branch other
15 marked working directory as branch other
16 marked working directory as branch other
17 (branches are permanent and global, did you want a bookmark?)
16 $ echo good > bye
18 $ echo good > bye
17 $ hg commit -Am other
19 $ hg commit -Am other
18 adding bye
20 adding bye
19 $ hg up -r mine
21 $ hg up -r mine
20 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
22 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
21
23
22 $ hg clone -U -u . .#other ../b -r 0 -r 1 -r 2 -b other
24 $ hg clone -U -u . .#other ../b -r 0 -r 1 -r 2 -b other
23 abort: cannot specify both --noupdate and --updaterev
25 abort: cannot specify both --noupdate and --updaterev
24 [255]
26 [255]
25
27
26 $ hg clone -U .#other ../b -r 0 -r 1 -r 2 -b other
28 $ hg clone -U .#other ../b -r 0 -r 1 -r 2 -b other
27 adding changesets
29 adding changesets
28 adding manifests
30 adding manifests
29 adding file changes
31 adding file changes
30 added 3 changesets with 3 changes to 3 files (+2 heads)
32 added 3 changesets with 3 changes to 3 files (+2 heads)
31 $ rm -rf ../b
33 $ rm -rf ../b
32
34
33 $ hg clone -u . .#other ../b -r 0 -r 1 -r 2 -b other
35 $ hg clone -u . .#other ../b -r 0 -r 1 -r 2 -b other
34 adding changesets
36 adding changesets
35 adding manifests
37 adding manifests
36 adding file changes
38 adding file changes
37 added 3 changesets with 3 changes to 3 files (+2 heads)
39 added 3 changesets with 3 changes to 3 files (+2 heads)
38 updating to branch mine
40 updating to branch mine
39 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
40 $ rm -rf ../b
42 $ rm -rf ../b
41
43
42 $ hg clone -u 0 .#other ../b -r 0 -r 1 -r 2 -b other
44 $ hg clone -u 0 .#other ../b -r 0 -r 1 -r 2 -b other
43 adding changesets
45 adding changesets
44 adding manifests
46 adding manifests
45 adding file changes
47 adding file changes
46 added 3 changesets with 3 changes to 3 files (+2 heads)
48 added 3 changesets with 3 changes to 3 files (+2 heads)
47 updating to branch default
49 updating to branch default
48 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
49 $ rm -rf ../b
51 $ rm -rf ../b
50
52
51 $ hg clone -u 1 .#other ../b -r 0 -r 1 -r 2 -b other
53 $ hg clone -u 1 .#other ../b -r 0 -r 1 -r 2 -b other
52 adding changesets
54 adding changesets
53 adding manifests
55 adding manifests
54 adding file changes
56 adding file changes
55 added 3 changesets with 3 changes to 3 files (+2 heads)
57 added 3 changesets with 3 changes to 3 files (+2 heads)
56 updating to branch mine
58 updating to branch mine
57 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 $ rm -rf ../b
60 $ rm -rf ../b
59
61
60 $ hg clone -u 2 .#other ../b -r 0 -r 1 -r 2 -b other
62 $ hg clone -u 2 .#other ../b -r 0 -r 1 -r 2 -b other
61 adding changesets
63 adding changesets
62 adding manifests
64 adding manifests
63 adding file changes
65 adding file changes
64 added 3 changesets with 3 changes to 3 files (+2 heads)
66 added 3 changesets with 3 changes to 3 files (+2 heads)
65 updating to branch other
67 updating to branch other
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
68 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 $ rm -rf ../b
69 $ rm -rf ../b
68
70
69 Test -r mine ... mine is ignored:
71 Test -r mine ... mine is ignored:
70
72
71 $ hg clone -u 2 .#other ../b -r mine -r 0 -r 1 -r 2 -b other
73 $ hg clone -u 2 .#other ../b -r mine -r 0 -r 1 -r 2 -b other
72 adding changesets
74 adding changesets
73 adding manifests
75 adding manifests
74 adding file changes
76 adding file changes
75 added 3 changesets with 3 changes to 3 files (+2 heads)
77 added 3 changesets with 3 changes to 3 files (+2 heads)
76 updating to branch other
78 updating to branch other
77 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 $ rm -rf ../b
80 $ rm -rf ../b
79
81
80 $ hg clone .#other ../b -b default -b mine
82 $ hg clone .#other ../b -b default -b mine
81 adding changesets
83 adding changesets
82 adding manifests
84 adding manifests
83 adding file changes
85 adding file changes
84 added 3 changesets with 3 changes to 3 files (+2 heads)
86 added 3 changesets with 3 changes to 3 files (+2 heads)
85 updating to branch default
87 updating to branch default
86 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 $ rm -rf ../b
89 $ rm -rf ../b
88
90
89 $ hg clone .#other ../b
91 $ hg clone .#other ../b
90 adding changesets
92 adding changesets
91 adding manifests
93 adding manifests
92 adding file changes
94 adding file changes
93 added 1 changesets with 1 changes to 1 files
95 added 1 changesets with 1 changes to 1 files
94 updating to branch other
96 updating to branch other
95 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
96 $ rm -rf ../b
98 $ rm -rf ../b
97
99
98 $ hg clone -U . ../c -r 1 -r 2 > /dev/null
100 $ hg clone -U . ../c -r 1 -r 2 > /dev/null
99 $ hg clone ../c ../b
101 $ hg clone ../c ../b
100 updating to branch other
102 updating to branch other
101 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
103 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 $ rm -rf ../b ../c
104 $ rm -rf ../b ../c
103
105
@@ -1,459 +1,460 b''
1 Prepare repo a:
1 Prepare repo a:
2
2
3 $ hg init a
3 $ hg init a
4 $ cd a
4 $ cd a
5 $ echo a > a
5 $ echo a > a
6 $ hg add a
6 $ hg add a
7 $ hg commit -m test
7 $ hg commit -m test
8 $ echo first line > b
8 $ echo first line > b
9 $ hg add b
9 $ hg add b
10
10
11 Create a non-inlined filelog:
11 Create a non-inlined filelog:
12
12
13 $ python -c 'for x in range(10000): print x' >> data1
13 $ python -c 'for x in range(10000): print x' >> data1
14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
14 $ for j in 0 1 2 3 4 5 6 7 8 9; do
15 > cat data1 >> b
15 > cat data1 >> b
16 > hg commit -m test
16 > hg commit -m test
17 > done
17 > done
18
18
19 List files in store/data (should show a 'b.d'):
19 List files in store/data (should show a 'b.d'):
20
20
21 $ for i in .hg/store/data/*; do
21 $ for i in .hg/store/data/*; do
22 > echo $i
22 > echo $i
23 > done
23 > done
24 .hg/store/data/a.i
24 .hg/store/data/a.i
25 .hg/store/data/b.d
25 .hg/store/data/b.d
26 .hg/store/data/b.i
26 .hg/store/data/b.i
27
27
28 Default operation:
28 Default operation:
29
29
30 $ hg clone . ../b
30 $ hg clone . ../b
31 updating to branch default
31 updating to branch default
32 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
32 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 $ cd ../b
33 $ cd ../b
34 $ cat a
34 $ cat a
35 a
35 a
36 $ hg verify
36 $ hg verify
37 checking changesets
37 checking changesets
38 checking manifests
38 checking manifests
39 crosschecking files in changesets and manifests
39 crosschecking files in changesets and manifests
40 checking files
40 checking files
41 2 files, 11 changesets, 11 total revisions
41 2 files, 11 changesets, 11 total revisions
42
42
43 Invalid dest '' must abort:
43 Invalid dest '' must abort:
44
44
45 $ hg clone . ''
45 $ hg clone . ''
46 abort: No such file or directory
46 abort: No such file or directory
47 [255]
47 [255]
48
48
49 No update, with debug option:
49 No update, with debug option:
50
50
51 $ hg --debug clone -U . ../c
51 $ hg --debug clone -U . ../c
52 linked 8 files
52 linked 8 files
53 $ cd ../c
53 $ cd ../c
54 $ cat a 2>/dev/null || echo "a not present"
54 $ cat a 2>/dev/null || echo "a not present"
55 a not present
55 a not present
56 $ hg verify
56 $ hg verify
57 checking changesets
57 checking changesets
58 checking manifests
58 checking manifests
59 crosschecking files in changesets and manifests
59 crosschecking files in changesets and manifests
60 checking files
60 checking files
61 2 files, 11 changesets, 11 total revisions
61 2 files, 11 changesets, 11 total revisions
62
62
63 Default destination:
63 Default destination:
64
64
65 $ mkdir ../d
65 $ mkdir ../d
66 $ cd ../d
66 $ cd ../d
67 $ hg clone ../a
67 $ hg clone ../a
68 destination directory: a
68 destination directory: a
69 updating to branch default
69 updating to branch default
70 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 $ cd a
71 $ cd a
72 $ hg cat a
72 $ hg cat a
73 a
73 a
74 $ cd ../..
74 $ cd ../..
75
75
76 Check that we drop the 'file:' from the path before writing the .hgrc:
76 Check that we drop the 'file:' from the path before writing the .hgrc:
77
77
78 $ hg clone file:a e
78 $ hg clone file:a e
79 updating to branch default
79 updating to branch default
80 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 $ grep 'file:' e/.hg/hgrc
81 $ grep 'file:' e/.hg/hgrc
82 [1]
82 [1]
83
83
84 Check that path aliases are expanded:
84 Check that path aliases are expanded:
85
85
86 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
86 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
87 $ hg -R f showconfig paths.default
87 $ hg -R f showconfig paths.default
88 $TESTTMP/a#0
88 $TESTTMP/a#0
89
89
90 Use --pull:
90 Use --pull:
91
91
92 $ hg clone --pull a g
92 $ hg clone --pull a g
93 requesting all changes
93 requesting all changes
94 adding changesets
94 adding changesets
95 adding manifests
95 adding manifests
96 adding file changes
96 adding file changes
97 added 11 changesets with 11 changes to 2 files
97 added 11 changesets with 11 changes to 2 files
98 updating to branch default
98 updating to branch default
99 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 $ hg -R g verify
100 $ hg -R g verify
101 checking changesets
101 checking changesets
102 checking manifests
102 checking manifests
103 crosschecking files in changesets and manifests
103 crosschecking files in changesets and manifests
104 checking files
104 checking files
105 2 files, 11 changesets, 11 total revisions
105 2 files, 11 changesets, 11 total revisions
106
106
107 Invalid dest '' with --pull must abort (issue2528):
107 Invalid dest '' with --pull must abort (issue2528):
108
108
109 $ hg clone --pull a ''
109 $ hg clone --pull a ''
110 abort: No such file or directory
110 abort: No such file or directory
111 [255]
111 [255]
112
112
113 Clone to '.':
113 Clone to '.':
114
114
115 $ mkdir h
115 $ mkdir h
116 $ cd h
116 $ cd h
117 $ hg clone ../a .
117 $ hg clone ../a .
118 updating to branch default
118 updating to branch default
119 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 $ cd ..
120 $ cd ..
121
121
122
122
123 *** Tests for option -u ***
123 *** Tests for option -u ***
124
124
125 Adding some more history to repo a:
125 Adding some more history to repo a:
126
126
127 $ cd a
127 $ cd a
128 $ hg tag ref1
128 $ hg tag ref1
129 $ echo the quick brown fox >a
129 $ echo the quick brown fox >a
130 $ hg ci -m "hacked default"
130 $ hg ci -m "hacked default"
131 $ hg up ref1
131 $ hg up ref1
132 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
132 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
133 $ hg branch stable
133 $ hg branch stable
134 marked working directory as branch stable
134 marked working directory as branch stable
135 (branches are permanent and global, did you want a bookmark?)
135 $ echo some text >a
136 $ echo some text >a
136 $ hg ci -m "starting branch stable"
137 $ hg ci -m "starting branch stable"
137 $ hg tag ref2
138 $ hg tag ref2
138 $ echo some more text >a
139 $ echo some more text >a
139 $ hg ci -m "another change for branch stable"
140 $ hg ci -m "another change for branch stable"
140 $ hg up ref2
141 $ hg up ref2
141 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
142 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
142 $ hg parents
143 $ hg parents
143 changeset: 13:e8ece76546a6
144 changeset: 13:e8ece76546a6
144 branch: stable
145 branch: stable
145 tag: ref2
146 tag: ref2
146 parent: 10:a7949464abda
147 parent: 10:a7949464abda
147 user: test
148 user: test
148 date: Thu Jan 01 00:00:00 1970 +0000
149 date: Thu Jan 01 00:00:00 1970 +0000
149 summary: starting branch stable
150 summary: starting branch stable
150
151
151
152
152 Repo a has two heads:
153 Repo a has two heads:
153
154
154 $ hg heads
155 $ hg heads
155 changeset: 15:0aae7cf88f0d
156 changeset: 15:0aae7cf88f0d
156 branch: stable
157 branch: stable
157 tag: tip
158 tag: tip
158 user: test
159 user: test
159 date: Thu Jan 01 00:00:00 1970 +0000
160 date: Thu Jan 01 00:00:00 1970 +0000
160 summary: another change for branch stable
161 summary: another change for branch stable
161
162
162 changeset: 12:f21241060d6a
163 changeset: 12:f21241060d6a
163 user: test
164 user: test
164 date: Thu Jan 01 00:00:00 1970 +0000
165 date: Thu Jan 01 00:00:00 1970 +0000
165 summary: hacked default
166 summary: hacked default
166
167
167
168
168 $ cd ..
169 $ cd ..
169
170
170
171
171 Testing --noupdate with --updaterev (must abort):
172 Testing --noupdate with --updaterev (must abort):
172
173
173 $ hg clone --noupdate --updaterev 1 a ua
174 $ hg clone --noupdate --updaterev 1 a ua
174 abort: cannot specify both --noupdate and --updaterev
175 abort: cannot specify both --noupdate and --updaterev
175 [255]
176 [255]
176
177
177
178
178 Testing clone -u:
179 Testing clone -u:
179
180
180 $ hg clone -u . a ua
181 $ hg clone -u . a ua
181 updating to branch stable
182 updating to branch stable
182 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
183 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
183
184
184 Repo ua has both heads:
185 Repo ua has both heads:
185
186
186 $ hg -R ua heads
187 $ hg -R ua heads
187 changeset: 15:0aae7cf88f0d
188 changeset: 15:0aae7cf88f0d
188 branch: stable
189 branch: stable
189 tag: tip
190 tag: tip
190 user: test
191 user: test
191 date: Thu Jan 01 00:00:00 1970 +0000
192 date: Thu Jan 01 00:00:00 1970 +0000
192 summary: another change for branch stable
193 summary: another change for branch stable
193
194
194 changeset: 12:f21241060d6a
195 changeset: 12:f21241060d6a
195 user: test
196 user: test
196 date: Thu Jan 01 00:00:00 1970 +0000
197 date: Thu Jan 01 00:00:00 1970 +0000
197 summary: hacked default
198 summary: hacked default
198
199
199
200
200 Same revision checked out in repo a and ua:
201 Same revision checked out in repo a and ua:
201
202
202 $ hg -R a parents --template "{node|short}\n"
203 $ hg -R a parents --template "{node|short}\n"
203 e8ece76546a6
204 e8ece76546a6
204 $ hg -R ua parents --template "{node|short}\n"
205 $ hg -R ua parents --template "{node|short}\n"
205 e8ece76546a6
206 e8ece76546a6
206
207
207 $ rm -r ua
208 $ rm -r ua
208
209
209
210
210 Testing clone --pull -u:
211 Testing clone --pull -u:
211
212
212 $ hg clone --pull -u . a ua
213 $ hg clone --pull -u . a ua
213 requesting all changes
214 requesting all changes
214 adding changesets
215 adding changesets
215 adding manifests
216 adding manifests
216 adding file changes
217 adding file changes
217 added 16 changesets with 16 changes to 3 files (+1 heads)
218 added 16 changesets with 16 changes to 3 files (+1 heads)
218 updating to branch stable
219 updating to branch stable
219 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
220
221
221 Repo ua has both heads:
222 Repo ua has both heads:
222
223
223 $ hg -R ua heads
224 $ hg -R ua heads
224 changeset: 15:0aae7cf88f0d
225 changeset: 15:0aae7cf88f0d
225 branch: stable
226 branch: stable
226 tag: tip
227 tag: tip
227 user: test
228 user: test
228 date: Thu Jan 01 00:00:00 1970 +0000
229 date: Thu Jan 01 00:00:00 1970 +0000
229 summary: another change for branch stable
230 summary: another change for branch stable
230
231
231 changeset: 12:f21241060d6a
232 changeset: 12:f21241060d6a
232 user: test
233 user: test
233 date: Thu Jan 01 00:00:00 1970 +0000
234 date: Thu Jan 01 00:00:00 1970 +0000
234 summary: hacked default
235 summary: hacked default
235
236
236
237
237 Same revision checked out in repo a and ua:
238 Same revision checked out in repo a and ua:
238
239
239 $ hg -R a parents --template "{node|short}\n"
240 $ hg -R a parents --template "{node|short}\n"
240 e8ece76546a6
241 e8ece76546a6
241 $ hg -R ua parents --template "{node|short}\n"
242 $ hg -R ua parents --template "{node|short}\n"
242 e8ece76546a6
243 e8ece76546a6
243
244
244 $ rm -r ua
245 $ rm -r ua
245
246
246
247
247 Testing clone -u <branch>:
248 Testing clone -u <branch>:
248
249
249 $ hg clone -u stable a ua
250 $ hg clone -u stable a ua
250 updating to branch stable
251 updating to branch stable
251 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
252 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
252
253
253 Repo ua has both heads:
254 Repo ua has both heads:
254
255
255 $ hg -R ua heads
256 $ hg -R ua heads
256 changeset: 15:0aae7cf88f0d
257 changeset: 15:0aae7cf88f0d
257 branch: stable
258 branch: stable
258 tag: tip
259 tag: tip
259 user: test
260 user: test
260 date: Thu Jan 01 00:00:00 1970 +0000
261 date: Thu Jan 01 00:00:00 1970 +0000
261 summary: another change for branch stable
262 summary: another change for branch stable
262
263
263 changeset: 12:f21241060d6a
264 changeset: 12:f21241060d6a
264 user: test
265 user: test
265 date: Thu Jan 01 00:00:00 1970 +0000
266 date: Thu Jan 01 00:00:00 1970 +0000
266 summary: hacked default
267 summary: hacked default
267
268
268
269
269 Branch 'stable' is checked out:
270 Branch 'stable' is checked out:
270
271
271 $ hg -R ua parents
272 $ hg -R ua parents
272 changeset: 15:0aae7cf88f0d
273 changeset: 15:0aae7cf88f0d
273 branch: stable
274 branch: stable
274 tag: tip
275 tag: tip
275 user: test
276 user: test
276 date: Thu Jan 01 00:00:00 1970 +0000
277 date: Thu Jan 01 00:00:00 1970 +0000
277 summary: another change for branch stable
278 summary: another change for branch stable
278
279
279
280
280 $ rm -r ua
281 $ rm -r ua
281
282
282
283
283 Testing default checkout:
284 Testing default checkout:
284
285
285 $ hg clone a ua
286 $ hg clone a ua
286 updating to branch default
287 updating to branch default
287 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
288 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
288
289
289 Repo ua has both heads:
290 Repo ua has both heads:
290
291
291 $ hg -R ua heads
292 $ hg -R ua heads
292 changeset: 15:0aae7cf88f0d
293 changeset: 15:0aae7cf88f0d
293 branch: stable
294 branch: stable
294 tag: tip
295 tag: tip
295 user: test
296 user: test
296 date: Thu Jan 01 00:00:00 1970 +0000
297 date: Thu Jan 01 00:00:00 1970 +0000
297 summary: another change for branch stable
298 summary: another change for branch stable
298
299
299 changeset: 12:f21241060d6a
300 changeset: 12:f21241060d6a
300 user: test
301 user: test
301 date: Thu Jan 01 00:00:00 1970 +0000
302 date: Thu Jan 01 00:00:00 1970 +0000
302 summary: hacked default
303 summary: hacked default
303
304
304
305
305 Branch 'default' is checked out:
306 Branch 'default' is checked out:
306
307
307 $ hg -R ua parents
308 $ hg -R ua parents
308 changeset: 12:f21241060d6a
309 changeset: 12:f21241060d6a
309 user: test
310 user: test
310 date: Thu Jan 01 00:00:00 1970 +0000
311 date: Thu Jan 01 00:00:00 1970 +0000
311 summary: hacked default
312 summary: hacked default
312
313
313
314
314 $ rm -r ua
315 $ rm -r ua
315
316
316
317
317 Testing #<branch>:
318 Testing #<branch>:
318
319
319 $ hg clone -u . a#stable ua
320 $ hg clone -u . a#stable ua
320 adding changesets
321 adding changesets
321 adding manifests
322 adding manifests
322 adding file changes
323 adding file changes
323 added 14 changesets with 14 changes to 3 files
324 added 14 changesets with 14 changes to 3 files
324 updating to branch stable
325 updating to branch stable
325 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
326 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
326
327
327 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
328 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
328
329
329 $ hg -R ua heads
330 $ hg -R ua heads
330 changeset: 13:0aae7cf88f0d
331 changeset: 13:0aae7cf88f0d
331 branch: stable
332 branch: stable
332 tag: tip
333 tag: tip
333 user: test
334 user: test
334 date: Thu Jan 01 00:00:00 1970 +0000
335 date: Thu Jan 01 00:00:00 1970 +0000
335 summary: another change for branch stable
336 summary: another change for branch stable
336
337
337 changeset: 10:a7949464abda
338 changeset: 10:a7949464abda
338 user: test
339 user: test
339 date: Thu Jan 01 00:00:00 1970 +0000
340 date: Thu Jan 01 00:00:00 1970 +0000
340 summary: test
341 summary: test
341
342
342
343
343 Same revision checked out in repo a and ua:
344 Same revision checked out in repo a and ua:
344
345
345 $ hg -R a parents --template "{node|short}\n"
346 $ hg -R a parents --template "{node|short}\n"
346 e8ece76546a6
347 e8ece76546a6
347 $ hg -R ua parents --template "{node|short}\n"
348 $ hg -R ua parents --template "{node|short}\n"
348 e8ece76546a6
349 e8ece76546a6
349
350
350 $ rm -r ua
351 $ rm -r ua
351
352
352
353
353 Testing -u -r <branch>:
354 Testing -u -r <branch>:
354
355
355 $ hg clone -u . -r stable a ua
356 $ hg clone -u . -r stable a ua
356 adding changesets
357 adding changesets
357 adding manifests
358 adding manifests
358 adding file changes
359 adding file changes
359 added 14 changesets with 14 changes to 3 files
360 added 14 changesets with 14 changes to 3 files
360 updating to branch stable
361 updating to branch stable
361 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
362 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
362
363
363 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
364 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
364
365
365 $ hg -R ua heads
366 $ hg -R ua heads
366 changeset: 13:0aae7cf88f0d
367 changeset: 13:0aae7cf88f0d
367 branch: stable
368 branch: stable
368 tag: tip
369 tag: tip
369 user: test
370 user: test
370 date: Thu Jan 01 00:00:00 1970 +0000
371 date: Thu Jan 01 00:00:00 1970 +0000
371 summary: another change for branch stable
372 summary: another change for branch stable
372
373
373 changeset: 10:a7949464abda
374 changeset: 10:a7949464abda
374 user: test
375 user: test
375 date: Thu Jan 01 00:00:00 1970 +0000
376 date: Thu Jan 01 00:00:00 1970 +0000
376 summary: test
377 summary: test
377
378
378
379
379 Same revision checked out in repo a and ua:
380 Same revision checked out in repo a and ua:
380
381
381 $ hg -R a parents --template "{node|short}\n"
382 $ hg -R a parents --template "{node|short}\n"
382 e8ece76546a6
383 e8ece76546a6
383 $ hg -R ua parents --template "{node|short}\n"
384 $ hg -R ua parents --template "{node|short}\n"
384 e8ece76546a6
385 e8ece76546a6
385
386
386 $ rm -r ua
387 $ rm -r ua
387
388
388
389
389 Testing -r <branch>:
390 Testing -r <branch>:
390
391
391 $ hg clone -r stable a ua
392 $ hg clone -r stable a ua
392 adding changesets
393 adding changesets
393 adding manifests
394 adding manifests
394 adding file changes
395 adding file changes
395 added 14 changesets with 14 changes to 3 files
396 added 14 changesets with 14 changes to 3 files
396 updating to branch stable
397 updating to branch stable
397 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
398 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
398
399
399 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
400 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
400
401
401 $ hg -R ua heads
402 $ hg -R ua heads
402 changeset: 13:0aae7cf88f0d
403 changeset: 13:0aae7cf88f0d
403 branch: stable
404 branch: stable
404 tag: tip
405 tag: tip
405 user: test
406 user: test
406 date: Thu Jan 01 00:00:00 1970 +0000
407 date: Thu Jan 01 00:00:00 1970 +0000
407 summary: another change for branch stable
408 summary: another change for branch stable
408
409
409 changeset: 10:a7949464abda
410 changeset: 10:a7949464abda
410 user: test
411 user: test
411 date: Thu Jan 01 00:00:00 1970 +0000
412 date: Thu Jan 01 00:00:00 1970 +0000
412 summary: test
413 summary: test
413
414
414
415
415 Branch 'stable' is checked out:
416 Branch 'stable' is checked out:
416
417
417 $ hg -R ua parents
418 $ hg -R ua parents
418 changeset: 13:0aae7cf88f0d
419 changeset: 13:0aae7cf88f0d
419 branch: stable
420 branch: stable
420 tag: tip
421 tag: tip
421 user: test
422 user: test
422 date: Thu Jan 01 00:00:00 1970 +0000
423 date: Thu Jan 01 00:00:00 1970 +0000
423 summary: another change for branch stable
424 summary: another change for branch stable
424
425
425
426
426 $ rm -r ua
427 $ rm -r ua
427
428
428
429
429 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
430 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
430 iterable in addbranchrevs()
431 iterable in addbranchrevs()
431
432
432 $ cat <<EOF > simpleclone.py
433 $ cat <<EOF > simpleclone.py
433 > from mercurial import ui, hg
434 > from mercurial import ui, hg
434 > myui = ui.ui()
435 > myui = ui.ui()
435 > repo = hg.repository(myui, 'a')
436 > repo = hg.repository(myui, 'a')
436 > hg.clone(myui, {}, repo, dest="ua")
437 > hg.clone(myui, {}, repo, dest="ua")
437 > EOF
438 > EOF
438
439
439 $ python simpleclone.py
440 $ python simpleclone.py
440 updating to branch default
441 updating to branch default
441 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
442 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
442
443
443 $ rm -r ua
444 $ rm -r ua
444
445
445 $ cat <<EOF > branchclone.py
446 $ cat <<EOF > branchclone.py
446 > from mercurial import ui, hg
447 > from mercurial import ui, hg
447 > myui = ui.ui()
448 > myui = ui.ui()
448 > repo = hg.repository(myui, 'a')
449 > repo = hg.repository(myui, 'a')
449 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
450 > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
450 > EOF
451 > EOF
451
452
452 $ python branchclone.py
453 $ python branchclone.py
453 adding changesets
454 adding changesets
454 adding manifests
455 adding manifests
455 adding file changes
456 adding file changes
456 added 14 changesets with 14 changes to 3 files
457 added 14 changesets with 14 changes to 3 files
457 updating to branch stable
458 updating to branch stable
458 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
459 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
459 $ rm -r ua
460 $ rm -r ua
@@ -1,129 +1,131 b''
1 # reproduce issue2264, issue2516
1 # reproduce issue2264, issue2516
2
2
3 create test repo
3 create test repo
4 $ cat <<EOF >> $HGRCPATH
4 $ cat <<EOF >> $HGRCPATH
5 > [extensions]
5 > [extensions]
6 > transplant =
6 > transplant =
7 > graphlog =
7 > graphlog =
8 > EOF
8 > EOF
9 $ hg init repo
9 $ hg init repo
10 $ cd repo
10 $ cd repo
11 $ template="{rev} {desc|firstline} [{branch}]\n"
11 $ template="{rev} {desc|firstline} [{branch}]\n"
12
12
13 # we need to start out with two changesets on the default branch
13 # we need to start out with two changesets on the default branch
14 # in order to avoid the cute little optimization where transplant
14 # in order to avoid the cute little optimization where transplant
15 # pulls rather than transplants
15 # pulls rather than transplants
16 add initial changesets
16 add initial changesets
17 $ echo feature1 > file1
17 $ echo feature1 > file1
18 $ hg ci -Am"feature 1"
18 $ hg ci -Am"feature 1"
19 adding file1
19 adding file1
20 $ echo feature2 >> file2
20 $ echo feature2 >> file2
21 $ hg ci -Am"feature 2"
21 $ hg ci -Am"feature 2"
22 adding file2
22 adding file2
23
23
24 # The changes to 'bugfix' are enough to show the bug: in fact, with only
24 # The changes to 'bugfix' are enough to show the bug: in fact, with only
25 # those changes, it's a very noisy crash ("RuntimeError: nothing
25 # those changes, it's a very noisy crash ("RuntimeError: nothing
26 # committed after transplant"). But if we modify a second file in the
26 # committed after transplant"). But if we modify a second file in the
27 # transplanted changesets, the bug is much more subtle: transplant
27 # transplanted changesets, the bug is much more subtle: transplant
28 # silently drops the second change to 'bugfix' on the floor, and we only
28 # silently drops the second change to 'bugfix' on the floor, and we only
29 # see it when we run 'hg status' after transplanting. Subtle data loss
29 # see it when we run 'hg status' after transplanting. Subtle data loss
30 # bugs are worse than crashes, so reproduce the subtle case here.
30 # bugs are worse than crashes, so reproduce the subtle case here.
31 commit bug fixes on bug fix branch
31 commit bug fixes on bug fix branch
32 $ hg branch fixes
32 $ hg branch fixes
33 marked working directory as branch fixes
33 marked working directory as branch fixes
34 (branches are permanent and global, did you want a bookmark?)
34 $ echo fix1 > bugfix
35 $ echo fix1 > bugfix
35 $ echo fix1 >> file1
36 $ echo fix1 >> file1
36 $ hg ci -Am"fix 1"
37 $ hg ci -Am"fix 1"
37 adding bugfix
38 adding bugfix
38 $ echo fix2 > bugfix
39 $ echo fix2 > bugfix
39 $ echo fix2 >> file1
40 $ echo fix2 >> file1
40 $ hg ci -Am"fix 2"
41 $ hg ci -Am"fix 2"
41 $ hg glog --template="$template"
42 $ hg glog --template="$template"
42 @ 3 fix 2 [fixes]
43 @ 3 fix 2 [fixes]
43 |
44 |
44 o 2 fix 1 [fixes]
45 o 2 fix 1 [fixes]
45 |
46 |
46 o 1 feature 2 [default]
47 o 1 feature 2 [default]
47 |
48 |
48 o 0 feature 1 [default]
49 o 0 feature 1 [default]
49
50
50 transplant bug fixes onto release branch
51 transplant bug fixes onto release branch
51 $ hg update 0
52 $ hg update 0
52 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
53 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
53 $ hg branch release
54 $ hg branch release
54 marked working directory as branch release
55 marked working directory as branch release
56 (branches are permanent and global, did you want a bookmark?)
55 $ hg transplant 2 3
57 $ hg transplant 2 3
56 applying [0-9a-f]{12} (re)
58 applying [0-9a-f]{12} (re)
57 [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
59 [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
58 applying [0-9a-f]{12} (re)
60 applying [0-9a-f]{12} (re)
59 [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
61 [0-9a-f]{12} transplanted to [0-9a-f]{12} (re)
60 $ hg glog --template="$template"
62 $ hg glog --template="$template"
61 @ 5 fix 2 [release]
63 @ 5 fix 2 [release]
62 |
64 |
63 o 4 fix 1 [release]
65 o 4 fix 1 [release]
64 |
66 |
65 | o 3 fix 2 [fixes]
67 | o 3 fix 2 [fixes]
66 | |
68 | |
67 | o 2 fix 1 [fixes]
69 | o 2 fix 1 [fixes]
68 | |
70 | |
69 | o 1 feature 2 [default]
71 | o 1 feature 2 [default]
70 |/
72 |/
71 o 0 feature 1 [default]
73 o 0 feature 1 [default]
72
74
73 $ hg status
75 $ hg status
74 $ hg status --rev 0:4
76 $ hg status --rev 0:4
75 M file1
77 M file1
76 A bugfix
78 A bugfix
77 $ hg status --rev 4:5
79 $ hg status --rev 4:5
78 M bugfix
80 M bugfix
79 M file1
81 M file1
80
82
81 now test that we fixed the bug for all scripts/extensions
83 now test that we fixed the bug for all scripts/extensions
82 $ cat > $TESTTMP/committwice.py <<__EOF__
84 $ cat > $TESTTMP/committwice.py <<__EOF__
83 > from mercurial import ui, hg, match, node
85 > from mercurial import ui, hg, match, node
84 > from time import sleep
86 > from time import sleep
85 >
87 >
86 > def replacebyte(fn, b):
88 > def replacebyte(fn, b):
87 > f = open(fn, "rb+")
89 > f = open(fn, "rb+")
88 > f.seek(0, 0)
90 > f.seek(0, 0)
89 > f.write(b)
91 > f.write(b)
90 > f.close()
92 > f.close()
91 >
93 >
92 > def printfiles(repo, rev):
94 > def printfiles(repo, rev):
93 > print "revision %s files: %s" % (rev, repo[rev].files())
95 > print "revision %s files: %s" % (rev, repo[rev].files())
94 >
96 >
95 > repo = hg.repository(ui.ui(), '.')
97 > repo = hg.repository(ui.ui(), '.')
96 > assert len(repo) == 6, \
98 > assert len(repo) == 6, \
97 > "initial: len(repo): %d, expected: 6" % len(repo)
99 > "initial: len(repo): %d, expected: 6" % len(repo)
98 >
100 >
99 > replacebyte("bugfix", "u")
101 > replacebyte("bugfix", "u")
100 > sleep(2)
102 > sleep(2)
101 > try:
103 > try:
102 > print "PRE: len(repo): %d" % len(repo)
104 > print "PRE: len(repo): %d" % len(repo)
103 > wlock = repo.wlock()
105 > wlock = repo.wlock()
104 > lock = repo.lock()
106 > lock = repo.lock()
105 > replacebyte("file1", "x")
107 > replacebyte("file1", "x")
106 > repo.commit(text="x", user="test", date=(0, 0))
108 > repo.commit(text="x", user="test", date=(0, 0))
107 > replacebyte("file1", "y")
109 > replacebyte("file1", "y")
108 > repo.commit(text="y", user="test", date=(0, 0))
110 > repo.commit(text="y", user="test", date=(0, 0))
109 > print "POST: len(repo): %d" % len(repo)
111 > print "POST: len(repo): %d" % len(repo)
110 > finally:
112 > finally:
111 > lock.release()
113 > lock.release()
112 > wlock.release()
114 > wlock.release()
113 > printfiles(repo, 6)
115 > printfiles(repo, 6)
114 > printfiles(repo, 7)
116 > printfiles(repo, 7)
115 > __EOF__
117 > __EOF__
116 $ $PYTHON $TESTTMP/committwice.py
118 $ $PYTHON $TESTTMP/committwice.py
117 PRE: len(repo): 6
119 PRE: len(repo): 6
118 POST: len(repo): 8
120 POST: len(repo): 8
119 revision 6 files: ['bugfix', 'file1']
121 revision 6 files: ['bugfix', 'file1']
120 revision 7 files: ['file1']
122 revision 7 files: ['file1']
121
123
122 Do a size-preserving modification outside of that process
124 Do a size-preserving modification outside of that process
123 $ echo abcd > bugfix
125 $ echo abcd > bugfix
124 $ hg status
126 $ hg status
125 M bugfix
127 M bugfix
126 $ hg log --template "{rev} {desc} {files}\n" -r5:
128 $ hg log --template "{rev} {desc} {files}\n" -r5:
127 5 fix 2 bugfix file1
129 5 fix 2 bugfix file1
128 6 x bugfix file1
130 6 x bugfix file1
129 7 y file1
131 7 y file1
@@ -1,84 +1,88 b''
1
1
2 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "convert = " >> $HGRCPATH
3 $ echo "convert = " >> $HGRCPATH
4 $ echo "[convert]" >> $HGRCPATH
4 $ echo "[convert]" >> $HGRCPATH
5 $ echo "hg.tagsbranch=0" >> $HGRCPATH
5 $ echo "hg.tagsbranch=0" >> $HGRCPATH
6 $ hg init source
6 $ hg init source
7 $ cd source
7 $ cd source
8 $ echo a > a
8 $ echo a > a
9 $ hg ci -qAm adda
9 $ hg ci -qAm adda
10
10
11 Add a merge with one parent in the same branch
11 Add a merge with one parent in the same branch
12
12
13 $ echo a >> a
13 $ echo a >> a
14 $ hg ci -qAm changea
14 $ hg ci -qAm changea
15 $ hg up -qC 0
15 $ hg up -qC 0
16 $ hg branch branch0
16 $ hg branch branch0
17 marked working directory as branch branch0
17 marked working directory as branch branch0
18 (branches are permanent and global, did you want a bookmark?)
18 $ echo b > b
19 $ echo b > b
19 $ hg ci -qAm addb
20 $ hg ci -qAm addb
20 $ hg up -qC
21 $ hg up -qC
21 $ hg merge default
22 $ hg merge default
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 (branch merge, don't forget to commit)
24 (branch merge, don't forget to commit)
24 $ hg ci -qm mergeab
25 $ hg ci -qm mergeab
25 $ hg tag -ql mergeab
26 $ hg tag -ql mergeab
26 $ cd ..
27 $ cd ..
27
28
28 Miss perl... sometimes
29 Miss perl... sometimes
29
30
30 $ cat > filter.py <<EOF
31 $ cat > filter.py <<EOF
31 > import sys, re
32 > import sys, re
32 >
33 >
33 > r = re.compile(r'^(?:\d+|pulling from)')
34 > r = re.compile(r'^(?:\d+|pulling from)')
34 > sys.stdout.writelines([l for l in sys.stdin if r.search(l)])
35 > sys.stdout.writelines([l for l in sys.stdin if r.search(l)])
35 > EOF
36 > EOF
36
37
37 convert
38 convert
38
39
39 $ hg convert -v --config convert.hg.clonebranches=1 source dest |
40 $ hg convert -v --config convert.hg.clonebranches=1 source dest |
40 > python filter.py
41 > python filter.py
41 3 adda
42 3 adda
42 2 changea
43 2 changea
43 1 addb
44 1 addb
44 pulling from default into branch0
45 pulling from default into branch0
45 1 changesets found
46 1 changesets found
46 0 mergeab
47 0 mergeab
47 pulling from default into branch0
48 pulling from default into branch0
48 1 changesets found
49 1 changesets found
49
50
50 Add a merge with both parents and child in different branches
51 Add a merge with both parents and child in different branches
51
52
52 $ cd source
53 $ cd source
53 $ hg branch branch1
54 $ hg branch branch1
54 marked working directory as branch branch1
55 marked working directory as branch branch1
56 (branches are permanent and global, did you want a bookmark?)
55 $ echo a > file1
57 $ echo a > file1
56 $ hg ci -qAm c1
58 $ hg ci -qAm c1
57 $ hg up -qC mergeab
59 $ hg up -qC mergeab
58 $ hg branch branch2
60 $ hg branch branch2
59 marked working directory as branch branch2
61 marked working directory as branch branch2
62 (branches are permanent and global, did you want a bookmark?)
60 $ echo a > file2
63 $ echo a > file2
61 $ hg ci -qAm c2
64 $ hg ci -qAm c2
62 $ hg merge branch1
65 $ hg merge branch1
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 (branch merge, don't forget to commit)
67 (branch merge, don't forget to commit)
65 $ hg branch branch3
68 $ hg branch branch3
66 marked working directory as branch branch3
69 marked working directory as branch branch3
70 (branches are permanent and global, did you want a bookmark?)
67 $ hg ci -qAm c3
71 $ hg ci -qAm c3
68 $ cd ..
72 $ cd ..
69
73
70 incremental conversion
74 incremental conversion
71
75
72 $ hg convert -v --config convert.hg.clonebranches=1 source dest |
76 $ hg convert -v --config convert.hg.clonebranches=1 source dest |
73 > python filter.py
77 > python filter.py
74 2 c1
78 2 c1
75 pulling from branch0 into branch1
79 pulling from branch0 into branch1
76 4 changesets found
80 4 changesets found
77 1 c2
81 1 c2
78 pulling from branch0 into branch2
82 pulling from branch0 into branch2
79 4 changesets found
83 4 changesets found
80 0 c3
84 0 c3
81 pulling from branch2 into branch3
85 pulling from branch2 into branch3
82 5 changesets found
86 5 changesets found
83 pulling from branch1 into branch3
87 pulling from branch1 into branch3
84 1 changesets found
88 1 changesets found
@@ -1,117 +1,119 b''
1
1
2 $ cat >> $HGRCPATH <<EOF
2 $ cat >> $HGRCPATH <<EOF
3 > [extensions]
3 > [extensions]
4 > convert=
4 > convert=
5 > graphlog=
5 > graphlog=
6 > EOF
6 > EOF
7 $ hg init t
7 $ hg init t
8 $ cd t
8 $ cd t
9 $ echo a >> a
9 $ echo a >> a
10 $ hg ci -Am a0 -d '1 0'
10 $ hg ci -Am a0 -d '1 0'
11 adding a
11 adding a
12 $ hg branch brancha
12 $ hg branch brancha
13 marked working directory as branch brancha
13 marked working directory as branch brancha
14 (branches are permanent and global, did you want a bookmark?)
14 $ echo a >> a
15 $ echo a >> a
15 $ hg ci -m a1 -d '2 0'
16 $ hg ci -m a1 -d '2 0'
16 $ echo a >> a
17 $ echo a >> a
17 $ hg ci -m a2 -d '3 0'
18 $ hg ci -m a2 -d '3 0'
18 $ echo a >> a
19 $ echo a >> a
19 $ hg ci -m a3 -d '4 0'
20 $ hg ci -m a3 -d '4 0'
20 $ hg up -C 0
21 $ hg up -C 0
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 $ hg branch branchb
23 $ hg branch branchb
23 marked working directory as branch branchb
24 marked working directory as branch branchb
25 (branches are permanent and global, did you want a bookmark?)
24 $ echo b >> b
26 $ echo b >> b
25 $ hg ci -Am b0 -d '6 0'
27 $ hg ci -Am b0 -d '6 0'
26 adding b
28 adding b
27 $ hg up -C brancha
29 $ hg up -C brancha
28 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
30 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
29 $ echo a >> a
31 $ echo a >> a
30 $ hg ci -m a4 -d '5 0'
32 $ hg ci -m a4 -d '5 0'
31 $ echo a >> a
33 $ echo a >> a
32 $ hg ci -m a5 -d '7 0'
34 $ hg ci -m a5 -d '7 0'
33 $ echo a >> a
35 $ echo a >> a
34 $ hg ci -m a6 -d '8 0'
36 $ hg ci -m a6 -d '8 0'
35 $ hg up -C branchb
37 $ hg up -C branchb
36 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
37 $ echo b >> b
39 $ echo b >> b
38 $ hg ci -m b1 -d '9 0'
40 $ hg ci -m b1 -d '9 0'
39 $ cd ..
41 $ cd ..
40
42
41 convert with datesort
43 convert with datesort
42
44
43 $ hg convert --datesort t t-datesort
45 $ hg convert --datesort t t-datesort
44 initializing destination t-datesort repository
46 initializing destination t-datesort repository
45 scanning source...
47 scanning source...
46 sorting...
48 sorting...
47 converting...
49 converting...
48 8 a0
50 8 a0
49 7 a1
51 7 a1
50 6 a2
52 6 a2
51 5 a3
53 5 a3
52 4 a4
54 4 a4
53 3 b0
55 3 b0
54 2 a5
56 2 a5
55 1 a6
57 1 a6
56 0 b1
58 0 b1
57
59
58 graph converted repo
60 graph converted repo
59
61
60 $ hg -R t-datesort glog --template '{rev} "{desc}"\n'
62 $ hg -R t-datesort glog --template '{rev} "{desc}"\n'
61 o 8 "b1"
63 o 8 "b1"
62 |
64 |
63 | o 7 "a6"
65 | o 7 "a6"
64 | |
66 | |
65 | o 6 "a5"
67 | o 6 "a5"
66 | |
68 | |
67 o | 5 "b0"
69 o | 5 "b0"
68 | |
70 | |
69 | o 4 "a4"
71 | o 4 "a4"
70 | |
72 | |
71 | o 3 "a3"
73 | o 3 "a3"
72 | |
74 | |
73 | o 2 "a2"
75 | o 2 "a2"
74 | |
76 | |
75 | o 1 "a1"
77 | o 1 "a1"
76 |/
78 |/
77 o 0 "a0"
79 o 0 "a0"
78
80
79
81
80 convert with datesort (default mode)
82 convert with datesort (default mode)
81
83
82 $ hg convert t t-sourcesort
84 $ hg convert t t-sourcesort
83 initializing destination t-sourcesort repository
85 initializing destination t-sourcesort repository
84 scanning source...
86 scanning source...
85 sorting...
87 sorting...
86 converting...
88 converting...
87 8 a0
89 8 a0
88 7 a1
90 7 a1
89 6 a2
91 6 a2
90 5 a3
92 5 a3
91 4 b0
93 4 b0
92 3 a4
94 3 a4
93 2 a5
95 2 a5
94 1 a6
96 1 a6
95 0 b1
97 0 b1
96
98
97 graph converted repo
99 graph converted repo
98
100
99 $ hg -R t-sourcesort glog --template '{rev} "{desc}"\n'
101 $ hg -R t-sourcesort glog --template '{rev} "{desc}"\n'
100 o 8 "b1"
102 o 8 "b1"
101 |
103 |
102 | o 7 "a6"
104 | o 7 "a6"
103 | |
105 | |
104 | o 6 "a5"
106 | o 6 "a5"
105 | |
107 | |
106 | o 5 "a4"
108 | o 5 "a4"
107 | |
109 | |
108 o | 4 "b0"
110 o | 4 "b0"
109 | |
111 | |
110 | o 3 "a3"
112 | o 3 "a3"
111 | |
113 | |
112 | o 2 "a2"
114 | o 2 "a2"
113 | |
115 | |
114 | o 1 "a1"
116 | o 1 "a1"
115 |/
117 |/
116 o 0 "a0"
118 o 0 "a0"
117
119
@@ -1,374 +1,377 b''
1
1
2 $ HGMERGE=true; export HGMERGE
2 $ HGMERGE=true; export HGMERGE
3 $ echo '[extensions]' >> $HGRCPATH
3 $ echo '[extensions]' >> $HGRCPATH
4 $ echo 'graphlog =' >> $HGRCPATH
4 $ echo 'graphlog =' >> $HGRCPATH
5 $ echo 'convert =' >> $HGRCPATH
5 $ echo 'convert =' >> $HGRCPATH
6 $ glog()
6 $ glog()
7 > {
7 > {
8 > hg glog --template '{rev} "{desc}" files: {files}\n' "$@"
8 > hg glog --template '{rev} "{desc}" files: {files}\n' "$@"
9 > }
9 > }
10 $ hg init source
10 $ hg init source
11 $ cd source
11 $ cd source
12 $ echo foo > foo
12 $ echo foo > foo
13 $ echo baz > baz
13 $ echo baz > baz
14 $ mkdir -p dir/subdir
14 $ mkdir -p dir/subdir
15 $ echo dir/file >> dir/file
15 $ echo dir/file >> dir/file
16 $ echo dir/file2 >> dir/file2
16 $ echo dir/file2 >> dir/file2
17 $ echo dir/file3 >> dir/file3 # to be corrupted in rev 0
17 $ echo dir/file3 >> dir/file3 # to be corrupted in rev 0
18 $ echo dir/subdir/file3 >> dir/subdir/file3
18 $ echo dir/subdir/file3 >> dir/subdir/file3
19 $ echo dir/subdir/file4 >> dir/subdir/file4
19 $ echo dir/subdir/file4 >> dir/subdir/file4
20 $ hg ci -d '0 0' -qAm '0: add foo baz dir/'
20 $ hg ci -d '0 0' -qAm '0: add foo baz dir/'
21 $ echo bar > bar
21 $ echo bar > bar
22 $ echo quux > quux
22 $ echo quux > quux
23 $ echo dir/file4 >> dir/file4 # to be corrupted in rev 1
23 $ echo dir/file4 >> dir/file4 # to be corrupted in rev 1
24 $ hg copy foo copied
24 $ hg copy foo copied
25 $ hg ci -d '1 0' -qAm '1: add bar quux; copy foo to copied'
25 $ hg ci -d '1 0' -qAm '1: add bar quux; copy foo to copied'
26 $ echo >> foo
26 $ echo >> foo
27 $ hg ci -d '2 0' -m '2: change foo'
27 $ hg ci -d '2 0' -m '2: change foo'
28 $ hg up -qC 1
28 $ hg up -qC 1
29 $ echo >> bar
29 $ echo >> bar
30 $ echo >> quux
30 $ echo >> quux
31 $ hg ci -d '3 0' -m '3: change bar quux'
31 $ hg ci -d '3 0' -m '3: change bar quux'
32 created new head
32 created new head
33 $ hg up -qC 2
33 $ hg up -qC 2
34 $ hg merge -qr 3
34 $ hg merge -qr 3
35 $ echo >> bar
35 $ echo >> bar
36 $ echo >> baz
36 $ echo >> baz
37 $ hg ci -d '4 0' -m '4: first merge; change bar baz'
37 $ hg ci -d '4 0' -m '4: first merge; change bar baz'
38 $ echo >> bar
38 $ echo >> bar
39 $ echo 1 >> baz
39 $ echo 1 >> baz
40 $ echo >> quux
40 $ echo >> quux
41 $ hg ci -d '5 0' -m '5: change bar baz quux'
41 $ hg ci -d '5 0' -m '5: change bar baz quux'
42 $ hg up -qC 4
42 $ hg up -qC 4
43 $ echo >> foo
43 $ echo >> foo
44 $ echo 2 >> baz
44 $ echo 2 >> baz
45 $ hg ci -d '6 0' -m '6: change foo baz'
45 $ hg ci -d '6 0' -m '6: change foo baz'
46 created new head
46 created new head
47 $ hg up -qC 5
47 $ hg up -qC 5
48 $ hg merge -qr 6
48 $ hg merge -qr 6
49 $ echo >> bar
49 $ echo >> bar
50 $ hg ci -d '7 0' -m '7: second merge; change bar'
50 $ hg ci -d '7 0' -m '7: second merge; change bar'
51 $ echo >> foo
51 $ echo >> foo
52 $ hg ci -m '8: change foo'
52 $ hg ci -m '8: change foo'
53 $ glog
53 $ glog
54 @ 8 "8: change foo" files: foo
54 @ 8 "8: change foo" files: foo
55 |
55 |
56 o 7 "7: second merge; change bar" files: bar baz
56 o 7 "7: second merge; change bar" files: bar baz
57 |\
57 |\
58 | o 6 "6: change foo baz" files: baz foo
58 | o 6 "6: change foo baz" files: baz foo
59 | |
59 | |
60 o | 5 "5: change bar baz quux" files: bar baz quux
60 o | 5 "5: change bar baz quux" files: bar baz quux
61 |/
61 |/
62 o 4 "4: first merge; change bar baz" files: bar baz
62 o 4 "4: first merge; change bar baz" files: bar baz
63 |\
63 |\
64 | o 3 "3: change bar quux" files: bar quux
64 | o 3 "3: change bar quux" files: bar quux
65 | |
65 | |
66 o | 2 "2: change foo" files: foo
66 o | 2 "2: change foo" files: foo
67 |/
67 |/
68 o 1 "1: add bar quux; copy foo to copied" files: bar copied dir/file4 quux
68 o 1 "1: add bar quux; copy foo to copied" files: bar copied dir/file4 quux
69 |
69 |
70 o 0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/file3 dir/subdir/file3 dir/subdir/file4 foo
70 o 0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/file3 dir/subdir/file3 dir/subdir/file4 foo
71
71
72
72
73 final file versions in this repo:
73 final file versions in this repo:
74
74
75 $ hg manifest --debug
75 $ hg manifest --debug
76 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
76 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
77 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
77 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
78 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
78 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
79 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir/file
79 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir/file
80 75e6d3f8328f5f6ace6bf10b98df793416a09dca 644 dir/file2
80 75e6d3f8328f5f6ace6bf10b98df793416a09dca 644 dir/file2
81 e96dce0bc6a217656a3a410e5e6bec2c4f42bf7c 644 dir/file3
81 e96dce0bc6a217656a3a410e5e6bec2c4f42bf7c 644 dir/file3
82 6edd55f559cdce67132b12ca09e09cee08b60442 644 dir/file4
82 6edd55f559cdce67132b12ca09e09cee08b60442 644 dir/file4
83 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir/subdir/file3
83 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir/subdir/file3
84 57a1c1511590f3de52874adfa04effe8a77d64af 644 dir/subdir/file4
84 57a1c1511590f3de52874adfa04effe8a77d64af 644 dir/subdir/file4
85 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
85 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
86 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
86 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
87 $ hg debugrename copied
87 $ hg debugrename copied
88 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
88 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
89
89
90 $ cd ..
90 $ cd ..
91 $ splitrepo()
91 $ splitrepo()
92 > {
92 > {
93 > msg="$1"
93 > msg="$1"
94 > files="$2"
94 > files="$2"
95 > opts=$3
95 > opts=$3
96 > echo "% $files: $msg"
96 > echo "% $files: $msg"
97 > prefix=`echo "$files" | sed -e 's/ /-/g'`
97 > prefix=`echo "$files" | sed -e 's/ /-/g'`
98 > fmap="$prefix.fmap"
98 > fmap="$prefix.fmap"
99 > repo="$prefix.repo"
99 > repo="$prefix.repo"
100 > for i in $files; do
100 > for i in $files; do
101 > echo "include $i" >> "$fmap"
101 > echo "include $i" >> "$fmap"
102 > done
102 > done
103 > hg -q convert $opts --filemap "$fmap" --datesort source "$repo"
103 > hg -q convert $opts --filemap "$fmap" --datesort source "$repo"
104 > hg up -q -R "$repo"
104 > hg up -q -R "$repo"
105 > glog -R "$repo"
105 > glog -R "$repo"
106 > hg -R "$repo" manifest --debug
106 > hg -R "$repo" manifest --debug
107 > }
107 > }
108 $ splitrepo 'skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd' foo
108 $ splitrepo 'skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd' foo
109 % foo: skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd
109 % foo: skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd
110 @ 3 "8: change foo" files: foo
110 @ 3 "8: change foo" files: foo
111 |
111 |
112 o 2 "6: change foo baz" files: foo
112 o 2 "6: change foo baz" files: foo
113 |
113 |
114 o 1 "2: change foo" files: foo
114 o 1 "2: change foo" files: foo
115 |
115 |
116 o 0 "0: add foo baz dir/" files: foo
116 o 0 "0: add foo baz dir/" files: foo
117
117
118 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
118 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
119 $ splitrepo 'merges are not merges anymore' bar
119 $ splitrepo 'merges are not merges anymore' bar
120 % bar: merges are not merges anymore
120 % bar: merges are not merges anymore
121 @ 4 "7: second merge; change bar" files: bar
121 @ 4 "7: second merge; change bar" files: bar
122 |
122 |
123 o 3 "5: change bar baz quux" files: bar
123 o 3 "5: change bar baz quux" files: bar
124 |
124 |
125 o 2 "4: first merge; change bar baz" files: bar
125 o 2 "4: first merge; change bar baz" files: bar
126 |
126 |
127 o 1 "3: change bar quux" files: bar
127 o 1 "3: change bar quux" files: bar
128 |
128 |
129 o 0 "1: add bar quux; copy foo to copied" files: bar
129 o 0 "1: add bar quux; copy foo to copied" files: bar
130
130
131 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
131 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
132 $ splitrepo '1st merge is not a merge anymore; 2nd still is' baz
132 $ splitrepo '1st merge is not a merge anymore; 2nd still is' baz
133 % baz: 1st merge is not a merge anymore; 2nd still is
133 % baz: 1st merge is not a merge anymore; 2nd still is
134 @ 4 "7: second merge; change bar" files: baz
134 @ 4 "7: second merge; change bar" files: baz
135 |\
135 |\
136 | o 3 "6: change foo baz" files: baz
136 | o 3 "6: change foo baz" files: baz
137 | |
137 | |
138 o | 2 "5: change bar baz quux" files: baz
138 o | 2 "5: change bar baz quux" files: baz
139 |/
139 |/
140 o 1 "4: first merge; change bar baz" files: baz
140 o 1 "4: first merge; change bar baz" files: baz
141 |
141 |
142 o 0 "0: add foo baz dir/" files: baz
142 o 0 "0: add foo baz dir/" files: baz
143
143
144 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
144 94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
145 $ splitrepo 'we add additional merges when they are interesting' 'foo quux'
145 $ splitrepo 'we add additional merges when they are interesting' 'foo quux'
146 % foo quux: we add additional merges when they are interesting
146 % foo quux: we add additional merges when they are interesting
147 @ 8 "8: change foo" files: foo
147 @ 8 "8: change foo" files: foo
148 |
148 |
149 o 7 "7: second merge; change bar" files:
149 o 7 "7: second merge; change bar" files:
150 |\
150 |\
151 | o 6 "6: change foo baz" files: foo
151 | o 6 "6: change foo baz" files: foo
152 | |
152 | |
153 o | 5 "5: change bar baz quux" files: quux
153 o | 5 "5: change bar baz quux" files: quux
154 |/
154 |/
155 o 4 "4: first merge; change bar baz" files:
155 o 4 "4: first merge; change bar baz" files:
156 |\
156 |\
157 | o 3 "3: change bar quux" files: quux
157 | o 3 "3: change bar quux" files: quux
158 | |
158 | |
159 o | 2 "2: change foo" files: foo
159 o | 2 "2: change foo" files: foo
160 |/
160 |/
161 o 1 "1: add bar quux; copy foo to copied" files: quux
161 o 1 "1: add bar quux; copy foo to copied" files: quux
162 |
162 |
163 o 0 "0: add foo baz dir/" files: foo
163 o 0 "0: add foo baz dir/" files: foo
164
164
165 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
165 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
166 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
166 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
167 $ splitrepo 'partial conversion' 'bar quux' '-r 3'
167 $ splitrepo 'partial conversion' 'bar quux' '-r 3'
168 % bar quux: partial conversion
168 % bar quux: partial conversion
169 @ 1 "3: change bar quux" files: bar quux
169 @ 1 "3: change bar quux" files: bar quux
170 |
170 |
171 o 0 "1: add bar quux; copy foo to copied" files: bar quux
171 o 0 "1: add bar quux; copy foo to copied" files: bar quux
172
172
173 b79105bedc55102f394e90a789c9c380117c1b4a 644 bar
173 b79105bedc55102f394e90a789c9c380117c1b4a 644 bar
174 db0421cc6b685a458c8d86c7d5c004f94429ea23 644 quux
174 db0421cc6b685a458c8d86c7d5c004f94429ea23 644 quux
175 $ splitrepo 'complete the partial conversion' 'bar quux'
175 $ splitrepo 'complete the partial conversion' 'bar quux'
176 % bar quux: complete the partial conversion
176 % bar quux: complete the partial conversion
177 @ 4 "7: second merge; change bar" files: bar
177 @ 4 "7: second merge; change bar" files: bar
178 |
178 |
179 o 3 "5: change bar baz quux" files: bar quux
179 o 3 "5: change bar baz quux" files: bar quux
180 |
180 |
181 o 2 "4: first merge; change bar baz" files: bar
181 o 2 "4: first merge; change bar baz" files: bar
182 |
182 |
183 o 1 "3: change bar quux" files: bar quux
183 o 1 "3: change bar quux" files: bar quux
184 |
184 |
185 o 0 "1: add bar quux; copy foo to copied" files: bar quux
185 o 0 "1: add bar quux; copy foo to copied" files: bar quux
186
186
187 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
187 9463f52fe115e377cf2878d4fc548117211063f2 644 bar
188 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
188 bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
189 $ rm -r foo.repo
189 $ rm -r foo.repo
190 $ splitrepo 'partial conversion' 'foo' '-r 3'
190 $ splitrepo 'partial conversion' 'foo' '-r 3'
191 % foo: partial conversion
191 % foo: partial conversion
192 @ 0 "0: add foo baz dir/" files: foo
192 @ 0 "0: add foo baz dir/" files: foo
193
193
194 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
194 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
195 $ splitrepo 'complete the partial conversion' 'foo'
195 $ splitrepo 'complete the partial conversion' 'foo'
196 % foo: complete the partial conversion
196 % foo: complete the partial conversion
197 @ 3 "8: change foo" files: foo
197 @ 3 "8: change foo" files: foo
198 |
198 |
199 o 2 "6: change foo baz" files: foo
199 o 2 "6: change foo baz" files: foo
200 |
200 |
201 o 1 "2: change foo" files: foo
201 o 1 "2: change foo" files: foo
202 |
202 |
203 o 0 "0: add foo baz dir/" files: foo
203 o 0 "0: add foo baz dir/" files: foo
204
204
205 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
205 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
206 $ splitrepo 'copied file; source not included in new repo' copied
206 $ splitrepo 'copied file; source not included in new repo' copied
207 % copied: copied file; source not included in new repo
207 % copied: copied file; source not included in new repo
208 @ 0 "1: add bar quux; copy foo to copied" files: copied
208 @ 0 "1: add bar quux; copy foo to copied" files: copied
209
209
210 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 copied
210 2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 copied
211 $ hg --cwd copied.repo debugrename copied
211 $ hg --cwd copied.repo debugrename copied
212 copied not renamed
212 copied not renamed
213 $ splitrepo 'copied file; source included in new repo' 'foo copied'
213 $ splitrepo 'copied file; source included in new repo' 'foo copied'
214 % foo copied: copied file; source included in new repo
214 % foo copied: copied file; source included in new repo
215 @ 4 "8: change foo" files: foo
215 @ 4 "8: change foo" files: foo
216 |
216 |
217 o 3 "6: change foo baz" files: foo
217 o 3 "6: change foo baz" files: foo
218 |
218 |
219 o 2 "2: change foo" files: foo
219 o 2 "2: change foo" files: foo
220 |
220 |
221 o 1 "1: add bar quux; copy foo to copied" files: copied
221 o 1 "1: add bar quux; copy foo to copied" files: copied
222 |
222 |
223 o 0 "0: add foo baz dir/" files: foo
223 o 0 "0: add foo baz dir/" files: foo
224
224
225 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
225 7711d36246cc83e61fb29cd6d4ef394c63f1ceaf 644 copied
226 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
226 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
227 $ hg --cwd foo-copied.repo debugrename copied
227 $ hg --cwd foo-copied.repo debugrename copied
228 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
228 copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
229 $ cat > renames.fmap <<EOF
229 $ cat > renames.fmap <<EOF
230 > include dir
230 > include dir
231 > exclude dir/file2
231 > exclude dir/file2
232 > rename dir dir2
232 > rename dir dir2
233 > include foo
233 > include foo
234 > include copied
234 > include copied
235 > rename foo foo2
235 > rename foo foo2
236 > rename copied copied2
236 > rename copied copied2
237 > exclude dir/subdir
237 > exclude dir/subdir
238 > include dir/subdir/file3
238 > include dir/subdir/file3
239 > EOF
239 > EOF
240 $ rm source/.hg/store/data/dir/file3.i
240 $ rm source/.hg/store/data/dir/file3.i
241 $ rm source/.hg/store/data/dir/file4.i
241 $ rm source/.hg/store/data/dir/file4.i
242 $ hg -q convert --filemap renames.fmap --datesort source dummydest
242 $ hg -q convert --filemap renames.fmap --datesort source dummydest
243 abort: data/dir/file3.i@e96dce0bc6a2: no match found!
243 abort: data/dir/file3.i@e96dce0bc6a2: no match found!
244 [255]
244 [255]
245 $ hg -q convert --filemap renames.fmap --datesort --config convert.hg.ignoreerrors=1 source renames.repo
245 $ hg -q convert --filemap renames.fmap --datesort --config convert.hg.ignoreerrors=1 source renames.repo
246 ignoring: data/dir/file3.i@e96dce0bc6a2: no match found
246 ignoring: data/dir/file3.i@e96dce0bc6a2: no match found
247 ignoring: data/dir/file4.i@6edd55f559cd: no match found
247 ignoring: data/dir/file4.i@6edd55f559cd: no match found
248 $ hg up -q -R renames.repo
248 $ hg up -q -R renames.repo
249 $ glog -R renames.repo
249 $ glog -R renames.repo
250 @ 4 "8: change foo" files: foo2
250 @ 4 "8: change foo" files: foo2
251 |
251 |
252 o 3 "6: change foo baz" files: foo2
252 o 3 "6: change foo baz" files: foo2
253 |
253 |
254 o 2 "2: change foo" files: foo2
254 o 2 "2: change foo" files: foo2
255 |
255 |
256 o 1 "1: add bar quux; copy foo to copied" files: copied2
256 o 1 "1: add bar quux; copy foo to copied" files: copied2
257 |
257 |
258 o 0 "0: add foo baz dir/" files: dir2/file dir2/subdir/file3 foo2
258 o 0 "0: add foo baz dir/" files: dir2/file dir2/subdir/file3 foo2
259
259
260 $ hg -R renames.repo manifest --debug
260 $ hg -R renames.repo manifest --debug
261 d43feacba7a4f1f2080dde4a4b985bd8a0236d46 644 copied2
261 d43feacba7a4f1f2080dde4a4b985bd8a0236d46 644 copied2
262 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir2/file
262 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir2/file
263 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir2/subdir/file3
263 5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir2/subdir/file3
264 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo2
264 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo2
265 $ hg --cwd renames.repo debugrename copied2
265 $ hg --cwd renames.repo debugrename copied2
266 copied2 renamed from foo2:2ed2a3912a0b24502043eae84ee4b279c18b90dd
266 copied2 renamed from foo2:2ed2a3912a0b24502043eae84ee4b279c18b90dd
267
267
268 copied:
268 copied:
269
269
270 $ hg --cwd source cat copied
270 $ hg --cwd source cat copied
271 foo
271 foo
272
272
273 copied2:
273 copied2:
274
274
275 $ hg --cwd renames.repo cat copied2
275 $ hg --cwd renames.repo cat copied2
276 foo
276 foo
277
277
278 filemap errors
278 filemap errors
279
279
280 $ cat > errors.fmap <<EOF
280 $ cat > errors.fmap <<EOF
281 > include dir/ # beware that comments changes error line numbers!
281 > include dir/ # beware that comments changes error line numbers!
282 > exclude /dir
282 > exclude /dir
283 > rename dir//dir /dir//dir/ "out of sync"
283 > rename dir//dir /dir//dir/ "out of sync"
284 > include
284 > include
285 > EOF
285 > EOF
286 $ hg -q convert --filemap errors.fmap source errors.repo
286 $ hg -q convert --filemap errors.fmap source errors.repo
287 errors.fmap:1: superfluous / in exclude 'dir/'
287 errors.fmap:1: superfluous / in exclude 'dir/'
288 errors.fmap:3: superfluous / in include '/dir'
288 errors.fmap:3: superfluous / in include '/dir'
289 errors.fmap:3: superfluous / in rename '/dir'
289 errors.fmap:3: superfluous / in rename '/dir'
290 errors.fmap:3: superfluous / in exclude 'dir//dir'
290 errors.fmap:3: superfluous / in exclude 'dir//dir'
291 errors.fmap:4: unknown directive 'out of sync'
291 errors.fmap:4: unknown directive 'out of sync'
292 errors.fmap:5: path to exclude is missing
292 errors.fmap:5: path to exclude is missing
293 abort: errors in filemap
293 abort: errors in filemap
294 [255]
294 [255]
295
295
296 test branch closing revision pruning if branch is pruned
296 test branch closing revision pruning if branch is pruned
297
297
298 $ hg init branchpruning
298 $ hg init branchpruning
299 $ cd branchpruning
299 $ cd branchpruning
300 $ hg branch foo
300 $ hg branch foo
301 marked working directory as branch foo
301 marked working directory as branch foo
302 (branches are permanent and global, did you want a bookmark?)
302 $ echo a > a
303 $ echo a > a
303 $ hg ci -Am adda
304 $ hg ci -Am adda
304 adding a
305 adding a
305 $ hg ci --close-branch -m closefoo
306 $ hg ci --close-branch -m closefoo
306 $ hg up 0
307 $ hg up 0
307 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
308 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
308 $ hg branch empty
309 $ hg branch empty
309 marked working directory as branch empty
310 marked working directory as branch empty
311 (branches are permanent and global, did you want a bookmark?)
310 $ hg ci -m emptybranch
312 $ hg ci -m emptybranch
311 $ hg ci --close-branch -m closeempty
313 $ hg ci --close-branch -m closeempty
312 $ hg up 0
314 $ hg up 0
313 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
315 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
314 $ hg branch default
316 $ hg branch default
315 marked working directory as branch default
317 marked working directory as branch default
318 (branches are permanent and global, did you want a bookmark?)
316 $ echo b > b
319 $ echo b > b
317 $ hg ci -Am addb
320 $ hg ci -Am addb
318 adding b
321 adding b
319 $ hg ci --close-branch -m closedefault
322 $ hg ci --close-branch -m closedefault
320 $ cat > filemap <<EOF
323 $ cat > filemap <<EOF
321 > include b
324 > include b
322 > EOF
325 > EOF
323 $ cd ..
326 $ cd ..
324 $ hg convert branchpruning branchpruning-hg1
327 $ hg convert branchpruning branchpruning-hg1
325 initializing destination branchpruning-hg1 repository
328 initializing destination branchpruning-hg1 repository
326 scanning source...
329 scanning source...
327 sorting...
330 sorting...
328 converting...
331 converting...
329 5 adda
332 5 adda
330 4 closefoo
333 4 closefoo
331 3 emptybranch
334 3 emptybranch
332 2 closeempty
335 2 closeempty
333 1 addb
336 1 addb
334 0 closedefault
337 0 closedefault
335 $ glog -R branchpruning-hg1
338 $ glog -R branchpruning-hg1
336 o 5 "closedefault" files:
339 o 5 "closedefault" files:
337 |
340 |
338 o 4 "addb" files: b
341 o 4 "addb" files: b
339 |
342 |
340 | o 3 "closeempty" files:
343 | o 3 "closeempty" files:
341 | |
344 | |
342 | o 2 "emptybranch" files:
345 | o 2 "emptybranch" files:
343 |/
346 |/
344 | o 1 "closefoo" files:
347 | o 1 "closefoo" files:
345 |/
348 |/
346 o 0 "adda" files: a
349 o 0 "adda" files: a
347
350
348
351
349 exercise incremental conversion at the same time
352 exercise incremental conversion at the same time
350
353
351 $ hg convert -r0 --filemap branchpruning/filemap branchpruning branchpruning-hg2
354 $ hg convert -r0 --filemap branchpruning/filemap branchpruning branchpruning-hg2
352 initializing destination branchpruning-hg2 repository
355 initializing destination branchpruning-hg2 repository
353 scanning source...
356 scanning source...
354 sorting...
357 sorting...
355 converting...
358 converting...
356 0 adda
359 0 adda
357 $ hg convert -r4 --filemap branchpruning/filemap branchpruning branchpruning-hg2
360 $ hg convert -r4 --filemap branchpruning/filemap branchpruning branchpruning-hg2
358 scanning source...
361 scanning source...
359 sorting...
362 sorting...
360 converting...
363 converting...
361 0 addb
364 0 addb
362 $ hg convert --filemap branchpruning/filemap branchpruning branchpruning-hg2
365 $ hg convert --filemap branchpruning/filemap branchpruning branchpruning-hg2
363 scanning source...
366 scanning source...
364 sorting...
367 sorting...
365 converting...
368 converting...
366 3 closefoo
369 3 closefoo
367 2 emptybranch
370 2 emptybranch
368 1 closeempty
371 1 closeempty
369 0 closedefault
372 0 closedefault
370 $ glog -R branchpruning-hg2
373 $ glog -R branchpruning-hg2
371 o 1 "closedefault" files:
374 o 1 "closedefault" files:
372 |
375 |
373 o 0 "addb" files: b
376 o 0 "addb" files: b
374
377
@@ -1,140 +1,143 b''
1 Test alignment of multibyte characters
1 Test alignment of multibyte characters
2
2
3 $ HGENCODING=utf-8
3 $ HGENCODING=utf-8
4 $ export HGENCODING
4 $ export HGENCODING
5 $ hg init t
5 $ hg init t
6 $ cd t
6 $ cd t
7 $ python << EOF
7 $ python << EOF
8 > # (byte, width) = (6, 4)
8 > # (byte, width) = (6, 4)
9 > s = "\xe7\x9f\xad\xe5\x90\x8d"
9 > s = "\xe7\x9f\xad\xe5\x90\x8d"
10 > # (byte, width) = (7, 7): odd width is good for alignment test
10 > # (byte, width) = (7, 7): odd width is good for alignment test
11 > m = "MIDDLE_"
11 > m = "MIDDLE_"
12 > # (byte, width) = (18, 12)
12 > # (byte, width) = (18, 12)
13 > l = "\xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d"
13 > l = "\xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d"
14 > f = file('s', 'w'); f.write(s); f.close()
14 > f = file('s', 'w'); f.write(s); f.close()
15 > f = file('m', 'w'); f.write(m); f.close()
15 > f = file('m', 'w'); f.write(m); f.close()
16 > f = file('l', 'w'); f.write(l); f.close()
16 > f = file('l', 'w'); f.write(l); f.close()
17 > # instant extension to show list of options
17 > # instant extension to show list of options
18 > f = file('showoptlist.py', 'w'); f.write("""# encoding: utf-8
18 > f = file('showoptlist.py', 'w'); f.write("""# encoding: utf-8
19 > def showoptlist(ui, repo, *pats, **opts):
19 > def showoptlist(ui, repo, *pats, **opts):
20 > '''dummy command to show option descriptions'''
20 > '''dummy command to show option descriptions'''
21 > return 0
21 > return 0
22 > cmdtable = {
22 > cmdtable = {
23 > 'showoptlist':
23 > 'showoptlist':
24 > (showoptlist,
24 > (showoptlist,
25 > [('s', 'opt1', '', 'short width' + ' %(s)s' * 8, '%(s)s'),
25 > [('s', 'opt1', '', 'short width' + ' %(s)s' * 8, '%(s)s'),
26 > ('m', 'opt2', '', 'middle width' + ' %(m)s' * 8, '%(m)s'),
26 > ('m', 'opt2', '', 'middle width' + ' %(m)s' * 8, '%(m)s'),
27 > ('l', 'opt3', '', 'long width' + ' %(l)s' * 8, '%(l)s')
27 > ('l', 'opt3', '', 'long width' + ' %(l)s' * 8, '%(l)s')
28 > ],
28 > ],
29 > ""
29 > ""
30 > )
30 > )
31 > }
31 > }
32 > """ % globals())
32 > """ % globals())
33 > f.close()
33 > f.close()
34 > EOF
34 > EOF
35 $ S=`cat s`
35 $ S=`cat s`
36 $ M=`cat m`
36 $ M=`cat m`
37 $ L=`cat l`
37 $ L=`cat l`
38
38
39 alignment of option descriptions in help
39 alignment of option descriptions in help
40
40
41 $ cat <<EOF > .hg/hgrc
41 $ cat <<EOF > .hg/hgrc
42 > [extensions]
42 > [extensions]
43 > ja_ext = `pwd`/showoptlist.py
43 > ja_ext = `pwd`/showoptlist.py
44 > EOF
44 > EOF
45
45
46 check alignment of option descriptions in help
46 check alignment of option descriptions in help
47
47
48 $ hg help showoptlist
48 $ hg help showoptlist
49 hg showoptlist
49 hg showoptlist
50
50
51 dummy command to show option descriptions
51 dummy command to show option descriptions
52
52
53 options:
53 options:
54
54
55 -s --opt1 \xe7\x9f\xad\xe5\x90\x8d short width \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d (esc)
55 -s --opt1 \xe7\x9f\xad\xe5\x90\x8d short width \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d \xe7\x9f\xad\xe5\x90\x8d (esc)
56 -m --opt2 MIDDLE_ middle width MIDDLE_ MIDDLE_ MIDDLE_ MIDDLE_ MIDDLE_
56 -m --opt2 MIDDLE_ middle width MIDDLE_ MIDDLE_ MIDDLE_ MIDDLE_ MIDDLE_
57 MIDDLE_ MIDDLE_ MIDDLE_
57 MIDDLE_ MIDDLE_ MIDDLE_
58 -l --opt3 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d long width \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
58 -l --opt3 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d long width \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
59 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
59 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
60 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
60 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
61
61
62 use "hg -v help showoptlist" to show more info
62 use "hg -v help showoptlist" to show more info
63
63
64
64
65 $ rm -f s; touch s
65 $ rm -f s; touch s
66 $ rm -f m; touch m
66 $ rm -f m; touch m
67 $ rm -f l; touch l
67 $ rm -f l; touch l
68
68
69 add files
69 add files
70
70
71 $ cp s $S
71 $ cp s $S
72 $ hg add $S
72 $ hg add $S
73 $ cp m $M
73 $ cp m $M
74 $ hg add $M
74 $ hg add $M
75 $ cp l $L
75 $ cp l $L
76 $ hg add $L
76 $ hg add $L
77
77
78 commit(1)
78 commit(1)
79
79
80 $ echo 'first line(1)' >> s; cp s $S
80 $ echo 'first line(1)' >> s; cp s $S
81 $ echo 'first line(2)' >> m; cp m $M
81 $ echo 'first line(2)' >> m; cp m $M
82 $ echo 'first line(3)' >> l; cp l $L
82 $ echo 'first line(3)' >> l; cp l $L
83 $ hg commit -m 'first commit' -u $S
83 $ hg commit -m 'first commit' -u $S
84
84
85 commit(2)
85 commit(2)
86
86
87 $ echo 'second line(1)' >> s; cp s $S
87 $ echo 'second line(1)' >> s; cp s $S
88 $ echo 'second line(2)' >> m; cp m $M
88 $ echo 'second line(2)' >> m; cp m $M
89 $ echo 'second line(3)' >> l; cp l $L
89 $ echo 'second line(3)' >> l; cp l $L
90 $ hg commit -m 'second commit' -u $M
90 $ hg commit -m 'second commit' -u $M
91
91
92 commit(3)
92 commit(3)
93
93
94 $ echo 'third line(1)' >> s; cp s $S
94 $ echo 'third line(1)' >> s; cp s $S
95 $ echo 'third line(2)' >> m; cp m $M
95 $ echo 'third line(2)' >> m; cp m $M
96 $ echo 'third line(3)' >> l; cp l $L
96 $ echo 'third line(3)' >> l; cp l $L
97 $ hg commit -m 'third commit' -u $L
97 $ hg commit -m 'third commit' -u $L
98
98
99 check alignment of user names in annotate
99 check alignment of user names in annotate
100
100
101 $ hg annotate -u $M
101 $ hg annotate -u $M
102 \xe7\x9f\xad\xe5\x90\x8d: first line(2) (esc)
102 \xe7\x9f\xad\xe5\x90\x8d: first line(2) (esc)
103 MIDDLE_: second line(2)
103 MIDDLE_: second line(2)
104 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d: third line(2) (esc)
104 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d: third line(2) (esc)
105
105
106 check alignment of filenames in diffstat
106 check alignment of filenames in diffstat
107
107
108 $ hg diff -c tip --stat
108 $ hg diff -c tip --stat
109 MIDDLE_ | 1 +
109 MIDDLE_ | 1 +
110 \xe7\x9f\xad\xe5\x90\x8d | 1 + (esc)
110 \xe7\x9f\xad\xe5\x90\x8d | 1 + (esc)
111 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d | 1 + (esc)
111 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d | 1 + (esc)
112 3 files changed, 3 insertions(+), 0 deletions(-)
112 3 files changed, 3 insertions(+), 0 deletions(-)
113
113
114 add branches/tags
114 add branches/tags
115
115
116 $ hg branch $S
116 $ hg branch $S
117 marked working directory as branch \xe7\x9f\xad\xe5\x90\x8d (esc)
117 marked working directory as branch \xe7\x9f\xad\xe5\x90\x8d (esc)
118 (branches are permanent and global, did you want a bookmark?)
118 $ hg tag $S
119 $ hg tag $S
119 $ hg branch $M
120 $ hg branch $M
120 marked working directory as branch MIDDLE_
121 marked working directory as branch MIDDLE_
122 (branches are permanent and global, did you want a bookmark?)
121 $ hg tag $M
123 $ hg tag $M
122 $ hg branch $L
124 $ hg branch $L
123 marked working directory as branch \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
125 marked working directory as branch \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d (esc)
126 (branches are permanent and global, did you want a bookmark?)
124 $ hg tag $L
127 $ hg tag $L
125
128
126 check alignment of branches
129 check alignment of branches
127
130
128 $ hg tags
131 $ hg tags
129 tip 5:d745ff46155b
132 tip 5:d745ff46155b
130 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d 4:9259be597f19 (esc)
133 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d 4:9259be597f19 (esc)
131 MIDDLE_ 3:b06c5b6def9e
134 MIDDLE_ 3:b06c5b6def9e
132 \xe7\x9f\xad\xe5\x90\x8d 2:64a70663cee8 (esc)
135 \xe7\x9f\xad\xe5\x90\x8d 2:64a70663cee8 (esc)
133
136
134 check alignment of tags
137 check alignment of tags
135
138
136 $ hg tags
139 $ hg tags
137 tip 5:d745ff46155b
140 tip 5:d745ff46155b
138 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d 4:9259be597f19 (esc)
141 \xe9\x95\xb7\xe3\x81\x84\xe9\x95\xb7\xe3\x81\x84\xe5\x90\x8d\xe5\x89\x8d 4:9259be597f19 (esc)
139 MIDDLE_ 3:b06c5b6def9e
142 MIDDLE_ 3:b06c5b6def9e
140 \xe7\x9f\xad\xe5\x90\x8d 2:64a70663cee8 (esc)
143 \xe7\x9f\xad\xe5\x90\x8d 2:64a70663cee8 (esc)
@@ -1,249 +1,250 b''
1 Test character encoding
1 Test character encoding
2
2
3 $ hg init t
3 $ hg init t
4 $ cd t
4 $ cd t
5
5
6 we need a repo with some legacy latin-1 changesets
6 we need a repo with some legacy latin-1 changesets
7
7
8 $ hg unbundle $TESTDIR/bundles/legacy-encoding.hg
8 $ hg unbundle $TESTDIR/bundles/legacy-encoding.hg
9 adding changesets
9 adding changesets
10 adding manifests
10 adding manifests
11 adding file changes
11 adding file changes
12 added 2 changesets with 2 changes to 1 files
12 added 2 changesets with 2 changes to 1 files
13 (run 'hg update' to get a working copy)
13 (run 'hg update' to get a working copy)
14 $ hg co
14 $ hg co
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 $ python << EOF
16 $ python << EOF
17 > f = file('latin-1', 'w'); f.write("latin-1 e' encoded: \xe9"); f.close()
17 > f = file('latin-1', 'w'); f.write("latin-1 e' encoded: \xe9"); f.close()
18 > f = file('utf-8', 'w'); f.write("utf-8 e' encoded: \xc3\xa9"); f.close()
18 > f = file('utf-8', 'w'); f.write("utf-8 e' encoded: \xc3\xa9"); f.close()
19 > f = file('latin-1-tag', 'w'); f.write("\xe9"); f.close()
19 > f = file('latin-1-tag', 'w'); f.write("\xe9"); f.close()
20 > EOF
20 > EOF
21
21
22 should fail with encoding error
22 should fail with encoding error
23
23
24 $ echo "plain old ascii" > a
24 $ echo "plain old ascii" > a
25 $ hg st
25 $ hg st
26 M a
26 M a
27 ? latin-1
27 ? latin-1
28 ? latin-1-tag
28 ? latin-1-tag
29 ? utf-8
29 ? utf-8
30 $ HGENCODING=ascii hg ci -l latin-1
30 $ HGENCODING=ascii hg ci -l latin-1
31 transaction abort!
31 transaction abort!
32 rollback completed
32 rollback completed
33 abort: decoding near ' encoded: \xe9': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)! (esc)
33 abort: decoding near ' encoded: \xe9': 'ascii' codec can't decode byte 0xe9 in position 20: ordinal not in range(128)! (esc)
34 [255]
34 [255]
35
35
36 these should work
36 these should work
37
37
38 $ echo "latin-1" > a
38 $ echo "latin-1" > a
39 $ HGENCODING=latin-1 hg ci -l latin-1
39 $ HGENCODING=latin-1 hg ci -l latin-1
40 $ echo "utf-8" > a
40 $ echo "utf-8" > a
41 $ HGENCODING=utf-8 hg ci -l utf-8
41 $ HGENCODING=utf-8 hg ci -l utf-8
42 $ HGENCODING=latin-1 hg tag `cat latin-1-tag`
42 $ HGENCODING=latin-1 hg tag `cat latin-1-tag`
43 $ HGENCODING=latin-1 hg branch `cat latin-1-tag`
43 $ HGENCODING=latin-1 hg branch `cat latin-1-tag`
44 marked working directory as branch \xe9 (esc)
44 marked working directory as branch \xe9 (esc)
45 (branches are permanent and global, did you want a bookmark?)
45 $ HGENCODING=latin-1 hg ci -m 'latin1 branch'
46 $ HGENCODING=latin-1 hg ci -m 'latin1 branch'
46 $ rm .hg/branch
47 $ rm .hg/branch
47
48
48 hg log (ascii)
49 hg log (ascii)
49
50
50 $ hg --encoding ascii log
51 $ hg --encoding ascii log
51 changeset: 5:a52c0692f24a
52 changeset: 5:a52c0692f24a
52 branch: ?
53 branch: ?
53 tag: tip
54 tag: tip
54 user: test
55 user: test
55 date: Thu Jan 01 00:00:00 1970 +0000
56 date: Thu Jan 01 00:00:00 1970 +0000
56 summary: latin1 branch
57 summary: latin1 branch
57
58
58 changeset: 4:94db611b4196
59 changeset: 4:94db611b4196
59 user: test
60 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
61 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: Added tag ? for changeset ca661e7520de
62 summary: Added tag ? for changeset ca661e7520de
62
63
63 changeset: 3:ca661e7520de
64 changeset: 3:ca661e7520de
64 tag: ?
65 tag: ?
65 user: test
66 user: test
66 date: Thu Jan 01 00:00:00 1970 +0000
67 date: Thu Jan 01 00:00:00 1970 +0000
67 summary: utf-8 e' encoded: ?
68 summary: utf-8 e' encoded: ?
68
69
69 changeset: 2:650c6f3d55dd
70 changeset: 2:650c6f3d55dd
70 user: test
71 user: test
71 date: Thu Jan 01 00:00:00 1970 +0000
72 date: Thu Jan 01 00:00:00 1970 +0000
72 summary: latin-1 e' encoded: ?
73 summary: latin-1 e' encoded: ?
73
74
74 changeset: 1:0e5b7e3f9c4a
75 changeset: 1:0e5b7e3f9c4a
75 user: test
76 user: test
76 date: Mon Jan 12 13:46:40 1970 +0000
77 date: Mon Jan 12 13:46:40 1970 +0000
77 summary: koi8-r: ????? = u'\u0440\u0442\u0443\u0442\u044c'
78 summary: koi8-r: ????? = u'\u0440\u0442\u0443\u0442\u044c'
78
79
79 changeset: 0:1e78a93102a3
80 changeset: 0:1e78a93102a3
80 user: test
81 user: test
81 date: Mon Jan 12 13:46:40 1970 +0000
82 date: Mon Jan 12 13:46:40 1970 +0000
82 summary: latin-1 e': ? = u'\xe9'
83 summary: latin-1 e': ? = u'\xe9'
83
84
84
85
85 hg log (latin-1)
86 hg log (latin-1)
86
87
87 $ hg --encoding latin-1 log
88 $ hg --encoding latin-1 log
88 changeset: 5:a52c0692f24a
89 changeset: 5:a52c0692f24a
89 branch: \xe9 (esc)
90 branch: \xe9 (esc)
90 tag: tip
91 tag: tip
91 user: test
92 user: test
92 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
93 summary: latin1 branch
94 summary: latin1 branch
94
95
95 changeset: 4:94db611b4196
96 changeset: 4:94db611b4196
96 user: test
97 user: test
97 date: Thu Jan 01 00:00:00 1970 +0000
98 date: Thu Jan 01 00:00:00 1970 +0000
98 summary: Added tag \xe9 for changeset ca661e7520de (esc)
99 summary: Added tag \xe9 for changeset ca661e7520de (esc)
99
100
100 changeset: 3:ca661e7520de
101 changeset: 3:ca661e7520de
101 tag: \xe9 (esc)
102 tag: \xe9 (esc)
102 user: test
103 user: test
103 date: Thu Jan 01 00:00:00 1970 +0000
104 date: Thu Jan 01 00:00:00 1970 +0000
104 summary: utf-8 e' encoded: \xe9 (esc)
105 summary: utf-8 e' encoded: \xe9 (esc)
105
106
106 changeset: 2:650c6f3d55dd
107 changeset: 2:650c6f3d55dd
107 user: test
108 user: test
108 date: Thu Jan 01 00:00:00 1970 +0000
109 date: Thu Jan 01 00:00:00 1970 +0000
109 summary: latin-1 e' encoded: \xe9 (esc)
110 summary: latin-1 e' encoded: \xe9 (esc)
110
111
111 changeset: 1:0e5b7e3f9c4a
112 changeset: 1:0e5b7e3f9c4a
112 user: test
113 user: test
113 date: Mon Jan 12 13:46:40 1970 +0000
114 date: Mon Jan 12 13:46:40 1970 +0000
114 summary: koi8-r: \xd2\xd4\xd5\xd4\xd8 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
115 summary: koi8-r: \xd2\xd4\xd5\xd4\xd8 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
115
116
116 changeset: 0:1e78a93102a3
117 changeset: 0:1e78a93102a3
117 user: test
118 user: test
118 date: Mon Jan 12 13:46:40 1970 +0000
119 date: Mon Jan 12 13:46:40 1970 +0000
119 summary: latin-1 e': \xe9 = u'\\xe9' (esc)
120 summary: latin-1 e': \xe9 = u'\\xe9' (esc)
120
121
121
122
122 hg log (utf-8)
123 hg log (utf-8)
123
124
124 $ hg --encoding utf-8 log
125 $ hg --encoding utf-8 log
125 changeset: 5:a52c0692f24a
126 changeset: 5:a52c0692f24a
126 branch: \xc3\xa9 (esc)
127 branch: \xc3\xa9 (esc)
127 tag: tip
128 tag: tip
128 user: test
129 user: test
129 date: Thu Jan 01 00:00:00 1970 +0000
130 date: Thu Jan 01 00:00:00 1970 +0000
130 summary: latin1 branch
131 summary: latin1 branch
131
132
132 changeset: 4:94db611b4196
133 changeset: 4:94db611b4196
133 user: test
134 user: test
134 date: Thu Jan 01 00:00:00 1970 +0000
135 date: Thu Jan 01 00:00:00 1970 +0000
135 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
136 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
136
137
137 changeset: 3:ca661e7520de
138 changeset: 3:ca661e7520de
138 tag: \xc3\xa9 (esc)
139 tag: \xc3\xa9 (esc)
139 user: test
140 user: test
140 date: Thu Jan 01 00:00:00 1970 +0000
141 date: Thu Jan 01 00:00:00 1970 +0000
141 summary: utf-8 e' encoded: \xc3\xa9 (esc)
142 summary: utf-8 e' encoded: \xc3\xa9 (esc)
142
143
143 changeset: 2:650c6f3d55dd
144 changeset: 2:650c6f3d55dd
144 user: test
145 user: test
145 date: Thu Jan 01 00:00:00 1970 +0000
146 date: Thu Jan 01 00:00:00 1970 +0000
146 summary: latin-1 e' encoded: \xc3\xa9 (esc)
147 summary: latin-1 e' encoded: \xc3\xa9 (esc)
147
148
148 changeset: 1:0e5b7e3f9c4a
149 changeset: 1:0e5b7e3f9c4a
149 user: test
150 user: test
150 date: Mon Jan 12 13:46:40 1970 +0000
151 date: Mon Jan 12 13:46:40 1970 +0000
151 summary: koi8-r: \xc3\x92\xc3\x94\xc3\x95\xc3\x94\xc3\x98 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
152 summary: koi8-r: \xc3\x92\xc3\x94\xc3\x95\xc3\x94\xc3\x98 = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
152
153
153 changeset: 0:1e78a93102a3
154 changeset: 0:1e78a93102a3
154 user: test
155 user: test
155 date: Mon Jan 12 13:46:40 1970 +0000
156 date: Mon Jan 12 13:46:40 1970 +0000
156 summary: latin-1 e': \xc3\xa9 = u'\\xe9' (esc)
157 summary: latin-1 e': \xc3\xa9 = u'\\xe9' (esc)
157
158
158
159
159 hg tags (ascii)
160 hg tags (ascii)
160
161
161 $ HGENCODING=ascii hg tags
162 $ HGENCODING=ascii hg tags
162 tip 5:a52c0692f24a
163 tip 5:a52c0692f24a
163 ? 3:ca661e7520de
164 ? 3:ca661e7520de
164
165
165 hg tags (latin-1)
166 hg tags (latin-1)
166
167
167 $ HGENCODING=latin-1 hg tags
168 $ HGENCODING=latin-1 hg tags
168 tip 5:a52c0692f24a
169 tip 5:a52c0692f24a
169 \xe9 3:ca661e7520de (esc)
170 \xe9 3:ca661e7520de (esc)
170
171
171 hg tags (utf-8)
172 hg tags (utf-8)
172
173
173 $ HGENCODING=utf-8 hg tags
174 $ HGENCODING=utf-8 hg tags
174 tip 5:a52c0692f24a
175 tip 5:a52c0692f24a
175 \xc3\xa9 3:ca661e7520de (esc)
176 \xc3\xa9 3:ca661e7520de (esc)
176
177
177 hg branches (ascii)
178 hg branches (ascii)
178
179
179 $ HGENCODING=ascii hg branches
180 $ HGENCODING=ascii hg branches
180 ? 5:a52c0692f24a
181 ? 5:a52c0692f24a
181 default 4:94db611b4196 (inactive)
182 default 4:94db611b4196 (inactive)
182
183
183 hg branches (latin-1)
184 hg branches (latin-1)
184
185
185 $ HGENCODING=latin-1 hg branches
186 $ HGENCODING=latin-1 hg branches
186 \xe9 5:a52c0692f24a (esc)
187 \xe9 5:a52c0692f24a (esc)
187 default 4:94db611b4196 (inactive)
188 default 4:94db611b4196 (inactive)
188
189
189 hg branches (utf-8)
190 hg branches (utf-8)
190
191
191 $ HGENCODING=utf-8 hg branches
192 $ HGENCODING=utf-8 hg branches
192 \xc3\xa9 5:a52c0692f24a (esc)
193 \xc3\xa9 5:a52c0692f24a (esc)
193 default 4:94db611b4196 (inactive)
194 default 4:94db611b4196 (inactive)
194 $ echo '[ui]' >> .hg/hgrc
195 $ echo '[ui]' >> .hg/hgrc
195 $ echo 'fallbackencoding = koi8-r' >> .hg/hgrc
196 $ echo 'fallbackencoding = koi8-r' >> .hg/hgrc
196
197
197 hg log (utf-8)
198 hg log (utf-8)
198
199
199 $ HGENCODING=utf-8 hg log
200 $ HGENCODING=utf-8 hg log
200 changeset: 5:a52c0692f24a
201 changeset: 5:a52c0692f24a
201 branch: \xc3\xa9 (esc)
202 branch: \xc3\xa9 (esc)
202 tag: tip
203 tag: tip
203 user: test
204 user: test
204 date: Thu Jan 01 00:00:00 1970 +0000
205 date: Thu Jan 01 00:00:00 1970 +0000
205 summary: latin1 branch
206 summary: latin1 branch
206
207
207 changeset: 4:94db611b4196
208 changeset: 4:94db611b4196
208 user: test
209 user: test
209 date: Thu Jan 01 00:00:00 1970 +0000
210 date: Thu Jan 01 00:00:00 1970 +0000
210 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
211 summary: Added tag \xc3\xa9 for changeset ca661e7520de (esc)
211
212
212 changeset: 3:ca661e7520de
213 changeset: 3:ca661e7520de
213 tag: \xc3\xa9 (esc)
214 tag: \xc3\xa9 (esc)
214 user: test
215 user: test
215 date: Thu Jan 01 00:00:00 1970 +0000
216 date: Thu Jan 01 00:00:00 1970 +0000
216 summary: utf-8 e' encoded: \xc3\xa9 (esc)
217 summary: utf-8 e' encoded: \xc3\xa9 (esc)
217
218
218 changeset: 2:650c6f3d55dd
219 changeset: 2:650c6f3d55dd
219 user: test
220 user: test
220 date: Thu Jan 01 00:00:00 1970 +0000
221 date: Thu Jan 01 00:00:00 1970 +0000
221 summary: latin-1 e' encoded: \xc3\xa9 (esc)
222 summary: latin-1 e' encoded: \xc3\xa9 (esc)
222
223
223 changeset: 1:0e5b7e3f9c4a
224 changeset: 1:0e5b7e3f9c4a
224 user: test
225 user: test
225 date: Mon Jan 12 13:46:40 1970 +0000
226 date: Mon Jan 12 13:46:40 1970 +0000
226 summary: koi8-r: \xd1\x80\xd1\x82\xd1\x83\xd1\x82\xd1\x8c = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
227 summary: koi8-r: \xd1\x80\xd1\x82\xd1\x83\xd1\x82\xd1\x8c = u'\\u0440\\u0442\\u0443\\u0442\\u044c' (esc)
227
228
228 changeset: 0:1e78a93102a3
229 changeset: 0:1e78a93102a3
229 user: test
230 user: test
230 date: Mon Jan 12 13:46:40 1970 +0000
231 date: Mon Jan 12 13:46:40 1970 +0000
231 summary: latin-1 e': \xd0\x98 = u'\\xe9' (esc)
232 summary: latin-1 e': \xd0\x98 = u'\\xe9' (esc)
232
233
233
234
234 hg log (dolphin)
235 hg log (dolphin)
235
236
236 $ HGENCODING=dolphin hg log
237 $ HGENCODING=dolphin hg log
237 abort: unknown encoding: dolphin, please check your locale settings
238 abort: unknown encoding: dolphin, please check your locale settings
238 [255]
239 [255]
239 $ HGENCODING=ascii hg branch `cat latin-1-tag`
240 $ HGENCODING=ascii hg branch `cat latin-1-tag`
240 abort: decoding near '\xe9': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)! (esc)
241 abort: decoding near '\xe9': 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)! (esc)
241 [255]
242 [255]
242 $ cp latin-1-tag .hg/branch
243 $ cp latin-1-tag .hg/branch
243 $ HGENCODING=latin-1 hg ci -m 'auto-promote legacy name'
244 $ HGENCODING=latin-1 hg ci -m 'auto-promote legacy name'
244
245
245 Test roundtrip encoding of lookup tables when not using UTF-8 (issue2763)
246 Test roundtrip encoding of lookup tables when not using UTF-8 (issue2763)
246
247
247 $ HGENCODING=latin-1 hg up `cat latin-1-tag`
248 $ HGENCODING=latin-1 hg up `cat latin-1-tag`
248 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
249
250
@@ -1,405 +1,410 b''
1 $ echo "[extensions]" >> $HGRCPATH
1 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "fetch=" >> $HGRCPATH
2 $ echo "fetch=" >> $HGRCPATH
3
3
4 test fetch with default branches only
4 test fetch with default branches only
5
5
6 $ hg init a
6 $ hg init a
7 $ echo a > a/a
7 $ echo a > a/a
8 $ hg --cwd a commit -Ama
8 $ hg --cwd a commit -Ama
9 adding a
9 adding a
10 $ hg clone a b
10 $ hg clone a b
11 updating to branch default
11 updating to branch default
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 $ hg clone a c
13 $ hg clone a c
14 updating to branch default
14 updating to branch default
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 $ echo b > a/b
16 $ echo b > a/b
17 $ hg --cwd a commit -Amb
17 $ hg --cwd a commit -Amb
18 adding b
18 adding b
19 $ hg --cwd a parents -q
19 $ hg --cwd a parents -q
20 1:d2ae7f538514
20 1:d2ae7f538514
21
21
22 should pull one change
22 should pull one change
23
23
24 $ hg --cwd b fetch ../a
24 $ hg --cwd b fetch ../a
25 pulling from ../a
25 pulling from ../a
26 searching for changes
26 searching for changes
27 adding changesets
27 adding changesets
28 adding manifests
28 adding manifests
29 adding file changes
29 adding file changes
30 added 1 changesets with 1 changes to 1 files
30 added 1 changesets with 1 changes to 1 files
31 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
31 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
32 $ hg --cwd b parents -q
32 $ hg --cwd b parents -q
33 1:d2ae7f538514
33 1:d2ae7f538514
34 $ echo c > c/c
34 $ echo c > c/c
35 $ hg --cwd c commit -Amc
35 $ hg --cwd c commit -Amc
36 adding c
36 adding c
37 $ hg clone c d
37 $ hg clone c d
38 updating to branch default
38 updating to branch default
39 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
39 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
40 $ hg clone c e
40 $ hg clone c e
41 updating to branch default
41 updating to branch default
42 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
43
43
44 We cannot use the default commit message if fetching from a local
44 We cannot use the default commit message if fetching from a local
45 repo, because the path of the repo will be included in the commit
45 repo, because the path of the repo will be included in the commit
46 message, making every commit appear different.
46 message, making every commit appear different.
47 should merge c into a
47 should merge c into a
48
48
49 $ hg --cwd c fetch -d '0 0' -m 'automated merge' ../a
49 $ hg --cwd c fetch -d '0 0' -m 'automated merge' ../a
50 pulling from ../a
50 pulling from ../a
51 searching for changes
51 searching for changes
52 adding changesets
52 adding changesets
53 adding manifests
53 adding manifests
54 adding file changes
54 adding file changes
55 added 1 changesets with 1 changes to 1 files (+1 heads)
55 added 1 changesets with 1 changes to 1 files (+1 heads)
56 updating to 2:d2ae7f538514
56 updating to 2:d2ae7f538514
57 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
57 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
58 merging with 1:d36c0562f908
58 merging with 1:d36c0562f908
59 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 new changeset 3:a323a0c43ec4 merges remote changes with local
60 new changeset 3:a323a0c43ec4 merges remote changes with local
61 $ ls c
61 $ ls c
62 a
62 a
63 b
63 b
64 c
64 c
65 $ hg --cwd a serve -a localhost -p $HGPORT -d --pid-file=hg.pid
65 $ hg --cwd a serve -a localhost -p $HGPORT -d --pid-file=hg.pid
66 $ cat a/hg.pid >> "$DAEMON_PIDS"
66 $ cat a/hg.pid >> "$DAEMON_PIDS"
67
67
68 fetch over http, no auth
68 fetch over http, no auth
69
69
70 $ hg --cwd d fetch http://localhost:$HGPORT/
70 $ hg --cwd d fetch http://localhost:$HGPORT/
71 pulling from http://localhost:$HGPORT/
71 pulling from http://localhost:$HGPORT/
72 searching for changes
72 searching for changes
73 adding changesets
73 adding changesets
74 adding manifests
74 adding manifests
75 adding file changes
75 adding file changes
76 added 1 changesets with 1 changes to 1 files (+1 heads)
76 added 1 changesets with 1 changes to 1 files (+1 heads)
77 updating to 2:d2ae7f538514
77 updating to 2:d2ae7f538514
78 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
78 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
79 merging with 1:d36c0562f908
79 merging with 1:d36c0562f908
80 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 new changeset 3:* merges remote changes with local (glob)
81 new changeset 3:* merges remote changes with local (glob)
82 $ hg --cwd d tip --template '{desc}\n'
82 $ hg --cwd d tip --template '{desc}\n'
83 Automated merge with http://localhost:$HGPORT/
83 Automated merge with http://localhost:$HGPORT/
84
84
85 fetch over http with auth (should be hidden in desc)
85 fetch over http with auth (should be hidden in desc)
86
86
87 $ hg --cwd e fetch http://user:password@localhost:$HGPORT/
87 $ hg --cwd e fetch http://user:password@localhost:$HGPORT/
88 pulling from http://user:***@localhost:$HGPORT/
88 pulling from http://user:***@localhost:$HGPORT/
89 searching for changes
89 searching for changes
90 adding changesets
90 adding changesets
91 adding manifests
91 adding manifests
92 adding file changes
92 adding file changes
93 added 1 changesets with 1 changes to 1 files (+1 heads)
93 added 1 changesets with 1 changes to 1 files (+1 heads)
94 updating to 2:d2ae7f538514
94 updating to 2:d2ae7f538514
95 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
95 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
96 merging with 1:d36c0562f908
96 merging with 1:d36c0562f908
97 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
98 new changeset 3:* merges remote changes with local (glob)
98 new changeset 3:* merges remote changes with local (glob)
99 $ hg --cwd e tip --template '{desc}\n'
99 $ hg --cwd e tip --template '{desc}\n'
100 Automated merge with http://localhost:$HGPORT/
100 Automated merge with http://localhost:$HGPORT/
101 $ hg clone a f
101 $ hg clone a f
102 updating to branch default
102 updating to branch default
103 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
103 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
104 $ hg clone a g
104 $ hg clone a g
105 updating to branch default
105 updating to branch default
106 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
106 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 $ echo f > f/f
107 $ echo f > f/f
108 $ hg --cwd f ci -Amf
108 $ hg --cwd f ci -Amf
109 adding f
109 adding f
110 $ echo g > g/g
110 $ echo g > g/g
111 $ hg --cwd g ci -Amg
111 $ hg --cwd g ci -Amg
112 adding g
112 adding g
113 $ hg clone -q f h
113 $ hg clone -q f h
114 $ hg clone -q g i
114 $ hg clone -q g i
115
115
116 should merge f into g
116 should merge f into g
117
117
118 $ hg --cwd g fetch -d '0 0' --switch -m 'automated merge' ../f
118 $ hg --cwd g fetch -d '0 0' --switch -m 'automated merge' ../f
119 pulling from ../f
119 pulling from ../f
120 searching for changes
120 searching for changes
121 adding changesets
121 adding changesets
122 adding manifests
122 adding manifests
123 adding file changes
123 adding file changes
124 added 1 changesets with 1 changes to 1 files (+1 heads)
124 added 1 changesets with 1 changes to 1 files (+1 heads)
125 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
125 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 merging with 3:6343ca3eff20
126 merging with 3:6343ca3eff20
127 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
128 new changeset 4:f7faa0b7d3c6 merges remote changes with local
128 new changeset 4:f7faa0b7d3c6 merges remote changes with local
129 $ rm i/g
129 $ rm i/g
130
130
131 should abort, because i is modified
131 should abort, because i is modified
132
132
133 $ hg --cwd i fetch ../h
133 $ hg --cwd i fetch ../h
134 abort: working directory is missing some files
134 abort: working directory is missing some files
135 [255]
135 [255]
136
136
137 test fetch with named branches
137 test fetch with named branches
138
138
139 $ hg init nbase
139 $ hg init nbase
140 $ echo base > nbase/a
140 $ echo base > nbase/a
141 $ hg -R nbase ci -Am base
141 $ hg -R nbase ci -Am base
142 adding a
142 adding a
143 $ hg -R nbase branch a
143 $ hg -R nbase branch a
144 marked working directory as branch a
144 marked working directory as branch a
145 (branches are permanent and global, did you want a bookmark?)
145 $ echo a > nbase/a
146 $ echo a > nbase/a
146 $ hg -R nbase ci -m a
147 $ hg -R nbase ci -m a
147 $ hg -R nbase up -C 0
148 $ hg -R nbase up -C 0
148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 $ hg -R nbase branch b
150 $ hg -R nbase branch b
150 marked working directory as branch b
151 marked working directory as branch b
152 (branches are permanent and global, did you want a bookmark?)
151 $ echo b > nbase/b
153 $ echo b > nbase/b
152 $ hg -R nbase ci -Am b
154 $ hg -R nbase ci -Am b
153 adding b
155 adding b
154
156
155 pull in change on foreign branch
157 pull in change on foreign branch
156
158
157 $ hg clone nbase n1
159 $ hg clone nbase n1
158 updating to branch default
160 updating to branch default
159 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 $ hg clone nbase n2
162 $ hg clone nbase n2
161 updating to branch default
163 updating to branch default
162 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 $ hg -R n1 up -C a
165 $ hg -R n1 up -C a
164 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
166 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
165 $ echo aa > n1/a
167 $ echo aa > n1/a
166 $ hg -R n1 ci -m a1
168 $ hg -R n1 ci -m a1
167 $ hg -R n2 up -C b
169 $ hg -R n2 up -C b
168 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
170 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
169 $ hg -R n2 fetch -m 'merge' n1
171 $ hg -R n2 fetch -m 'merge' n1
170 pulling from n1
172 pulling from n1
171 searching for changes
173 searching for changes
172 adding changesets
174 adding changesets
173 adding manifests
175 adding manifests
174 adding file changes
176 adding file changes
175 added 1 changesets with 1 changes to 1 files
177 added 1 changesets with 1 changes to 1 files
176
178
177 parent should be 2 (no automatic update)
179 parent should be 2 (no automatic update)
178
180
179 $ hg -R n2 parents --template '{rev}\n'
181 $ hg -R n2 parents --template '{rev}\n'
180 2
182 2
181 $ rm -fr n1 n2
183 $ rm -fr n1 n2
182
184
183 pull in changes on both foreign and local branches
185 pull in changes on both foreign and local branches
184
186
185 $ hg clone nbase n1
187 $ hg clone nbase n1
186 updating to branch default
188 updating to branch default
187 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
189 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
188 $ hg clone nbase n2
190 $ hg clone nbase n2
189 updating to branch default
191 updating to branch default
190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 $ hg -R n1 up -C a
193 $ hg -R n1 up -C a
192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
194 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 $ echo aa > n1/a
195 $ echo aa > n1/a
194 $ hg -R n1 ci -m a1
196 $ hg -R n1 ci -m a1
195 $ hg -R n1 up -C b
197 $ hg -R n1 up -C b
196 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
198 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
197 $ echo bb > n1/b
199 $ echo bb > n1/b
198 $ hg -R n1 ci -m b1
200 $ hg -R n1 ci -m b1
199 $ hg -R n2 up -C b
201 $ hg -R n2 up -C b
200 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
202 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
201 $ hg -R n2 fetch -m 'merge' n1
203 $ hg -R n2 fetch -m 'merge' n1
202 pulling from n1
204 pulling from n1
203 searching for changes
205 searching for changes
204 adding changesets
206 adding changesets
205 adding manifests
207 adding manifests
206 adding file changes
208 adding file changes
207 added 2 changesets with 2 changes to 2 files
209 added 2 changesets with 2 changes to 2 files
208 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
209
211
210 parent should be 4 (fast forward)
212 parent should be 4 (fast forward)
211
213
212 $ hg -R n2 parents --template '{rev}\n'
214 $ hg -R n2 parents --template '{rev}\n'
213 4
215 4
214 $ rm -fr n1 n2
216 $ rm -fr n1 n2
215
217
216 pull changes on foreign (2 new heads) and local (1 new head) branches
218 pull changes on foreign (2 new heads) and local (1 new head) branches
217 with a local change
219 with a local change
218
220
219 $ hg clone nbase n1
221 $ hg clone nbase n1
220 updating to branch default
222 updating to branch default
221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
223 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 $ hg clone nbase n2
224 $ hg clone nbase n2
223 updating to branch default
225 updating to branch default
224 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
225 $ hg -R n1 up -C a
227 $ hg -R n1 up -C a
226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
228 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
227 $ echo a1 > n1/a
229 $ echo a1 > n1/a
228 $ hg -R n1 ci -m a1
230 $ hg -R n1 ci -m a1
229 $ hg -R n1 up -C b
231 $ hg -R n1 up -C b
230 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
232 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
231 $ echo bb > n1/b
233 $ echo bb > n1/b
232 $ hg -R n1 ci -m b1
234 $ hg -R n1 ci -m b1
233 $ hg -R n1 up -C 1
235 $ hg -R n1 up -C 1
234 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
236 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
235 $ echo a2 > n1/a
237 $ echo a2 > n1/a
236 $ hg -R n1 ci -m a2
238 $ hg -R n1 ci -m a2
237 created new head
239 created new head
238 $ hg -R n2 up -C b
240 $ hg -R n2 up -C b
239 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
241 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
240 $ echo change >> n2/c
242 $ echo change >> n2/c
241 $ hg -R n2 ci -A -m local
243 $ hg -R n2 ci -A -m local
242 adding c
244 adding c
243 $ hg -R n2 fetch -d '0 0' -m 'merge' n1
245 $ hg -R n2 fetch -d '0 0' -m 'merge' n1
244 pulling from n1
246 pulling from n1
245 searching for changes
247 searching for changes
246 adding changesets
248 adding changesets
247 adding manifests
249 adding manifests
248 adding file changes
250 adding file changes
249 added 3 changesets with 3 changes to 2 files (+2 heads)
251 added 3 changesets with 3 changes to 2 files (+2 heads)
250 updating to 5:3c4a837a864f
252 updating to 5:3c4a837a864f
251 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
253 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
252 merging with 3:1267f84a9ea5
254 merging with 3:1267f84a9ea5
253 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
254 new changeset 7:2cf2a1261f21 merges remote changes with local
256 new changeset 7:2cf2a1261f21 merges remote changes with local
255
257
256 parent should be 7 (new merge changeset)
258 parent should be 7 (new merge changeset)
257
259
258 $ hg -R n2 parents --template '{rev}\n'
260 $ hg -R n2 parents --template '{rev}\n'
259 7
261 7
260 $ rm -fr n1 n2
262 $ rm -fr n1 n2
261
263
262 pull in changes on foreign (merge of local branch) and local (2 new
264 pull in changes on foreign (merge of local branch) and local (2 new
263 heads) with a local change
265 heads) with a local change
264
266
265 $ hg clone nbase n1
267 $ hg clone nbase n1
266 updating to branch default
268 updating to branch default
267 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
269 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
268 $ hg clone nbase n2
270 $ hg clone nbase n2
269 updating to branch default
271 updating to branch default
270 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
272 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
271 $ hg -R n1 up -C a
273 $ hg -R n1 up -C a
272 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
274 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
273 $ hg -R n1 merge b
275 $ hg -R n1 merge b
274 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
275 (branch merge, don't forget to commit)
277 (branch merge, don't forget to commit)
276 $ hg -R n1 ci -m merge
278 $ hg -R n1 ci -m merge
277 $ hg -R n1 up -C 2
279 $ hg -R n1 up -C 2
278 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 $ echo c > n1/a
281 $ echo c > n1/a
280 $ hg -R n1 ci -m c
282 $ hg -R n1 ci -m c
281 $ hg -R n1 up -C 2
283 $ hg -R n1 up -C 2
282 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
284 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
283 $ echo cc > n1/a
285 $ echo cc > n1/a
284 $ hg -R n1 ci -m cc
286 $ hg -R n1 ci -m cc
285 created new head
287 created new head
286 $ hg -R n2 up -C b
288 $ hg -R n2 up -C b
287 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
288 $ echo change >> n2/b
290 $ echo change >> n2/b
289 $ hg -R n2 ci -A -m local
291 $ hg -R n2 ci -A -m local
290 $ hg -R n2 fetch -m 'merge' n1
292 $ hg -R n2 fetch -m 'merge' n1
291 pulling from n1
293 pulling from n1
292 searching for changes
294 searching for changes
293 adding changesets
295 adding changesets
294 adding manifests
296 adding manifests
295 adding file changes
297 adding file changes
296 added 3 changesets with 2 changes to 1 files (+2 heads)
298 added 3 changesets with 2 changes to 1 files (+2 heads)
297 not merging with 1 other new branch heads (use "hg heads ." and "hg merge" to merge them)
299 not merging with 1 other new branch heads (use "hg heads ." and "hg merge" to merge them)
298 [1]
300 [1]
299
301
300 parent should be 3 (fetch did not merge anything)
302 parent should be 3 (fetch did not merge anything)
301
303
302 $ hg -R n2 parents --template '{rev}\n'
304 $ hg -R n2 parents --template '{rev}\n'
303 3
305 3
304 $ rm -fr n1 n2
306 $ rm -fr n1 n2
305
307
306 pull in change on different branch than dirstate
308 pull in change on different branch than dirstate
307
309
308 $ hg init n1
310 $ hg init n1
309 $ echo a > n1/a
311 $ echo a > n1/a
310 $ hg -R n1 ci -Am initial
312 $ hg -R n1 ci -Am initial
311 adding a
313 adding a
312 $ hg clone n1 n2
314 $ hg clone n1 n2
313 updating to branch default
315 updating to branch default
314 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
316 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
315 $ echo b > n1/a
317 $ echo b > n1/a
316 $ hg -R n1 ci -m next
318 $ hg -R n1 ci -m next
317 $ hg -R n2 branch topic
319 $ hg -R n2 branch topic
318 marked working directory as branch topic
320 marked working directory as branch topic
321 (branches are permanent and global, did you want a bookmark?)
319 $ hg -R n2 fetch -m merge n1
322 $ hg -R n2 fetch -m merge n1
320 abort: working dir not at branch tip (use "hg update" to check out branch tip)
323 abort: working dir not at branch tip (use "hg update" to check out branch tip)
321 [255]
324 [255]
322
325
323 parent should be 0 (fetch did not update or merge anything)
326 parent should be 0 (fetch did not update or merge anything)
324
327
325 $ hg -R n2 parents --template '{rev}\n'
328 $ hg -R n2 parents --template '{rev}\n'
326 0
329 0
327 $ rm -fr n1 n2
330 $ rm -fr n1 n2
328
331
329 test fetch with inactive branches
332 test fetch with inactive branches
330
333
331 $ hg init ib1
334 $ hg init ib1
332 $ echo a > ib1/a
335 $ echo a > ib1/a
333 $ hg --cwd ib1 ci -Am base
336 $ hg --cwd ib1 ci -Am base
334 adding a
337 adding a
335 $ hg --cwd ib1 branch second
338 $ hg --cwd ib1 branch second
336 marked working directory as branch second
339 marked working directory as branch second
340 (branches are permanent and global, did you want a bookmark?)
337 $ echo b > ib1/b
341 $ echo b > ib1/b
338 $ hg --cwd ib1 ci -Am onsecond
342 $ hg --cwd ib1 ci -Am onsecond
339 adding b
343 adding b
340 $ hg --cwd ib1 branch -f default
344 $ hg --cwd ib1 branch -f default
341 marked working directory as branch default
345 marked working directory as branch default
346 (branches are permanent and global, did you want a bookmark?)
342 $ echo c > ib1/c
347 $ echo c > ib1/c
343 $ hg --cwd ib1 ci -Am newdefault
348 $ hg --cwd ib1 ci -Am newdefault
344 adding c
349 adding c
345 created new head
350 created new head
346 $ hg clone ib1 ib2
351 $ hg clone ib1 ib2
347 updating to branch default
352 updating to branch default
348 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
353 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
349
354
350 fetch should succeed
355 fetch should succeed
351
356
352 $ hg --cwd ib2 fetch ../ib1
357 $ hg --cwd ib2 fetch ../ib1
353 pulling from ../ib1
358 pulling from ../ib1
354 searching for changes
359 searching for changes
355 no changes found
360 no changes found
356 $ rm -fr ib1 ib2
361 $ rm -fr ib1 ib2
357
362
358 test issue1726
363 test issue1726
359
364
360 $ hg init i1726r1
365 $ hg init i1726r1
361 $ echo a > i1726r1/a
366 $ echo a > i1726r1/a
362 $ hg --cwd i1726r1 ci -Am base
367 $ hg --cwd i1726r1 ci -Am base
363 adding a
368 adding a
364 $ hg clone i1726r1 i1726r2
369 $ hg clone i1726r1 i1726r2
365 updating to branch default
370 updating to branch default
366 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
371 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
367 $ echo b > i1726r1/a
372 $ echo b > i1726r1/a
368 $ hg --cwd i1726r1 ci -m second
373 $ hg --cwd i1726r1 ci -m second
369 $ echo c > i1726r2/a
374 $ echo c > i1726r2/a
370 $ hg --cwd i1726r2 ci -m third
375 $ hg --cwd i1726r2 ci -m third
371 $ HGMERGE=true hg --cwd i1726r2 fetch ../i1726r1
376 $ HGMERGE=true hg --cwd i1726r2 fetch ../i1726r1
372 pulling from ../i1726r1
377 pulling from ../i1726r1
373 searching for changes
378 searching for changes
374 adding changesets
379 adding changesets
375 adding manifests
380 adding manifests
376 adding file changes
381 adding file changes
377 added 1 changesets with 1 changes to 1 files (+1 heads)
382 added 1 changesets with 1 changes to 1 files (+1 heads)
378 updating to 2:7837755a2789
383 updating to 2:7837755a2789
379 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
384 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 merging with 1:d1f0c6c48ebd
385 merging with 1:d1f0c6c48ebd
381 merging a
386 merging a
382 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
387 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
383 new changeset 3:* merges remote changes with local (glob)
388 new changeset 3:* merges remote changes with local (glob)
384 $ hg --cwd i1726r2 heads default --template '{rev}\n'
389 $ hg --cwd i1726r2 heads default --template '{rev}\n'
385 3
390 3
386
391
387 test issue2047
392 test issue2047
388
393
389 $ hg -q init i2047a
394 $ hg -q init i2047a
390 $ cd i2047a
395 $ cd i2047a
391 $ echo a > a
396 $ echo a > a
392 $ hg -q ci -Am a
397 $ hg -q ci -Am a
393 $ hg -q branch stable
398 $ hg -q branch stable
394 $ echo b > b
399 $ echo b > b
395 $ hg -q ci -Am b
400 $ hg -q ci -Am b
396 $ cd ..
401 $ cd ..
397 $ hg -q clone -r 0 i2047a i2047b
402 $ hg -q clone -r 0 i2047a i2047b
398 $ cd i2047b
403 $ cd i2047b
399 $ hg fetch ../i2047a
404 $ hg fetch ../i2047a
400 pulling from ../i2047a
405 pulling from ../i2047a
401 searching for changes
406 searching for changes
402 adding changesets
407 adding changesets
403 adding manifests
408 adding manifests
404 adding file changes
409 adding file changes
405 added 1 changesets with 1 changes to 1 files
410 added 1 changesets with 1 changes to 1 files
@@ -1,1157 +1,1158 b''
1 An attempt at more fully testing the hgweb web interface.
1 An attempt at more fully testing the hgweb web interface.
2 The following things are tested elsewhere and are therefore omitted:
2 The following things are tested elsewhere and are therefore omitted:
3 - archive, tested in test-archive
3 - archive, tested in test-archive
4 - unbundle, tested in test-push-http
4 - unbundle, tested in test-push-http
5 - changegroupsubset, tested in test-pull
5 - changegroupsubset, tested in test-pull
6
6
7 Set up the repo
7 Set up the repo
8
8
9 $ hg init test
9 $ hg init test
10 $ cd test
10 $ cd test
11 $ mkdir da
11 $ mkdir da
12 $ echo foo > da/foo
12 $ echo foo > da/foo
13 $ echo foo > foo
13 $ echo foo > foo
14 $ hg ci -Ambase
14 $ hg ci -Ambase
15 adding da/foo
15 adding da/foo
16 adding foo
16 adding foo
17 $ hg tag 1.0
17 $ hg tag 1.0
18 $ hg bookmark something
18 $ hg bookmark something
19 $ hg bookmark -r0 anotherthing
19 $ hg bookmark -r0 anotherthing
20 $ echo another > foo
20 $ echo another > foo
21 $ hg branch stable
21 $ hg branch stable
22 marked working directory as branch stable
22 marked working directory as branch stable
23 (branches are permanent and global, did you want a bookmark?)
23 $ hg ci -Ambranch
24 $ hg ci -Ambranch
24 $ hg serve --config server.uncompressed=False -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
25 $ hg serve --config server.uncompressed=False -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
25 $ cat hg.pid >> $DAEMON_PIDS
26 $ cat hg.pid >> $DAEMON_PIDS
26
27
27 Logs and changes
28 Logs and changes
28
29
29 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/?style=atom'
30 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/?style=atom'
30 200 Script output follows
31 200 Script output follows
31
32
32 <?xml version="1.0" encoding="ascii"?>
33 <?xml version="1.0" encoding="ascii"?>
33 <feed xmlns="http://www.w3.org/2005/Atom">
34 <feed xmlns="http://www.w3.org/2005/Atom">
34 <!-- Changelog -->
35 <!-- Changelog -->
35 <id>http://*:$HGPORT/</id> (glob)
36 <id>http://*:$HGPORT/</id> (glob)
36 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
37 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
37 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
38 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
38 <title>test Changelog</title>
39 <title>test Changelog</title>
39 <updated>1970-01-01T00:00:00+00:00</updated>
40 <updated>1970-01-01T00:00:00+00:00</updated>
40
41
41 <entry>
42 <entry>
42 <title>branch</title>
43 <title>branch</title>
43 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
44 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
44 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
45 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
45 <author>
46 <author>
46 <name>test</name>
47 <name>test</name>
47 <email>&#116;&#101;&#115;&#116;</email>
48 <email>&#116;&#101;&#115;&#116;</email>
48 </author>
49 </author>
49 <updated>1970-01-01T00:00:00+00:00</updated>
50 <updated>1970-01-01T00:00:00+00:00</updated>
50 <published>1970-01-01T00:00:00+00:00</published>
51 <published>1970-01-01T00:00:00+00:00</published>
51 <content type="xhtml">
52 <content type="xhtml">
52 <div xmlns="http://www.w3.org/1999/xhtml">
53 <div xmlns="http://www.w3.org/1999/xhtml">
53 <pre xml:space="preserve">branch</pre>
54 <pre xml:space="preserve">branch</pre>
54 </div>
55 </div>
55 </content>
56 </content>
56 </entry>
57 </entry>
57 <entry>
58 <entry>
58 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
59 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
59 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
60 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
60 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
61 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
61 <author>
62 <author>
62 <name>test</name>
63 <name>test</name>
63 <email>&#116;&#101;&#115;&#116;</email>
64 <email>&#116;&#101;&#115;&#116;</email>
64 </author>
65 </author>
65 <updated>1970-01-01T00:00:00+00:00</updated>
66 <updated>1970-01-01T00:00:00+00:00</updated>
66 <published>1970-01-01T00:00:00+00:00</published>
67 <published>1970-01-01T00:00:00+00:00</published>
67 <content type="xhtml">
68 <content type="xhtml">
68 <div xmlns="http://www.w3.org/1999/xhtml">
69 <div xmlns="http://www.w3.org/1999/xhtml">
69 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
70 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
70 </div>
71 </div>
71 </content>
72 </content>
72 </entry>
73 </entry>
73 <entry>
74 <entry>
74 <title>base</title>
75 <title>base</title>
75 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
76 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
76 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
77 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
77 <author>
78 <author>
78 <name>test</name>
79 <name>test</name>
79 <email>&#116;&#101;&#115;&#116;</email>
80 <email>&#116;&#101;&#115;&#116;</email>
80 </author>
81 </author>
81 <updated>1970-01-01T00:00:00+00:00</updated>
82 <updated>1970-01-01T00:00:00+00:00</updated>
82 <published>1970-01-01T00:00:00+00:00</published>
83 <published>1970-01-01T00:00:00+00:00</published>
83 <content type="xhtml">
84 <content type="xhtml">
84 <div xmlns="http://www.w3.org/1999/xhtml">
85 <div xmlns="http://www.w3.org/1999/xhtml">
85 <pre xml:space="preserve">base</pre>
86 <pre xml:space="preserve">base</pre>
86 </div>
87 </div>
87 </content>
88 </content>
88 </entry>
89 </entry>
89
90
90 </feed>
91 </feed>
91 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/?style=atom'
92 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/?style=atom'
92 200 Script output follows
93 200 Script output follows
93
94
94 <?xml version="1.0" encoding="ascii"?>
95 <?xml version="1.0" encoding="ascii"?>
95 <feed xmlns="http://www.w3.org/2005/Atom">
96 <feed xmlns="http://www.w3.org/2005/Atom">
96 <!-- Changelog -->
97 <!-- Changelog -->
97 <id>http://*:$HGPORT/</id> (glob)
98 <id>http://*:$HGPORT/</id> (glob)
98 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
99 <link rel="self" href="http://*:$HGPORT/atom-log"/> (glob)
99 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
100 <link rel="alternate" href="http://*:$HGPORT/"/> (glob)
100 <title>test Changelog</title>
101 <title>test Changelog</title>
101 <updated>1970-01-01T00:00:00+00:00</updated>
102 <updated>1970-01-01T00:00:00+00:00</updated>
102
103
103 <entry>
104 <entry>
104 <title>branch</title>
105 <title>branch</title>
105 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
106 <id>http://*:$HGPORT/#changeset-1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe</id> (glob)
106 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
107 <link href="http://*:$HGPORT/rev/1d22e65f027e"/> (glob)
107 <author>
108 <author>
108 <name>test</name>
109 <name>test</name>
109 <email>&#116;&#101;&#115;&#116;</email>
110 <email>&#116;&#101;&#115;&#116;</email>
110 </author>
111 </author>
111 <updated>1970-01-01T00:00:00+00:00</updated>
112 <updated>1970-01-01T00:00:00+00:00</updated>
112 <published>1970-01-01T00:00:00+00:00</published>
113 <published>1970-01-01T00:00:00+00:00</published>
113 <content type="xhtml">
114 <content type="xhtml">
114 <div xmlns="http://www.w3.org/1999/xhtml">
115 <div xmlns="http://www.w3.org/1999/xhtml">
115 <pre xml:space="preserve">branch</pre>
116 <pre xml:space="preserve">branch</pre>
116 </div>
117 </div>
117 </content>
118 </content>
118 </entry>
119 </entry>
119 <entry>
120 <entry>
120 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
121 <title>Added tag 1.0 for changeset 2ef0ac749a14</title>
121 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
122 <id>http://*:$HGPORT/#changeset-a4f92ed23982be056b9852de5dfe873eaac7f0de</id> (glob)
122 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
123 <link href="http://*:$HGPORT/rev/a4f92ed23982"/> (glob)
123 <author>
124 <author>
124 <name>test</name>
125 <name>test</name>
125 <email>&#116;&#101;&#115;&#116;</email>
126 <email>&#116;&#101;&#115;&#116;</email>
126 </author>
127 </author>
127 <updated>1970-01-01T00:00:00+00:00</updated>
128 <updated>1970-01-01T00:00:00+00:00</updated>
128 <published>1970-01-01T00:00:00+00:00</published>
129 <published>1970-01-01T00:00:00+00:00</published>
129 <content type="xhtml">
130 <content type="xhtml">
130 <div xmlns="http://www.w3.org/1999/xhtml">
131 <div xmlns="http://www.w3.org/1999/xhtml">
131 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
132 <pre xml:space="preserve">Added tag 1.0 for changeset 2ef0ac749a14</pre>
132 </div>
133 </div>
133 </content>
134 </content>
134 </entry>
135 </entry>
135 <entry>
136 <entry>
136 <title>base</title>
137 <title>base</title>
137 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
138 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
138 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
139 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
139 <author>
140 <author>
140 <name>test</name>
141 <name>test</name>
141 <email>&#116;&#101;&#115;&#116;</email>
142 <email>&#116;&#101;&#115;&#116;</email>
142 </author>
143 </author>
143 <updated>1970-01-01T00:00:00+00:00</updated>
144 <updated>1970-01-01T00:00:00+00:00</updated>
144 <published>1970-01-01T00:00:00+00:00</published>
145 <published>1970-01-01T00:00:00+00:00</published>
145 <content type="xhtml">
146 <content type="xhtml">
146 <div xmlns="http://www.w3.org/1999/xhtml">
147 <div xmlns="http://www.w3.org/1999/xhtml">
147 <pre xml:space="preserve">base</pre>
148 <pre xml:space="preserve">base</pre>
148 </div>
149 </div>
149 </content>
150 </content>
150 </entry>
151 </entry>
151
152
152 </feed>
153 </feed>
153 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/foo/?style=atom'
154 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/foo/?style=atom'
154 200 Script output follows
155 200 Script output follows
155
156
156 <?xml version="1.0" encoding="ascii"?>
157 <?xml version="1.0" encoding="ascii"?>
157 <feed xmlns="http://www.w3.org/2005/Atom">
158 <feed xmlns="http://www.w3.org/2005/Atom">
158 <id>http://*:$HGPORT/atom-log/tip/foo</id> (glob)
159 <id>http://*:$HGPORT/atom-log/tip/foo</id> (glob)
159 <link rel="self" href="http://*:$HGPORT/atom-log/tip/foo"/> (glob)
160 <link rel="self" href="http://*:$HGPORT/atom-log/tip/foo"/> (glob)
160 <title>test: foo history</title>
161 <title>test: foo history</title>
161 <updated>1970-01-01T00:00:00+00:00</updated>
162 <updated>1970-01-01T00:00:00+00:00</updated>
162
163
163 <entry>
164 <entry>
164 <title>base</title>
165 <title>base</title>
165 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
166 <id>http://*:$HGPORT/#changeset-2ef0ac749a14e4f57a5a822464a0902c6f7f448f</id> (glob)
166 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
167 <link href="http://*:$HGPORT/rev/2ef0ac749a14"/> (glob)
167 <author>
168 <author>
168 <name>test</name>
169 <name>test</name>
169 <email>&#116;&#101;&#115;&#116;</email>
170 <email>&#116;&#101;&#115;&#116;</email>
170 </author>
171 </author>
171 <updated>1970-01-01T00:00:00+00:00</updated>
172 <updated>1970-01-01T00:00:00+00:00</updated>
172 <published>1970-01-01T00:00:00+00:00</published>
173 <published>1970-01-01T00:00:00+00:00</published>
173 <content type="xhtml">
174 <content type="xhtml">
174 <div xmlns="http://www.w3.org/1999/xhtml">
175 <div xmlns="http://www.w3.org/1999/xhtml">
175 <pre xml:space="preserve">base</pre>
176 <pre xml:space="preserve">base</pre>
176 </div>
177 </div>
177 </content>
178 </content>
178 </entry>
179 </entry>
179
180
180 </feed>
181 </feed>
181 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/shortlog/'
182 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/shortlog/'
182 200 Script output follows
183 200 Script output follows
183
184
184 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
185 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
185 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
186 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
186 <head>
187 <head>
187 <link rel="icon" href="/static/hgicon.png" type="image/png" />
188 <link rel="icon" href="/static/hgicon.png" type="image/png" />
188 <meta name="robots" content="index, nofollow" />
189 <meta name="robots" content="index, nofollow" />
189 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
190 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
190 <script type="text/javascript" src="/static/mercurial.js"></script>
191 <script type="text/javascript" src="/static/mercurial.js"></script>
191
192
192 <title>test: log</title>
193 <title>test: log</title>
193 <link rel="alternate" type="application/atom+xml"
194 <link rel="alternate" type="application/atom+xml"
194 href="/atom-log" title="Atom feed for test" />
195 href="/atom-log" title="Atom feed for test" />
195 <link rel="alternate" type="application/rss+xml"
196 <link rel="alternate" type="application/rss+xml"
196 href="/rss-log" title="RSS feed for test" />
197 href="/rss-log" title="RSS feed for test" />
197 </head>
198 </head>
198 <body>
199 <body>
199
200
200 <div class="container">
201 <div class="container">
201 <div class="menu">
202 <div class="menu">
202 <div class="logo">
203 <div class="logo">
203 <a href="http://mercurial.selenic.com/">
204 <a href="http://mercurial.selenic.com/">
204 <img src="/static/hglogo.png" alt="mercurial" /></a>
205 <img src="/static/hglogo.png" alt="mercurial" /></a>
205 </div>
206 </div>
206 <ul>
207 <ul>
207 <li class="active">log</li>
208 <li class="active">log</li>
208 <li><a href="/graph/1d22e65f027e">graph</a></li>
209 <li><a href="/graph/1d22e65f027e">graph</a></li>
209 <li><a href="/tags">tags</a></li>
210 <li><a href="/tags">tags</a></li>
210 <li><a href="/bookmarks">bookmarks</a></li>
211 <li><a href="/bookmarks">bookmarks</a></li>
211 <li><a href="/branches">branches</a></li>
212 <li><a href="/branches">branches</a></li>
212 </ul>
213 </ul>
213 <ul>
214 <ul>
214 <li><a href="/rev/1d22e65f027e">changeset</a></li>
215 <li><a href="/rev/1d22e65f027e">changeset</a></li>
215 <li><a href="/file/1d22e65f027e">browse</a></li>
216 <li><a href="/file/1d22e65f027e">browse</a></li>
216 </ul>
217 </ul>
217 <ul>
218 <ul>
218
219
219 </ul>
220 </ul>
220 <ul>
221 <ul>
221 <li><a href="/help">help</a></li>
222 <li><a href="/help">help</a></li>
222 </ul>
223 </ul>
223 </div>
224 </div>
224
225
225 <div class="main">
226 <div class="main">
226 <h2><a href="/">test</a></h2>
227 <h2><a href="/">test</a></h2>
227 <h3>log</h3>
228 <h3>log</h3>
228
229
229 <form class="search" action="/log">
230 <form class="search" action="/log">
230
231
231 <p><input name="rev" id="search1" type="text" size="30" /></p>
232 <p><input name="rev" id="search1" type="text" size="30" /></p>
232 <div id="hint">find changesets by author, revision,
233 <div id="hint">find changesets by author, revision,
233 files, or words in the commit message</div>
234 files, or words in the commit message</div>
234 </form>
235 </form>
235
236
236 <div class="navigate">
237 <div class="navigate">
237 <a href="/shortlog/2?revcount=30">less</a>
238 <a href="/shortlog/2?revcount=30">less</a>
238 <a href="/shortlog/2?revcount=120">more</a>
239 <a href="/shortlog/2?revcount=120">more</a>
239 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
240 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
240 </div>
241 </div>
241
242
242 <table class="bigtable">
243 <table class="bigtable">
243 <tr>
244 <tr>
244 <th class="age">age</th>
245 <th class="age">age</th>
245 <th class="author">author</th>
246 <th class="author">author</th>
246 <th class="description">description</th>
247 <th class="description">description</th>
247 </tr>
248 </tr>
248 <tr class="parity0">
249 <tr class="parity0">
249 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
250 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
250 <td class="author">test</td>
251 <td class="author">test</td>
251 <td class="description"><a href="/rev/1d22e65f027e">branch</a><span class="branchhead">stable</span> <span class="tag">tip</span> <span class="tag">something</span> </td>
252 <td class="description"><a href="/rev/1d22e65f027e">branch</a><span class="branchhead">stable</span> <span class="tag">tip</span> <span class="tag">something</span> </td>
252 </tr>
253 </tr>
253 <tr class="parity1">
254 <tr class="parity1">
254 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
255 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
255 <td class="author">test</td>
256 <td class="author">test</td>
256 <td class="description"><a href="/rev/a4f92ed23982">Added tag 1.0 for changeset 2ef0ac749a14</a><span class="branchhead">default</span> </td>
257 <td class="description"><a href="/rev/a4f92ed23982">Added tag 1.0 for changeset 2ef0ac749a14</a><span class="branchhead">default</span> </td>
257 </tr>
258 </tr>
258 <tr class="parity0">
259 <tr class="parity0">
259 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
260 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
260 <td class="author">test</td>
261 <td class="author">test</td>
261 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
262 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
262 </tr>
263 </tr>
263
264
264 </table>
265 </table>
265
266
266 <div class="navigate">
267 <div class="navigate">
267 <a href="/shortlog/2?revcount=30">less</a>
268 <a href="/shortlog/2?revcount=30">less</a>
268 <a href="/shortlog/2?revcount=120">more</a>
269 <a href="/shortlog/2?revcount=120">more</a>
269 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
270 | rev 2: <a href="/shortlog/2ef0ac749a14">(0)</a> <a href="/shortlog/tip">tip</a>
270 </div>
271 </div>
271
272
272 </div>
273 </div>
273 </div>
274 </div>
274
275
275 <script type="text/javascript">process_dates()</script>
276 <script type="text/javascript">process_dates()</script>
276
277
277
278
278 </body>
279 </body>
279 </html>
280 </html>
280
281
281 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/0/'
282 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/0/'
282 200 Script output follows
283 200 Script output follows
283
284
284 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
285 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
285 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
286 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
286 <head>
287 <head>
287 <link rel="icon" href="/static/hgicon.png" type="image/png" />
288 <link rel="icon" href="/static/hgicon.png" type="image/png" />
288 <meta name="robots" content="index, nofollow" />
289 <meta name="robots" content="index, nofollow" />
289 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
290 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
290 <script type="text/javascript" src="/static/mercurial.js"></script>
291 <script type="text/javascript" src="/static/mercurial.js"></script>
291
292
292 <title>test: 2ef0ac749a14</title>
293 <title>test: 2ef0ac749a14</title>
293 </head>
294 </head>
294 <body>
295 <body>
295 <div class="container">
296 <div class="container">
296 <div class="menu">
297 <div class="menu">
297 <div class="logo">
298 <div class="logo">
298 <a href="http://mercurial.selenic.com/">
299 <a href="http://mercurial.selenic.com/">
299 <img src="/static/hglogo.png" alt="mercurial" /></a>
300 <img src="/static/hglogo.png" alt="mercurial" /></a>
300 </div>
301 </div>
301 <ul>
302 <ul>
302 <li><a href="/shortlog/2ef0ac749a14">log</a></li>
303 <li><a href="/shortlog/2ef0ac749a14">log</a></li>
303 <li><a href="/graph/2ef0ac749a14">graph</a></li>
304 <li><a href="/graph/2ef0ac749a14">graph</a></li>
304 <li><a href="/tags">tags</a></li>
305 <li><a href="/tags">tags</a></li>
305 <li><a href="/bookmarks">bookmarks</a></li>
306 <li><a href="/bookmarks">bookmarks</a></li>
306 <li><a href="/branches">branches</a></li>
307 <li><a href="/branches">branches</a></li>
307 </ul>
308 </ul>
308 <ul>
309 <ul>
309 <li class="active">changeset</li>
310 <li class="active">changeset</li>
310 <li><a href="/raw-rev/2ef0ac749a14">raw</a></li>
311 <li><a href="/raw-rev/2ef0ac749a14">raw</a></li>
311 <li><a href="/file/2ef0ac749a14">browse</a></li>
312 <li><a href="/file/2ef0ac749a14">browse</a></li>
312 </ul>
313 </ul>
313 <ul>
314 <ul>
314
315
315 </ul>
316 </ul>
316 <ul>
317 <ul>
317 <li><a href="/help">help</a></li>
318 <li><a href="/help">help</a></li>
318 </ul>
319 </ul>
319 </div>
320 </div>
320
321
321 <div class="main">
322 <div class="main">
322
323
323 <h2><a href="/">test</a></h2>
324 <h2><a href="/">test</a></h2>
324 <h3>changeset 0:2ef0ac749a14 <span class="tag">1.0</span> <span class="tag">anotherthing</span> </h3>
325 <h3>changeset 0:2ef0ac749a14 <span class="tag">1.0</span> <span class="tag">anotherthing</span> </h3>
325
326
326 <form class="search" action="/log">
327 <form class="search" action="/log">
327
328
328 <p><input name="rev" id="search1" type="text" size="30" /></p>
329 <p><input name="rev" id="search1" type="text" size="30" /></p>
329 <div id="hint">find changesets by author, revision,
330 <div id="hint">find changesets by author, revision,
330 files, or words in the commit message</div>
331 files, or words in the commit message</div>
331 </form>
332 </form>
332
333
333 <div class="description">base</div>
334 <div class="description">base</div>
334
335
335 <table id="changesetEntry">
336 <table id="changesetEntry">
336 <tr>
337 <tr>
337 <th class="author">author</th>
338 <th class="author">author</th>
338 <td class="author">&#116;&#101;&#115;&#116;</td>
339 <td class="author">&#116;&#101;&#115;&#116;</td>
339 </tr>
340 </tr>
340 <tr>
341 <tr>
341 <th class="date">date</th>
342 <th class="date">date</th>
342 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
343 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
343 <tr>
344 <tr>
344 <th class="author">parents</th>
345 <th class="author">parents</th>
345 <td class="author"></td>
346 <td class="author"></td>
346 </tr>
347 </tr>
347 <tr>
348 <tr>
348 <th class="author">children</th>
349 <th class="author">children</th>
349 <td class="author"> <a href="/rev/a4f92ed23982">a4f92ed23982</a></td>
350 <td class="author"> <a href="/rev/a4f92ed23982">a4f92ed23982</a></td>
350 </tr>
351 </tr>
351 <tr>
352 <tr>
352 <th class="files">files</th>
353 <th class="files">files</th>
353 <td class="files"><a href="/file/2ef0ac749a14/da/foo">da/foo</a> <a href="/file/2ef0ac749a14/foo">foo</a> </td>
354 <td class="files"><a href="/file/2ef0ac749a14/da/foo">da/foo</a> <a href="/file/2ef0ac749a14/foo">foo</a> </td>
354 </tr>
355 </tr>
355 <tr>
356 <tr>
356 <th class="diffstat">diffstat</th>
357 <th class="diffstat">diffstat</th>
357 <td class="diffstat">
358 <td class="diffstat">
358 2 files changed, 2 insertions(+), 0 deletions(-)
359 2 files changed, 2 insertions(+), 0 deletions(-)
359
360
360 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
361 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
361 <div id="diffstatdetails" style="display:none;">
362 <div id="diffstatdetails" style="display:none;">
362 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
363 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
363 <p>
364 <p>
364 <table> <tr class="parity0">
365 <table> <tr class="parity0">
365 <td class="diffstat-file"><a href="#l1.1">da/foo</a></td>
366 <td class="diffstat-file"><a href="#l1.1">da/foo</a></td>
366 <td class="diffstat-total" align="right">1</td>
367 <td class="diffstat-total" align="right">1</td>
367 <td class="diffstat-graph">
368 <td class="diffstat-graph">
368 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
369 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
369 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
370 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
370 </td>
371 </td>
371 </tr>
372 </tr>
372 <tr class="parity1">
373 <tr class="parity1">
373 <td class="diffstat-file"><a href="#l2.1">foo</a></td>
374 <td class="diffstat-file"><a href="#l2.1">foo</a></td>
374 <td class="diffstat-total" align="right">1</td>
375 <td class="diffstat-total" align="right">1</td>
375 <td class="diffstat-graph">
376 <td class="diffstat-graph">
376 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
377 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
377 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
378 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
378 </td>
379 </td>
379 </tr>
380 </tr>
380 </table>
381 </table>
381 </div>
382 </div>
382 </td>
383 </td>
383 </tr>
384 </tr>
384 </table>
385 </table>
385
386
386 <div class="overflow">
387 <div class="overflow">
387 <div class="sourcefirst"> line diff</div>
388 <div class="sourcefirst"> line diff</div>
388
389
389 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
390 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
390 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/da/foo Thu Jan 01 00:00:00 1970 +0000
391 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/da/foo Thu Jan 01 00:00:00 1970 +0000
391 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
392 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
392 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+foo
393 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+foo
393 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
394 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
394 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/foo Thu Jan 01 00:00:00 1970 +0000
395 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/foo Thu Jan 01 00:00:00 1970 +0000
395 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
396 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
396 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+foo
397 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+foo
397 </span></pre></div>
398 </span></pre></div>
398 </div>
399 </div>
399
400
400 </div>
401 </div>
401 </div>
402 </div>
402 <script type="text/javascript">process_dates()</script>
403 <script type="text/javascript">process_dates()</script>
403
404
404
405
405 </body>
406 </body>
406 </html>
407 </html>
407
408
408 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/1/?style=raw'
409 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/1/?style=raw'
409 200 Script output follows
410 200 Script output follows
410
411
411
412
412 # HG changeset patch
413 # HG changeset patch
413 # User test
414 # User test
414 # Date 0 0
415 # Date 0 0
415 # Node ID a4f92ed23982be056b9852de5dfe873eaac7f0de
416 # Node ID a4f92ed23982be056b9852de5dfe873eaac7f0de
416 # Parent 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
417 # Parent 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
417 Added tag 1.0 for changeset 2ef0ac749a14
418 Added tag 1.0 for changeset 2ef0ac749a14
418
419
419 diff -r 2ef0ac749a14 -r a4f92ed23982 .hgtags
420 diff -r 2ef0ac749a14 -r a4f92ed23982 .hgtags
420 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
421 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
421 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
422 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
422 @@ -0,0 +1,1 @@
423 @@ -0,0 +1,1 @@
423 +2ef0ac749a14e4f57a5a822464a0902c6f7f448f 1.0
424 +2ef0ac749a14e4f57a5a822464a0902c6f7f448f 1.0
424
425
425 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log?rev=base'
426 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log?rev=base'
426 200 Script output follows
427 200 Script output follows
427
428
428 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
429 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
429 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
430 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
430 <head>
431 <head>
431 <link rel="icon" href="/static/hgicon.png" type="image/png" />
432 <link rel="icon" href="/static/hgicon.png" type="image/png" />
432 <meta name="robots" content="index, nofollow" />
433 <meta name="robots" content="index, nofollow" />
433 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
434 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
434 <script type="text/javascript" src="/static/mercurial.js"></script>
435 <script type="text/javascript" src="/static/mercurial.js"></script>
435
436
436 <title>test: searching for base</title>
437 <title>test: searching for base</title>
437 </head>
438 </head>
438 <body>
439 <body>
439
440
440 <div class="container">
441 <div class="container">
441 <div class="menu">
442 <div class="menu">
442 <div class="logo">
443 <div class="logo">
443 <a href="http://mercurial.selenic.com/">
444 <a href="http://mercurial.selenic.com/">
444 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
445 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
445 </div>
446 </div>
446 <ul>
447 <ul>
447 <li><a href="/shortlog">log</a></li>
448 <li><a href="/shortlog">log</a></li>
448 <li><a href="/graph">graph</a></li>
449 <li><a href="/graph">graph</a></li>
449 <li><a href="/tags">tags</a></li>
450 <li><a href="/tags">tags</a></li>
450 <li><a href="/bookmarks">bookmarks</a></li>
451 <li><a href="/bookmarks">bookmarks</a></li>
451 <li><a href="/branches">branches</a></li>
452 <li><a href="/branches">branches</a></li>
452 <li><a href="/help">help</a></li>
453 <li><a href="/help">help</a></li>
453 </ul>
454 </ul>
454 </div>
455 </div>
455
456
456 <div class="main">
457 <div class="main">
457 <h2><a href="/">test</a></h2>
458 <h2><a href="/">test</a></h2>
458 <h3>searching for 'base'</h3>
459 <h3>searching for 'base'</h3>
459
460
460 <form class="search" action="/log">
461 <form class="search" action="/log">
461
462
462 <p><input name="rev" id="search1" type="text" size="30"></p>
463 <p><input name="rev" id="search1" type="text" size="30"></p>
463 <div id="hint">find changesets by author, revision,
464 <div id="hint">find changesets by author, revision,
464 files, or words in the commit message</div>
465 files, or words in the commit message</div>
465 </form>
466 </form>
466
467
467 <div class="navigate">
468 <div class="navigate">
468 <a href="/search/?rev=base&revcount=5">less</a>
469 <a href="/search/?rev=base&revcount=5">less</a>
469 <a href="/search/?rev=base&revcount=20">more</a>
470 <a href="/search/?rev=base&revcount=20">more</a>
470 </div>
471 </div>
471
472
472 <table class="bigtable">
473 <table class="bigtable">
473 <tr>
474 <tr>
474 <th class="age">age</th>
475 <th class="age">age</th>
475 <th class="author">author</th>
476 <th class="author">author</th>
476 <th class="description">description</th>
477 <th class="description">description</th>
477 </tr>
478 </tr>
478 <tr class="parity0">
479 <tr class="parity0">
479 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
480 <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>
480 <td class="author">test</td>
481 <td class="author">test</td>
481 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
482 <td class="description"><a href="/rev/2ef0ac749a14">base</a><span class="tag">1.0</span> <span class="tag">anotherthing</span> </td>
482 </tr>
483 </tr>
483
484
484 </table>
485 </table>
485
486
486 <div class="navigate">
487 <div class="navigate">
487 <a href="/search/?rev=base&revcount=5">less</a>
488 <a href="/search/?rev=base&revcount=5">less</a>
488 <a href="/search/?rev=base&revcount=20">more</a>
489 <a href="/search/?rev=base&revcount=20">more</a>
489 </div>
490 </div>
490
491
491 </div>
492 </div>
492 </div>
493 </div>
493
494
494 <script type="text/javascript">process_dates()</script>
495 <script type="text/javascript">process_dates()</script>
495
496
496
497
497 </body>
498 </body>
498 </html>
499 </html>
499
500
500
501
501 File-related
502 File-related
502
503
503 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo/?style=raw'
504 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo/?style=raw'
504 200 Script output follows
505 200 Script output follows
505
506
506 foo
507 foo
507 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/annotate/1/foo/?style=raw'
508 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/annotate/1/foo/?style=raw'
508 200 Script output follows
509 200 Script output follows
509
510
510
511
511 test@0: foo
512 test@0: foo
512
513
513
514
514
515
515
516
516 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/?style=raw'
517 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/?style=raw'
517 200 Script output follows
518 200 Script output follows
518
519
519
520
520 drwxr-xr-x da
521 drwxr-xr-x da
521 -rw-r--r-- 45 .hgtags
522 -rw-r--r-- 45 .hgtags
522 -rw-r--r-- 4 foo
523 -rw-r--r-- 4 foo
523
524
524
525
525 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo'
526 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo'
526 200 Script output follows
527 200 Script output follows
527
528
528 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
529 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
529 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
530 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
530 <head>
531 <head>
531 <link rel="icon" href="/static/hgicon.png" type="image/png" />
532 <link rel="icon" href="/static/hgicon.png" type="image/png" />
532 <meta name="robots" content="index, nofollow" />
533 <meta name="robots" content="index, nofollow" />
533 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
534 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
534 <script type="text/javascript" src="/static/mercurial.js"></script>
535 <script type="text/javascript" src="/static/mercurial.js"></script>
535
536
536 <title>test: a4f92ed23982 foo</title>
537 <title>test: a4f92ed23982 foo</title>
537 </head>
538 </head>
538 <body>
539 <body>
539
540
540 <div class="container">
541 <div class="container">
541 <div class="menu">
542 <div class="menu">
542 <div class="logo">
543 <div class="logo">
543 <a href="http://mercurial.selenic.com/">
544 <a href="http://mercurial.selenic.com/">
544 <img src="/static/hglogo.png" alt="mercurial" /></a>
545 <img src="/static/hglogo.png" alt="mercurial" /></a>
545 </div>
546 </div>
546 <ul>
547 <ul>
547 <li><a href="/shortlog/a4f92ed23982">log</a></li>
548 <li><a href="/shortlog/a4f92ed23982">log</a></li>
548 <li><a href="/graph/a4f92ed23982">graph</a></li>
549 <li><a href="/graph/a4f92ed23982">graph</a></li>
549 <li><a href="/tags">tags</a></li>
550 <li><a href="/tags">tags</a></li>
550 <li><a href="/branches">branches</a></li>
551 <li><a href="/branches">branches</a></li>
551 </ul>
552 </ul>
552 <ul>
553 <ul>
553 <li><a href="/rev/a4f92ed23982">changeset</a></li>
554 <li><a href="/rev/a4f92ed23982">changeset</a></li>
554 <li><a href="/file/a4f92ed23982/">browse</a></li>
555 <li><a href="/file/a4f92ed23982/">browse</a></li>
555 </ul>
556 </ul>
556 <ul>
557 <ul>
557 <li class="active">file</li>
558 <li class="active">file</li>
558 <li><a href="/file/tip/foo">latest</a></li>
559 <li><a href="/file/tip/foo">latest</a></li>
559 <li><a href="/diff/a4f92ed23982/foo">diff</a></li>
560 <li><a href="/diff/a4f92ed23982/foo">diff</a></li>
560 <li><a href="/annotate/a4f92ed23982/foo">annotate</a></li>
561 <li><a href="/annotate/a4f92ed23982/foo">annotate</a></li>
561 <li><a href="/log/a4f92ed23982/foo">file log</a></li>
562 <li><a href="/log/a4f92ed23982/foo">file log</a></li>
562 <li><a href="/raw-file/a4f92ed23982/foo">raw</a></li>
563 <li><a href="/raw-file/a4f92ed23982/foo">raw</a></li>
563 </ul>
564 </ul>
564 <ul>
565 <ul>
565 <li><a href="/help">help</a></li>
566 <li><a href="/help">help</a></li>
566 </ul>
567 </ul>
567 </div>
568 </div>
568
569
569 <div class="main">
570 <div class="main">
570 <h2><a href="/">test</a></h2>
571 <h2><a href="/">test</a></h2>
571 <h3>view foo @ 1:a4f92ed23982</h3>
572 <h3>view foo @ 1:a4f92ed23982</h3>
572
573
573 <form class="search" action="/log">
574 <form class="search" action="/log">
574
575
575 <p><input name="rev" id="search1" type="text" size="30" /></p>
576 <p><input name="rev" id="search1" type="text" size="30" /></p>
576 <div id="hint">find changesets by author, revision,
577 <div id="hint">find changesets by author, revision,
577 files, or words in the commit message</div>
578 files, or words in the commit message</div>
578 </form>
579 </form>
579
580
580 <div class="description">Added tag 1.0 for changeset 2ef0ac749a14</div>
581 <div class="description">Added tag 1.0 for changeset 2ef0ac749a14</div>
581
582
582 <table id="changesetEntry">
583 <table id="changesetEntry">
583 <tr>
584 <tr>
584 <th class="author">author</th>
585 <th class="author">author</th>
585 <td class="author">&#116;&#101;&#115;&#116;</td>
586 <td class="author">&#116;&#101;&#115;&#116;</td>
586 </tr>
587 </tr>
587 <tr>
588 <tr>
588 <th class="date">date</th>
589 <th class="date">date</th>
589 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
590 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
590 </tr>
591 </tr>
591 <tr>
592 <tr>
592 <th class="author">parents</th>
593 <th class="author">parents</th>
593 <td class="author"></td>
594 <td class="author"></td>
594 </tr>
595 </tr>
595 <tr>
596 <tr>
596 <th class="author">children</th>
597 <th class="author">children</th>
597 <td class="author"><a href="/file/1d22e65f027e/foo">1d22e65f027e</a> </td>
598 <td class="author"><a href="/file/1d22e65f027e/foo">1d22e65f027e</a> </td>
598 </tr>
599 </tr>
599
600
600 </table>
601 </table>
601
602
602 <div class="overflow">
603 <div class="overflow">
603 <div class="sourcefirst"> line source</div>
604 <div class="sourcefirst"> line source</div>
604
605
605 <div class="parity0 source"><a href="#l1" id="l1"> 1</a> foo
606 <div class="parity0 source"><a href="#l1" id="l1"> 1</a> foo
606 </div>
607 </div>
607 <div class="sourcelast"></div>
608 <div class="sourcelast"></div>
608 </div>
609 </div>
609 </div>
610 </div>
610 </div>
611 </div>
611
612
612 <script type="text/javascript">process_dates()</script>
613 <script type="text/javascript">process_dates()</script>
613
614
614
615
615 </body>
616 </body>
616 </html>
617 </html>
617
618
618 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/filediff/1/foo/?style=raw'
619 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/filediff/1/foo/?style=raw'
619 200 Script output follows
620 200 Script output follows
620
621
621
622
622 diff -r 000000000000 -r a4f92ed23982 foo
623 diff -r 000000000000 -r a4f92ed23982 foo
623 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
624 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
624 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
625 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
625 @@ -0,0 +1,1 @@
626 @@ -0,0 +1,1 @@
626 +foo
627 +foo
627
628
628
629
629
630
630
631
631
632
632 Overviews
633 Overviews
633
634
634 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-tags'
635 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-tags'
635 200 Script output follows
636 200 Script output follows
636
637
637 tip 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
638 tip 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
638 1.0 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
639 1.0 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
639 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-branches'
640 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-branches'
640 200 Script output follows
641 200 Script output follows
641
642
642 stable 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe open
643 stable 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe open
643 default a4f92ed23982be056b9852de5dfe873eaac7f0de inactive
644 default a4f92ed23982be056b9852de5dfe873eaac7f0de inactive
644 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-bookmarks'
645 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-bookmarks'
645 200 Script output follows
646 200 Script output follows
646
647
647 anotherthing 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
648 anotherthing 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
648 something 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
649 something 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
649 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb'
650 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb'
650 200 Script output follows
651 200 Script output follows
651
652
652 <?xml version="1.0" encoding="ascii"?>
653 <?xml version="1.0" encoding="ascii"?>
653 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
654 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
654 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
655 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
655 <head>
656 <head>
656 <link rel="icon" href="/static/hgicon.png" type="image/png" />
657 <link rel="icon" href="/static/hgicon.png" type="image/png" />
657 <meta name="robots" content="index, nofollow"/>
658 <meta name="robots" content="index, nofollow"/>
658 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
659 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
659 <script type="text/javascript" src="/static/mercurial.js"></script>
660 <script type="text/javascript" src="/static/mercurial.js"></script>
660
661
661 <title>test: Summary</title>
662 <title>test: Summary</title>
662 <link rel="alternate" type="application/atom+xml"
663 <link rel="alternate" type="application/atom+xml"
663 href="/atom-log" title="Atom feed for test"/>
664 href="/atom-log" title="Atom feed for test"/>
664 <link rel="alternate" type="application/rss+xml"
665 <link rel="alternate" type="application/rss+xml"
665 href="/rss-log" title="RSS feed for test"/>
666 href="/rss-log" title="RSS feed for test"/>
666 </head>
667 </head>
667 <body>
668 <body>
668
669
669 <div class="page_header">
670 <div class="page_header">
670 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / summary
671 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / summary
671
672
672 <form action="/log">
673 <form action="/log">
673 <input type="hidden" name="style" value="gitweb" />
674 <input type="hidden" name="style" value="gitweb" />
674 <div class="search">
675 <div class="search">
675 <input type="text" name="rev" />
676 <input type="text" name="rev" />
676 </div>
677 </div>
677 </form>
678 </form>
678 </div>
679 </div>
679
680
680 <div class="page_nav">
681 <div class="page_nav">
681 summary |
682 summary |
682 <a href="/shortlog?style=gitweb">shortlog</a> |
683 <a href="/shortlog?style=gitweb">shortlog</a> |
683 <a href="/log?style=gitweb">changelog</a> |
684 <a href="/log?style=gitweb">changelog</a> |
684 <a href="/graph?style=gitweb">graph</a> |
685 <a href="/graph?style=gitweb">graph</a> |
685 <a href="/tags?style=gitweb">tags</a> |
686 <a href="/tags?style=gitweb">tags</a> |
686 <a href="/bookmarks?style=gitweb">bookmarks</a> |
687 <a href="/bookmarks?style=gitweb">bookmarks</a> |
687 <a href="/branches?style=gitweb">branches</a> |
688 <a href="/branches?style=gitweb">branches</a> |
688 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
689 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
689 <a href="/help?style=gitweb">help</a>
690 <a href="/help?style=gitweb">help</a>
690 <br/>
691 <br/>
691 </div>
692 </div>
692
693
693 <div class="title">&nbsp;</div>
694 <div class="title">&nbsp;</div>
694 <table cellspacing="0">
695 <table cellspacing="0">
695 <tr><td>description</td><td>unknown</td></tr>
696 <tr><td>description</td><td>unknown</td></tr>
696 <tr><td>owner</td><td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td></tr>
697 <tr><td>owner</td><td>&#70;&#111;&#111;&#32;&#66;&#97;&#114;&#32;&#60;&#102;&#111;&#111;&#46;&#98;&#97;&#114;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;&#62;</td></tr>
697 <tr><td>last change</td><td>Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
698 <tr><td>last change</td><td>Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
698 </table>
699 </table>
699
700
700 <div><a class="title" href="/shortlog?style=gitweb">changes</a></div>
701 <div><a class="title" href="/shortlog?style=gitweb">changes</a></div>
701 <table cellspacing="0">
702 <table cellspacing="0">
702
703
703 <tr class="parity0">
704 <tr class="parity0">
704 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
705 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
705 <td><i>test</i></td>
706 <td><i>test</i></td>
706 <td>
707 <td>
707 <a class="list" href="/rev/1d22e65f027e?style=gitweb">
708 <a class="list" href="/rev/1d22e65f027e?style=gitweb">
708 <b>branch</b>
709 <b>branch</b>
709 <span class="logtags"><span class="branchtag" title="stable">stable</span> <span class="tagtag" title="tip">tip</span> <span class="bookmarktag" title="something">something</span> </span>
710 <span class="logtags"><span class="branchtag" title="stable">stable</span> <span class="tagtag" title="tip">tip</span> <span class="bookmarktag" title="something">something</span> </span>
710 </a>
711 </a>
711 </td>
712 </td>
712 <td class="link" nowrap>
713 <td class="link" nowrap>
713 <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
714 <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
714 <a href="/file/1d22e65f027e?style=gitweb">files</a>
715 <a href="/file/1d22e65f027e?style=gitweb">files</a>
715 </td>
716 </td>
716 </tr>
717 </tr>
717 <tr class="parity1">
718 <tr class="parity1">
718 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
719 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
719 <td><i>test</i></td>
720 <td><i>test</i></td>
720 <td>
721 <td>
721 <a class="list" href="/rev/a4f92ed23982?style=gitweb">
722 <a class="list" href="/rev/a4f92ed23982?style=gitweb">
722 <b>Added tag 1.0 for changeset 2ef0ac749a14</b>
723 <b>Added tag 1.0 for changeset 2ef0ac749a14</b>
723 <span class="logtags"><span class="branchtag" title="default">default</span> </span>
724 <span class="logtags"><span class="branchtag" title="default">default</span> </span>
724 </a>
725 </a>
725 </td>
726 </td>
726 <td class="link" nowrap>
727 <td class="link" nowrap>
727 <a href="/rev/a4f92ed23982?style=gitweb">changeset</a> |
728 <a href="/rev/a4f92ed23982?style=gitweb">changeset</a> |
728 <a href="/file/a4f92ed23982?style=gitweb">files</a>
729 <a href="/file/a4f92ed23982?style=gitweb">files</a>
729 </td>
730 </td>
730 </tr>
731 </tr>
731 <tr class="parity0">
732 <tr class="parity0">
732 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
733 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
733 <td><i>test</i></td>
734 <td><i>test</i></td>
734 <td>
735 <td>
735 <a class="list" href="/rev/2ef0ac749a14?style=gitweb">
736 <a class="list" href="/rev/2ef0ac749a14?style=gitweb">
736 <b>base</b>
737 <b>base</b>
737 <span class="logtags"><span class="tagtag" title="1.0">1.0</span> <span class="bookmarktag" title="anotherthing">anotherthing</span> </span>
738 <span class="logtags"><span class="tagtag" title="1.0">1.0</span> <span class="bookmarktag" title="anotherthing">anotherthing</span> </span>
738 </a>
739 </a>
739 </td>
740 </td>
740 <td class="link" nowrap>
741 <td class="link" nowrap>
741 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
742 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
742 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
743 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
743 </td>
744 </td>
744 </tr>
745 </tr>
745 <tr class="light"><td colspan="4"><a class="list" href="/shortlog?style=gitweb">...</a></td></tr>
746 <tr class="light"><td colspan="4"><a class="list" href="/shortlog?style=gitweb">...</a></td></tr>
746 </table>
747 </table>
747
748
748 <div><a class="title" href="/tags?style=gitweb">tags</a></div>
749 <div><a class="title" href="/tags?style=gitweb">tags</a></div>
749 <table cellspacing="0">
750 <table cellspacing="0">
750
751
751 <tr class="parity0">
752 <tr class="parity0">
752 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
753 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
753 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>1.0</b></a></td>
754 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>1.0</b></a></td>
754 <td class="link">
755 <td class="link">
755 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
756 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
756 <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
757 <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
757 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
758 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
758 </td>
759 </td>
759 </tr>
760 </tr>
760 <tr class="light"><td colspan="3"><a class="list" href="/tags?style=gitweb">...</a></td></tr>
761 <tr class="light"><td colspan="3"><a class="list" href="/tags?style=gitweb">...</a></td></tr>
761 </table>
762 </table>
762
763
763 <div><a class="title" href="/bookmarks?style=gitweb">bookmarks</a></div>
764 <div><a class="title" href="/bookmarks?style=gitweb">bookmarks</a></div>
764 <table cellspacing="0">
765 <table cellspacing="0">
765
766
766 <tr class="parity0">
767 <tr class="parity0">
767 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
768 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
768 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>anotherthing</b></a></td>
769 <td><a class="list" href="/rev/2ef0ac749a14?style=gitweb"><b>anotherthing</b></a></td>
769 <td class="link">
770 <td class="link">
770 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
771 <a href="/rev/2ef0ac749a14?style=gitweb">changeset</a> |
771 <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
772 <a href="/log/2ef0ac749a14?style=gitweb">changelog</a> |
772 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
773 <a href="/file/2ef0ac749a14?style=gitweb">files</a>
773 </td>
774 </td>
774 </tr>
775 </tr>
775 <tr class="parity1">
776 <tr class="parity1">
776 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
777 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
777 <td><a class="list" href="/rev/1d22e65f027e?style=gitweb"><b>something</b></a></td>
778 <td><a class="list" href="/rev/1d22e65f027e?style=gitweb"><b>something</b></a></td>
778 <td class="link">
779 <td class="link">
779 <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
780 <a href="/rev/1d22e65f027e?style=gitweb">changeset</a> |
780 <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
781 <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
781 <a href="/file/1d22e65f027e?style=gitweb">files</a>
782 <a href="/file/1d22e65f027e?style=gitweb">files</a>
782 </td>
783 </td>
783 </tr>
784 </tr>
784 <tr class="light"><td colspan="3"><a class="list" href="/bookmarks?style=gitweb">...</a></td></tr>
785 <tr class="light"><td colspan="3"><a class="list" href="/bookmarks?style=gitweb">...</a></td></tr>
785 </table>
786 </table>
786
787
787 <div><a class="title" href="#">branches</a></div>
788 <div><a class="title" href="#">branches</a></div>
788 <table cellspacing="0">
789 <table cellspacing="0">
789
790
790 <tr class="parity0">
791 <tr class="parity0">
791 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
792 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
792 <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td>
793 <td><a class="list" href="/shortlog/1d22e65f027e?style=gitweb"><b>1d22e65f027e</b></a></td>
793 <td class="">stable</td>
794 <td class="">stable</td>
794 <td class="link">
795 <td class="link">
795 <a href="/changeset/1d22e65f027e?style=gitweb">changeset</a> |
796 <a href="/changeset/1d22e65f027e?style=gitweb">changeset</a> |
796 <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
797 <a href="/log/1d22e65f027e?style=gitweb">changelog</a> |
797 <a href="/file/1d22e65f027e?style=gitweb">files</a>
798 <a href="/file/1d22e65f027e?style=gitweb">files</a>
798 </td>
799 </td>
799 </tr>
800 </tr>
800 <tr class="parity1">
801 <tr class="parity1">
801 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
802 <td class="age"><i class="age">Thu, 01 Jan 1970 00:00:00 +0000</i></td>
802 <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td>
803 <td><a class="list" href="/shortlog/a4f92ed23982?style=gitweb"><b>a4f92ed23982</b></a></td>
803 <td class="">default</td>
804 <td class="">default</td>
804 <td class="link">
805 <td class="link">
805 <a href="/changeset/a4f92ed23982?style=gitweb">changeset</a> |
806 <a href="/changeset/a4f92ed23982?style=gitweb">changeset</a> |
806 <a href="/log/a4f92ed23982?style=gitweb">changelog</a> |
807 <a href="/log/a4f92ed23982?style=gitweb">changelog</a> |
807 <a href="/file/a4f92ed23982?style=gitweb">files</a>
808 <a href="/file/a4f92ed23982?style=gitweb">files</a>
808 </td>
809 </td>
809 </tr>
810 </tr>
810 <tr class="light">
811 <tr class="light">
811 <td colspan="4"><a class="list" href="#">...</a></td>
812 <td colspan="4"><a class="list" href="#">...</a></td>
812 </tr>
813 </tr>
813 </table>
814 </table>
814 <script type="text/javascript">process_dates()</script>
815 <script type="text/javascript">process_dates()</script>
815 <div class="page_footer">
816 <div class="page_footer">
816 <div class="page_footer_text">test</div>
817 <div class="page_footer_text">test</div>
817 <div class="rss_logo">
818 <div class="rss_logo">
818 <a href="/rss-log">RSS</a>
819 <a href="/rss-log">RSS</a>
819 <a href="/atom-log">Atom</a>
820 <a href="/atom-log">Atom</a>
820 </div>
821 </div>
821 <br />
822 <br />
822
823
823 </div>
824 </div>
824 </body>
825 </body>
825 </html>
826 </html>
826
827
827 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb'
828 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb'
828 200 Script output follows
829 200 Script output follows
829
830
830 <?xml version="1.0" encoding="ascii"?>
831 <?xml version="1.0" encoding="ascii"?>
831 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
832 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
832 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
833 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
833 <head>
834 <head>
834 <link rel="icon" href="/static/hgicon.png" type="image/png" />
835 <link rel="icon" href="/static/hgicon.png" type="image/png" />
835 <meta name="robots" content="index, nofollow"/>
836 <meta name="robots" content="index, nofollow"/>
836 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
837 <link rel="stylesheet" href="/static/style-gitweb.css" type="text/css" />
837 <script type="text/javascript" src="/static/mercurial.js"></script>
838 <script type="text/javascript" src="/static/mercurial.js"></script>
838
839
839 <title>test: Graph</title>
840 <title>test: Graph</title>
840 <link rel="alternate" type="application/atom+xml"
841 <link rel="alternate" type="application/atom+xml"
841 href="/atom-log" title="Atom feed for test"/>
842 href="/atom-log" title="Atom feed for test"/>
842 <link rel="alternate" type="application/rss+xml"
843 <link rel="alternate" type="application/rss+xml"
843 href="/rss-log" title="RSS feed for test"/>
844 href="/rss-log" title="RSS feed for test"/>
844 <!--[if IE]><script type="text/javascript" src="/static/excanvas.js"></script><![endif]-->
845 <!--[if IE]><script type="text/javascript" src="/static/excanvas.js"></script><![endif]-->
845 </head>
846 </head>
846 <body>
847 <body>
847
848
848 <div class="page_header">
849 <div class="page_header">
849 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / graph
850 <a href="http://mercurial.selenic.com/" title="Mercurial" style="float: right;">Mercurial</a><a href="/summary?style=gitweb">test</a> / graph
850 </div>
851 </div>
851
852
852 <form action="/log">
853 <form action="/log">
853 <input type="hidden" name="style" value="gitweb" />
854 <input type="hidden" name="style" value="gitweb" />
854 <div class="search">
855 <div class="search">
855 <input type="text" name="rev" />
856 <input type="text" name="rev" />
856 </div>
857 </div>
857 </form>
858 </form>
858 <div class="page_nav">
859 <div class="page_nav">
859 <a href="/summary?style=gitweb">summary</a> |
860 <a href="/summary?style=gitweb">summary</a> |
860 <a href="/shortlog?style=gitweb">shortlog</a> |
861 <a href="/shortlog?style=gitweb">shortlog</a> |
861 <a href="/log/2?style=gitweb">changelog</a> |
862 <a href="/log/2?style=gitweb">changelog</a> |
862 graph |
863 graph |
863 <a href="/tags?style=gitweb">tags</a> |
864 <a href="/tags?style=gitweb">tags</a> |
864 <a href="/bookmarks?style=gitweb">bookmarks</a> |
865 <a href="/bookmarks?style=gitweb">bookmarks</a> |
865 <a href="/branches?style=gitweb">branches</a> |
866 <a href="/branches?style=gitweb">branches</a> |
866 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
867 <a href="/file/1d22e65f027e?style=gitweb">files</a> |
867 <a href="/help?style=gitweb">help</a>
868 <a href="/help?style=gitweb">help</a>
868 <br/>
869 <br/>
869 <a href="/graph/2?style=gitweb&revcount=30">less</a>
870 <a href="/graph/2?style=gitweb&revcount=30">less</a>
870 <a href="/graph/2?style=gitweb&revcount=120">more</a>
871 <a href="/graph/2?style=gitweb&revcount=120">more</a>
871 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a> <br/>
872 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a> <br/>
872 </div>
873 </div>
873
874
874 <div class="title">&nbsp;</div>
875 <div class="title">&nbsp;</div>
875
876
876 <noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
877 <noscript>The revision graph only works with JavaScript-enabled browsers.</noscript>
877
878
878 <div id="wrapper">
879 <div id="wrapper">
879 <ul id="nodebgs"></ul>
880 <ul id="nodebgs"></ul>
880 <canvas id="graph" width="480" height="129"></canvas>
881 <canvas id="graph" width="480" height="129"></canvas>
881 <ul id="graphnodes"></ul>
882 <ul id="graphnodes"></ul>
882 </div>
883 </div>
883
884
884 <script>
885 <script>
885 <!-- hide script content
886 <!-- hide script content
886
887
887 var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
888 var data = [["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
888 var graph = new Graph();
889 var graph = new Graph();
889 graph.scale(39);
890 graph.scale(39);
890
891
891 graph.edge = function(x0, y0, x1, y1, color) {
892 graph.edge = function(x0, y0, x1, y1, color) {
892
893
893 this.setColor(color, 0.0, 0.65);
894 this.setColor(color, 0.0, 0.65);
894 this.ctx.beginPath();
895 this.ctx.beginPath();
895 this.ctx.moveTo(x0, y0);
896 this.ctx.moveTo(x0, y0);
896 this.ctx.lineTo(x1, y1);
897 this.ctx.lineTo(x1, y1);
897 this.ctx.stroke();
898 this.ctx.stroke();
898
899
899 }
900 }
900
901
901 var revlink = '<li style="_STYLE"><span class="desc">';
902 var revlink = '<li style="_STYLE"><span class="desc">';
902 revlink += '<a class="list" href="/rev/_NODEID?style=gitweb" title="_NODEID"><b>_DESC</b></a>';
903 revlink += '<a class="list" href="/rev/_NODEID?style=gitweb" title="_NODEID"><b>_DESC</b></a>';
903 revlink += '</span> _TAGS';
904 revlink += '</span> _TAGS';
904 revlink += '<span class="info">_DATE, by _USER</span></li>';
905 revlink += '<span class="info">_DATE, by _USER</span></li>';
905
906
906 graph.vertex = function(x, y, color, parity, cur) {
907 graph.vertex = function(x, y, color, parity, cur) {
907
908
908 this.ctx.beginPath();
909 this.ctx.beginPath();
909 color = this.setColor(color, 0.25, 0.75);
910 color = this.setColor(color, 0.25, 0.75);
910 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
911 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
911 this.ctx.fill();
912 this.ctx.fill();
912
913
913 var bg = '<li class="bg parity' + parity + '"></li>';
914 var bg = '<li class="bg parity' + parity + '"></li>';
914 var left = (this.columns + 1) * this.bg_height;
915 var left = (this.columns + 1) * this.bg_height;
915 var nstyle = 'padding-left: ' + left + 'px;';
916 var nstyle = 'padding-left: ' + left + 'px;';
916 var item = revlink.replace(/_STYLE/, nstyle);
917 var item = revlink.replace(/_STYLE/, nstyle);
917 item = item.replace(/_PARITY/, 'parity' + parity);
918 item = item.replace(/_PARITY/, 'parity' + parity);
918 item = item.replace(/_NODEID/, cur[0]);
919 item = item.replace(/_NODEID/, cur[0]);
919 item = item.replace(/_NODEID/, cur[0]);
920 item = item.replace(/_NODEID/, cur[0]);
920 item = item.replace(/_DESC/, cur[3]);
921 item = item.replace(/_DESC/, cur[3]);
921 item = item.replace(/_USER/, cur[4]);
922 item = item.replace(/_USER/, cur[4]);
922 item = item.replace(/_DATE/, cur[5]);
923 item = item.replace(/_DATE/, cur[5]);
923
924
924 var tagspan = '';
925 var tagspan = '';
925 if (cur[7].length || cur[8].length || (cur[6][0] != 'default' || cur[6][1])) {
926 if (cur[7].length || cur[8].length || (cur[6][0] != 'default' || cur[6][1])) {
926 tagspan = '<span class="logtags">';
927 tagspan = '<span class="logtags">';
927 if (cur[6][1]) {
928 if (cur[6][1]) {
928 tagspan += '<span class="branchtag" title="' + cur[6][0] + '">';
929 tagspan += '<span class="branchtag" title="' + cur[6][0] + '">';
929 tagspan += cur[6][0] + '</span> ';
930 tagspan += cur[6][0] + '</span> ';
930 } else if (!cur[6][1] && cur[6][0] != 'default') {
931 } else if (!cur[6][1] && cur[6][0] != 'default') {
931 tagspan += '<span class="inbranchtag" title="' + cur[6][0] + '">';
932 tagspan += '<span class="inbranchtag" title="' + cur[6][0] + '">';
932 tagspan += cur[6][0] + '</span> ';
933 tagspan += cur[6][0] + '</span> ';
933 }
934 }
934 if (cur[7].length) {
935 if (cur[7].length) {
935 for (var t in cur[7]) {
936 for (var t in cur[7]) {
936 var tag = cur[7][t];
937 var tag = cur[7][t];
937 tagspan += '<span class="tagtag">' + tag + '</span> ';
938 tagspan += '<span class="tagtag">' + tag + '</span> ';
938 }
939 }
939 }
940 }
940 if (cur[8].length) {
941 if (cur[8].length) {
941 for (var t in cur[8]) {
942 for (var t in cur[8]) {
942 var bookmark = cur[8][t];
943 var bookmark = cur[8][t];
943 tagspan += '<span class="bookmarktag">' + bookmark + '</span> ';
944 tagspan += '<span class="bookmarktag">' + bookmark + '</span> ';
944 }
945 }
945 }
946 }
946 tagspan += '</span>';
947 tagspan += '</span>';
947 }
948 }
948
949
949 item = item.replace(/_TAGS/, tagspan);
950 item = item.replace(/_TAGS/, tagspan);
950 return [bg, item];
951 return [bg, item];
951
952
952 }
953 }
953
954
954 graph.render(data);
955 graph.render(data);
955
956
956 // stop hiding script -->
957 // stop hiding script -->
957 </script>
958 </script>
958
959
959 <div class="page_nav">
960 <div class="page_nav">
960 <a href="/graph/2?style=gitweb&revcount=30">less</a>
961 <a href="/graph/2?style=gitweb&revcount=30">less</a>
961 <a href="/graph/2?style=gitweb&revcount=120">more</a>
962 <a href="/graph/2?style=gitweb&revcount=120">more</a>
962 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a>
963 | <a href="/graph/2ef0ac749a14?style=gitweb">(0)</a> <a href="/graph/2ef0ac749a14?style=gitweb">-2</a> <a href="/graph/tip?style=gitweb">tip</a>
963 </div>
964 </div>
964
965
965 <script type="text/javascript">process_dates()</script>
966 <script type="text/javascript">process_dates()</script>
966 <div class="page_footer">
967 <div class="page_footer">
967 <div class="page_footer_text">test</div>
968 <div class="page_footer_text">test</div>
968 <div class="rss_logo">
969 <div class="rss_logo">
969 <a href="/rss-log">RSS</a>
970 <a href="/rss-log">RSS</a>
970 <a href="/atom-log">Atom</a>
971 <a href="/atom-log">Atom</a>
971 </div>
972 </div>
972 <br />
973 <br />
973
974
974 </div>
975 </div>
975 </body>
976 </body>
976 </html>
977 </html>
977
978
978
979
979 capabilities
980 capabilities
980
981
981 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo
982 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo
982 200 Script output follows
983 200 Script output follows
983
984
984 lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
985 lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024
985
986
986 heads
987 heads
987
988
988 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=heads'
989 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=heads'
989 200 Script output follows
990 200 Script output follows
990
991
991 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
992 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe
992
993
993 branches
994 branches
994
995
995 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=branches&nodes=0000000000000000000000000000000000000000'
996 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=branches&nodes=0000000000000000000000000000000000000000'
996 200 Script output follows
997 200 Script output follows
997
998
998 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
999 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
999
1000
1000 changegroup
1001 changegroup
1001
1002
1002 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup&roots=0000000000000000000000000000000000000000'
1003 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup&roots=0000000000000000000000000000000000000000'
1003 200 Script output follows
1004 200 Script output follows
1004
1005
1005 x\x9c\xbdTMHUA\x14\xbe\xa8\xf9\xec\xda&\x10\x11*\xb8\x88\x81\x99\xbef\xe6\xce\xbdw\xc6\xf2a\x16E\x1b\x11[%\x98\xcc\xaf\x8f\x8c\xf7\xc0\xf7\x82 (esc)
1006 x\x9c\xbdTMHUA\x14\xbe\xa8\xf9\xec\xda&\x10\x11*\xb8\x88\x81\x99\xbef\xe6\xce\xbdw\xc6\xf2a\x16E\x1b\x11[%\x98\xcc\xaf\x8f\x8c\xf7\xc0\xf7\x82 (esc)
1006 4\x11KP2m\x95\xad*\xabE\x05AP\xd0\xc22Z\x14\xf9\x03\xb9j\xa3\x9b$\xa4MJ\xb4\x90\xc0\x9a\x9bO0\x10\xdf\x13\xa2\x81\x0f\x869g\xe6|\xe7\x9c\xef\x8ceY\xf7\xa2KO\xd2\xb7K\x16~\\n\xe9\xad\x90w\x86\xab\x93W\x8e\xdf\xb0r\\Y\xee6(\xa2)\xf6\x95\xc6\x01\xe4\x1az\x80R\xe8kN\x98\xe7R\xa4\xa9K@\xe0!A\xb4k\xa7U*m\x03\x07\xd8\x92\x1d\xd2\xc9\xa4\x1d\xc2\xe6,\xa5\xcc+\x1f\xef\xafDgi\xef\xab\x1d\x1d\xb7\x9a\xe7[W\xfbc\x8f\xde-\xcd\xe7\xcaz\xb3\xbb\x19\xd3\x81\x10>c>\x08\x00"X\x11\xc2\x84@\xd2\xe7B*L\x00\x01P\x04R\xc3@\xbaB0\xdb8#\x83:\x83\xa2h\xbc=\xcd\xdaS\xe1Y,L\xd3\xa0\xf2\xa8\x94J:\xe6\xd8\x81Q\xe0\xe8d\xa7#\xe2,\xd1\xaeR*\xed \xa5\x01\x13\x01\xa6\x0cb\xe3;\xbe\xaf\xfcK[^wK\xe1N\xaf\xbbk\xe8B\xd1\xf4\xc1\x07\xb3\xab[\x10\xfdkmvwcB\xa6\xa4\xd4G\xc4D\xc2\x141\xad\x91\x10\x00\x08J\x81\xcb}\xee \xee+W\xba\x8a\x80\x90|\xd4\xa0\xd6\xa0\xd4T\xde\xe1\x9d,!\xe2\xb5\xa94\xe3\xe7\xd5\x9f\x06\x18\xcba\x03aP\xb8f\xcd\x04\x1a_\\9\xf1\xed\xe4\x9e\xe5\xa6\xd1\xd2\x9f\x03\xa7o\xae\x90H\xf3\xfb\xef\xffH3\xadk (esc)
1007 4\x11KP2m\x95\xad*\xabE\x05AP\xd0\xc22Z\x14\xf9\x03\xb9j\xa3\x9b$\xa4MJ\xb4\x90\xc0\x9a\x9bO0\x10\xdf\x13\xa2\x81\x0f\x869g\xe6|\xe7\x9c\xef\x8ceY\xf7\xa2KO\xd2\xb7K\x16~\\n\xe9\xad\x90w\x86\xab\x93W\x8e\xdf\xb0r\\Y\xee6(\xa2)\xf6\x95\xc6\x01\xe4\x1az\x80R\xe8kN\x98\xe7R\xa4\xa9K@\xe0!A\xb4k\xa7U*m\x03\x07\xd8\x92\x1d\xd2\xc9\xa4\x1d\xc2\xe6,\xa5\xcc+\x1f\xef\xafDgi\xef\xab\x1d\x1d\xb7\x9a\xe7[W\xfbc\x8f\xde-\xcd\xe7\xcaz\xb3\xbb\x19\xd3\x81\x10>c>\x08\x00"X\x11\xc2\x84@\xd2\xe7B*L\x00\x01P\x04R\xc3@\xbaB0\xdb8#\x83:\x83\xa2h\xbc=\xcd\xdaS\xe1Y,L\xd3\xa0\xf2\xa8\x94J:\xe6\xd8\x81Q\xe0\xe8d\xa7#\xe2,\xd1\xaeR*\xed \xa5\x01\x13\x01\xa6\x0cb\xe3;\xbe\xaf\xfcK[^wK\xe1N\xaf\xbbk\xe8B\xd1\xf4\xc1\x07\xb3\xab[\x10\xfdkmvwcB\xa6\xa4\xd4G\xc4D\xc2\x141\xad\x91\x10\x00\x08J\x81\xcb}\xee \xee+W\xba\x8a\x80\x90|\xd4\xa0\xd6\xa0\xd4T\xde\xe1\x9d,!\xe2\xb5\xa94\xe3\xe7\xd5\x9f\x06\x18\xcba\x03aP\xb8f\xcd\x04\x1a_\\9\xf1\xed\xe4\x9e\xe5\xa6\xd1\xd2\x9f\x03\xa7o\xae\x90H\xf3\xfb\xef\xffH3\xadk (esc)
1007 \xb0\x90\x92\x88\xb9\x14"\x068\xc2\x1e@\x00\xbb\x8a)\xd3'\x859 (esc)
1008 \xb0\x90\x92\x88\xb9\x14"\x068\xc2\x1e@\x00\xbb\x8a)\xd3'\x859 (esc)
1008 \xa8\x80\x84S \xa5\xbd-g\x13`\xe4\xdc\xc3H^\xdf\xe2\xc0TM\xc7\xf4BO\xcf\xde\xae\xe5\xae#\x1frM(K\x97`F\x19\x16s\x05GD\xb9\x01\xc1\x00+\x8c|\x9fp\xc11\xf0\x14\x00\x9cJ\x82<\xe0\x12\x9f\xc1\x90\xd0\xf5\xc8\x19>Pr\xaa\xeaW\xf5\xc4\xae\xd1\xfc\x17\xcf'\x13u\xb1\x9e\xcdHnC\x0e\xcc`\xc8\xa0&\xac\x0e\xf1|\x8c\x10$\xc4\x8c\xa2p\x05`\xdc\x08 \x80\xc4\xd7Rr-\x94\x10\x102\xedi;\xf3f\xf1z\x16\x86\xdb\xd8d\xe5\xe7\x8b\xf5\x8d\rzp\xb2\xfe\xac\xf5\xf2\xd3\xfe\xfckws\xedt\x96b\xd5l\x1c\x0b\x85\xb5\x170\x8f\x11\x84\xb0\x8f\x19\xa0\x00 _\x07\x1ac\xa2\xc3\x89Z\xe7\x96\xf9 \xccNFg\xc7F\xaa\x8a+\x9a\x9cc_\x17\x1b\x17\x9e]z38<\x97+\xb5,",\xc8\xc8?\\\x91\xff\x17.~U\x96\x97\xf5%\xdeN<\x8e\xf5\x97%\xe7^\xcfL\xed~\xda\x96k\xdc->\x86\x02\x83"\x96H\xa6\xe3\xaas=-\xeb7\xe5\xda\x8f\xbc (no-eol) (esc)
1009 \xa8\x80\x84S \xa5\xbd-g\x13`\xe4\xdc\xc3H^\xdf\xe2\xc0TM\xc7\xf4BO\xcf\xde\xae\xe5\xae#\x1frM(K\x97`F\x19\x16s\x05GD\xb9\x01\xc1\x00+\x8c|\x9fp\xc11\xf0\x14\x00\x9cJ\x82<\xe0\x12\x9f\xc1\x90\xd0\xf5\xc8\x19>Pr\xaa\xeaW\xf5\xc4\xae\xd1\xfc\x17\xcf'\x13u\xb1\x9e\xcdHnC\x0e\xcc`\xc8\xa0&\xac\x0e\xf1|\x8c\x10$\xc4\x8c\xa2p\x05`\xdc\x08 \x80\xc4\xd7Rr-\x94\x10\x102\xedi;\xf3f\xf1z\x16\x86\xdb\xd8d\xe5\xe7\x8b\xf5\x8d\rzp\xb2\xfe\xac\xf5\xf2\xd3\xfe\xfckws\xedt\x96b\xd5l\x1c\x0b\x85\xb5\x170\x8f\x11\x84\xb0\x8f\x19\xa0\x00 _\x07\x1ac\xa2\xc3\x89Z\xe7\x96\xf9 \xccNFg\xc7F\xaa\x8a+\x9a\x9cc_\x17\x1b\x17\x9e]z38<\x97+\xb5,",\xc8\xc8?\\\x91\xff\x17.~U\x96\x97\xf5%\xdeN<\x8e\xf5\x97%\xe7^\xcfL\xed~\xda\x96k\xdc->\x86\x02\x83"\x96H\xa6\xe3\xaas=-\xeb7\xe5\xda\x8f\xbc (no-eol) (esc)
1009
1010
1010 stream_out
1011 stream_out
1011
1012
1012 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=stream_out'
1013 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=stream_out'
1013 200 Script output follows
1014 200 Script output follows
1014
1015
1015 1
1016 1
1016
1017
1017 failing unbundle, requires POST request
1018 failing unbundle, requires POST request
1018
1019
1019 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=unbundle'
1020 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=unbundle'
1020 405 push requires POST request
1021 405 push requires POST request
1021
1022
1022 0
1023 0
1023 push requires POST request
1024 push requires POST request
1024 [1]
1025 [1]
1025
1026
1026 Static files
1027 Static files
1027
1028
1028 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/static/style.css'
1029 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/static/style.css'
1029 200 Script output follows
1030 200 Script output follows
1030
1031
1031 a { text-decoration:none; }
1032 a { text-decoration:none; }
1032 .age { white-space:nowrap; }
1033 .age { white-space:nowrap; }
1033 .date { white-space:nowrap; }
1034 .date { white-space:nowrap; }
1034 .indexlinks { white-space:nowrap; }
1035 .indexlinks { white-space:nowrap; }
1035 .parity0 { background-color: #ddd; }
1036 .parity0 { background-color: #ddd; }
1036 .parity1 { background-color: #eee; }
1037 .parity1 { background-color: #eee; }
1037 .lineno { width: 60px; color: #aaa; font-size: smaller;
1038 .lineno { width: 60px; color: #aaa; font-size: smaller;
1038 text-align: right; }
1039 text-align: right; }
1039 .plusline { color: green; }
1040 .plusline { color: green; }
1040 .minusline { color: red; }
1041 .minusline { color: red; }
1041 .atline { color: purple; }
1042 .atline { color: purple; }
1042 .annotate { font-size: smaller; text-align: right; padding-right: 1em; }
1043 .annotate { font-size: smaller; text-align: right; padding-right: 1em; }
1043 .buttons a {
1044 .buttons a {
1044 background-color: #666;
1045 background-color: #666;
1045 padding: 2pt;
1046 padding: 2pt;
1046 color: white;
1047 color: white;
1047 font-family: sans;
1048 font-family: sans;
1048 font-weight: bold;
1049 font-weight: bold;
1049 }
1050 }
1050 .navigate a {
1051 .navigate a {
1051 background-color: #ccc;
1052 background-color: #ccc;
1052 padding: 2pt;
1053 padding: 2pt;
1053 font-family: sans;
1054 font-family: sans;
1054 color: black;
1055 color: black;
1055 }
1056 }
1056
1057
1057 .metatag {
1058 .metatag {
1058 background-color: #888;
1059 background-color: #888;
1059 color: white;
1060 color: white;
1060 text-align: right;
1061 text-align: right;
1061 }
1062 }
1062
1063
1063 /* Common */
1064 /* Common */
1064 pre { margin: 0; }
1065 pre { margin: 0; }
1065
1066
1066 .logo {
1067 .logo {
1067 float: right;
1068 float: right;
1068 clear: right;
1069 clear: right;
1069 }
1070 }
1070
1071
1071 /* Changelog/Filelog entries */
1072 /* Changelog/Filelog entries */
1072 .logEntry { width: 100%; }
1073 .logEntry { width: 100%; }
1073 .logEntry .age { width: 15%; }
1074 .logEntry .age { width: 15%; }
1074 .logEntry th { font-weight: normal; text-align: right; vertical-align: top; }
1075 .logEntry th { font-weight: normal; text-align: right; vertical-align: top; }
1075 .logEntry th.age, .logEntry th.firstline { font-weight: bold; }
1076 .logEntry th.age, .logEntry th.firstline { font-weight: bold; }
1076 .logEntry th.firstline { text-align: left; width: inherit; }
1077 .logEntry th.firstline { text-align: left; width: inherit; }
1077
1078
1078 /* Shortlog entries */
1079 /* Shortlog entries */
1079 .slogEntry { width: 100%; }
1080 .slogEntry { width: 100%; }
1080 .slogEntry .age { width: 8em; }
1081 .slogEntry .age { width: 8em; }
1081 .slogEntry td { font-weight: normal; text-align: left; vertical-align: top; }
1082 .slogEntry td { font-weight: normal; text-align: left; vertical-align: top; }
1082 .slogEntry td.author { width: 15em; }
1083 .slogEntry td.author { width: 15em; }
1083
1084
1084 /* Tag entries */
1085 /* Tag entries */
1085 #tagEntries { list-style: none; margin: 0; padding: 0; }
1086 #tagEntries { list-style: none; margin: 0; padding: 0; }
1086 #tagEntries .tagEntry { list-style: none; margin: 0; padding: 0; }
1087 #tagEntries .tagEntry { list-style: none; margin: 0; padding: 0; }
1087
1088
1088 /* Changeset entry */
1089 /* Changeset entry */
1089 #changesetEntry { }
1090 #changesetEntry { }
1090 #changesetEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1091 #changesetEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1091 #changesetEntry th.files, #changesetEntry th.description { vertical-align: top; }
1092 #changesetEntry th.files, #changesetEntry th.description { vertical-align: top; }
1092
1093
1093 /* File diff view */
1094 /* File diff view */
1094 #filediffEntry { }
1095 #filediffEntry { }
1095 #filediffEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1096 #filediffEntry th { font-weight: normal; background-color: #888; color: #fff; text-align: right; }
1096
1097
1097 /* Graph */
1098 /* Graph */
1098 div#wrapper {
1099 div#wrapper {
1099 position: relative;
1100 position: relative;
1100 margin: 0;
1101 margin: 0;
1101 padding: 0;
1102 padding: 0;
1102 }
1103 }
1103
1104
1104 canvas {
1105 canvas {
1105 position: absolute;
1106 position: absolute;
1106 z-index: 5;
1107 z-index: 5;
1107 top: -0.6em;
1108 top: -0.6em;
1108 margin: 0;
1109 margin: 0;
1109 }
1110 }
1110
1111
1111 ul#nodebgs {
1112 ul#nodebgs {
1112 list-style: none inside none;
1113 list-style: none inside none;
1113 padding: 0;
1114 padding: 0;
1114 margin: 0;
1115 margin: 0;
1115 top: -0.7em;
1116 top: -0.7em;
1116 }
1117 }
1117
1118
1118 ul#graphnodes li, ul#nodebgs li {
1119 ul#graphnodes li, ul#nodebgs li {
1119 height: 39px;
1120 height: 39px;
1120 }
1121 }
1121
1122
1122 ul#graphnodes {
1123 ul#graphnodes {
1123 position: absolute;
1124 position: absolute;
1124 z-index: 10;
1125 z-index: 10;
1125 top: -0.85em;
1126 top: -0.85em;
1126 list-style: none inside none;
1127 list-style: none inside none;
1127 padding: 0;
1128 padding: 0;
1128 }
1129 }
1129
1130
1130 ul#graphnodes li .info {
1131 ul#graphnodes li .info {
1131 display: block;
1132 display: block;
1132 font-size: 70%;
1133 font-size: 70%;
1133 position: relative;
1134 position: relative;
1134 top: -1px;
1135 top: -1px;
1135 }
1136 }
1136
1137
1137 Stop and restart with HGENCODING=cp932
1138 Stop and restart with HGENCODING=cp932
1138
1139
1139 $ "$TESTDIR/killdaemons.py"
1140 $ "$TESTDIR/killdaemons.py"
1140 $ HGENCODING=cp932 hg serve --config server.uncompressed=False -n test \
1141 $ HGENCODING=cp932 hg serve --config server.uncompressed=False -n test \
1141 > -p $HGPORT -d --pid-file=hg.pid -E errors.log
1142 > -p $HGPORT -d --pid-file=hg.pid -E errors.log
1142 $ cat hg.pid >> $DAEMON_PIDS
1143 $ cat hg.pid >> $DAEMON_PIDS
1143
1144
1144 commit message with Japanese Kanji 'Noh', which ends with '\x5c'
1145 commit message with Japanese Kanji 'Noh', which ends with '\x5c'
1145
1146
1146 $ echo foo >> foo
1147 $ echo foo >> foo
1147 $ HGENCODING=cp932 hg ci -m `python -c 'print("\x94\x5c")'`
1148 $ HGENCODING=cp932 hg ci -m `python -c 'print("\x94\x5c")'`
1148
1149
1149 Graph json escape of multibyte character
1150 Graph json escape of multibyte character
1150
1151
1151 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/' \
1152 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/' \
1152 > | grep '^var data ='
1153 > | grep '^var data ='
1153 var data = [["40b4d6888e92", [0, 1], [[0, 0, 1]], "\u80fd", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", false], [], []], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
1154 var data = [["40b4d6888e92", [0, 1], [[0, 0, 1]], "\u80fd", "test", "1970-01-01", ["stable", true], ["tip"], ["something"]], ["1d22e65f027e", [0, 1], [[0, 0, 1]], "branch", "test", "1970-01-01", ["stable", false], [], []], ["a4f92ed23982", [0, 1], [[0, 0, 1]], "Added tag 1.0 for changeset 2ef0ac749a14", "test", "1970-01-01", ["default", true], [], []], ["2ef0ac749a14", [0, 1], [], "base", "test", "1970-01-01", ["default", false], ["1.0"], ["anotherthing"]]];
1154
1155
1155 ERRORS ENCOUNTERED
1156 ERRORS ENCOUNTERED
1156
1157
1157 $ cat errors.log
1158 $ cat errors.log
@@ -1,92 +1,93 b''
1
1
2 $ hgserve() {
2 $ hgserve() {
3 > hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -E errors.log -v $@
3 > hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid -E errors.log -v $@
4 > cat hg.pid >> "$DAEMON_PIDS"
4 > cat hg.pid >> "$DAEMON_PIDS"
5 > }
5 > }
6 $ hg init a
6 $ hg init a
7 $ hg --encoding utf-8 -R a branch æ
7 $ hg --encoding utf-8 -R a branch æ
8 marked working directory as branch \xc3\xa6 (esc)
8 marked working directory as branch \xc3\xa6 (esc)
9 (branches are permanent and global, did you want a bookmark?)
9 $ echo foo > a/foo
10 $ echo foo > a/foo
10 $ hg -R a ci -Am foo
11 $ hg -R a ci -Am foo
11 adding foo
12 adding foo
12 $ hgserve -R a --config web.push_ssl=False --config web.allow_push=* --encoding latin1
13 $ hgserve -R a --config web.push_ssl=False --config web.allow_push=* --encoding latin1
13 listening at http://*:$HGPORT1/ (bound to 127.0.0.1:$HGPORT1) (glob)
14 listening at http://*:$HGPORT1/ (bound to 127.0.0.1:$HGPORT1) (glob)
14 $ hg --encoding utf-8 clone http://localhost:$HGPORT1 b
15 $ hg --encoding utf-8 clone http://localhost:$HGPORT1 b
15 requesting all changes
16 requesting all changes
16 adding changesets
17 adding changesets
17 adding manifests
18 adding manifests
18 adding file changes
19 adding file changes
19 added 1 changesets with 1 changes to 1 files
20 added 1 changesets with 1 changes to 1 files
20 updating to branch \xc3\xa6 (esc)
21 updating to branch \xc3\xa6 (esc)
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 $ hg --encoding utf-8 -R b log
23 $ hg --encoding utf-8 -R b log
23 changeset: 0:867c11ce77b8
24 changeset: 0:867c11ce77b8
24 branch: \xc3\xa6 (esc)
25 branch: \xc3\xa6 (esc)
25 tag: tip
26 tag: tip
26 user: test
27 user: test
27 date: Thu Jan 01 00:00:00 1970 +0000
28 date: Thu Jan 01 00:00:00 1970 +0000
28 summary: foo
29 summary: foo
29
30
30 $ echo bar >> b/foo
31 $ echo bar >> b/foo
31 $ hg -R b ci -m bar
32 $ hg -R b ci -m bar
32 $ hg --encoding utf-8 -R b push
33 $ hg --encoding utf-8 -R b push
33 pushing to http://localhost:$HGPORT1/
34 pushing to http://localhost:$HGPORT1/
34 searching for changes
35 searching for changes
35 remote: adding changesets
36 remote: adding changesets
36 remote: adding manifests
37 remote: adding manifests
37 remote: adding file changes
38 remote: adding file changes
38 remote: added 1 changesets with 1 changes to 1 files
39 remote: added 1 changesets with 1 changes to 1 files
39 $ hg -R a --encoding utf-8 log
40 $ hg -R a --encoding utf-8 log
40 changeset: 1:58e7c90d67cb
41 changeset: 1:58e7c90d67cb
41 branch: \xc3\xa6 (esc)
42 branch: \xc3\xa6 (esc)
42 tag: tip
43 tag: tip
43 user: test
44 user: test
44 date: Thu Jan 01 00:00:00 1970 +0000
45 date: Thu Jan 01 00:00:00 1970 +0000
45 summary: bar
46 summary: bar
46
47
47 changeset: 0:867c11ce77b8
48 changeset: 0:867c11ce77b8
48 branch: \xc3\xa6 (esc)
49 branch: \xc3\xa6 (esc)
49 user: test
50 user: test
50 date: Thu Jan 01 00:00:00 1970 +0000
51 date: Thu Jan 01 00:00:00 1970 +0000
51 summary: foo
52 summary: foo
52
53
53 $ kill `cat hg.pid`
54 $ kill `cat hg.pid`
54
55
55 verify 7e7d56fe4833 (encoding fallback in branchmap to maintain compatibility with 1.3.x)
56 verify 7e7d56fe4833 (encoding fallback in branchmap to maintain compatibility with 1.3.x)
56
57
57 $ cat <<EOF > oldhg
58 $ cat <<EOF > oldhg
58 > import sys
59 > import sys
59 > from mercurial import ui, hg, commands
60 > from mercurial import ui, hg, commands
60 >
61 >
61 > class StdoutWrapper(object):
62 > class StdoutWrapper(object):
62 > def __init__(self, stdout):
63 > def __init__(self, stdout):
63 > self._file = stdout
64 > self._file = stdout
64 >
65 >
65 > def write(self, data):
66 > def write(self, data):
66 > if data == '47\n':
67 > if data == '47\n':
67 > # latin1 encoding is one %xx (3 bytes) shorter
68 > # latin1 encoding is one %xx (3 bytes) shorter
68 > data = '44\n'
69 > data = '44\n'
69 > elif data.startswith('%C3%A6 '):
70 > elif data.startswith('%C3%A6 '):
70 > # translate to latin1 encoding
71 > # translate to latin1 encoding
71 > data = '%%E6 %s' % data[7:]
72 > data = '%%E6 %s' % data[7:]
72 > self._file.write(data)
73 > self._file.write(data)
73 >
74 >
74 > def __getattr__(self, name):
75 > def __getattr__(self, name):
75 > return getattr(self._file, name)
76 > return getattr(self._file, name)
76 >
77 >
77 > sys.stdout = StdoutWrapper(sys.stdout)
78 > sys.stdout = StdoutWrapper(sys.stdout)
78 > sys.stderr = StdoutWrapper(sys.stderr)
79 > sys.stderr = StdoutWrapper(sys.stderr)
79 >
80 >
80 > myui = ui.ui()
81 > myui = ui.ui()
81 > repo = hg.repository(myui, 'a')
82 > repo = hg.repository(myui, 'a')
82 > commands.serve(myui, repo, stdio=True, cmdserver=False)
83 > commands.serve(myui, repo, stdio=True, cmdserver=False)
83 > EOF
84 > EOF
84 $ echo baz >> b/foo
85 $ echo baz >> b/foo
85 $ hg -R b ci -m baz
86 $ hg -R b ci -m baz
86 $ hg push -R b -e 'python oldhg' ssh://dummy/ --encoding latin1
87 $ hg push -R b -e 'python oldhg' ssh://dummy/ --encoding latin1
87 pushing to ssh://dummy/
88 pushing to ssh://dummy/
88 searching for changes
89 searching for changes
89 remote: adding changesets
90 remote: adding changesets
90 remote: adding manifests
91 remote: adding manifests
91 remote: adding file changes
92 remote: adding file changes
92 remote: added 1 changesets with 1 changes to 1 files
93 remote: added 1 changesets with 1 changes to 1 files
@@ -1,56 +1,57 b''
1 $ cat >findbranch.py <<EOF
1 $ cat >findbranch.py <<EOF
2 > import re, sys
2 > import re, sys
3 >
3 >
4 > head_re = re.compile('^#(?:(?:\\s+([A-Za-z][A-Za-z0-9_]*)(?:\\s.*)?)|(?:\\s*))$')
4 > head_re = re.compile('^#(?:(?:\\s+([A-Za-z][A-Za-z0-9_]*)(?:\\s.*)?)|(?:\\s*))$')
5 >
5 >
6 > for line in sys.stdin:
6 > for line in sys.stdin:
7 > hmatch = head_re.match(line)
7 > hmatch = head_re.match(line)
8 > if not hmatch:
8 > if not hmatch:
9 > sys.exit(1)
9 > sys.exit(1)
10 > if hmatch.group(1) == 'Branch':
10 > if hmatch.group(1) == 'Branch':
11 > sys.exit(0)
11 > sys.exit(0)
12 > sys.exit(1)
12 > sys.exit(1)
13 > EOF
13 > EOF
14
14
15 $ hg init a
15 $ hg init a
16 $ cd a
16 $ cd a
17 $ echo "Rev 1" >rev
17 $ echo "Rev 1" >rev
18 $ hg add rev
18 $ hg add rev
19 $ hg commit -m "No branch."
19 $ hg commit -m "No branch."
20 $ hg branch abranch
20 $ hg branch abranch
21 marked working directory as branch abranch
21 marked working directory as branch abranch
22 (branches are permanent and global, did you want a bookmark?)
22 $ echo "Rev 2" >rev
23 $ echo "Rev 2" >rev
23 $ hg commit -m "With branch."
24 $ hg commit -m "With branch."
24
25
25 $ hg export 0 > ../r0.patch
26 $ hg export 0 > ../r0.patch
26 $ hg export 1 > ../r1.patch
27 $ hg export 1 > ../r1.patch
27 $ cd ..
28 $ cd ..
28
29
29 $ if python findbranch.py < r0.patch; then
30 $ if python findbranch.py < r0.patch; then
30 > echo "Export of default branch revision has Branch header" 1>&2
31 > echo "Export of default branch revision has Branch header" 1>&2
31 > exit 1
32 > exit 1
32 > fi
33 > fi
33
34
34 $ if python findbranch.py < r1.patch; then
35 $ if python findbranch.py < r1.patch; then
35 > : # Do nothing
36 > : # Do nothing
36 > else
37 > else
37 > echo "Export of branch revision is missing Branch header" 1>&2
38 > echo "Export of branch revision is missing Branch header" 1>&2
38 > exit 1
39 > exit 1
39 > fi
40 > fi
40
41
41 Make sure import still works with branch information in patches.
42 Make sure import still works with branch information in patches.
42
43
43 $ hg init b
44 $ hg init b
44 $ cd b
45 $ cd b
45 $ hg import ../r0.patch
46 $ hg import ../r0.patch
46 applying ../r0.patch
47 applying ../r0.patch
47 $ hg import ../r1.patch
48 $ hg import ../r1.patch
48 applying ../r1.patch
49 applying ../r1.patch
49 $ cd ..
50 $ cd ..
50
51
51 $ hg init c
52 $ hg init c
52 $ cd c
53 $ cd c
53 $ hg import --exact ../r0.patch
54 $ hg import --exact ../r0.patch
54 applying ../r0.patch
55 applying ../r0.patch
55 $ hg import --exact ../r1.patch
56 $ hg import --exact ../r1.patch
56 applying ../r1.patch
57 applying ../r1.patch
@@ -1,256 +1,257 b''
1 $ echo "[extensions]" >> $HGRCPATH
1 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "purge=" >> $HGRCPATH
2 $ echo "purge=" >> $HGRCPATH
3 $ echo "graphlog=" >> $HGRCPATH
3 $ echo "graphlog=" >> $HGRCPATH
4
4
5 $ shortlog() {
5 $ shortlog() {
6 > hg glog --template '{rev}:{node|short} {author} {date|hgdate} - {branch} - {desc|firstline}\n'
6 > hg glog --template '{rev}:{node|short} {author} {date|hgdate} - {branch} - {desc|firstline}\n'
7 > }
7 > }
8
8
9 Test --bypass with other options
9 Test --bypass with other options
10
10
11 $ hg init repo-options
11 $ hg init repo-options
12 $ cd repo-options
12 $ cd repo-options
13 $ echo a > a
13 $ echo a > a
14 $ hg ci -Am adda
14 $ hg ci -Am adda
15 adding a
15 adding a
16 $ echo a >> a
16 $ echo a >> a
17 $ hg branch foo
17 $ hg branch foo
18 marked working directory as branch foo
18 marked working directory as branch foo
19 (branches are permanent and global, did you want a bookmark?)
19 $ hg ci -Am changea
20 $ hg ci -Am changea
20 $ hg export . > ../test.diff
21 $ hg export . > ../test.diff
21 $ hg up null
22 $ hg up null
22 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
23 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
23
24
24 Test importing an existing revision
25 Test importing an existing revision
25
26
26 $ hg import --bypass --exact ../test.diff
27 $ hg import --bypass --exact ../test.diff
27 applying ../test.diff
28 applying ../test.diff
28 $ shortlog
29 $ shortlog
29 o 1:4e322f7ce8e3 test 0 0 - foo - changea
30 o 1:4e322f7ce8e3 test 0 0 - foo - changea
30 |
31 |
31 o 0:07f494440405 test 0 0 - default - adda
32 o 0:07f494440405 test 0 0 - default - adda
32
33
33
34
34 Test failure without --exact
35 Test failure without --exact
35
36
36 $ hg import --bypass ../test.diff
37 $ hg import --bypass ../test.diff
37 applying ../test.diff
38 applying ../test.diff
38 unable to find 'a' for patching
39 unable to find 'a' for patching
39 abort: patch failed to apply
40 abort: patch failed to apply
40 [255]
41 [255]
41 $ hg st
42 $ hg st
42 $ shortlog
43 $ shortlog
43 o 1:4e322f7ce8e3 test 0 0 - foo - changea
44 o 1:4e322f7ce8e3 test 0 0 - foo - changea
44 |
45 |
45 o 0:07f494440405 test 0 0 - default - adda
46 o 0:07f494440405 test 0 0 - default - adda
46
47
47
48
48 Test --user, --date and --message
49 Test --user, --date and --message
49
50
50 $ hg up 0
51 $ hg up 0
51 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
52 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
52 $ hg import --bypass --u test2 -d '1 0' -m patch2 ../test.diff
53 $ hg import --bypass --u test2 -d '1 0' -m patch2 ../test.diff
53 applying ../test.diff
54 applying ../test.diff
54 $ cat .hg/last-message.txt
55 $ cat .hg/last-message.txt
55 patch2 (no-eol)
56 patch2 (no-eol)
56 $ shortlog
57 $ shortlog
57 o 2:2e127d1da504 test2 1 0 - default - patch2
58 o 2:2e127d1da504 test2 1 0 - default - patch2
58 |
59 |
59 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
60 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
60 |/
61 |/
61 @ 0:07f494440405 test 0 0 - default - adda
62 @ 0:07f494440405 test 0 0 - default - adda
62
63
63 $ hg rollback
64 $ hg rollback
64 repository tip rolled back to revision 1 (undo import)
65 repository tip rolled back to revision 1 (undo import)
65
66
66 Test --import-branch
67 Test --import-branch
67
68
68 $ hg import --bypass --import-branch ../test.diff
69 $ hg import --bypass --import-branch ../test.diff
69 applying ../test.diff
70 applying ../test.diff
70 $ shortlog
71 $ shortlog
71 o 1:4e322f7ce8e3 test 0 0 - foo - changea
72 o 1:4e322f7ce8e3 test 0 0 - foo - changea
72 |
73 |
73 @ 0:07f494440405 test 0 0 - default - adda
74 @ 0:07f494440405 test 0 0 - default - adda
74
75
75 $ hg rollback
76 $ hg rollback
76 repository tip rolled back to revision 1 (undo import)
77 repository tip rolled back to revision 1 (undo import)
77
78
78 Test --strip
79 Test --strip
79
80
80 $ hg import --bypass --strip 0 - <<EOF
81 $ hg import --bypass --strip 0 - <<EOF
81 > # HG changeset patch
82 > # HG changeset patch
82 > # User test
83 > # User test
83 > # Date 0 0
84 > # Date 0 0
84 > # Branch foo
85 > # Branch foo
85 > # Node ID 4e322f7ce8e3e4203950eac9ece27bf7e45ffa6c
86 > # Node ID 4e322f7ce8e3e4203950eac9ece27bf7e45ffa6c
86 > # Parent 07f4944404050f47db2e5c5071e0e84e7a27bba9
87 > # Parent 07f4944404050f47db2e5c5071e0e84e7a27bba9
87 > changea
88 > changea
88 >
89 >
89 > diff -r 07f494440405 -r 4e322f7ce8e3 a
90 > diff -r 07f494440405 -r 4e322f7ce8e3 a
90 > --- a Thu Jan 01 00:00:00 1970 +0000
91 > --- a Thu Jan 01 00:00:00 1970 +0000
91 > +++ a Thu Jan 01 00:00:00 1970 +0000
92 > +++ a Thu Jan 01 00:00:00 1970 +0000
92 > @@ -1,1 +1,2 @@
93 > @@ -1,1 +1,2 @@
93 > a
94 > a
94 > +a
95 > +a
95 > EOF
96 > EOF
96 applying patch from stdin
97 applying patch from stdin
97 $ hg rollback
98 $ hg rollback
98 repository tip rolled back to revision 1 (undo import)
99 repository tip rolled back to revision 1 (undo import)
99
100
100 Test unsupported combinations
101 Test unsupported combinations
101
102
102 $ hg import --bypass --no-commit ../test.diff
103 $ hg import --bypass --no-commit ../test.diff
103 abort: cannot use --no-commit with --bypass
104 abort: cannot use --no-commit with --bypass
104 [255]
105 [255]
105 $ hg import --bypass --similarity 50 ../test.diff
106 $ hg import --bypass --similarity 50 ../test.diff
106 abort: cannot use --similarity with --bypass
107 abort: cannot use --similarity with --bypass
107 [255]
108 [255]
108
109
109 Test commit editor
110 Test commit editor
110
111
111 $ hg diff -c 1 > ../test.diff
112 $ hg diff -c 1 > ../test.diff
112 $ HGEDITOR=cat hg import --bypass ../test.diff
113 $ HGEDITOR=cat hg import --bypass ../test.diff
113 applying ../test.diff
114 applying ../test.diff
114
115
115
116
116 HG: Enter commit message. Lines beginning with 'HG:' are removed.
117 HG: Enter commit message. Lines beginning with 'HG:' are removed.
117 HG: Leave message empty to abort commit.
118 HG: Leave message empty to abort commit.
118 HG: --
119 HG: --
119 HG: user: test
120 HG: user: test
120 HG: branch 'default'
121 HG: branch 'default'
121 HG: changed a
122 HG: changed a
122 abort: empty commit message
123 abort: empty commit message
123 [255]
124 [255]
124
125
125 Test patch.eol is handled
126 Test patch.eol is handled
126
127
127 $ python -c 'file("a", "wb").write("a\r\n")'
128 $ python -c 'file("a", "wb").write("a\r\n")'
128 $ hg ci -m makeacrlf
129 $ hg ci -m makeacrlf
129 $ hg import -m 'should fail because of eol' --bypass ../test.diff
130 $ hg import -m 'should fail because of eol' --bypass ../test.diff
130 applying ../test.diff
131 applying ../test.diff
131 patching file a
132 patching file a
132 Hunk #1 FAILED at 0
133 Hunk #1 FAILED at 0
133 abort: patch failed to apply
134 abort: patch failed to apply
134 [255]
135 [255]
135 $ hg --config patch.eol=auto import -d '0 0' -m 'test patch.eol' --bypass ../test.diff
136 $ hg --config patch.eol=auto import -d '0 0' -m 'test patch.eol' --bypass ../test.diff
136 applying ../test.diff
137 applying ../test.diff
137 $ shortlog
138 $ shortlog
138 o 3:d7805b4d2cb3 test 0 0 - default - test patch.eol
139 o 3:d7805b4d2cb3 test 0 0 - default - test patch.eol
139 |
140 |
140 @ 2:872023de769d test 0 0 - default - makeacrlf
141 @ 2:872023de769d test 0 0 - default - makeacrlf
141 |
142 |
142 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
143 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
143 |/
144 |/
144 o 0:07f494440405 test 0 0 - default - adda
145 o 0:07f494440405 test 0 0 - default - adda
145
146
146
147
147 Test applying multiple patches
148 Test applying multiple patches
148
149
149 $ hg up -qC 0
150 $ hg up -qC 0
150 $ echo e > e
151 $ echo e > e
151 $ hg ci -Am adde
152 $ hg ci -Am adde
152 adding e
153 adding e
153 created new head
154 created new head
154 $ hg export . > ../patch1.diff
155 $ hg export . > ../patch1.diff
155 $ hg up -qC 1
156 $ hg up -qC 1
156 $ echo f > f
157 $ echo f > f
157 $ hg ci -Am addf
158 $ hg ci -Am addf
158 adding f
159 adding f
159 $ hg export . > ../patch2.diff
160 $ hg export . > ../patch2.diff
160 $ cd ..
161 $ cd ..
161 $ hg clone -r1 repo-options repo-multi1
162 $ hg clone -r1 repo-options repo-multi1
162 adding changesets
163 adding changesets
163 adding manifests
164 adding manifests
164 adding file changes
165 adding file changes
165 added 2 changesets with 2 changes to 1 files
166 added 2 changesets with 2 changes to 1 files
166 updating to branch foo
167 updating to branch foo
167 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
168 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
168 $ cd repo-multi1
169 $ cd repo-multi1
169 $ hg up 0
170 $ hg up 0
170 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
171 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
171 $ hg import --bypass ../patch1.diff ../patch2.diff
172 $ hg import --bypass ../patch1.diff ../patch2.diff
172 applying ../patch1.diff
173 applying ../patch1.diff
173 applying ../patch2.diff
174 applying ../patch2.diff
174 $ shortlog
175 $ shortlog
175 o 3:bc8ca3f8a7c4 test 0 0 - default - addf
176 o 3:bc8ca3f8a7c4 test 0 0 - default - addf
176 |
177 |
177 o 2:16581080145e test 0 0 - default - adde
178 o 2:16581080145e test 0 0 - default - adde
178 |
179 |
179 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
180 | o 1:4e322f7ce8e3 test 0 0 - foo - changea
180 |/
181 |/
181 @ 0:07f494440405 test 0 0 - default - adda
182 @ 0:07f494440405 test 0 0 - default - adda
182
183
183
184
184 Test applying multiple patches with --exact
185 Test applying multiple patches with --exact
185
186
186 $ cd ..
187 $ cd ..
187 $ hg clone -r1 repo-options repo-multi2
188 $ hg clone -r1 repo-options repo-multi2
188 adding changesets
189 adding changesets
189 adding manifests
190 adding manifests
190 adding file changes
191 adding file changes
191 added 2 changesets with 2 changes to 1 files
192 added 2 changesets with 2 changes to 1 files
192 updating to branch foo
193 updating to branch foo
193 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
194 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
194 $ cd repo-multi2
195 $ cd repo-multi2
195 $ hg import --bypass --exact ../patch1.diff ../patch2.diff
196 $ hg import --bypass --exact ../patch1.diff ../patch2.diff
196 applying ../patch1.diff
197 applying ../patch1.diff
197 applying ../patch2.diff
198 applying ../patch2.diff
198 $ shortlog
199 $ shortlog
199 o 3:d60cb8989666 test 0 0 - foo - addf
200 o 3:d60cb8989666 test 0 0 - foo - addf
200 |
201 |
201 | o 2:16581080145e test 0 0 - default - adde
202 | o 2:16581080145e test 0 0 - default - adde
202 | |
203 | |
203 @ | 1:4e322f7ce8e3 test 0 0 - foo - changea
204 @ | 1:4e322f7ce8e3 test 0 0 - foo - changea
204 |/
205 |/
205 o 0:07f494440405 test 0 0 - default - adda
206 o 0:07f494440405 test 0 0 - default - adda
206
207
207
208
208 $ cd ..
209 $ cd ..
209
210
210 Test complicated patch with --exact
211 Test complicated patch with --exact
211
212
212 $ hg init repo-exact
213 $ hg init repo-exact
213 $ cd repo-exact
214 $ cd repo-exact
214 $ echo a > a
215 $ echo a > a
215 $ echo c > c
216 $ echo c > c
216 $ echo d > d
217 $ echo d > d
217 $ echo e > e
218 $ echo e > e
218 $ echo f > f
219 $ echo f > f
219 $ chmod +x f
220 $ chmod +x f
220 $ ln -s c linkc
221 $ ln -s c linkc
221 $ hg ci -Am t
222 $ hg ci -Am t
222 adding a
223 adding a
223 adding c
224 adding c
224 adding d
225 adding d
225 adding e
226 adding e
226 adding f
227 adding f
227 adding linkc
228 adding linkc
228 $ hg cp a aa1
229 $ hg cp a aa1
229 $ echo b >> a
230 $ echo b >> a
230 $ echo b > b
231 $ echo b > b
231 $ hg add b
232 $ hg add b
232 $ hg cp a aa2
233 $ hg cp a aa2
233 $ echo aa >> aa2
234 $ echo aa >> aa2
234 $ chmod +x e
235 $ chmod +x e
235 $ chmod -x f
236 $ chmod -x f
236 $ ln -s a linka
237 $ ln -s a linka
237 $ hg rm d
238 $ hg rm d
238 $ hg rm linkc
239 $ hg rm linkc
239 $ hg mv c cc
240 $ hg mv c cc
240 $ hg ci -m patch
241 $ hg ci -m patch
241 $ hg export --git . > ../test.diff
242 $ hg export --git . > ../test.diff
242 $ hg up -C null
243 $ hg up -C null
243 0 files updated, 0 files merged, 7 files removed, 0 files unresolved
244 0 files updated, 0 files merged, 7 files removed, 0 files unresolved
244 $ hg purge
245 $ hg purge
245 $ hg st
246 $ hg st
246 $ hg import --bypass --exact ../test.diff
247 $ hg import --bypass --exact ../test.diff
247 applying ../test.diff
248 applying ../test.diff
248
249
249 The patch should have matched the exported revision and generated no additional
250 The patch should have matched the exported revision and generated no additional
250 data. If not, diff both heads to debug it.
251 data. If not, diff both heads to debug it.
251
252
252 $ shortlog
253 $ shortlog
253 o 1:2978fd5c8aa4 test 0 0 - default - patch
254 o 1:2978fd5c8aa4 test 0 0 - default - patch
254 |
255 |
255 o 0:a0e19e636a43 test 0 0 - default - t
256 o 0:a0e19e636a43 test 0 0 - default - t
256
257
@@ -1,95 +1,96 b''
1 http://mercurial.selenic.com/bts/issue1306
1 http://mercurial.selenic.com/bts/issue1306
2
2
3 Initialize remote repo with branches:
3 Initialize remote repo with branches:
4
4
5 $ hg init remote
5 $ hg init remote
6 $ cd remote
6 $ cd remote
7
7
8 $ echo a > a
8 $ echo a > a
9 $ hg ci -Ama
9 $ hg ci -Ama
10 adding a
10 adding a
11
11
12 $ hg branch br
12 $ hg branch br
13 marked working directory as branch br
13 marked working directory as branch br
14 (branches are permanent and global, did you want a bookmark?)
14 $ hg ci -Amb
15 $ hg ci -Amb
15
16
16 $ echo c > c
17 $ echo c > c
17 $ hg ci -Amc
18 $ hg ci -Amc
18 adding c
19 adding c
19
20
20 $ hg log
21 $ hg log
21 changeset: 2:ae3d9c30ec50
22 changeset: 2:ae3d9c30ec50
22 branch: br
23 branch: br
23 tag: tip
24 tag: tip
24 user: test
25 user: test
25 date: Thu Jan 01 00:00:00 1970 +0000
26 date: Thu Jan 01 00:00:00 1970 +0000
26 summary: c
27 summary: c
27
28
28 changeset: 1:3f7f930ca414
29 changeset: 1:3f7f930ca414
29 branch: br
30 branch: br
30 user: test
31 user: test
31 date: Thu Jan 01 00:00:00 1970 +0000
32 date: Thu Jan 01 00:00:00 1970 +0000
32 summary: b
33 summary: b
33
34
34 changeset: 0:cb9a9f314b8b
35 changeset: 0:cb9a9f314b8b
35 user: test
36 user: test
36 date: Thu Jan 01 00:00:00 1970 +0000
37 date: Thu Jan 01 00:00:00 1970 +0000
37 summary: a
38 summary: a
38
39
39
40
40 $ cd ..
41 $ cd ..
41
42
42 Try cloning -r branch:
43 Try cloning -r branch:
43
44
44 $ hg clone -rbr remote local1
45 $ hg clone -rbr remote local1
45 adding changesets
46 adding changesets
46 adding manifests
47 adding manifests
47 adding file changes
48 adding file changes
48 added 3 changesets with 2 changes to 2 files
49 added 3 changesets with 2 changes to 2 files
49 updating to branch br
50 updating to branch br
50 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
51
52
52 $ hg -R local1 parents
53 $ hg -R local1 parents
53 changeset: 2:ae3d9c30ec50
54 changeset: 2:ae3d9c30ec50
54 branch: br
55 branch: br
55 tag: tip
56 tag: tip
56 user: test
57 user: test
57 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
58 summary: c
59 summary: c
59
60
60
61
61 Try cloning -rother clone#branch:
62 Try cloning -rother clone#branch:
62
63
63 $ hg clone -r0 remote#br local2
64 $ hg clone -r0 remote#br local2
64 adding changesets
65 adding changesets
65 adding manifests
66 adding manifests
66 adding file changes
67 adding file changes
67 added 3 changesets with 2 changes to 2 files
68 added 3 changesets with 2 changes to 2 files
68 updating to branch default
69 updating to branch default
69 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
70
71
71 $ hg -R local2 parents
72 $ hg -R local2 parents
72 changeset: 0:cb9a9f314b8b
73 changeset: 0:cb9a9f314b8b
73 user: test
74 user: test
74 date: Thu Jan 01 00:00:00 1970 +0000
75 date: Thu Jan 01 00:00:00 1970 +0000
75 summary: a
76 summary: a
76
77
77
78
78 Try cloning -r1 clone#branch:
79 Try cloning -r1 clone#branch:
79
80
80 $ hg clone -r1 remote#br local3
81 $ hg clone -r1 remote#br local3
81 adding changesets
82 adding changesets
82 adding manifests
83 adding manifests
83 adding file changes
84 adding file changes
84 added 3 changesets with 2 changes to 2 files
85 added 3 changesets with 2 changes to 2 files
85 updating to branch br
86 updating to branch br
86 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
87
88
88 $ hg -R local3 parents
89 $ hg -R local3 parents
89 changeset: 1:3f7f930ca414
90 changeset: 1:3f7f930ca414
90 branch: br
91 branch: br
91 user: test
92 user: test
92 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
93 summary: b
94 summary: b
94
95
95
96
@@ -1,29 +1,30 b''
1 http://mercurial.selenic.com/bts/issue619
1 http://mercurial.selenic.com/bts/issue619
2
2
3 $ hg init
3 $ hg init
4 $ echo a > a
4 $ echo a > a
5 $ hg ci -Ama
5 $ hg ci -Ama
6 adding a
6 adding a
7
7
8 $ echo b > b
8 $ echo b > b
9 $ hg branch b
9 $ hg branch b
10 marked working directory as branch b
10 marked working directory as branch b
11 (branches are permanent and global, did you want a bookmark?)
11 $ hg ci -Amb
12 $ hg ci -Amb
12 adding b
13 adding b
13
14
14 $ hg co -C 0
15 $ hg co -C 0
15 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
16 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
16
17
17 Fast-forward:
18 Fast-forward:
18
19
19 $ hg merge b
20 $ hg merge b
20 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 (branch merge, don't forget to commit)
22 (branch merge, don't forget to commit)
22 $ hg ci -Ammerge
23 $ hg ci -Ammerge
23
24
24 Bogus fast-forward should fail:
25 Bogus fast-forward should fail:
25
26
26 $ hg merge b
27 $ hg merge b
27 abort: merging with a working directory ancestor has no effect
28 abort: merging with a working directory ancestor has no effect
28 [255]
29 [255]
29
30
@@ -1,38 +1,39 b''
1 http://mercurial.selenic.com/bts/issue842
1 http://mercurial.selenic.com/bts/issue842
2
2
3 $ hg init
3 $ hg init
4 $ echo foo > a
4 $ echo foo > a
5 $ hg ci -Ama
5 $ hg ci -Ama
6 adding a
6 adding a
7
7
8 $ hg up -r0000
8 $ hg up -r0000
9 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
9 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
10
10
11 $ echo bar > a
11 $ echo bar > a
12
12
13 Should issue new head warning:
13 Should issue new head warning:
14
14
15 $ hg ci -Amb
15 $ hg ci -Amb
16 adding a
16 adding a
17 created new head
17 created new head
18
18
19 $ hg up -r0000
19 $ hg up -r0000
20 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
20 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
21
21
22 $ echo stuffy > a
22 $ echo stuffy > a
23
23
24 Should not issue new head warning:
24 Should not issue new head warning:
25
25
26 $ hg ci -q -Amc
26 $ hg ci -q -Amc
27
27
28 $ hg up -r0000
28 $ hg up -r0000
29 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
29 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
30
30
31 $ echo crap > a
31 $ echo crap > a
32 $ hg branch testing
32 $ hg branch testing
33 marked working directory as branch testing
33 marked working directory as branch testing
34 (branches are permanent and global, did you want a bookmark?)
34
35
35 Should not issue warning:
36 Should not issue warning:
36
37
37 $ hg ci -q -Amd
38 $ hg ci -q -Amd
38
39
@@ -1,1083 +1,1084 b''
1 $ cat <<EOF >> $HGRCPATH
1 $ cat <<EOF >> $HGRCPATH
2 > [extensions]
2 > [extensions]
3 > keyword =
3 > keyword =
4 > mq =
4 > mq =
5 > notify =
5 > notify =
6 > record =
6 > record =
7 > transplant =
7 > transplant =
8 > [ui]
8 > [ui]
9 > interactive = true
9 > interactive = true
10 > EOF
10 > EOF
11
11
12 Run kwdemo before [keyword] files are set up
12 Run kwdemo before [keyword] files are set up
13 as it would succeed without uisetup otherwise
13 as it would succeed without uisetup otherwise
14
14
15 $ hg --quiet kwdemo
15 $ hg --quiet kwdemo
16 [extensions]
16 [extensions]
17 keyword =
17 keyword =
18 [keyword]
18 [keyword]
19 demo.txt =
19 demo.txt =
20 [keywordset]
20 [keywordset]
21 svn = False
21 svn = False
22 [keywordmaps]
22 [keywordmaps]
23 Author = {author|user}
23 Author = {author|user}
24 Date = {date|utcdate}
24 Date = {date|utcdate}
25 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
25 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
26 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
26 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
27 RCSFile = {file|basename},v
27 RCSFile = {file|basename},v
28 RCSfile = {file|basename},v
28 RCSfile = {file|basename},v
29 Revision = {node|short}
29 Revision = {node|short}
30 Source = {root}/{file},v
30 Source = {root}/{file},v
31 $Author: test $
31 $Author: test $
32 $Date: ????/??/?? ??:??:?? $ (glob)
32 $Date: ????/??/?? ??:??:?? $ (glob)
33 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
33 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
34 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
34 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
35 $RCSFile: demo.txt,v $
35 $RCSFile: demo.txt,v $
36 $RCSfile: demo.txt,v $
36 $RCSfile: demo.txt,v $
37 $Revision: ???????????? $ (glob)
37 $Revision: ???????????? $ (glob)
38 $Source: */demo.txt,v $ (glob)
38 $Source: */demo.txt,v $ (glob)
39
39
40 $ hg --quiet kwdemo "Branch = {branches}"
40 $ hg --quiet kwdemo "Branch = {branches}"
41 [extensions]
41 [extensions]
42 keyword =
42 keyword =
43 [keyword]
43 [keyword]
44 demo.txt =
44 demo.txt =
45 [keywordset]
45 [keywordset]
46 svn = False
46 svn = False
47 [keywordmaps]
47 [keywordmaps]
48 Branch = {branches}
48 Branch = {branches}
49 $Branch: demobranch $
49 $Branch: demobranch $
50
50
51 $ cat <<EOF >> $HGRCPATH
51 $ cat <<EOF >> $HGRCPATH
52 > [keyword]
52 > [keyword]
53 > ** =
53 > ** =
54 > b = ignore
54 > b = ignore
55 > i = ignore
55 > i = ignore
56 > [hooks]
56 > [hooks]
57 > EOF
57 > EOF
58 $ cp $HGRCPATH $HGRCPATH.nohooks
58 $ cp $HGRCPATH $HGRCPATH.nohooks
59 > cat <<EOF >> $HGRCPATH
59 > cat <<EOF >> $HGRCPATH
60 > commit=
60 > commit=
61 > commit.test=cp a hooktest
61 > commit.test=cp a hooktest
62 > EOF
62 > EOF
63
63
64 $ hg init Test-bndl
64 $ hg init Test-bndl
65 $ cd Test-bndl
65 $ cd Test-bndl
66
66
67 kwshrink should exit silently in empty/invalid repo
67 kwshrink should exit silently in empty/invalid repo
68
68
69 $ hg kwshrink
69 $ hg kwshrink
70
70
71 Symlinks cannot be created on Windows.
71 Symlinks cannot be created on Windows.
72 A bundle to test this was made with:
72 A bundle to test this was made with:
73 hg init t
73 hg init t
74 cd t
74 cd t
75 echo a > a
75 echo a > a
76 ln -s a sym
76 ln -s a sym
77 hg add sym
77 hg add sym
78 hg ci -m addsym -u mercurial
78 hg ci -m addsym -u mercurial
79 hg bundle --base null ../test-keyword.hg
79 hg bundle --base null ../test-keyword.hg
80
80
81 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
81 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
82 pulling from *test-keyword.hg (glob)
82 pulling from *test-keyword.hg (glob)
83 requesting all changes
83 requesting all changes
84 adding changesets
84 adding changesets
85 adding manifests
85 adding manifests
86 adding file changes
86 adding file changes
87 added 1 changesets with 1 changes to 1 files
87 added 1 changesets with 1 changes to 1 files
88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
89
89
90 $ echo 'expand $Id$' > a
90 $ echo 'expand $Id$' > a
91 $ echo 'do not process $Id:' >> a
91 $ echo 'do not process $Id:' >> a
92 $ echo 'xxx $' >> a
92 $ echo 'xxx $' >> a
93 $ echo 'ignore $Id$' > b
93 $ echo 'ignore $Id$' > b
94
94
95 Output files as they were created
95 Output files as they were created
96
96
97 $ cat a b
97 $ cat a b
98 expand $Id$
98 expand $Id$
99 do not process $Id:
99 do not process $Id:
100 xxx $
100 xxx $
101 ignore $Id$
101 ignore $Id$
102
102
103 no kwfiles
103 no kwfiles
104
104
105 $ hg kwfiles
105 $ hg kwfiles
106
106
107 untracked candidates
107 untracked candidates
108
108
109 $ hg -v kwfiles --unknown
109 $ hg -v kwfiles --unknown
110 k a
110 k a
111
111
112 Add files and check status
112 Add files and check status
113
113
114 $ hg addremove
114 $ hg addremove
115 adding a
115 adding a
116 adding b
116 adding b
117 $ hg status
117 $ hg status
118 A a
118 A a
119 A b
119 A b
120
120
121
121
122 Default keyword expansion including commit hook
122 Default keyword expansion including commit hook
123 Interrupted commit should not change state or run commit hook
123 Interrupted commit should not change state or run commit hook
124
124
125 $ hg --debug commit
125 $ hg --debug commit
126 abort: empty commit message
126 abort: empty commit message
127 [255]
127 [255]
128 $ hg status
128 $ hg status
129 A a
129 A a
130 A b
130 A b
131
131
132 Commit with several checks
132 Commit with several checks
133
133
134 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
134 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
135 a
135 a
136 b
136 b
137 overwriting a expanding keywords
137 overwriting a expanding keywords
138 running hook commit.test: cp a hooktest
138 running hook commit.test: cp a hooktest
139 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
139 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
140 $ hg status
140 $ hg status
141 ? hooktest
141 ? hooktest
142 $ hg debugrebuildstate
142 $ hg debugrebuildstate
143 $ hg --quiet identify
143 $ hg --quiet identify
144 ef63ca68695b
144 ef63ca68695b
145
145
146 cat files in working directory with keywords expanded
146 cat files in working directory with keywords expanded
147
147
148 $ cat a b
148 $ cat a b
149 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
149 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
150 do not process $Id:
150 do not process $Id:
151 xxx $
151 xxx $
152 ignore $Id$
152 ignore $Id$
153
153
154 hg cat files and symlink, no expansion
154 hg cat files and symlink, no expansion
155
155
156 $ hg cat sym a b && echo
156 $ hg cat sym a b && echo
157 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
157 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
158 do not process $Id:
158 do not process $Id:
159 xxx $
159 xxx $
160 ignore $Id$
160 ignore $Id$
161 a
161 a
162
162
163 Test hook execution
163 Test hook execution
164
164
165 $ diff a hooktest
165 $ diff a hooktest
166
166
167 $ cp $HGRCPATH.nohooks $HGRCPATH
167 $ cp $HGRCPATH.nohooks $HGRCPATH
168 $ rm hooktest
168 $ rm hooktest
169
169
170 bundle
170 bundle
171
171
172 $ hg bundle --base null ../kw.hg
172 $ hg bundle --base null ../kw.hg
173 2 changesets found
173 2 changesets found
174 $ cd ..
174 $ cd ..
175 $ hg init Test
175 $ hg init Test
176 $ cd Test
176 $ cd Test
177
177
178 Notify on pull to check whether keywords stay as is in email
178 Notify on pull to check whether keywords stay as is in email
179 ie. if patch.diff wrapper acts as it should
179 ie. if patch.diff wrapper acts as it should
180
180
181 $ cat <<EOF >> $HGRCPATH
181 $ cat <<EOF >> $HGRCPATH
182 > [hooks]
182 > [hooks]
183 > incoming.notify = python:hgext.notify.hook
183 > incoming.notify = python:hgext.notify.hook
184 > [notify]
184 > [notify]
185 > sources = pull
185 > sources = pull
186 > diffstat = False
186 > diffstat = False
187 > maxsubject = 15
187 > maxsubject = 15
188 > [reposubs]
188 > [reposubs]
189 > * = Test
189 > * = Test
190 > EOF
190 > EOF
191
191
192 Pull from bundle and trigger notify
192 Pull from bundle and trigger notify
193
193
194 $ hg pull -u ../kw.hg
194 $ hg pull -u ../kw.hg
195 pulling from ../kw.hg
195 pulling from ../kw.hg
196 requesting all changes
196 requesting all changes
197 adding changesets
197 adding changesets
198 adding manifests
198 adding manifests
199 adding file changes
199 adding file changes
200 added 2 changesets with 3 changes to 3 files
200 added 2 changesets with 3 changes to 3 files
201 Content-Type: text/plain; charset="us-ascii"
201 Content-Type: text/plain; charset="us-ascii"
202 MIME-Version: 1.0
202 MIME-Version: 1.0
203 Content-Transfer-Encoding: 7bit
203 Content-Transfer-Encoding: 7bit
204 Date: * (glob)
204 Date: * (glob)
205 Subject: changeset in...
205 Subject: changeset in...
206 From: mercurial
206 From: mercurial
207 X-Hg-Notification: changeset a2392c293916
207 X-Hg-Notification: changeset a2392c293916
208 Message-Id: <hg.a2392c293916*> (glob)
208 Message-Id: <hg.a2392c293916*> (glob)
209 To: Test
209 To: Test
210
210
211 changeset a2392c293916 in $TESTTMP/Test
211 changeset a2392c293916 in $TESTTMP/Test
212 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
212 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
213 description:
213 description:
214 addsym
214 addsym
215
215
216 diffs (6 lines):
216 diffs (6 lines):
217
217
218 diff -r 000000000000 -r a2392c293916 sym
218 diff -r 000000000000 -r a2392c293916 sym
219 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
219 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
220 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
220 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
221 @@ -0,0 +1,1 @@
221 @@ -0,0 +1,1 @@
222 +a
222 +a
223 \ No newline at end of file
223 \ No newline at end of file
224 Content-Type: text/plain; charset="us-ascii"
224 Content-Type: text/plain; charset="us-ascii"
225 MIME-Version: 1.0
225 MIME-Version: 1.0
226 Content-Transfer-Encoding: 7bit
226 Content-Transfer-Encoding: 7bit
227 Date:* (glob)
227 Date:* (glob)
228 Subject: changeset in...
228 Subject: changeset in...
229 From: User Name <user@example.com>
229 From: User Name <user@example.com>
230 X-Hg-Notification: changeset ef63ca68695b
230 X-Hg-Notification: changeset ef63ca68695b
231 Message-Id: <hg.ef63ca68695b*> (glob)
231 Message-Id: <hg.ef63ca68695b*> (glob)
232 To: Test
232 To: Test
233
233
234 changeset ef63ca68695b in $TESTTMP/Test
234 changeset ef63ca68695b in $TESTTMP/Test
235 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
235 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
236 description:
236 description:
237 absym
237 absym
238
238
239 diffs (12 lines):
239 diffs (12 lines):
240
240
241 diff -r a2392c293916 -r ef63ca68695b a
241 diff -r a2392c293916 -r ef63ca68695b a
242 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
242 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
243 +++ b/a Thu Jan 01 00:00:00 1970 +0000
243 +++ b/a Thu Jan 01 00:00:00 1970 +0000
244 @@ -0,0 +1,3 @@
244 @@ -0,0 +1,3 @@
245 +expand $Id$
245 +expand $Id$
246 +do not process $Id:
246 +do not process $Id:
247 +xxx $
247 +xxx $
248 diff -r a2392c293916 -r ef63ca68695b b
248 diff -r a2392c293916 -r ef63ca68695b b
249 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
249 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
250 +++ b/b Thu Jan 01 00:00:00 1970 +0000
250 +++ b/b Thu Jan 01 00:00:00 1970 +0000
251 @@ -0,0 +1,1 @@
251 @@ -0,0 +1,1 @@
252 +ignore $Id$
252 +ignore $Id$
253 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
253 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
254
254
255 $ cp $HGRCPATH.nohooks $HGRCPATH
255 $ cp $HGRCPATH.nohooks $HGRCPATH
256
256
257 Touch files and check with status
257 Touch files and check with status
258
258
259 $ touch a b
259 $ touch a b
260 $ hg status
260 $ hg status
261
261
262 Update and expand
262 Update and expand
263
263
264 $ rm sym a b
264 $ rm sym a b
265 $ hg update -C
265 $ hg update -C
266 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
267 $ cat a b
267 $ cat a b
268 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
268 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
269 do not process $Id:
269 do not process $Id:
270 xxx $
270 xxx $
271 ignore $Id$
271 ignore $Id$
272
272
273 Check whether expansion is filewise and file mode is preserved
273 Check whether expansion is filewise and file mode is preserved
274
274
275 $ echo '$Id$' > c
275 $ echo '$Id$' > c
276 $ echo 'tests for different changenodes' >> c
276 $ echo 'tests for different changenodes' >> c
277 $ chmod 600 c
277 $ chmod 600 c
278 $ ls -l c | cut -b 1-10
278 $ ls -l c | cut -b 1-10
279 -rw-------
279 -rw-------
280
280
281 commit file c
281 commit file c
282
282
283 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
283 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
284 adding c
284 adding c
285 $ ls -l c | cut -b 1-10
285 $ ls -l c | cut -b 1-10
286 -rw-------
286 -rw-------
287
287
288 force expansion
288 force expansion
289
289
290 $ hg -v kwexpand
290 $ hg -v kwexpand
291 overwriting a expanding keywords
291 overwriting a expanding keywords
292 overwriting c expanding keywords
292 overwriting c expanding keywords
293
293
294 compare changenodes in a and c
294 compare changenodes in a and c
295
295
296 $ cat a c
296 $ cat a c
297 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
297 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
298 do not process $Id:
298 do not process $Id:
299 xxx $
299 xxx $
300 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
300 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
301 tests for different changenodes
301 tests for different changenodes
302
302
303 record
303 record
304
304
305 $ echo '$Id$' > r
305 $ echo '$Id$' > r
306 $ hg add r
306 $ hg add r
307
307
308 record chunk
308 record chunk
309
309
310 $ python -c \
310 $ python -c \
311 > 'l=open("a").readlines();l.insert(1,"foo\n");l.append("bar\n");open("a","w").writelines(l);'
311 > 'l=open("a").readlines();l.insert(1,"foo\n");l.append("bar\n");open("a","w").writelines(l);'
312 $ hg record -d '1 10' -m rectest a<<EOF
312 $ hg record -d '1 10' -m rectest a<<EOF
313 > y
313 > y
314 > y
314 > y
315 > n
315 > n
316 > EOF
316 > EOF
317 diff --git a/a b/a
317 diff --git a/a b/a
318 2 hunks, 2 lines changed
318 2 hunks, 2 lines changed
319 examine changes to 'a'? [Ynsfdaq?]
319 examine changes to 'a'? [Ynsfdaq?]
320 @@ -1,3 +1,4 @@
320 @@ -1,3 +1,4 @@
321 expand $Id$
321 expand $Id$
322 +foo
322 +foo
323 do not process $Id:
323 do not process $Id:
324 xxx $
324 xxx $
325 record change 1/2 to 'a'? [Ynsfdaq?]
325 record change 1/2 to 'a'? [Ynsfdaq?]
326 @@ -2,2 +3,3 @@
326 @@ -2,2 +3,3 @@
327 do not process $Id:
327 do not process $Id:
328 xxx $
328 xxx $
329 +bar
329 +bar
330 record change 2/2 to 'a'? [Ynsfdaq?]
330 record change 2/2 to 'a'? [Ynsfdaq?]
331
331
332 $ hg identify
332 $ hg identify
333 d17e03c92c97+ tip
333 d17e03c92c97+ tip
334 $ hg status
334 $ hg status
335 M a
335 M a
336 A r
336 A r
337
337
338 Cat modified file a
338 Cat modified file a
339
339
340 $ cat a
340 $ cat a
341 expand $Id: a,v d17e03c92c97 1970/01/01 00:00:01 test $
341 expand $Id: a,v d17e03c92c97 1970/01/01 00:00:01 test $
342 foo
342 foo
343 do not process $Id:
343 do not process $Id:
344 xxx $
344 xxx $
345 bar
345 bar
346
346
347 Diff remaining chunk
347 Diff remaining chunk
348
348
349 $ hg diff a
349 $ hg diff a
350 diff -r d17e03c92c97 a
350 diff -r d17e03c92c97 a
351 --- a/a Wed Dec 31 23:59:51 1969 -0000
351 --- a/a Wed Dec 31 23:59:51 1969 -0000
352 +++ b/a * (glob)
352 +++ b/a * (glob)
353 @@ -2,3 +2,4 @@
353 @@ -2,3 +2,4 @@
354 foo
354 foo
355 do not process $Id:
355 do not process $Id:
356 xxx $
356 xxx $
357 +bar
357 +bar
358
358
359 $ hg rollback
359 $ hg rollback
360 repository tip rolled back to revision 2 (undo commit)
360 repository tip rolled back to revision 2 (undo commit)
361 working directory now based on revision 2
361 working directory now based on revision 2
362
362
363 Record all chunks in file a
363 Record all chunks in file a
364
364
365 $ echo foo > msg
365 $ echo foo > msg
366
366
367 - do not use "hg record -m" here!
367 - do not use "hg record -m" here!
368
368
369 $ hg record -l msg -d '1 11' a<<EOF
369 $ hg record -l msg -d '1 11' a<<EOF
370 > y
370 > y
371 > y
371 > y
372 > y
372 > y
373 > EOF
373 > EOF
374 diff --git a/a b/a
374 diff --git a/a b/a
375 2 hunks, 2 lines changed
375 2 hunks, 2 lines changed
376 examine changes to 'a'? [Ynsfdaq?]
376 examine changes to 'a'? [Ynsfdaq?]
377 @@ -1,3 +1,4 @@
377 @@ -1,3 +1,4 @@
378 expand $Id$
378 expand $Id$
379 +foo
379 +foo
380 do not process $Id:
380 do not process $Id:
381 xxx $
381 xxx $
382 record change 1/2 to 'a'? [Ynsfdaq?]
382 record change 1/2 to 'a'? [Ynsfdaq?]
383 @@ -2,2 +3,3 @@
383 @@ -2,2 +3,3 @@
384 do not process $Id:
384 do not process $Id:
385 xxx $
385 xxx $
386 +bar
386 +bar
387 record change 2/2 to 'a'? [Ynsfdaq?]
387 record change 2/2 to 'a'? [Ynsfdaq?]
388
388
389 File a should be clean
389 File a should be clean
390
390
391 $ hg status -A a
391 $ hg status -A a
392 C a
392 C a
393
393
394 rollback and revert expansion
394 rollback and revert expansion
395
395
396 $ cat a
396 $ cat a
397 expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $
397 expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $
398 foo
398 foo
399 do not process $Id:
399 do not process $Id:
400 xxx $
400 xxx $
401 bar
401 bar
402 $ hg --verbose rollback
402 $ hg --verbose rollback
403 repository tip rolled back to revision 2 (undo commit)
403 repository tip rolled back to revision 2 (undo commit)
404 working directory now based on revision 2
404 working directory now based on revision 2
405 overwriting a expanding keywords
405 overwriting a expanding keywords
406 $ hg status a
406 $ hg status a
407 M a
407 M a
408 $ cat a
408 $ cat a
409 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
409 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
410 foo
410 foo
411 do not process $Id:
411 do not process $Id:
412 xxx $
412 xxx $
413 bar
413 bar
414 $ echo '$Id$' > y
414 $ echo '$Id$' > y
415 $ echo '$Id$' > z
415 $ echo '$Id$' > z
416 $ hg add y
416 $ hg add y
417 $ hg commit -Am "rollback only" z
417 $ hg commit -Am "rollback only" z
418 $ cat z
418 $ cat z
419 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
419 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
420 $ hg --verbose rollback
420 $ hg --verbose rollback
421 repository tip rolled back to revision 2 (undo commit)
421 repository tip rolled back to revision 2 (undo commit)
422 working directory now based on revision 2
422 working directory now based on revision 2
423 overwriting z shrinking keywords
423 overwriting z shrinking keywords
424
424
425 Only z should be overwritten
425 Only z should be overwritten
426
426
427 $ hg status a y z
427 $ hg status a y z
428 M a
428 M a
429 A y
429 A y
430 A z
430 A z
431 $ cat z
431 $ cat z
432 $Id$
432 $Id$
433 $ hg forget y z
433 $ hg forget y z
434 $ rm y z
434 $ rm y z
435
435
436 record added file alone
436 record added file alone
437
437
438 $ hg -v record -l msg -d '1 12' r<<EOF
438 $ hg -v record -l msg -d '1 12' r<<EOF
439 > y
439 > y
440 > EOF
440 > EOF
441 diff --git a/r b/r
441 diff --git a/r b/r
442 new file mode 100644
442 new file mode 100644
443 examine changes to 'r'? [Ynsfdaq?]
443 examine changes to 'r'? [Ynsfdaq?]
444 r
444 r
445 committed changeset 3:899491280810
445 committed changeset 3:899491280810
446 overwriting r expanding keywords
446 overwriting r expanding keywords
447 - status call required for dirstate.normallookup() check
447 - status call required for dirstate.normallookup() check
448 $ hg status r
448 $ hg status r
449 $ hg --verbose rollback
449 $ hg --verbose rollback
450 repository tip rolled back to revision 2 (undo commit)
450 repository tip rolled back to revision 2 (undo commit)
451 working directory now based on revision 2
451 working directory now based on revision 2
452 overwriting r shrinking keywords
452 overwriting r shrinking keywords
453 $ hg forget r
453 $ hg forget r
454 $ rm msg r
454 $ rm msg r
455 $ hg update -C
455 $ hg update -C
456 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
456 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
457
457
458 record added keyword ignored file
458 record added keyword ignored file
459
459
460 $ echo '$Id$' > i
460 $ echo '$Id$' > i
461 $ hg add i
461 $ hg add i
462 $ hg --verbose record -d '1 13' -m recignored<<EOF
462 $ hg --verbose record -d '1 13' -m recignored<<EOF
463 > y
463 > y
464 > EOF
464 > EOF
465 diff --git a/i b/i
465 diff --git a/i b/i
466 new file mode 100644
466 new file mode 100644
467 examine changes to 'i'? [Ynsfdaq?]
467 examine changes to 'i'? [Ynsfdaq?]
468 i
468 i
469 committed changeset 3:5f40fe93bbdc
469 committed changeset 3:5f40fe93bbdc
470 $ cat i
470 $ cat i
471 $Id$
471 $Id$
472 $ hg -q rollback
472 $ hg -q rollback
473 $ hg forget i
473 $ hg forget i
474 $ rm i
474 $ rm i
475
475
476 Test patch queue repo
476 Test patch queue repo
477
477
478 $ hg init --mq
478 $ hg init --mq
479 $ hg qimport -r tip -n mqtest.diff
479 $ hg qimport -r tip -n mqtest.diff
480 $ hg commit --mq -m mqtest
480 $ hg commit --mq -m mqtest
481
481
482 Keywords should not be expanded in patch
482 Keywords should not be expanded in patch
483
483
484 $ cat .hg/patches/mqtest.diff
484 $ cat .hg/patches/mqtest.diff
485 # HG changeset patch
485 # HG changeset patch
486 # User User Name <user@example.com>
486 # User User Name <user@example.com>
487 # Date 1 0
487 # Date 1 0
488 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
488 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
489 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
489 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
490 cndiff
490 cndiff
491
491
492 diff -r ef63ca68695b -r 40a904bbbe4c c
492 diff -r ef63ca68695b -r 40a904bbbe4c c
493 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
493 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
494 +++ b/c Thu Jan 01 00:00:01 1970 +0000
494 +++ b/c Thu Jan 01 00:00:01 1970 +0000
495 @@ -0,0 +1,2 @@
495 @@ -0,0 +1,2 @@
496 +$Id$
496 +$Id$
497 +tests for different changenodes
497 +tests for different changenodes
498
498
499 $ hg qpop
499 $ hg qpop
500 popping mqtest.diff
500 popping mqtest.diff
501 patch queue now empty
501 patch queue now empty
502
502
503 qgoto, implying qpush, should expand
503 qgoto, implying qpush, should expand
504
504
505 $ hg qgoto mqtest.diff
505 $ hg qgoto mqtest.diff
506 applying mqtest.diff
506 applying mqtest.diff
507 now at: mqtest.diff
507 now at: mqtest.diff
508 $ cat c
508 $ cat c
509 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
509 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
510 tests for different changenodes
510 tests for different changenodes
511 $ hg cat c
511 $ hg cat c
512 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
512 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
513 tests for different changenodes
513 tests for different changenodes
514
514
515 Keywords should not be expanded in filelog
515 Keywords should not be expanded in filelog
516
516
517 $ hg --config 'extensions.keyword=!' cat c
517 $ hg --config 'extensions.keyword=!' cat c
518 $Id$
518 $Id$
519 tests for different changenodes
519 tests for different changenodes
520
520
521 qpop and move on
521 qpop and move on
522
522
523 $ hg qpop
523 $ hg qpop
524 popping mqtest.diff
524 popping mqtest.diff
525 patch queue now empty
525 patch queue now empty
526
526
527 Copy and show added kwfiles
527 Copy and show added kwfiles
528
528
529 $ hg cp a c
529 $ hg cp a c
530 $ hg kwfiles
530 $ hg kwfiles
531 a
531 a
532 c
532 c
533
533
534 Commit and show expansion in original and copy
534 Commit and show expansion in original and copy
535
535
536 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
536 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
537 c
537 c
538 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
538 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
539 overwriting c expanding keywords
539 overwriting c expanding keywords
540 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
540 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
541 $ cat a c
541 $ cat a c
542 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
542 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
543 do not process $Id:
543 do not process $Id:
544 xxx $
544 xxx $
545 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
545 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
546 do not process $Id:
546 do not process $Id:
547 xxx $
547 xxx $
548
548
549 Touch copied c and check its status
549 Touch copied c and check its status
550
550
551 $ touch c
551 $ touch c
552 $ hg status
552 $ hg status
553
553
554 Copy kwfile to keyword ignored file unexpanding keywords
554 Copy kwfile to keyword ignored file unexpanding keywords
555
555
556 $ hg --verbose copy a i
556 $ hg --verbose copy a i
557 copying a to i
557 copying a to i
558 overwriting i shrinking keywords
558 overwriting i shrinking keywords
559 $ head -n 1 i
559 $ head -n 1 i
560 expand $Id$
560 expand $Id$
561 $ hg forget i
561 $ hg forget i
562 $ rm i
562 $ rm i
563
563
564 Copy ignored file to ignored file: no overwriting
564 Copy ignored file to ignored file: no overwriting
565
565
566 $ hg --verbose copy b i
566 $ hg --verbose copy b i
567 copying b to i
567 copying b to i
568 $ hg forget i
568 $ hg forget i
569 $ rm i
569 $ rm i
570
570
571 cp symlink file; hg cp -A symlink file (part1)
571 cp symlink file; hg cp -A symlink file (part1)
572 - copied symlink points to kwfile: overwrite
572 - copied symlink points to kwfile: overwrite
573
573
574 $ cp sym i
574 $ cp sym i
575 $ ls -l i
575 $ ls -l i
576 -rw-r--r--* (glob)
576 -rw-r--r--* (glob)
577 $ head -1 i
577 $ head -1 i
578 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
578 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
579 $ hg copy --after --verbose sym i
579 $ hg copy --after --verbose sym i
580 copying sym to i
580 copying sym to i
581 overwriting i shrinking keywords
581 overwriting i shrinking keywords
582 $ head -1 i
582 $ head -1 i
583 expand $Id$
583 expand $Id$
584 $ hg forget i
584 $ hg forget i
585 $ rm i
585 $ rm i
586
586
587 Test different options of hg kwfiles
587 Test different options of hg kwfiles
588
588
589 $ hg kwfiles
589 $ hg kwfiles
590 a
590 a
591 c
591 c
592 $ hg -v kwfiles --ignore
592 $ hg -v kwfiles --ignore
593 I b
593 I b
594 I sym
594 I sym
595 $ hg kwfiles --all
595 $ hg kwfiles --all
596 K a
596 K a
597 K c
597 K c
598 I b
598 I b
599 I sym
599 I sym
600
600
601 Diff specific revision
601 Diff specific revision
602
602
603 $ hg diff --rev 1
603 $ hg diff --rev 1
604 diff -r ef63ca68695b c
604 diff -r ef63ca68695b c
605 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
605 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
606 +++ b/c * (glob)
606 +++ b/c * (glob)
607 @@ -0,0 +1,3 @@
607 @@ -0,0 +1,3 @@
608 +expand $Id$
608 +expand $Id$
609 +do not process $Id:
609 +do not process $Id:
610 +xxx $
610 +xxx $
611
611
612 Status after rollback:
612 Status after rollback:
613
613
614 $ hg rollback
614 $ hg rollback
615 repository tip rolled back to revision 1 (undo commit)
615 repository tip rolled back to revision 1 (undo commit)
616 working directory now based on revision 1
616 working directory now based on revision 1
617 $ hg status
617 $ hg status
618 A c
618 A c
619 $ hg update --clean
619 $ hg update --clean
620 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
620 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
621
621
622 cp symlink file; hg cp -A symlink file (part2)
622 cp symlink file; hg cp -A symlink file (part2)
623 - copied symlink points to kw ignored file: do not overwrite
623 - copied symlink points to kw ignored file: do not overwrite
624
624
625 $ cat a > i
625 $ cat a > i
626 $ ln -s i symignored
626 $ ln -s i symignored
627 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
627 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
628 $ cp symignored x
628 $ cp symignored x
629 $ hg copy --after --verbose symignored x
629 $ hg copy --after --verbose symignored x
630 copying symignored to x
630 copying symignored to x
631 $ head -n 1 x
631 $ head -n 1 x
632 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
632 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
633 $ hg forget x
633 $ hg forget x
634 $ rm x
634 $ rm x
635
635
636 $ hg rollback
636 $ hg rollback
637 repository tip rolled back to revision 1 (undo commit)
637 repository tip rolled back to revision 1 (undo commit)
638 working directory now based on revision 1
638 working directory now based on revision 1
639 $ hg update --clean
639 $ hg update --clean
640 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
640 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
641 $ rm i symignored
641 $ rm i symignored
642
642
643 Custom keywordmaps as argument to kwdemo
643 Custom keywordmaps as argument to kwdemo
644
644
645 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
645 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
646 [extensions]
646 [extensions]
647 keyword =
647 keyword =
648 [keyword]
648 [keyword]
649 ** =
649 ** =
650 b = ignore
650 b = ignore
651 demo.txt =
651 demo.txt =
652 i = ignore
652 i = ignore
653 [keywordset]
653 [keywordset]
654 svn = False
654 svn = False
655 [keywordmaps]
655 [keywordmaps]
656 Xinfo = {author}: {desc}
656 Xinfo = {author}: {desc}
657 $Xinfo: test: hg keyword configuration and expansion example $
657 $Xinfo: test: hg keyword configuration and expansion example $
658
658
659 Configure custom keywordmaps
659 Configure custom keywordmaps
660
660
661 $ cat <<EOF >>$HGRCPATH
661 $ cat <<EOF >>$HGRCPATH
662 > [keywordmaps]
662 > [keywordmaps]
663 > Id = {file} {node|short} {date|rfc822date} {author|user}
663 > Id = {file} {node|short} {date|rfc822date} {author|user}
664 > Xinfo = {author}: {desc}
664 > Xinfo = {author}: {desc}
665 > EOF
665 > EOF
666
666
667 Cat and hg cat files before custom expansion
667 Cat and hg cat files before custom expansion
668
668
669 $ cat a b
669 $ cat a b
670 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
670 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
671 do not process $Id:
671 do not process $Id:
672 xxx $
672 xxx $
673 ignore $Id$
673 ignore $Id$
674 $ hg cat sym a b && echo
674 $ hg cat sym a b && echo
675 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
675 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
676 do not process $Id:
676 do not process $Id:
677 xxx $
677 xxx $
678 ignore $Id$
678 ignore $Id$
679 a
679 a
680
680
681 Write custom keyword and prepare multiline commit message
681 Write custom keyword and prepare multiline commit message
682
682
683 $ echo '$Xinfo$' >> a
683 $ echo '$Xinfo$' >> a
684 $ cat <<EOF >> log
684 $ cat <<EOF >> log
685 > firstline
685 > firstline
686 > secondline
686 > secondline
687 > EOF
687 > EOF
688
688
689 Interrupted commit should not change state
689 Interrupted commit should not change state
690
690
691 $ hg commit
691 $ hg commit
692 abort: empty commit message
692 abort: empty commit message
693 [255]
693 [255]
694 $ hg status
694 $ hg status
695 M a
695 M a
696 ? c
696 ? c
697 ? log
697 ? log
698
698
699 Commit with multiline message and custom expansion
699 Commit with multiline message and custom expansion
700
700
701 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
701 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
702 a
702 a
703 overwriting a expanding keywords
703 overwriting a expanding keywords
704 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
704 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
705 $ rm log
705 $ rm log
706
706
707 Stat, verify and show custom expansion (firstline)
707 Stat, verify and show custom expansion (firstline)
708
708
709 $ hg status
709 $ hg status
710 ? c
710 ? c
711 $ hg verify
711 $ hg verify
712 checking changesets
712 checking changesets
713 checking manifests
713 checking manifests
714 crosschecking files in changesets and manifests
714 crosschecking files in changesets and manifests
715 checking files
715 checking files
716 3 files, 3 changesets, 4 total revisions
716 3 files, 3 changesets, 4 total revisions
717 $ cat a b
717 $ cat a b
718 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
718 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
719 do not process $Id:
719 do not process $Id:
720 xxx $
720 xxx $
721 $Xinfo: User Name <user@example.com>: firstline $
721 $Xinfo: User Name <user@example.com>: firstline $
722 ignore $Id$
722 ignore $Id$
723 $ hg cat sym a b && echo
723 $ hg cat sym a b && echo
724 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
724 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
725 do not process $Id:
725 do not process $Id:
726 xxx $
726 xxx $
727 $Xinfo: User Name <user@example.com>: firstline $
727 $Xinfo: User Name <user@example.com>: firstline $
728 ignore $Id$
728 ignore $Id$
729 a
729 a
730
730
731 annotate
731 annotate
732
732
733 $ hg annotate a
733 $ hg annotate a
734 1: expand $Id$
734 1: expand $Id$
735 1: do not process $Id:
735 1: do not process $Id:
736 1: xxx $
736 1: xxx $
737 2: $Xinfo$
737 2: $Xinfo$
738
738
739 remove with status checks
739 remove with status checks
740
740
741 $ hg debugrebuildstate
741 $ hg debugrebuildstate
742 $ hg remove a
742 $ hg remove a
743 $ hg --debug commit -m rma
743 $ hg --debug commit -m rma
744 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
744 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
745 $ hg status
745 $ hg status
746 ? c
746 ? c
747
747
748 Rollback, revert, and check expansion
748 Rollback, revert, and check expansion
749
749
750 $ hg rollback
750 $ hg rollback
751 repository tip rolled back to revision 2 (undo commit)
751 repository tip rolled back to revision 2 (undo commit)
752 working directory now based on revision 2
752 working directory now based on revision 2
753 $ hg status
753 $ hg status
754 R a
754 R a
755 ? c
755 ? c
756 $ hg revert --no-backup --rev tip a
756 $ hg revert --no-backup --rev tip a
757 $ cat a
757 $ cat a
758 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
758 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
759 do not process $Id:
759 do not process $Id:
760 xxx $
760 xxx $
761 $Xinfo: User Name <user@example.com>: firstline $
761 $Xinfo: User Name <user@example.com>: firstline $
762
762
763 Clone to test global and local configurations
763 Clone to test global and local configurations
764
764
765 $ cd ..
765 $ cd ..
766
766
767 Expansion in destinaton with global configuration
767 Expansion in destinaton with global configuration
768
768
769 $ hg --quiet clone Test globalconf
769 $ hg --quiet clone Test globalconf
770 $ cat globalconf/a
770 $ cat globalconf/a
771 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
771 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
772 do not process $Id:
772 do not process $Id:
773 xxx $
773 xxx $
774 $Xinfo: User Name <user@example.com>: firstline $
774 $Xinfo: User Name <user@example.com>: firstline $
775
775
776 No expansion in destination with local configuration in origin only
776 No expansion in destination with local configuration in origin only
777
777
778 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
778 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
779 $ cat localconf/a
779 $ cat localconf/a
780 expand $Id$
780 expand $Id$
781 do not process $Id:
781 do not process $Id:
782 xxx $
782 xxx $
783 $Xinfo$
783 $Xinfo$
784
784
785 Clone to test incoming
785 Clone to test incoming
786
786
787 $ hg clone -r1 Test Test-a
787 $ hg clone -r1 Test Test-a
788 adding changesets
788 adding changesets
789 adding manifests
789 adding manifests
790 adding file changes
790 adding file changes
791 added 2 changesets with 3 changes to 3 files
791 added 2 changesets with 3 changes to 3 files
792 updating to branch default
792 updating to branch default
793 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
793 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
794 $ cd Test-a
794 $ cd Test-a
795 $ cat <<EOF >> .hg/hgrc
795 $ cat <<EOF >> .hg/hgrc
796 > [paths]
796 > [paths]
797 > default = ../Test
797 > default = ../Test
798 > EOF
798 > EOF
799 $ hg incoming
799 $ hg incoming
800 comparing with $TESTTMP/Test
800 comparing with $TESTTMP/Test
801 searching for changes
801 searching for changes
802 changeset: 2:bb948857c743
802 changeset: 2:bb948857c743
803 tag: tip
803 tag: tip
804 user: User Name <user@example.com>
804 user: User Name <user@example.com>
805 date: Thu Jan 01 00:00:02 1970 +0000
805 date: Thu Jan 01 00:00:02 1970 +0000
806 summary: firstline
806 summary: firstline
807
807
808 Imported patch should not be rejected
808 Imported patch should not be rejected
809
809
810 $ python -c \
810 $ python -c \
811 > 'import re; s=re.sub("(Id.*)","\\1 rejecttest",open("a").read()); open("a","wb").write(s);'
811 > 'import re; s=re.sub("(Id.*)","\\1 rejecttest",open("a").read()); open("a","wb").write(s);'
812 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
812 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
813 a
813 a
814 overwriting a expanding keywords
814 overwriting a expanding keywords
815 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
815 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
816 $ hg export -o ../rejecttest.diff tip
816 $ hg export -o ../rejecttest.diff tip
817 $ cd ../Test
817 $ cd ../Test
818 $ hg import ../rejecttest.diff
818 $ hg import ../rejecttest.diff
819 applying ../rejecttest.diff
819 applying ../rejecttest.diff
820 $ cat a b
820 $ cat a b
821 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
821 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
822 do not process $Id: rejecttest
822 do not process $Id: rejecttest
823 xxx $
823 xxx $
824 $Xinfo: User Name <user@example.com>: rejects? $
824 $Xinfo: User Name <user@example.com>: rejects? $
825 ignore $Id$
825 ignore $Id$
826
826
827 $ hg rollback
827 $ hg rollback
828 repository tip rolled back to revision 2 (undo import)
828 repository tip rolled back to revision 2 (undo import)
829 working directory now based on revision 2
829 working directory now based on revision 2
830 $ hg update --clean
830 $ hg update --clean
831 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
831 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
832
832
833 kwexpand/kwshrink on selected files
833 kwexpand/kwshrink on selected files
834
834
835 $ mkdir x
835 $ mkdir x
836 $ hg copy a x/a
836 $ hg copy a x/a
837 $ hg --verbose kwshrink a
837 $ hg --verbose kwshrink a
838 overwriting a shrinking keywords
838 overwriting a shrinking keywords
839 - sleep required for dirstate.normal() check
839 - sleep required for dirstate.normal() check
840 $ sleep 1
840 $ sleep 1
841 $ hg status a
841 $ hg status a
842 $ hg --verbose kwexpand a
842 $ hg --verbose kwexpand a
843 overwriting a expanding keywords
843 overwriting a expanding keywords
844 $ hg status a
844 $ hg status a
845
845
846 kwexpand x/a should abort
846 kwexpand x/a should abort
847
847
848 $ hg --verbose kwexpand x/a
848 $ hg --verbose kwexpand x/a
849 abort: outstanding uncommitted changes
849 abort: outstanding uncommitted changes
850 [255]
850 [255]
851 $ cd x
851 $ cd x
852 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
852 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
853 x/a
853 x/a
854 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
854 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
855 overwriting x/a expanding keywords
855 overwriting x/a expanding keywords
856 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
856 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
857 $ cat a
857 $ cat a
858 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
858 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
859 do not process $Id:
859 do not process $Id:
860 xxx $
860 xxx $
861 $Xinfo: User Name <user@example.com>: xa $
861 $Xinfo: User Name <user@example.com>: xa $
862
862
863 kwshrink a inside directory x
863 kwshrink a inside directory x
864
864
865 $ hg --verbose kwshrink a
865 $ hg --verbose kwshrink a
866 overwriting x/a shrinking keywords
866 overwriting x/a shrinking keywords
867 $ cat a
867 $ cat a
868 expand $Id$
868 expand $Id$
869 do not process $Id:
869 do not process $Id:
870 xxx $
870 xxx $
871 $Xinfo$
871 $Xinfo$
872 $ cd ..
872 $ cd ..
873
873
874 kwexpand nonexistent
874 kwexpand nonexistent
875
875
876 $ hg kwexpand nonexistent
876 $ hg kwexpand nonexistent
877 nonexistent:* (glob)
877 nonexistent:* (glob)
878
878
879
879
880 hg serve
880 hg serve
881 - expand with hgweb file
881 - expand with hgweb file
882 - no expansion with hgweb annotate/changeset/filediff
882 - no expansion with hgweb annotate/changeset/filediff
883 - check errors
883 - check errors
884
884
885 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
885 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
886 $ cat hg.pid >> $DAEMON_PIDS
886 $ cat hg.pid >> $DAEMON_PIDS
887 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/file/tip/a/?style=raw'
887 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/file/tip/a/?style=raw'
888 200 Script output follows
888 200 Script output follows
889
889
890 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
890 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
891 do not process $Id:
891 do not process $Id:
892 xxx $
892 xxx $
893 $Xinfo: User Name <user@example.com>: firstline $
893 $Xinfo: User Name <user@example.com>: firstline $
894 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/annotate/tip/a/?style=raw'
894 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/annotate/tip/a/?style=raw'
895 200 Script output follows
895 200 Script output follows
896
896
897
897
898 user@1: expand $Id$
898 user@1: expand $Id$
899 user@1: do not process $Id:
899 user@1: do not process $Id:
900 user@1: xxx $
900 user@1: xxx $
901 user@2: $Xinfo$
901 user@2: $Xinfo$
902
902
903
903
904
904
905
905
906 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/rev/tip/?style=raw'
906 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/rev/tip/?style=raw'
907 200 Script output follows
907 200 Script output follows
908
908
909
909
910 # HG changeset patch
910 # HG changeset patch
911 # User User Name <user@example.com>
911 # User User Name <user@example.com>
912 # Date 3 0
912 # Date 3 0
913 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
913 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
914 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
914 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
915 xa
915 xa
916
916
917 diff -r bb948857c743 -r b4560182a3f9 x/a
917 diff -r bb948857c743 -r b4560182a3f9 x/a
918 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
918 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
919 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
919 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
920 @@ -0,0 +1,4 @@
920 @@ -0,0 +1,4 @@
921 +expand $Id$
921 +expand $Id$
922 +do not process $Id:
922 +do not process $Id:
923 +xxx $
923 +xxx $
924 +$Xinfo$
924 +$Xinfo$
925
925
926 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/diff/bb948857c743/a?style=raw'
926 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/diff/bb948857c743/a?style=raw'
927 200 Script output follows
927 200 Script output follows
928
928
929
929
930 diff -r ef63ca68695b -r bb948857c743 a
930 diff -r ef63ca68695b -r bb948857c743 a
931 --- a/a Thu Jan 01 00:00:00 1970 +0000
931 --- a/a Thu Jan 01 00:00:00 1970 +0000
932 +++ b/a Thu Jan 01 00:00:02 1970 +0000
932 +++ b/a Thu Jan 01 00:00:02 1970 +0000
933 @@ -1,3 +1,4 @@
933 @@ -1,3 +1,4 @@
934 expand $Id$
934 expand $Id$
935 do not process $Id:
935 do not process $Id:
936 xxx $
936 xxx $
937 +$Xinfo$
937 +$Xinfo$
938
938
939
939
940
940
941
941
942 $ cat errors.log
942 $ cat errors.log
943
943
944 Prepare merge and resolve tests
944 Prepare merge and resolve tests
945
945
946 $ echo '$Id$' > m
946 $ echo '$Id$' > m
947 $ hg add m
947 $ hg add m
948 $ hg commit -m 4kw
948 $ hg commit -m 4kw
949 $ echo foo >> m
949 $ echo foo >> m
950 $ hg commit -m 5foo
950 $ hg commit -m 5foo
951
951
952 simplemerge
952 simplemerge
953
953
954 $ hg update 4
954 $ hg update 4
955 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
955 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
956 $ echo foo >> m
956 $ echo foo >> m
957 $ hg commit -m 6foo
957 $ hg commit -m 6foo
958 created new head
958 created new head
959 $ hg merge
959 $ hg merge
960 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
960 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
961 (branch merge, don't forget to commit)
961 (branch merge, don't forget to commit)
962 $ hg commit -m simplemerge
962 $ hg commit -m simplemerge
963 $ cat m
963 $ cat m
964 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
964 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
965 foo
965 foo
966
966
967 conflict: keyword should stay outside conflict zone
967 conflict: keyword should stay outside conflict zone
968
968
969 $ hg update 4
969 $ hg update 4
970 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
970 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
971 $ echo bar >> m
971 $ echo bar >> m
972 $ hg commit -m 8bar
972 $ hg commit -m 8bar
973 created new head
973 created new head
974 $ hg merge
974 $ hg merge
975 merging m
975 merging m
976 warning: conflicts during merge.
976 warning: conflicts during merge.
977 merging m failed!
977 merging m failed!
978 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
978 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
979 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
979 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
980 [1]
980 [1]
981 $ cat m
981 $ cat m
982 $Id$
982 $Id$
983 <<<<<<< local
983 <<<<<<< local
984 bar
984 bar
985 =======
985 =======
986 foo
986 foo
987 >>>>>>> other
987 >>>>>>> other
988
988
989 resolve to local
989 resolve to local
990
990
991 $ HGMERGE=internal:local hg resolve -a
991 $ HGMERGE=internal:local hg resolve -a
992 $ hg commit -m localresolve
992 $ hg commit -m localresolve
993 $ cat m
993 $ cat m
994 $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
994 $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
995 bar
995 bar
996
996
997 Test restricted mode with transplant -b
997 Test restricted mode with transplant -b
998
998
999 $ hg update 6
999 $ hg update 6
1000 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1000 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1001 $ hg branch foo
1001 $ hg branch foo
1002 marked working directory as branch foo
1002 marked working directory as branch foo
1003 (branches are permanent and global, did you want a bookmark?)
1003 $ mv a a.bak
1004 $ mv a a.bak
1004 $ echo foobranch > a
1005 $ echo foobranch > a
1005 $ cat a.bak >> a
1006 $ cat a.bak >> a
1006 $ rm a.bak
1007 $ rm a.bak
1007 $ hg commit -m 9foobranch
1008 $ hg commit -m 9foobranch
1008 $ hg update default
1009 $ hg update default
1009 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1010 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1010 $ hg -y transplant -b foo tip
1011 $ hg -y transplant -b foo tip
1011 applying 4aa30d025d50
1012 applying 4aa30d025d50
1012 4aa30d025d50 transplanted to e00abbf63521
1013 4aa30d025d50 transplanted to e00abbf63521
1013
1014
1014 Expansion in changeset but not in file
1015 Expansion in changeset but not in file
1015
1016
1016 $ hg tip -p
1017 $ hg tip -p
1017 changeset: 11:e00abbf63521
1018 changeset: 11:e00abbf63521
1018 tag: tip
1019 tag: tip
1019 parent: 9:800511b3a22d
1020 parent: 9:800511b3a22d
1020 user: test
1021 user: test
1021 date: Thu Jan 01 00:00:00 1970 +0000
1022 date: Thu Jan 01 00:00:00 1970 +0000
1022 summary: 9foobranch
1023 summary: 9foobranch
1023
1024
1024 diff -r 800511b3a22d -r e00abbf63521 a
1025 diff -r 800511b3a22d -r e00abbf63521 a
1025 --- a/a Thu Jan 01 00:00:00 1970 +0000
1026 --- a/a Thu Jan 01 00:00:00 1970 +0000
1026 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1027 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1027 @@ -1,3 +1,4 @@
1028 @@ -1,3 +1,4 @@
1028 +foobranch
1029 +foobranch
1029 expand $Id$
1030 expand $Id$
1030 do not process $Id:
1031 do not process $Id:
1031 xxx $
1032 xxx $
1032
1033
1033 $ head -n 2 a
1034 $ head -n 2 a
1034 foobranch
1035 foobranch
1035 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1036 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1036
1037
1037 Turn off expansion
1038 Turn off expansion
1038
1039
1039 $ hg -q rollback
1040 $ hg -q rollback
1040 $ hg -q update -C
1041 $ hg -q update -C
1041
1042
1042 kwshrink with unknown file u
1043 kwshrink with unknown file u
1043
1044
1044 $ cp a u
1045 $ cp a u
1045 $ hg --verbose kwshrink
1046 $ hg --verbose kwshrink
1046 overwriting a shrinking keywords
1047 overwriting a shrinking keywords
1047 overwriting m shrinking keywords
1048 overwriting m shrinking keywords
1048 overwriting x/a shrinking keywords
1049 overwriting x/a shrinking keywords
1049
1050
1050 Keywords shrunk in working directory, but not yet disabled
1051 Keywords shrunk in working directory, but not yet disabled
1051 - cat shows unexpanded keywords
1052 - cat shows unexpanded keywords
1052 - hg cat shows expanded keywords
1053 - hg cat shows expanded keywords
1053
1054
1054 $ cat a b
1055 $ cat a b
1055 expand $Id$
1056 expand $Id$
1056 do not process $Id:
1057 do not process $Id:
1057 xxx $
1058 xxx $
1058 $Xinfo$
1059 $Xinfo$
1059 ignore $Id$
1060 ignore $Id$
1060 $ hg cat sym a b && echo
1061 $ hg cat sym a b && echo
1061 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1062 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1062 do not process $Id:
1063 do not process $Id:
1063 xxx $
1064 xxx $
1064 $Xinfo: User Name <user@example.com>: firstline $
1065 $Xinfo: User Name <user@example.com>: firstline $
1065 ignore $Id$
1066 ignore $Id$
1066 a
1067 a
1067
1068
1068 Now disable keyword expansion
1069 Now disable keyword expansion
1069
1070
1070 $ rm "$HGRCPATH"
1071 $ rm "$HGRCPATH"
1071 $ cat a b
1072 $ cat a b
1072 expand $Id$
1073 expand $Id$
1073 do not process $Id:
1074 do not process $Id:
1074 xxx $
1075 xxx $
1075 $Xinfo$
1076 $Xinfo$
1076 ignore $Id$
1077 ignore $Id$
1077 $ hg cat sym a b && echo
1078 $ hg cat sym a b && echo
1078 expand $Id$
1079 expand $Id$
1079 do not process $Id:
1080 do not process $Id:
1080 xxx $
1081 xxx $
1081 $Xinfo$
1082 $Xinfo$
1082 ignore $Id$
1083 ignore $Id$
1083 a
1084 a
@@ -1,1158 +1,1159 b''
1 $ hg init a
1 $ hg init a
2
2
3 $ cd a
3 $ cd a
4 $ echo a > a
4 $ echo a > a
5 $ hg ci -Ama -d '1 0'
5 $ hg ci -Ama -d '1 0'
6 adding a
6 adding a
7
7
8 $ hg cp a b
8 $ hg cp a b
9 $ hg ci -mb -d '2 0'
9 $ hg ci -mb -d '2 0'
10
10
11 $ mkdir dir
11 $ mkdir dir
12 $ hg mv b dir
12 $ hg mv b dir
13 $ hg ci -mc -d '3 0'
13 $ hg ci -mc -d '3 0'
14
14
15 $ hg mv a b
15 $ hg mv a b
16 $ echo a > d
16 $ echo a > d
17 $ hg add d
17 $ hg add d
18 $ hg ci -md -d '4 0'
18 $ hg ci -md -d '4 0'
19
19
20 $ hg mv dir/b e
20 $ hg mv dir/b e
21 $ hg ci -me -d '5 0'
21 $ hg ci -me -d '5 0'
22
22
23 $ hg log a
23 $ hg log a
24 changeset: 0:8580ff50825a
24 changeset: 0:8580ff50825a
25 user: test
25 user: test
26 date: Thu Jan 01 00:00:01 1970 +0000
26 date: Thu Jan 01 00:00:01 1970 +0000
27 summary: a
27 summary: a
28
28
29
29
30 -f, directory
30 -f, directory
31
31
32 $ hg log -f dir
32 $ hg log -f dir
33 abort: cannot follow nonexistent file: "dir"
33 abort: cannot follow nonexistent file: "dir"
34 [255]
34 [255]
35
35
36 -f, but no args
36 -f, but no args
37
37
38 $ hg log -f
38 $ hg log -f
39 changeset: 4:66c1345dc4f9
39 changeset: 4:66c1345dc4f9
40 tag: tip
40 tag: tip
41 user: test
41 user: test
42 date: Thu Jan 01 00:00:05 1970 +0000
42 date: Thu Jan 01 00:00:05 1970 +0000
43 summary: e
43 summary: e
44
44
45 changeset: 3:7c6c671bb7cc
45 changeset: 3:7c6c671bb7cc
46 user: test
46 user: test
47 date: Thu Jan 01 00:00:04 1970 +0000
47 date: Thu Jan 01 00:00:04 1970 +0000
48 summary: d
48 summary: d
49
49
50 changeset: 2:41dd4284081e
50 changeset: 2:41dd4284081e
51 user: test
51 user: test
52 date: Thu Jan 01 00:00:03 1970 +0000
52 date: Thu Jan 01 00:00:03 1970 +0000
53 summary: c
53 summary: c
54
54
55 changeset: 1:784de7cef101
55 changeset: 1:784de7cef101
56 user: test
56 user: test
57 date: Thu Jan 01 00:00:02 1970 +0000
57 date: Thu Jan 01 00:00:02 1970 +0000
58 summary: b
58 summary: b
59
59
60 changeset: 0:8580ff50825a
60 changeset: 0:8580ff50825a
61 user: test
61 user: test
62 date: Thu Jan 01 00:00:01 1970 +0000
62 date: Thu Jan 01 00:00:01 1970 +0000
63 summary: a
63 summary: a
64
64
65
65
66 one rename
66 one rename
67
67
68 $ hg log -vf a
68 $ hg log -vf a
69 changeset: 0:8580ff50825a
69 changeset: 0:8580ff50825a
70 user: test
70 user: test
71 date: Thu Jan 01 00:00:01 1970 +0000
71 date: Thu Jan 01 00:00:01 1970 +0000
72 files: a
72 files: a
73 description:
73 description:
74 a
74 a
75
75
76
76
77
77
78 many renames
78 many renames
79
79
80 $ hg log -vf e
80 $ hg log -vf e
81 changeset: 4:66c1345dc4f9
81 changeset: 4:66c1345dc4f9
82 tag: tip
82 tag: tip
83 user: test
83 user: test
84 date: Thu Jan 01 00:00:05 1970 +0000
84 date: Thu Jan 01 00:00:05 1970 +0000
85 files: dir/b e
85 files: dir/b e
86 description:
86 description:
87 e
87 e
88
88
89
89
90 changeset: 2:41dd4284081e
90 changeset: 2:41dd4284081e
91 user: test
91 user: test
92 date: Thu Jan 01 00:00:03 1970 +0000
92 date: Thu Jan 01 00:00:03 1970 +0000
93 files: b dir/b
93 files: b dir/b
94 description:
94 description:
95 c
95 c
96
96
97
97
98 changeset: 1:784de7cef101
98 changeset: 1:784de7cef101
99 user: test
99 user: test
100 date: Thu Jan 01 00:00:02 1970 +0000
100 date: Thu Jan 01 00:00:02 1970 +0000
101 files: b
101 files: b
102 description:
102 description:
103 b
103 b
104
104
105
105
106 changeset: 0:8580ff50825a
106 changeset: 0:8580ff50825a
107 user: test
107 user: test
108 date: Thu Jan 01 00:00:01 1970 +0000
108 date: Thu Jan 01 00:00:01 1970 +0000
109 files: a
109 files: a
110 description:
110 description:
111 a
111 a
112
112
113
113
114
114
115
115
116 log -pf dir/b
116 log -pf dir/b
117
117
118 $ hg log -pf dir/b
118 $ hg log -pf dir/b
119 changeset: 2:41dd4284081e
119 changeset: 2:41dd4284081e
120 user: test
120 user: test
121 date: Thu Jan 01 00:00:03 1970 +0000
121 date: Thu Jan 01 00:00:03 1970 +0000
122 summary: c
122 summary: c
123
123
124 diff -r 784de7cef101 -r 41dd4284081e dir/b
124 diff -r 784de7cef101 -r 41dd4284081e dir/b
125 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
125 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
126 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
126 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
127 @@ -0,0 +1,1 @@
127 @@ -0,0 +1,1 @@
128 +a
128 +a
129
129
130 changeset: 1:784de7cef101
130 changeset: 1:784de7cef101
131 user: test
131 user: test
132 date: Thu Jan 01 00:00:02 1970 +0000
132 date: Thu Jan 01 00:00:02 1970 +0000
133 summary: b
133 summary: b
134
134
135 diff -r 8580ff50825a -r 784de7cef101 b
135 diff -r 8580ff50825a -r 784de7cef101 b
136 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
136 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
137 +++ b/b Thu Jan 01 00:00:02 1970 +0000
137 +++ b/b Thu Jan 01 00:00:02 1970 +0000
138 @@ -0,0 +1,1 @@
138 @@ -0,0 +1,1 @@
139 +a
139 +a
140
140
141 changeset: 0:8580ff50825a
141 changeset: 0:8580ff50825a
142 user: test
142 user: test
143 date: Thu Jan 01 00:00:01 1970 +0000
143 date: Thu Jan 01 00:00:01 1970 +0000
144 summary: a
144 summary: a
145
145
146 diff -r 000000000000 -r 8580ff50825a a
146 diff -r 000000000000 -r 8580ff50825a a
147 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
147 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
148 +++ b/a Thu Jan 01 00:00:01 1970 +0000
148 +++ b/a Thu Jan 01 00:00:01 1970 +0000
149 @@ -0,0 +1,1 @@
149 @@ -0,0 +1,1 @@
150 +a
150 +a
151
151
152
152
153 log -vf dir/b
153 log -vf dir/b
154
154
155 $ hg log -vf dir/b
155 $ hg log -vf dir/b
156 changeset: 2:41dd4284081e
156 changeset: 2:41dd4284081e
157 user: test
157 user: test
158 date: Thu Jan 01 00:00:03 1970 +0000
158 date: Thu Jan 01 00:00:03 1970 +0000
159 files: b dir/b
159 files: b dir/b
160 description:
160 description:
161 c
161 c
162
162
163
163
164 changeset: 1:784de7cef101
164 changeset: 1:784de7cef101
165 user: test
165 user: test
166 date: Thu Jan 01 00:00:02 1970 +0000
166 date: Thu Jan 01 00:00:02 1970 +0000
167 files: b
167 files: b
168 description:
168 description:
169 b
169 b
170
170
171
171
172 changeset: 0:8580ff50825a
172 changeset: 0:8580ff50825a
173 user: test
173 user: test
174 date: Thu Jan 01 00:00:01 1970 +0000
174 date: Thu Jan 01 00:00:01 1970 +0000
175 files: a
175 files: a
176 description:
176 description:
177 a
177 a
178
178
179
179
180
180
181
181
182 log copies with --copies
182 log copies with --copies
183
183
184 $ hg log -vC --template '{rev} {file_copies}\n'
184 $ hg log -vC --template '{rev} {file_copies}\n'
185 4 e (dir/b)
185 4 e (dir/b)
186 3 b (a)
186 3 b (a)
187 2 dir/b (b)
187 2 dir/b (b)
188 1 b (a)
188 1 b (a)
189 0
189 0
190
190
191 log copies switch without --copies, with old filecopy template
191 log copies switch without --copies, with old filecopy template
192
192
193 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
193 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
194 4
194 4
195 3
195 3
196 2
196 2
197 1
197 1
198 0
198 0
199
199
200 log copies switch with --copies
200 log copies switch with --copies
201
201
202 $ hg log -vC --template '{rev} {file_copies_switch}\n'
202 $ hg log -vC --template '{rev} {file_copies_switch}\n'
203 4 e (dir/b)
203 4 e (dir/b)
204 3 b (a)
204 3 b (a)
205 2 dir/b (b)
205 2 dir/b (b)
206 1 b (a)
206 1 b (a)
207 0
207 0
208
208
209
209
210 log copies with hardcoded style and with --style=default
210 log copies with hardcoded style and with --style=default
211
211
212 $ hg log -vC -r4
212 $ hg log -vC -r4
213 changeset: 4:66c1345dc4f9
213 changeset: 4:66c1345dc4f9
214 tag: tip
214 tag: tip
215 user: test
215 user: test
216 date: Thu Jan 01 00:00:05 1970 +0000
216 date: Thu Jan 01 00:00:05 1970 +0000
217 files: dir/b e
217 files: dir/b e
218 copies: e (dir/b)
218 copies: e (dir/b)
219 description:
219 description:
220 e
220 e
221
221
222
222
223 $ hg log -vC -r4 --style=default
223 $ hg log -vC -r4 --style=default
224 changeset: 4:66c1345dc4f9
224 changeset: 4:66c1345dc4f9
225 tag: tip
225 tag: tip
226 user: test
226 user: test
227 date: Thu Jan 01 00:00:05 1970 +0000
227 date: Thu Jan 01 00:00:05 1970 +0000
228 files: dir/b e
228 files: dir/b e
229 copies: e (dir/b)
229 copies: e (dir/b)
230 description:
230 description:
231 e
231 e
232
232
233
233
234
234
235
235
236 log copies, non-linear manifest
236 log copies, non-linear manifest
237
237
238 $ hg up -C 3
238 $ hg up -C 3
239 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
239 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
240 $ hg mv dir/b e
240 $ hg mv dir/b e
241 $ echo foo > foo
241 $ echo foo > foo
242 $ hg ci -Ame2 -d '6 0'
242 $ hg ci -Ame2 -d '6 0'
243 adding foo
243 adding foo
244 created new head
244 created new head
245 $ hg log -v --template '{rev} {file_copies}\n' -r 5
245 $ hg log -v --template '{rev} {file_copies}\n' -r 5
246 5 e (dir/b)
246 5 e (dir/b)
247
247
248
248
249 log copies, execute bit set
249 log copies, execute bit set
250
250
251 $ chmod +x e
251 $ chmod +x e
252 $ hg ci -me3 -d '7 0'
252 $ hg ci -me3 -d '7 0'
253 $ hg log -v --template '{rev} {file_copies}\n' -r 6
253 $ hg log -v --template '{rev} {file_copies}\n' -r 6
254 6
254 6
255
255
256
256
257 log -p d
257 log -p d
258
258
259 $ hg log -pv d
259 $ hg log -pv d
260 changeset: 3:7c6c671bb7cc
260 changeset: 3:7c6c671bb7cc
261 user: test
261 user: test
262 date: Thu Jan 01 00:00:04 1970 +0000
262 date: Thu Jan 01 00:00:04 1970 +0000
263 files: a b d
263 files: a b d
264 description:
264 description:
265 d
265 d
266
266
267
267
268 diff -r 41dd4284081e -r 7c6c671bb7cc d
268 diff -r 41dd4284081e -r 7c6c671bb7cc d
269 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
269 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
270 +++ b/d Thu Jan 01 00:00:04 1970 +0000
270 +++ b/d Thu Jan 01 00:00:04 1970 +0000
271 @@ -0,0 +1,1 @@
271 @@ -0,0 +1,1 @@
272 +a
272 +a
273
273
274
274
275
275
276 log --removed file
276 log --removed file
277
277
278 $ hg log --removed -v a
278 $ hg log --removed -v a
279 changeset: 3:7c6c671bb7cc
279 changeset: 3:7c6c671bb7cc
280 user: test
280 user: test
281 date: Thu Jan 01 00:00:04 1970 +0000
281 date: Thu Jan 01 00:00:04 1970 +0000
282 files: a b d
282 files: a b d
283 description:
283 description:
284 d
284 d
285
285
286
286
287 changeset: 0:8580ff50825a
287 changeset: 0:8580ff50825a
288 user: test
288 user: test
289 date: Thu Jan 01 00:00:01 1970 +0000
289 date: Thu Jan 01 00:00:01 1970 +0000
290 files: a
290 files: a
291 description:
291 description:
292 a
292 a
293
293
294
294
295
295
296 log --removed revrange file
296 log --removed revrange file
297
297
298 $ hg log --removed -v -r0:2 a
298 $ hg log --removed -v -r0:2 a
299 changeset: 0:8580ff50825a
299 changeset: 0:8580ff50825a
300 user: test
300 user: test
301 date: Thu Jan 01 00:00:01 1970 +0000
301 date: Thu Jan 01 00:00:01 1970 +0000
302 files: a
302 files: a
303 description:
303 description:
304 a
304 a
305
305
306
306
307
307
308
308
309 log --follow tests
309 log --follow tests
310
310
311 $ hg init ../follow
311 $ hg init ../follow
312 $ cd ../follow
312 $ cd ../follow
313
313
314 $ echo base > base
314 $ echo base > base
315 $ hg ci -Ambase -d '1 0'
315 $ hg ci -Ambase -d '1 0'
316 adding base
316 adding base
317
317
318 $ echo r1 >> base
318 $ echo r1 >> base
319 $ hg ci -Amr1 -d '1 0'
319 $ hg ci -Amr1 -d '1 0'
320 $ echo r2 >> base
320 $ echo r2 >> base
321 $ hg ci -Amr2 -d '1 0'
321 $ hg ci -Amr2 -d '1 0'
322
322
323 $ hg up -C 1
323 $ hg up -C 1
324 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
324 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
325 $ echo b1 > b1
325 $ echo b1 > b1
326 $ hg ci -Amb1 -d '1 0'
326 $ hg ci -Amb1 -d '1 0'
327 adding b1
327 adding b1
328 created new head
328 created new head
329
329
330
330
331 log -f
331 log -f
332
332
333 $ hg log -f
333 $ hg log -f
334 changeset: 3:e62f78d544b4
334 changeset: 3:e62f78d544b4
335 tag: tip
335 tag: tip
336 parent: 1:3d5bf5654eda
336 parent: 1:3d5bf5654eda
337 user: test
337 user: test
338 date: Thu Jan 01 00:00:01 1970 +0000
338 date: Thu Jan 01 00:00:01 1970 +0000
339 summary: b1
339 summary: b1
340
340
341 changeset: 1:3d5bf5654eda
341 changeset: 1:3d5bf5654eda
342 user: test
342 user: test
343 date: Thu Jan 01 00:00:01 1970 +0000
343 date: Thu Jan 01 00:00:01 1970 +0000
344 summary: r1
344 summary: r1
345
345
346 changeset: 0:67e992f2c4f3
346 changeset: 0:67e992f2c4f3
347 user: test
347 user: test
348 date: Thu Jan 01 00:00:01 1970 +0000
348 date: Thu Jan 01 00:00:01 1970 +0000
349 summary: base
349 summary: base
350
350
351
351
352
352
353 log -f -r 1:tip
353 log -f -r 1:tip
354
354
355 $ hg up -C 0
355 $ hg up -C 0
356 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
356 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
357 $ echo b2 > b2
357 $ echo b2 > b2
358 $ hg ci -Amb2 -d '1 0'
358 $ hg ci -Amb2 -d '1 0'
359 adding b2
359 adding b2
360 created new head
360 created new head
361 $ hg log -f -r 1:tip
361 $ hg log -f -r 1:tip
362 changeset: 1:3d5bf5654eda
362 changeset: 1:3d5bf5654eda
363 user: test
363 user: test
364 date: Thu Jan 01 00:00:01 1970 +0000
364 date: Thu Jan 01 00:00:01 1970 +0000
365 summary: r1
365 summary: r1
366
366
367 changeset: 2:60c670bf5b30
367 changeset: 2:60c670bf5b30
368 user: test
368 user: test
369 date: Thu Jan 01 00:00:01 1970 +0000
369 date: Thu Jan 01 00:00:01 1970 +0000
370 summary: r2
370 summary: r2
371
371
372 changeset: 3:e62f78d544b4
372 changeset: 3:e62f78d544b4
373 parent: 1:3d5bf5654eda
373 parent: 1:3d5bf5654eda
374 user: test
374 user: test
375 date: Thu Jan 01 00:00:01 1970 +0000
375 date: Thu Jan 01 00:00:01 1970 +0000
376 summary: b1
376 summary: b1
377
377
378
378
379
379
380 log -r . with two parents
380 log -r . with two parents
381
381
382 $ hg up -C 3
382 $ hg up -C 3
383 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
383 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
384 $ hg merge tip
384 $ hg merge tip
385 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
385 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
386 (branch merge, don't forget to commit)
386 (branch merge, don't forget to commit)
387 $ hg log -r .
387 $ hg log -r .
388 changeset: 3:e62f78d544b4
388 changeset: 3:e62f78d544b4
389 parent: 1:3d5bf5654eda
389 parent: 1:3d5bf5654eda
390 user: test
390 user: test
391 date: Thu Jan 01 00:00:01 1970 +0000
391 date: Thu Jan 01 00:00:01 1970 +0000
392 summary: b1
392 summary: b1
393
393
394
394
395
395
396 log -r . with one parent
396 log -r . with one parent
397
397
398 $ hg ci -mm12 -d '1 0'
398 $ hg ci -mm12 -d '1 0'
399 $ hg log -r .
399 $ hg log -r .
400 changeset: 5:302e9dd6890d
400 changeset: 5:302e9dd6890d
401 tag: tip
401 tag: tip
402 parent: 3:e62f78d544b4
402 parent: 3:e62f78d544b4
403 parent: 4:ddb82e70d1a1
403 parent: 4:ddb82e70d1a1
404 user: test
404 user: test
405 date: Thu Jan 01 00:00:01 1970 +0000
405 date: Thu Jan 01 00:00:01 1970 +0000
406 summary: m12
406 summary: m12
407
407
408
408
409 $ echo postm >> b1
409 $ echo postm >> b1
410 $ hg ci -Amb1.1 -d'1 0'
410 $ hg ci -Amb1.1 -d'1 0'
411
411
412
412
413 log --follow-first
413 log --follow-first
414
414
415 $ hg log --follow-first
415 $ hg log --follow-first
416 changeset: 6:2404bbcab562
416 changeset: 6:2404bbcab562
417 tag: tip
417 tag: tip
418 user: test
418 user: test
419 date: Thu Jan 01 00:00:01 1970 +0000
419 date: Thu Jan 01 00:00:01 1970 +0000
420 summary: b1.1
420 summary: b1.1
421
421
422 changeset: 5:302e9dd6890d
422 changeset: 5:302e9dd6890d
423 parent: 3:e62f78d544b4
423 parent: 3:e62f78d544b4
424 parent: 4:ddb82e70d1a1
424 parent: 4:ddb82e70d1a1
425 user: test
425 user: test
426 date: Thu Jan 01 00:00:01 1970 +0000
426 date: Thu Jan 01 00:00:01 1970 +0000
427 summary: m12
427 summary: m12
428
428
429 changeset: 3:e62f78d544b4
429 changeset: 3:e62f78d544b4
430 parent: 1:3d5bf5654eda
430 parent: 1:3d5bf5654eda
431 user: test
431 user: test
432 date: Thu Jan 01 00:00:01 1970 +0000
432 date: Thu Jan 01 00:00:01 1970 +0000
433 summary: b1
433 summary: b1
434
434
435 changeset: 1:3d5bf5654eda
435 changeset: 1:3d5bf5654eda
436 user: test
436 user: test
437 date: Thu Jan 01 00:00:01 1970 +0000
437 date: Thu Jan 01 00:00:01 1970 +0000
438 summary: r1
438 summary: r1
439
439
440 changeset: 0:67e992f2c4f3
440 changeset: 0:67e992f2c4f3
441 user: test
441 user: test
442 date: Thu Jan 01 00:00:01 1970 +0000
442 date: Thu Jan 01 00:00:01 1970 +0000
443 summary: base
443 summary: base
444
444
445
445
446
446
447 log -P 2
447 log -P 2
448
448
449 $ hg log -P 2
449 $ hg log -P 2
450 changeset: 6:2404bbcab562
450 changeset: 6:2404bbcab562
451 tag: tip
451 tag: tip
452 user: test
452 user: test
453 date: Thu Jan 01 00:00:01 1970 +0000
453 date: Thu Jan 01 00:00:01 1970 +0000
454 summary: b1.1
454 summary: b1.1
455
455
456 changeset: 5:302e9dd6890d
456 changeset: 5:302e9dd6890d
457 parent: 3:e62f78d544b4
457 parent: 3:e62f78d544b4
458 parent: 4:ddb82e70d1a1
458 parent: 4:ddb82e70d1a1
459 user: test
459 user: test
460 date: Thu Jan 01 00:00:01 1970 +0000
460 date: Thu Jan 01 00:00:01 1970 +0000
461 summary: m12
461 summary: m12
462
462
463 changeset: 4:ddb82e70d1a1
463 changeset: 4:ddb82e70d1a1
464 parent: 0:67e992f2c4f3
464 parent: 0:67e992f2c4f3
465 user: test
465 user: test
466 date: Thu Jan 01 00:00:01 1970 +0000
466 date: Thu Jan 01 00:00:01 1970 +0000
467 summary: b2
467 summary: b2
468
468
469 changeset: 3:e62f78d544b4
469 changeset: 3:e62f78d544b4
470 parent: 1:3d5bf5654eda
470 parent: 1:3d5bf5654eda
471 user: test
471 user: test
472 date: Thu Jan 01 00:00:01 1970 +0000
472 date: Thu Jan 01 00:00:01 1970 +0000
473 summary: b1
473 summary: b1
474
474
475
475
476
476
477 log -r tip -p --git
477 log -r tip -p --git
478
478
479 $ hg log -r tip -p --git
479 $ hg log -r tip -p --git
480 changeset: 6:2404bbcab562
480 changeset: 6:2404bbcab562
481 tag: tip
481 tag: tip
482 user: test
482 user: test
483 date: Thu Jan 01 00:00:01 1970 +0000
483 date: Thu Jan 01 00:00:01 1970 +0000
484 summary: b1.1
484 summary: b1.1
485
485
486 diff --git a/b1 b/b1
486 diff --git a/b1 b/b1
487 --- a/b1
487 --- a/b1
488 +++ b/b1
488 +++ b/b1
489 @@ -1,1 +1,2 @@
489 @@ -1,1 +1,2 @@
490 b1
490 b1
491 +postm
491 +postm
492
492
493
493
494
494
495 log -r ""
495 log -r ""
496
496
497 $ hg log -r ''
497 $ hg log -r ''
498 hg: parse error: empty query
498 hg: parse error: empty query
499 [255]
499 [255]
500
500
501 log -r <some unknown node id>
501 log -r <some unknown node id>
502
502
503 $ hg log -r 1000000000000000000000000000000000000000
503 $ hg log -r 1000000000000000000000000000000000000000
504 abort: unknown revision '1000000000000000000000000000000000000000'!
504 abort: unknown revision '1000000000000000000000000000000000000000'!
505 [255]
505 [255]
506
506
507 log -k r1
507 log -k r1
508
508
509 $ hg log -k r1
509 $ hg log -k r1
510 changeset: 1:3d5bf5654eda
510 changeset: 1:3d5bf5654eda
511 user: test
511 user: test
512 date: Thu Jan 01 00:00:01 1970 +0000
512 date: Thu Jan 01 00:00:01 1970 +0000
513 summary: r1
513 summary: r1
514
514
515 log -d " " (whitespaces only)
515 log -d " " (whitespaces only)
516
516
517 $ hg log -d " "
517 $ hg log -d " "
518 abort: dates cannot consist entirely of whitespace
518 abort: dates cannot consist entirely of whitespace
519 [255]
519 [255]
520
520
521 log -d -1
521 log -d -1
522
522
523 $ hg log -d -1
523 $ hg log -d -1
524
524
525 log -d ">"
525 log -d ">"
526
526
527 $ hg log -d ">"
527 $ hg log -d ">"
528 abort: invalid day spec, use '>DATE'
528 abort: invalid day spec, use '>DATE'
529 [255]
529 [255]
530
530
531 log -d "<"
531 log -d "<"
532
532
533 $ hg log -d "<"
533 $ hg log -d "<"
534 abort: invalid day spec, use '<DATE'
534 abort: invalid day spec, use '<DATE'
535 [255]
535 [255]
536
536
537 Negative ranges
537 Negative ranges
538 $ hg log -d "--2"
538 $ hg log -d "--2"
539 abort: -2 must be nonnegative (see 'hg help dates')
539 abort: -2 must be nonnegative (see 'hg help dates')
540 [255]
540 [255]
541
541
542
542
543 log -p -l2 --color=always
543 log -p -l2 --color=always
544
544
545 $ hg --config extensions.color= --config color.mode=ansi \
545 $ hg --config extensions.color= --config color.mode=ansi \
546 > log -p -l2 --color=always
546 > log -p -l2 --color=always
547 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
547 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
548 tag: tip
548 tag: tip
549 user: test
549 user: test
550 date: Thu Jan 01 00:00:01 1970 +0000
550 date: Thu Jan 01 00:00:01 1970 +0000
551 summary: b1.1
551 summary: b1.1
552
552
553 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
553 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
554 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
554 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
555 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
555 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
556 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
556 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
557 b1
557 b1
558 \x1b[0;32m+postm\x1b[0m (esc)
558 \x1b[0;32m+postm\x1b[0m (esc)
559
559
560 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
560 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
561 parent: 3:e62f78d544b4
561 parent: 3:e62f78d544b4
562 parent: 4:ddb82e70d1a1
562 parent: 4:ddb82e70d1a1
563 user: test
563 user: test
564 date: Thu Jan 01 00:00:01 1970 +0000
564 date: Thu Jan 01 00:00:01 1970 +0000
565 summary: m12
565 summary: m12
566
566
567 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
567 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
568 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
568 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
569 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
569 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
570 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
570 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
571 \x1b[0;32m+b2\x1b[0m (esc)
571 \x1b[0;32m+b2\x1b[0m (esc)
572
572
573
573
574
574
575 log -r tip --stat
575 log -r tip --stat
576
576
577 $ hg log -r tip --stat
577 $ hg log -r tip --stat
578 changeset: 6:2404bbcab562
578 changeset: 6:2404bbcab562
579 tag: tip
579 tag: tip
580 user: test
580 user: test
581 date: Thu Jan 01 00:00:01 1970 +0000
581 date: Thu Jan 01 00:00:01 1970 +0000
582 summary: b1.1
582 summary: b1.1
583
583
584 b1 | 1 +
584 b1 | 1 +
585 1 files changed, 1 insertions(+), 0 deletions(-)
585 1 files changed, 1 insertions(+), 0 deletions(-)
586
586
587
587
588 $ cd ..
588 $ cd ..
589
589
590 $ hg init usertest
590 $ hg init usertest
591 $ cd usertest
591 $ cd usertest
592
592
593 $ echo a > a
593 $ echo a > a
594 $ hg ci -A -m "a" -u "User One <user1@example.org>"
594 $ hg ci -A -m "a" -u "User One <user1@example.org>"
595 adding a
595 adding a
596 $ echo b > b
596 $ echo b > b
597 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
597 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
598 adding b
598 adding b
599
599
600 $ hg log -u "User One <user1@example.org>"
600 $ hg log -u "User One <user1@example.org>"
601 changeset: 0:29a4c94f1924
601 changeset: 0:29a4c94f1924
602 user: User One <user1@example.org>
602 user: User One <user1@example.org>
603 date: Thu Jan 01 00:00:00 1970 +0000
603 date: Thu Jan 01 00:00:00 1970 +0000
604 summary: a
604 summary: a
605
605
606 $ hg log -u "user1" -u "user2"
606 $ hg log -u "user1" -u "user2"
607 changeset: 1:e834b5e69c0e
607 changeset: 1:e834b5e69c0e
608 tag: tip
608 tag: tip
609 user: User Two <user2@example.org>
609 user: User Two <user2@example.org>
610 date: Thu Jan 01 00:00:00 1970 +0000
610 date: Thu Jan 01 00:00:00 1970 +0000
611 summary: b
611 summary: b
612
612
613 changeset: 0:29a4c94f1924
613 changeset: 0:29a4c94f1924
614 user: User One <user1@example.org>
614 user: User One <user1@example.org>
615 date: Thu Jan 01 00:00:00 1970 +0000
615 date: Thu Jan 01 00:00:00 1970 +0000
616 summary: a
616 summary: a
617
617
618 $ hg log -u "user3"
618 $ hg log -u "user3"
619
619
620 $ cd ..
620 $ cd ..
621
621
622 $ hg init branches
622 $ hg init branches
623 $ cd branches
623 $ cd branches
624
624
625 $ echo a > a
625 $ echo a > a
626 $ hg ci -A -m "commit on default"
626 $ hg ci -A -m "commit on default"
627 adding a
627 adding a
628 $ hg branch test
628 $ hg branch test
629 marked working directory as branch test
629 marked working directory as branch test
630 (branches are permanent and global, did you want a bookmark?)
630 $ echo b > b
631 $ echo b > b
631 $ hg ci -A -m "commit on test"
632 $ hg ci -A -m "commit on test"
632 adding b
633 adding b
633
634
634 $ hg up default
635 $ hg up default
635 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
636 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
636 $ echo c > c
637 $ echo c > c
637 $ hg ci -A -m "commit on default"
638 $ hg ci -A -m "commit on default"
638 adding c
639 adding c
639 $ hg up test
640 $ hg up test
640 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
641 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
641 $ echo c > c
642 $ echo c > c
642 $ hg ci -A -m "commit on test"
643 $ hg ci -A -m "commit on test"
643 adding c
644 adding c
644
645
645
646
646 log -b default
647 log -b default
647
648
648 $ hg log -b default
649 $ hg log -b default
649 changeset: 2:c3a4f03cc9a7
650 changeset: 2:c3a4f03cc9a7
650 parent: 0:24427303d56f
651 parent: 0:24427303d56f
651 user: test
652 user: test
652 date: Thu Jan 01 00:00:00 1970 +0000
653 date: Thu Jan 01 00:00:00 1970 +0000
653 summary: commit on default
654 summary: commit on default
654
655
655 changeset: 0:24427303d56f
656 changeset: 0:24427303d56f
656 user: test
657 user: test
657 date: Thu Jan 01 00:00:00 1970 +0000
658 date: Thu Jan 01 00:00:00 1970 +0000
658 summary: commit on default
659 summary: commit on default
659
660
660
661
661
662
662 log -b test
663 log -b test
663
664
664 $ hg log -b test
665 $ hg log -b test
665 changeset: 3:f5d8de11c2e2
666 changeset: 3:f5d8de11c2e2
666 branch: test
667 branch: test
667 tag: tip
668 tag: tip
668 parent: 1:d32277701ccb
669 parent: 1:d32277701ccb
669 user: test
670 user: test
670 date: Thu Jan 01 00:00:00 1970 +0000
671 date: Thu Jan 01 00:00:00 1970 +0000
671 summary: commit on test
672 summary: commit on test
672
673
673 changeset: 1:d32277701ccb
674 changeset: 1:d32277701ccb
674 branch: test
675 branch: test
675 user: test
676 user: test
676 date: Thu Jan 01 00:00:00 1970 +0000
677 date: Thu Jan 01 00:00:00 1970 +0000
677 summary: commit on test
678 summary: commit on test
678
679
679
680
680
681
681 log -b dummy
682 log -b dummy
682
683
683 $ hg log -b dummy
684 $ hg log -b dummy
684 abort: unknown revision 'dummy'!
685 abort: unknown revision 'dummy'!
685 [255]
686 [255]
686
687
687
688
688 log -b .
689 log -b .
689
690
690 $ hg log -b .
691 $ hg log -b .
691 changeset: 3:f5d8de11c2e2
692 changeset: 3:f5d8de11c2e2
692 branch: test
693 branch: test
693 tag: tip
694 tag: tip
694 parent: 1:d32277701ccb
695 parent: 1:d32277701ccb
695 user: test
696 user: test
696 date: Thu Jan 01 00:00:00 1970 +0000
697 date: Thu Jan 01 00:00:00 1970 +0000
697 summary: commit on test
698 summary: commit on test
698
699
699 changeset: 1:d32277701ccb
700 changeset: 1:d32277701ccb
700 branch: test
701 branch: test
701 user: test
702 user: test
702 date: Thu Jan 01 00:00:00 1970 +0000
703 date: Thu Jan 01 00:00:00 1970 +0000
703 summary: commit on test
704 summary: commit on test
704
705
705
706
706
707
707 log -b default -b test
708 log -b default -b test
708
709
709 $ hg log -b default -b test
710 $ hg log -b default -b test
710 changeset: 3:f5d8de11c2e2
711 changeset: 3:f5d8de11c2e2
711 branch: test
712 branch: test
712 tag: tip
713 tag: tip
713 parent: 1:d32277701ccb
714 parent: 1:d32277701ccb
714 user: test
715 user: test
715 date: Thu Jan 01 00:00:00 1970 +0000
716 date: Thu Jan 01 00:00:00 1970 +0000
716 summary: commit on test
717 summary: commit on test
717
718
718 changeset: 2:c3a4f03cc9a7
719 changeset: 2:c3a4f03cc9a7
719 parent: 0:24427303d56f
720 parent: 0:24427303d56f
720 user: test
721 user: test
721 date: Thu Jan 01 00:00:00 1970 +0000
722 date: Thu Jan 01 00:00:00 1970 +0000
722 summary: commit on default
723 summary: commit on default
723
724
724 changeset: 1:d32277701ccb
725 changeset: 1:d32277701ccb
725 branch: test
726 branch: test
726 user: test
727 user: test
727 date: Thu Jan 01 00:00:00 1970 +0000
728 date: Thu Jan 01 00:00:00 1970 +0000
728 summary: commit on test
729 summary: commit on test
729
730
730 changeset: 0:24427303d56f
731 changeset: 0:24427303d56f
731 user: test
732 user: test
732 date: Thu Jan 01 00:00:00 1970 +0000
733 date: Thu Jan 01 00:00:00 1970 +0000
733 summary: commit on default
734 summary: commit on default
734
735
735
736
736
737
737 log -b default -b .
738 log -b default -b .
738
739
739 $ hg log -b default -b .
740 $ hg log -b default -b .
740 changeset: 3:f5d8de11c2e2
741 changeset: 3:f5d8de11c2e2
741 branch: test
742 branch: test
742 tag: tip
743 tag: tip
743 parent: 1:d32277701ccb
744 parent: 1:d32277701ccb
744 user: test
745 user: test
745 date: Thu Jan 01 00:00:00 1970 +0000
746 date: Thu Jan 01 00:00:00 1970 +0000
746 summary: commit on test
747 summary: commit on test
747
748
748 changeset: 2:c3a4f03cc9a7
749 changeset: 2:c3a4f03cc9a7
749 parent: 0:24427303d56f
750 parent: 0:24427303d56f
750 user: test
751 user: test
751 date: Thu Jan 01 00:00:00 1970 +0000
752 date: Thu Jan 01 00:00:00 1970 +0000
752 summary: commit on default
753 summary: commit on default
753
754
754 changeset: 1:d32277701ccb
755 changeset: 1:d32277701ccb
755 branch: test
756 branch: test
756 user: test
757 user: test
757 date: Thu Jan 01 00:00:00 1970 +0000
758 date: Thu Jan 01 00:00:00 1970 +0000
758 summary: commit on test
759 summary: commit on test
759
760
760 changeset: 0:24427303d56f
761 changeset: 0:24427303d56f
761 user: test
762 user: test
762 date: Thu Jan 01 00:00:00 1970 +0000
763 date: Thu Jan 01 00:00:00 1970 +0000
763 summary: commit on default
764 summary: commit on default
764
765
765
766
766
767
767 log -b . -b test
768 log -b . -b test
768
769
769 $ hg log -b . -b test
770 $ hg log -b . -b test
770 changeset: 3:f5d8de11c2e2
771 changeset: 3:f5d8de11c2e2
771 branch: test
772 branch: test
772 tag: tip
773 tag: tip
773 parent: 1:d32277701ccb
774 parent: 1:d32277701ccb
774 user: test
775 user: test
775 date: Thu Jan 01 00:00:00 1970 +0000
776 date: Thu Jan 01 00:00:00 1970 +0000
776 summary: commit on test
777 summary: commit on test
777
778
778 changeset: 1:d32277701ccb
779 changeset: 1:d32277701ccb
779 branch: test
780 branch: test
780 user: test
781 user: test
781 date: Thu Jan 01 00:00:00 1970 +0000
782 date: Thu Jan 01 00:00:00 1970 +0000
782 summary: commit on test
783 summary: commit on test
783
784
784
785
785
786
786 log -b 2
787 log -b 2
787
788
788 $ hg log -b 2
789 $ hg log -b 2
789 changeset: 2:c3a4f03cc9a7
790 changeset: 2:c3a4f03cc9a7
790 parent: 0:24427303d56f
791 parent: 0:24427303d56f
791 user: test
792 user: test
792 date: Thu Jan 01 00:00:00 1970 +0000
793 date: Thu Jan 01 00:00:00 1970 +0000
793 summary: commit on default
794 summary: commit on default
794
795
795 changeset: 0:24427303d56f
796 changeset: 0:24427303d56f
796 user: test
797 user: test
797 date: Thu Jan 01 00:00:00 1970 +0000
798 date: Thu Jan 01 00:00:00 1970 +0000
798 summary: commit on default
799 summary: commit on default
799
800
800
801
801
802
802 log -p --cwd dir (in subdir)
803 log -p --cwd dir (in subdir)
803
804
804 $ mkdir dir
805 $ mkdir dir
805 $ hg log -p --cwd dir
806 $ hg log -p --cwd dir
806 changeset: 3:f5d8de11c2e2
807 changeset: 3:f5d8de11c2e2
807 branch: test
808 branch: test
808 tag: tip
809 tag: tip
809 parent: 1:d32277701ccb
810 parent: 1:d32277701ccb
810 user: test
811 user: test
811 date: Thu Jan 01 00:00:00 1970 +0000
812 date: Thu Jan 01 00:00:00 1970 +0000
812 summary: commit on test
813 summary: commit on test
813
814
814 diff -r d32277701ccb -r f5d8de11c2e2 c
815 diff -r d32277701ccb -r f5d8de11c2e2 c
815 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
816 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
816 +++ b/c Thu Jan 01 00:00:00 1970 +0000
817 +++ b/c Thu Jan 01 00:00:00 1970 +0000
817 @@ -0,0 +1,1 @@
818 @@ -0,0 +1,1 @@
818 +c
819 +c
819
820
820 changeset: 2:c3a4f03cc9a7
821 changeset: 2:c3a4f03cc9a7
821 parent: 0:24427303d56f
822 parent: 0:24427303d56f
822 user: test
823 user: test
823 date: Thu Jan 01 00:00:00 1970 +0000
824 date: Thu Jan 01 00:00:00 1970 +0000
824 summary: commit on default
825 summary: commit on default
825
826
826 diff -r 24427303d56f -r c3a4f03cc9a7 c
827 diff -r 24427303d56f -r c3a4f03cc9a7 c
827 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
828 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
828 +++ b/c Thu Jan 01 00:00:00 1970 +0000
829 +++ b/c Thu Jan 01 00:00:00 1970 +0000
829 @@ -0,0 +1,1 @@
830 @@ -0,0 +1,1 @@
830 +c
831 +c
831
832
832 changeset: 1:d32277701ccb
833 changeset: 1:d32277701ccb
833 branch: test
834 branch: test
834 user: test
835 user: test
835 date: Thu Jan 01 00:00:00 1970 +0000
836 date: Thu Jan 01 00:00:00 1970 +0000
836 summary: commit on test
837 summary: commit on test
837
838
838 diff -r 24427303d56f -r d32277701ccb b
839 diff -r 24427303d56f -r d32277701ccb b
839 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
840 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
840 +++ b/b Thu Jan 01 00:00:00 1970 +0000
841 +++ b/b Thu Jan 01 00:00:00 1970 +0000
841 @@ -0,0 +1,1 @@
842 @@ -0,0 +1,1 @@
842 +b
843 +b
843
844
844 changeset: 0:24427303d56f
845 changeset: 0:24427303d56f
845 user: test
846 user: test
846 date: Thu Jan 01 00:00:00 1970 +0000
847 date: Thu Jan 01 00:00:00 1970 +0000
847 summary: commit on default
848 summary: commit on default
848
849
849 diff -r 000000000000 -r 24427303d56f a
850 diff -r 000000000000 -r 24427303d56f a
850 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
851 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
851 +++ b/a Thu Jan 01 00:00:00 1970 +0000
852 +++ b/a Thu Jan 01 00:00:00 1970 +0000
852 @@ -0,0 +1,1 @@
853 @@ -0,0 +1,1 @@
853 +a
854 +a
854
855
855
856
856
857
857 log -p -R repo
858 log -p -R repo
858
859
859 $ cd dir
860 $ cd dir
860 $ hg log -p -R .. ../a
861 $ hg log -p -R .. ../a
861 changeset: 0:24427303d56f
862 changeset: 0:24427303d56f
862 user: test
863 user: test
863 date: Thu Jan 01 00:00:00 1970 +0000
864 date: Thu Jan 01 00:00:00 1970 +0000
864 summary: commit on default
865 summary: commit on default
865
866
866 diff -r 000000000000 -r 24427303d56f a
867 diff -r 000000000000 -r 24427303d56f a
867 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
868 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
868 +++ b/a Thu Jan 01 00:00:00 1970 +0000
869 +++ b/a Thu Jan 01 00:00:00 1970 +0000
869 @@ -0,0 +1,1 @@
870 @@ -0,0 +1,1 @@
870 +a
871 +a
871
872
872
873
873
874
874 $ cd ..
875 $ cd ..
875 $ hg init follow2
876 $ hg init follow2
876 $ cd follow2
877 $ cd follow2
877
878
878
879
879 # Build the following history:
880 # Build the following history:
880 # tip - o - x - o - x - x
881 # tip - o - x - o - x - x
881 # \ /
882 # \ /
882 # o - o - o - x
883 # o - o - o - x
883 # \ /
884 # \ /
884 # o
885 # o
885 #
886 #
886 # Where "o" is a revision containing "foo" and
887 # Where "o" is a revision containing "foo" and
887 # "x" is a revision without "foo"
888 # "x" is a revision without "foo"
888
889
889 $ touch init
890 $ touch init
890 $ hg ci -A -m "init, unrelated"
891 $ hg ci -A -m "init, unrelated"
891 adding init
892 adding init
892 $ echo 'foo' > init
893 $ echo 'foo' > init
893 $ hg ci -m "change, unrelated"
894 $ hg ci -m "change, unrelated"
894 $ echo 'foo' > foo
895 $ echo 'foo' > foo
895 $ hg ci -A -m "add unrelated old foo"
896 $ hg ci -A -m "add unrelated old foo"
896 adding foo
897 adding foo
897 $ hg rm foo
898 $ hg rm foo
898 $ hg ci -m "delete foo, unrelated"
899 $ hg ci -m "delete foo, unrelated"
899 $ echo 'related' > foo
900 $ echo 'related' > foo
900 $ hg ci -A -m "add foo, related"
901 $ hg ci -A -m "add foo, related"
901 adding foo
902 adding foo
902
903
903 $ hg up 0
904 $ hg up 0
904 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
905 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
905 $ touch branch
906 $ touch branch
906 $ hg ci -A -m "first branch, unrelated"
907 $ hg ci -A -m "first branch, unrelated"
907 adding branch
908 adding branch
908 created new head
909 created new head
909 $ touch foo
910 $ touch foo
910 $ hg ci -A -m "create foo, related"
911 $ hg ci -A -m "create foo, related"
911 adding foo
912 adding foo
912 $ echo 'change' > foo
913 $ echo 'change' > foo
913 $ hg ci -m "change foo, related"
914 $ hg ci -m "change foo, related"
914
915
915 $ hg up 6
916 $ hg up 6
916 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
917 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
917 $ echo 'change foo in branch' > foo
918 $ echo 'change foo in branch' > foo
918 $ hg ci -m "change foo in branch, related"
919 $ hg ci -m "change foo in branch, related"
919 created new head
920 created new head
920 $ hg merge 7
921 $ hg merge 7
921 merging foo
922 merging foo
922 warning: conflicts during merge.
923 warning: conflicts during merge.
923 merging foo failed!
924 merging foo failed!
924 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
925 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
925 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
926 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
926 [1]
927 [1]
927 $ echo 'merge 1' > foo
928 $ echo 'merge 1' > foo
928 $ hg resolve -m foo
929 $ hg resolve -m foo
929 $ hg ci -m "First merge, related"
930 $ hg ci -m "First merge, related"
930
931
931 $ hg merge 4
932 $ hg merge 4
932 merging foo
933 merging foo
933 warning: conflicts during merge.
934 warning: conflicts during merge.
934 merging foo failed!
935 merging foo failed!
935 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
936 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
936 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
937 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
937 [1]
938 [1]
938 $ echo 'merge 2' > foo
939 $ echo 'merge 2' > foo
939 $ hg resolve -m foo
940 $ hg resolve -m foo
940 $ hg ci -m "Last merge, related"
941 $ hg ci -m "Last merge, related"
941
942
942 $ hg --config "extensions.graphlog=" glog
943 $ hg --config "extensions.graphlog=" glog
943 @ changeset: 10:4dae8563d2c5
944 @ changeset: 10:4dae8563d2c5
944 |\ tag: tip
945 |\ tag: tip
945 | | parent: 9:7b35701b003e
946 | | parent: 9:7b35701b003e
946 | | parent: 4:88176d361b69
947 | | parent: 4:88176d361b69
947 | | user: test
948 | | user: test
948 | | date: Thu Jan 01 00:00:00 1970 +0000
949 | | date: Thu Jan 01 00:00:00 1970 +0000
949 | | summary: Last merge, related
950 | | summary: Last merge, related
950 | |
951 | |
951 | o changeset: 9:7b35701b003e
952 | o changeset: 9:7b35701b003e
952 | |\ parent: 8:e5416ad8a855
953 | |\ parent: 8:e5416ad8a855
953 | | | parent: 7:87fe3144dcfa
954 | | | parent: 7:87fe3144dcfa
954 | | | user: test
955 | | | user: test
955 | | | date: Thu Jan 01 00:00:00 1970 +0000
956 | | | date: Thu Jan 01 00:00:00 1970 +0000
956 | | | summary: First merge, related
957 | | | summary: First merge, related
957 | | |
958 | | |
958 | | o changeset: 8:e5416ad8a855
959 | | o changeset: 8:e5416ad8a855
959 | | | parent: 6:dc6c325fe5ee
960 | | | parent: 6:dc6c325fe5ee
960 | | | user: test
961 | | | user: test
961 | | | date: Thu Jan 01 00:00:00 1970 +0000
962 | | | date: Thu Jan 01 00:00:00 1970 +0000
962 | | | summary: change foo in branch, related
963 | | | summary: change foo in branch, related
963 | | |
964 | | |
964 | o | changeset: 7:87fe3144dcfa
965 | o | changeset: 7:87fe3144dcfa
965 | |/ user: test
966 | |/ user: test
966 | | date: Thu Jan 01 00:00:00 1970 +0000
967 | | date: Thu Jan 01 00:00:00 1970 +0000
967 | | summary: change foo, related
968 | | summary: change foo, related
968 | |
969 | |
969 | o changeset: 6:dc6c325fe5ee
970 | o changeset: 6:dc6c325fe5ee
970 | | user: test
971 | | user: test
971 | | date: Thu Jan 01 00:00:00 1970 +0000
972 | | date: Thu Jan 01 00:00:00 1970 +0000
972 | | summary: create foo, related
973 | | summary: create foo, related
973 | |
974 | |
974 | o changeset: 5:73db34516eb9
975 | o changeset: 5:73db34516eb9
975 | | parent: 0:e87515fd044a
976 | | parent: 0:e87515fd044a
976 | | user: test
977 | | user: test
977 | | date: Thu Jan 01 00:00:00 1970 +0000
978 | | date: Thu Jan 01 00:00:00 1970 +0000
978 | | summary: first branch, unrelated
979 | | summary: first branch, unrelated
979 | |
980 | |
980 o | changeset: 4:88176d361b69
981 o | changeset: 4:88176d361b69
981 | | user: test
982 | | user: test
982 | | date: Thu Jan 01 00:00:00 1970 +0000
983 | | date: Thu Jan 01 00:00:00 1970 +0000
983 | | summary: add foo, related
984 | | summary: add foo, related
984 | |
985 | |
985 o | changeset: 3:dd78ae4afb56
986 o | changeset: 3:dd78ae4afb56
986 | | user: test
987 | | user: test
987 | | date: Thu Jan 01 00:00:00 1970 +0000
988 | | date: Thu Jan 01 00:00:00 1970 +0000
988 | | summary: delete foo, unrelated
989 | | summary: delete foo, unrelated
989 | |
990 | |
990 o | changeset: 2:c4c64aedf0f7
991 o | changeset: 2:c4c64aedf0f7
991 | | user: test
992 | | user: test
992 | | date: Thu Jan 01 00:00:00 1970 +0000
993 | | date: Thu Jan 01 00:00:00 1970 +0000
993 | | summary: add unrelated old foo
994 | | summary: add unrelated old foo
994 | |
995 | |
995 o | changeset: 1:e5faa7440653
996 o | changeset: 1:e5faa7440653
996 |/ user: test
997 |/ user: test
997 | date: Thu Jan 01 00:00:00 1970 +0000
998 | date: Thu Jan 01 00:00:00 1970 +0000
998 | summary: change, unrelated
999 | summary: change, unrelated
999 |
1000 |
1000 o changeset: 0:e87515fd044a
1001 o changeset: 0:e87515fd044a
1001 user: test
1002 user: test
1002 date: Thu Jan 01 00:00:00 1970 +0000
1003 date: Thu Jan 01 00:00:00 1970 +0000
1003 summary: init, unrelated
1004 summary: init, unrelated
1004
1005
1005
1006
1006 $ hg --traceback log -f foo
1007 $ hg --traceback log -f foo
1007 changeset: 10:4dae8563d2c5
1008 changeset: 10:4dae8563d2c5
1008 tag: tip
1009 tag: tip
1009 parent: 9:7b35701b003e
1010 parent: 9:7b35701b003e
1010 parent: 4:88176d361b69
1011 parent: 4:88176d361b69
1011 user: test
1012 user: test
1012 date: Thu Jan 01 00:00:00 1970 +0000
1013 date: Thu Jan 01 00:00:00 1970 +0000
1013 summary: Last merge, related
1014 summary: Last merge, related
1014
1015
1015 changeset: 9:7b35701b003e
1016 changeset: 9:7b35701b003e
1016 parent: 8:e5416ad8a855
1017 parent: 8:e5416ad8a855
1017 parent: 7:87fe3144dcfa
1018 parent: 7:87fe3144dcfa
1018 user: test
1019 user: test
1019 date: Thu Jan 01 00:00:00 1970 +0000
1020 date: Thu Jan 01 00:00:00 1970 +0000
1020 summary: First merge, related
1021 summary: First merge, related
1021
1022
1022 changeset: 8:e5416ad8a855
1023 changeset: 8:e5416ad8a855
1023 parent: 6:dc6c325fe5ee
1024 parent: 6:dc6c325fe5ee
1024 user: test
1025 user: test
1025 date: Thu Jan 01 00:00:00 1970 +0000
1026 date: Thu Jan 01 00:00:00 1970 +0000
1026 summary: change foo in branch, related
1027 summary: change foo in branch, related
1027
1028
1028 changeset: 7:87fe3144dcfa
1029 changeset: 7:87fe3144dcfa
1029 user: test
1030 user: test
1030 date: Thu Jan 01 00:00:00 1970 +0000
1031 date: Thu Jan 01 00:00:00 1970 +0000
1031 summary: change foo, related
1032 summary: change foo, related
1032
1033
1033 changeset: 6:dc6c325fe5ee
1034 changeset: 6:dc6c325fe5ee
1034 user: test
1035 user: test
1035 date: Thu Jan 01 00:00:00 1970 +0000
1036 date: Thu Jan 01 00:00:00 1970 +0000
1036 summary: create foo, related
1037 summary: create foo, related
1037
1038
1038 changeset: 4:88176d361b69
1039 changeset: 4:88176d361b69
1039 user: test
1040 user: test
1040 date: Thu Jan 01 00:00:00 1970 +0000
1041 date: Thu Jan 01 00:00:00 1970 +0000
1041 summary: add foo, related
1042 summary: add foo, related
1042
1043
1043
1044
1044 Also check when maxrev < lastrevfilelog
1045 Also check when maxrev < lastrevfilelog
1045
1046
1046 $ hg --traceback log -f -r4 foo
1047 $ hg --traceback log -f -r4 foo
1047 changeset: 4:88176d361b69
1048 changeset: 4:88176d361b69
1048 user: test
1049 user: test
1049 date: Thu Jan 01 00:00:00 1970 +0000
1050 date: Thu Jan 01 00:00:00 1970 +0000
1050 summary: add foo, related
1051 summary: add foo, related
1051
1052
1052
1053
1053 Issue2383: hg log showing _less_ differences than hg diff
1054 Issue2383: hg log showing _less_ differences than hg diff
1054
1055
1055 $ hg init issue2383
1056 $ hg init issue2383
1056 $ cd issue2383
1057 $ cd issue2383
1057
1058
1058 Create a test repo:
1059 Create a test repo:
1059
1060
1060 $ echo a > a
1061 $ echo a > a
1061 $ hg ci -Am0
1062 $ hg ci -Am0
1062 adding a
1063 adding a
1063 $ echo b > b
1064 $ echo b > b
1064 $ hg ci -Am1
1065 $ hg ci -Am1
1065 adding b
1066 adding b
1066 $ hg co 0
1067 $ hg co 0
1067 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1068 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1068 $ echo b > a
1069 $ echo b > a
1069 $ hg ci -m2
1070 $ hg ci -m2
1070 created new head
1071 created new head
1071
1072
1072 Merge:
1073 Merge:
1073
1074
1074 $ hg merge
1075 $ hg merge
1075 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1076 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1076 (branch merge, don't forget to commit)
1077 (branch merge, don't forget to commit)
1077
1078
1078 Make sure there's a file listed in the merge to trigger the bug:
1079 Make sure there's a file listed in the merge to trigger the bug:
1079
1080
1080 $ echo c > a
1081 $ echo c > a
1081 $ hg ci -m3
1082 $ hg ci -m3
1082
1083
1083 Two files shown here in diff:
1084 Two files shown here in diff:
1084
1085
1085 $ hg diff --rev 2:3
1086 $ hg diff --rev 2:3
1086 diff -r b09be438c43a -r 8e07aafe1edc a
1087 diff -r b09be438c43a -r 8e07aafe1edc a
1087 --- a/a Thu Jan 01 00:00:00 1970 +0000
1088 --- a/a Thu Jan 01 00:00:00 1970 +0000
1088 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1089 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1089 @@ -1,1 +1,1 @@
1090 @@ -1,1 +1,1 @@
1090 -b
1091 -b
1091 +c
1092 +c
1092 diff -r b09be438c43a -r 8e07aafe1edc b
1093 diff -r b09be438c43a -r 8e07aafe1edc b
1093 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1094 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1094 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1095 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1095 @@ -0,0 +1,1 @@
1096 @@ -0,0 +1,1 @@
1096 +b
1097 +b
1097
1098
1098 Diff here should be the same:
1099 Diff here should be the same:
1099
1100
1100 $ hg log -vpr 3
1101 $ hg log -vpr 3
1101 changeset: 3:8e07aafe1edc
1102 changeset: 3:8e07aafe1edc
1102 tag: tip
1103 tag: tip
1103 parent: 2:b09be438c43a
1104 parent: 2:b09be438c43a
1104 parent: 1:925d80f479bb
1105 parent: 1:925d80f479bb
1105 user: test
1106 user: test
1106 date: Thu Jan 01 00:00:00 1970 +0000
1107 date: Thu Jan 01 00:00:00 1970 +0000
1107 files: a
1108 files: a
1108 description:
1109 description:
1109 3
1110 3
1110
1111
1111
1112
1112 diff -r b09be438c43a -r 8e07aafe1edc a
1113 diff -r b09be438c43a -r 8e07aafe1edc a
1113 --- a/a Thu Jan 01 00:00:00 1970 +0000
1114 --- a/a Thu Jan 01 00:00:00 1970 +0000
1114 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1115 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1115 @@ -1,1 +1,1 @@
1116 @@ -1,1 +1,1 @@
1116 -b
1117 -b
1117 +c
1118 +c
1118 diff -r b09be438c43a -r 8e07aafe1edc b
1119 diff -r b09be438c43a -r 8e07aafe1edc b
1119 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1120 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1120 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1121 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1121 @@ -0,0 +1,1 @@
1122 @@ -0,0 +1,1 @@
1122 +b
1123 +b
1123
1124
1124 $ cd ..
1125 $ cd ..
1125
1126
1126 'hg log -r rev fn' when last(filelog(fn)) != rev
1127 'hg log -r rev fn' when last(filelog(fn)) != rev
1127
1128
1128 $ hg init simplelog; cd simplelog
1129 $ hg init simplelog; cd simplelog
1129 $ echo f > a
1130 $ echo f > a
1130 $ hg ci -Am'a' -d '0 0'
1131 $ hg ci -Am'a' -d '0 0'
1131 adding a
1132 adding a
1132 $ echo f >> a
1133 $ echo f >> a
1133 $ hg ci -Am'a bis' -d '1 0'
1134 $ hg ci -Am'a bis' -d '1 0'
1134
1135
1135 $ hg log -r0 a
1136 $ hg log -r0 a
1136 changeset: 0:9f758d63dcde
1137 changeset: 0:9f758d63dcde
1137 user: test
1138 user: test
1138 date: Thu Jan 01 00:00:00 1970 +0000
1139 date: Thu Jan 01 00:00:00 1970 +0000
1139 summary: a
1140 summary: a
1140
1141
1141 $ cat > $HGTMP/testhidden.py << EOF
1142 $ cat > $HGTMP/testhidden.py << EOF
1142 > def reposetup(ui, repo):
1143 > def reposetup(ui, repo):
1143 > for line in repo.opener('hidden'):
1144 > for line in repo.opener('hidden'):
1144 > ctx = repo[line.strip()]
1145 > ctx = repo[line.strip()]
1145 > repo.changelog.hiddenrevs.add(ctx.rev())
1146 > repo.changelog.hiddenrevs.add(ctx.rev())
1146 > EOF
1147 > EOF
1147 $ echo '[extensions]' >> $HGRCPATH
1148 $ echo '[extensions]' >> $HGRCPATH
1148 $ echo "hidden=$HGTMP/testhidden.py" >> $HGRCPATH
1149 $ echo "hidden=$HGTMP/testhidden.py" >> $HGRCPATH
1149 $ touch .hg/hidden
1150 $ touch .hg/hidden
1150 $ hg log --template='{rev}:{node}\n'
1151 $ hg log --template='{rev}:{node}\n'
1151 1:a765632148dc55d38c35c4f247c618701886cb2f
1152 1:a765632148dc55d38c35c4f247c618701886cb2f
1152 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1153 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1153 $ echo a765632148dc55d38c35c4f247c618701886cb2f > .hg/hidden
1154 $ echo a765632148dc55d38c35c4f247c618701886cb2f > .hg/hidden
1154 $ hg log --template='{rev}:{node}\n'
1155 $ hg log --template='{rev}:{node}\n'
1155 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1156 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1156 $ hg log --template='{rev}:{node}\n' --hidden
1157 $ hg log --template='{rev}:{node}\n' --hidden
1157 1:a765632148dc55d38c35c4f247c618701886cb2f
1158 1:a765632148dc55d38c35c4f247c618701886cb2f
1158 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1159 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
@@ -1,85 +1,86 b''
1 $ hgcommit() {
1 $ hgcommit() {
2 > hg commit -u user "$@"
2 > hg commit -u user "$@"
3 > }
3 > }
4
4
5 $ hg init clhead
5 $ hg init clhead
6 $ cd clhead
6 $ cd clhead
7
7
8 $ touch foo && hg add && hgcommit -m 'foo'
8 $ touch foo && hg add && hgcommit -m 'foo'
9 adding foo
9 adding foo
10 $ touch bar && hg add && hgcommit -m 'bar'
10 $ touch bar && hg add && hgcommit -m 'bar'
11 adding bar
11 adding bar
12 $ touch baz && hg add && hgcommit -m 'baz'
12 $ touch baz && hg add && hgcommit -m 'baz'
13 adding baz
13 adding baz
14
14
15 $ echo "flub" > foo
15 $ echo "flub" > foo
16 $ hgcommit -m "flub"
16 $ hgcommit -m "flub"
17 $ echo "nub" > foo
17 $ echo "nub" > foo
18 $ hgcommit -m "nub"
18 $ hgcommit -m "nub"
19
19
20 $ hg up -C 2
20 $ hg up -C 2
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22
22
23 $ echo "c1" > c1
23 $ echo "c1" > c1
24 $ hg add c1
24 $ hg add c1
25 $ hgcommit -m "c1"
25 $ hgcommit -m "c1"
26 created new head
26 created new head
27 $ echo "c2" > c1
27 $ echo "c2" > c1
28 $ hgcommit -m "c2"
28 $ hgcommit -m "c2"
29
29
30 $ hg up -C 2
30 $ hg up -C 2
31 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
31 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
32
32
33 $ echo "d1" > d1
33 $ echo "d1" > d1
34 $ hg add d1
34 $ hg add d1
35 $ hgcommit -m "d1"
35 $ hgcommit -m "d1"
36 created new head
36 created new head
37 $ echo "d2" > d1
37 $ echo "d2" > d1
38 $ hgcommit -m "d2"
38 $ hgcommit -m "d2"
39 $ hg tag -l good
39 $ hg tag -l good
40
40
41 fail with three heads
41 fail with three heads
42 $ hg up -C good
42 $ hg up -C good
43 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
43 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 $ hg merge
44 $ hg merge
45 abort: branch 'default' has 3 heads - please merge with an explicit rev
45 abort: branch 'default' has 3 heads - please merge with an explicit rev
46 (run 'hg heads .' to see heads)
46 (run 'hg heads .' to see heads)
47 [255]
47 [255]
48
48
49 close one of the heads
49 close one of the heads
50 $ hg up -C 6
50 $ hg up -C 6
51 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
51 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
52 $ hgcommit -m 'close this head' --close-branch
52 $ hgcommit -m 'close this head' --close-branch
53
53
54 succeed with two open heads
54 succeed with two open heads
55 $ hg up -C good
55 $ hg up -C good
56 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
56 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
57 $ hg up -C good
57 $ hg up -C good
58 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 $ hg merge
59 $ hg merge
60 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 (branch merge, don't forget to commit)
61 (branch merge, don't forget to commit)
62 $ hgcommit -m 'merged heads'
62 $ hgcommit -m 'merged heads'
63
63
64 hg update -C 8
64 hg update -C 8
65 $ hg update -C 8
65 $ hg update -C 8
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
67
67
68 hg branch some-branch
68 hg branch some-branch
69 $ hg branch some-branch
69 $ hg branch some-branch
70 marked working directory as branch some-branch
70 marked working directory as branch some-branch
71 (branches are permanent and global, did you want a bookmark?)
71 hg commit
72 hg commit
72 $ hgcommit -m 'started some-branch'
73 $ hgcommit -m 'started some-branch'
73 hg commit --close-branch
74 hg commit --close-branch
74 $ hgcommit --close-branch -m 'closed some-branch'
75 $ hgcommit --close-branch -m 'closed some-branch'
75
76
76 hg update default
77 hg update default
77 $ hg update default
78 $ hg update default
78 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 hg merge some-branch
80 hg merge some-branch
80 $ hg merge some-branch
81 $ hg merge some-branch
81 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 (branch merge, don't forget to commit)
83 (branch merge, don't forget to commit)
83 hg commit (no reopening of some-branch)
84 hg commit (no reopening of some-branch)
84 $ hgcommit -m 'merge with closed branch'
85 $ hgcommit -m 'merge with closed branch'
85
86
@@ -1,109 +1,110 b''
1 $ hg init
1 $ hg init
2 $ echo a > a
2 $ echo a > a
3 $ hg commit -A -ma
3 $ hg commit -A -ma
4 adding a
4 adding a
5
5
6 $ echo b >> a
6 $ echo b >> a
7 $ hg commit -mb
7 $ hg commit -mb
8
8
9 $ echo c >> a
9 $ echo c >> a
10 $ hg commit -mc
10 $ hg commit -mc
11
11
12 $ hg up 1
12 $ hg up 1
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 $ echo d >> a
14 $ echo d >> a
15 $ hg commit -md
15 $ hg commit -md
16 created new head
16 created new head
17
17
18 $ hg up 1
18 $ hg up 1
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 $ echo e >> a
20 $ echo e >> a
21 $ hg commit -me
21 $ hg commit -me
22 created new head
22 created new head
23
23
24 $ hg up 1
24 $ hg up 1
25 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
26
26
27 Should fail because not at a head:
27 Should fail because not at a head:
28
28
29 $ hg merge
29 $ hg merge
30 abort: branch 'default' has 3 heads - please merge with an explicit rev
30 abort: branch 'default' has 3 heads - please merge with an explicit rev
31 (run 'hg heads .' to see heads)
31 (run 'hg heads .' to see heads)
32 [255]
32 [255]
33
33
34 $ hg up
34 $ hg up
35 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
35 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
36
36
37 Should fail because > 2 heads:
37 Should fail because > 2 heads:
38
38
39 $ HGMERGE=internal:other; export HGMERGE
39 $ HGMERGE=internal:other; export HGMERGE
40 $ hg merge
40 $ hg merge
41 abort: branch 'default' has 3 heads - please merge with an explicit rev
41 abort: branch 'default' has 3 heads - please merge with an explicit rev
42 (run 'hg heads .' to see heads)
42 (run 'hg heads .' to see heads)
43 [255]
43 [255]
44
44
45 Should succeed:
45 Should succeed:
46
46
47 $ hg merge 2
47 $ hg merge 2
48 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
48 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
49 (branch merge, don't forget to commit)
49 (branch merge, don't forget to commit)
50 $ hg commit -mm1
50 $ hg commit -mm1
51
51
52 Should succeed - 2 heads:
52 Should succeed - 2 heads:
53
53
54 $ hg merge -P
54 $ hg merge -P
55 changeset: 3:ea9ff125ff88
55 changeset: 3:ea9ff125ff88
56 parent: 1:1846eede8b68
56 parent: 1:1846eede8b68
57 user: test
57 user: test
58 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
59 summary: d
59 summary: d
60
60
61 $ hg merge
61 $ hg merge
62 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
62 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
63 (branch merge, don't forget to commit)
63 (branch merge, don't forget to commit)
64 $ hg commit -mm2
64 $ hg commit -mm2
65
65
66 Should fail because at tip:
66 Should fail because at tip:
67
67
68 $ hg merge
68 $ hg merge
69 abort: there is nothing to merge
69 abort: there is nothing to merge
70 [255]
70 [255]
71
71
72 $ hg up 0
72 $ hg up 0
73 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
73 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
74
74
75 Should fail because there is only one head:
75 Should fail because there is only one head:
76
76
77 $ hg merge
77 $ hg merge
78 abort: there is nothing to merge - use "hg update" instead
78 abort: there is nothing to merge - use "hg update" instead
79 [255]
79 [255]
80
80
81 $ hg up 3
81 $ hg up 3
82 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
83
83
84 $ echo f >> a
84 $ echo f >> a
85 $ hg branch foobranch
85 $ hg branch foobranch
86 marked working directory as branch foobranch
86 marked working directory as branch foobranch
87 (branches are permanent and global, did you want a bookmark?)
87 $ hg commit -mf
88 $ hg commit -mf
88
89
89 Should fail because merge with other branch:
90 Should fail because merge with other branch:
90
91
91 $ hg merge
92 $ hg merge
92 abort: branch 'foobranch' has one head - please merge with an explicit rev
93 abort: branch 'foobranch' has one head - please merge with an explicit rev
93 (run 'hg heads' to see all heads)
94 (run 'hg heads' to see all heads)
94 [255]
95 [255]
95
96
96
97
97 Test for issue2043: ensure that 'merge -P' shows ancestors of 6 that
98 Test for issue2043: ensure that 'merge -P' shows ancestors of 6 that
98 are not ancestors of 7, regardless of where their least common
99 are not ancestors of 7, regardless of where their least common
99 ancestor is.
100 ancestor is.
100
101
101 Merge preview not affected by common ancestor:
102 Merge preview not affected by common ancestor:
102
103
103 $ hg up -q 7
104 $ hg up -q 7
104 $ hg merge -q -P 6
105 $ hg merge -q -P 6
105 2:2d95304fed5d
106 2:2d95304fed5d
106 4:f25cbe84d8b3
107 4:f25cbe84d8b3
107 5:a431fabd6039
108 5:a431fabd6039
108 6:e88e33f3bf62
109 6:e88e33f3bf62
109
110
@@ -1,175 +1,177 b''
1 $ echo '[extensions]' >> $HGRCPATH
1 $ echo '[extensions]' >> $HGRCPATH
2 $ echo 'mq =' >> $HGRCPATH
2 $ echo 'mq =' >> $HGRCPATH
3
3
4 $ hg init repo
4 $ hg init repo
5 $ cd repo
5 $ cd repo
6
6
7 $ echo foo > foo
7 $ echo foo > foo
8 $ hg ci -qAm 'add a file'
8 $ hg ci -qAm 'add a file'
9
9
10 $ hg qinit
10 $ hg qinit
11
11
12 $ hg qnew foo
12 $ hg qnew foo
13 $ echo foo >> foo
13 $ echo foo >> foo
14 $ hg qrefresh -m 'append foo'
14 $ hg qrefresh -m 'append foo'
15
15
16 $ hg qnew bar
16 $ hg qnew bar
17 $ echo bar >> foo
17 $ echo bar >> foo
18 $ hg qrefresh -m 'append bar'
18 $ hg qrefresh -m 'append bar'
19
19
20
20
21 try to commit on top of a patch
21 try to commit on top of a patch
22
22
23 $ echo quux >> foo
23 $ echo quux >> foo
24 $ hg ci -m 'append quux'
24 $ hg ci -m 'append quux'
25 abort: cannot commit over an applied mq patch
25 abort: cannot commit over an applied mq patch
26 [255]
26 [255]
27
27
28
28
29 cheat a bit...
29 cheat a bit...
30
30
31 $ mv .hg/patches .hg/patches2
31 $ mv .hg/patches .hg/patches2
32 $ hg ci -m 'append quux'
32 $ hg ci -m 'append quux'
33 $ mv .hg/patches2 .hg/patches
33 $ mv .hg/patches2 .hg/patches
34
34
35
35
36 qpop/qrefresh on the wrong revision
36 qpop/qrefresh on the wrong revision
37
37
38 $ hg qpop
38 $ hg qpop
39 abort: popping would remove a revision not managed by this patch queue
39 abort: popping would remove a revision not managed by this patch queue
40 [255]
40 [255]
41 $ hg qpop -n patches
41 $ hg qpop -n patches
42 using patch queue: $TESTTMP/repo/.hg/patches
42 using patch queue: $TESTTMP/repo/.hg/patches
43 abort: popping would remove a revision not managed by this patch queue
43 abort: popping would remove a revision not managed by this patch queue
44 [255]
44 [255]
45 $ hg qrefresh
45 $ hg qrefresh
46 abort: working directory revision is not qtip
46 abort: working directory revision is not qtip
47 [255]
47 [255]
48
48
49 $ hg up -C qtip
49 $ hg up -C qtip
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 $ hg qpop
51 $ hg qpop
52 abort: popping would remove a revision not managed by this patch queue
52 abort: popping would remove a revision not managed by this patch queue
53 [255]
53 [255]
54 $ hg qrefresh
54 $ hg qrefresh
55 abort: cannot refresh a revision with children
55 abort: cannot refresh a revision with children
56 [255]
56 [255]
57 $ hg tip --template '{rev} {desc}\n'
57 $ hg tip --template '{rev} {desc}\n'
58 3 append quux
58 3 append quux
59
59
60
60
61 qpush warning branchheads
61 qpush warning branchheads
62
62
63 $ cd ..
63 $ cd ..
64 $ hg init branchy
64 $ hg init branchy
65 $ cd branchy
65 $ cd branchy
66 $ echo q > q
66 $ echo q > q
67 $ hg add q
67 $ hg add q
68 $ hg qnew -f qp
68 $ hg qnew -f qp
69 $ hg qpop
69 $ hg qpop
70 popping qp
70 popping qp
71 patch queue now empty
71 patch queue now empty
72 $ echo a > a
72 $ echo a > a
73 $ hg ci -Ama
73 $ hg ci -Ama
74 adding a
74 adding a
75 $ hg up null
75 $ hg up null
76 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
76 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
77 $ hg branch b
77 $ hg branch b
78 marked working directory as branch b
78 marked working directory as branch b
79 (branches are permanent and global, did you want a bookmark?)
79 $ echo c > c
80 $ echo c > c
80 $ hg ci -Amc
81 $ hg ci -Amc
81 adding c
82 adding c
82 $ hg merge default
83 $ hg merge default
83 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 (branch merge, don't forget to commit)
85 (branch merge, don't forget to commit)
85 $ hg ci -mmerge
86 $ hg ci -mmerge
86 $ hg up default
87 $ hg up default
87 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
88 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
88 $ hg log
89 $ hg log
89 changeset: 2:65309210bf4e
90 changeset: 2:65309210bf4e
90 branch: b
91 branch: b
91 tag: tip
92 tag: tip
92 parent: 1:707adb4c8ae1
93 parent: 1:707adb4c8ae1
93 parent: 0:cb9a9f314b8b
94 parent: 0:cb9a9f314b8b
94 user: test
95 user: test
95 date: Thu Jan 01 00:00:00 1970 +0000
96 date: Thu Jan 01 00:00:00 1970 +0000
96 summary: merge
97 summary: merge
97
98
98 changeset: 1:707adb4c8ae1
99 changeset: 1:707adb4c8ae1
99 branch: b
100 branch: b
100 parent: -1:000000000000
101 parent: -1:000000000000
101 user: test
102 user: test
102 date: Thu Jan 01 00:00:00 1970 +0000
103 date: Thu Jan 01 00:00:00 1970 +0000
103 summary: c
104 summary: c
104
105
105 changeset: 0:cb9a9f314b8b
106 changeset: 0:cb9a9f314b8b
106 user: test
107 user: test
107 date: Thu Jan 01 00:00:00 1970 +0000
108 date: Thu Jan 01 00:00:00 1970 +0000
108 summary: a
109 summary: a
109
110
110 $ hg qpush
111 $ hg qpush
111 applying qp
112 applying qp
112 now at: qp
113 now at: qp
113
114
114 Testing applied patches, push and --force
115 Testing applied patches, push and --force
115
116
116 $ cd ..
117 $ cd ..
117 $ hg init forcepush
118 $ hg init forcepush
118 $ cd forcepush
119 $ cd forcepush
119 $ echo a > a
120 $ echo a > a
120 $ hg ci -Am adda
121 $ hg ci -Am adda
121 adding a
122 adding a
122 $ echo a >> a
123 $ echo a >> a
123 $ hg ci -m changea
124 $ hg ci -m changea
124 $ hg up 0
125 $ hg up 0
125 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 $ hg branch branch
127 $ hg branch branch
127 marked working directory as branch branch
128 marked working directory as branch branch
129 (branches are permanent and global, did you want a bookmark?)
128 $ echo b > b
130 $ echo b > b
129 $ hg ci -Am addb
131 $ hg ci -Am addb
130 adding b
132 adding b
131 $ hg up 0
133 $ hg up 0
132 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
134 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
133 $ hg --cwd .. clone -r 0 forcepush forcepush2
135 $ hg --cwd .. clone -r 0 forcepush forcepush2
134 adding changesets
136 adding changesets
135 adding manifests
137 adding manifests
136 adding file changes
138 adding file changes
137 added 1 changesets with 1 changes to 1 files
139 added 1 changesets with 1 changes to 1 files
138 updating to branch default
140 updating to branch default
139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 $ echo a >> a
142 $ echo a >> a
141 $ hg qnew patch
143 $ hg qnew patch
142
144
143 Pushing applied patch with --rev without --force
145 Pushing applied patch with --rev without --force
144
146
145 $ hg push -r default ../forcepush2
147 $ hg push -r default ../forcepush2
146 pushing to ../forcepush2
148 pushing to ../forcepush2
147 abort: source has mq patches applied
149 abort: source has mq patches applied
148 [255]
150 [255]
149
151
150 Pushing applied patch with branchhash, without --force
152 Pushing applied patch with branchhash, without --force
151
153
152 $ hg push ../forcepush2#default
154 $ hg push ../forcepush2#default
153 pushing to ../forcepush2
155 pushing to ../forcepush2
154 abort: source has mq patches applied
156 abort: source has mq patches applied
155 [255]
157 [255]
156
158
157 Pushing revs excluding applied patch
159 Pushing revs excluding applied patch
158
160
159 $ hg push --new-branch -r branch -r 2 ../forcepush2
161 $ hg push --new-branch -r branch -r 2 ../forcepush2
160 pushing to ../forcepush2
162 pushing to ../forcepush2
161 searching for changes
163 searching for changes
162 adding changesets
164 adding changesets
163 adding manifests
165 adding manifests
164 adding file changes
166 adding file changes
165 added 1 changesets with 1 changes to 1 files
167 added 1 changesets with 1 changes to 1 files
166
168
167 Pushing applied patch with --force
169 Pushing applied patch with --force
168
170
169 $ hg push --force -r default ../forcepush2
171 $ hg push --force -r default ../forcepush2
170 pushing to ../forcepush2
172 pushing to ../forcepush2
171 searching for changes
173 searching for changes
172 adding changesets
174 adding changesets
173 adding manifests
175 adding manifests
174 adding file changes
176 adding file changes
175 added 1 changesets with 1 changes to 1 files (+1 heads)
177 added 1 changesets with 1 changes to 1 files (+1 heads)
@@ -1,322 +1,328 b''
1 $ branchcache=.hg/cache/branchheads
1 $ branchcache=.hg/cache/branchheads
2
2
3 $ hg init t
3 $ hg init t
4 $ cd t
4 $ cd t
5
5
6 $ hg branches
6 $ hg branches
7 $ echo foo > a
7 $ echo foo > a
8 $ hg add a
8 $ hg add a
9 $ hg ci -m "initial"
9 $ hg ci -m "initial"
10 $ hg branch foo
10 $ hg branch foo
11 marked working directory as branch foo
11 marked working directory as branch foo
12 (branches are permanent and global, did you want a bookmark?)
12 $ hg branch
13 $ hg branch
13 foo
14 foo
14 $ hg ci -m "add branch name"
15 $ hg ci -m "add branch name"
15 $ hg branch bar
16 $ hg branch bar
16 marked working directory as branch bar
17 marked working directory as branch bar
18 (branches are permanent and global, did you want a bookmark?)
17 $ hg ci -m "change branch name"
19 $ hg ci -m "change branch name"
18
20
19 Branch shadowing:
21 Branch shadowing:
20
22
21 $ hg branch default
23 $ hg branch default
22 abort: a branch of the same name already exists
24 abort: a branch of the same name already exists
23 (use 'hg update' to switch to it)
25 (use 'hg update' to switch to it)
24 [255]
26 [255]
25
27
26 $ hg branch -f default
28 $ hg branch -f default
27 marked working directory as branch default
29 marked working directory as branch default
30 (branches are permanent and global, did you want a bookmark?)
28
31
29 $ hg ci -m "clear branch name"
32 $ hg ci -m "clear branch name"
30 created new head
33 created new head
31
34
32 There should be only one default branch head
35 There should be only one default branch head
33
36
34 $ hg heads .
37 $ hg heads .
35 changeset: 3:1c28f494dae6
38 changeset: 3:1c28f494dae6
36 tag: tip
39 tag: tip
37 user: test
40 user: test
38 date: Thu Jan 01 00:00:00 1970 +0000
41 date: Thu Jan 01 00:00:00 1970 +0000
39 summary: clear branch name
42 summary: clear branch name
40
43
41
44
42 $ hg co foo
45 $ hg co foo
43 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
46 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
44 $ hg branch
47 $ hg branch
45 foo
48 foo
46 $ echo bleah > a
49 $ echo bleah > a
47 $ hg ci -m "modify a branch"
50 $ hg ci -m "modify a branch"
48
51
49 $ hg merge default
52 $ hg merge default
50 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
53 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 (branch merge, don't forget to commit)
54 (branch merge, don't forget to commit)
52
55
53 $ hg branch
56 $ hg branch
54 foo
57 foo
55 $ hg ci -m "merge"
58 $ hg ci -m "merge"
56
59
57 $ hg log
60 $ hg log
58 changeset: 5:530046499edf
61 changeset: 5:530046499edf
59 branch: foo
62 branch: foo
60 tag: tip
63 tag: tip
61 parent: 4:adf1a74a7f7b
64 parent: 4:adf1a74a7f7b
62 parent: 3:1c28f494dae6
65 parent: 3:1c28f494dae6
63 user: test
66 user: test
64 date: Thu Jan 01 00:00:00 1970 +0000
67 date: Thu Jan 01 00:00:00 1970 +0000
65 summary: merge
68 summary: merge
66
69
67 changeset: 4:adf1a74a7f7b
70 changeset: 4:adf1a74a7f7b
68 branch: foo
71 branch: foo
69 parent: 1:6c0e42da283a
72 parent: 1:6c0e42da283a
70 user: test
73 user: test
71 date: Thu Jan 01 00:00:00 1970 +0000
74 date: Thu Jan 01 00:00:00 1970 +0000
72 summary: modify a branch
75 summary: modify a branch
73
76
74 changeset: 3:1c28f494dae6
77 changeset: 3:1c28f494dae6
75 user: test
78 user: test
76 date: Thu Jan 01 00:00:00 1970 +0000
79 date: Thu Jan 01 00:00:00 1970 +0000
77 summary: clear branch name
80 summary: clear branch name
78
81
79 changeset: 2:c21617b13b22
82 changeset: 2:c21617b13b22
80 branch: bar
83 branch: bar
81 user: test
84 user: test
82 date: Thu Jan 01 00:00:00 1970 +0000
85 date: Thu Jan 01 00:00:00 1970 +0000
83 summary: change branch name
86 summary: change branch name
84
87
85 changeset: 1:6c0e42da283a
88 changeset: 1:6c0e42da283a
86 branch: foo
89 branch: foo
87 user: test
90 user: test
88 date: Thu Jan 01 00:00:00 1970 +0000
91 date: Thu Jan 01 00:00:00 1970 +0000
89 summary: add branch name
92 summary: add branch name
90
93
91 changeset: 0:db01e8ea3388
94 changeset: 0:db01e8ea3388
92 user: test
95 user: test
93 date: Thu Jan 01 00:00:00 1970 +0000
96 date: Thu Jan 01 00:00:00 1970 +0000
94 summary: initial
97 summary: initial
95
98
96 $ hg branches
99 $ hg branches
97 foo 5:530046499edf
100 foo 5:530046499edf
98 default 3:1c28f494dae6 (inactive)
101 default 3:1c28f494dae6 (inactive)
99 bar 2:c21617b13b22 (inactive)
102 bar 2:c21617b13b22 (inactive)
100
103
101 $ hg branches -q
104 $ hg branches -q
102 foo
105 foo
103 default
106 default
104 bar
107 bar
105
108
106 Test for invalid branch cache:
109 Test for invalid branch cache:
107
110
108 $ hg rollback
111 $ hg rollback
109 repository tip rolled back to revision 4 (undo commit)
112 repository tip rolled back to revision 4 (undo commit)
110 working directory now based on revisions 4 and 3
113 working directory now based on revisions 4 and 3
111
114
112 $ cp $branchcache .hg/bc-invalid
115 $ cp $branchcache .hg/bc-invalid
113
116
114 $ hg log -r foo
117 $ hg log -r foo
115 changeset: 4:adf1a74a7f7b
118 changeset: 4:adf1a74a7f7b
116 branch: foo
119 branch: foo
117 tag: tip
120 tag: tip
118 parent: 1:6c0e42da283a
121 parent: 1:6c0e42da283a
119 user: test
122 user: test
120 date: Thu Jan 01 00:00:00 1970 +0000
123 date: Thu Jan 01 00:00:00 1970 +0000
121 summary: modify a branch
124 summary: modify a branch
122
125
123 $ cp .hg/bc-invalid $branchcache
126 $ cp .hg/bc-invalid $branchcache
124
127
125 $ hg --debug log -r foo
128 $ hg --debug log -r foo
126 invalidating branch cache (tip differs)
129 invalidating branch cache (tip differs)
127 changeset: 4:adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6
130 changeset: 4:adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6
128 branch: foo
131 branch: foo
129 tag: tip
132 tag: tip
130 parent: 1:6c0e42da283a56b5edc5b4fadb491365ec7f5fa8
133 parent: 1:6c0e42da283a56b5edc5b4fadb491365ec7f5fa8
131 parent: -1:0000000000000000000000000000000000000000
134 parent: -1:0000000000000000000000000000000000000000
132 manifest: 1:8c342a37dfba0b3d3ce073562a00d8a813c54ffe
135 manifest: 1:8c342a37dfba0b3d3ce073562a00d8a813c54ffe
133 user: test
136 user: test
134 date: Thu Jan 01 00:00:00 1970 +0000
137 date: Thu Jan 01 00:00:00 1970 +0000
135 files: a
138 files: a
136 extra: branch=foo
139 extra: branch=foo
137 description:
140 description:
138 modify a branch
141 modify a branch
139
142
140
143
141 $ rm $branchcache
144 $ rm $branchcache
142 $ echo corrupted > $branchcache
145 $ echo corrupted > $branchcache
143
146
144 $ hg log -qr foo
147 $ hg log -qr foo
145 4:adf1a74a7f7b
148 4:adf1a74a7f7b
146
149
147 $ cat $branchcache
150 $ cat $branchcache
148 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
151 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
149 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
152 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
150 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
153 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
151 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
154 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
152
155
153 Push should update the branch cache:
156 Push should update the branch cache:
154
157
155 $ hg init ../target
158 $ hg init ../target
156
159
157 Pushing just rev 0:
160 Pushing just rev 0:
158
161
159 $ hg push -qr 0 ../target
162 $ hg push -qr 0 ../target
160
163
161 $ cat ../target/$branchcache
164 $ cat ../target/$branchcache
162 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
165 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
163 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 default
166 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 default
164
167
165 Pushing everything:
168 Pushing everything:
166
169
167 $ hg push -qf ../target
170 $ hg push -qf ../target
168
171
169 $ cat ../target/$branchcache
172 $ cat ../target/$branchcache
170 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
173 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
171 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
174 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
172 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
175 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
173 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
176 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
174
177
175 Update with no arguments: tipmost revision of the current branch:
178 Update with no arguments: tipmost revision of the current branch:
176
179
177 $ hg up -q -C 0
180 $ hg up -q -C 0
178 $ hg up -q
181 $ hg up -q
179 $ hg id
182 $ hg id
180 1c28f494dae6
183 1c28f494dae6
181
184
182 $ hg up -q 1
185 $ hg up -q 1
183 $ hg up -q
186 $ hg up -q
184 $ hg id
187 $ hg id
185 adf1a74a7f7b (foo) tip
188 adf1a74a7f7b (foo) tip
186
189
187 $ hg branch foobar
190 $ hg branch foobar
188 marked working directory as branch foobar
191 marked working directory as branch foobar
192 (branches are permanent and global, did you want a bookmark?)
189
193
190 $ hg up
194 $ hg up
191 abort: branch foobar not found
195 abort: branch foobar not found
192 [255]
196 [255]
193
197
194 Fastforward merge:
198 Fastforward merge:
195
199
196 $ hg branch ff
200 $ hg branch ff
197 marked working directory as branch ff
201 marked working directory as branch ff
202 (branches are permanent and global, did you want a bookmark?)
198
203
199 $ echo ff > ff
204 $ echo ff > ff
200 $ hg ci -Am'fast forward'
205 $ hg ci -Am'fast forward'
201 adding ff
206 adding ff
202
207
203 $ hg up foo
208 $ hg up foo
204 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
209 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
205
210
206 $ hg merge ff
211 $ hg merge ff
207 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
208 (branch merge, don't forget to commit)
213 (branch merge, don't forget to commit)
209
214
210 $ hg branch
215 $ hg branch
211 foo
216 foo
212 $ hg commit -m'Merge ff into foo'
217 $ hg commit -m'Merge ff into foo'
213 $ hg parents
218 $ hg parents
214 changeset: 6:185ffbfefa30
219 changeset: 6:185ffbfefa30
215 branch: foo
220 branch: foo
216 tag: tip
221 tag: tip
217 parent: 4:adf1a74a7f7b
222 parent: 4:adf1a74a7f7b
218 parent: 5:1a3c27dc5e11
223 parent: 5:1a3c27dc5e11
219 user: test
224 user: test
220 date: Thu Jan 01 00:00:00 1970 +0000
225 date: Thu Jan 01 00:00:00 1970 +0000
221 summary: Merge ff into foo
226 summary: Merge ff into foo
222
227
223 $ hg manifest
228 $ hg manifest
224 a
229 a
225 ff
230 ff
226
231
227
232
228 Test merging, add 3 default heads and one test head:
233 Test merging, add 3 default heads and one test head:
229
234
230 $ cd ..
235 $ cd ..
231 $ hg init merges
236 $ hg init merges
232 $ cd merges
237 $ cd merges
233 $ echo a > a
238 $ echo a > a
234 $ hg ci -Ama
239 $ hg ci -Ama
235 adding a
240 adding a
236
241
237 $ echo b > b
242 $ echo b > b
238 $ hg ci -Amb
243 $ hg ci -Amb
239 adding b
244 adding b
240
245
241 $ hg up 0
246 $ hg up 0
242 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
247 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
243 $ echo c > c
248 $ echo c > c
244 $ hg ci -Amc
249 $ hg ci -Amc
245 adding c
250 adding c
246 created new head
251 created new head
247
252
248 $ hg up 0
253 $ hg up 0
249 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
254 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
250 $ echo d > d
255 $ echo d > d
251 $ hg ci -Amd
256 $ hg ci -Amd
252 adding d
257 adding d
253 created new head
258 created new head
254
259
255 $ hg up 0
260 $ hg up 0
256 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
261 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
257 $ hg branch test
262 $ hg branch test
258 marked working directory as branch test
263 marked working directory as branch test
264 (branches are permanent and global, did you want a bookmark?)
259 $ echo e >> e
265 $ echo e >> e
260 $ hg ci -Ame
266 $ hg ci -Ame
261 adding e
267 adding e
262
268
263 $ hg log
269 $ hg log
264 changeset: 4:3a1e01ed1df4
270 changeset: 4:3a1e01ed1df4
265 branch: test
271 branch: test
266 tag: tip
272 tag: tip
267 parent: 0:cb9a9f314b8b
273 parent: 0:cb9a9f314b8b
268 user: test
274 user: test
269 date: Thu Jan 01 00:00:00 1970 +0000
275 date: Thu Jan 01 00:00:00 1970 +0000
270 summary: e
276 summary: e
271
277
272 changeset: 3:980f7dc84c29
278 changeset: 3:980f7dc84c29
273 parent: 0:cb9a9f314b8b
279 parent: 0:cb9a9f314b8b
274 user: test
280 user: test
275 date: Thu Jan 01 00:00:00 1970 +0000
281 date: Thu Jan 01 00:00:00 1970 +0000
276 summary: d
282 summary: d
277
283
278 changeset: 2:d36c0562f908
284 changeset: 2:d36c0562f908
279 parent: 0:cb9a9f314b8b
285 parent: 0:cb9a9f314b8b
280 user: test
286 user: test
281 date: Thu Jan 01 00:00:00 1970 +0000
287 date: Thu Jan 01 00:00:00 1970 +0000
282 summary: c
288 summary: c
283
289
284 changeset: 1:d2ae7f538514
290 changeset: 1:d2ae7f538514
285 user: test
291 user: test
286 date: Thu Jan 01 00:00:00 1970 +0000
292 date: Thu Jan 01 00:00:00 1970 +0000
287 summary: b
293 summary: b
288
294
289 changeset: 0:cb9a9f314b8b
295 changeset: 0:cb9a9f314b8b
290 user: test
296 user: test
291 date: Thu Jan 01 00:00:00 1970 +0000
297 date: Thu Jan 01 00:00:00 1970 +0000
292 summary: a
298 summary: a
293
299
294 Implicit merge with test branch as parent:
300 Implicit merge with test branch as parent:
295
301
296 $ hg merge
302 $ hg merge
297 abort: branch 'test' has one head - please merge with an explicit rev
303 abort: branch 'test' has one head - please merge with an explicit rev
298 (run 'hg heads' to see all heads)
304 (run 'hg heads' to see all heads)
299 [255]
305 [255]
300 $ hg up -C default
306 $ hg up -C default
301 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
307 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
302
308
303 Implicit merge with default branch as parent:
309 Implicit merge with default branch as parent:
304
310
305 $ hg merge
311 $ hg merge
306 abort: branch 'default' has 3 heads - please merge with an explicit rev
312 abort: branch 'default' has 3 heads - please merge with an explicit rev
307 (run 'hg heads .' to see heads)
313 (run 'hg heads .' to see heads)
308 [255]
314 [255]
309
315
310 3 branch heads, explicit merge required:
316 3 branch heads, explicit merge required:
311
317
312 $ hg merge 2
318 $ hg merge 2
313 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
319 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
314 (branch merge, don't forget to commit)
320 (branch merge, don't forget to commit)
315 $ hg ci -m merge
321 $ hg ci -m merge
316
322
317 2 branch heads, implicit merge works:
323 2 branch heads, implicit merge works:
318
324
319 $ hg merge
325 $ hg merge
320 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
326 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
321 (branch merge, don't forget to commit)
327 (branch merge, don't forget to commit)
322
328
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now