##// END OF EJS Templates
log: fix --follow null parent not to include revision 0...
Yuya Nishihara -
r24064:c260887c default
parent child Browse files
Show More
@@ -1,2960 +1,2962 b''
1 # cmdutil.py - help for command processing in mercurial
1 # cmdutil.py - help for command processing in 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, nullid, nullrev, short
8 from node import hex, nullid, nullrev, short
9 from i18n import _
9 from i18n import _
10 import os, sys, errno, re, tempfile
10 import os, sys, errno, re, tempfile
11 import util, scmutil, templater, patch, error, templatekw, revlog, copies
11 import util, scmutil, templater, patch, error, templatekw, revlog, copies
12 import match as matchmod
12 import match as matchmod
13 import context, repair, graphmod, revset, phases, obsolete, pathutil
13 import context, repair, graphmod, revset, phases, obsolete, pathutil
14 import changelog
14 import changelog
15 import bookmarks
15 import bookmarks
16 import encoding
16 import encoding
17 import lock as lockmod
17 import lock as lockmod
18
18
19 def parsealiases(cmd):
19 def parsealiases(cmd):
20 return cmd.lstrip("^").split("|")
20 return cmd.lstrip("^").split("|")
21
21
22 def findpossible(cmd, table, strict=False):
22 def findpossible(cmd, table, strict=False):
23 """
23 """
24 Return cmd -> (aliases, command table entry)
24 Return cmd -> (aliases, command table entry)
25 for each matching command.
25 for each matching command.
26 Return debug commands (or their aliases) only if no normal command matches.
26 Return debug commands (or their aliases) only if no normal command matches.
27 """
27 """
28 choice = {}
28 choice = {}
29 debugchoice = {}
29 debugchoice = {}
30
30
31 if cmd in table:
31 if cmd in table:
32 # short-circuit exact matches, "log" alias beats "^log|history"
32 # short-circuit exact matches, "log" alias beats "^log|history"
33 keys = [cmd]
33 keys = [cmd]
34 else:
34 else:
35 keys = table.keys()
35 keys = table.keys()
36
36
37 for e in keys:
37 for e in keys:
38 aliases = parsealiases(e)
38 aliases = parsealiases(e)
39 found = None
39 found = None
40 if cmd in aliases:
40 if cmd in aliases:
41 found = cmd
41 found = cmd
42 elif not strict:
42 elif not strict:
43 for a in aliases:
43 for a in aliases:
44 if a.startswith(cmd):
44 if a.startswith(cmd):
45 found = a
45 found = a
46 break
46 break
47 if found is not None:
47 if found is not None:
48 if aliases[0].startswith("debug") or found.startswith("debug"):
48 if aliases[0].startswith("debug") or found.startswith("debug"):
49 debugchoice[found] = (aliases, table[e])
49 debugchoice[found] = (aliases, table[e])
50 else:
50 else:
51 choice[found] = (aliases, table[e])
51 choice[found] = (aliases, table[e])
52
52
53 if not choice and debugchoice:
53 if not choice and debugchoice:
54 choice = debugchoice
54 choice = debugchoice
55
55
56 return choice
56 return choice
57
57
58 def findcmd(cmd, table, strict=True):
58 def findcmd(cmd, table, strict=True):
59 """Return (aliases, command table entry) for command string."""
59 """Return (aliases, command table entry) for command string."""
60 choice = findpossible(cmd, table, strict)
60 choice = findpossible(cmd, table, strict)
61
61
62 if cmd in choice:
62 if cmd in choice:
63 return choice[cmd]
63 return choice[cmd]
64
64
65 if len(choice) > 1:
65 if len(choice) > 1:
66 clist = choice.keys()
66 clist = choice.keys()
67 clist.sort()
67 clist.sort()
68 raise error.AmbiguousCommand(cmd, clist)
68 raise error.AmbiguousCommand(cmd, clist)
69
69
70 if choice:
70 if choice:
71 return choice.values()[0]
71 return choice.values()[0]
72
72
73 raise error.UnknownCommand(cmd)
73 raise error.UnknownCommand(cmd)
74
74
75 def findrepo(p):
75 def findrepo(p):
76 while not os.path.isdir(os.path.join(p, ".hg")):
76 while not os.path.isdir(os.path.join(p, ".hg")):
77 oldp, p = p, os.path.dirname(p)
77 oldp, p = p, os.path.dirname(p)
78 if p == oldp:
78 if p == oldp:
79 return None
79 return None
80
80
81 return p
81 return p
82
82
83 def bailifchanged(repo):
83 def bailifchanged(repo):
84 if repo.dirstate.p2() != nullid:
84 if repo.dirstate.p2() != nullid:
85 raise util.Abort(_('outstanding uncommitted merge'))
85 raise util.Abort(_('outstanding uncommitted merge'))
86 modified, added, removed, deleted = repo.status()[:4]
86 modified, added, removed, deleted = repo.status()[:4]
87 if modified or added or removed or deleted:
87 if modified or added or removed or deleted:
88 raise util.Abort(_('uncommitted changes'))
88 raise util.Abort(_('uncommitted changes'))
89 ctx = repo[None]
89 ctx = repo[None]
90 for s in sorted(ctx.substate):
90 for s in sorted(ctx.substate):
91 if ctx.sub(s).dirty():
91 if ctx.sub(s).dirty():
92 raise util.Abort(_("uncommitted changes in subrepo %s") % s)
92 raise util.Abort(_("uncommitted changes in subrepo %s") % s)
93
93
94 def logmessage(ui, opts):
94 def logmessage(ui, opts):
95 """ get the log message according to -m and -l option """
95 """ get the log message according to -m and -l option """
96 message = opts.get('message')
96 message = opts.get('message')
97 logfile = opts.get('logfile')
97 logfile = opts.get('logfile')
98
98
99 if message and logfile:
99 if message and logfile:
100 raise util.Abort(_('options --message and --logfile are mutually '
100 raise util.Abort(_('options --message and --logfile are mutually '
101 'exclusive'))
101 'exclusive'))
102 if not message and logfile:
102 if not message and logfile:
103 try:
103 try:
104 if logfile == '-':
104 if logfile == '-':
105 message = ui.fin.read()
105 message = ui.fin.read()
106 else:
106 else:
107 message = '\n'.join(util.readfile(logfile).splitlines())
107 message = '\n'.join(util.readfile(logfile).splitlines())
108 except IOError, inst:
108 except IOError, inst:
109 raise util.Abort(_("can't read commit message '%s': %s") %
109 raise util.Abort(_("can't read commit message '%s': %s") %
110 (logfile, inst.strerror))
110 (logfile, inst.strerror))
111 return message
111 return message
112
112
113 def mergeeditform(ctxorbool, baseform):
113 def mergeeditform(ctxorbool, baseform):
114 """build appropriate editform from ctxorbool and baseform
114 """build appropriate editform from ctxorbool and baseform
115
115
116 'ctxorbool' is one of a ctx to be committed, or a bool whether
116 'ctxorbool' is one of a ctx to be committed, or a bool whether
117 merging is committed.
117 merging is committed.
118
118
119 This returns editform 'baseform' with '.merge' if merging is
119 This returns editform 'baseform' with '.merge' if merging is
120 committed, or one with '.normal' suffix otherwise.
120 committed, or one with '.normal' suffix otherwise.
121 """
121 """
122 if isinstance(ctxorbool, bool):
122 if isinstance(ctxorbool, bool):
123 if ctxorbool:
123 if ctxorbool:
124 return baseform + ".merge"
124 return baseform + ".merge"
125 elif 1 < len(ctxorbool.parents()):
125 elif 1 < len(ctxorbool.parents()):
126 return baseform + ".merge"
126 return baseform + ".merge"
127
127
128 return baseform + ".normal"
128 return baseform + ".normal"
129
129
130 def getcommiteditor(edit=False, finishdesc=None, extramsg=None,
130 def getcommiteditor(edit=False, finishdesc=None, extramsg=None,
131 editform='', **opts):
131 editform='', **opts):
132 """get appropriate commit message editor according to '--edit' option
132 """get appropriate commit message editor according to '--edit' option
133
133
134 'finishdesc' is a function to be called with edited commit message
134 'finishdesc' is a function to be called with edited commit message
135 (= 'description' of the new changeset) just after editing, but
135 (= 'description' of the new changeset) just after editing, but
136 before checking empty-ness. It should return actual text to be
136 before checking empty-ness. It should return actual text to be
137 stored into history. This allows to change description before
137 stored into history. This allows to change description before
138 storing.
138 storing.
139
139
140 'extramsg' is a extra message to be shown in the editor instead of
140 'extramsg' is a extra message to be shown in the editor instead of
141 'Leave message empty to abort commit' line. 'HG: ' prefix and EOL
141 'Leave message empty to abort commit' line. 'HG: ' prefix and EOL
142 is automatically added.
142 is automatically added.
143
143
144 'editform' is a dot-separated list of names, to distinguish
144 'editform' is a dot-separated list of names, to distinguish
145 the purpose of commit text editing.
145 the purpose of commit text editing.
146
146
147 'getcommiteditor' returns 'commitforceeditor' regardless of
147 'getcommiteditor' returns 'commitforceeditor' regardless of
148 'edit', if one of 'finishdesc' or 'extramsg' is specified, because
148 'edit', if one of 'finishdesc' or 'extramsg' is specified, because
149 they are specific for usage in MQ.
149 they are specific for usage in MQ.
150 """
150 """
151 if edit or finishdesc or extramsg:
151 if edit or finishdesc or extramsg:
152 return lambda r, c, s: commitforceeditor(r, c, s,
152 return lambda r, c, s: commitforceeditor(r, c, s,
153 finishdesc=finishdesc,
153 finishdesc=finishdesc,
154 extramsg=extramsg,
154 extramsg=extramsg,
155 editform=editform)
155 editform=editform)
156 elif editform:
156 elif editform:
157 return lambda r, c, s: commiteditor(r, c, s, editform=editform)
157 return lambda r, c, s: commiteditor(r, c, s, editform=editform)
158 else:
158 else:
159 return commiteditor
159 return commiteditor
160
160
161 def loglimit(opts):
161 def loglimit(opts):
162 """get the log limit according to option -l/--limit"""
162 """get the log limit according to option -l/--limit"""
163 limit = opts.get('limit')
163 limit = opts.get('limit')
164 if limit:
164 if limit:
165 try:
165 try:
166 limit = int(limit)
166 limit = int(limit)
167 except ValueError:
167 except ValueError:
168 raise util.Abort(_('limit must be a positive integer'))
168 raise util.Abort(_('limit must be a positive integer'))
169 if limit <= 0:
169 if limit <= 0:
170 raise util.Abort(_('limit must be positive'))
170 raise util.Abort(_('limit must be positive'))
171 else:
171 else:
172 limit = None
172 limit = None
173 return limit
173 return limit
174
174
175 def makefilename(repo, pat, node, desc=None,
175 def makefilename(repo, pat, node, desc=None,
176 total=None, seqno=None, revwidth=None, pathname=None):
176 total=None, seqno=None, revwidth=None, pathname=None):
177 node_expander = {
177 node_expander = {
178 'H': lambda: hex(node),
178 'H': lambda: hex(node),
179 'R': lambda: str(repo.changelog.rev(node)),
179 'R': lambda: str(repo.changelog.rev(node)),
180 'h': lambda: short(node),
180 'h': lambda: short(node),
181 'm': lambda: re.sub('[^\w]', '_', str(desc))
181 'm': lambda: re.sub('[^\w]', '_', str(desc))
182 }
182 }
183 expander = {
183 expander = {
184 '%': lambda: '%',
184 '%': lambda: '%',
185 'b': lambda: os.path.basename(repo.root),
185 'b': lambda: os.path.basename(repo.root),
186 }
186 }
187
187
188 try:
188 try:
189 if node:
189 if node:
190 expander.update(node_expander)
190 expander.update(node_expander)
191 if node:
191 if node:
192 expander['r'] = (lambda:
192 expander['r'] = (lambda:
193 str(repo.changelog.rev(node)).zfill(revwidth or 0))
193 str(repo.changelog.rev(node)).zfill(revwidth or 0))
194 if total is not None:
194 if total is not None:
195 expander['N'] = lambda: str(total)
195 expander['N'] = lambda: str(total)
196 if seqno is not None:
196 if seqno is not None:
197 expander['n'] = lambda: str(seqno)
197 expander['n'] = lambda: str(seqno)
198 if total is not None and seqno is not None:
198 if total is not None and seqno is not None:
199 expander['n'] = lambda: str(seqno).zfill(len(str(total)))
199 expander['n'] = lambda: str(seqno).zfill(len(str(total)))
200 if pathname is not None:
200 if pathname is not None:
201 expander['s'] = lambda: os.path.basename(pathname)
201 expander['s'] = lambda: os.path.basename(pathname)
202 expander['d'] = lambda: os.path.dirname(pathname) or '.'
202 expander['d'] = lambda: os.path.dirname(pathname) or '.'
203 expander['p'] = lambda: pathname
203 expander['p'] = lambda: pathname
204
204
205 newname = []
205 newname = []
206 patlen = len(pat)
206 patlen = len(pat)
207 i = 0
207 i = 0
208 while i < patlen:
208 while i < patlen:
209 c = pat[i]
209 c = pat[i]
210 if c == '%':
210 if c == '%':
211 i += 1
211 i += 1
212 c = pat[i]
212 c = pat[i]
213 c = expander[c]()
213 c = expander[c]()
214 newname.append(c)
214 newname.append(c)
215 i += 1
215 i += 1
216 return ''.join(newname)
216 return ''.join(newname)
217 except KeyError, inst:
217 except KeyError, inst:
218 raise util.Abort(_("invalid format spec '%%%s' in output filename") %
218 raise util.Abort(_("invalid format spec '%%%s' in output filename") %
219 inst.args[0])
219 inst.args[0])
220
220
221 def makefileobj(repo, pat, node=None, desc=None, total=None,
221 def makefileobj(repo, pat, node=None, desc=None, total=None,
222 seqno=None, revwidth=None, mode='wb', modemap=None,
222 seqno=None, revwidth=None, mode='wb', modemap=None,
223 pathname=None):
223 pathname=None):
224
224
225 writable = mode not in ('r', 'rb')
225 writable = mode not in ('r', 'rb')
226
226
227 if not pat or pat == '-':
227 if not pat or pat == '-':
228 fp = writable and repo.ui.fout or repo.ui.fin
228 fp = writable and repo.ui.fout or repo.ui.fin
229 if util.safehasattr(fp, 'fileno'):
229 if util.safehasattr(fp, 'fileno'):
230 return os.fdopen(os.dup(fp.fileno()), mode)
230 return os.fdopen(os.dup(fp.fileno()), mode)
231 else:
231 else:
232 # if this fp can't be duped properly, return
232 # if this fp can't be duped properly, return
233 # a dummy object that can be closed
233 # a dummy object that can be closed
234 class wrappedfileobj(object):
234 class wrappedfileobj(object):
235 noop = lambda x: None
235 noop = lambda x: None
236 def __init__(self, f):
236 def __init__(self, f):
237 self.f = f
237 self.f = f
238 def __getattr__(self, attr):
238 def __getattr__(self, attr):
239 if attr == 'close':
239 if attr == 'close':
240 return self.noop
240 return self.noop
241 else:
241 else:
242 return getattr(self.f, attr)
242 return getattr(self.f, attr)
243
243
244 return wrappedfileobj(fp)
244 return wrappedfileobj(fp)
245 if util.safehasattr(pat, 'write') and writable:
245 if util.safehasattr(pat, 'write') and writable:
246 return pat
246 return pat
247 if util.safehasattr(pat, 'read') and 'r' in mode:
247 if util.safehasattr(pat, 'read') and 'r' in mode:
248 return pat
248 return pat
249 fn = makefilename(repo, pat, node, desc, total, seqno, revwidth, pathname)
249 fn = makefilename(repo, pat, node, desc, total, seqno, revwidth, pathname)
250 if modemap is not None:
250 if modemap is not None:
251 mode = modemap.get(fn, mode)
251 mode = modemap.get(fn, mode)
252 if mode == 'wb':
252 if mode == 'wb':
253 modemap[fn] = 'ab'
253 modemap[fn] = 'ab'
254 return open(fn, mode)
254 return open(fn, mode)
255
255
256 def openrevlog(repo, cmd, file_, opts):
256 def openrevlog(repo, cmd, file_, opts):
257 """opens the changelog, manifest, a filelog or a given revlog"""
257 """opens the changelog, manifest, a filelog or a given revlog"""
258 cl = opts['changelog']
258 cl = opts['changelog']
259 mf = opts['manifest']
259 mf = opts['manifest']
260 msg = None
260 msg = None
261 if cl and mf:
261 if cl and mf:
262 msg = _('cannot specify --changelog and --manifest at the same time')
262 msg = _('cannot specify --changelog and --manifest at the same time')
263 elif cl or mf:
263 elif cl or mf:
264 if file_:
264 if file_:
265 msg = _('cannot specify filename with --changelog or --manifest')
265 msg = _('cannot specify filename with --changelog or --manifest')
266 elif not repo:
266 elif not repo:
267 msg = _('cannot specify --changelog or --manifest '
267 msg = _('cannot specify --changelog or --manifest '
268 'without a repository')
268 'without a repository')
269 if msg:
269 if msg:
270 raise util.Abort(msg)
270 raise util.Abort(msg)
271
271
272 r = None
272 r = None
273 if repo:
273 if repo:
274 if cl:
274 if cl:
275 r = repo.unfiltered().changelog
275 r = repo.unfiltered().changelog
276 elif mf:
276 elif mf:
277 r = repo.manifest
277 r = repo.manifest
278 elif file_:
278 elif file_:
279 filelog = repo.file(file_)
279 filelog = repo.file(file_)
280 if len(filelog):
280 if len(filelog):
281 r = filelog
281 r = filelog
282 if not r:
282 if not r:
283 if not file_:
283 if not file_:
284 raise error.CommandError(cmd, _('invalid arguments'))
284 raise error.CommandError(cmd, _('invalid arguments'))
285 if not os.path.isfile(file_):
285 if not os.path.isfile(file_):
286 raise util.Abort(_("revlog '%s' not found") % file_)
286 raise util.Abort(_("revlog '%s' not found") % file_)
287 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
287 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
288 file_[:-2] + ".i")
288 file_[:-2] + ".i")
289 return r
289 return r
290
290
291 def copy(ui, repo, pats, opts, rename=False):
291 def copy(ui, repo, pats, opts, rename=False):
292 # called with the repo lock held
292 # called with the repo lock held
293 #
293 #
294 # hgsep => pathname that uses "/" to separate directories
294 # hgsep => pathname that uses "/" to separate directories
295 # ossep => pathname that uses os.sep to separate directories
295 # ossep => pathname that uses os.sep to separate directories
296 cwd = repo.getcwd()
296 cwd = repo.getcwd()
297 targets = {}
297 targets = {}
298 after = opts.get("after")
298 after = opts.get("after")
299 dryrun = opts.get("dry_run")
299 dryrun = opts.get("dry_run")
300 wctx = repo[None]
300 wctx = repo[None]
301
301
302 def walkpat(pat):
302 def walkpat(pat):
303 srcs = []
303 srcs = []
304 badstates = after and '?' or '?r'
304 badstates = after and '?' or '?r'
305 m = scmutil.match(repo[None], [pat], opts, globbed=True)
305 m = scmutil.match(repo[None], [pat], opts, globbed=True)
306 for abs in repo.walk(m):
306 for abs in repo.walk(m):
307 state = repo.dirstate[abs]
307 state = repo.dirstate[abs]
308 rel = m.rel(abs)
308 rel = m.rel(abs)
309 exact = m.exact(abs)
309 exact = m.exact(abs)
310 if state in badstates:
310 if state in badstates:
311 if exact and state == '?':
311 if exact and state == '?':
312 ui.warn(_('%s: not copying - file is not managed\n') % rel)
312 ui.warn(_('%s: not copying - file is not managed\n') % rel)
313 if exact and state == 'r':
313 if exact and state == 'r':
314 ui.warn(_('%s: not copying - file has been marked for'
314 ui.warn(_('%s: not copying - file has been marked for'
315 ' remove\n') % rel)
315 ' remove\n') % rel)
316 continue
316 continue
317 # abs: hgsep
317 # abs: hgsep
318 # rel: ossep
318 # rel: ossep
319 srcs.append((abs, rel, exact))
319 srcs.append((abs, rel, exact))
320 return srcs
320 return srcs
321
321
322 # abssrc: hgsep
322 # abssrc: hgsep
323 # relsrc: ossep
323 # relsrc: ossep
324 # otarget: ossep
324 # otarget: ossep
325 def copyfile(abssrc, relsrc, otarget, exact):
325 def copyfile(abssrc, relsrc, otarget, exact):
326 abstarget = pathutil.canonpath(repo.root, cwd, otarget)
326 abstarget = pathutil.canonpath(repo.root, cwd, otarget)
327 if '/' in abstarget:
327 if '/' in abstarget:
328 # We cannot normalize abstarget itself, this would prevent
328 # We cannot normalize abstarget itself, this would prevent
329 # case only renames, like a => A.
329 # case only renames, like a => A.
330 abspath, absname = abstarget.rsplit('/', 1)
330 abspath, absname = abstarget.rsplit('/', 1)
331 abstarget = repo.dirstate.normalize(abspath) + '/' + absname
331 abstarget = repo.dirstate.normalize(abspath) + '/' + absname
332 reltarget = repo.pathto(abstarget, cwd)
332 reltarget = repo.pathto(abstarget, cwd)
333 target = repo.wjoin(abstarget)
333 target = repo.wjoin(abstarget)
334 src = repo.wjoin(abssrc)
334 src = repo.wjoin(abssrc)
335 state = repo.dirstate[abstarget]
335 state = repo.dirstate[abstarget]
336
336
337 scmutil.checkportable(ui, abstarget)
337 scmutil.checkportable(ui, abstarget)
338
338
339 # check for collisions
339 # check for collisions
340 prevsrc = targets.get(abstarget)
340 prevsrc = targets.get(abstarget)
341 if prevsrc is not None:
341 if prevsrc is not None:
342 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
342 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
343 (reltarget, repo.pathto(abssrc, cwd),
343 (reltarget, repo.pathto(abssrc, cwd),
344 repo.pathto(prevsrc, cwd)))
344 repo.pathto(prevsrc, cwd)))
345 return
345 return
346
346
347 # check for overwrites
347 # check for overwrites
348 exists = os.path.lexists(target)
348 exists = os.path.lexists(target)
349 samefile = False
349 samefile = False
350 if exists and abssrc != abstarget:
350 if exists and abssrc != abstarget:
351 if (repo.dirstate.normalize(abssrc) ==
351 if (repo.dirstate.normalize(abssrc) ==
352 repo.dirstate.normalize(abstarget)):
352 repo.dirstate.normalize(abstarget)):
353 if not rename:
353 if not rename:
354 ui.warn(_("%s: can't copy - same file\n") % reltarget)
354 ui.warn(_("%s: can't copy - same file\n") % reltarget)
355 return
355 return
356 exists = False
356 exists = False
357 samefile = True
357 samefile = True
358
358
359 if not after and exists or after and state in 'mn':
359 if not after and exists or after and state in 'mn':
360 if not opts['force']:
360 if not opts['force']:
361 ui.warn(_('%s: not overwriting - file exists\n') %
361 ui.warn(_('%s: not overwriting - file exists\n') %
362 reltarget)
362 reltarget)
363 return
363 return
364
364
365 if after:
365 if after:
366 if not exists:
366 if not exists:
367 if rename:
367 if rename:
368 ui.warn(_('%s: not recording move - %s does not exist\n') %
368 ui.warn(_('%s: not recording move - %s does not exist\n') %
369 (relsrc, reltarget))
369 (relsrc, reltarget))
370 else:
370 else:
371 ui.warn(_('%s: not recording copy - %s does not exist\n') %
371 ui.warn(_('%s: not recording copy - %s does not exist\n') %
372 (relsrc, reltarget))
372 (relsrc, reltarget))
373 return
373 return
374 elif not dryrun:
374 elif not dryrun:
375 try:
375 try:
376 if exists:
376 if exists:
377 os.unlink(target)
377 os.unlink(target)
378 targetdir = os.path.dirname(target) or '.'
378 targetdir = os.path.dirname(target) or '.'
379 if not os.path.isdir(targetdir):
379 if not os.path.isdir(targetdir):
380 os.makedirs(targetdir)
380 os.makedirs(targetdir)
381 if samefile:
381 if samefile:
382 tmp = target + "~hgrename"
382 tmp = target + "~hgrename"
383 os.rename(src, tmp)
383 os.rename(src, tmp)
384 os.rename(tmp, target)
384 os.rename(tmp, target)
385 else:
385 else:
386 util.copyfile(src, target)
386 util.copyfile(src, target)
387 srcexists = True
387 srcexists = True
388 except IOError, inst:
388 except IOError, inst:
389 if inst.errno == errno.ENOENT:
389 if inst.errno == errno.ENOENT:
390 ui.warn(_('%s: deleted in working copy\n') % relsrc)
390 ui.warn(_('%s: deleted in working copy\n') % relsrc)
391 srcexists = False
391 srcexists = False
392 else:
392 else:
393 ui.warn(_('%s: cannot copy - %s\n') %
393 ui.warn(_('%s: cannot copy - %s\n') %
394 (relsrc, inst.strerror))
394 (relsrc, inst.strerror))
395 return True # report a failure
395 return True # report a failure
396
396
397 if ui.verbose or not exact:
397 if ui.verbose or not exact:
398 if rename:
398 if rename:
399 ui.status(_('moving %s to %s\n') % (relsrc, reltarget))
399 ui.status(_('moving %s to %s\n') % (relsrc, reltarget))
400 else:
400 else:
401 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
401 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
402
402
403 targets[abstarget] = abssrc
403 targets[abstarget] = abssrc
404
404
405 # fix up dirstate
405 # fix up dirstate
406 scmutil.dirstatecopy(ui, repo, wctx, abssrc, abstarget,
406 scmutil.dirstatecopy(ui, repo, wctx, abssrc, abstarget,
407 dryrun=dryrun, cwd=cwd)
407 dryrun=dryrun, cwd=cwd)
408 if rename and not dryrun:
408 if rename and not dryrun:
409 if not after and srcexists and not samefile:
409 if not after and srcexists and not samefile:
410 util.unlinkpath(repo.wjoin(abssrc))
410 util.unlinkpath(repo.wjoin(abssrc))
411 wctx.forget([abssrc])
411 wctx.forget([abssrc])
412
412
413 # pat: ossep
413 # pat: ossep
414 # dest ossep
414 # dest ossep
415 # srcs: list of (hgsep, hgsep, ossep, bool)
415 # srcs: list of (hgsep, hgsep, ossep, bool)
416 # return: function that takes hgsep and returns ossep
416 # return: function that takes hgsep and returns ossep
417 def targetpathfn(pat, dest, srcs):
417 def targetpathfn(pat, dest, srcs):
418 if os.path.isdir(pat):
418 if os.path.isdir(pat):
419 abspfx = pathutil.canonpath(repo.root, cwd, pat)
419 abspfx = pathutil.canonpath(repo.root, cwd, pat)
420 abspfx = util.localpath(abspfx)
420 abspfx = util.localpath(abspfx)
421 if destdirexists:
421 if destdirexists:
422 striplen = len(os.path.split(abspfx)[0])
422 striplen = len(os.path.split(abspfx)[0])
423 else:
423 else:
424 striplen = len(abspfx)
424 striplen = len(abspfx)
425 if striplen:
425 if striplen:
426 striplen += len(os.sep)
426 striplen += len(os.sep)
427 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
427 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
428 elif destdirexists:
428 elif destdirexists:
429 res = lambda p: os.path.join(dest,
429 res = lambda p: os.path.join(dest,
430 os.path.basename(util.localpath(p)))
430 os.path.basename(util.localpath(p)))
431 else:
431 else:
432 res = lambda p: dest
432 res = lambda p: dest
433 return res
433 return res
434
434
435 # pat: ossep
435 # pat: ossep
436 # dest ossep
436 # dest ossep
437 # srcs: list of (hgsep, hgsep, ossep, bool)
437 # srcs: list of (hgsep, hgsep, ossep, bool)
438 # return: function that takes hgsep and returns ossep
438 # return: function that takes hgsep and returns ossep
439 def targetpathafterfn(pat, dest, srcs):
439 def targetpathafterfn(pat, dest, srcs):
440 if matchmod.patkind(pat):
440 if matchmod.patkind(pat):
441 # a mercurial pattern
441 # a mercurial pattern
442 res = lambda p: os.path.join(dest,
442 res = lambda p: os.path.join(dest,
443 os.path.basename(util.localpath(p)))
443 os.path.basename(util.localpath(p)))
444 else:
444 else:
445 abspfx = pathutil.canonpath(repo.root, cwd, pat)
445 abspfx = pathutil.canonpath(repo.root, cwd, pat)
446 if len(abspfx) < len(srcs[0][0]):
446 if len(abspfx) < len(srcs[0][0]):
447 # A directory. Either the target path contains the last
447 # A directory. Either the target path contains the last
448 # component of the source path or it does not.
448 # component of the source path or it does not.
449 def evalpath(striplen):
449 def evalpath(striplen):
450 score = 0
450 score = 0
451 for s in srcs:
451 for s in srcs:
452 t = os.path.join(dest, util.localpath(s[0])[striplen:])
452 t = os.path.join(dest, util.localpath(s[0])[striplen:])
453 if os.path.lexists(t):
453 if os.path.lexists(t):
454 score += 1
454 score += 1
455 return score
455 return score
456
456
457 abspfx = util.localpath(abspfx)
457 abspfx = util.localpath(abspfx)
458 striplen = len(abspfx)
458 striplen = len(abspfx)
459 if striplen:
459 if striplen:
460 striplen += len(os.sep)
460 striplen += len(os.sep)
461 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
461 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
462 score = evalpath(striplen)
462 score = evalpath(striplen)
463 striplen1 = len(os.path.split(abspfx)[0])
463 striplen1 = len(os.path.split(abspfx)[0])
464 if striplen1:
464 if striplen1:
465 striplen1 += len(os.sep)
465 striplen1 += len(os.sep)
466 if evalpath(striplen1) > score:
466 if evalpath(striplen1) > score:
467 striplen = striplen1
467 striplen = striplen1
468 res = lambda p: os.path.join(dest,
468 res = lambda p: os.path.join(dest,
469 util.localpath(p)[striplen:])
469 util.localpath(p)[striplen:])
470 else:
470 else:
471 # a file
471 # a file
472 if destdirexists:
472 if destdirexists:
473 res = lambda p: os.path.join(dest,
473 res = lambda p: os.path.join(dest,
474 os.path.basename(util.localpath(p)))
474 os.path.basename(util.localpath(p)))
475 else:
475 else:
476 res = lambda p: dest
476 res = lambda p: dest
477 return res
477 return res
478
478
479
479
480 pats = scmutil.expandpats(pats)
480 pats = scmutil.expandpats(pats)
481 if not pats:
481 if not pats:
482 raise util.Abort(_('no source or destination specified'))
482 raise util.Abort(_('no source or destination specified'))
483 if len(pats) == 1:
483 if len(pats) == 1:
484 raise util.Abort(_('no destination specified'))
484 raise util.Abort(_('no destination specified'))
485 dest = pats.pop()
485 dest = pats.pop()
486 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
486 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
487 if not destdirexists:
487 if not destdirexists:
488 if len(pats) > 1 or matchmod.patkind(pats[0]):
488 if len(pats) > 1 or matchmod.patkind(pats[0]):
489 raise util.Abort(_('with multiple sources, destination must be an '
489 raise util.Abort(_('with multiple sources, destination must be an '
490 'existing directory'))
490 'existing directory'))
491 if util.endswithsep(dest):
491 if util.endswithsep(dest):
492 raise util.Abort(_('destination %s is not a directory') % dest)
492 raise util.Abort(_('destination %s is not a directory') % dest)
493
493
494 tfn = targetpathfn
494 tfn = targetpathfn
495 if after:
495 if after:
496 tfn = targetpathafterfn
496 tfn = targetpathafterfn
497 copylist = []
497 copylist = []
498 for pat in pats:
498 for pat in pats:
499 srcs = walkpat(pat)
499 srcs = walkpat(pat)
500 if not srcs:
500 if not srcs:
501 continue
501 continue
502 copylist.append((tfn(pat, dest, srcs), srcs))
502 copylist.append((tfn(pat, dest, srcs), srcs))
503 if not copylist:
503 if not copylist:
504 raise util.Abort(_('no files to copy'))
504 raise util.Abort(_('no files to copy'))
505
505
506 errors = 0
506 errors = 0
507 for targetpath, srcs in copylist:
507 for targetpath, srcs in copylist:
508 for abssrc, relsrc, exact in srcs:
508 for abssrc, relsrc, exact in srcs:
509 if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
509 if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
510 errors += 1
510 errors += 1
511
511
512 if errors:
512 if errors:
513 ui.warn(_('(consider using --after)\n'))
513 ui.warn(_('(consider using --after)\n'))
514
514
515 return errors != 0
515 return errors != 0
516
516
517 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
517 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
518 runargs=None, appendpid=False):
518 runargs=None, appendpid=False):
519 '''Run a command as a service.'''
519 '''Run a command as a service.'''
520
520
521 def writepid(pid):
521 def writepid(pid):
522 if opts['pid_file']:
522 if opts['pid_file']:
523 mode = appendpid and 'a' or 'w'
523 mode = appendpid and 'a' or 'w'
524 fp = open(opts['pid_file'], mode)
524 fp = open(opts['pid_file'], mode)
525 fp.write(str(pid) + '\n')
525 fp.write(str(pid) + '\n')
526 fp.close()
526 fp.close()
527
527
528 if opts['daemon'] and not opts['daemon_pipefds']:
528 if opts['daemon'] and not opts['daemon_pipefds']:
529 # Signal child process startup with file removal
529 # Signal child process startup with file removal
530 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
530 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
531 os.close(lockfd)
531 os.close(lockfd)
532 try:
532 try:
533 if not runargs:
533 if not runargs:
534 runargs = util.hgcmd() + sys.argv[1:]
534 runargs = util.hgcmd() + sys.argv[1:]
535 runargs.append('--daemon-pipefds=%s' % lockpath)
535 runargs.append('--daemon-pipefds=%s' % lockpath)
536 # Don't pass --cwd to the child process, because we've already
536 # Don't pass --cwd to the child process, because we've already
537 # changed directory.
537 # changed directory.
538 for i in xrange(1, len(runargs)):
538 for i in xrange(1, len(runargs)):
539 if runargs[i].startswith('--cwd='):
539 if runargs[i].startswith('--cwd='):
540 del runargs[i]
540 del runargs[i]
541 break
541 break
542 elif runargs[i].startswith('--cwd'):
542 elif runargs[i].startswith('--cwd'):
543 del runargs[i:i + 2]
543 del runargs[i:i + 2]
544 break
544 break
545 def condfn():
545 def condfn():
546 return not os.path.exists(lockpath)
546 return not os.path.exists(lockpath)
547 pid = util.rundetached(runargs, condfn)
547 pid = util.rundetached(runargs, condfn)
548 if pid < 0:
548 if pid < 0:
549 raise util.Abort(_('child process failed to start'))
549 raise util.Abort(_('child process failed to start'))
550 writepid(pid)
550 writepid(pid)
551 finally:
551 finally:
552 try:
552 try:
553 os.unlink(lockpath)
553 os.unlink(lockpath)
554 except OSError, e:
554 except OSError, e:
555 if e.errno != errno.ENOENT:
555 if e.errno != errno.ENOENT:
556 raise
556 raise
557 if parentfn:
557 if parentfn:
558 return parentfn(pid)
558 return parentfn(pid)
559 else:
559 else:
560 return
560 return
561
561
562 if initfn:
562 if initfn:
563 initfn()
563 initfn()
564
564
565 if not opts['daemon']:
565 if not opts['daemon']:
566 writepid(os.getpid())
566 writepid(os.getpid())
567
567
568 if opts['daemon_pipefds']:
568 if opts['daemon_pipefds']:
569 lockpath = opts['daemon_pipefds']
569 lockpath = opts['daemon_pipefds']
570 try:
570 try:
571 os.setsid()
571 os.setsid()
572 except AttributeError:
572 except AttributeError:
573 pass
573 pass
574 os.unlink(lockpath)
574 os.unlink(lockpath)
575 util.hidewindow()
575 util.hidewindow()
576 sys.stdout.flush()
576 sys.stdout.flush()
577 sys.stderr.flush()
577 sys.stderr.flush()
578
578
579 nullfd = os.open(os.devnull, os.O_RDWR)
579 nullfd = os.open(os.devnull, os.O_RDWR)
580 logfilefd = nullfd
580 logfilefd = nullfd
581 if logfile:
581 if logfile:
582 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
582 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
583 os.dup2(nullfd, 0)
583 os.dup2(nullfd, 0)
584 os.dup2(logfilefd, 1)
584 os.dup2(logfilefd, 1)
585 os.dup2(logfilefd, 2)
585 os.dup2(logfilefd, 2)
586 if nullfd not in (0, 1, 2):
586 if nullfd not in (0, 1, 2):
587 os.close(nullfd)
587 os.close(nullfd)
588 if logfile and logfilefd not in (0, 1, 2):
588 if logfile and logfilefd not in (0, 1, 2):
589 os.close(logfilefd)
589 os.close(logfilefd)
590
590
591 if runfn:
591 if runfn:
592 return runfn()
592 return runfn()
593
593
594 def tryimportone(ui, repo, hunk, parents, opts, msgs, updatefunc):
594 def tryimportone(ui, repo, hunk, parents, opts, msgs, updatefunc):
595 """Utility function used by commands.import to import a single patch
595 """Utility function used by commands.import to import a single patch
596
596
597 This function is explicitly defined here to help the evolve extension to
597 This function is explicitly defined here to help the evolve extension to
598 wrap this part of the import logic.
598 wrap this part of the import logic.
599
599
600 The API is currently a bit ugly because it a simple code translation from
600 The API is currently a bit ugly because it a simple code translation from
601 the import command. Feel free to make it better.
601 the import command. Feel free to make it better.
602
602
603 :hunk: a patch (as a binary string)
603 :hunk: a patch (as a binary string)
604 :parents: nodes that will be parent of the created commit
604 :parents: nodes that will be parent of the created commit
605 :opts: the full dict of option passed to the import command
605 :opts: the full dict of option passed to the import command
606 :msgs: list to save commit message to.
606 :msgs: list to save commit message to.
607 (used in case we need to save it when failing)
607 (used in case we need to save it when failing)
608 :updatefunc: a function that update a repo to a given node
608 :updatefunc: a function that update a repo to a given node
609 updatefunc(<repo>, <node>)
609 updatefunc(<repo>, <node>)
610 """
610 """
611 tmpname, message, user, date, branch, nodeid, p1, p2 = \
611 tmpname, message, user, date, branch, nodeid, p1, p2 = \
612 patch.extract(ui, hunk)
612 patch.extract(ui, hunk)
613
613
614 update = not opts.get('bypass')
614 update = not opts.get('bypass')
615 strip = opts["strip"]
615 strip = opts["strip"]
616 sim = float(opts.get('similarity') or 0)
616 sim = float(opts.get('similarity') or 0)
617 if not tmpname:
617 if not tmpname:
618 return (None, None, False)
618 return (None, None, False)
619 msg = _('applied to working directory')
619 msg = _('applied to working directory')
620
620
621 rejects = False
621 rejects = False
622
622
623 try:
623 try:
624 cmdline_message = logmessage(ui, opts)
624 cmdline_message = logmessage(ui, opts)
625 if cmdline_message:
625 if cmdline_message:
626 # pickup the cmdline msg
626 # pickup the cmdline msg
627 message = cmdline_message
627 message = cmdline_message
628 elif message:
628 elif message:
629 # pickup the patch msg
629 # pickup the patch msg
630 message = message.strip()
630 message = message.strip()
631 else:
631 else:
632 # launch the editor
632 # launch the editor
633 message = None
633 message = None
634 ui.debug('message:\n%s\n' % message)
634 ui.debug('message:\n%s\n' % message)
635
635
636 if len(parents) == 1:
636 if len(parents) == 1:
637 parents.append(repo[nullid])
637 parents.append(repo[nullid])
638 if opts.get('exact'):
638 if opts.get('exact'):
639 if not nodeid or not p1:
639 if not nodeid or not p1:
640 raise util.Abort(_('not a Mercurial patch'))
640 raise util.Abort(_('not a Mercurial patch'))
641 p1 = repo[p1]
641 p1 = repo[p1]
642 p2 = repo[p2 or nullid]
642 p2 = repo[p2 or nullid]
643 elif p2:
643 elif p2:
644 try:
644 try:
645 p1 = repo[p1]
645 p1 = repo[p1]
646 p2 = repo[p2]
646 p2 = repo[p2]
647 # Without any options, consider p2 only if the
647 # Without any options, consider p2 only if the
648 # patch is being applied on top of the recorded
648 # patch is being applied on top of the recorded
649 # first parent.
649 # first parent.
650 if p1 != parents[0]:
650 if p1 != parents[0]:
651 p1 = parents[0]
651 p1 = parents[0]
652 p2 = repo[nullid]
652 p2 = repo[nullid]
653 except error.RepoError:
653 except error.RepoError:
654 p1, p2 = parents
654 p1, p2 = parents
655 if p2.node() == nullid:
655 if p2.node() == nullid:
656 ui.warn(_("warning: import the patch as a normal revision\n"
656 ui.warn(_("warning: import the patch as a normal revision\n"
657 "(use --exact to import the patch as a merge)\n"))
657 "(use --exact to import the patch as a merge)\n"))
658 else:
658 else:
659 p1, p2 = parents
659 p1, p2 = parents
660
660
661 n = None
661 n = None
662 if update:
662 if update:
663 repo.dirstate.beginparentchange()
663 repo.dirstate.beginparentchange()
664 if p1 != parents[0]:
664 if p1 != parents[0]:
665 updatefunc(repo, p1.node())
665 updatefunc(repo, p1.node())
666 if p2 != parents[1]:
666 if p2 != parents[1]:
667 repo.setparents(p1.node(), p2.node())
667 repo.setparents(p1.node(), p2.node())
668
668
669 if opts.get('exact') or opts.get('import_branch'):
669 if opts.get('exact') or opts.get('import_branch'):
670 repo.dirstate.setbranch(branch or 'default')
670 repo.dirstate.setbranch(branch or 'default')
671
671
672 partial = opts.get('partial', False)
672 partial = opts.get('partial', False)
673 files = set()
673 files = set()
674 try:
674 try:
675 patch.patch(ui, repo, tmpname, strip=strip, files=files,
675 patch.patch(ui, repo, tmpname, strip=strip, files=files,
676 eolmode=None, similarity=sim / 100.0)
676 eolmode=None, similarity=sim / 100.0)
677 except patch.PatchError, e:
677 except patch.PatchError, e:
678 if not partial:
678 if not partial:
679 raise util.Abort(str(e))
679 raise util.Abort(str(e))
680 if partial:
680 if partial:
681 rejects = True
681 rejects = True
682
682
683 files = list(files)
683 files = list(files)
684 if opts.get('no_commit'):
684 if opts.get('no_commit'):
685 if message:
685 if message:
686 msgs.append(message)
686 msgs.append(message)
687 else:
687 else:
688 if opts.get('exact') or p2:
688 if opts.get('exact') or p2:
689 # If you got here, you either use --force and know what
689 # If you got here, you either use --force and know what
690 # you are doing or used --exact or a merge patch while
690 # you are doing or used --exact or a merge patch while
691 # being updated to its first parent.
691 # being updated to its first parent.
692 m = None
692 m = None
693 else:
693 else:
694 m = scmutil.matchfiles(repo, files or [])
694 m = scmutil.matchfiles(repo, files or [])
695 editform = mergeeditform(repo[None], 'import.normal')
695 editform = mergeeditform(repo[None], 'import.normal')
696 if opts.get('exact'):
696 if opts.get('exact'):
697 editor = None
697 editor = None
698 else:
698 else:
699 editor = getcommiteditor(editform=editform, **opts)
699 editor = getcommiteditor(editform=editform, **opts)
700 n = repo.commit(message, opts.get('user') or user,
700 n = repo.commit(message, opts.get('user') or user,
701 opts.get('date') or date, match=m,
701 opts.get('date') or date, match=m,
702 editor=editor, force=partial)
702 editor=editor, force=partial)
703 repo.dirstate.endparentchange()
703 repo.dirstate.endparentchange()
704 else:
704 else:
705 if opts.get('exact') or opts.get('import_branch'):
705 if opts.get('exact') or opts.get('import_branch'):
706 branch = branch or 'default'
706 branch = branch or 'default'
707 else:
707 else:
708 branch = p1.branch()
708 branch = p1.branch()
709 store = patch.filestore()
709 store = patch.filestore()
710 try:
710 try:
711 files = set()
711 files = set()
712 try:
712 try:
713 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
713 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
714 files, eolmode=None)
714 files, eolmode=None)
715 except patch.PatchError, e:
715 except patch.PatchError, e:
716 raise util.Abort(str(e))
716 raise util.Abort(str(e))
717 if opts.get('exact'):
717 if opts.get('exact'):
718 editor = None
718 editor = None
719 else:
719 else:
720 editor = getcommiteditor(editform='import.bypass')
720 editor = getcommiteditor(editform='import.bypass')
721 memctx = context.makememctx(repo, (p1.node(), p2.node()),
721 memctx = context.makememctx(repo, (p1.node(), p2.node()),
722 message,
722 message,
723 opts.get('user') or user,
723 opts.get('user') or user,
724 opts.get('date') or date,
724 opts.get('date') or date,
725 branch, files, store,
725 branch, files, store,
726 editor=editor)
726 editor=editor)
727 n = memctx.commit()
727 n = memctx.commit()
728 finally:
728 finally:
729 store.close()
729 store.close()
730 if opts.get('exact') and opts.get('no_commit'):
730 if opts.get('exact') and opts.get('no_commit'):
731 # --exact with --no-commit is still useful in that it does merge
731 # --exact with --no-commit is still useful in that it does merge
732 # and branch bits
732 # and branch bits
733 ui.warn(_("warning: can't check exact import with --no-commit\n"))
733 ui.warn(_("warning: can't check exact import with --no-commit\n"))
734 elif opts.get('exact') and hex(n) != nodeid:
734 elif opts.get('exact') and hex(n) != nodeid:
735 raise util.Abort(_('patch is damaged or loses information'))
735 raise util.Abort(_('patch is damaged or loses information'))
736 if n:
736 if n:
737 # i18n: refers to a short changeset id
737 # i18n: refers to a short changeset id
738 msg = _('created %s') % short(n)
738 msg = _('created %s') % short(n)
739 return (msg, n, rejects)
739 return (msg, n, rejects)
740 finally:
740 finally:
741 os.unlink(tmpname)
741 os.unlink(tmpname)
742
742
743 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
743 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
744 opts=None):
744 opts=None):
745 '''export changesets as hg patches.'''
745 '''export changesets as hg patches.'''
746
746
747 total = len(revs)
747 total = len(revs)
748 revwidth = max([len(str(rev)) for rev in revs])
748 revwidth = max([len(str(rev)) for rev in revs])
749 filemode = {}
749 filemode = {}
750
750
751 def single(rev, seqno, fp):
751 def single(rev, seqno, fp):
752 ctx = repo[rev]
752 ctx = repo[rev]
753 node = ctx.node()
753 node = ctx.node()
754 parents = [p.node() for p in ctx.parents() if p]
754 parents = [p.node() for p in ctx.parents() if p]
755 branch = ctx.branch()
755 branch = ctx.branch()
756 if switch_parent:
756 if switch_parent:
757 parents.reverse()
757 parents.reverse()
758 prev = (parents and parents[0]) or nullid
758 prev = (parents and parents[0]) or nullid
759
759
760 shouldclose = False
760 shouldclose = False
761 if not fp and len(template) > 0:
761 if not fp and len(template) > 0:
762 desc_lines = ctx.description().rstrip().split('\n')
762 desc_lines = ctx.description().rstrip().split('\n')
763 desc = desc_lines[0] #Commit always has a first line.
763 desc = desc_lines[0] #Commit always has a first line.
764 fp = makefileobj(repo, template, node, desc=desc, total=total,
764 fp = makefileobj(repo, template, node, desc=desc, total=total,
765 seqno=seqno, revwidth=revwidth, mode='wb',
765 seqno=seqno, revwidth=revwidth, mode='wb',
766 modemap=filemode)
766 modemap=filemode)
767 if fp != template:
767 if fp != template:
768 shouldclose = True
768 shouldclose = True
769 if fp and fp != sys.stdout and util.safehasattr(fp, 'name'):
769 if fp and fp != sys.stdout and util.safehasattr(fp, 'name'):
770 repo.ui.note("%s\n" % fp.name)
770 repo.ui.note("%s\n" % fp.name)
771
771
772 if not fp:
772 if not fp:
773 write = repo.ui.write
773 write = repo.ui.write
774 else:
774 else:
775 def write(s, **kw):
775 def write(s, **kw):
776 fp.write(s)
776 fp.write(s)
777
777
778
778
779 write("# HG changeset patch\n")
779 write("# HG changeset patch\n")
780 write("# User %s\n" % ctx.user())
780 write("# User %s\n" % ctx.user())
781 write("# Date %d %d\n" % ctx.date())
781 write("# Date %d %d\n" % ctx.date())
782 write("# %s\n" % util.datestr(ctx.date()))
782 write("# %s\n" % util.datestr(ctx.date()))
783 if branch and branch != 'default':
783 if branch and branch != 'default':
784 write("# Branch %s\n" % branch)
784 write("# Branch %s\n" % branch)
785 write("# Node ID %s\n" % hex(node))
785 write("# Node ID %s\n" % hex(node))
786 write("# Parent %s\n" % hex(prev))
786 write("# Parent %s\n" % hex(prev))
787 if len(parents) > 1:
787 if len(parents) > 1:
788 write("# Parent %s\n" % hex(parents[1]))
788 write("# Parent %s\n" % hex(parents[1]))
789 write(ctx.description().rstrip())
789 write(ctx.description().rstrip())
790 write("\n\n")
790 write("\n\n")
791
791
792 for chunk, label in patch.diffui(repo, prev, node, opts=opts):
792 for chunk, label in patch.diffui(repo, prev, node, opts=opts):
793 write(chunk, label=label)
793 write(chunk, label=label)
794
794
795 if shouldclose:
795 if shouldclose:
796 fp.close()
796 fp.close()
797
797
798 for seqno, rev in enumerate(revs):
798 for seqno, rev in enumerate(revs):
799 single(rev, seqno + 1, fp)
799 single(rev, seqno + 1, fp)
800
800
801 def diffordiffstat(ui, repo, diffopts, node1, node2, match,
801 def diffordiffstat(ui, repo, diffopts, node1, node2, match,
802 changes=None, stat=False, fp=None, prefix='',
802 changes=None, stat=False, fp=None, prefix='',
803 listsubrepos=False):
803 listsubrepos=False):
804 '''show diff or diffstat.'''
804 '''show diff or diffstat.'''
805 if fp is None:
805 if fp is None:
806 write = ui.write
806 write = ui.write
807 else:
807 else:
808 def write(s, **kw):
808 def write(s, **kw):
809 fp.write(s)
809 fp.write(s)
810
810
811 if stat:
811 if stat:
812 diffopts = diffopts.copy(context=0)
812 diffopts = diffopts.copy(context=0)
813 width = 80
813 width = 80
814 if not ui.plain():
814 if not ui.plain():
815 width = ui.termwidth()
815 width = ui.termwidth()
816 chunks = patch.diff(repo, node1, node2, match, changes, diffopts,
816 chunks = patch.diff(repo, node1, node2, match, changes, diffopts,
817 prefix=prefix)
817 prefix=prefix)
818 for chunk, label in patch.diffstatui(util.iterlines(chunks),
818 for chunk, label in patch.diffstatui(util.iterlines(chunks),
819 width=width,
819 width=width,
820 git=diffopts.git):
820 git=diffopts.git):
821 write(chunk, label=label)
821 write(chunk, label=label)
822 else:
822 else:
823 for chunk, label in patch.diffui(repo, node1, node2, match,
823 for chunk, label in patch.diffui(repo, node1, node2, match,
824 changes, diffopts, prefix=prefix):
824 changes, diffopts, prefix=prefix):
825 write(chunk, label=label)
825 write(chunk, label=label)
826
826
827 if listsubrepos:
827 if listsubrepos:
828 ctx1 = repo[node1]
828 ctx1 = repo[node1]
829 ctx2 = repo[node2]
829 ctx2 = repo[node2]
830 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
830 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
831 tempnode2 = node2
831 tempnode2 = node2
832 try:
832 try:
833 if node2 is not None:
833 if node2 is not None:
834 tempnode2 = ctx2.substate[subpath][1]
834 tempnode2 = ctx2.substate[subpath][1]
835 except KeyError:
835 except KeyError:
836 # A subrepo that existed in node1 was deleted between node1 and
836 # A subrepo that existed in node1 was deleted between node1 and
837 # node2 (inclusive). Thus, ctx2's substate won't contain that
837 # node2 (inclusive). Thus, ctx2's substate won't contain that
838 # subpath. The best we can do is to ignore it.
838 # subpath. The best we can do is to ignore it.
839 tempnode2 = None
839 tempnode2 = None
840 submatch = matchmod.narrowmatcher(subpath, match)
840 submatch = matchmod.narrowmatcher(subpath, match)
841 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes,
841 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes,
842 stat=stat, fp=fp, prefix=prefix)
842 stat=stat, fp=fp, prefix=prefix)
843
843
844 class changeset_printer(object):
844 class changeset_printer(object):
845 '''show changeset information when templating not requested.'''
845 '''show changeset information when templating not requested.'''
846
846
847 def __init__(self, ui, repo, matchfn, diffopts, buffered):
847 def __init__(self, ui, repo, matchfn, diffopts, buffered):
848 self.ui = ui
848 self.ui = ui
849 self.repo = repo
849 self.repo = repo
850 self.buffered = buffered
850 self.buffered = buffered
851 self.matchfn = matchfn
851 self.matchfn = matchfn
852 self.diffopts = diffopts
852 self.diffopts = diffopts
853 self.header = {}
853 self.header = {}
854 self.hunk = {}
854 self.hunk = {}
855 self.lastheader = None
855 self.lastheader = None
856 self.footer = None
856 self.footer = None
857
857
858 def flush(self, rev):
858 def flush(self, rev):
859 if rev in self.header:
859 if rev in self.header:
860 h = self.header[rev]
860 h = self.header[rev]
861 if h != self.lastheader:
861 if h != self.lastheader:
862 self.lastheader = h
862 self.lastheader = h
863 self.ui.write(h)
863 self.ui.write(h)
864 del self.header[rev]
864 del self.header[rev]
865 if rev in self.hunk:
865 if rev in self.hunk:
866 self.ui.write(self.hunk[rev])
866 self.ui.write(self.hunk[rev])
867 del self.hunk[rev]
867 del self.hunk[rev]
868 return 1
868 return 1
869 return 0
869 return 0
870
870
871 def close(self):
871 def close(self):
872 if self.footer:
872 if self.footer:
873 self.ui.write(self.footer)
873 self.ui.write(self.footer)
874
874
875 def show(self, ctx, copies=None, matchfn=None, **props):
875 def show(self, ctx, copies=None, matchfn=None, **props):
876 if self.buffered:
876 if self.buffered:
877 self.ui.pushbuffer()
877 self.ui.pushbuffer()
878 self._show(ctx, copies, matchfn, props)
878 self._show(ctx, copies, matchfn, props)
879 self.hunk[ctx.rev()] = self.ui.popbuffer(labeled=True)
879 self.hunk[ctx.rev()] = self.ui.popbuffer(labeled=True)
880 else:
880 else:
881 self._show(ctx, copies, matchfn, props)
881 self._show(ctx, copies, matchfn, props)
882
882
883 def _show(self, ctx, copies, matchfn, props):
883 def _show(self, ctx, copies, matchfn, props):
884 '''show a single changeset or file revision'''
884 '''show a single changeset or file revision'''
885 changenode = ctx.node()
885 changenode = ctx.node()
886 rev = ctx.rev()
886 rev = ctx.rev()
887
887
888 if self.ui.quiet:
888 if self.ui.quiet:
889 self.ui.write("%d:%s\n" % (rev, short(changenode)),
889 self.ui.write("%d:%s\n" % (rev, short(changenode)),
890 label='log.node')
890 label='log.node')
891 return
891 return
892
892
893 log = self.repo.changelog
893 log = self.repo.changelog
894 date = util.datestr(ctx.date())
894 date = util.datestr(ctx.date())
895
895
896 hexfunc = self.ui.debugflag and hex or short
896 hexfunc = self.ui.debugflag and hex or short
897
897
898 parents = [(p, hexfunc(log.node(p)))
898 parents = [(p, hexfunc(log.node(p)))
899 for p in self._meaningful_parentrevs(log, rev)]
899 for p in self._meaningful_parentrevs(log, rev)]
900
900
901 # i18n: column positioning for "hg log"
901 # i18n: column positioning for "hg log"
902 self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode)),
902 self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode)),
903 label='log.changeset changeset.%s' % ctx.phasestr())
903 label='log.changeset changeset.%s' % ctx.phasestr())
904
904
905 # branches are shown first before any other names due to backwards
905 # branches are shown first before any other names due to backwards
906 # compatibility
906 # compatibility
907 branch = ctx.branch()
907 branch = ctx.branch()
908 # don't show the default branch name
908 # don't show the default branch name
909 if branch != 'default':
909 if branch != 'default':
910 # i18n: column positioning for "hg log"
910 # i18n: column positioning for "hg log"
911 self.ui.write(_("branch: %s\n") % branch,
911 self.ui.write(_("branch: %s\n") % branch,
912 label='log.branch')
912 label='log.branch')
913
913
914 for name, ns in self.repo.names.iteritems():
914 for name, ns in self.repo.names.iteritems():
915 # branches has special logic already handled above, so here we just
915 # branches has special logic already handled above, so here we just
916 # skip it
916 # skip it
917 if name == 'branches':
917 if name == 'branches':
918 continue
918 continue
919 # we will use the templatename as the color name since those two
919 # we will use the templatename as the color name since those two
920 # should be the same
920 # should be the same
921 for name in ns.names(self.repo, changenode):
921 for name in ns.names(self.repo, changenode):
922 self.ui.write(ns.logfmt % name,
922 self.ui.write(ns.logfmt % name,
923 label='log.%s' % ns.colorname)
923 label='log.%s' % ns.colorname)
924 if self.ui.debugflag:
924 if self.ui.debugflag:
925 # i18n: column positioning for "hg log"
925 # i18n: column positioning for "hg log"
926 self.ui.write(_("phase: %s\n") % _(ctx.phasestr()),
926 self.ui.write(_("phase: %s\n") % _(ctx.phasestr()),
927 label='log.phase')
927 label='log.phase')
928 for parent in parents:
928 for parent in parents:
929 label = 'log.parent changeset.%s' % self.repo[parent[0]].phasestr()
929 label = 'log.parent changeset.%s' % self.repo[parent[0]].phasestr()
930 # i18n: column positioning for "hg log"
930 # i18n: column positioning for "hg log"
931 self.ui.write(_("parent: %d:%s\n") % parent,
931 self.ui.write(_("parent: %d:%s\n") % parent,
932 label=label)
932 label=label)
933
933
934 if self.ui.debugflag:
934 if self.ui.debugflag:
935 mnode = ctx.manifestnode()
935 mnode = ctx.manifestnode()
936 # i18n: column positioning for "hg log"
936 # i18n: column positioning for "hg log"
937 self.ui.write(_("manifest: %d:%s\n") %
937 self.ui.write(_("manifest: %d:%s\n") %
938 (self.repo.manifest.rev(mnode), hex(mnode)),
938 (self.repo.manifest.rev(mnode), hex(mnode)),
939 label='ui.debug log.manifest')
939 label='ui.debug log.manifest')
940 # i18n: column positioning for "hg log"
940 # i18n: column positioning for "hg log"
941 self.ui.write(_("user: %s\n") % ctx.user(),
941 self.ui.write(_("user: %s\n") % ctx.user(),
942 label='log.user')
942 label='log.user')
943 # i18n: column positioning for "hg log"
943 # i18n: column positioning for "hg log"
944 self.ui.write(_("date: %s\n") % date,
944 self.ui.write(_("date: %s\n") % date,
945 label='log.date')
945 label='log.date')
946
946
947 if self.ui.debugflag:
947 if self.ui.debugflag:
948 files = self.repo.status(log.parents(changenode)[0], changenode)[:3]
948 files = self.repo.status(log.parents(changenode)[0], changenode)[:3]
949 for key, value in zip([# i18n: column positioning for "hg log"
949 for key, value in zip([# i18n: column positioning for "hg log"
950 _("files:"),
950 _("files:"),
951 # i18n: column positioning for "hg log"
951 # i18n: column positioning for "hg log"
952 _("files+:"),
952 _("files+:"),
953 # i18n: column positioning for "hg log"
953 # i18n: column positioning for "hg log"
954 _("files-:")], files):
954 _("files-:")], files):
955 if value:
955 if value:
956 self.ui.write("%-12s %s\n" % (key, " ".join(value)),
956 self.ui.write("%-12s %s\n" % (key, " ".join(value)),
957 label='ui.debug log.files')
957 label='ui.debug log.files')
958 elif ctx.files() and self.ui.verbose:
958 elif ctx.files() and self.ui.verbose:
959 # i18n: column positioning for "hg log"
959 # i18n: column positioning for "hg log"
960 self.ui.write(_("files: %s\n") % " ".join(ctx.files()),
960 self.ui.write(_("files: %s\n") % " ".join(ctx.files()),
961 label='ui.note log.files')
961 label='ui.note log.files')
962 if copies and self.ui.verbose:
962 if copies and self.ui.verbose:
963 copies = ['%s (%s)' % c for c in copies]
963 copies = ['%s (%s)' % c for c in copies]
964 # i18n: column positioning for "hg log"
964 # i18n: column positioning for "hg log"
965 self.ui.write(_("copies: %s\n") % ' '.join(copies),
965 self.ui.write(_("copies: %s\n") % ' '.join(copies),
966 label='ui.note log.copies')
966 label='ui.note log.copies')
967
967
968 extra = ctx.extra()
968 extra = ctx.extra()
969 if extra and self.ui.debugflag:
969 if extra and self.ui.debugflag:
970 for key, value in sorted(extra.items()):
970 for key, value in sorted(extra.items()):
971 # i18n: column positioning for "hg log"
971 # i18n: column positioning for "hg log"
972 self.ui.write(_("extra: %s=%s\n")
972 self.ui.write(_("extra: %s=%s\n")
973 % (key, value.encode('string_escape')),
973 % (key, value.encode('string_escape')),
974 label='ui.debug log.extra')
974 label='ui.debug log.extra')
975
975
976 description = ctx.description().strip()
976 description = ctx.description().strip()
977 if description:
977 if description:
978 if self.ui.verbose:
978 if self.ui.verbose:
979 self.ui.write(_("description:\n"),
979 self.ui.write(_("description:\n"),
980 label='ui.note log.description')
980 label='ui.note log.description')
981 self.ui.write(description,
981 self.ui.write(description,
982 label='ui.note log.description')
982 label='ui.note log.description')
983 self.ui.write("\n\n")
983 self.ui.write("\n\n")
984 else:
984 else:
985 # i18n: column positioning for "hg log"
985 # i18n: column positioning for "hg log"
986 self.ui.write(_("summary: %s\n") %
986 self.ui.write(_("summary: %s\n") %
987 description.splitlines()[0],
987 description.splitlines()[0],
988 label='log.summary')
988 label='log.summary')
989 self.ui.write("\n")
989 self.ui.write("\n")
990
990
991 self.showpatch(changenode, matchfn)
991 self.showpatch(changenode, matchfn)
992
992
993 def showpatch(self, node, matchfn):
993 def showpatch(self, node, matchfn):
994 if not matchfn:
994 if not matchfn:
995 matchfn = self.matchfn
995 matchfn = self.matchfn
996 if matchfn:
996 if matchfn:
997 stat = self.diffopts.get('stat')
997 stat = self.diffopts.get('stat')
998 diff = self.diffopts.get('patch')
998 diff = self.diffopts.get('patch')
999 diffopts = patch.diffallopts(self.ui, self.diffopts)
999 diffopts = patch.diffallopts(self.ui, self.diffopts)
1000 prev = self.repo.changelog.parents(node)[0]
1000 prev = self.repo.changelog.parents(node)[0]
1001 if stat:
1001 if stat:
1002 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1002 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1003 match=matchfn, stat=True)
1003 match=matchfn, stat=True)
1004 if diff:
1004 if diff:
1005 if stat:
1005 if stat:
1006 self.ui.write("\n")
1006 self.ui.write("\n")
1007 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1007 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1008 match=matchfn, stat=False)
1008 match=matchfn, stat=False)
1009 self.ui.write("\n")
1009 self.ui.write("\n")
1010
1010
1011 def _meaningful_parentrevs(self, log, rev):
1011 def _meaningful_parentrevs(self, log, rev):
1012 """Return list of meaningful (or all if debug) parentrevs for rev.
1012 """Return list of meaningful (or all if debug) parentrevs for rev.
1013
1013
1014 For merges (two non-nullrev revisions) both parents are meaningful.
1014 For merges (two non-nullrev revisions) both parents are meaningful.
1015 Otherwise the first parent revision is considered meaningful if it
1015 Otherwise the first parent revision is considered meaningful if it
1016 is not the preceding revision.
1016 is not the preceding revision.
1017 """
1017 """
1018 parents = log.parentrevs(rev)
1018 parents = log.parentrevs(rev)
1019 if not self.ui.debugflag and parents[1] == nullrev:
1019 if not self.ui.debugflag and parents[1] == nullrev:
1020 if parents[0] >= rev - 1:
1020 if parents[0] >= rev - 1:
1021 parents = []
1021 parents = []
1022 else:
1022 else:
1023 parents = [parents[0]]
1023 parents = [parents[0]]
1024 return parents
1024 return parents
1025
1025
1026 class jsonchangeset(changeset_printer):
1026 class jsonchangeset(changeset_printer):
1027 '''format changeset information.'''
1027 '''format changeset information.'''
1028
1028
1029 def __init__(self, ui, repo, matchfn, diffopts, buffered):
1029 def __init__(self, ui, repo, matchfn, diffopts, buffered):
1030 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
1030 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
1031 self.cache = {}
1031 self.cache = {}
1032 self._first = True
1032 self._first = True
1033
1033
1034 def close(self):
1034 def close(self):
1035 if not self._first:
1035 if not self._first:
1036 self.ui.write("\n]\n")
1036 self.ui.write("\n]\n")
1037 else:
1037 else:
1038 self.ui.write("[]\n")
1038 self.ui.write("[]\n")
1039
1039
1040 def _show(self, ctx, copies, matchfn, props):
1040 def _show(self, ctx, copies, matchfn, props):
1041 '''show a single changeset or file revision'''
1041 '''show a single changeset or file revision'''
1042 hexnode = hex(ctx.node())
1042 hexnode = hex(ctx.node())
1043 rev = ctx.rev()
1043 rev = ctx.rev()
1044 j = encoding.jsonescape
1044 j = encoding.jsonescape
1045
1045
1046 if self._first:
1046 if self._first:
1047 self.ui.write("[\n {")
1047 self.ui.write("[\n {")
1048 self._first = False
1048 self._first = False
1049 else:
1049 else:
1050 self.ui.write(",\n {")
1050 self.ui.write(",\n {")
1051
1051
1052 if self.ui.quiet:
1052 if self.ui.quiet:
1053 self.ui.write('\n "rev": %d' % rev)
1053 self.ui.write('\n "rev": %d' % rev)
1054 self.ui.write(',\n "node": "%s"' % hexnode)
1054 self.ui.write(',\n "node": "%s"' % hexnode)
1055 self.ui.write('\n }')
1055 self.ui.write('\n }')
1056 return
1056 return
1057
1057
1058 self.ui.write('\n "rev": %d' % rev)
1058 self.ui.write('\n "rev": %d' % rev)
1059 self.ui.write(',\n "node": "%s"' % hexnode)
1059 self.ui.write(',\n "node": "%s"' % hexnode)
1060 self.ui.write(',\n "branch": "%s"' % j(ctx.branch()))
1060 self.ui.write(',\n "branch": "%s"' % j(ctx.branch()))
1061 self.ui.write(',\n "phase": "%s"' % ctx.phasestr())
1061 self.ui.write(',\n "phase": "%s"' % ctx.phasestr())
1062 self.ui.write(',\n "user": "%s"' % j(ctx.user()))
1062 self.ui.write(',\n "user": "%s"' % j(ctx.user()))
1063 self.ui.write(',\n "date": [%d, %d]' % ctx.date())
1063 self.ui.write(',\n "date": [%d, %d]' % ctx.date())
1064 self.ui.write(',\n "desc": "%s"' % j(ctx.description()))
1064 self.ui.write(',\n "desc": "%s"' % j(ctx.description()))
1065
1065
1066 self.ui.write(',\n "bookmarks": [%s]' %
1066 self.ui.write(',\n "bookmarks": [%s]' %
1067 ", ".join('"%s"' % j(b) for b in ctx.bookmarks()))
1067 ", ".join('"%s"' % j(b) for b in ctx.bookmarks()))
1068 self.ui.write(',\n "tags": [%s]' %
1068 self.ui.write(',\n "tags": [%s]' %
1069 ", ".join('"%s"' % j(t) for t in ctx.tags()))
1069 ", ".join('"%s"' % j(t) for t in ctx.tags()))
1070 self.ui.write(',\n "parents": [%s]' %
1070 self.ui.write(',\n "parents": [%s]' %
1071 ", ".join('"%s"' % c.hex() for c in ctx.parents()))
1071 ", ".join('"%s"' % c.hex() for c in ctx.parents()))
1072
1072
1073 if self.ui.debugflag:
1073 if self.ui.debugflag:
1074 self.ui.write(',\n "manifest": "%s"' % hex(ctx.manifestnode()))
1074 self.ui.write(',\n "manifest": "%s"' % hex(ctx.manifestnode()))
1075
1075
1076 self.ui.write(',\n "extra": {%s}' %
1076 self.ui.write(',\n "extra": {%s}' %
1077 ", ".join('"%s": "%s"' % (j(k), j(v))
1077 ", ".join('"%s": "%s"' % (j(k), j(v))
1078 for k, v in ctx.extra().items()))
1078 for k, v in ctx.extra().items()))
1079
1079
1080 files = ctx.p1().status(ctx)
1080 files = ctx.p1().status(ctx)
1081 self.ui.write(',\n "modified": [%s]' %
1081 self.ui.write(',\n "modified": [%s]' %
1082 ", ".join('"%s"' % j(f) for f in files[0]))
1082 ", ".join('"%s"' % j(f) for f in files[0]))
1083 self.ui.write(',\n "added": [%s]' %
1083 self.ui.write(',\n "added": [%s]' %
1084 ", ".join('"%s"' % j(f) for f in files[1]))
1084 ", ".join('"%s"' % j(f) for f in files[1]))
1085 self.ui.write(',\n "removed": [%s]' %
1085 self.ui.write(',\n "removed": [%s]' %
1086 ", ".join('"%s"' % j(f) for f in files[2]))
1086 ", ".join('"%s"' % j(f) for f in files[2]))
1087
1087
1088 elif self.ui.verbose:
1088 elif self.ui.verbose:
1089 self.ui.write(',\n "files": [%s]' %
1089 self.ui.write(',\n "files": [%s]' %
1090 ", ".join('"%s"' % j(f) for f in ctx.files()))
1090 ", ".join('"%s"' % j(f) for f in ctx.files()))
1091
1091
1092 if copies:
1092 if copies:
1093 self.ui.write(',\n "copies": {%s}' %
1093 self.ui.write(',\n "copies": {%s}' %
1094 ", ".join('"%s": "%s"' % (j(k), j(v))
1094 ", ".join('"%s": "%s"' % (j(k), j(v))
1095 for k, v in copies))
1095 for k, v in copies))
1096
1096
1097 matchfn = self.matchfn
1097 matchfn = self.matchfn
1098 if matchfn:
1098 if matchfn:
1099 stat = self.diffopts.get('stat')
1099 stat = self.diffopts.get('stat')
1100 diff = self.diffopts.get('patch')
1100 diff = self.diffopts.get('patch')
1101 diffopts = patch.difffeatureopts(self.ui, self.diffopts, git=True)
1101 diffopts = patch.difffeatureopts(self.ui, self.diffopts, git=True)
1102 node, prev = ctx.node(), ctx.p1().node()
1102 node, prev = ctx.node(), ctx.p1().node()
1103 if stat:
1103 if stat:
1104 self.ui.pushbuffer()
1104 self.ui.pushbuffer()
1105 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1105 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1106 match=matchfn, stat=True)
1106 match=matchfn, stat=True)
1107 self.ui.write(',\n "diffstat": "%s"' % j(self.ui.popbuffer()))
1107 self.ui.write(',\n "diffstat": "%s"' % j(self.ui.popbuffer()))
1108 if diff:
1108 if diff:
1109 self.ui.pushbuffer()
1109 self.ui.pushbuffer()
1110 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1110 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1111 match=matchfn, stat=False)
1111 match=matchfn, stat=False)
1112 self.ui.write(',\n "diff": "%s"' % j(self.ui.popbuffer()))
1112 self.ui.write(',\n "diff": "%s"' % j(self.ui.popbuffer()))
1113
1113
1114 self.ui.write("\n }")
1114 self.ui.write("\n }")
1115
1115
1116 class changeset_templater(changeset_printer):
1116 class changeset_templater(changeset_printer):
1117 '''format changeset information.'''
1117 '''format changeset information.'''
1118
1118
1119 def __init__(self, ui, repo, matchfn, diffopts, tmpl, mapfile, buffered):
1119 def __init__(self, ui, repo, matchfn, diffopts, tmpl, mapfile, buffered):
1120 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
1120 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
1121 formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
1121 formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
1122 defaulttempl = {
1122 defaulttempl = {
1123 'parent': '{rev}:{node|formatnode} ',
1123 'parent': '{rev}:{node|formatnode} ',
1124 'manifest': '{rev}:{node|formatnode}',
1124 'manifest': '{rev}:{node|formatnode}',
1125 'file_copy': '{name} ({source})',
1125 'file_copy': '{name} ({source})',
1126 'extra': '{key}={value|stringescape}'
1126 'extra': '{key}={value|stringescape}'
1127 }
1127 }
1128 # filecopy is preserved for compatibility reasons
1128 # filecopy is preserved for compatibility reasons
1129 defaulttempl['filecopy'] = defaulttempl['file_copy']
1129 defaulttempl['filecopy'] = defaulttempl['file_copy']
1130 self.t = templater.templater(mapfile, {'formatnode': formatnode},
1130 self.t = templater.templater(mapfile, {'formatnode': formatnode},
1131 cache=defaulttempl)
1131 cache=defaulttempl)
1132 if tmpl:
1132 if tmpl:
1133 self.t.cache['changeset'] = tmpl
1133 self.t.cache['changeset'] = tmpl
1134
1134
1135 self.cache = {}
1135 self.cache = {}
1136
1136
1137 def _meaningful_parentrevs(self, ctx):
1137 def _meaningful_parentrevs(self, ctx):
1138 """Return list of meaningful (or all if debug) parentrevs for rev.
1138 """Return list of meaningful (or all if debug) parentrevs for rev.
1139 """
1139 """
1140 parents = ctx.parents()
1140 parents = ctx.parents()
1141 if len(parents) > 1:
1141 if len(parents) > 1:
1142 return parents
1142 return parents
1143 if self.ui.debugflag:
1143 if self.ui.debugflag:
1144 return [parents[0], self.repo['null']]
1144 return [parents[0], self.repo['null']]
1145 if parents[0].rev() >= ctx.rev() - 1:
1145 if parents[0].rev() >= ctx.rev() - 1:
1146 return []
1146 return []
1147 return parents
1147 return parents
1148
1148
1149 def _show(self, ctx, copies, matchfn, props):
1149 def _show(self, ctx, copies, matchfn, props):
1150 '''show a single changeset or file revision'''
1150 '''show a single changeset or file revision'''
1151
1151
1152 showlist = templatekw.showlist
1152 showlist = templatekw.showlist
1153
1153
1154 # showparents() behaviour depends on ui trace level which
1154 # showparents() behaviour depends on ui trace level which
1155 # causes unexpected behaviours at templating level and makes
1155 # causes unexpected behaviours at templating level and makes
1156 # it harder to extract it in a standalone function. Its
1156 # it harder to extract it in a standalone function. Its
1157 # behaviour cannot be changed so leave it here for now.
1157 # behaviour cannot be changed so leave it here for now.
1158 def showparents(**args):
1158 def showparents(**args):
1159 ctx = args['ctx']
1159 ctx = args['ctx']
1160 parents = [[('rev', p.rev()),
1160 parents = [[('rev', p.rev()),
1161 ('node', p.hex()),
1161 ('node', p.hex()),
1162 ('phase', p.phasestr())]
1162 ('phase', p.phasestr())]
1163 for p in self._meaningful_parentrevs(ctx)]
1163 for p in self._meaningful_parentrevs(ctx)]
1164 return showlist('parent', parents, **args)
1164 return showlist('parent', parents, **args)
1165
1165
1166 props = props.copy()
1166 props = props.copy()
1167 props.update(templatekw.keywords)
1167 props.update(templatekw.keywords)
1168 props['parents'] = showparents
1168 props['parents'] = showparents
1169 props['templ'] = self.t
1169 props['templ'] = self.t
1170 props['ctx'] = ctx
1170 props['ctx'] = ctx
1171 props['repo'] = self.repo
1171 props['repo'] = self.repo
1172 props['revcache'] = {'copies': copies}
1172 props['revcache'] = {'copies': copies}
1173 props['cache'] = self.cache
1173 props['cache'] = self.cache
1174
1174
1175 # find correct templates for current mode
1175 # find correct templates for current mode
1176
1176
1177 tmplmodes = [
1177 tmplmodes = [
1178 (True, None),
1178 (True, None),
1179 (self.ui.verbose, 'verbose'),
1179 (self.ui.verbose, 'verbose'),
1180 (self.ui.quiet, 'quiet'),
1180 (self.ui.quiet, 'quiet'),
1181 (self.ui.debugflag, 'debug'),
1181 (self.ui.debugflag, 'debug'),
1182 ]
1182 ]
1183
1183
1184 types = {'header': '', 'footer':'', 'changeset': 'changeset'}
1184 types = {'header': '', 'footer':'', 'changeset': 'changeset'}
1185 for mode, postfix in tmplmodes:
1185 for mode, postfix in tmplmodes:
1186 for type in types:
1186 for type in types:
1187 cur = postfix and ('%s_%s' % (type, postfix)) or type
1187 cur = postfix and ('%s_%s' % (type, postfix)) or type
1188 if mode and cur in self.t:
1188 if mode and cur in self.t:
1189 types[type] = cur
1189 types[type] = cur
1190
1190
1191 try:
1191 try:
1192
1192
1193 # write header
1193 # write header
1194 if types['header']:
1194 if types['header']:
1195 h = templater.stringify(self.t(types['header'], **props))
1195 h = templater.stringify(self.t(types['header'], **props))
1196 if self.buffered:
1196 if self.buffered:
1197 self.header[ctx.rev()] = h
1197 self.header[ctx.rev()] = h
1198 else:
1198 else:
1199 if self.lastheader != h:
1199 if self.lastheader != h:
1200 self.lastheader = h
1200 self.lastheader = h
1201 self.ui.write(h)
1201 self.ui.write(h)
1202
1202
1203 # write changeset metadata, then patch if requested
1203 # write changeset metadata, then patch if requested
1204 key = types['changeset']
1204 key = types['changeset']
1205 self.ui.write(templater.stringify(self.t(key, **props)))
1205 self.ui.write(templater.stringify(self.t(key, **props)))
1206 self.showpatch(ctx.node(), matchfn)
1206 self.showpatch(ctx.node(), matchfn)
1207
1207
1208 if types['footer']:
1208 if types['footer']:
1209 if not self.footer:
1209 if not self.footer:
1210 self.footer = templater.stringify(self.t(types['footer'],
1210 self.footer = templater.stringify(self.t(types['footer'],
1211 **props))
1211 **props))
1212
1212
1213 except KeyError, inst:
1213 except KeyError, inst:
1214 msg = _("%s: no key named '%s'")
1214 msg = _("%s: no key named '%s'")
1215 raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
1215 raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
1216 except SyntaxError, inst:
1216 except SyntaxError, inst:
1217 raise util.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
1217 raise util.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
1218
1218
1219 def gettemplate(ui, tmpl, style):
1219 def gettemplate(ui, tmpl, style):
1220 """
1220 """
1221 Find the template matching the given template spec or style.
1221 Find the template matching the given template spec or style.
1222 """
1222 """
1223
1223
1224 # ui settings
1224 # ui settings
1225 if not tmpl and not style: # template are stronger than style
1225 if not tmpl and not style: # template are stronger than style
1226 tmpl = ui.config('ui', 'logtemplate')
1226 tmpl = ui.config('ui', 'logtemplate')
1227 if tmpl:
1227 if tmpl:
1228 try:
1228 try:
1229 tmpl = templater.parsestring(tmpl)
1229 tmpl = templater.parsestring(tmpl)
1230 except SyntaxError:
1230 except SyntaxError:
1231 tmpl = templater.parsestring(tmpl, quoted=False)
1231 tmpl = templater.parsestring(tmpl, quoted=False)
1232 return tmpl, None
1232 return tmpl, None
1233 else:
1233 else:
1234 style = util.expandpath(ui.config('ui', 'style', ''))
1234 style = util.expandpath(ui.config('ui', 'style', ''))
1235
1235
1236 if not tmpl and style:
1236 if not tmpl and style:
1237 mapfile = style
1237 mapfile = style
1238 if not os.path.split(mapfile)[0]:
1238 if not os.path.split(mapfile)[0]:
1239 mapname = (templater.templatepath('map-cmdline.' + mapfile)
1239 mapname = (templater.templatepath('map-cmdline.' + mapfile)
1240 or templater.templatepath(mapfile))
1240 or templater.templatepath(mapfile))
1241 if mapname:
1241 if mapname:
1242 mapfile = mapname
1242 mapfile = mapname
1243 return None, mapfile
1243 return None, mapfile
1244
1244
1245 if not tmpl:
1245 if not tmpl:
1246 return None, None
1246 return None, None
1247
1247
1248 # looks like a literal template?
1248 # looks like a literal template?
1249 if '{' in tmpl:
1249 if '{' in tmpl:
1250 return tmpl, None
1250 return tmpl, None
1251
1251
1252 # perhaps a stock style?
1252 # perhaps a stock style?
1253 if not os.path.split(tmpl)[0]:
1253 if not os.path.split(tmpl)[0]:
1254 mapname = (templater.templatepath('map-cmdline.' + tmpl)
1254 mapname = (templater.templatepath('map-cmdline.' + tmpl)
1255 or templater.templatepath(tmpl))
1255 or templater.templatepath(tmpl))
1256 if mapname and os.path.isfile(mapname):
1256 if mapname and os.path.isfile(mapname):
1257 return None, mapname
1257 return None, mapname
1258
1258
1259 # perhaps it's a reference to [templates]
1259 # perhaps it's a reference to [templates]
1260 t = ui.config('templates', tmpl)
1260 t = ui.config('templates', tmpl)
1261 if t:
1261 if t:
1262 try:
1262 try:
1263 tmpl = templater.parsestring(t)
1263 tmpl = templater.parsestring(t)
1264 except SyntaxError:
1264 except SyntaxError:
1265 tmpl = templater.parsestring(t, quoted=False)
1265 tmpl = templater.parsestring(t, quoted=False)
1266 return tmpl, None
1266 return tmpl, None
1267
1267
1268 if tmpl == 'list':
1268 if tmpl == 'list':
1269 ui.write(_("available styles: %s\n") % templater.stylelist())
1269 ui.write(_("available styles: %s\n") % templater.stylelist())
1270 raise util.Abort(_("specify a template"))
1270 raise util.Abort(_("specify a template"))
1271
1271
1272 # perhaps it's a path to a map or a template
1272 # perhaps it's a path to a map or a template
1273 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
1273 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
1274 # is it a mapfile for a style?
1274 # is it a mapfile for a style?
1275 if os.path.basename(tmpl).startswith("map-"):
1275 if os.path.basename(tmpl).startswith("map-"):
1276 return None, os.path.realpath(tmpl)
1276 return None, os.path.realpath(tmpl)
1277 tmpl = open(tmpl).read()
1277 tmpl = open(tmpl).read()
1278 return tmpl, None
1278 return tmpl, None
1279
1279
1280 # constant string?
1280 # constant string?
1281 return tmpl, None
1281 return tmpl, None
1282
1282
1283 def show_changeset(ui, repo, opts, buffered=False):
1283 def show_changeset(ui, repo, opts, buffered=False):
1284 """show one changeset using template or regular display.
1284 """show one changeset using template or regular display.
1285
1285
1286 Display format will be the first non-empty hit of:
1286 Display format will be the first non-empty hit of:
1287 1. option 'template'
1287 1. option 'template'
1288 2. option 'style'
1288 2. option 'style'
1289 3. [ui] setting 'logtemplate'
1289 3. [ui] setting 'logtemplate'
1290 4. [ui] setting 'style'
1290 4. [ui] setting 'style'
1291 If all of these values are either the unset or the empty string,
1291 If all of these values are either the unset or the empty string,
1292 regular display via changeset_printer() is done.
1292 regular display via changeset_printer() is done.
1293 """
1293 """
1294 # options
1294 # options
1295 matchfn = None
1295 matchfn = None
1296 if opts.get('patch') or opts.get('stat'):
1296 if opts.get('patch') or opts.get('stat'):
1297 matchfn = scmutil.matchall(repo)
1297 matchfn = scmutil.matchall(repo)
1298
1298
1299 if opts.get('template') == 'json':
1299 if opts.get('template') == 'json':
1300 return jsonchangeset(ui, repo, matchfn, opts, buffered)
1300 return jsonchangeset(ui, repo, matchfn, opts, buffered)
1301
1301
1302 tmpl, mapfile = gettemplate(ui, opts.get('template'), opts.get('style'))
1302 tmpl, mapfile = gettemplate(ui, opts.get('template'), opts.get('style'))
1303
1303
1304 if not tmpl and not mapfile:
1304 if not tmpl and not mapfile:
1305 return changeset_printer(ui, repo, matchfn, opts, buffered)
1305 return changeset_printer(ui, repo, matchfn, opts, buffered)
1306
1306
1307 try:
1307 try:
1308 t = changeset_templater(ui, repo, matchfn, opts, tmpl, mapfile,
1308 t = changeset_templater(ui, repo, matchfn, opts, tmpl, mapfile,
1309 buffered)
1309 buffered)
1310 except SyntaxError, inst:
1310 except SyntaxError, inst:
1311 raise util.Abort(inst.args[0])
1311 raise util.Abort(inst.args[0])
1312 return t
1312 return t
1313
1313
1314 def showmarker(ui, marker):
1314 def showmarker(ui, marker):
1315 """utility function to display obsolescence marker in a readable way
1315 """utility function to display obsolescence marker in a readable way
1316
1316
1317 To be used by debug function."""
1317 To be used by debug function."""
1318 ui.write(hex(marker.precnode()))
1318 ui.write(hex(marker.precnode()))
1319 for repl in marker.succnodes():
1319 for repl in marker.succnodes():
1320 ui.write(' ')
1320 ui.write(' ')
1321 ui.write(hex(repl))
1321 ui.write(hex(repl))
1322 ui.write(' %X ' % marker.flags())
1322 ui.write(' %X ' % marker.flags())
1323 parents = marker.parentnodes()
1323 parents = marker.parentnodes()
1324 if parents is not None:
1324 if parents is not None:
1325 ui.write('{%s} ' % ', '.join(hex(p) for p in parents))
1325 ui.write('{%s} ' % ', '.join(hex(p) for p in parents))
1326 ui.write('(%s) ' % util.datestr(marker.date()))
1326 ui.write('(%s) ' % util.datestr(marker.date()))
1327 ui.write('{%s}' % (', '.join('%r: %r' % t for t in
1327 ui.write('{%s}' % (', '.join('%r: %r' % t for t in
1328 sorted(marker.metadata().items())
1328 sorted(marker.metadata().items())
1329 if t[0] != 'date')))
1329 if t[0] != 'date')))
1330 ui.write('\n')
1330 ui.write('\n')
1331
1331
1332 def finddate(ui, repo, date):
1332 def finddate(ui, repo, date):
1333 """Find the tipmost changeset that matches the given date spec"""
1333 """Find the tipmost changeset that matches the given date spec"""
1334
1334
1335 df = util.matchdate(date)
1335 df = util.matchdate(date)
1336 m = scmutil.matchall(repo)
1336 m = scmutil.matchall(repo)
1337 results = {}
1337 results = {}
1338
1338
1339 def prep(ctx, fns):
1339 def prep(ctx, fns):
1340 d = ctx.date()
1340 d = ctx.date()
1341 if df(d[0]):
1341 if df(d[0]):
1342 results[ctx.rev()] = d
1342 results[ctx.rev()] = d
1343
1343
1344 for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
1344 for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
1345 rev = ctx.rev()
1345 rev = ctx.rev()
1346 if rev in results:
1346 if rev in results:
1347 ui.status(_("found revision %s from %s\n") %
1347 ui.status(_("found revision %s from %s\n") %
1348 (rev, util.datestr(results[rev])))
1348 (rev, util.datestr(results[rev])))
1349 return str(rev)
1349 return str(rev)
1350
1350
1351 raise util.Abort(_("revision matching date not found"))
1351 raise util.Abort(_("revision matching date not found"))
1352
1352
1353 def increasingwindows(windowsize=8, sizelimit=512):
1353 def increasingwindows(windowsize=8, sizelimit=512):
1354 while True:
1354 while True:
1355 yield windowsize
1355 yield windowsize
1356 if windowsize < sizelimit:
1356 if windowsize < sizelimit:
1357 windowsize *= 2
1357 windowsize *= 2
1358
1358
1359 class FileWalkError(Exception):
1359 class FileWalkError(Exception):
1360 pass
1360 pass
1361
1361
1362 def walkfilerevs(repo, match, follow, revs, fncache):
1362 def walkfilerevs(repo, match, follow, revs, fncache):
1363 '''Walks the file history for the matched files.
1363 '''Walks the file history for the matched files.
1364
1364
1365 Returns the changeset revs that are involved in the file history.
1365 Returns the changeset revs that are involved in the file history.
1366
1366
1367 Throws FileWalkError if the file history can't be walked using
1367 Throws FileWalkError if the file history can't be walked using
1368 filelogs alone.
1368 filelogs alone.
1369 '''
1369 '''
1370 wanted = set()
1370 wanted = set()
1371 copies = []
1371 copies = []
1372 minrev, maxrev = min(revs), max(revs)
1372 minrev, maxrev = min(revs), max(revs)
1373 def filerevgen(filelog, last):
1373 def filerevgen(filelog, last):
1374 """
1374 """
1375 Only files, no patterns. Check the history of each file.
1375 Only files, no patterns. Check the history of each file.
1376
1376
1377 Examines filelog entries within minrev, maxrev linkrev range
1377 Examines filelog entries within minrev, maxrev linkrev range
1378 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1378 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1379 tuples in backwards order
1379 tuples in backwards order
1380 """
1380 """
1381 cl_count = len(repo)
1381 cl_count = len(repo)
1382 revs = []
1382 revs = []
1383 for j in xrange(0, last + 1):
1383 for j in xrange(0, last + 1):
1384 linkrev = filelog.linkrev(j)
1384 linkrev = filelog.linkrev(j)
1385 if linkrev < minrev:
1385 if linkrev < minrev:
1386 continue
1386 continue
1387 # only yield rev for which we have the changelog, it can
1387 # only yield rev for which we have the changelog, it can
1388 # happen while doing "hg log" during a pull or commit
1388 # happen while doing "hg log" during a pull or commit
1389 if linkrev >= cl_count:
1389 if linkrev >= cl_count:
1390 break
1390 break
1391
1391
1392 parentlinkrevs = []
1392 parentlinkrevs = []
1393 for p in filelog.parentrevs(j):
1393 for p in filelog.parentrevs(j):
1394 if p != nullrev:
1394 if p != nullrev:
1395 parentlinkrevs.append(filelog.linkrev(p))
1395 parentlinkrevs.append(filelog.linkrev(p))
1396 n = filelog.node(j)
1396 n = filelog.node(j)
1397 revs.append((linkrev, parentlinkrevs,
1397 revs.append((linkrev, parentlinkrevs,
1398 follow and filelog.renamed(n)))
1398 follow and filelog.renamed(n)))
1399
1399
1400 return reversed(revs)
1400 return reversed(revs)
1401 def iterfiles():
1401 def iterfiles():
1402 pctx = repo['.']
1402 pctx = repo['.']
1403 for filename in match.files():
1403 for filename in match.files():
1404 if follow:
1404 if follow:
1405 if filename not in pctx:
1405 if filename not in pctx:
1406 raise util.Abort(_('cannot follow file not in parent '
1406 raise util.Abort(_('cannot follow file not in parent '
1407 'revision: "%s"') % filename)
1407 'revision: "%s"') % filename)
1408 yield filename, pctx[filename].filenode()
1408 yield filename, pctx[filename].filenode()
1409 else:
1409 else:
1410 yield filename, None
1410 yield filename, None
1411 for filename_node in copies:
1411 for filename_node in copies:
1412 yield filename_node
1412 yield filename_node
1413
1413
1414 for file_, node in iterfiles():
1414 for file_, node in iterfiles():
1415 filelog = repo.file(file_)
1415 filelog = repo.file(file_)
1416 if not len(filelog):
1416 if not len(filelog):
1417 if node is None:
1417 if node is None:
1418 # A zero count may be a directory or deleted file, so
1418 # A zero count may be a directory or deleted file, so
1419 # try to find matching entries on the slow path.
1419 # try to find matching entries on the slow path.
1420 if follow:
1420 if follow:
1421 raise util.Abort(
1421 raise util.Abort(
1422 _('cannot follow nonexistent file: "%s"') % file_)
1422 _('cannot follow nonexistent file: "%s"') % file_)
1423 raise FileWalkError("Cannot walk via filelog")
1423 raise FileWalkError("Cannot walk via filelog")
1424 else:
1424 else:
1425 continue
1425 continue
1426
1426
1427 if node is None:
1427 if node is None:
1428 last = len(filelog) - 1
1428 last = len(filelog) - 1
1429 else:
1429 else:
1430 last = filelog.rev(node)
1430 last = filelog.rev(node)
1431
1431
1432
1432
1433 # keep track of all ancestors of the file
1433 # keep track of all ancestors of the file
1434 ancestors = set([filelog.linkrev(last)])
1434 ancestors = set([filelog.linkrev(last)])
1435
1435
1436 # iterate from latest to oldest revision
1436 # iterate from latest to oldest revision
1437 for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
1437 for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
1438 if not follow:
1438 if not follow:
1439 if rev > maxrev:
1439 if rev > maxrev:
1440 continue
1440 continue
1441 else:
1441 else:
1442 # Note that last might not be the first interesting
1442 # Note that last might not be the first interesting
1443 # rev to us:
1443 # rev to us:
1444 # if the file has been changed after maxrev, we'll
1444 # if the file has been changed after maxrev, we'll
1445 # have linkrev(last) > maxrev, and we still need
1445 # have linkrev(last) > maxrev, and we still need
1446 # to explore the file graph
1446 # to explore the file graph
1447 if rev not in ancestors:
1447 if rev not in ancestors:
1448 continue
1448 continue
1449 # XXX insert 1327 fix here
1449 # XXX insert 1327 fix here
1450 if flparentlinkrevs:
1450 if flparentlinkrevs:
1451 ancestors.update(flparentlinkrevs)
1451 ancestors.update(flparentlinkrevs)
1452
1452
1453 fncache.setdefault(rev, []).append(file_)
1453 fncache.setdefault(rev, []).append(file_)
1454 wanted.add(rev)
1454 wanted.add(rev)
1455 if copied:
1455 if copied:
1456 copies.append(copied)
1456 copies.append(copied)
1457
1457
1458 return wanted
1458 return wanted
1459
1459
1460 def walkchangerevs(repo, match, opts, prepare):
1460 def walkchangerevs(repo, match, opts, prepare):
1461 '''Iterate over files and the revs in which they changed.
1461 '''Iterate over files and the revs in which they changed.
1462
1462
1463 Callers most commonly need to iterate backwards over the history
1463 Callers most commonly need to iterate backwards over the history
1464 in which they are interested. Doing so has awful (quadratic-looking)
1464 in which they are interested. Doing so has awful (quadratic-looking)
1465 performance, so we use iterators in a "windowed" way.
1465 performance, so we use iterators in a "windowed" way.
1466
1466
1467 We walk a window of revisions in the desired order. Within the
1467 We walk a window of revisions in the desired order. Within the
1468 window, we first walk forwards to gather data, then in the desired
1468 window, we first walk forwards to gather data, then in the desired
1469 order (usually backwards) to display it.
1469 order (usually backwards) to display it.
1470
1470
1471 This function returns an iterator yielding contexts. Before
1471 This function returns an iterator yielding contexts. Before
1472 yielding each context, the iterator will first call the prepare
1472 yielding each context, the iterator will first call the prepare
1473 function on each context in the window in forward order.'''
1473 function on each context in the window in forward order.'''
1474
1474
1475 follow = opts.get('follow') or opts.get('follow_first')
1475 follow = opts.get('follow') or opts.get('follow_first')
1476 revs = _logrevs(repo, opts)
1476 revs = _logrevs(repo, opts)
1477 if not revs:
1477 if not revs:
1478 return []
1478 return []
1479 wanted = set()
1479 wanted = set()
1480 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1480 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1481 fncache = {}
1481 fncache = {}
1482 change = repo.changectx
1482 change = repo.changectx
1483
1483
1484 # First step is to fill wanted, the set of revisions that we want to yield.
1484 # First step is to fill wanted, the set of revisions that we want to yield.
1485 # When it does not induce extra cost, we also fill fncache for revisions in
1485 # When it does not induce extra cost, we also fill fncache for revisions in
1486 # wanted: a cache of filenames that were changed (ctx.files()) and that
1486 # wanted: a cache of filenames that were changed (ctx.files()) and that
1487 # match the file filtering conditions.
1487 # match the file filtering conditions.
1488
1488
1489 if not slowpath and not match.files():
1489 if not slowpath and not match.files():
1490 # No files, no patterns. Display all revs.
1490 # No files, no patterns. Display all revs.
1491 wanted = revs
1491 wanted = revs
1492
1492
1493 if not slowpath and match.files():
1493 if not slowpath and match.files():
1494 # We only have to read through the filelog to find wanted revisions
1494 # We only have to read through the filelog to find wanted revisions
1495
1495
1496 try:
1496 try:
1497 wanted = walkfilerevs(repo, match, follow, revs, fncache)
1497 wanted = walkfilerevs(repo, match, follow, revs, fncache)
1498 except FileWalkError:
1498 except FileWalkError:
1499 slowpath = True
1499 slowpath = True
1500
1500
1501 # We decided to fall back to the slowpath because at least one
1501 # We decided to fall back to the slowpath because at least one
1502 # of the paths was not a file. Check to see if at least one of them
1502 # of the paths was not a file. Check to see if at least one of them
1503 # existed in history, otherwise simply return
1503 # existed in history, otherwise simply return
1504 for path in match.files():
1504 for path in match.files():
1505 if path == '.' or path in repo.store:
1505 if path == '.' or path in repo.store:
1506 break
1506 break
1507 else:
1507 else:
1508 return []
1508 return []
1509
1509
1510 if slowpath:
1510 if slowpath:
1511 # We have to read the changelog to match filenames against
1511 # We have to read the changelog to match filenames against
1512 # changed files
1512 # changed files
1513
1513
1514 if follow:
1514 if follow:
1515 raise util.Abort(_('can only follow copies/renames for explicit '
1515 raise util.Abort(_('can only follow copies/renames for explicit '
1516 'filenames'))
1516 'filenames'))
1517
1517
1518 # The slow path checks files modified in every changeset.
1518 # The slow path checks files modified in every changeset.
1519 # This is really slow on large repos, so compute the set lazily.
1519 # This is really slow on large repos, so compute the set lazily.
1520 class lazywantedset(object):
1520 class lazywantedset(object):
1521 def __init__(self):
1521 def __init__(self):
1522 self.set = set()
1522 self.set = set()
1523 self.revs = set(revs)
1523 self.revs = set(revs)
1524
1524
1525 # No need to worry about locality here because it will be accessed
1525 # No need to worry about locality here because it will be accessed
1526 # in the same order as the increasing window below.
1526 # in the same order as the increasing window below.
1527 def __contains__(self, value):
1527 def __contains__(self, value):
1528 if value in self.set:
1528 if value in self.set:
1529 return True
1529 return True
1530 elif not value in self.revs:
1530 elif not value in self.revs:
1531 return False
1531 return False
1532 else:
1532 else:
1533 self.revs.discard(value)
1533 self.revs.discard(value)
1534 ctx = change(value)
1534 ctx = change(value)
1535 matches = filter(match, ctx.files())
1535 matches = filter(match, ctx.files())
1536 if matches:
1536 if matches:
1537 fncache[value] = matches
1537 fncache[value] = matches
1538 self.set.add(value)
1538 self.set.add(value)
1539 return True
1539 return True
1540 return False
1540 return False
1541
1541
1542 def discard(self, value):
1542 def discard(self, value):
1543 self.revs.discard(value)
1543 self.revs.discard(value)
1544 self.set.discard(value)
1544 self.set.discard(value)
1545
1545
1546 wanted = lazywantedset()
1546 wanted = lazywantedset()
1547
1547
1548 class followfilter(object):
1548 class followfilter(object):
1549 def __init__(self, onlyfirst=False):
1549 def __init__(self, onlyfirst=False):
1550 self.startrev = nullrev
1550 self.startrev = nullrev
1551 self.roots = set()
1551 self.roots = set()
1552 self.onlyfirst = onlyfirst
1552 self.onlyfirst = onlyfirst
1553
1553
1554 def match(self, rev):
1554 def match(self, rev):
1555 def realparents(rev):
1555 def realparents(rev):
1556 if self.onlyfirst:
1556 if self.onlyfirst:
1557 return repo.changelog.parentrevs(rev)[0:1]
1557 return repo.changelog.parentrevs(rev)[0:1]
1558 else:
1558 else:
1559 return filter(lambda x: x != nullrev,
1559 return filter(lambda x: x != nullrev,
1560 repo.changelog.parentrevs(rev))
1560 repo.changelog.parentrevs(rev))
1561
1561
1562 if self.startrev == nullrev:
1562 if self.startrev == nullrev:
1563 self.startrev = rev
1563 self.startrev = rev
1564 return True
1564 return True
1565
1565
1566 if rev > self.startrev:
1566 if rev > self.startrev:
1567 # forward: all descendants
1567 # forward: all descendants
1568 if not self.roots:
1568 if not self.roots:
1569 self.roots.add(self.startrev)
1569 self.roots.add(self.startrev)
1570 for parent in realparents(rev):
1570 for parent in realparents(rev):
1571 if parent in self.roots:
1571 if parent in self.roots:
1572 self.roots.add(rev)
1572 self.roots.add(rev)
1573 return True
1573 return True
1574 else:
1574 else:
1575 # backwards: all parents
1575 # backwards: all parents
1576 if not self.roots:
1576 if not self.roots:
1577 self.roots.update(realparents(self.startrev))
1577 self.roots.update(realparents(self.startrev))
1578 if rev in self.roots:
1578 if rev in self.roots:
1579 self.roots.remove(rev)
1579 self.roots.remove(rev)
1580 self.roots.update(realparents(rev))
1580 self.roots.update(realparents(rev))
1581 return True
1581 return True
1582
1582
1583 return False
1583 return False
1584
1584
1585 # it might be worthwhile to do this in the iterator if the rev range
1585 # it might be worthwhile to do this in the iterator if the rev range
1586 # is descending and the prune args are all within that range
1586 # is descending and the prune args are all within that range
1587 for rev in opts.get('prune', ()):
1587 for rev in opts.get('prune', ()):
1588 rev = repo[rev].rev()
1588 rev = repo[rev].rev()
1589 ff = followfilter()
1589 ff = followfilter()
1590 stop = min(revs[0], revs[-1])
1590 stop = min(revs[0], revs[-1])
1591 for x in xrange(rev, stop - 1, -1):
1591 for x in xrange(rev, stop - 1, -1):
1592 if ff.match(x):
1592 if ff.match(x):
1593 wanted = wanted - [x]
1593 wanted = wanted - [x]
1594
1594
1595 # Now that wanted is correctly initialized, we can iterate over the
1595 # Now that wanted is correctly initialized, we can iterate over the
1596 # revision range, yielding only revisions in wanted.
1596 # revision range, yielding only revisions in wanted.
1597 def iterate():
1597 def iterate():
1598 if follow and not match.files():
1598 if follow and not match.files():
1599 ff = followfilter(onlyfirst=opts.get('follow_first'))
1599 ff = followfilter(onlyfirst=opts.get('follow_first'))
1600 def want(rev):
1600 def want(rev):
1601 return ff.match(rev) and rev in wanted
1601 return ff.match(rev) and rev in wanted
1602 else:
1602 else:
1603 def want(rev):
1603 def want(rev):
1604 return rev in wanted
1604 return rev in wanted
1605
1605
1606 it = iter(revs)
1606 it = iter(revs)
1607 stopiteration = False
1607 stopiteration = False
1608 for windowsize in increasingwindows():
1608 for windowsize in increasingwindows():
1609 nrevs = []
1609 nrevs = []
1610 for i in xrange(windowsize):
1610 for i in xrange(windowsize):
1611 try:
1611 try:
1612 rev = it.next()
1612 rev = it.next()
1613 if want(rev):
1613 if want(rev):
1614 nrevs.append(rev)
1614 nrevs.append(rev)
1615 except (StopIteration):
1615 except (StopIteration):
1616 stopiteration = True
1616 stopiteration = True
1617 break
1617 break
1618 for rev in sorted(nrevs):
1618 for rev in sorted(nrevs):
1619 fns = fncache.get(rev)
1619 fns = fncache.get(rev)
1620 ctx = change(rev)
1620 ctx = change(rev)
1621 if not fns:
1621 if not fns:
1622 def fns_generator():
1622 def fns_generator():
1623 for f in ctx.files():
1623 for f in ctx.files():
1624 if match(f):
1624 if match(f):
1625 yield f
1625 yield f
1626 fns = fns_generator()
1626 fns = fns_generator()
1627 prepare(ctx, fns)
1627 prepare(ctx, fns)
1628 for rev in nrevs:
1628 for rev in nrevs:
1629 yield change(rev)
1629 yield change(rev)
1630
1630
1631 if stopiteration:
1631 if stopiteration:
1632 break
1632 break
1633
1633
1634 return iterate()
1634 return iterate()
1635
1635
1636 def _makefollowlogfilematcher(repo, files, followfirst):
1636 def _makefollowlogfilematcher(repo, files, followfirst):
1637 # When displaying a revision with --patch --follow FILE, we have
1637 # When displaying a revision with --patch --follow FILE, we have
1638 # to know which file of the revision must be diffed. With
1638 # to know which file of the revision must be diffed. With
1639 # --follow, we want the names of the ancestors of FILE in the
1639 # --follow, we want the names of the ancestors of FILE in the
1640 # revision, stored in "fcache". "fcache" is populated by
1640 # revision, stored in "fcache". "fcache" is populated by
1641 # reproducing the graph traversal already done by --follow revset
1641 # reproducing the graph traversal already done by --follow revset
1642 # and relating linkrevs to file names (which is not "correct" but
1642 # and relating linkrevs to file names (which is not "correct" but
1643 # good enough).
1643 # good enough).
1644 fcache = {}
1644 fcache = {}
1645 fcacheready = [False]
1645 fcacheready = [False]
1646 pctx = repo['.']
1646 pctx = repo['.']
1647
1647
1648 def populate():
1648 def populate():
1649 for fn in files:
1649 for fn in files:
1650 for i in ((pctx[fn],), pctx[fn].ancestors(followfirst=followfirst)):
1650 for i in ((pctx[fn],), pctx[fn].ancestors(followfirst=followfirst)):
1651 for c in i:
1651 for c in i:
1652 fcache.setdefault(c.linkrev(), set()).add(c.path())
1652 fcache.setdefault(c.linkrev(), set()).add(c.path())
1653
1653
1654 def filematcher(rev):
1654 def filematcher(rev):
1655 if not fcacheready[0]:
1655 if not fcacheready[0]:
1656 # Lazy initialization
1656 # Lazy initialization
1657 fcacheready[0] = True
1657 fcacheready[0] = True
1658 populate()
1658 populate()
1659 return scmutil.matchfiles(repo, fcache.get(rev, []))
1659 return scmutil.matchfiles(repo, fcache.get(rev, []))
1660
1660
1661 return filematcher
1661 return filematcher
1662
1662
1663 def _makenofollowlogfilematcher(repo, pats, opts):
1663 def _makenofollowlogfilematcher(repo, pats, opts):
1664 '''hook for extensions to override the filematcher for non-follow cases'''
1664 '''hook for extensions to override the filematcher for non-follow cases'''
1665 return None
1665 return None
1666
1666
1667 def _makelogrevset(repo, pats, opts, revs):
1667 def _makelogrevset(repo, pats, opts, revs):
1668 """Return (expr, filematcher) where expr is a revset string built
1668 """Return (expr, filematcher) where expr is a revset string built
1669 from log options and file patterns or None. If --stat or --patch
1669 from log options and file patterns or None. If --stat or --patch
1670 are not passed filematcher is None. Otherwise it is a callable
1670 are not passed filematcher is None. Otherwise it is a callable
1671 taking a revision number and returning a match objects filtering
1671 taking a revision number and returning a match objects filtering
1672 the files to be detailed when displaying the revision.
1672 the files to be detailed when displaying the revision.
1673 """
1673 """
1674 opt2revset = {
1674 opt2revset = {
1675 'no_merges': ('not merge()', None),
1675 'no_merges': ('not merge()', None),
1676 'only_merges': ('merge()', None),
1676 'only_merges': ('merge()', None),
1677 '_ancestors': ('ancestors(%(val)s)', None),
1677 '_ancestors': ('ancestors(%(val)s)', None),
1678 '_fancestors': ('_firstancestors(%(val)s)', None),
1678 '_fancestors': ('_firstancestors(%(val)s)', None),
1679 '_descendants': ('descendants(%(val)s)', None),
1679 '_descendants': ('descendants(%(val)s)', None),
1680 '_fdescendants': ('_firstdescendants(%(val)s)', None),
1680 '_fdescendants': ('_firstdescendants(%(val)s)', None),
1681 '_matchfiles': ('_matchfiles(%(val)s)', None),
1681 '_matchfiles': ('_matchfiles(%(val)s)', None),
1682 'date': ('date(%(val)r)', None),
1682 'date': ('date(%(val)r)', None),
1683 'branch': ('branch(%(val)r)', ' or '),
1683 'branch': ('branch(%(val)r)', ' or '),
1684 '_patslog': ('filelog(%(val)r)', ' or '),
1684 '_patslog': ('filelog(%(val)r)', ' or '),
1685 '_patsfollow': ('follow(%(val)r)', ' or '),
1685 '_patsfollow': ('follow(%(val)r)', ' or '),
1686 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
1686 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
1687 'keyword': ('keyword(%(val)r)', ' or '),
1687 'keyword': ('keyword(%(val)r)', ' or '),
1688 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
1688 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
1689 'user': ('user(%(val)r)', ' or '),
1689 'user': ('user(%(val)r)', ' or '),
1690 }
1690 }
1691
1691
1692 opts = dict(opts)
1692 opts = dict(opts)
1693 # follow or not follow?
1693 # follow or not follow?
1694 follow = opts.get('follow') or opts.get('follow_first')
1694 follow = opts.get('follow') or opts.get('follow_first')
1695 followfirst = opts.get('follow_first') and 1 or 0
1695 followfirst = opts.get('follow_first') and 1 or 0
1696 # --follow with FILE behaviour depends on revs...
1696 # --follow with FILE behaviour depends on revs...
1697 it = iter(revs)
1697 it = iter(revs)
1698 startrev = it.next()
1698 startrev = it.next()
1699 try:
1699 try:
1700 followdescendants = startrev < it.next()
1700 followdescendants = startrev < it.next()
1701 except (StopIteration):
1701 except (StopIteration):
1702 followdescendants = False
1702 followdescendants = False
1703
1703
1704 # branch and only_branch are really aliases and must be handled at
1704 # branch and only_branch are really aliases and must be handled at
1705 # the same time
1705 # the same time
1706 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', [])
1706 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', [])
1707 opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']]
1707 opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']]
1708 # pats/include/exclude are passed to match.match() directly in
1708 # pats/include/exclude are passed to match.match() directly in
1709 # _matchfiles() revset but walkchangerevs() builds its matcher with
1709 # _matchfiles() revset but walkchangerevs() builds its matcher with
1710 # scmutil.match(). The difference is input pats are globbed on
1710 # scmutil.match(). The difference is input pats are globbed on
1711 # platforms without shell expansion (windows).
1711 # platforms without shell expansion (windows).
1712 pctx = repo[None]
1712 pctx = repo[None]
1713 match, pats = scmutil.matchandpats(pctx, pats, opts)
1713 match, pats = scmutil.matchandpats(pctx, pats, opts)
1714 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1714 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1715 if not slowpath:
1715 if not slowpath:
1716 for f in match.files():
1716 for f in match.files():
1717 if follow and f not in pctx:
1717 if follow and f not in pctx:
1718 # If the file exists, it may be a directory, so let it
1718 # If the file exists, it may be a directory, so let it
1719 # take the slow path.
1719 # take the slow path.
1720 if os.path.exists(repo.wjoin(f)):
1720 if os.path.exists(repo.wjoin(f)):
1721 slowpath = True
1721 slowpath = True
1722 continue
1722 continue
1723 else:
1723 else:
1724 raise util.Abort(_('cannot follow file not in parent '
1724 raise util.Abort(_('cannot follow file not in parent '
1725 'revision: "%s"') % f)
1725 'revision: "%s"') % f)
1726 filelog = repo.file(f)
1726 filelog = repo.file(f)
1727 if not filelog:
1727 if not filelog:
1728 # A zero count may be a directory or deleted file, so
1728 # A zero count may be a directory or deleted file, so
1729 # try to find matching entries on the slow path.
1729 # try to find matching entries on the slow path.
1730 if follow:
1730 if follow:
1731 raise util.Abort(
1731 raise util.Abort(
1732 _('cannot follow nonexistent file: "%s"') % f)
1732 _('cannot follow nonexistent file: "%s"') % f)
1733 slowpath = True
1733 slowpath = True
1734
1734
1735 # We decided to fall back to the slowpath because at least one
1735 # We decided to fall back to the slowpath because at least one
1736 # of the paths was not a file. Check to see if at least one of them
1736 # of the paths was not a file. Check to see if at least one of them
1737 # existed in history - in that case, we'll continue down the
1737 # existed in history - in that case, we'll continue down the
1738 # slowpath; otherwise, we can turn off the slowpath
1738 # slowpath; otherwise, we can turn off the slowpath
1739 if slowpath:
1739 if slowpath:
1740 for path in match.files():
1740 for path in match.files():
1741 if path == '.' or path in repo.store:
1741 if path == '.' or path in repo.store:
1742 break
1742 break
1743 else:
1743 else:
1744 slowpath = False
1744 slowpath = False
1745
1745
1746 fpats = ('_patsfollow', '_patsfollowfirst')
1746 fpats = ('_patsfollow', '_patsfollowfirst')
1747 fnopats = (('_ancestors', '_fancestors'),
1747 fnopats = (('_ancestors', '_fancestors'),
1748 ('_descendants', '_fdescendants'))
1748 ('_descendants', '_fdescendants'))
1749 if slowpath:
1749 if slowpath:
1750 # See walkchangerevs() slow path.
1750 # See walkchangerevs() slow path.
1751 #
1751 #
1752 # pats/include/exclude cannot be represented as separate
1752 # pats/include/exclude cannot be represented as separate
1753 # revset expressions as their filtering logic applies at file
1753 # revset expressions as their filtering logic applies at file
1754 # level. For instance "-I a -X a" matches a revision touching
1754 # level. For instance "-I a -X a" matches a revision touching
1755 # "a" and "b" while "file(a) and not file(b)" does
1755 # "a" and "b" while "file(a) and not file(b)" does
1756 # not. Besides, filesets are evaluated against the working
1756 # not. Besides, filesets are evaluated against the working
1757 # directory.
1757 # directory.
1758 matchargs = ['r:', 'd:relpath']
1758 matchargs = ['r:', 'd:relpath']
1759 for p in pats:
1759 for p in pats:
1760 matchargs.append('p:' + p)
1760 matchargs.append('p:' + p)
1761 for p in opts.get('include', []):
1761 for p in opts.get('include', []):
1762 matchargs.append('i:' + p)
1762 matchargs.append('i:' + p)
1763 for p in opts.get('exclude', []):
1763 for p in opts.get('exclude', []):
1764 matchargs.append('x:' + p)
1764 matchargs.append('x:' + p)
1765 matchargs = ','.join(('%r' % p) for p in matchargs)
1765 matchargs = ','.join(('%r' % p) for p in matchargs)
1766 opts['_matchfiles'] = matchargs
1766 opts['_matchfiles'] = matchargs
1767 if follow:
1767 if follow:
1768 opts[fnopats[0][followfirst]] = '.'
1768 opts[fnopats[0][followfirst]] = '.'
1769 else:
1769 else:
1770 if follow:
1770 if follow:
1771 if pats:
1771 if pats:
1772 # follow() revset interprets its file argument as a
1772 # follow() revset interprets its file argument as a
1773 # manifest entry, so use match.files(), not pats.
1773 # manifest entry, so use match.files(), not pats.
1774 opts[fpats[followfirst]] = list(match.files())
1774 opts[fpats[followfirst]] = list(match.files())
1775 else:
1775 else:
1776 op = fnopats[followdescendants][followfirst]
1776 op = fnopats[followdescendants][followfirst]
1777 opts[op] = 'rev(%d)' % startrev
1777 opts[op] = 'rev(%d)' % startrev
1778 else:
1778 else:
1779 opts['_patslog'] = list(pats)
1779 opts['_patslog'] = list(pats)
1780
1780
1781 filematcher = None
1781 filematcher = None
1782 if opts.get('patch') or opts.get('stat'):
1782 if opts.get('patch') or opts.get('stat'):
1783 # When following files, track renames via a special matcher.
1783 # When following files, track renames via a special matcher.
1784 # If we're forced to take the slowpath it means we're following
1784 # If we're forced to take the slowpath it means we're following
1785 # at least one pattern/directory, so don't bother with rename tracking.
1785 # at least one pattern/directory, so don't bother with rename tracking.
1786 if follow and not match.always() and not slowpath:
1786 if follow and not match.always() and not slowpath:
1787 # _makefollowlogfilematcher expects its files argument to be
1787 # _makefollowlogfilematcher expects its files argument to be
1788 # relative to the repo root, so use match.files(), not pats.
1788 # relative to the repo root, so use match.files(), not pats.
1789 filematcher = _makefollowlogfilematcher(repo, match.files(),
1789 filematcher = _makefollowlogfilematcher(repo, match.files(),
1790 followfirst)
1790 followfirst)
1791 else:
1791 else:
1792 filematcher = _makenofollowlogfilematcher(repo, pats, opts)
1792 filematcher = _makenofollowlogfilematcher(repo, pats, opts)
1793 if filematcher is None:
1793 if filematcher is None:
1794 filematcher = lambda rev: match
1794 filematcher = lambda rev: match
1795
1795
1796 expr = []
1796 expr = []
1797 for op, val in sorted(opts.iteritems()):
1797 for op, val in sorted(opts.iteritems()):
1798 if not val:
1798 if not val:
1799 continue
1799 continue
1800 if op not in opt2revset:
1800 if op not in opt2revset:
1801 continue
1801 continue
1802 revop, andor = opt2revset[op]
1802 revop, andor = opt2revset[op]
1803 if '%(val)' not in revop:
1803 if '%(val)' not in revop:
1804 expr.append(revop)
1804 expr.append(revop)
1805 else:
1805 else:
1806 if not isinstance(val, list):
1806 if not isinstance(val, list):
1807 e = revop % {'val': val}
1807 e = revop % {'val': val}
1808 else:
1808 else:
1809 e = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
1809 e = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
1810 expr.append(e)
1810 expr.append(e)
1811
1811
1812 if expr:
1812 if expr:
1813 expr = '(' + ' and '.join(expr) + ')'
1813 expr = '(' + ' and '.join(expr) + ')'
1814 else:
1814 else:
1815 expr = None
1815 expr = None
1816 return expr, filematcher
1816 return expr, filematcher
1817
1817
1818 def _logrevs(repo, opts):
1818 def _logrevs(repo, opts):
1819 # Default --rev value depends on --follow but --follow behaviour
1819 # Default --rev value depends on --follow but --follow behaviour
1820 # depends on revisions resolved from --rev...
1820 # depends on revisions resolved from --rev...
1821 follow = opts.get('follow') or opts.get('follow_first')
1821 follow = opts.get('follow') or opts.get('follow_first')
1822 if opts.get('rev'):
1822 if opts.get('rev'):
1823 revs = scmutil.revrange(repo, opts['rev'])
1823 revs = scmutil.revrange(repo, opts['rev'])
1824 elif follow and repo.dirstate.p1() == nullid:
1825 revs = revset.baseset()
1824 elif follow:
1826 elif follow:
1825 revs = repo.revs('reverse(:.)')
1827 revs = repo.revs('reverse(:.)')
1826 else:
1828 else:
1827 revs = revset.spanset(repo)
1829 revs = revset.spanset(repo)
1828 revs.reverse()
1830 revs.reverse()
1829 return revs
1831 return revs
1830
1832
1831 def getgraphlogrevs(repo, pats, opts):
1833 def getgraphlogrevs(repo, pats, opts):
1832 """Return (revs, expr, filematcher) where revs is an iterable of
1834 """Return (revs, expr, filematcher) where revs is an iterable of
1833 revision numbers, expr is a revset string built from log options
1835 revision numbers, expr is a revset string built from log options
1834 and file patterns or None, and used to filter 'revs'. If --stat or
1836 and file patterns or None, and used to filter 'revs'. If --stat or
1835 --patch are not passed filematcher is None. Otherwise it is a
1837 --patch are not passed filematcher is None. Otherwise it is a
1836 callable taking a revision number and returning a match objects
1838 callable taking a revision number and returning a match objects
1837 filtering the files to be detailed when displaying the revision.
1839 filtering the files to be detailed when displaying the revision.
1838 """
1840 """
1839 limit = loglimit(opts)
1841 limit = loglimit(opts)
1840 revs = _logrevs(repo, opts)
1842 revs = _logrevs(repo, opts)
1841 if not revs:
1843 if not revs:
1842 return revset.baseset(), None, None
1844 return revset.baseset(), None, None
1843 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1845 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1844 if opts.get('rev'):
1846 if opts.get('rev'):
1845 # User-specified revs might be unsorted, but don't sort before
1847 # User-specified revs might be unsorted, but don't sort before
1846 # _makelogrevset because it might depend on the order of revs
1848 # _makelogrevset because it might depend on the order of revs
1847 revs.sort(reverse=True)
1849 revs.sort(reverse=True)
1848 if expr:
1850 if expr:
1849 # Revset matchers often operate faster on revisions in changelog
1851 # Revset matchers often operate faster on revisions in changelog
1850 # order, because most filters deal with the changelog.
1852 # order, because most filters deal with the changelog.
1851 revs.reverse()
1853 revs.reverse()
1852 matcher = revset.match(repo.ui, expr)
1854 matcher = revset.match(repo.ui, expr)
1853 # Revset matches can reorder revisions. "A or B" typically returns
1855 # Revset matches can reorder revisions. "A or B" typically returns
1854 # returns the revision matching A then the revision matching B. Sort
1856 # returns the revision matching A then the revision matching B. Sort
1855 # again to fix that.
1857 # again to fix that.
1856 revs = matcher(repo, revs)
1858 revs = matcher(repo, revs)
1857 revs.sort(reverse=True)
1859 revs.sort(reverse=True)
1858 if limit is not None:
1860 if limit is not None:
1859 limitedrevs = []
1861 limitedrevs = []
1860 for idx, rev in enumerate(revs):
1862 for idx, rev in enumerate(revs):
1861 if idx >= limit:
1863 if idx >= limit:
1862 break
1864 break
1863 limitedrevs.append(rev)
1865 limitedrevs.append(rev)
1864 revs = revset.baseset(limitedrevs)
1866 revs = revset.baseset(limitedrevs)
1865
1867
1866 return revs, expr, filematcher
1868 return revs, expr, filematcher
1867
1869
1868 def getlogrevs(repo, pats, opts):
1870 def getlogrevs(repo, pats, opts):
1869 """Return (revs, expr, filematcher) where revs is an iterable of
1871 """Return (revs, expr, filematcher) where revs is an iterable of
1870 revision numbers, expr is a revset string built from log options
1872 revision numbers, expr is a revset string built from log options
1871 and file patterns or None, and used to filter 'revs'. If --stat or
1873 and file patterns or None, and used to filter 'revs'. If --stat or
1872 --patch are not passed filematcher is None. Otherwise it is a
1874 --patch are not passed filematcher is None. Otherwise it is a
1873 callable taking a revision number and returning a match objects
1875 callable taking a revision number and returning a match objects
1874 filtering the files to be detailed when displaying the revision.
1876 filtering the files to be detailed when displaying the revision.
1875 """
1877 """
1876 limit = loglimit(opts)
1878 limit = loglimit(opts)
1877 revs = _logrevs(repo, opts)
1879 revs = _logrevs(repo, opts)
1878 if not revs:
1880 if not revs:
1879 return revset.baseset([]), None, None
1881 return revset.baseset([]), None, None
1880 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1882 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1881 if expr:
1883 if expr:
1882 # Revset matchers often operate faster on revisions in changelog
1884 # Revset matchers often operate faster on revisions in changelog
1883 # order, because most filters deal with the changelog.
1885 # order, because most filters deal with the changelog.
1884 if not opts.get('rev'):
1886 if not opts.get('rev'):
1885 revs.reverse()
1887 revs.reverse()
1886 matcher = revset.match(repo.ui, expr)
1888 matcher = revset.match(repo.ui, expr)
1887 # Revset matches can reorder revisions. "A or B" typically returns
1889 # Revset matches can reorder revisions. "A or B" typically returns
1888 # returns the revision matching A then the revision matching B. Sort
1890 # returns the revision matching A then the revision matching B. Sort
1889 # again to fix that.
1891 # again to fix that.
1890 revs = matcher(repo, revs)
1892 revs = matcher(repo, revs)
1891 if not opts.get('rev'):
1893 if not opts.get('rev'):
1892 revs.sort(reverse=True)
1894 revs.sort(reverse=True)
1893 if limit is not None:
1895 if limit is not None:
1894 count = 0
1896 count = 0
1895 limitedrevs = []
1897 limitedrevs = []
1896 it = iter(revs)
1898 it = iter(revs)
1897 while count < limit:
1899 while count < limit:
1898 try:
1900 try:
1899 limitedrevs.append(it.next())
1901 limitedrevs.append(it.next())
1900 except (StopIteration):
1902 except (StopIteration):
1901 break
1903 break
1902 count += 1
1904 count += 1
1903 revs = revset.baseset(limitedrevs)
1905 revs = revset.baseset(limitedrevs)
1904
1906
1905 return revs, expr, filematcher
1907 return revs, expr, filematcher
1906
1908
1907 def displaygraph(ui, dag, displayer, showparents, edgefn, getrenamed=None,
1909 def displaygraph(ui, dag, displayer, showparents, edgefn, getrenamed=None,
1908 filematcher=None):
1910 filematcher=None):
1909 seen, state = [], graphmod.asciistate()
1911 seen, state = [], graphmod.asciistate()
1910 for rev, type, ctx, parents in dag:
1912 for rev, type, ctx, parents in dag:
1911 char = 'o'
1913 char = 'o'
1912 if ctx.node() in showparents:
1914 if ctx.node() in showparents:
1913 char = '@'
1915 char = '@'
1914 elif ctx.obsolete():
1916 elif ctx.obsolete():
1915 char = 'x'
1917 char = 'x'
1916 copies = None
1918 copies = None
1917 if getrenamed and ctx.rev():
1919 if getrenamed and ctx.rev():
1918 copies = []
1920 copies = []
1919 for fn in ctx.files():
1921 for fn in ctx.files():
1920 rename = getrenamed(fn, ctx.rev())
1922 rename = getrenamed(fn, ctx.rev())
1921 if rename:
1923 if rename:
1922 copies.append((fn, rename[0]))
1924 copies.append((fn, rename[0]))
1923 revmatchfn = None
1925 revmatchfn = None
1924 if filematcher is not None:
1926 if filematcher is not None:
1925 revmatchfn = filematcher(ctx.rev())
1927 revmatchfn = filematcher(ctx.rev())
1926 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
1928 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
1927 lines = displayer.hunk.pop(rev).split('\n')
1929 lines = displayer.hunk.pop(rev).split('\n')
1928 if not lines[-1]:
1930 if not lines[-1]:
1929 del lines[-1]
1931 del lines[-1]
1930 displayer.flush(rev)
1932 displayer.flush(rev)
1931 edges = edgefn(type, char, lines, seen, rev, parents)
1933 edges = edgefn(type, char, lines, seen, rev, parents)
1932 for type, char, lines, coldata in edges:
1934 for type, char, lines, coldata in edges:
1933 graphmod.ascii(ui, state, type, char, lines, coldata)
1935 graphmod.ascii(ui, state, type, char, lines, coldata)
1934 displayer.close()
1936 displayer.close()
1935
1937
1936 def graphlog(ui, repo, *pats, **opts):
1938 def graphlog(ui, repo, *pats, **opts):
1937 # Parameters are identical to log command ones
1939 # Parameters are identical to log command ones
1938 revs, expr, filematcher = getgraphlogrevs(repo, pats, opts)
1940 revs, expr, filematcher = getgraphlogrevs(repo, pats, opts)
1939 revdag = graphmod.dagwalker(repo, revs)
1941 revdag = graphmod.dagwalker(repo, revs)
1940
1942
1941 getrenamed = None
1943 getrenamed = None
1942 if opts.get('copies'):
1944 if opts.get('copies'):
1943 endrev = None
1945 endrev = None
1944 if opts.get('rev'):
1946 if opts.get('rev'):
1945 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
1947 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
1946 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
1948 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
1947 displayer = show_changeset(ui, repo, opts, buffered=True)
1949 displayer = show_changeset(ui, repo, opts, buffered=True)
1948 showparents = [ctx.node() for ctx in repo[None].parents()]
1950 showparents = [ctx.node() for ctx in repo[None].parents()]
1949 displaygraph(ui, revdag, displayer, showparents,
1951 displaygraph(ui, revdag, displayer, showparents,
1950 graphmod.asciiedges, getrenamed, filematcher)
1952 graphmod.asciiedges, getrenamed, filematcher)
1951
1953
1952 def checkunsupportedgraphflags(pats, opts):
1954 def checkunsupportedgraphflags(pats, opts):
1953 for op in ["newest_first"]:
1955 for op in ["newest_first"]:
1954 if op in opts and opts[op]:
1956 if op in opts and opts[op]:
1955 raise util.Abort(_("-G/--graph option is incompatible with --%s")
1957 raise util.Abort(_("-G/--graph option is incompatible with --%s")
1956 % op.replace("_", "-"))
1958 % op.replace("_", "-"))
1957
1959
1958 def graphrevs(repo, nodes, opts):
1960 def graphrevs(repo, nodes, opts):
1959 limit = loglimit(opts)
1961 limit = loglimit(opts)
1960 nodes.reverse()
1962 nodes.reverse()
1961 if limit is not None:
1963 if limit is not None:
1962 nodes = nodes[:limit]
1964 nodes = nodes[:limit]
1963 return graphmod.nodes(repo, nodes)
1965 return graphmod.nodes(repo, nodes)
1964
1966
1965 def add(ui, repo, match, prefix, explicitonly, **opts):
1967 def add(ui, repo, match, prefix, explicitonly, **opts):
1966 join = lambda f: os.path.join(prefix, f)
1968 join = lambda f: os.path.join(prefix, f)
1967 bad = []
1969 bad = []
1968 oldbad = match.bad
1970 oldbad = match.bad
1969 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1971 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1970 names = []
1972 names = []
1971 wctx = repo[None]
1973 wctx = repo[None]
1972 cca = None
1974 cca = None
1973 abort, warn = scmutil.checkportabilityalert(ui)
1975 abort, warn = scmutil.checkportabilityalert(ui)
1974 if abort or warn:
1976 if abort or warn:
1975 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
1977 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
1976 for f in wctx.walk(match):
1978 for f in wctx.walk(match):
1977 exact = match.exact(f)
1979 exact = match.exact(f)
1978 if exact or not explicitonly and f not in wctx and repo.wvfs.lexists(f):
1980 if exact or not explicitonly and f not in wctx and repo.wvfs.lexists(f):
1979 if cca:
1981 if cca:
1980 cca(f)
1982 cca(f)
1981 names.append(f)
1983 names.append(f)
1982 if ui.verbose or not exact:
1984 if ui.verbose or not exact:
1983 ui.status(_('adding %s\n') % match.rel(f))
1985 ui.status(_('adding %s\n') % match.rel(f))
1984
1986
1985 for subpath in sorted(wctx.substate):
1987 for subpath in sorted(wctx.substate):
1986 sub = wctx.sub(subpath)
1988 sub = wctx.sub(subpath)
1987 try:
1989 try:
1988 submatch = matchmod.narrowmatcher(subpath, match)
1990 submatch = matchmod.narrowmatcher(subpath, match)
1989 if opts.get('subrepos'):
1991 if opts.get('subrepos'):
1990 bad.extend(sub.add(ui, submatch, prefix, False, **opts))
1992 bad.extend(sub.add(ui, submatch, prefix, False, **opts))
1991 else:
1993 else:
1992 bad.extend(sub.add(ui, submatch, prefix, True, **opts))
1994 bad.extend(sub.add(ui, submatch, prefix, True, **opts))
1993 except error.LookupError:
1995 except error.LookupError:
1994 ui.status(_("skipping missing subrepository: %s\n")
1996 ui.status(_("skipping missing subrepository: %s\n")
1995 % join(subpath))
1997 % join(subpath))
1996
1998
1997 if not opts.get('dry_run'):
1999 if not opts.get('dry_run'):
1998 rejected = wctx.add(names, prefix)
2000 rejected = wctx.add(names, prefix)
1999 bad.extend(f for f in rejected if f in match.files())
2001 bad.extend(f for f in rejected if f in match.files())
2000 return bad
2002 return bad
2001
2003
2002 def forget(ui, repo, match, prefix, explicitonly):
2004 def forget(ui, repo, match, prefix, explicitonly):
2003 join = lambda f: os.path.join(prefix, f)
2005 join = lambda f: os.path.join(prefix, f)
2004 bad = []
2006 bad = []
2005 oldbad = match.bad
2007 oldbad = match.bad
2006 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
2008 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
2007 wctx = repo[None]
2009 wctx = repo[None]
2008 forgot = []
2010 forgot = []
2009 s = repo.status(match=match, clean=True)
2011 s = repo.status(match=match, clean=True)
2010 forget = sorted(s[0] + s[1] + s[3] + s[6])
2012 forget = sorted(s[0] + s[1] + s[3] + s[6])
2011 if explicitonly:
2013 if explicitonly:
2012 forget = [f for f in forget if match.exact(f)]
2014 forget = [f for f in forget if match.exact(f)]
2013
2015
2014 for subpath in sorted(wctx.substate):
2016 for subpath in sorted(wctx.substate):
2015 sub = wctx.sub(subpath)
2017 sub = wctx.sub(subpath)
2016 try:
2018 try:
2017 submatch = matchmod.narrowmatcher(subpath, match)
2019 submatch = matchmod.narrowmatcher(subpath, match)
2018 subbad, subforgot = sub.forget(submatch, prefix)
2020 subbad, subforgot = sub.forget(submatch, prefix)
2019 bad.extend([subpath + '/' + f for f in subbad])
2021 bad.extend([subpath + '/' + f for f in subbad])
2020 forgot.extend([subpath + '/' + f for f in subforgot])
2022 forgot.extend([subpath + '/' + f for f in subforgot])
2021 except error.LookupError:
2023 except error.LookupError:
2022 ui.status(_("skipping missing subrepository: %s\n")
2024 ui.status(_("skipping missing subrepository: %s\n")
2023 % join(subpath))
2025 % join(subpath))
2024
2026
2025 if not explicitonly:
2027 if not explicitonly:
2026 for f in match.files():
2028 for f in match.files():
2027 if f not in repo.dirstate and not repo.wvfs.isdir(f):
2029 if f not in repo.dirstate and not repo.wvfs.isdir(f):
2028 if f not in forgot:
2030 if f not in forgot:
2029 if repo.wvfs.exists(f):
2031 if repo.wvfs.exists(f):
2030 ui.warn(_('not removing %s: '
2032 ui.warn(_('not removing %s: '
2031 'file is already untracked\n')
2033 'file is already untracked\n')
2032 % match.rel(f))
2034 % match.rel(f))
2033 bad.append(f)
2035 bad.append(f)
2034
2036
2035 for f in forget:
2037 for f in forget:
2036 if ui.verbose or not match.exact(f):
2038 if ui.verbose or not match.exact(f):
2037 ui.status(_('removing %s\n') % match.rel(f))
2039 ui.status(_('removing %s\n') % match.rel(f))
2038
2040
2039 rejected = wctx.forget(forget, prefix)
2041 rejected = wctx.forget(forget, prefix)
2040 bad.extend(f for f in rejected if f in match.files())
2042 bad.extend(f for f in rejected if f in match.files())
2041 forgot.extend(f for f in forget if f not in rejected)
2043 forgot.extend(f for f in forget if f not in rejected)
2042 return bad, forgot
2044 return bad, forgot
2043
2045
2044 def remove(ui, repo, m, prefix, after, force, subrepos):
2046 def remove(ui, repo, m, prefix, after, force, subrepos):
2045 join = lambda f: os.path.join(prefix, f)
2047 join = lambda f: os.path.join(prefix, f)
2046 ret = 0
2048 ret = 0
2047 s = repo.status(match=m, clean=True)
2049 s = repo.status(match=m, clean=True)
2048 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2050 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2049
2051
2050 wctx = repo[None]
2052 wctx = repo[None]
2051
2053
2052 for subpath in sorted(wctx.substate):
2054 for subpath in sorted(wctx.substate):
2053 def matchessubrepo(matcher, subpath):
2055 def matchessubrepo(matcher, subpath):
2054 if matcher.exact(subpath):
2056 if matcher.exact(subpath):
2055 return True
2057 return True
2056 for f in matcher.files():
2058 for f in matcher.files():
2057 if f.startswith(subpath):
2059 if f.startswith(subpath):
2058 return True
2060 return True
2059 return False
2061 return False
2060
2062
2061 if subrepos or matchessubrepo(m, subpath):
2063 if subrepos or matchessubrepo(m, subpath):
2062 sub = wctx.sub(subpath)
2064 sub = wctx.sub(subpath)
2063 try:
2065 try:
2064 submatch = matchmod.narrowmatcher(subpath, m)
2066 submatch = matchmod.narrowmatcher(subpath, m)
2065 if sub.removefiles(submatch, prefix, after, force, subrepos):
2067 if sub.removefiles(submatch, prefix, after, force, subrepos):
2066 ret = 1
2068 ret = 1
2067 except error.LookupError:
2069 except error.LookupError:
2068 ui.status(_("skipping missing subrepository: %s\n")
2070 ui.status(_("skipping missing subrepository: %s\n")
2069 % join(subpath))
2071 % join(subpath))
2070
2072
2071 # warn about failure to delete explicit files/dirs
2073 # warn about failure to delete explicit files/dirs
2072 for f in m.files():
2074 for f in m.files():
2073 def insubrepo():
2075 def insubrepo():
2074 for subpath in wctx.substate:
2076 for subpath in wctx.substate:
2075 if f.startswith(subpath):
2077 if f.startswith(subpath):
2076 return True
2078 return True
2077 return False
2079 return False
2078
2080
2079 if f in repo.dirstate or f in wctx.dirs() or f == '.' or insubrepo():
2081 if f in repo.dirstate or f in wctx.dirs() or f == '.' or insubrepo():
2080 continue
2082 continue
2081
2083
2082 if repo.wvfs.exists(f):
2084 if repo.wvfs.exists(f):
2083 if repo.wvfs.isdir(f):
2085 if repo.wvfs.isdir(f):
2084 ui.warn(_('not removing %s: no tracked files\n')
2086 ui.warn(_('not removing %s: no tracked files\n')
2085 % m.rel(f))
2087 % m.rel(f))
2086 else:
2088 else:
2087 ui.warn(_('not removing %s: file is untracked\n')
2089 ui.warn(_('not removing %s: file is untracked\n')
2088 % m.rel(f))
2090 % m.rel(f))
2089 # missing files will generate a warning elsewhere
2091 # missing files will generate a warning elsewhere
2090 ret = 1
2092 ret = 1
2091
2093
2092 if force:
2094 if force:
2093 list = modified + deleted + clean + added
2095 list = modified + deleted + clean + added
2094 elif after:
2096 elif after:
2095 list = deleted
2097 list = deleted
2096 for f in modified + added + clean:
2098 for f in modified + added + clean:
2097 ui.warn(_('not removing %s: file still exists\n') % m.rel(f))
2099 ui.warn(_('not removing %s: file still exists\n') % m.rel(f))
2098 ret = 1
2100 ret = 1
2099 else:
2101 else:
2100 list = deleted + clean
2102 list = deleted + clean
2101 for f in modified:
2103 for f in modified:
2102 ui.warn(_('not removing %s: file is modified (use -f'
2104 ui.warn(_('not removing %s: file is modified (use -f'
2103 ' to force removal)\n') % m.rel(f))
2105 ' to force removal)\n') % m.rel(f))
2104 ret = 1
2106 ret = 1
2105 for f in added:
2107 for f in added:
2106 ui.warn(_('not removing %s: file has been marked for add'
2108 ui.warn(_('not removing %s: file has been marked for add'
2107 ' (use forget to undo)\n') % m.rel(f))
2109 ' (use forget to undo)\n') % m.rel(f))
2108 ret = 1
2110 ret = 1
2109
2111
2110 for f in sorted(list):
2112 for f in sorted(list):
2111 if ui.verbose or not m.exact(f):
2113 if ui.verbose or not m.exact(f):
2112 ui.status(_('removing %s\n') % m.rel(f))
2114 ui.status(_('removing %s\n') % m.rel(f))
2113
2115
2114 wlock = repo.wlock()
2116 wlock = repo.wlock()
2115 try:
2117 try:
2116 if not after:
2118 if not after:
2117 for f in list:
2119 for f in list:
2118 if f in added:
2120 if f in added:
2119 continue # we never unlink added files on remove
2121 continue # we never unlink added files on remove
2120 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
2122 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
2121 repo[None].forget(list)
2123 repo[None].forget(list)
2122 finally:
2124 finally:
2123 wlock.release()
2125 wlock.release()
2124
2126
2125 return ret
2127 return ret
2126
2128
2127 def cat(ui, repo, ctx, matcher, prefix, **opts):
2129 def cat(ui, repo, ctx, matcher, prefix, **opts):
2128 err = 1
2130 err = 1
2129
2131
2130 def write(path):
2132 def write(path):
2131 fp = makefileobj(repo, opts.get('output'), ctx.node(),
2133 fp = makefileobj(repo, opts.get('output'), ctx.node(),
2132 pathname=os.path.join(prefix, path))
2134 pathname=os.path.join(prefix, path))
2133 data = ctx[path].data()
2135 data = ctx[path].data()
2134 if opts.get('decode'):
2136 if opts.get('decode'):
2135 data = repo.wwritedata(path, data)
2137 data = repo.wwritedata(path, data)
2136 fp.write(data)
2138 fp.write(data)
2137 fp.close()
2139 fp.close()
2138
2140
2139 # Automation often uses hg cat on single files, so special case it
2141 # Automation often uses hg cat on single files, so special case it
2140 # for performance to avoid the cost of parsing the manifest.
2142 # for performance to avoid the cost of parsing the manifest.
2141 if len(matcher.files()) == 1 and not matcher.anypats():
2143 if len(matcher.files()) == 1 and not matcher.anypats():
2142 file = matcher.files()[0]
2144 file = matcher.files()[0]
2143 mf = repo.manifest
2145 mf = repo.manifest
2144 mfnode = ctx._changeset[0]
2146 mfnode = ctx._changeset[0]
2145 if mf.find(mfnode, file)[0]:
2147 if mf.find(mfnode, file)[0]:
2146 write(file)
2148 write(file)
2147 return 0
2149 return 0
2148
2150
2149 # Don't warn about "missing" files that are really in subrepos
2151 # Don't warn about "missing" files that are really in subrepos
2150 bad = matcher.bad
2152 bad = matcher.bad
2151
2153
2152 def badfn(path, msg):
2154 def badfn(path, msg):
2153 for subpath in ctx.substate:
2155 for subpath in ctx.substate:
2154 if path.startswith(subpath):
2156 if path.startswith(subpath):
2155 return
2157 return
2156 bad(path, msg)
2158 bad(path, msg)
2157
2159
2158 matcher.bad = badfn
2160 matcher.bad = badfn
2159
2161
2160 for abs in ctx.walk(matcher):
2162 for abs in ctx.walk(matcher):
2161 write(abs)
2163 write(abs)
2162 err = 0
2164 err = 0
2163
2165
2164 matcher.bad = bad
2166 matcher.bad = bad
2165
2167
2166 for subpath in sorted(ctx.substate):
2168 for subpath in sorted(ctx.substate):
2167 sub = ctx.sub(subpath)
2169 sub = ctx.sub(subpath)
2168 try:
2170 try:
2169 submatch = matchmod.narrowmatcher(subpath, matcher)
2171 submatch = matchmod.narrowmatcher(subpath, matcher)
2170
2172
2171 if not sub.cat(submatch, os.path.join(prefix, sub._path),
2173 if not sub.cat(submatch, os.path.join(prefix, sub._path),
2172 **opts):
2174 **opts):
2173 err = 0
2175 err = 0
2174 except error.RepoLookupError:
2176 except error.RepoLookupError:
2175 ui.status(_("skipping missing subrepository: %s\n")
2177 ui.status(_("skipping missing subrepository: %s\n")
2176 % os.path.join(prefix, subpath))
2178 % os.path.join(prefix, subpath))
2177
2179
2178 return err
2180 return err
2179
2181
2180 def commit(ui, repo, commitfunc, pats, opts):
2182 def commit(ui, repo, commitfunc, pats, opts):
2181 '''commit the specified files or all outstanding changes'''
2183 '''commit the specified files or all outstanding changes'''
2182 date = opts.get('date')
2184 date = opts.get('date')
2183 if date:
2185 if date:
2184 opts['date'] = util.parsedate(date)
2186 opts['date'] = util.parsedate(date)
2185 message = logmessage(ui, opts)
2187 message = logmessage(ui, opts)
2186 matcher = scmutil.match(repo[None], pats, opts)
2188 matcher = scmutil.match(repo[None], pats, opts)
2187
2189
2188 # extract addremove carefully -- this function can be called from a command
2190 # extract addremove carefully -- this function can be called from a command
2189 # that doesn't support addremove
2191 # that doesn't support addremove
2190 if opts.get('addremove'):
2192 if opts.get('addremove'):
2191 if scmutil.addremove(repo, matcher, "", opts) != 0:
2193 if scmutil.addremove(repo, matcher, "", opts) != 0:
2192 raise util.Abort(
2194 raise util.Abort(
2193 _("failed to mark all new/missing files as added/removed"))
2195 _("failed to mark all new/missing files as added/removed"))
2194
2196
2195 return commitfunc(ui, repo, message, matcher, opts)
2197 return commitfunc(ui, repo, message, matcher, opts)
2196
2198
2197 def amend(ui, repo, commitfunc, old, extra, pats, opts):
2199 def amend(ui, repo, commitfunc, old, extra, pats, opts):
2198 # amend will reuse the existing user if not specified, but the obsolete
2200 # amend will reuse the existing user if not specified, but the obsolete
2199 # marker creation requires that the current user's name is specified.
2201 # marker creation requires that the current user's name is specified.
2200 if obsolete._enabled:
2202 if obsolete._enabled:
2201 ui.username() # raise exception if username not set
2203 ui.username() # raise exception if username not set
2202
2204
2203 ui.note(_('amending changeset %s\n') % old)
2205 ui.note(_('amending changeset %s\n') % old)
2204 base = old.p1()
2206 base = old.p1()
2205
2207
2206 wlock = lock = newid = None
2208 wlock = lock = newid = None
2207 try:
2209 try:
2208 wlock = repo.wlock()
2210 wlock = repo.wlock()
2209 lock = repo.lock()
2211 lock = repo.lock()
2210 tr = repo.transaction('amend')
2212 tr = repo.transaction('amend')
2211 try:
2213 try:
2212 # See if we got a message from -m or -l, if not, open the editor
2214 # See if we got a message from -m or -l, if not, open the editor
2213 # with the message of the changeset to amend
2215 # with the message of the changeset to amend
2214 message = logmessage(ui, opts)
2216 message = logmessage(ui, opts)
2215 # ensure logfile does not conflict with later enforcement of the
2217 # ensure logfile does not conflict with later enforcement of the
2216 # message. potential logfile content has been processed by
2218 # message. potential logfile content has been processed by
2217 # `logmessage` anyway.
2219 # `logmessage` anyway.
2218 opts.pop('logfile')
2220 opts.pop('logfile')
2219 # First, do a regular commit to record all changes in the working
2221 # First, do a regular commit to record all changes in the working
2220 # directory (if there are any)
2222 # directory (if there are any)
2221 ui.callhooks = False
2223 ui.callhooks = False
2222 currentbookmark = repo._bookmarkcurrent
2224 currentbookmark = repo._bookmarkcurrent
2223 try:
2225 try:
2224 repo._bookmarkcurrent = None
2226 repo._bookmarkcurrent = None
2225 opts['message'] = 'temporary amend commit for %s' % old
2227 opts['message'] = 'temporary amend commit for %s' % old
2226 node = commit(ui, repo, commitfunc, pats, opts)
2228 node = commit(ui, repo, commitfunc, pats, opts)
2227 finally:
2229 finally:
2228 repo._bookmarkcurrent = currentbookmark
2230 repo._bookmarkcurrent = currentbookmark
2229 ui.callhooks = True
2231 ui.callhooks = True
2230 ctx = repo[node]
2232 ctx = repo[node]
2231
2233
2232 # Participating changesets:
2234 # Participating changesets:
2233 #
2235 #
2234 # node/ctx o - new (intermediate) commit that contains changes
2236 # node/ctx o - new (intermediate) commit that contains changes
2235 # | from working dir to go into amending commit
2237 # | from working dir to go into amending commit
2236 # | (or a workingctx if there were no changes)
2238 # | (or a workingctx if there were no changes)
2237 # |
2239 # |
2238 # old o - changeset to amend
2240 # old o - changeset to amend
2239 # |
2241 # |
2240 # base o - parent of amending changeset
2242 # base o - parent of amending changeset
2241
2243
2242 # Update extra dict from amended commit (e.g. to preserve graft
2244 # Update extra dict from amended commit (e.g. to preserve graft
2243 # source)
2245 # source)
2244 extra.update(old.extra())
2246 extra.update(old.extra())
2245
2247
2246 # Also update it from the intermediate commit or from the wctx
2248 # Also update it from the intermediate commit or from the wctx
2247 extra.update(ctx.extra())
2249 extra.update(ctx.extra())
2248
2250
2249 if len(old.parents()) > 1:
2251 if len(old.parents()) > 1:
2250 # ctx.files() isn't reliable for merges, so fall back to the
2252 # ctx.files() isn't reliable for merges, so fall back to the
2251 # slower repo.status() method
2253 # slower repo.status() method
2252 files = set([fn for st in repo.status(base, old)[:3]
2254 files = set([fn for st in repo.status(base, old)[:3]
2253 for fn in st])
2255 for fn in st])
2254 else:
2256 else:
2255 files = set(old.files())
2257 files = set(old.files())
2256
2258
2257 # Second, we use either the commit we just did, or if there were no
2259 # Second, we use either the commit we just did, or if there were no
2258 # changes the parent of the working directory as the version of the
2260 # changes the parent of the working directory as the version of the
2259 # files in the final amend commit
2261 # files in the final amend commit
2260 if node:
2262 if node:
2261 ui.note(_('copying changeset %s to %s\n') % (ctx, base))
2263 ui.note(_('copying changeset %s to %s\n') % (ctx, base))
2262
2264
2263 user = ctx.user()
2265 user = ctx.user()
2264 date = ctx.date()
2266 date = ctx.date()
2265 # Recompute copies (avoid recording a -> b -> a)
2267 # Recompute copies (avoid recording a -> b -> a)
2266 copied = copies.pathcopies(base, ctx)
2268 copied = copies.pathcopies(base, ctx)
2267
2269
2268 # Prune files which were reverted by the updates: if old
2270 # Prune files which were reverted by the updates: if old
2269 # introduced file X and our intermediate commit, node,
2271 # introduced file X and our intermediate commit, node,
2270 # renamed that file, then those two files are the same and
2272 # renamed that file, then those two files are the same and
2271 # we can discard X from our list of files. Likewise if X
2273 # we can discard X from our list of files. Likewise if X
2272 # was deleted, it's no longer relevant
2274 # was deleted, it's no longer relevant
2273 files.update(ctx.files())
2275 files.update(ctx.files())
2274
2276
2275 def samefile(f):
2277 def samefile(f):
2276 if f in ctx.manifest():
2278 if f in ctx.manifest():
2277 a = ctx.filectx(f)
2279 a = ctx.filectx(f)
2278 if f in base.manifest():
2280 if f in base.manifest():
2279 b = base.filectx(f)
2281 b = base.filectx(f)
2280 return (not a.cmp(b)
2282 return (not a.cmp(b)
2281 and a.flags() == b.flags())
2283 and a.flags() == b.flags())
2282 else:
2284 else:
2283 return False
2285 return False
2284 else:
2286 else:
2285 return f not in base.manifest()
2287 return f not in base.manifest()
2286 files = [f for f in files if not samefile(f)]
2288 files = [f for f in files if not samefile(f)]
2287
2289
2288 def filectxfn(repo, ctx_, path):
2290 def filectxfn(repo, ctx_, path):
2289 try:
2291 try:
2290 fctx = ctx[path]
2292 fctx = ctx[path]
2291 flags = fctx.flags()
2293 flags = fctx.flags()
2292 mctx = context.memfilectx(repo,
2294 mctx = context.memfilectx(repo,
2293 fctx.path(), fctx.data(),
2295 fctx.path(), fctx.data(),
2294 islink='l' in flags,
2296 islink='l' in flags,
2295 isexec='x' in flags,
2297 isexec='x' in flags,
2296 copied=copied.get(path))
2298 copied=copied.get(path))
2297 return mctx
2299 return mctx
2298 except KeyError:
2300 except KeyError:
2299 return None
2301 return None
2300 else:
2302 else:
2301 ui.note(_('copying changeset %s to %s\n') % (old, base))
2303 ui.note(_('copying changeset %s to %s\n') % (old, base))
2302
2304
2303 # Use version of files as in the old cset
2305 # Use version of files as in the old cset
2304 def filectxfn(repo, ctx_, path):
2306 def filectxfn(repo, ctx_, path):
2305 try:
2307 try:
2306 return old.filectx(path)
2308 return old.filectx(path)
2307 except KeyError:
2309 except KeyError:
2308 return None
2310 return None
2309
2311
2310 user = opts.get('user') or old.user()
2312 user = opts.get('user') or old.user()
2311 date = opts.get('date') or old.date()
2313 date = opts.get('date') or old.date()
2312 editform = mergeeditform(old, 'commit.amend')
2314 editform = mergeeditform(old, 'commit.amend')
2313 editor = getcommiteditor(editform=editform, **opts)
2315 editor = getcommiteditor(editform=editform, **opts)
2314 if not message:
2316 if not message:
2315 editor = getcommiteditor(edit=True, editform=editform)
2317 editor = getcommiteditor(edit=True, editform=editform)
2316 message = old.description()
2318 message = old.description()
2317
2319
2318 pureextra = extra.copy()
2320 pureextra = extra.copy()
2319 extra['amend_source'] = old.hex()
2321 extra['amend_source'] = old.hex()
2320
2322
2321 new = context.memctx(repo,
2323 new = context.memctx(repo,
2322 parents=[base.node(), old.p2().node()],
2324 parents=[base.node(), old.p2().node()],
2323 text=message,
2325 text=message,
2324 files=files,
2326 files=files,
2325 filectxfn=filectxfn,
2327 filectxfn=filectxfn,
2326 user=user,
2328 user=user,
2327 date=date,
2329 date=date,
2328 extra=extra,
2330 extra=extra,
2329 editor=editor)
2331 editor=editor)
2330
2332
2331 newdesc = changelog.stripdesc(new.description())
2333 newdesc = changelog.stripdesc(new.description())
2332 if ((not node)
2334 if ((not node)
2333 and newdesc == old.description()
2335 and newdesc == old.description()
2334 and user == old.user()
2336 and user == old.user()
2335 and date == old.date()
2337 and date == old.date()
2336 and pureextra == old.extra()):
2338 and pureextra == old.extra()):
2337 # nothing changed. continuing here would create a new node
2339 # nothing changed. continuing here would create a new node
2338 # anyway because of the amend_source noise.
2340 # anyway because of the amend_source noise.
2339 #
2341 #
2340 # This not what we expect from amend.
2342 # This not what we expect from amend.
2341 return old.node()
2343 return old.node()
2342
2344
2343 ph = repo.ui.config('phases', 'new-commit', phases.draft)
2345 ph = repo.ui.config('phases', 'new-commit', phases.draft)
2344 try:
2346 try:
2345 if opts.get('secret'):
2347 if opts.get('secret'):
2346 commitphase = 'secret'
2348 commitphase = 'secret'
2347 else:
2349 else:
2348 commitphase = old.phase()
2350 commitphase = old.phase()
2349 repo.ui.setconfig('phases', 'new-commit', commitphase, 'amend')
2351 repo.ui.setconfig('phases', 'new-commit', commitphase, 'amend')
2350 newid = repo.commitctx(new)
2352 newid = repo.commitctx(new)
2351 finally:
2353 finally:
2352 repo.ui.setconfig('phases', 'new-commit', ph, 'amend')
2354 repo.ui.setconfig('phases', 'new-commit', ph, 'amend')
2353 if newid != old.node():
2355 if newid != old.node():
2354 # Reroute the working copy parent to the new changeset
2356 # Reroute the working copy parent to the new changeset
2355 repo.setparents(newid, nullid)
2357 repo.setparents(newid, nullid)
2356
2358
2357 # Move bookmarks from old parent to amend commit
2359 # Move bookmarks from old parent to amend commit
2358 bms = repo.nodebookmarks(old.node())
2360 bms = repo.nodebookmarks(old.node())
2359 if bms:
2361 if bms:
2360 marks = repo._bookmarks
2362 marks = repo._bookmarks
2361 for bm in bms:
2363 for bm in bms:
2362 marks[bm] = newid
2364 marks[bm] = newid
2363 marks.write()
2365 marks.write()
2364 #commit the whole amend process
2366 #commit the whole amend process
2365 createmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt)
2367 createmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt)
2366 if createmarkers and newid != old.node():
2368 if createmarkers and newid != old.node():
2367 # mark the new changeset as successor of the rewritten one
2369 # mark the new changeset as successor of the rewritten one
2368 new = repo[newid]
2370 new = repo[newid]
2369 obs = [(old, (new,))]
2371 obs = [(old, (new,))]
2370 if node:
2372 if node:
2371 obs.append((ctx, ()))
2373 obs.append((ctx, ()))
2372
2374
2373 obsolete.createmarkers(repo, obs)
2375 obsolete.createmarkers(repo, obs)
2374 tr.close()
2376 tr.close()
2375 finally:
2377 finally:
2376 tr.release()
2378 tr.release()
2377 if not createmarkers and newid != old.node():
2379 if not createmarkers and newid != old.node():
2378 # Strip the intermediate commit (if there was one) and the amended
2380 # Strip the intermediate commit (if there was one) and the amended
2379 # commit
2381 # commit
2380 if node:
2382 if node:
2381 ui.note(_('stripping intermediate changeset %s\n') % ctx)
2383 ui.note(_('stripping intermediate changeset %s\n') % ctx)
2382 ui.note(_('stripping amended changeset %s\n') % old)
2384 ui.note(_('stripping amended changeset %s\n') % old)
2383 repair.strip(ui, repo, old.node(), topic='amend-backup')
2385 repair.strip(ui, repo, old.node(), topic='amend-backup')
2384 finally:
2386 finally:
2385 if newid is None:
2387 if newid is None:
2386 repo.dirstate.invalidate()
2388 repo.dirstate.invalidate()
2387 lockmod.release(lock, wlock)
2389 lockmod.release(lock, wlock)
2388 return newid
2390 return newid
2389
2391
2390 def commiteditor(repo, ctx, subs, editform=''):
2392 def commiteditor(repo, ctx, subs, editform=''):
2391 if ctx.description():
2393 if ctx.description():
2392 return ctx.description()
2394 return ctx.description()
2393 return commitforceeditor(repo, ctx, subs, editform=editform)
2395 return commitforceeditor(repo, ctx, subs, editform=editform)
2394
2396
2395 def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None,
2397 def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None,
2396 editform=''):
2398 editform=''):
2397 if not extramsg:
2399 if not extramsg:
2398 extramsg = _("Leave message empty to abort commit.")
2400 extramsg = _("Leave message empty to abort commit.")
2399
2401
2400 forms = [e for e in editform.split('.') if e]
2402 forms = [e for e in editform.split('.') if e]
2401 forms.insert(0, 'changeset')
2403 forms.insert(0, 'changeset')
2402 while forms:
2404 while forms:
2403 tmpl = repo.ui.config('committemplate', '.'.join(forms))
2405 tmpl = repo.ui.config('committemplate', '.'.join(forms))
2404 if tmpl:
2406 if tmpl:
2405 committext = buildcommittemplate(repo, ctx, subs, extramsg, tmpl)
2407 committext = buildcommittemplate(repo, ctx, subs, extramsg, tmpl)
2406 break
2408 break
2407 forms.pop()
2409 forms.pop()
2408 else:
2410 else:
2409 committext = buildcommittext(repo, ctx, subs, extramsg)
2411 committext = buildcommittext(repo, ctx, subs, extramsg)
2410
2412
2411 # run editor in the repository root
2413 # run editor in the repository root
2412 olddir = os.getcwd()
2414 olddir = os.getcwd()
2413 os.chdir(repo.root)
2415 os.chdir(repo.root)
2414 text = repo.ui.edit(committext, ctx.user(), ctx.extra(), editform=editform)
2416 text = repo.ui.edit(committext, ctx.user(), ctx.extra(), editform=editform)
2415 text = re.sub("(?m)^HG:.*(\n|$)", "", text)
2417 text = re.sub("(?m)^HG:.*(\n|$)", "", text)
2416 os.chdir(olddir)
2418 os.chdir(olddir)
2417
2419
2418 if finishdesc:
2420 if finishdesc:
2419 text = finishdesc(text)
2421 text = finishdesc(text)
2420 if not text.strip():
2422 if not text.strip():
2421 raise util.Abort(_("empty commit message"))
2423 raise util.Abort(_("empty commit message"))
2422
2424
2423 return text
2425 return text
2424
2426
2425 def buildcommittemplate(repo, ctx, subs, extramsg, tmpl):
2427 def buildcommittemplate(repo, ctx, subs, extramsg, tmpl):
2426 ui = repo.ui
2428 ui = repo.ui
2427 tmpl, mapfile = gettemplate(ui, tmpl, None)
2429 tmpl, mapfile = gettemplate(ui, tmpl, None)
2428
2430
2429 try:
2431 try:
2430 t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
2432 t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
2431 except SyntaxError, inst:
2433 except SyntaxError, inst:
2432 raise util.Abort(inst.args[0])
2434 raise util.Abort(inst.args[0])
2433
2435
2434 for k, v in repo.ui.configitems('committemplate'):
2436 for k, v in repo.ui.configitems('committemplate'):
2435 if k != 'changeset':
2437 if k != 'changeset':
2436 t.t.cache[k] = v
2438 t.t.cache[k] = v
2437
2439
2438 if not extramsg:
2440 if not extramsg:
2439 extramsg = '' # ensure that extramsg is string
2441 extramsg = '' # ensure that extramsg is string
2440
2442
2441 ui.pushbuffer()
2443 ui.pushbuffer()
2442 t.show(ctx, extramsg=extramsg)
2444 t.show(ctx, extramsg=extramsg)
2443 return ui.popbuffer()
2445 return ui.popbuffer()
2444
2446
2445 def buildcommittext(repo, ctx, subs, extramsg):
2447 def buildcommittext(repo, ctx, subs, extramsg):
2446 edittext = []
2448 edittext = []
2447 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
2449 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
2448 if ctx.description():
2450 if ctx.description():
2449 edittext.append(ctx.description())
2451 edittext.append(ctx.description())
2450 edittext.append("")
2452 edittext.append("")
2451 edittext.append("") # Empty line between message and comments.
2453 edittext.append("") # Empty line between message and comments.
2452 edittext.append(_("HG: Enter commit message."
2454 edittext.append(_("HG: Enter commit message."
2453 " Lines beginning with 'HG:' are removed."))
2455 " Lines beginning with 'HG:' are removed."))
2454 edittext.append("HG: %s" % extramsg)
2456 edittext.append("HG: %s" % extramsg)
2455 edittext.append("HG: --")
2457 edittext.append("HG: --")
2456 edittext.append(_("HG: user: %s") % ctx.user())
2458 edittext.append(_("HG: user: %s") % ctx.user())
2457 if ctx.p2():
2459 if ctx.p2():
2458 edittext.append(_("HG: branch merge"))
2460 edittext.append(_("HG: branch merge"))
2459 if ctx.branch():
2461 if ctx.branch():
2460 edittext.append(_("HG: branch '%s'") % ctx.branch())
2462 edittext.append(_("HG: branch '%s'") % ctx.branch())
2461 if bookmarks.iscurrent(repo):
2463 if bookmarks.iscurrent(repo):
2462 edittext.append(_("HG: bookmark '%s'") % repo._bookmarkcurrent)
2464 edittext.append(_("HG: bookmark '%s'") % repo._bookmarkcurrent)
2463 edittext.extend([_("HG: subrepo %s") % s for s in subs])
2465 edittext.extend([_("HG: subrepo %s") % s for s in subs])
2464 edittext.extend([_("HG: added %s") % f for f in added])
2466 edittext.extend([_("HG: added %s") % f for f in added])
2465 edittext.extend([_("HG: changed %s") % f for f in modified])
2467 edittext.extend([_("HG: changed %s") % f for f in modified])
2466 edittext.extend([_("HG: removed %s") % f for f in removed])
2468 edittext.extend([_("HG: removed %s") % f for f in removed])
2467 if not added and not modified and not removed:
2469 if not added and not modified and not removed:
2468 edittext.append(_("HG: no files changed"))
2470 edittext.append(_("HG: no files changed"))
2469 edittext.append("")
2471 edittext.append("")
2470
2472
2471 return "\n".join(edittext)
2473 return "\n".join(edittext)
2472
2474
2473 def commitstatus(repo, node, branch, bheads=None, opts={}):
2475 def commitstatus(repo, node, branch, bheads=None, opts={}):
2474 ctx = repo[node]
2476 ctx = repo[node]
2475 parents = ctx.parents()
2477 parents = ctx.parents()
2476
2478
2477 if (not opts.get('amend') and bheads and node not in bheads and not
2479 if (not opts.get('amend') and bheads and node not in bheads and not
2478 [x for x in parents if x.node() in bheads and x.branch() == branch]):
2480 [x for x in parents if x.node() in bheads and x.branch() == branch]):
2479 repo.ui.status(_('created new head\n'))
2481 repo.ui.status(_('created new head\n'))
2480 # The message is not printed for initial roots. For the other
2482 # The message is not printed for initial roots. For the other
2481 # changesets, it is printed in the following situations:
2483 # changesets, it is printed in the following situations:
2482 #
2484 #
2483 # Par column: for the 2 parents with ...
2485 # Par column: for the 2 parents with ...
2484 # N: null or no parent
2486 # N: null or no parent
2485 # B: parent is on another named branch
2487 # B: parent is on another named branch
2486 # C: parent is a regular non head changeset
2488 # C: parent is a regular non head changeset
2487 # H: parent was a branch head of the current branch
2489 # H: parent was a branch head of the current branch
2488 # Msg column: whether we print "created new head" message
2490 # Msg column: whether we print "created new head" message
2489 # In the following, it is assumed that there already exists some
2491 # In the following, it is assumed that there already exists some
2490 # initial branch heads of the current branch, otherwise nothing is
2492 # initial branch heads of the current branch, otherwise nothing is
2491 # printed anyway.
2493 # printed anyway.
2492 #
2494 #
2493 # Par Msg Comment
2495 # Par Msg Comment
2494 # N N y additional topo root
2496 # N N y additional topo root
2495 #
2497 #
2496 # B N y additional branch root
2498 # B N y additional branch root
2497 # C N y additional topo head
2499 # C N y additional topo head
2498 # H N n usual case
2500 # H N n usual case
2499 #
2501 #
2500 # B B y weird additional branch root
2502 # B B y weird additional branch root
2501 # C B y branch merge
2503 # C B y branch merge
2502 # H B n merge with named branch
2504 # H B n merge with named branch
2503 #
2505 #
2504 # C C y additional head from merge
2506 # C C y additional head from merge
2505 # C H n merge with a head
2507 # C H n merge with a head
2506 #
2508 #
2507 # H H n head merge: head count decreases
2509 # H H n head merge: head count decreases
2508
2510
2509 if not opts.get('close_branch'):
2511 if not opts.get('close_branch'):
2510 for r in parents:
2512 for r in parents:
2511 if r.closesbranch() and r.branch() == branch:
2513 if r.closesbranch() and r.branch() == branch:
2512 repo.ui.status(_('reopening closed branch head %d\n') % r)
2514 repo.ui.status(_('reopening closed branch head %d\n') % r)
2513
2515
2514 if repo.ui.debugflag:
2516 if repo.ui.debugflag:
2515 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
2517 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
2516 elif repo.ui.verbose:
2518 elif repo.ui.verbose:
2517 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
2519 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
2518
2520
2519 def revert(ui, repo, ctx, parents, *pats, **opts):
2521 def revert(ui, repo, ctx, parents, *pats, **opts):
2520 parent, p2 = parents
2522 parent, p2 = parents
2521 node = ctx.node()
2523 node = ctx.node()
2522
2524
2523 mf = ctx.manifest()
2525 mf = ctx.manifest()
2524 if node == p2:
2526 if node == p2:
2525 parent = p2
2527 parent = p2
2526 if node == parent:
2528 if node == parent:
2527 pmf = mf
2529 pmf = mf
2528 else:
2530 else:
2529 pmf = None
2531 pmf = None
2530
2532
2531 # need all matching names in dirstate and manifest of target rev,
2533 # need all matching names in dirstate and manifest of target rev,
2532 # so have to walk both. do not print errors if files exist in one
2534 # so have to walk both. do not print errors if files exist in one
2533 # but not other.
2535 # but not other.
2534
2536
2535 # `names` is a mapping for all elements in working copy and target revision
2537 # `names` is a mapping for all elements in working copy and target revision
2536 # The mapping is in the form:
2538 # The mapping is in the form:
2537 # <asb path in repo> -> (<path from CWD>, <exactly specified by matcher?>)
2539 # <asb path in repo> -> (<path from CWD>, <exactly specified by matcher?>)
2538 names = {}
2540 names = {}
2539
2541
2540 wlock = repo.wlock()
2542 wlock = repo.wlock()
2541 try:
2543 try:
2542 ## filling of the `names` mapping
2544 ## filling of the `names` mapping
2543 # walk dirstate to fill `names`
2545 # walk dirstate to fill `names`
2544
2546
2545 m = scmutil.match(repo[None], pats, opts)
2547 m = scmutil.match(repo[None], pats, opts)
2546 if not m.always() or node != parent:
2548 if not m.always() or node != parent:
2547 m.bad = lambda x, y: False
2549 m.bad = lambda x, y: False
2548 for abs in repo.walk(m):
2550 for abs in repo.walk(m):
2549 names[abs] = m.rel(abs), m.exact(abs)
2551 names[abs] = m.rel(abs), m.exact(abs)
2550
2552
2551 # walk target manifest to fill `names`
2553 # walk target manifest to fill `names`
2552
2554
2553 def badfn(path, msg):
2555 def badfn(path, msg):
2554 if path in names:
2556 if path in names:
2555 return
2557 return
2556 if path in ctx.substate:
2558 if path in ctx.substate:
2557 return
2559 return
2558 path_ = path + '/'
2560 path_ = path + '/'
2559 for f in names:
2561 for f in names:
2560 if f.startswith(path_):
2562 if f.startswith(path_):
2561 return
2563 return
2562 ui.warn("%s: %s\n" % (m.rel(path), msg))
2564 ui.warn("%s: %s\n" % (m.rel(path), msg))
2563
2565
2564 m = scmutil.match(ctx, pats, opts)
2566 m = scmutil.match(ctx, pats, opts)
2565 m.bad = badfn
2567 m.bad = badfn
2566 for abs in ctx.walk(m):
2568 for abs in ctx.walk(m):
2567 if abs not in names:
2569 if abs not in names:
2568 names[abs] = m.rel(abs), m.exact(abs)
2570 names[abs] = m.rel(abs), m.exact(abs)
2569
2571
2570 # Find status of all file in `names`.
2572 # Find status of all file in `names`.
2571 m = scmutil.matchfiles(repo, names)
2573 m = scmutil.matchfiles(repo, names)
2572
2574
2573 changes = repo.status(node1=node, match=m,
2575 changes = repo.status(node1=node, match=m,
2574 unknown=True, ignored=True, clean=True)
2576 unknown=True, ignored=True, clean=True)
2575 else:
2577 else:
2576 changes = repo.status(match=m)
2578 changes = repo.status(match=m)
2577 for kind in changes:
2579 for kind in changes:
2578 for abs in kind:
2580 for abs in kind:
2579 names[abs] = m.rel(abs), m.exact(abs)
2581 names[abs] = m.rel(abs), m.exact(abs)
2580
2582
2581 m = scmutil.matchfiles(repo, names)
2583 m = scmutil.matchfiles(repo, names)
2582
2584
2583 modified = set(changes.modified)
2585 modified = set(changes.modified)
2584 added = set(changes.added)
2586 added = set(changes.added)
2585 removed = set(changes.removed)
2587 removed = set(changes.removed)
2586 _deleted = set(changes.deleted)
2588 _deleted = set(changes.deleted)
2587 unknown = set(changes.unknown)
2589 unknown = set(changes.unknown)
2588 unknown.update(changes.ignored)
2590 unknown.update(changes.ignored)
2589 clean = set(changes.clean)
2591 clean = set(changes.clean)
2590 modadded = set()
2592 modadded = set()
2591
2593
2592 # split between files known in target manifest and the others
2594 # split between files known in target manifest and the others
2593 smf = set(mf)
2595 smf = set(mf)
2594
2596
2595 # determine the exact nature of the deleted changesets
2597 # determine the exact nature of the deleted changesets
2596 deladded = _deleted - smf
2598 deladded = _deleted - smf
2597 deleted = _deleted - deladded
2599 deleted = _deleted - deladded
2598
2600
2599 # We need to account for the state of file in the dirstate.
2601 # We need to account for the state of file in the dirstate.
2600 #
2602 #
2601 # Even, when we revert against something else than parent. This will
2603 # Even, when we revert against something else than parent. This will
2602 # slightly alter the behavior of revert (doing back up or not, delete
2604 # slightly alter the behavior of revert (doing back up or not, delete
2603 # or just forget etc).
2605 # or just forget etc).
2604 if parent == node:
2606 if parent == node:
2605 dsmodified = modified
2607 dsmodified = modified
2606 dsadded = added
2608 dsadded = added
2607 dsremoved = removed
2609 dsremoved = removed
2608 # store all local modifications, useful later for rename detection
2610 # store all local modifications, useful later for rename detection
2609 localchanges = dsmodified | dsadded
2611 localchanges = dsmodified | dsadded
2610 modified, added, removed = set(), set(), set()
2612 modified, added, removed = set(), set(), set()
2611 else:
2613 else:
2612 changes = repo.status(node1=parent, match=m)
2614 changes = repo.status(node1=parent, match=m)
2613 dsmodified = set(changes.modified)
2615 dsmodified = set(changes.modified)
2614 dsadded = set(changes.added)
2616 dsadded = set(changes.added)
2615 dsremoved = set(changes.removed)
2617 dsremoved = set(changes.removed)
2616 # store all local modifications, useful later for rename detection
2618 # store all local modifications, useful later for rename detection
2617 localchanges = dsmodified | dsadded
2619 localchanges = dsmodified | dsadded
2618
2620
2619 # only take into account for removes between wc and target
2621 # only take into account for removes between wc and target
2620 clean |= dsremoved - removed
2622 clean |= dsremoved - removed
2621 dsremoved &= removed
2623 dsremoved &= removed
2622 # distinct between dirstate remove and other
2624 # distinct between dirstate remove and other
2623 removed -= dsremoved
2625 removed -= dsremoved
2624
2626
2625 modadded = added & dsmodified
2627 modadded = added & dsmodified
2626 added -= modadded
2628 added -= modadded
2627
2629
2628 # tell newly modified apart.
2630 # tell newly modified apart.
2629 dsmodified &= modified
2631 dsmodified &= modified
2630 dsmodified |= modified & dsadded # dirstate added may needs backup
2632 dsmodified |= modified & dsadded # dirstate added may needs backup
2631 modified -= dsmodified
2633 modified -= dsmodified
2632
2634
2633 # We need to wait for some post-processing to update this set
2635 # We need to wait for some post-processing to update this set
2634 # before making the distinction. The dirstate will be used for
2636 # before making the distinction. The dirstate will be used for
2635 # that purpose.
2637 # that purpose.
2636 dsadded = added
2638 dsadded = added
2637
2639
2638 # in case of merge, files that are actually added can be reported as
2640 # in case of merge, files that are actually added can be reported as
2639 # modified, we need to post process the result
2641 # modified, we need to post process the result
2640 if p2 != nullid:
2642 if p2 != nullid:
2641 if pmf is None:
2643 if pmf is None:
2642 # only need parent manifest in the merge case,
2644 # only need parent manifest in the merge case,
2643 # so do not read by default
2645 # so do not read by default
2644 pmf = repo[parent].manifest()
2646 pmf = repo[parent].manifest()
2645 mergeadd = dsmodified - set(pmf)
2647 mergeadd = dsmodified - set(pmf)
2646 dsadded |= mergeadd
2648 dsadded |= mergeadd
2647 dsmodified -= mergeadd
2649 dsmodified -= mergeadd
2648
2650
2649 # if f is a rename, update `names` to also revert the source
2651 # if f is a rename, update `names` to also revert the source
2650 cwd = repo.getcwd()
2652 cwd = repo.getcwd()
2651 for f in localchanges:
2653 for f in localchanges:
2652 src = repo.dirstate.copied(f)
2654 src = repo.dirstate.copied(f)
2653 # XXX should we check for rename down to target node?
2655 # XXX should we check for rename down to target node?
2654 if src and src not in names and repo.dirstate[src] == 'r':
2656 if src and src not in names and repo.dirstate[src] == 'r':
2655 dsremoved.add(src)
2657 dsremoved.add(src)
2656 names[src] = (repo.pathto(src, cwd), True)
2658 names[src] = (repo.pathto(src, cwd), True)
2657
2659
2658 # distinguish between file to forget and the other
2660 # distinguish between file to forget and the other
2659 added = set()
2661 added = set()
2660 for abs in dsadded:
2662 for abs in dsadded:
2661 if repo.dirstate[abs] != 'a':
2663 if repo.dirstate[abs] != 'a':
2662 added.add(abs)
2664 added.add(abs)
2663 dsadded -= added
2665 dsadded -= added
2664
2666
2665 for abs in deladded:
2667 for abs in deladded:
2666 if repo.dirstate[abs] == 'a':
2668 if repo.dirstate[abs] == 'a':
2667 dsadded.add(abs)
2669 dsadded.add(abs)
2668 deladded -= dsadded
2670 deladded -= dsadded
2669
2671
2670 # For files marked as removed, we check if an unknown file is present at
2672 # For files marked as removed, we check if an unknown file is present at
2671 # the same path. If a such file exists it may need to be backed up.
2673 # the same path. If a such file exists it may need to be backed up.
2672 # Making the distinction at this stage helps have simpler backup
2674 # Making the distinction at this stage helps have simpler backup
2673 # logic.
2675 # logic.
2674 removunk = set()
2676 removunk = set()
2675 for abs in removed:
2677 for abs in removed:
2676 target = repo.wjoin(abs)
2678 target = repo.wjoin(abs)
2677 if os.path.lexists(target):
2679 if os.path.lexists(target):
2678 removunk.add(abs)
2680 removunk.add(abs)
2679 removed -= removunk
2681 removed -= removunk
2680
2682
2681 dsremovunk = set()
2683 dsremovunk = set()
2682 for abs in dsremoved:
2684 for abs in dsremoved:
2683 target = repo.wjoin(abs)
2685 target = repo.wjoin(abs)
2684 if os.path.lexists(target):
2686 if os.path.lexists(target):
2685 dsremovunk.add(abs)
2687 dsremovunk.add(abs)
2686 dsremoved -= dsremovunk
2688 dsremoved -= dsremovunk
2687
2689
2688 # action to be actually performed by revert
2690 # action to be actually performed by revert
2689 # (<list of file>, message>) tuple
2691 # (<list of file>, message>) tuple
2690 actions = {'revert': ([], _('reverting %s\n')),
2692 actions = {'revert': ([], _('reverting %s\n')),
2691 'add': ([], _('adding %s\n')),
2693 'add': ([], _('adding %s\n')),
2692 'remove': ([], _('removing %s\n')),
2694 'remove': ([], _('removing %s\n')),
2693 'drop': ([], _('removing %s\n')),
2695 'drop': ([], _('removing %s\n')),
2694 'forget': ([], _('forgetting %s\n')),
2696 'forget': ([], _('forgetting %s\n')),
2695 'undelete': ([], _('undeleting %s\n')),
2697 'undelete': ([], _('undeleting %s\n')),
2696 'noop': (None, _('no changes needed to %s\n')),
2698 'noop': (None, _('no changes needed to %s\n')),
2697 'unknown': (None, _('file not managed: %s\n')),
2699 'unknown': (None, _('file not managed: %s\n')),
2698 }
2700 }
2699
2701
2700 # "constant" that convey the backup strategy.
2702 # "constant" that convey the backup strategy.
2701 # All set to `discard` if `no-backup` is set do avoid checking
2703 # All set to `discard` if `no-backup` is set do avoid checking
2702 # no_backup lower in the code.
2704 # no_backup lower in the code.
2703 # These values are ordered for comparison purposes
2705 # These values are ordered for comparison purposes
2704 backup = 2 # unconditionally do backup
2706 backup = 2 # unconditionally do backup
2705 check = 1 # check if the existing file differs from target
2707 check = 1 # check if the existing file differs from target
2706 discard = 0 # never do backup
2708 discard = 0 # never do backup
2707 if opts.get('no_backup'):
2709 if opts.get('no_backup'):
2708 backup = check = discard
2710 backup = check = discard
2709
2711
2710 backupanddel = actions['remove']
2712 backupanddel = actions['remove']
2711 if not opts.get('no_backup'):
2713 if not opts.get('no_backup'):
2712 backupanddel = actions['drop']
2714 backupanddel = actions['drop']
2713
2715
2714 disptable = (
2716 disptable = (
2715 # dispatch table:
2717 # dispatch table:
2716 # file state
2718 # file state
2717 # action
2719 # action
2718 # make backup
2720 # make backup
2719
2721
2720 ## Sets that results that will change file on disk
2722 ## Sets that results that will change file on disk
2721 # Modified compared to target, no local change
2723 # Modified compared to target, no local change
2722 (modified, actions['revert'], discard),
2724 (modified, actions['revert'], discard),
2723 # Modified compared to target, but local file is deleted
2725 # Modified compared to target, but local file is deleted
2724 (deleted, actions['revert'], discard),
2726 (deleted, actions['revert'], discard),
2725 # Modified compared to target, local change
2727 # Modified compared to target, local change
2726 (dsmodified, actions['revert'], backup),
2728 (dsmodified, actions['revert'], backup),
2727 # Added since target
2729 # Added since target
2728 (added, actions['remove'], discard),
2730 (added, actions['remove'], discard),
2729 # Added in working directory
2731 # Added in working directory
2730 (dsadded, actions['forget'], discard),
2732 (dsadded, actions['forget'], discard),
2731 # Added since target, have local modification
2733 # Added since target, have local modification
2732 (modadded, backupanddel, backup),
2734 (modadded, backupanddel, backup),
2733 # Added since target but file is missing in working directory
2735 # Added since target but file is missing in working directory
2734 (deladded, actions['drop'], discard),
2736 (deladded, actions['drop'], discard),
2735 # Removed since target, before working copy parent
2737 # Removed since target, before working copy parent
2736 (removed, actions['add'], discard),
2738 (removed, actions['add'], discard),
2737 # Same as `removed` but an unknown file exists at the same path
2739 # Same as `removed` but an unknown file exists at the same path
2738 (removunk, actions['add'], check),
2740 (removunk, actions['add'], check),
2739 # Removed since targe, marked as such in working copy parent
2741 # Removed since targe, marked as such in working copy parent
2740 (dsremoved, actions['undelete'], discard),
2742 (dsremoved, actions['undelete'], discard),
2741 # Same as `dsremoved` but an unknown file exists at the same path
2743 # Same as `dsremoved` but an unknown file exists at the same path
2742 (dsremovunk, actions['undelete'], check),
2744 (dsremovunk, actions['undelete'], check),
2743 ## the following sets does not result in any file changes
2745 ## the following sets does not result in any file changes
2744 # File with no modification
2746 # File with no modification
2745 (clean, actions['noop'], discard),
2747 (clean, actions['noop'], discard),
2746 # Existing file, not tracked anywhere
2748 # Existing file, not tracked anywhere
2747 (unknown, actions['unknown'], discard),
2749 (unknown, actions['unknown'], discard),
2748 )
2750 )
2749
2751
2750 wctx = repo[None]
2752 wctx = repo[None]
2751 for abs, (rel, exact) in sorted(names.items()):
2753 for abs, (rel, exact) in sorted(names.items()):
2752 # target file to be touch on disk (relative to cwd)
2754 # target file to be touch on disk (relative to cwd)
2753 target = repo.wjoin(abs)
2755 target = repo.wjoin(abs)
2754 # search the entry in the dispatch table.
2756 # search the entry in the dispatch table.
2755 # if the file is in any of these sets, it was touched in the working
2757 # if the file is in any of these sets, it was touched in the working
2756 # directory parent and we are sure it needs to be reverted.
2758 # directory parent and we are sure it needs to be reverted.
2757 for table, (xlist, msg), dobackup in disptable:
2759 for table, (xlist, msg), dobackup in disptable:
2758 if abs not in table:
2760 if abs not in table:
2759 continue
2761 continue
2760 if xlist is not None:
2762 if xlist is not None:
2761 xlist.append(abs)
2763 xlist.append(abs)
2762 if dobackup and (backup <= dobackup
2764 if dobackup and (backup <= dobackup
2763 or wctx[abs].cmp(ctx[abs])):
2765 or wctx[abs].cmp(ctx[abs])):
2764 bakname = "%s.orig" % rel
2766 bakname = "%s.orig" % rel
2765 ui.note(_('saving current version of %s as %s\n') %
2767 ui.note(_('saving current version of %s as %s\n') %
2766 (rel, bakname))
2768 (rel, bakname))
2767 if not opts.get('dry_run'):
2769 if not opts.get('dry_run'):
2768 util.rename(target, bakname)
2770 util.rename(target, bakname)
2769 if ui.verbose or not exact:
2771 if ui.verbose or not exact:
2770 if not isinstance(msg, basestring):
2772 if not isinstance(msg, basestring):
2771 msg = msg(abs)
2773 msg = msg(abs)
2772 ui.status(msg % rel)
2774 ui.status(msg % rel)
2773 elif exact:
2775 elif exact:
2774 ui.warn(msg % rel)
2776 ui.warn(msg % rel)
2775 break
2777 break
2776
2778
2777
2779
2778 if not opts.get('dry_run'):
2780 if not opts.get('dry_run'):
2779 needdata = ('revert', 'add', 'undelete')
2781 needdata = ('revert', 'add', 'undelete')
2780 _revertprefetch(repo, ctx, *[actions[name][0] for name in needdata])
2782 _revertprefetch(repo, ctx, *[actions[name][0] for name in needdata])
2781
2783
2782 _performrevert(repo, parents, ctx, actions)
2784 _performrevert(repo, parents, ctx, actions)
2783
2785
2784 # get the list of subrepos that must be reverted
2786 # get the list of subrepos that must be reverted
2785 subrepomatch = scmutil.match(ctx, pats, opts)
2787 subrepomatch = scmutil.match(ctx, pats, opts)
2786 targetsubs = sorted(s for s in ctx.substate if subrepomatch(s))
2788 targetsubs = sorted(s for s in ctx.substate if subrepomatch(s))
2787
2789
2788 if targetsubs:
2790 if targetsubs:
2789 # Revert the subrepos on the revert list
2791 # Revert the subrepos on the revert list
2790 for sub in targetsubs:
2792 for sub in targetsubs:
2791 ctx.sub(sub).revert(ctx.substate[sub], *pats, **opts)
2793 ctx.sub(sub).revert(ctx.substate[sub], *pats, **opts)
2792 finally:
2794 finally:
2793 wlock.release()
2795 wlock.release()
2794
2796
2795 def _revertprefetch(repo, ctx, *files):
2797 def _revertprefetch(repo, ctx, *files):
2796 """Let extension changing the storage layer prefetch content"""
2798 """Let extension changing the storage layer prefetch content"""
2797 pass
2799 pass
2798
2800
2799 def _performrevert(repo, parents, ctx, actions):
2801 def _performrevert(repo, parents, ctx, actions):
2800 """function that actually perform all the actions computed for revert
2802 """function that actually perform all the actions computed for revert
2801
2803
2802 This is an independent function to let extension to plug in and react to
2804 This is an independent function to let extension to plug in and react to
2803 the imminent revert.
2805 the imminent revert.
2804
2806
2805 Make sure you have the working directory locked when calling this function.
2807 Make sure you have the working directory locked when calling this function.
2806 """
2808 """
2807 parent, p2 = parents
2809 parent, p2 = parents
2808 node = ctx.node()
2810 node = ctx.node()
2809 def checkout(f):
2811 def checkout(f):
2810 fc = ctx[f]
2812 fc = ctx[f]
2811 repo.wwrite(f, fc.data(), fc.flags())
2813 repo.wwrite(f, fc.data(), fc.flags())
2812
2814
2813 audit_path = pathutil.pathauditor(repo.root)
2815 audit_path = pathutil.pathauditor(repo.root)
2814 for f in actions['forget'][0]:
2816 for f in actions['forget'][0]:
2815 repo.dirstate.drop(f)
2817 repo.dirstate.drop(f)
2816 for f in actions['remove'][0]:
2818 for f in actions['remove'][0]:
2817 audit_path(f)
2819 audit_path(f)
2818 util.unlinkpath(repo.wjoin(f))
2820 util.unlinkpath(repo.wjoin(f))
2819 repo.dirstate.remove(f)
2821 repo.dirstate.remove(f)
2820 for f in actions['drop'][0]:
2822 for f in actions['drop'][0]:
2821 audit_path(f)
2823 audit_path(f)
2822 repo.dirstate.remove(f)
2824 repo.dirstate.remove(f)
2823
2825
2824 normal = None
2826 normal = None
2825 if node == parent:
2827 if node == parent:
2826 # We're reverting to our parent. If possible, we'd like status
2828 # We're reverting to our parent. If possible, we'd like status
2827 # to report the file as clean. We have to use normallookup for
2829 # to report the file as clean. We have to use normallookup for
2828 # merges to avoid losing information about merged/dirty files.
2830 # merges to avoid losing information about merged/dirty files.
2829 if p2 != nullid:
2831 if p2 != nullid:
2830 normal = repo.dirstate.normallookup
2832 normal = repo.dirstate.normallookup
2831 else:
2833 else:
2832 normal = repo.dirstate.normal
2834 normal = repo.dirstate.normal
2833 for f in actions['revert'][0]:
2835 for f in actions['revert'][0]:
2834 checkout(f)
2836 checkout(f)
2835 if normal:
2837 if normal:
2836 normal(f)
2838 normal(f)
2837
2839
2838 for f in actions['add'][0]:
2840 for f in actions['add'][0]:
2839 checkout(f)
2841 checkout(f)
2840 repo.dirstate.add(f)
2842 repo.dirstate.add(f)
2841
2843
2842 normal = repo.dirstate.normallookup
2844 normal = repo.dirstate.normallookup
2843 if node == parent and p2 == nullid:
2845 if node == parent and p2 == nullid:
2844 normal = repo.dirstate.normal
2846 normal = repo.dirstate.normal
2845 for f in actions['undelete'][0]:
2847 for f in actions['undelete'][0]:
2846 checkout(f)
2848 checkout(f)
2847 normal(f)
2849 normal(f)
2848
2850
2849 copied = copies.pathcopies(repo[parent], ctx)
2851 copied = copies.pathcopies(repo[parent], ctx)
2850
2852
2851 for f in actions['add'][0] + actions['undelete'][0] + actions['revert'][0]:
2853 for f in actions['add'][0] + actions['undelete'][0] + actions['revert'][0]:
2852 if f in copied:
2854 if f in copied:
2853 repo.dirstate.copy(copied[f], f)
2855 repo.dirstate.copy(copied[f], f)
2854
2856
2855 def command(table):
2857 def command(table):
2856 """Returns a function object to be used as a decorator for making commands.
2858 """Returns a function object to be used as a decorator for making commands.
2857
2859
2858 This function receives a command table as its argument. The table should
2860 This function receives a command table as its argument. The table should
2859 be a dict.
2861 be a dict.
2860
2862
2861 The returned function can be used as a decorator for adding commands
2863 The returned function can be used as a decorator for adding commands
2862 to that command table. This function accepts multiple arguments to define
2864 to that command table. This function accepts multiple arguments to define
2863 a command.
2865 a command.
2864
2866
2865 The first argument is the command name.
2867 The first argument is the command name.
2866
2868
2867 The options argument is an iterable of tuples defining command arguments.
2869 The options argument is an iterable of tuples defining command arguments.
2868 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
2870 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
2869
2871
2870 The synopsis argument defines a short, one line summary of how to use the
2872 The synopsis argument defines a short, one line summary of how to use the
2871 command. This shows up in the help output.
2873 command. This shows up in the help output.
2872
2874
2873 The norepo argument defines whether the command does not require a
2875 The norepo argument defines whether the command does not require a
2874 local repository. Most commands operate against a repository, thus the
2876 local repository. Most commands operate against a repository, thus the
2875 default is False.
2877 default is False.
2876
2878
2877 The optionalrepo argument defines whether the command optionally requires
2879 The optionalrepo argument defines whether the command optionally requires
2878 a local repository.
2880 a local repository.
2879
2881
2880 The inferrepo argument defines whether to try to find a repository from the
2882 The inferrepo argument defines whether to try to find a repository from the
2881 command line arguments. If True, arguments will be examined for potential
2883 command line arguments. If True, arguments will be examined for potential
2882 repository locations. See ``findrepo()``. If a repository is found, it
2884 repository locations. See ``findrepo()``. If a repository is found, it
2883 will be used.
2885 will be used.
2884 """
2886 """
2885 def cmd(name, options=(), synopsis=None, norepo=False, optionalrepo=False,
2887 def cmd(name, options=(), synopsis=None, norepo=False, optionalrepo=False,
2886 inferrepo=False):
2888 inferrepo=False):
2887 def decorator(func):
2889 def decorator(func):
2888 if synopsis:
2890 if synopsis:
2889 table[name] = func, list(options), synopsis
2891 table[name] = func, list(options), synopsis
2890 else:
2892 else:
2891 table[name] = func, list(options)
2893 table[name] = func, list(options)
2892
2894
2893 if norepo:
2895 if norepo:
2894 # Avoid import cycle.
2896 # Avoid import cycle.
2895 import commands
2897 import commands
2896 commands.norepo += ' %s' % ' '.join(parsealiases(name))
2898 commands.norepo += ' %s' % ' '.join(parsealiases(name))
2897
2899
2898 if optionalrepo:
2900 if optionalrepo:
2899 import commands
2901 import commands
2900 commands.optionalrepo += ' %s' % ' '.join(parsealiases(name))
2902 commands.optionalrepo += ' %s' % ' '.join(parsealiases(name))
2901
2903
2902 if inferrepo:
2904 if inferrepo:
2903 import commands
2905 import commands
2904 commands.inferrepo += ' %s' % ' '.join(parsealiases(name))
2906 commands.inferrepo += ' %s' % ' '.join(parsealiases(name))
2905
2907
2906 return func
2908 return func
2907 return decorator
2909 return decorator
2908
2910
2909 return cmd
2911 return cmd
2910
2912
2911 # a list of (ui, repo, otherpeer, opts, missing) functions called by
2913 # a list of (ui, repo, otherpeer, opts, missing) functions called by
2912 # commands.outgoing. "missing" is "missing" of the result of
2914 # commands.outgoing. "missing" is "missing" of the result of
2913 # "findcommonoutgoing()"
2915 # "findcommonoutgoing()"
2914 outgoinghooks = util.hooks()
2916 outgoinghooks = util.hooks()
2915
2917
2916 # a list of (ui, repo) functions called by commands.summary
2918 # a list of (ui, repo) functions called by commands.summary
2917 summaryhooks = util.hooks()
2919 summaryhooks = util.hooks()
2918
2920
2919 # a list of (ui, repo, opts, changes) functions called by commands.summary.
2921 # a list of (ui, repo, opts, changes) functions called by commands.summary.
2920 #
2922 #
2921 # functions should return tuple of booleans below, if 'changes' is None:
2923 # functions should return tuple of booleans below, if 'changes' is None:
2922 # (whether-incomings-are-needed, whether-outgoings-are-needed)
2924 # (whether-incomings-are-needed, whether-outgoings-are-needed)
2923 #
2925 #
2924 # otherwise, 'changes' is a tuple of tuples below:
2926 # otherwise, 'changes' is a tuple of tuples below:
2925 # - (sourceurl, sourcebranch, sourcepeer, incoming)
2927 # - (sourceurl, sourcebranch, sourcepeer, incoming)
2926 # - (desturl, destbranch, destpeer, outgoing)
2928 # - (desturl, destbranch, destpeer, outgoing)
2927 summaryremotehooks = util.hooks()
2929 summaryremotehooks = util.hooks()
2928
2930
2929 # A list of state files kept by multistep operations like graft.
2931 # A list of state files kept by multistep operations like graft.
2930 # Since graft cannot be aborted, it is considered 'clearable' by update.
2932 # Since graft cannot be aborted, it is considered 'clearable' by update.
2931 # note: bisect is intentionally excluded
2933 # note: bisect is intentionally excluded
2932 # (state file, clearable, allowcommit, error, hint)
2934 # (state file, clearable, allowcommit, error, hint)
2933 unfinishedstates = [
2935 unfinishedstates = [
2934 ('graftstate', True, False, _('graft in progress'),
2936 ('graftstate', True, False, _('graft in progress'),
2935 _("use 'hg graft --continue' or 'hg update' to abort")),
2937 _("use 'hg graft --continue' or 'hg update' to abort")),
2936 ('updatestate', True, False, _('last update was interrupted'),
2938 ('updatestate', True, False, _('last update was interrupted'),
2937 _("use 'hg update' to get a consistent checkout"))
2939 _("use 'hg update' to get a consistent checkout"))
2938 ]
2940 ]
2939
2941
2940 def checkunfinished(repo, commit=False):
2942 def checkunfinished(repo, commit=False):
2941 '''Look for an unfinished multistep operation, like graft, and abort
2943 '''Look for an unfinished multistep operation, like graft, and abort
2942 if found. It's probably good to check this right before
2944 if found. It's probably good to check this right before
2943 bailifchanged().
2945 bailifchanged().
2944 '''
2946 '''
2945 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2947 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2946 if commit and allowcommit:
2948 if commit and allowcommit:
2947 continue
2949 continue
2948 if repo.vfs.exists(f):
2950 if repo.vfs.exists(f):
2949 raise util.Abort(msg, hint=hint)
2951 raise util.Abort(msg, hint=hint)
2950
2952
2951 def clearunfinished(repo):
2953 def clearunfinished(repo):
2952 '''Check for unfinished operations (as above), and clear the ones
2954 '''Check for unfinished operations (as above), and clear the ones
2953 that are clearable.
2955 that are clearable.
2954 '''
2956 '''
2955 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2957 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2956 if not clearable and repo.vfs.exists(f):
2958 if not clearable and repo.vfs.exists(f):
2957 raise util.Abort(msg, hint=hint)
2959 raise util.Abort(msg, hint=hint)
2958 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2960 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2959 if clearable and repo.vfs.exists(f):
2961 if clearable and repo.vfs.exists(f):
2960 util.unlink(repo.join(f))
2962 util.unlink(repo.join(f))
@@ -1,2360 +1,2367 b''
1 @ (34) head
1 @ (34) head
2 |
2 |
3 | o (33) head
3 | o (33) head
4 | |
4 | |
5 o | (32) expand
5 o | (32) expand
6 |\ \
6 |\ \
7 | o \ (31) expand
7 | o \ (31) expand
8 | |\ \
8 | |\ \
9 | | o \ (30) expand
9 | | o \ (30) expand
10 | | |\ \
10 | | |\ \
11 | | | o | (29) regular commit
11 | | | o | (29) regular commit
12 | | | | |
12 | | | | |
13 | | o | | (28) merge zero known
13 | | o | | (28) merge zero known
14 | | |\ \ \
14 | | |\ \ \
15 o | | | | | (27) collapse
15 o | | | | | (27) collapse
16 |/ / / / /
16 |/ / / / /
17 | | o---+ (26) merge one known; far right
17 | | o---+ (26) merge one known; far right
18 | | | | |
18 | | | | |
19 +---o | | (25) merge one known; far left
19 +---o | | (25) merge one known; far left
20 | | | | |
20 | | | | |
21 | | o | | (24) merge one known; immediate right
21 | | o | | (24) merge one known; immediate right
22 | | |\| |
22 | | |\| |
23 | | o | | (23) merge one known; immediate left
23 | | o | | (23) merge one known; immediate left
24 | |/| | |
24 | |/| | |
25 +---o---+ (22) merge two known; one far left, one far right
25 +---o---+ (22) merge two known; one far left, one far right
26 | | / /
26 | | / /
27 o | | | (21) expand
27 o | | | (21) expand
28 |\ \ \ \
28 |\ \ \ \
29 | o---+-+ (20) merge two known; two far right
29 | o---+-+ (20) merge two known; two far right
30 | / / /
30 | / / /
31 o | | | (19) expand
31 o | | | (19) expand
32 |\ \ \ \
32 |\ \ \ \
33 +---+---o (18) merge two known; two far left
33 +---+---o (18) merge two known; two far left
34 | | | |
34 | | | |
35 | o | | (17) expand
35 | o | | (17) expand
36 | |\ \ \
36 | |\ \ \
37 | | o---+ (16) merge two known; one immediate right, one near right
37 | | o---+ (16) merge two known; one immediate right, one near right
38 | | |/ /
38 | | |/ /
39 o | | | (15) expand
39 o | | | (15) expand
40 |\ \ \ \
40 |\ \ \ \
41 | o-----+ (14) merge two known; one immediate right, one far right
41 | o-----+ (14) merge two known; one immediate right, one far right
42 | |/ / /
42 | |/ / /
43 o | | | (13) expand
43 o | | | (13) expand
44 |\ \ \ \
44 |\ \ \ \
45 +---o | | (12) merge two known; one immediate right, one far left
45 +---o | | (12) merge two known; one immediate right, one far left
46 | | |/ /
46 | | |/ /
47 | o | | (11) expand
47 | o | | (11) expand
48 | |\ \ \
48 | |\ \ \
49 | | o---+ (10) merge two known; one immediate left, one near right
49 | | o---+ (10) merge two known; one immediate left, one near right
50 | |/ / /
50 | |/ / /
51 o | | | (9) expand
51 o | | | (9) expand
52 |\ \ \ \
52 |\ \ \ \
53 | o-----+ (8) merge two known; one immediate left, one far right
53 | o-----+ (8) merge two known; one immediate left, one far right
54 |/ / / /
54 |/ / / /
55 o | | | (7) expand
55 o | | | (7) expand
56 |\ \ \ \
56 |\ \ \ \
57 +---o | | (6) merge two known; one immediate left, one far left
57 +---o | | (6) merge two known; one immediate left, one far left
58 | |/ / /
58 | |/ / /
59 | o | | (5) expand
59 | o | | (5) expand
60 | |\ \ \
60 | |\ \ \
61 | | o | | (4) merge two known; one immediate left, one immediate right
61 | | o | | (4) merge two known; one immediate left, one immediate right
62 | |/|/ /
62 | |/|/ /
63 | o / / (3) collapse
63 | o / / (3) collapse
64 |/ / /
64 |/ / /
65 o / / (2) collapse
65 o / / (2) collapse
66 |/ /
66 |/ /
67 o / (1) collapse
67 o / (1) collapse
68 |/
68 |/
69 o (0) root
69 o (0) root
70
70
71
71
72 $ commit()
72 $ commit()
73 > {
73 > {
74 > rev=$1
74 > rev=$1
75 > msg=$2
75 > msg=$2
76 > shift 2
76 > shift 2
77 > if [ "$#" -gt 0 ]; then
77 > if [ "$#" -gt 0 ]; then
78 > hg debugsetparents "$@"
78 > hg debugsetparents "$@"
79 > fi
79 > fi
80 > echo $rev > a
80 > echo $rev > a
81 > hg commit -Aqd "$rev 0" -m "($rev) $msg"
81 > hg commit -Aqd "$rev 0" -m "($rev) $msg"
82 > }
82 > }
83
83
84 $ cat > printrevset.py <<EOF
84 $ cat > printrevset.py <<EOF
85 > from mercurial import extensions, revset, commands, cmdutil
85 > from mercurial import extensions, revset, commands, cmdutil
86 >
86 >
87 > def uisetup(ui):
87 > def uisetup(ui):
88 > def printrevset(orig, ui, repo, *pats, **opts):
88 > def printrevset(orig, ui, repo, *pats, **opts):
89 > if opts.get('print_revset'):
89 > if opts.get('print_revset'):
90 > expr = cmdutil.getgraphlogrevs(repo, pats, opts)[1]
90 > expr = cmdutil.getgraphlogrevs(repo, pats, opts)[1]
91 > if expr:
91 > if expr:
92 > tree = revset.parse(expr)[0]
92 > tree = revset.parse(expr)[0]
93 > else:
93 > else:
94 > tree = []
94 > tree = []
95 > ui.write('%r\n' % (opts.get('rev', []),))
95 > ui.write('%r\n' % (opts.get('rev', []),))
96 > ui.write(revset.prettyformat(tree) + '\n')
96 > ui.write(revset.prettyformat(tree) + '\n')
97 > return 0
97 > return 0
98 > return orig(ui, repo, *pats, **opts)
98 > return orig(ui, repo, *pats, **opts)
99 > entry = extensions.wrapcommand(commands.table, 'log', printrevset)
99 > entry = extensions.wrapcommand(commands.table, 'log', printrevset)
100 > entry[1].append(('', 'print-revset', False,
100 > entry[1].append(('', 'print-revset', False,
101 > 'print generated revset and exit (DEPRECATED)'))
101 > 'print generated revset and exit (DEPRECATED)'))
102 > EOF
102 > EOF
103
103
104 $ echo "[extensions]" >> $HGRCPATH
104 $ echo "[extensions]" >> $HGRCPATH
105 $ echo "printrevset=`pwd`/printrevset.py" >> $HGRCPATH
105 $ echo "printrevset=`pwd`/printrevset.py" >> $HGRCPATH
106
106
107 $ hg init repo
107 $ hg init repo
108 $ cd repo
108 $ cd repo
109
109
110 Empty repo:
110 Empty repo:
111
111
112 $ hg log -G
112 $ hg log -G
113
113
114
114
115 Building DAG:
115 Building DAG:
116
116
117 $ commit 0 "root"
117 $ commit 0 "root"
118 $ commit 1 "collapse" 0
118 $ commit 1 "collapse" 0
119 $ commit 2 "collapse" 1
119 $ commit 2 "collapse" 1
120 $ commit 3 "collapse" 2
120 $ commit 3 "collapse" 2
121 $ commit 4 "merge two known; one immediate left, one immediate right" 1 3
121 $ commit 4 "merge two known; one immediate left, one immediate right" 1 3
122 $ commit 5 "expand" 3 4
122 $ commit 5 "expand" 3 4
123 $ commit 6 "merge two known; one immediate left, one far left" 2 5
123 $ commit 6 "merge two known; one immediate left, one far left" 2 5
124 $ commit 7 "expand" 2 5
124 $ commit 7 "expand" 2 5
125 $ commit 8 "merge two known; one immediate left, one far right" 0 7
125 $ commit 8 "merge two known; one immediate left, one far right" 0 7
126 $ commit 9 "expand" 7 8
126 $ commit 9 "expand" 7 8
127 $ commit 10 "merge two known; one immediate left, one near right" 0 6
127 $ commit 10 "merge two known; one immediate left, one near right" 0 6
128 $ commit 11 "expand" 6 10
128 $ commit 11 "expand" 6 10
129 $ commit 12 "merge two known; one immediate right, one far left" 1 9
129 $ commit 12 "merge two known; one immediate right, one far left" 1 9
130 $ commit 13 "expand" 9 11
130 $ commit 13 "expand" 9 11
131 $ commit 14 "merge two known; one immediate right, one far right" 0 12
131 $ commit 14 "merge two known; one immediate right, one far right" 0 12
132 $ commit 15 "expand" 13 14
132 $ commit 15 "expand" 13 14
133 $ commit 16 "merge two known; one immediate right, one near right" 0 1
133 $ commit 16 "merge two known; one immediate right, one near right" 0 1
134 $ commit 17 "expand" 12 16
134 $ commit 17 "expand" 12 16
135 $ commit 18 "merge two known; two far left" 1 15
135 $ commit 18 "merge two known; two far left" 1 15
136 $ commit 19 "expand" 15 17
136 $ commit 19 "expand" 15 17
137 $ commit 20 "merge two known; two far right" 0 18
137 $ commit 20 "merge two known; two far right" 0 18
138 $ commit 21 "expand" 19 20
138 $ commit 21 "expand" 19 20
139 $ commit 22 "merge two known; one far left, one far right" 18 21
139 $ commit 22 "merge two known; one far left, one far right" 18 21
140 $ commit 23 "merge one known; immediate left" 1 22
140 $ commit 23 "merge one known; immediate left" 1 22
141 $ commit 24 "merge one known; immediate right" 0 23
141 $ commit 24 "merge one known; immediate right" 0 23
142 $ commit 25 "merge one known; far left" 21 24
142 $ commit 25 "merge one known; far left" 21 24
143 $ commit 26 "merge one known; far right" 18 25
143 $ commit 26 "merge one known; far right" 18 25
144 $ commit 27 "collapse" 21
144 $ commit 27 "collapse" 21
145 $ commit 28 "merge zero known" 1 26
145 $ commit 28 "merge zero known" 1 26
146 $ commit 29 "regular commit" 0
146 $ commit 29 "regular commit" 0
147 $ commit 30 "expand" 28 29
147 $ commit 30 "expand" 28 29
148 $ commit 31 "expand" 21 30
148 $ commit 31 "expand" 21 30
149 $ commit 32 "expand" 27 31
149 $ commit 32 "expand" 27 31
150 $ commit 33 "head" 18
150 $ commit 33 "head" 18
151 $ commit 34 "head" 32
151 $ commit 34 "head" 32
152
152
153
153
154 $ hg log -G -q
154 $ hg log -G -q
155 @ 34:fea3ac5810e0
155 @ 34:fea3ac5810e0
156 |
156 |
157 | o 33:68608f5145f9
157 | o 33:68608f5145f9
158 | |
158 | |
159 o | 32:d06dffa21a31
159 o | 32:d06dffa21a31
160 |\ \
160 |\ \
161 | o \ 31:621d83e11f67
161 | o \ 31:621d83e11f67
162 | |\ \
162 | |\ \
163 | | o \ 30:6e11cd4b648f
163 | | o \ 30:6e11cd4b648f
164 | | |\ \
164 | | |\ \
165 | | | o | 29:cd9bb2be7593
165 | | | o | 29:cd9bb2be7593
166 | | | | |
166 | | | | |
167 | | o | | 28:44ecd0b9ae99
167 | | o | | 28:44ecd0b9ae99
168 | | |\ \ \
168 | | |\ \ \
169 o | | | | | 27:886ed638191b
169 o | | | | | 27:886ed638191b
170 |/ / / / /
170 |/ / / / /
171 | | o---+ 26:7f25b6c2f0b9
171 | | o---+ 26:7f25b6c2f0b9
172 | | | | |
172 | | | | |
173 +---o | | 25:91da8ed57247
173 +---o | | 25:91da8ed57247
174 | | | | |
174 | | | | |
175 | | o | | 24:a9c19a3d96b7
175 | | o | | 24:a9c19a3d96b7
176 | | |\| |
176 | | |\| |
177 | | o | | 23:a01cddf0766d
177 | | o | | 23:a01cddf0766d
178 | |/| | |
178 | |/| | |
179 +---o---+ 22:e0d9cccacb5d
179 +---o---+ 22:e0d9cccacb5d
180 | | / /
180 | | / /
181 o | | | 21:d42a756af44d
181 o | | | 21:d42a756af44d
182 |\ \ \ \
182 |\ \ \ \
183 | o---+-+ 20:d30ed6450e32
183 | o---+-+ 20:d30ed6450e32
184 | / / /
184 | / / /
185 o | | | 19:31ddc2c1573b
185 o | | | 19:31ddc2c1573b
186 |\ \ \ \
186 |\ \ \ \
187 +---+---o 18:1aa84d96232a
187 +---+---o 18:1aa84d96232a
188 | | | |
188 | | | |
189 | o | | 17:44765d7c06e0
189 | o | | 17:44765d7c06e0
190 | |\ \ \
190 | |\ \ \
191 | | o---+ 16:3677d192927d
191 | | o---+ 16:3677d192927d
192 | | |/ /
192 | | |/ /
193 o | | | 15:1dda3f72782d
193 o | | | 15:1dda3f72782d
194 |\ \ \ \
194 |\ \ \ \
195 | o-----+ 14:8eac370358ef
195 | o-----+ 14:8eac370358ef
196 | |/ / /
196 | |/ / /
197 o | | | 13:22d8966a97e3
197 o | | | 13:22d8966a97e3
198 |\ \ \ \
198 |\ \ \ \
199 +---o | | 12:86b91144a6e9
199 +---o | | 12:86b91144a6e9
200 | | |/ /
200 | | |/ /
201 | o | | 11:832d76e6bdf2
201 | o | | 11:832d76e6bdf2
202 | |\ \ \
202 | |\ \ \
203 | | o---+ 10:74c64d036d72
203 | | o---+ 10:74c64d036d72
204 | |/ / /
204 | |/ / /
205 o | | | 9:7010c0af0a35
205 o | | | 9:7010c0af0a35
206 |\ \ \ \
206 |\ \ \ \
207 | o-----+ 8:7a0b11f71937
207 | o-----+ 8:7a0b11f71937
208 |/ / / /
208 |/ / / /
209 o | | | 7:b632bb1b1224
209 o | | | 7:b632bb1b1224
210 |\ \ \ \
210 |\ \ \ \
211 +---o | | 6:b105a072e251
211 +---o | | 6:b105a072e251
212 | |/ / /
212 | |/ / /
213 | o | | 5:4409d547b708
213 | o | | 5:4409d547b708
214 | |\ \ \
214 | |\ \ \
215 | | o | | 4:26a8bac39d9f
215 | | o | | 4:26a8bac39d9f
216 | |/|/ /
216 | |/|/ /
217 | o / / 3:27eef8ed80b4
217 | o / / 3:27eef8ed80b4
218 |/ / /
218 |/ / /
219 o / / 2:3d9a33b8d1e1
219 o / / 2:3d9a33b8d1e1
220 |/ /
220 |/ /
221 o / 1:6db2ef61d156
221 o / 1:6db2ef61d156
222 |/
222 |/
223 o 0:e6eb3150255d
223 o 0:e6eb3150255d
224
224
225
225
226 $ hg log -G
226 $ hg log -G
227 @ changeset: 34:fea3ac5810e0
227 @ changeset: 34:fea3ac5810e0
228 | tag: tip
228 | tag: tip
229 | parent: 32:d06dffa21a31
229 | parent: 32:d06dffa21a31
230 | user: test
230 | user: test
231 | date: Thu Jan 01 00:00:34 1970 +0000
231 | date: Thu Jan 01 00:00:34 1970 +0000
232 | summary: (34) head
232 | summary: (34) head
233 |
233 |
234 | o changeset: 33:68608f5145f9
234 | o changeset: 33:68608f5145f9
235 | | parent: 18:1aa84d96232a
235 | | parent: 18:1aa84d96232a
236 | | user: test
236 | | user: test
237 | | date: Thu Jan 01 00:00:33 1970 +0000
237 | | date: Thu Jan 01 00:00:33 1970 +0000
238 | | summary: (33) head
238 | | summary: (33) head
239 | |
239 | |
240 o | changeset: 32:d06dffa21a31
240 o | changeset: 32:d06dffa21a31
241 |\ \ parent: 27:886ed638191b
241 |\ \ parent: 27:886ed638191b
242 | | | parent: 31:621d83e11f67
242 | | | parent: 31:621d83e11f67
243 | | | user: test
243 | | | user: test
244 | | | date: Thu Jan 01 00:00:32 1970 +0000
244 | | | date: Thu Jan 01 00:00:32 1970 +0000
245 | | | summary: (32) expand
245 | | | summary: (32) expand
246 | | |
246 | | |
247 | o | changeset: 31:621d83e11f67
247 | o | changeset: 31:621d83e11f67
248 | |\ \ parent: 21:d42a756af44d
248 | |\ \ parent: 21:d42a756af44d
249 | | | | parent: 30:6e11cd4b648f
249 | | | | parent: 30:6e11cd4b648f
250 | | | | user: test
250 | | | | user: test
251 | | | | date: Thu Jan 01 00:00:31 1970 +0000
251 | | | | date: Thu Jan 01 00:00:31 1970 +0000
252 | | | | summary: (31) expand
252 | | | | summary: (31) expand
253 | | | |
253 | | | |
254 | | o | changeset: 30:6e11cd4b648f
254 | | o | changeset: 30:6e11cd4b648f
255 | | |\ \ parent: 28:44ecd0b9ae99
255 | | |\ \ parent: 28:44ecd0b9ae99
256 | | | | | parent: 29:cd9bb2be7593
256 | | | | | parent: 29:cd9bb2be7593
257 | | | | | user: test
257 | | | | | user: test
258 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
258 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
259 | | | | | summary: (30) expand
259 | | | | | summary: (30) expand
260 | | | | |
260 | | | | |
261 | | | o | changeset: 29:cd9bb2be7593
261 | | | o | changeset: 29:cd9bb2be7593
262 | | | | | parent: 0:e6eb3150255d
262 | | | | | parent: 0:e6eb3150255d
263 | | | | | user: test
263 | | | | | user: test
264 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
264 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
265 | | | | | summary: (29) regular commit
265 | | | | | summary: (29) regular commit
266 | | | | |
266 | | | | |
267 | | o | | changeset: 28:44ecd0b9ae99
267 | | o | | changeset: 28:44ecd0b9ae99
268 | | |\ \ \ parent: 1:6db2ef61d156
268 | | |\ \ \ parent: 1:6db2ef61d156
269 | | | | | | parent: 26:7f25b6c2f0b9
269 | | | | | | parent: 26:7f25b6c2f0b9
270 | | | | | | user: test
270 | | | | | | user: test
271 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
271 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
272 | | | | | | summary: (28) merge zero known
272 | | | | | | summary: (28) merge zero known
273 | | | | | |
273 | | | | | |
274 o | | | | | changeset: 27:886ed638191b
274 o | | | | | changeset: 27:886ed638191b
275 |/ / / / / parent: 21:d42a756af44d
275 |/ / / / / parent: 21:d42a756af44d
276 | | | | | user: test
276 | | | | | user: test
277 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
277 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
278 | | | | | summary: (27) collapse
278 | | | | | summary: (27) collapse
279 | | | | |
279 | | | | |
280 | | o---+ changeset: 26:7f25b6c2f0b9
280 | | o---+ changeset: 26:7f25b6c2f0b9
281 | | | | | parent: 18:1aa84d96232a
281 | | | | | parent: 18:1aa84d96232a
282 | | | | | parent: 25:91da8ed57247
282 | | | | | parent: 25:91da8ed57247
283 | | | | | user: test
283 | | | | | user: test
284 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
284 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
285 | | | | | summary: (26) merge one known; far right
285 | | | | | summary: (26) merge one known; far right
286 | | | | |
286 | | | | |
287 +---o | | changeset: 25:91da8ed57247
287 +---o | | changeset: 25:91da8ed57247
288 | | | | | parent: 21:d42a756af44d
288 | | | | | parent: 21:d42a756af44d
289 | | | | | parent: 24:a9c19a3d96b7
289 | | | | | parent: 24:a9c19a3d96b7
290 | | | | | user: test
290 | | | | | user: test
291 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
291 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
292 | | | | | summary: (25) merge one known; far left
292 | | | | | summary: (25) merge one known; far left
293 | | | | |
293 | | | | |
294 | | o | | changeset: 24:a9c19a3d96b7
294 | | o | | changeset: 24:a9c19a3d96b7
295 | | |\| | parent: 0:e6eb3150255d
295 | | |\| | parent: 0:e6eb3150255d
296 | | | | | parent: 23:a01cddf0766d
296 | | | | | parent: 23:a01cddf0766d
297 | | | | | user: test
297 | | | | | user: test
298 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
298 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
299 | | | | | summary: (24) merge one known; immediate right
299 | | | | | summary: (24) merge one known; immediate right
300 | | | | |
300 | | | | |
301 | | o | | changeset: 23:a01cddf0766d
301 | | o | | changeset: 23:a01cddf0766d
302 | |/| | | parent: 1:6db2ef61d156
302 | |/| | | parent: 1:6db2ef61d156
303 | | | | | parent: 22:e0d9cccacb5d
303 | | | | | parent: 22:e0d9cccacb5d
304 | | | | | user: test
304 | | | | | user: test
305 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
305 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
306 | | | | | summary: (23) merge one known; immediate left
306 | | | | | summary: (23) merge one known; immediate left
307 | | | | |
307 | | | | |
308 +---o---+ changeset: 22:e0d9cccacb5d
308 +---o---+ changeset: 22:e0d9cccacb5d
309 | | | | parent: 18:1aa84d96232a
309 | | | | parent: 18:1aa84d96232a
310 | | / / parent: 21:d42a756af44d
310 | | / / parent: 21:d42a756af44d
311 | | | | user: test
311 | | | | user: test
312 | | | | date: Thu Jan 01 00:00:22 1970 +0000
312 | | | | date: Thu Jan 01 00:00:22 1970 +0000
313 | | | | summary: (22) merge two known; one far left, one far right
313 | | | | summary: (22) merge two known; one far left, one far right
314 | | | |
314 | | | |
315 o | | | changeset: 21:d42a756af44d
315 o | | | changeset: 21:d42a756af44d
316 |\ \ \ \ parent: 19:31ddc2c1573b
316 |\ \ \ \ parent: 19:31ddc2c1573b
317 | | | | | parent: 20:d30ed6450e32
317 | | | | | parent: 20:d30ed6450e32
318 | | | | | user: test
318 | | | | | user: test
319 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
319 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
320 | | | | | summary: (21) expand
320 | | | | | summary: (21) expand
321 | | | | |
321 | | | | |
322 | o---+-+ changeset: 20:d30ed6450e32
322 | o---+-+ changeset: 20:d30ed6450e32
323 | | | | parent: 0:e6eb3150255d
323 | | | | parent: 0:e6eb3150255d
324 | / / / parent: 18:1aa84d96232a
324 | / / / parent: 18:1aa84d96232a
325 | | | | user: test
325 | | | | user: test
326 | | | | date: Thu Jan 01 00:00:20 1970 +0000
326 | | | | date: Thu Jan 01 00:00:20 1970 +0000
327 | | | | summary: (20) merge two known; two far right
327 | | | | summary: (20) merge two known; two far right
328 | | | |
328 | | | |
329 o | | | changeset: 19:31ddc2c1573b
329 o | | | changeset: 19:31ddc2c1573b
330 |\ \ \ \ parent: 15:1dda3f72782d
330 |\ \ \ \ parent: 15:1dda3f72782d
331 | | | | | parent: 17:44765d7c06e0
331 | | | | | parent: 17:44765d7c06e0
332 | | | | | user: test
332 | | | | | user: test
333 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
333 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
334 | | | | | summary: (19) expand
334 | | | | | summary: (19) expand
335 | | | | |
335 | | | | |
336 +---+---o changeset: 18:1aa84d96232a
336 +---+---o changeset: 18:1aa84d96232a
337 | | | | parent: 1:6db2ef61d156
337 | | | | parent: 1:6db2ef61d156
338 | | | | parent: 15:1dda3f72782d
338 | | | | parent: 15:1dda3f72782d
339 | | | | user: test
339 | | | | user: test
340 | | | | date: Thu Jan 01 00:00:18 1970 +0000
340 | | | | date: Thu Jan 01 00:00:18 1970 +0000
341 | | | | summary: (18) merge two known; two far left
341 | | | | summary: (18) merge two known; two far left
342 | | | |
342 | | | |
343 | o | | changeset: 17:44765d7c06e0
343 | o | | changeset: 17:44765d7c06e0
344 | |\ \ \ parent: 12:86b91144a6e9
344 | |\ \ \ parent: 12:86b91144a6e9
345 | | | | | parent: 16:3677d192927d
345 | | | | | parent: 16:3677d192927d
346 | | | | | user: test
346 | | | | | user: test
347 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
347 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
348 | | | | | summary: (17) expand
348 | | | | | summary: (17) expand
349 | | | | |
349 | | | | |
350 | | o---+ changeset: 16:3677d192927d
350 | | o---+ changeset: 16:3677d192927d
351 | | | | | parent: 0:e6eb3150255d
351 | | | | | parent: 0:e6eb3150255d
352 | | |/ / parent: 1:6db2ef61d156
352 | | |/ / parent: 1:6db2ef61d156
353 | | | | user: test
353 | | | | user: test
354 | | | | date: Thu Jan 01 00:00:16 1970 +0000
354 | | | | date: Thu Jan 01 00:00:16 1970 +0000
355 | | | | summary: (16) merge two known; one immediate right, one near right
355 | | | | summary: (16) merge two known; one immediate right, one near right
356 | | | |
356 | | | |
357 o | | | changeset: 15:1dda3f72782d
357 o | | | changeset: 15:1dda3f72782d
358 |\ \ \ \ parent: 13:22d8966a97e3
358 |\ \ \ \ parent: 13:22d8966a97e3
359 | | | | | parent: 14:8eac370358ef
359 | | | | | parent: 14:8eac370358ef
360 | | | | | user: test
360 | | | | | user: test
361 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
361 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
362 | | | | | summary: (15) expand
362 | | | | | summary: (15) expand
363 | | | | |
363 | | | | |
364 | o-----+ changeset: 14:8eac370358ef
364 | o-----+ changeset: 14:8eac370358ef
365 | | | | | parent: 0:e6eb3150255d
365 | | | | | parent: 0:e6eb3150255d
366 | |/ / / parent: 12:86b91144a6e9
366 | |/ / / parent: 12:86b91144a6e9
367 | | | | user: test
367 | | | | user: test
368 | | | | date: Thu Jan 01 00:00:14 1970 +0000
368 | | | | date: Thu Jan 01 00:00:14 1970 +0000
369 | | | | summary: (14) merge two known; one immediate right, one far right
369 | | | | summary: (14) merge two known; one immediate right, one far right
370 | | | |
370 | | | |
371 o | | | changeset: 13:22d8966a97e3
371 o | | | changeset: 13:22d8966a97e3
372 |\ \ \ \ parent: 9:7010c0af0a35
372 |\ \ \ \ parent: 9:7010c0af0a35
373 | | | | | parent: 11:832d76e6bdf2
373 | | | | | parent: 11:832d76e6bdf2
374 | | | | | user: test
374 | | | | | user: test
375 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
375 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
376 | | | | | summary: (13) expand
376 | | | | | summary: (13) expand
377 | | | | |
377 | | | | |
378 +---o | | changeset: 12:86b91144a6e9
378 +---o | | changeset: 12:86b91144a6e9
379 | | |/ / parent: 1:6db2ef61d156
379 | | |/ / parent: 1:6db2ef61d156
380 | | | | parent: 9:7010c0af0a35
380 | | | | parent: 9:7010c0af0a35
381 | | | | user: test
381 | | | | user: test
382 | | | | date: Thu Jan 01 00:00:12 1970 +0000
382 | | | | date: Thu Jan 01 00:00:12 1970 +0000
383 | | | | summary: (12) merge two known; one immediate right, one far left
383 | | | | summary: (12) merge two known; one immediate right, one far left
384 | | | |
384 | | | |
385 | o | | changeset: 11:832d76e6bdf2
385 | o | | changeset: 11:832d76e6bdf2
386 | |\ \ \ parent: 6:b105a072e251
386 | |\ \ \ parent: 6:b105a072e251
387 | | | | | parent: 10:74c64d036d72
387 | | | | | parent: 10:74c64d036d72
388 | | | | | user: test
388 | | | | | user: test
389 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
389 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
390 | | | | | summary: (11) expand
390 | | | | | summary: (11) expand
391 | | | | |
391 | | | | |
392 | | o---+ changeset: 10:74c64d036d72
392 | | o---+ changeset: 10:74c64d036d72
393 | | | | | parent: 0:e6eb3150255d
393 | | | | | parent: 0:e6eb3150255d
394 | |/ / / parent: 6:b105a072e251
394 | |/ / / parent: 6:b105a072e251
395 | | | | user: test
395 | | | | user: test
396 | | | | date: Thu Jan 01 00:00:10 1970 +0000
396 | | | | date: Thu Jan 01 00:00:10 1970 +0000
397 | | | | summary: (10) merge two known; one immediate left, one near right
397 | | | | summary: (10) merge two known; one immediate left, one near right
398 | | | |
398 | | | |
399 o | | | changeset: 9:7010c0af0a35
399 o | | | changeset: 9:7010c0af0a35
400 |\ \ \ \ parent: 7:b632bb1b1224
400 |\ \ \ \ parent: 7:b632bb1b1224
401 | | | | | parent: 8:7a0b11f71937
401 | | | | | parent: 8:7a0b11f71937
402 | | | | | user: test
402 | | | | | user: test
403 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
403 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
404 | | | | | summary: (9) expand
404 | | | | | summary: (9) expand
405 | | | | |
405 | | | | |
406 | o-----+ changeset: 8:7a0b11f71937
406 | o-----+ changeset: 8:7a0b11f71937
407 | | | | | parent: 0:e6eb3150255d
407 | | | | | parent: 0:e6eb3150255d
408 |/ / / / parent: 7:b632bb1b1224
408 |/ / / / parent: 7:b632bb1b1224
409 | | | | user: test
409 | | | | user: test
410 | | | | date: Thu Jan 01 00:00:08 1970 +0000
410 | | | | date: Thu Jan 01 00:00:08 1970 +0000
411 | | | | summary: (8) merge two known; one immediate left, one far right
411 | | | | summary: (8) merge two known; one immediate left, one far right
412 | | | |
412 | | | |
413 o | | | changeset: 7:b632bb1b1224
413 o | | | changeset: 7:b632bb1b1224
414 |\ \ \ \ parent: 2:3d9a33b8d1e1
414 |\ \ \ \ parent: 2:3d9a33b8d1e1
415 | | | | | parent: 5:4409d547b708
415 | | | | | parent: 5:4409d547b708
416 | | | | | user: test
416 | | | | | user: test
417 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
417 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
418 | | | | | summary: (7) expand
418 | | | | | summary: (7) expand
419 | | | | |
419 | | | | |
420 +---o | | changeset: 6:b105a072e251
420 +---o | | changeset: 6:b105a072e251
421 | |/ / / parent: 2:3d9a33b8d1e1
421 | |/ / / parent: 2:3d9a33b8d1e1
422 | | | | parent: 5:4409d547b708
422 | | | | parent: 5:4409d547b708
423 | | | | user: test
423 | | | | user: test
424 | | | | date: Thu Jan 01 00:00:06 1970 +0000
424 | | | | date: Thu Jan 01 00:00:06 1970 +0000
425 | | | | summary: (6) merge two known; one immediate left, one far left
425 | | | | summary: (6) merge two known; one immediate left, one far left
426 | | | |
426 | | | |
427 | o | | changeset: 5:4409d547b708
427 | o | | changeset: 5:4409d547b708
428 | |\ \ \ parent: 3:27eef8ed80b4
428 | |\ \ \ parent: 3:27eef8ed80b4
429 | | | | | parent: 4:26a8bac39d9f
429 | | | | | parent: 4:26a8bac39d9f
430 | | | | | user: test
430 | | | | | user: test
431 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
431 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
432 | | | | | summary: (5) expand
432 | | | | | summary: (5) expand
433 | | | | |
433 | | | | |
434 | | o | | changeset: 4:26a8bac39d9f
434 | | o | | changeset: 4:26a8bac39d9f
435 | |/|/ / parent: 1:6db2ef61d156
435 | |/|/ / parent: 1:6db2ef61d156
436 | | | | parent: 3:27eef8ed80b4
436 | | | | parent: 3:27eef8ed80b4
437 | | | | user: test
437 | | | | user: test
438 | | | | date: Thu Jan 01 00:00:04 1970 +0000
438 | | | | date: Thu Jan 01 00:00:04 1970 +0000
439 | | | | summary: (4) merge two known; one immediate left, one immediate right
439 | | | | summary: (4) merge two known; one immediate left, one immediate right
440 | | | |
440 | | | |
441 | o | | changeset: 3:27eef8ed80b4
441 | o | | changeset: 3:27eef8ed80b4
442 |/ / / user: test
442 |/ / / user: test
443 | | | date: Thu Jan 01 00:00:03 1970 +0000
443 | | | date: Thu Jan 01 00:00:03 1970 +0000
444 | | | summary: (3) collapse
444 | | | summary: (3) collapse
445 | | |
445 | | |
446 o | | changeset: 2:3d9a33b8d1e1
446 o | | changeset: 2:3d9a33b8d1e1
447 |/ / user: test
447 |/ / user: test
448 | | date: Thu Jan 01 00:00:02 1970 +0000
448 | | date: Thu Jan 01 00:00:02 1970 +0000
449 | | summary: (2) collapse
449 | | summary: (2) collapse
450 | |
450 | |
451 o | changeset: 1:6db2ef61d156
451 o | changeset: 1:6db2ef61d156
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: (1) collapse
454 | summary: (1) collapse
455 |
455 |
456 o changeset: 0:e6eb3150255d
456 o changeset: 0:e6eb3150255d
457 user: test
457 user: test
458 date: Thu Jan 01 00:00:00 1970 +0000
458 date: Thu Jan 01 00:00:00 1970 +0000
459 summary: (0) root
459 summary: (0) root
460
460
461
461
462 File glog:
462 File glog:
463 $ hg log -G a
463 $ hg log -G a
464 @ changeset: 34:fea3ac5810e0
464 @ changeset: 34:fea3ac5810e0
465 | tag: tip
465 | tag: tip
466 | parent: 32:d06dffa21a31
466 | parent: 32:d06dffa21a31
467 | user: test
467 | user: test
468 | date: Thu Jan 01 00:00:34 1970 +0000
468 | date: Thu Jan 01 00:00:34 1970 +0000
469 | summary: (34) head
469 | summary: (34) head
470 |
470 |
471 | o changeset: 33:68608f5145f9
471 | o changeset: 33:68608f5145f9
472 | | parent: 18:1aa84d96232a
472 | | parent: 18:1aa84d96232a
473 | | user: test
473 | | user: test
474 | | date: Thu Jan 01 00:00:33 1970 +0000
474 | | date: Thu Jan 01 00:00:33 1970 +0000
475 | | summary: (33) head
475 | | summary: (33) head
476 | |
476 | |
477 o | changeset: 32:d06dffa21a31
477 o | changeset: 32:d06dffa21a31
478 |\ \ parent: 27:886ed638191b
478 |\ \ parent: 27:886ed638191b
479 | | | parent: 31:621d83e11f67
479 | | | parent: 31:621d83e11f67
480 | | | user: test
480 | | | user: test
481 | | | date: Thu Jan 01 00:00:32 1970 +0000
481 | | | date: Thu Jan 01 00:00:32 1970 +0000
482 | | | summary: (32) expand
482 | | | summary: (32) expand
483 | | |
483 | | |
484 | o | changeset: 31:621d83e11f67
484 | o | changeset: 31:621d83e11f67
485 | |\ \ parent: 21:d42a756af44d
485 | |\ \ parent: 21:d42a756af44d
486 | | | | parent: 30:6e11cd4b648f
486 | | | | parent: 30:6e11cd4b648f
487 | | | | user: test
487 | | | | user: test
488 | | | | date: Thu Jan 01 00:00:31 1970 +0000
488 | | | | date: Thu Jan 01 00:00:31 1970 +0000
489 | | | | summary: (31) expand
489 | | | | summary: (31) expand
490 | | | |
490 | | | |
491 | | o | changeset: 30:6e11cd4b648f
491 | | o | changeset: 30:6e11cd4b648f
492 | | |\ \ parent: 28:44ecd0b9ae99
492 | | |\ \ parent: 28:44ecd0b9ae99
493 | | | | | parent: 29:cd9bb2be7593
493 | | | | | parent: 29:cd9bb2be7593
494 | | | | | user: test
494 | | | | | user: test
495 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
495 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
496 | | | | | summary: (30) expand
496 | | | | | summary: (30) expand
497 | | | | |
497 | | | | |
498 | | | o | changeset: 29:cd9bb2be7593
498 | | | o | changeset: 29:cd9bb2be7593
499 | | | | | parent: 0:e6eb3150255d
499 | | | | | parent: 0:e6eb3150255d
500 | | | | | user: test
500 | | | | | user: test
501 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
501 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
502 | | | | | summary: (29) regular commit
502 | | | | | summary: (29) regular commit
503 | | | | |
503 | | | | |
504 | | o | | changeset: 28:44ecd0b9ae99
504 | | o | | changeset: 28:44ecd0b9ae99
505 | | |\ \ \ parent: 1:6db2ef61d156
505 | | |\ \ \ parent: 1:6db2ef61d156
506 | | | | | | parent: 26:7f25b6c2f0b9
506 | | | | | | parent: 26:7f25b6c2f0b9
507 | | | | | | user: test
507 | | | | | | user: test
508 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
508 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
509 | | | | | | summary: (28) merge zero known
509 | | | | | | summary: (28) merge zero known
510 | | | | | |
510 | | | | | |
511 o | | | | | changeset: 27:886ed638191b
511 o | | | | | changeset: 27:886ed638191b
512 |/ / / / / parent: 21:d42a756af44d
512 |/ / / / / parent: 21:d42a756af44d
513 | | | | | user: test
513 | | | | | user: test
514 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
514 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
515 | | | | | summary: (27) collapse
515 | | | | | summary: (27) collapse
516 | | | | |
516 | | | | |
517 | | o---+ changeset: 26:7f25b6c2f0b9
517 | | o---+ changeset: 26:7f25b6c2f0b9
518 | | | | | parent: 18:1aa84d96232a
518 | | | | | parent: 18:1aa84d96232a
519 | | | | | parent: 25:91da8ed57247
519 | | | | | parent: 25:91da8ed57247
520 | | | | | user: test
520 | | | | | user: test
521 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
521 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
522 | | | | | summary: (26) merge one known; far right
522 | | | | | summary: (26) merge one known; far right
523 | | | | |
523 | | | | |
524 +---o | | changeset: 25:91da8ed57247
524 +---o | | changeset: 25:91da8ed57247
525 | | | | | parent: 21:d42a756af44d
525 | | | | | parent: 21:d42a756af44d
526 | | | | | parent: 24:a9c19a3d96b7
526 | | | | | parent: 24:a9c19a3d96b7
527 | | | | | user: test
527 | | | | | user: test
528 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
528 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
529 | | | | | summary: (25) merge one known; far left
529 | | | | | summary: (25) merge one known; far left
530 | | | | |
530 | | | | |
531 | | o | | changeset: 24:a9c19a3d96b7
531 | | o | | changeset: 24:a9c19a3d96b7
532 | | |\| | parent: 0:e6eb3150255d
532 | | |\| | parent: 0:e6eb3150255d
533 | | | | | parent: 23:a01cddf0766d
533 | | | | | parent: 23:a01cddf0766d
534 | | | | | user: test
534 | | | | | user: test
535 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
535 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
536 | | | | | summary: (24) merge one known; immediate right
536 | | | | | summary: (24) merge one known; immediate right
537 | | | | |
537 | | | | |
538 | | o | | changeset: 23:a01cddf0766d
538 | | o | | changeset: 23:a01cddf0766d
539 | |/| | | parent: 1:6db2ef61d156
539 | |/| | | parent: 1:6db2ef61d156
540 | | | | | parent: 22:e0d9cccacb5d
540 | | | | | parent: 22:e0d9cccacb5d
541 | | | | | user: test
541 | | | | | user: test
542 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
542 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
543 | | | | | summary: (23) merge one known; immediate left
543 | | | | | summary: (23) merge one known; immediate left
544 | | | | |
544 | | | | |
545 +---o---+ changeset: 22:e0d9cccacb5d
545 +---o---+ changeset: 22:e0d9cccacb5d
546 | | | | parent: 18:1aa84d96232a
546 | | | | parent: 18:1aa84d96232a
547 | | / / parent: 21:d42a756af44d
547 | | / / parent: 21:d42a756af44d
548 | | | | user: test
548 | | | | user: test
549 | | | | date: Thu Jan 01 00:00:22 1970 +0000
549 | | | | date: Thu Jan 01 00:00:22 1970 +0000
550 | | | | summary: (22) merge two known; one far left, one far right
550 | | | | summary: (22) merge two known; one far left, one far right
551 | | | |
551 | | | |
552 o | | | changeset: 21:d42a756af44d
552 o | | | changeset: 21:d42a756af44d
553 |\ \ \ \ parent: 19:31ddc2c1573b
553 |\ \ \ \ parent: 19:31ddc2c1573b
554 | | | | | parent: 20:d30ed6450e32
554 | | | | | parent: 20:d30ed6450e32
555 | | | | | user: test
555 | | | | | user: test
556 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
556 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
557 | | | | | summary: (21) expand
557 | | | | | summary: (21) expand
558 | | | | |
558 | | | | |
559 | o---+-+ changeset: 20:d30ed6450e32
559 | o---+-+ changeset: 20:d30ed6450e32
560 | | | | parent: 0:e6eb3150255d
560 | | | | parent: 0:e6eb3150255d
561 | / / / parent: 18:1aa84d96232a
561 | / / / parent: 18:1aa84d96232a
562 | | | | user: test
562 | | | | user: test
563 | | | | date: Thu Jan 01 00:00:20 1970 +0000
563 | | | | date: Thu Jan 01 00:00:20 1970 +0000
564 | | | | summary: (20) merge two known; two far right
564 | | | | summary: (20) merge two known; two far right
565 | | | |
565 | | | |
566 o | | | changeset: 19:31ddc2c1573b
566 o | | | changeset: 19:31ddc2c1573b
567 |\ \ \ \ parent: 15:1dda3f72782d
567 |\ \ \ \ parent: 15:1dda3f72782d
568 | | | | | parent: 17:44765d7c06e0
568 | | | | | parent: 17:44765d7c06e0
569 | | | | | user: test
569 | | | | | user: test
570 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
570 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
571 | | | | | summary: (19) expand
571 | | | | | summary: (19) expand
572 | | | | |
572 | | | | |
573 +---+---o changeset: 18:1aa84d96232a
573 +---+---o changeset: 18:1aa84d96232a
574 | | | | parent: 1:6db2ef61d156
574 | | | | parent: 1:6db2ef61d156
575 | | | | parent: 15:1dda3f72782d
575 | | | | parent: 15:1dda3f72782d
576 | | | | user: test
576 | | | | user: test
577 | | | | date: Thu Jan 01 00:00:18 1970 +0000
577 | | | | date: Thu Jan 01 00:00:18 1970 +0000
578 | | | | summary: (18) merge two known; two far left
578 | | | | summary: (18) merge two known; two far left
579 | | | |
579 | | | |
580 | o | | changeset: 17:44765d7c06e0
580 | o | | changeset: 17:44765d7c06e0
581 | |\ \ \ parent: 12:86b91144a6e9
581 | |\ \ \ parent: 12:86b91144a6e9
582 | | | | | parent: 16:3677d192927d
582 | | | | | parent: 16:3677d192927d
583 | | | | | user: test
583 | | | | | user: test
584 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
584 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
585 | | | | | summary: (17) expand
585 | | | | | summary: (17) expand
586 | | | | |
586 | | | | |
587 | | o---+ changeset: 16:3677d192927d
587 | | o---+ changeset: 16:3677d192927d
588 | | | | | parent: 0:e6eb3150255d
588 | | | | | parent: 0:e6eb3150255d
589 | | |/ / parent: 1:6db2ef61d156
589 | | |/ / parent: 1:6db2ef61d156
590 | | | | user: test
590 | | | | user: test
591 | | | | date: Thu Jan 01 00:00:16 1970 +0000
591 | | | | date: Thu Jan 01 00:00:16 1970 +0000
592 | | | | summary: (16) merge two known; one immediate right, one near right
592 | | | | summary: (16) merge two known; one immediate right, one near right
593 | | | |
593 | | | |
594 o | | | changeset: 15:1dda3f72782d
594 o | | | changeset: 15:1dda3f72782d
595 |\ \ \ \ parent: 13:22d8966a97e3
595 |\ \ \ \ parent: 13:22d8966a97e3
596 | | | | | parent: 14:8eac370358ef
596 | | | | | parent: 14:8eac370358ef
597 | | | | | user: test
597 | | | | | user: test
598 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
598 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
599 | | | | | summary: (15) expand
599 | | | | | summary: (15) expand
600 | | | | |
600 | | | | |
601 | o-----+ changeset: 14:8eac370358ef
601 | o-----+ changeset: 14:8eac370358ef
602 | | | | | parent: 0:e6eb3150255d
602 | | | | | parent: 0:e6eb3150255d
603 | |/ / / parent: 12:86b91144a6e9
603 | |/ / / parent: 12:86b91144a6e9
604 | | | | user: test
604 | | | | user: test
605 | | | | date: Thu Jan 01 00:00:14 1970 +0000
605 | | | | date: Thu Jan 01 00:00:14 1970 +0000
606 | | | | summary: (14) merge two known; one immediate right, one far right
606 | | | | summary: (14) merge two known; one immediate right, one far right
607 | | | |
607 | | | |
608 o | | | changeset: 13:22d8966a97e3
608 o | | | changeset: 13:22d8966a97e3
609 |\ \ \ \ parent: 9:7010c0af0a35
609 |\ \ \ \ parent: 9:7010c0af0a35
610 | | | | | parent: 11:832d76e6bdf2
610 | | | | | parent: 11:832d76e6bdf2
611 | | | | | user: test
611 | | | | | user: test
612 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
612 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
613 | | | | | summary: (13) expand
613 | | | | | summary: (13) expand
614 | | | | |
614 | | | | |
615 +---o | | changeset: 12:86b91144a6e9
615 +---o | | changeset: 12:86b91144a6e9
616 | | |/ / parent: 1:6db2ef61d156
616 | | |/ / parent: 1:6db2ef61d156
617 | | | | parent: 9:7010c0af0a35
617 | | | | parent: 9:7010c0af0a35
618 | | | | user: test
618 | | | | user: test
619 | | | | date: Thu Jan 01 00:00:12 1970 +0000
619 | | | | date: Thu Jan 01 00:00:12 1970 +0000
620 | | | | summary: (12) merge two known; one immediate right, one far left
620 | | | | summary: (12) merge two known; one immediate right, one far left
621 | | | |
621 | | | |
622 | o | | changeset: 11:832d76e6bdf2
622 | o | | changeset: 11:832d76e6bdf2
623 | |\ \ \ parent: 6:b105a072e251
623 | |\ \ \ parent: 6:b105a072e251
624 | | | | | parent: 10:74c64d036d72
624 | | | | | parent: 10:74c64d036d72
625 | | | | | user: test
625 | | | | | user: test
626 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
626 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
627 | | | | | summary: (11) expand
627 | | | | | summary: (11) expand
628 | | | | |
628 | | | | |
629 | | o---+ changeset: 10:74c64d036d72
629 | | o---+ changeset: 10:74c64d036d72
630 | | | | | parent: 0:e6eb3150255d
630 | | | | | parent: 0:e6eb3150255d
631 | |/ / / parent: 6:b105a072e251
631 | |/ / / parent: 6:b105a072e251
632 | | | | user: test
632 | | | | user: test
633 | | | | date: Thu Jan 01 00:00:10 1970 +0000
633 | | | | date: Thu Jan 01 00:00:10 1970 +0000
634 | | | | summary: (10) merge two known; one immediate left, one near right
634 | | | | summary: (10) merge two known; one immediate left, one near right
635 | | | |
635 | | | |
636 o | | | changeset: 9:7010c0af0a35
636 o | | | changeset: 9:7010c0af0a35
637 |\ \ \ \ parent: 7:b632bb1b1224
637 |\ \ \ \ parent: 7:b632bb1b1224
638 | | | | | parent: 8:7a0b11f71937
638 | | | | | parent: 8:7a0b11f71937
639 | | | | | user: test
639 | | | | | user: test
640 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
640 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
641 | | | | | summary: (9) expand
641 | | | | | summary: (9) expand
642 | | | | |
642 | | | | |
643 | o-----+ changeset: 8:7a0b11f71937
643 | o-----+ changeset: 8:7a0b11f71937
644 | | | | | parent: 0:e6eb3150255d
644 | | | | | parent: 0:e6eb3150255d
645 |/ / / / parent: 7:b632bb1b1224
645 |/ / / / parent: 7:b632bb1b1224
646 | | | | user: test
646 | | | | user: test
647 | | | | date: Thu Jan 01 00:00:08 1970 +0000
647 | | | | date: Thu Jan 01 00:00:08 1970 +0000
648 | | | | summary: (8) merge two known; one immediate left, one far right
648 | | | | summary: (8) merge two known; one immediate left, one far right
649 | | | |
649 | | | |
650 o | | | changeset: 7:b632bb1b1224
650 o | | | changeset: 7:b632bb1b1224
651 |\ \ \ \ parent: 2:3d9a33b8d1e1
651 |\ \ \ \ parent: 2:3d9a33b8d1e1
652 | | | | | parent: 5:4409d547b708
652 | | | | | parent: 5:4409d547b708
653 | | | | | user: test
653 | | | | | user: test
654 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
654 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
655 | | | | | summary: (7) expand
655 | | | | | summary: (7) expand
656 | | | | |
656 | | | | |
657 +---o | | changeset: 6:b105a072e251
657 +---o | | changeset: 6:b105a072e251
658 | |/ / / parent: 2:3d9a33b8d1e1
658 | |/ / / parent: 2:3d9a33b8d1e1
659 | | | | parent: 5:4409d547b708
659 | | | | parent: 5:4409d547b708
660 | | | | user: test
660 | | | | user: test
661 | | | | date: Thu Jan 01 00:00:06 1970 +0000
661 | | | | date: Thu Jan 01 00:00:06 1970 +0000
662 | | | | summary: (6) merge two known; one immediate left, one far left
662 | | | | summary: (6) merge two known; one immediate left, one far left
663 | | | |
663 | | | |
664 | o | | changeset: 5:4409d547b708
664 | o | | changeset: 5:4409d547b708
665 | |\ \ \ parent: 3:27eef8ed80b4
665 | |\ \ \ parent: 3:27eef8ed80b4
666 | | | | | parent: 4:26a8bac39d9f
666 | | | | | parent: 4:26a8bac39d9f
667 | | | | | user: test
667 | | | | | user: test
668 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
668 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
669 | | | | | summary: (5) expand
669 | | | | | summary: (5) expand
670 | | | | |
670 | | | | |
671 | | o | | changeset: 4:26a8bac39d9f
671 | | o | | changeset: 4:26a8bac39d9f
672 | |/|/ / parent: 1:6db2ef61d156
672 | |/|/ / parent: 1:6db2ef61d156
673 | | | | parent: 3:27eef8ed80b4
673 | | | | parent: 3:27eef8ed80b4
674 | | | | user: test
674 | | | | user: test
675 | | | | date: Thu Jan 01 00:00:04 1970 +0000
675 | | | | date: Thu Jan 01 00:00:04 1970 +0000
676 | | | | summary: (4) merge two known; one immediate left, one immediate right
676 | | | | summary: (4) merge two known; one immediate left, one immediate right
677 | | | |
677 | | | |
678 | o | | changeset: 3:27eef8ed80b4
678 | o | | changeset: 3:27eef8ed80b4
679 |/ / / user: test
679 |/ / / user: test
680 | | | date: Thu Jan 01 00:00:03 1970 +0000
680 | | | date: Thu Jan 01 00:00:03 1970 +0000
681 | | | summary: (3) collapse
681 | | | summary: (3) collapse
682 | | |
682 | | |
683 o | | changeset: 2:3d9a33b8d1e1
683 o | | changeset: 2:3d9a33b8d1e1
684 |/ / user: test
684 |/ / user: test
685 | | date: Thu Jan 01 00:00:02 1970 +0000
685 | | date: Thu Jan 01 00:00:02 1970 +0000
686 | | summary: (2) collapse
686 | | summary: (2) collapse
687 | |
687 | |
688 o | changeset: 1:6db2ef61d156
688 o | changeset: 1:6db2ef61d156
689 |/ user: test
689 |/ user: test
690 | date: Thu Jan 01 00:00:01 1970 +0000
690 | date: Thu Jan 01 00:00:01 1970 +0000
691 | summary: (1) collapse
691 | summary: (1) collapse
692 |
692 |
693 o changeset: 0:e6eb3150255d
693 o changeset: 0:e6eb3150255d
694 user: test
694 user: test
695 date: Thu Jan 01 00:00:00 1970 +0000
695 date: Thu Jan 01 00:00:00 1970 +0000
696 summary: (0) root
696 summary: (0) root
697
697
698
698
699 File glog per revset:
699 File glog per revset:
700
700
701 $ hg log -G -r 'file("a")'
701 $ hg log -G -r 'file("a")'
702 @ changeset: 34:fea3ac5810e0
702 @ changeset: 34:fea3ac5810e0
703 | tag: tip
703 | tag: tip
704 | parent: 32:d06dffa21a31
704 | parent: 32:d06dffa21a31
705 | user: test
705 | user: test
706 | date: Thu Jan 01 00:00:34 1970 +0000
706 | date: Thu Jan 01 00:00:34 1970 +0000
707 | summary: (34) head
707 | summary: (34) head
708 |
708 |
709 | o changeset: 33:68608f5145f9
709 | o changeset: 33:68608f5145f9
710 | | parent: 18:1aa84d96232a
710 | | parent: 18:1aa84d96232a
711 | | user: test
711 | | user: test
712 | | date: Thu Jan 01 00:00:33 1970 +0000
712 | | date: Thu Jan 01 00:00:33 1970 +0000
713 | | summary: (33) head
713 | | summary: (33) head
714 | |
714 | |
715 o | changeset: 32:d06dffa21a31
715 o | changeset: 32:d06dffa21a31
716 |\ \ parent: 27:886ed638191b
716 |\ \ parent: 27:886ed638191b
717 | | | parent: 31:621d83e11f67
717 | | | parent: 31:621d83e11f67
718 | | | user: test
718 | | | user: test
719 | | | date: Thu Jan 01 00:00:32 1970 +0000
719 | | | date: Thu Jan 01 00:00:32 1970 +0000
720 | | | summary: (32) expand
720 | | | summary: (32) expand
721 | | |
721 | | |
722 | o | changeset: 31:621d83e11f67
722 | o | changeset: 31:621d83e11f67
723 | |\ \ parent: 21:d42a756af44d
723 | |\ \ parent: 21:d42a756af44d
724 | | | | parent: 30:6e11cd4b648f
724 | | | | parent: 30:6e11cd4b648f
725 | | | | user: test
725 | | | | user: test
726 | | | | date: Thu Jan 01 00:00:31 1970 +0000
726 | | | | date: Thu Jan 01 00:00:31 1970 +0000
727 | | | | summary: (31) expand
727 | | | | summary: (31) expand
728 | | | |
728 | | | |
729 | | o | changeset: 30:6e11cd4b648f
729 | | o | changeset: 30:6e11cd4b648f
730 | | |\ \ parent: 28:44ecd0b9ae99
730 | | |\ \ parent: 28:44ecd0b9ae99
731 | | | | | parent: 29:cd9bb2be7593
731 | | | | | parent: 29:cd9bb2be7593
732 | | | | | user: test
732 | | | | | user: test
733 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
733 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
734 | | | | | summary: (30) expand
734 | | | | | summary: (30) expand
735 | | | | |
735 | | | | |
736 | | | o | changeset: 29:cd9bb2be7593
736 | | | o | changeset: 29:cd9bb2be7593
737 | | | | | parent: 0:e6eb3150255d
737 | | | | | parent: 0:e6eb3150255d
738 | | | | | user: test
738 | | | | | user: test
739 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
739 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
740 | | | | | summary: (29) regular commit
740 | | | | | summary: (29) regular commit
741 | | | | |
741 | | | | |
742 | | o | | changeset: 28:44ecd0b9ae99
742 | | o | | changeset: 28:44ecd0b9ae99
743 | | |\ \ \ parent: 1:6db2ef61d156
743 | | |\ \ \ parent: 1:6db2ef61d156
744 | | | | | | parent: 26:7f25b6c2f0b9
744 | | | | | | parent: 26:7f25b6c2f0b9
745 | | | | | | user: test
745 | | | | | | user: test
746 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
746 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
747 | | | | | | summary: (28) merge zero known
747 | | | | | | summary: (28) merge zero known
748 | | | | | |
748 | | | | | |
749 o | | | | | changeset: 27:886ed638191b
749 o | | | | | changeset: 27:886ed638191b
750 |/ / / / / parent: 21:d42a756af44d
750 |/ / / / / parent: 21:d42a756af44d
751 | | | | | user: test
751 | | | | | user: test
752 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
752 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
753 | | | | | summary: (27) collapse
753 | | | | | summary: (27) collapse
754 | | | | |
754 | | | | |
755 | | o---+ changeset: 26:7f25b6c2f0b9
755 | | o---+ changeset: 26:7f25b6c2f0b9
756 | | | | | parent: 18:1aa84d96232a
756 | | | | | parent: 18:1aa84d96232a
757 | | | | | parent: 25:91da8ed57247
757 | | | | | parent: 25:91da8ed57247
758 | | | | | user: test
758 | | | | | user: test
759 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
759 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
760 | | | | | summary: (26) merge one known; far right
760 | | | | | summary: (26) merge one known; far right
761 | | | | |
761 | | | | |
762 +---o | | changeset: 25:91da8ed57247
762 +---o | | changeset: 25:91da8ed57247
763 | | | | | parent: 21:d42a756af44d
763 | | | | | parent: 21:d42a756af44d
764 | | | | | parent: 24:a9c19a3d96b7
764 | | | | | parent: 24:a9c19a3d96b7
765 | | | | | user: test
765 | | | | | user: test
766 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
766 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
767 | | | | | summary: (25) merge one known; far left
767 | | | | | summary: (25) merge one known; far left
768 | | | | |
768 | | | | |
769 | | o | | changeset: 24:a9c19a3d96b7
769 | | o | | changeset: 24:a9c19a3d96b7
770 | | |\| | parent: 0:e6eb3150255d
770 | | |\| | parent: 0:e6eb3150255d
771 | | | | | parent: 23:a01cddf0766d
771 | | | | | parent: 23:a01cddf0766d
772 | | | | | user: test
772 | | | | | user: test
773 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
773 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
774 | | | | | summary: (24) merge one known; immediate right
774 | | | | | summary: (24) merge one known; immediate right
775 | | | | |
775 | | | | |
776 | | o | | changeset: 23:a01cddf0766d
776 | | o | | changeset: 23:a01cddf0766d
777 | |/| | | parent: 1:6db2ef61d156
777 | |/| | | parent: 1:6db2ef61d156
778 | | | | | parent: 22:e0d9cccacb5d
778 | | | | | parent: 22:e0d9cccacb5d
779 | | | | | user: test
779 | | | | | user: test
780 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
780 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
781 | | | | | summary: (23) merge one known; immediate left
781 | | | | | summary: (23) merge one known; immediate left
782 | | | | |
782 | | | | |
783 +---o---+ changeset: 22:e0d9cccacb5d
783 +---o---+ changeset: 22:e0d9cccacb5d
784 | | | | parent: 18:1aa84d96232a
784 | | | | parent: 18:1aa84d96232a
785 | | / / parent: 21:d42a756af44d
785 | | / / parent: 21:d42a756af44d
786 | | | | user: test
786 | | | | user: test
787 | | | | date: Thu Jan 01 00:00:22 1970 +0000
787 | | | | date: Thu Jan 01 00:00:22 1970 +0000
788 | | | | summary: (22) merge two known; one far left, one far right
788 | | | | summary: (22) merge two known; one far left, one far right
789 | | | |
789 | | | |
790 o | | | changeset: 21:d42a756af44d
790 o | | | changeset: 21:d42a756af44d
791 |\ \ \ \ parent: 19:31ddc2c1573b
791 |\ \ \ \ parent: 19:31ddc2c1573b
792 | | | | | parent: 20:d30ed6450e32
792 | | | | | parent: 20:d30ed6450e32
793 | | | | | user: test
793 | | | | | user: test
794 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
794 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
795 | | | | | summary: (21) expand
795 | | | | | summary: (21) expand
796 | | | | |
796 | | | | |
797 | o---+-+ changeset: 20:d30ed6450e32
797 | o---+-+ changeset: 20:d30ed6450e32
798 | | | | parent: 0:e6eb3150255d
798 | | | | parent: 0:e6eb3150255d
799 | / / / parent: 18:1aa84d96232a
799 | / / / parent: 18:1aa84d96232a
800 | | | | user: test
800 | | | | user: test
801 | | | | date: Thu Jan 01 00:00:20 1970 +0000
801 | | | | date: Thu Jan 01 00:00:20 1970 +0000
802 | | | | summary: (20) merge two known; two far right
802 | | | | summary: (20) merge two known; two far right
803 | | | |
803 | | | |
804 o | | | changeset: 19:31ddc2c1573b
804 o | | | changeset: 19:31ddc2c1573b
805 |\ \ \ \ parent: 15:1dda3f72782d
805 |\ \ \ \ parent: 15:1dda3f72782d
806 | | | | | parent: 17:44765d7c06e0
806 | | | | | parent: 17:44765d7c06e0
807 | | | | | user: test
807 | | | | | user: test
808 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
808 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
809 | | | | | summary: (19) expand
809 | | | | | summary: (19) expand
810 | | | | |
810 | | | | |
811 +---+---o changeset: 18:1aa84d96232a
811 +---+---o changeset: 18:1aa84d96232a
812 | | | | parent: 1:6db2ef61d156
812 | | | | parent: 1:6db2ef61d156
813 | | | | parent: 15:1dda3f72782d
813 | | | | parent: 15:1dda3f72782d
814 | | | | user: test
814 | | | | user: test
815 | | | | date: Thu Jan 01 00:00:18 1970 +0000
815 | | | | date: Thu Jan 01 00:00:18 1970 +0000
816 | | | | summary: (18) merge two known; two far left
816 | | | | summary: (18) merge two known; two far left
817 | | | |
817 | | | |
818 | o | | changeset: 17:44765d7c06e0
818 | o | | changeset: 17:44765d7c06e0
819 | |\ \ \ parent: 12:86b91144a6e9
819 | |\ \ \ parent: 12:86b91144a6e9
820 | | | | | parent: 16:3677d192927d
820 | | | | | parent: 16:3677d192927d
821 | | | | | user: test
821 | | | | | user: test
822 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
822 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
823 | | | | | summary: (17) expand
823 | | | | | summary: (17) expand
824 | | | | |
824 | | | | |
825 | | o---+ changeset: 16:3677d192927d
825 | | o---+ changeset: 16:3677d192927d
826 | | | | | parent: 0:e6eb3150255d
826 | | | | | parent: 0:e6eb3150255d
827 | | |/ / parent: 1:6db2ef61d156
827 | | |/ / parent: 1:6db2ef61d156
828 | | | | user: test
828 | | | | user: test
829 | | | | date: Thu Jan 01 00:00:16 1970 +0000
829 | | | | date: Thu Jan 01 00:00:16 1970 +0000
830 | | | | summary: (16) merge two known; one immediate right, one near right
830 | | | | summary: (16) merge two known; one immediate right, one near right
831 | | | |
831 | | | |
832 o | | | changeset: 15:1dda3f72782d
832 o | | | changeset: 15:1dda3f72782d
833 |\ \ \ \ parent: 13:22d8966a97e3
833 |\ \ \ \ parent: 13:22d8966a97e3
834 | | | | | parent: 14:8eac370358ef
834 | | | | | parent: 14:8eac370358ef
835 | | | | | user: test
835 | | | | | user: test
836 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
836 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
837 | | | | | summary: (15) expand
837 | | | | | summary: (15) expand
838 | | | | |
838 | | | | |
839 | o-----+ changeset: 14:8eac370358ef
839 | o-----+ changeset: 14:8eac370358ef
840 | | | | | parent: 0:e6eb3150255d
840 | | | | | parent: 0:e6eb3150255d
841 | |/ / / parent: 12:86b91144a6e9
841 | |/ / / parent: 12:86b91144a6e9
842 | | | | user: test
842 | | | | user: test
843 | | | | date: Thu Jan 01 00:00:14 1970 +0000
843 | | | | date: Thu Jan 01 00:00:14 1970 +0000
844 | | | | summary: (14) merge two known; one immediate right, one far right
844 | | | | summary: (14) merge two known; one immediate right, one far right
845 | | | |
845 | | | |
846 o | | | changeset: 13:22d8966a97e3
846 o | | | changeset: 13:22d8966a97e3
847 |\ \ \ \ parent: 9:7010c0af0a35
847 |\ \ \ \ parent: 9:7010c0af0a35
848 | | | | | parent: 11:832d76e6bdf2
848 | | | | | parent: 11:832d76e6bdf2
849 | | | | | user: test
849 | | | | | user: test
850 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
850 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
851 | | | | | summary: (13) expand
851 | | | | | summary: (13) expand
852 | | | | |
852 | | | | |
853 +---o | | changeset: 12:86b91144a6e9
853 +---o | | changeset: 12:86b91144a6e9
854 | | |/ / parent: 1:6db2ef61d156
854 | | |/ / parent: 1:6db2ef61d156
855 | | | | parent: 9:7010c0af0a35
855 | | | | parent: 9:7010c0af0a35
856 | | | | user: test
856 | | | | user: test
857 | | | | date: Thu Jan 01 00:00:12 1970 +0000
857 | | | | date: Thu Jan 01 00:00:12 1970 +0000
858 | | | | summary: (12) merge two known; one immediate right, one far left
858 | | | | summary: (12) merge two known; one immediate right, one far left
859 | | | |
859 | | | |
860 | o | | changeset: 11:832d76e6bdf2
860 | o | | changeset: 11:832d76e6bdf2
861 | |\ \ \ parent: 6:b105a072e251
861 | |\ \ \ parent: 6:b105a072e251
862 | | | | | parent: 10:74c64d036d72
862 | | | | | parent: 10:74c64d036d72
863 | | | | | user: test
863 | | | | | user: test
864 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
864 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
865 | | | | | summary: (11) expand
865 | | | | | summary: (11) expand
866 | | | | |
866 | | | | |
867 | | o---+ changeset: 10:74c64d036d72
867 | | o---+ changeset: 10:74c64d036d72
868 | | | | | parent: 0:e6eb3150255d
868 | | | | | parent: 0:e6eb3150255d
869 | |/ / / parent: 6:b105a072e251
869 | |/ / / parent: 6:b105a072e251
870 | | | | user: test
870 | | | | user: test
871 | | | | date: Thu Jan 01 00:00:10 1970 +0000
871 | | | | date: Thu Jan 01 00:00:10 1970 +0000
872 | | | | summary: (10) merge two known; one immediate left, one near right
872 | | | | summary: (10) merge two known; one immediate left, one near right
873 | | | |
873 | | | |
874 o | | | changeset: 9:7010c0af0a35
874 o | | | changeset: 9:7010c0af0a35
875 |\ \ \ \ parent: 7:b632bb1b1224
875 |\ \ \ \ parent: 7:b632bb1b1224
876 | | | | | parent: 8:7a0b11f71937
876 | | | | | parent: 8:7a0b11f71937
877 | | | | | user: test
877 | | | | | user: test
878 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
878 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
879 | | | | | summary: (9) expand
879 | | | | | summary: (9) expand
880 | | | | |
880 | | | | |
881 | o-----+ changeset: 8:7a0b11f71937
881 | o-----+ changeset: 8:7a0b11f71937
882 | | | | | parent: 0:e6eb3150255d
882 | | | | | parent: 0:e6eb3150255d
883 |/ / / / parent: 7:b632bb1b1224
883 |/ / / / parent: 7:b632bb1b1224
884 | | | | user: test
884 | | | | user: test
885 | | | | date: Thu Jan 01 00:00:08 1970 +0000
885 | | | | date: Thu Jan 01 00:00:08 1970 +0000
886 | | | | summary: (8) merge two known; one immediate left, one far right
886 | | | | summary: (8) merge two known; one immediate left, one far right
887 | | | |
887 | | | |
888 o | | | changeset: 7:b632bb1b1224
888 o | | | changeset: 7:b632bb1b1224
889 |\ \ \ \ parent: 2:3d9a33b8d1e1
889 |\ \ \ \ parent: 2:3d9a33b8d1e1
890 | | | | | parent: 5:4409d547b708
890 | | | | | parent: 5:4409d547b708
891 | | | | | user: test
891 | | | | | user: test
892 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
892 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
893 | | | | | summary: (7) expand
893 | | | | | summary: (7) expand
894 | | | | |
894 | | | | |
895 +---o | | changeset: 6:b105a072e251
895 +---o | | changeset: 6:b105a072e251
896 | |/ / / parent: 2:3d9a33b8d1e1
896 | |/ / / parent: 2:3d9a33b8d1e1
897 | | | | parent: 5:4409d547b708
897 | | | | parent: 5:4409d547b708
898 | | | | user: test
898 | | | | user: test
899 | | | | date: Thu Jan 01 00:00:06 1970 +0000
899 | | | | date: Thu Jan 01 00:00:06 1970 +0000
900 | | | | summary: (6) merge two known; one immediate left, one far left
900 | | | | summary: (6) merge two known; one immediate left, one far left
901 | | | |
901 | | | |
902 | o | | changeset: 5:4409d547b708
902 | o | | changeset: 5:4409d547b708
903 | |\ \ \ parent: 3:27eef8ed80b4
903 | |\ \ \ parent: 3:27eef8ed80b4
904 | | | | | parent: 4:26a8bac39d9f
904 | | | | | parent: 4:26a8bac39d9f
905 | | | | | user: test
905 | | | | | user: test
906 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
906 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
907 | | | | | summary: (5) expand
907 | | | | | summary: (5) expand
908 | | | | |
908 | | | | |
909 | | o | | changeset: 4:26a8bac39d9f
909 | | o | | changeset: 4:26a8bac39d9f
910 | |/|/ / parent: 1:6db2ef61d156
910 | |/|/ / parent: 1:6db2ef61d156
911 | | | | parent: 3:27eef8ed80b4
911 | | | | parent: 3:27eef8ed80b4
912 | | | | user: test
912 | | | | user: test
913 | | | | date: Thu Jan 01 00:00:04 1970 +0000
913 | | | | date: Thu Jan 01 00:00:04 1970 +0000
914 | | | | summary: (4) merge two known; one immediate left, one immediate right
914 | | | | summary: (4) merge two known; one immediate left, one immediate right
915 | | | |
915 | | | |
916 | o | | changeset: 3:27eef8ed80b4
916 | o | | changeset: 3:27eef8ed80b4
917 |/ / / user: test
917 |/ / / user: test
918 | | | date: Thu Jan 01 00:00:03 1970 +0000
918 | | | date: Thu Jan 01 00:00:03 1970 +0000
919 | | | summary: (3) collapse
919 | | | summary: (3) collapse
920 | | |
920 | | |
921 o | | changeset: 2:3d9a33b8d1e1
921 o | | changeset: 2:3d9a33b8d1e1
922 |/ / user: test
922 |/ / user: test
923 | | date: Thu Jan 01 00:00:02 1970 +0000
923 | | date: Thu Jan 01 00:00:02 1970 +0000
924 | | summary: (2) collapse
924 | | summary: (2) collapse
925 | |
925 | |
926 o | changeset: 1:6db2ef61d156
926 o | changeset: 1:6db2ef61d156
927 |/ user: test
927 |/ user: test
928 | date: Thu Jan 01 00:00:01 1970 +0000
928 | date: Thu Jan 01 00:00:01 1970 +0000
929 | summary: (1) collapse
929 | summary: (1) collapse
930 |
930 |
931 o changeset: 0:e6eb3150255d
931 o changeset: 0:e6eb3150255d
932 user: test
932 user: test
933 date: Thu Jan 01 00:00:00 1970 +0000
933 date: Thu Jan 01 00:00:00 1970 +0000
934 summary: (0) root
934 summary: (0) root
935
935
936
936
937
937
938 File glog per revset (only merges):
938 File glog per revset (only merges):
939
939
940 $ hg log -G -r 'file("a")' -m
940 $ hg log -G -r 'file("a")' -m
941 o changeset: 32:d06dffa21a31
941 o changeset: 32:d06dffa21a31
942 |\ parent: 27:886ed638191b
942 |\ parent: 27:886ed638191b
943 | | parent: 31:621d83e11f67
943 | | parent: 31:621d83e11f67
944 | | user: test
944 | | user: test
945 | | date: Thu Jan 01 00:00:32 1970 +0000
945 | | date: Thu Jan 01 00:00:32 1970 +0000
946 | | summary: (32) expand
946 | | summary: (32) expand
947 | |
947 | |
948 o | changeset: 31:621d83e11f67
948 o | changeset: 31:621d83e11f67
949 |\| parent: 21:d42a756af44d
949 |\| parent: 21:d42a756af44d
950 | | parent: 30:6e11cd4b648f
950 | | parent: 30:6e11cd4b648f
951 | | user: test
951 | | user: test
952 | | date: Thu Jan 01 00:00:31 1970 +0000
952 | | date: Thu Jan 01 00:00:31 1970 +0000
953 | | summary: (31) expand
953 | | summary: (31) expand
954 | |
954 | |
955 o | changeset: 30:6e11cd4b648f
955 o | changeset: 30:6e11cd4b648f
956 |\ \ parent: 28:44ecd0b9ae99
956 |\ \ parent: 28:44ecd0b9ae99
957 | | | parent: 29:cd9bb2be7593
957 | | | parent: 29:cd9bb2be7593
958 | | | user: test
958 | | | user: test
959 | | | date: Thu Jan 01 00:00:30 1970 +0000
959 | | | date: Thu Jan 01 00:00:30 1970 +0000
960 | | | summary: (30) expand
960 | | | summary: (30) expand
961 | | |
961 | | |
962 o | | changeset: 28:44ecd0b9ae99
962 o | | changeset: 28:44ecd0b9ae99
963 |\ \ \ parent: 1:6db2ef61d156
963 |\ \ \ parent: 1:6db2ef61d156
964 | | | | parent: 26:7f25b6c2f0b9
964 | | | | parent: 26:7f25b6c2f0b9
965 | | | | user: test
965 | | | | user: test
966 | | | | date: Thu Jan 01 00:00:28 1970 +0000
966 | | | | date: Thu Jan 01 00:00:28 1970 +0000
967 | | | | summary: (28) merge zero known
967 | | | | summary: (28) merge zero known
968 | | | |
968 | | | |
969 o | | | changeset: 26:7f25b6c2f0b9
969 o | | | changeset: 26:7f25b6c2f0b9
970 |\ \ \ \ parent: 18:1aa84d96232a
970 |\ \ \ \ parent: 18:1aa84d96232a
971 | | | | | parent: 25:91da8ed57247
971 | | | | | parent: 25:91da8ed57247
972 | | | | | user: test
972 | | | | | user: test
973 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
973 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
974 | | | | | summary: (26) merge one known; far right
974 | | | | | summary: (26) merge one known; far right
975 | | | | |
975 | | | | |
976 | o-----+ changeset: 25:91da8ed57247
976 | o-----+ changeset: 25:91da8ed57247
977 | | | | | parent: 21:d42a756af44d
977 | | | | | parent: 21:d42a756af44d
978 | | | | | parent: 24:a9c19a3d96b7
978 | | | | | parent: 24:a9c19a3d96b7
979 | | | | | user: test
979 | | | | | user: test
980 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
980 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
981 | | | | | summary: (25) merge one known; far left
981 | | | | | summary: (25) merge one known; far left
982 | | | | |
982 | | | | |
983 | o | | | changeset: 24:a9c19a3d96b7
983 | o | | | changeset: 24:a9c19a3d96b7
984 | |\ \ \ \ parent: 0:e6eb3150255d
984 | |\ \ \ \ parent: 0:e6eb3150255d
985 | | | | | | parent: 23:a01cddf0766d
985 | | | | | | parent: 23:a01cddf0766d
986 | | | | | | user: test
986 | | | | | | user: test
987 | | | | | | date: Thu Jan 01 00:00:24 1970 +0000
987 | | | | | | date: Thu Jan 01 00:00:24 1970 +0000
988 | | | | | | summary: (24) merge one known; immediate right
988 | | | | | | summary: (24) merge one known; immediate right
989 | | | | | |
989 | | | | | |
990 | o---+ | | changeset: 23:a01cddf0766d
990 | o---+ | | changeset: 23:a01cddf0766d
991 | | | | | | parent: 1:6db2ef61d156
991 | | | | | | parent: 1:6db2ef61d156
992 | | | | | | parent: 22:e0d9cccacb5d
992 | | | | | | parent: 22:e0d9cccacb5d
993 | | | | | | user: test
993 | | | | | | user: test
994 | | | | | | date: Thu Jan 01 00:00:23 1970 +0000
994 | | | | | | date: Thu Jan 01 00:00:23 1970 +0000
995 | | | | | | summary: (23) merge one known; immediate left
995 | | | | | | summary: (23) merge one known; immediate left
996 | | | | | |
996 | | | | | |
997 | o-------+ changeset: 22:e0d9cccacb5d
997 | o-------+ changeset: 22:e0d9cccacb5d
998 | | | | | | parent: 18:1aa84d96232a
998 | | | | | | parent: 18:1aa84d96232a
999 |/ / / / / parent: 21:d42a756af44d
999 |/ / / / / parent: 21:d42a756af44d
1000 | | | | | user: test
1000 | | | | | user: test
1001 | | | | | date: Thu Jan 01 00:00:22 1970 +0000
1001 | | | | | date: Thu Jan 01 00:00:22 1970 +0000
1002 | | | | | summary: (22) merge two known; one far left, one far right
1002 | | | | | summary: (22) merge two known; one far left, one far right
1003 | | | | |
1003 | | | | |
1004 | | | | o changeset: 21:d42a756af44d
1004 | | | | o changeset: 21:d42a756af44d
1005 | | | | |\ parent: 19:31ddc2c1573b
1005 | | | | |\ parent: 19:31ddc2c1573b
1006 | | | | | | parent: 20:d30ed6450e32
1006 | | | | | | parent: 20:d30ed6450e32
1007 | | | | | | user: test
1007 | | | | | | user: test
1008 | | | | | | date: Thu Jan 01 00:00:21 1970 +0000
1008 | | | | | | date: Thu Jan 01 00:00:21 1970 +0000
1009 | | | | | | summary: (21) expand
1009 | | | | | | summary: (21) expand
1010 | | | | | |
1010 | | | | | |
1011 +-+-------o changeset: 20:d30ed6450e32
1011 +-+-------o changeset: 20:d30ed6450e32
1012 | | | | | parent: 0:e6eb3150255d
1012 | | | | | parent: 0:e6eb3150255d
1013 | | | | | parent: 18:1aa84d96232a
1013 | | | | | parent: 18:1aa84d96232a
1014 | | | | | user: test
1014 | | | | | user: test
1015 | | | | | date: Thu Jan 01 00:00:20 1970 +0000
1015 | | | | | date: Thu Jan 01 00:00:20 1970 +0000
1016 | | | | | summary: (20) merge two known; two far right
1016 | | | | | summary: (20) merge two known; two far right
1017 | | | | |
1017 | | | | |
1018 | | | | o changeset: 19:31ddc2c1573b
1018 | | | | o changeset: 19:31ddc2c1573b
1019 | | | | |\ parent: 15:1dda3f72782d
1019 | | | | |\ parent: 15:1dda3f72782d
1020 | | | | | | parent: 17:44765d7c06e0
1020 | | | | | | parent: 17:44765d7c06e0
1021 | | | | | | user: test
1021 | | | | | | user: test
1022 | | | | | | date: Thu Jan 01 00:00:19 1970 +0000
1022 | | | | | | date: Thu Jan 01 00:00:19 1970 +0000
1023 | | | | | | summary: (19) expand
1023 | | | | | | summary: (19) expand
1024 | | | | | |
1024 | | | | | |
1025 o---+---+ | changeset: 18:1aa84d96232a
1025 o---+---+ | changeset: 18:1aa84d96232a
1026 | | | | | parent: 1:6db2ef61d156
1026 | | | | | parent: 1:6db2ef61d156
1027 / / / / / parent: 15:1dda3f72782d
1027 / / / / / parent: 15:1dda3f72782d
1028 | | | | | user: test
1028 | | | | | user: test
1029 | | | | | date: Thu Jan 01 00:00:18 1970 +0000
1029 | | | | | date: Thu Jan 01 00:00:18 1970 +0000
1030 | | | | | summary: (18) merge two known; two far left
1030 | | | | | summary: (18) merge two known; two far left
1031 | | | | |
1031 | | | | |
1032 | | | | o changeset: 17:44765d7c06e0
1032 | | | | o changeset: 17:44765d7c06e0
1033 | | | | |\ parent: 12:86b91144a6e9
1033 | | | | |\ parent: 12:86b91144a6e9
1034 | | | | | | parent: 16:3677d192927d
1034 | | | | | | parent: 16:3677d192927d
1035 | | | | | | user: test
1035 | | | | | | user: test
1036 | | | | | | date: Thu Jan 01 00:00:17 1970 +0000
1036 | | | | | | date: Thu Jan 01 00:00:17 1970 +0000
1037 | | | | | | summary: (17) expand
1037 | | | | | | summary: (17) expand
1038 | | | | | |
1038 | | | | | |
1039 +-+-------o changeset: 16:3677d192927d
1039 +-+-------o changeset: 16:3677d192927d
1040 | | | | | parent: 0:e6eb3150255d
1040 | | | | | parent: 0:e6eb3150255d
1041 | | | | | parent: 1:6db2ef61d156
1041 | | | | | parent: 1:6db2ef61d156
1042 | | | | | user: test
1042 | | | | | user: test
1043 | | | | | date: Thu Jan 01 00:00:16 1970 +0000
1043 | | | | | date: Thu Jan 01 00:00:16 1970 +0000
1044 | | | | | summary: (16) merge two known; one immediate right, one near right
1044 | | | | | summary: (16) merge two known; one immediate right, one near right
1045 | | | | |
1045 | | | | |
1046 | | | o | changeset: 15:1dda3f72782d
1046 | | | o | changeset: 15:1dda3f72782d
1047 | | | |\ \ parent: 13:22d8966a97e3
1047 | | | |\ \ parent: 13:22d8966a97e3
1048 | | | | | | parent: 14:8eac370358ef
1048 | | | | | | parent: 14:8eac370358ef
1049 | | | | | | user: test
1049 | | | | | | user: test
1050 | | | | | | date: Thu Jan 01 00:00:15 1970 +0000
1050 | | | | | | date: Thu Jan 01 00:00:15 1970 +0000
1051 | | | | | | summary: (15) expand
1051 | | | | | | summary: (15) expand
1052 | | | | | |
1052 | | | | | |
1053 +-------o | changeset: 14:8eac370358ef
1053 +-------o | changeset: 14:8eac370358ef
1054 | | | | |/ parent: 0:e6eb3150255d
1054 | | | | |/ parent: 0:e6eb3150255d
1055 | | | | | parent: 12:86b91144a6e9
1055 | | | | | parent: 12:86b91144a6e9
1056 | | | | | user: test
1056 | | | | | user: test
1057 | | | | | date: Thu Jan 01 00:00:14 1970 +0000
1057 | | | | | date: Thu Jan 01 00:00:14 1970 +0000
1058 | | | | | summary: (14) merge two known; one immediate right, one far right
1058 | | | | | summary: (14) merge two known; one immediate right, one far right
1059 | | | | |
1059 | | | | |
1060 | | | o | changeset: 13:22d8966a97e3
1060 | | | o | changeset: 13:22d8966a97e3
1061 | | | |\ \ parent: 9:7010c0af0a35
1061 | | | |\ \ parent: 9:7010c0af0a35
1062 | | | | | | parent: 11:832d76e6bdf2
1062 | | | | | | parent: 11:832d76e6bdf2
1063 | | | | | | user: test
1063 | | | | | | user: test
1064 | | | | | | date: Thu Jan 01 00:00:13 1970 +0000
1064 | | | | | | date: Thu Jan 01 00:00:13 1970 +0000
1065 | | | | | | summary: (13) expand
1065 | | | | | | summary: (13) expand
1066 | | | | | |
1066 | | | | | |
1067 | +---+---o changeset: 12:86b91144a6e9
1067 | +---+---o changeset: 12:86b91144a6e9
1068 | | | | | parent: 1:6db2ef61d156
1068 | | | | | parent: 1:6db2ef61d156
1069 | | | | | parent: 9:7010c0af0a35
1069 | | | | | parent: 9:7010c0af0a35
1070 | | | | | user: test
1070 | | | | | user: test
1071 | | | | | date: Thu Jan 01 00:00:12 1970 +0000
1071 | | | | | date: Thu Jan 01 00:00:12 1970 +0000
1072 | | | | | summary: (12) merge two known; one immediate right, one far left
1072 | | | | | summary: (12) merge two known; one immediate right, one far left
1073 | | | | |
1073 | | | | |
1074 | | | | o changeset: 11:832d76e6bdf2
1074 | | | | o changeset: 11:832d76e6bdf2
1075 | | | | |\ parent: 6:b105a072e251
1075 | | | | |\ parent: 6:b105a072e251
1076 | | | | | | parent: 10:74c64d036d72
1076 | | | | | | parent: 10:74c64d036d72
1077 | | | | | | user: test
1077 | | | | | | user: test
1078 | | | | | | date: Thu Jan 01 00:00:11 1970 +0000
1078 | | | | | | date: Thu Jan 01 00:00:11 1970 +0000
1079 | | | | | | summary: (11) expand
1079 | | | | | | summary: (11) expand
1080 | | | | | |
1080 | | | | | |
1081 +---------o changeset: 10:74c64d036d72
1081 +---------o changeset: 10:74c64d036d72
1082 | | | | |/ parent: 0:e6eb3150255d
1082 | | | | |/ parent: 0:e6eb3150255d
1083 | | | | | parent: 6:b105a072e251
1083 | | | | | parent: 6:b105a072e251
1084 | | | | | user: test
1084 | | | | | user: test
1085 | | | | | date: Thu Jan 01 00:00:10 1970 +0000
1085 | | | | | date: Thu Jan 01 00:00:10 1970 +0000
1086 | | | | | summary: (10) merge two known; one immediate left, one near right
1086 | | | | | summary: (10) merge two known; one immediate left, one near right
1087 | | | | |
1087 | | | | |
1088 | | | o | changeset: 9:7010c0af0a35
1088 | | | o | changeset: 9:7010c0af0a35
1089 | | | |\ \ parent: 7:b632bb1b1224
1089 | | | |\ \ parent: 7:b632bb1b1224
1090 | | | | | | parent: 8:7a0b11f71937
1090 | | | | | | parent: 8:7a0b11f71937
1091 | | | | | | user: test
1091 | | | | | | user: test
1092 | | | | | | date: Thu Jan 01 00:00:09 1970 +0000
1092 | | | | | | date: Thu Jan 01 00:00:09 1970 +0000
1093 | | | | | | summary: (9) expand
1093 | | | | | | summary: (9) expand
1094 | | | | | |
1094 | | | | | |
1095 +-------o | changeset: 8:7a0b11f71937
1095 +-------o | changeset: 8:7a0b11f71937
1096 | | | |/ / parent: 0:e6eb3150255d
1096 | | | |/ / parent: 0:e6eb3150255d
1097 | | | | | parent: 7:b632bb1b1224
1097 | | | | | parent: 7:b632bb1b1224
1098 | | | | | user: test
1098 | | | | | user: test
1099 | | | | | date: Thu Jan 01 00:00:08 1970 +0000
1099 | | | | | date: Thu Jan 01 00:00:08 1970 +0000
1100 | | | | | summary: (8) merge two known; one immediate left, one far right
1100 | | | | | summary: (8) merge two known; one immediate left, one far right
1101 | | | | |
1101 | | | | |
1102 | | | o | changeset: 7:b632bb1b1224
1102 | | | o | changeset: 7:b632bb1b1224
1103 | | | |\ \ parent: 2:3d9a33b8d1e1
1103 | | | |\ \ parent: 2:3d9a33b8d1e1
1104 | | | | | | parent: 5:4409d547b708
1104 | | | | | | parent: 5:4409d547b708
1105 | | | | | | user: test
1105 | | | | | | user: test
1106 | | | | | | date: Thu Jan 01 00:00:07 1970 +0000
1106 | | | | | | date: Thu Jan 01 00:00:07 1970 +0000
1107 | | | | | | summary: (7) expand
1107 | | | | | | summary: (7) expand
1108 | | | | | |
1108 | | | | | |
1109 | | | +---o changeset: 6:b105a072e251
1109 | | | +---o changeset: 6:b105a072e251
1110 | | | | |/ parent: 2:3d9a33b8d1e1
1110 | | | | |/ parent: 2:3d9a33b8d1e1
1111 | | | | | parent: 5:4409d547b708
1111 | | | | | parent: 5:4409d547b708
1112 | | | | | user: test
1112 | | | | | user: test
1113 | | | | | date: Thu Jan 01 00:00:06 1970 +0000
1113 | | | | | date: Thu Jan 01 00:00:06 1970 +0000
1114 | | | | | summary: (6) merge two known; one immediate left, one far left
1114 | | | | | summary: (6) merge two known; one immediate left, one far left
1115 | | | | |
1115 | | | | |
1116 | | | o | changeset: 5:4409d547b708
1116 | | | o | changeset: 5:4409d547b708
1117 | | | |\ \ parent: 3:27eef8ed80b4
1117 | | | |\ \ parent: 3:27eef8ed80b4
1118 | | | | | | parent: 4:26a8bac39d9f
1118 | | | | | | parent: 4:26a8bac39d9f
1119 | | | | | | user: test
1119 | | | | | | user: test
1120 | | | | | | date: Thu Jan 01 00:00:05 1970 +0000
1120 | | | | | | date: Thu Jan 01 00:00:05 1970 +0000
1121 | | | | | | summary: (5) expand
1121 | | | | | | summary: (5) expand
1122 | | | | | |
1122 | | | | | |
1123 | +---o | | changeset: 4:26a8bac39d9f
1123 | +---o | | changeset: 4:26a8bac39d9f
1124 | | | |/ / parent: 1:6db2ef61d156
1124 | | | |/ / parent: 1:6db2ef61d156
1125 | | | | | parent: 3:27eef8ed80b4
1125 | | | | | parent: 3:27eef8ed80b4
1126 | | | | | user: test
1126 | | | | | user: test
1127 | | | | | date: Thu Jan 01 00:00:04 1970 +0000
1127 | | | | | date: Thu Jan 01 00:00:04 1970 +0000
1128 | | | | | summary: (4) merge two known; one immediate left, one immediate right
1128 | | | | | summary: (4) merge two known; one immediate left, one immediate right
1129 | | | | |
1129 | | | | |
1130
1130
1131
1131
1132 Empty revision range - display nothing:
1132 Empty revision range - display nothing:
1133 $ hg log -G -r 1..0
1133 $ hg log -G -r 1..0
1134
1134
1135 $ cd ..
1135 $ cd ..
1136
1136
1137 #if no-outer-repo
1137 #if no-outer-repo
1138
1138
1139 From outer space:
1139 From outer space:
1140 $ hg log -G -l1 repo
1140 $ hg log -G -l1 repo
1141 @ changeset: 34:fea3ac5810e0
1141 @ changeset: 34:fea3ac5810e0
1142 | tag: tip
1142 | tag: tip
1143 | parent: 32:d06dffa21a31
1143 | parent: 32:d06dffa21a31
1144 | user: test
1144 | user: test
1145 | date: Thu Jan 01 00:00:34 1970 +0000
1145 | date: Thu Jan 01 00:00:34 1970 +0000
1146 | summary: (34) head
1146 | summary: (34) head
1147 |
1147 |
1148 $ hg log -G -l1 repo/a
1148 $ hg log -G -l1 repo/a
1149 @ changeset: 34:fea3ac5810e0
1149 @ changeset: 34:fea3ac5810e0
1150 | tag: tip
1150 | tag: tip
1151 | parent: 32:d06dffa21a31
1151 | parent: 32:d06dffa21a31
1152 | user: test
1152 | user: test
1153 | date: Thu Jan 01 00:00:34 1970 +0000
1153 | date: Thu Jan 01 00:00:34 1970 +0000
1154 | summary: (34) head
1154 | summary: (34) head
1155 |
1155 |
1156 $ hg log -G -l1 repo/missing
1156 $ hg log -G -l1 repo/missing
1157
1157
1158 #endif
1158 #endif
1159
1159
1160 File log with revs != cset revs:
1160 File log with revs != cset revs:
1161 $ hg init flog
1161 $ hg init flog
1162 $ cd flog
1162 $ cd flog
1163 $ echo one >one
1163 $ echo one >one
1164 $ hg add one
1164 $ hg add one
1165 $ hg commit -mone
1165 $ hg commit -mone
1166 $ echo two >two
1166 $ echo two >two
1167 $ hg add two
1167 $ hg add two
1168 $ hg commit -mtwo
1168 $ hg commit -mtwo
1169 $ echo more >two
1169 $ echo more >two
1170 $ hg commit -mmore
1170 $ hg commit -mmore
1171 $ hg log -G two
1171 $ hg log -G two
1172 @ changeset: 2:12c28321755b
1172 @ changeset: 2:12c28321755b
1173 | tag: tip
1173 | tag: tip
1174 | user: test
1174 | user: test
1175 | date: Thu Jan 01 00:00:00 1970 +0000
1175 | date: Thu Jan 01 00:00:00 1970 +0000
1176 | summary: more
1176 | summary: more
1177 |
1177 |
1178 o changeset: 1:5ac72c0599bf
1178 o changeset: 1:5ac72c0599bf
1179 | user: test
1179 | user: test
1180 | date: Thu Jan 01 00:00:00 1970 +0000
1180 | date: Thu Jan 01 00:00:00 1970 +0000
1181 | summary: two
1181 | summary: two
1182 |
1182 |
1183
1183
1184 Issue1896: File log with explicit style
1184 Issue1896: File log with explicit style
1185 $ hg log -G --style=default one
1185 $ hg log -G --style=default one
1186 o changeset: 0:3d578b4a1f53
1186 o changeset: 0:3d578b4a1f53
1187 user: test
1187 user: test
1188 date: Thu Jan 01 00:00:00 1970 +0000
1188 date: Thu Jan 01 00:00:00 1970 +0000
1189 summary: one
1189 summary: one
1190
1190
1191 Issue2395: glog --style header and footer
1191 Issue2395: glog --style header and footer
1192 $ hg log -G --style=xml one
1192 $ hg log -G --style=xml one
1193 <?xml version="1.0"?>
1193 <?xml version="1.0"?>
1194 <log>
1194 <log>
1195 o <logentry revision="0" node="3d578b4a1f537d5fcf7301bfa9c0b97adfaa6fb1">
1195 o <logentry revision="0" node="3d578b4a1f537d5fcf7301bfa9c0b97adfaa6fb1">
1196 <author email="test">test</author>
1196 <author email="test">test</author>
1197 <date>1970-01-01T00:00:00+00:00</date>
1197 <date>1970-01-01T00:00:00+00:00</date>
1198 <msg xml:space="preserve">one</msg>
1198 <msg xml:space="preserve">one</msg>
1199 </logentry>
1199 </logentry>
1200 </log>
1200 </log>
1201
1201
1202 $ cd ..
1202 $ cd ..
1203
1203
1204 Incoming and outgoing:
1204 Incoming and outgoing:
1205
1205
1206 $ hg clone -U -r31 repo repo2
1206 $ hg clone -U -r31 repo repo2
1207 adding changesets
1207 adding changesets
1208 adding manifests
1208 adding manifests
1209 adding file changes
1209 adding file changes
1210 added 31 changesets with 31 changes to 1 files
1210 added 31 changesets with 31 changes to 1 files
1211 $ cd repo2
1211 $ cd repo2
1212
1212
1213 $ hg incoming --graph ../repo
1213 $ hg incoming --graph ../repo
1214 comparing with ../repo
1214 comparing with ../repo
1215 searching for changes
1215 searching for changes
1216 o changeset: 34:fea3ac5810e0
1216 o changeset: 34:fea3ac5810e0
1217 | tag: tip
1217 | tag: tip
1218 | parent: 32:d06dffa21a31
1218 | parent: 32:d06dffa21a31
1219 | user: test
1219 | user: test
1220 | date: Thu Jan 01 00:00:34 1970 +0000
1220 | date: Thu Jan 01 00:00:34 1970 +0000
1221 | summary: (34) head
1221 | summary: (34) head
1222 |
1222 |
1223 | o changeset: 33:68608f5145f9
1223 | o changeset: 33:68608f5145f9
1224 | parent: 18:1aa84d96232a
1224 | parent: 18:1aa84d96232a
1225 | user: test
1225 | user: test
1226 | date: Thu Jan 01 00:00:33 1970 +0000
1226 | date: Thu Jan 01 00:00:33 1970 +0000
1227 | summary: (33) head
1227 | summary: (33) head
1228 |
1228 |
1229 o changeset: 32:d06dffa21a31
1229 o changeset: 32:d06dffa21a31
1230 | parent: 27:886ed638191b
1230 | parent: 27:886ed638191b
1231 | parent: 31:621d83e11f67
1231 | parent: 31:621d83e11f67
1232 | user: test
1232 | user: test
1233 | date: Thu Jan 01 00:00:32 1970 +0000
1233 | date: Thu Jan 01 00:00:32 1970 +0000
1234 | summary: (32) expand
1234 | summary: (32) expand
1235 |
1235 |
1236 o changeset: 27:886ed638191b
1236 o changeset: 27:886ed638191b
1237 parent: 21:d42a756af44d
1237 parent: 21:d42a756af44d
1238 user: test
1238 user: test
1239 date: Thu Jan 01 00:00:27 1970 +0000
1239 date: Thu Jan 01 00:00:27 1970 +0000
1240 summary: (27) collapse
1240 summary: (27) collapse
1241
1241
1242 $ cd ..
1242 $ cd ..
1243
1243
1244 $ hg -R repo outgoing --graph repo2
1244 $ hg -R repo outgoing --graph repo2
1245 comparing with repo2
1245 comparing with repo2
1246 searching for changes
1246 searching for changes
1247 @ changeset: 34:fea3ac5810e0
1247 @ changeset: 34:fea3ac5810e0
1248 | tag: tip
1248 | tag: tip
1249 | parent: 32:d06dffa21a31
1249 | parent: 32:d06dffa21a31
1250 | user: test
1250 | user: test
1251 | date: Thu Jan 01 00:00:34 1970 +0000
1251 | date: Thu Jan 01 00:00:34 1970 +0000
1252 | summary: (34) head
1252 | summary: (34) head
1253 |
1253 |
1254 | o changeset: 33:68608f5145f9
1254 | o changeset: 33:68608f5145f9
1255 | parent: 18:1aa84d96232a
1255 | parent: 18:1aa84d96232a
1256 | user: test
1256 | user: test
1257 | date: Thu Jan 01 00:00:33 1970 +0000
1257 | date: Thu Jan 01 00:00:33 1970 +0000
1258 | summary: (33) head
1258 | summary: (33) head
1259 |
1259 |
1260 o changeset: 32:d06dffa21a31
1260 o changeset: 32:d06dffa21a31
1261 | parent: 27:886ed638191b
1261 | parent: 27:886ed638191b
1262 | parent: 31:621d83e11f67
1262 | parent: 31:621d83e11f67
1263 | user: test
1263 | user: test
1264 | date: Thu Jan 01 00:00:32 1970 +0000
1264 | date: Thu Jan 01 00:00:32 1970 +0000
1265 | summary: (32) expand
1265 | summary: (32) expand
1266 |
1266 |
1267 o changeset: 27:886ed638191b
1267 o changeset: 27:886ed638191b
1268 parent: 21:d42a756af44d
1268 parent: 21:d42a756af44d
1269 user: test
1269 user: test
1270 date: Thu Jan 01 00:00:27 1970 +0000
1270 date: Thu Jan 01 00:00:27 1970 +0000
1271 summary: (27) collapse
1271 summary: (27) collapse
1272
1272
1273
1273
1274 File + limit with revs != cset revs:
1274 File + limit with revs != cset revs:
1275 $ cd repo
1275 $ cd repo
1276 $ touch b
1276 $ touch b
1277 $ hg ci -Aqm0
1277 $ hg ci -Aqm0
1278 $ hg log -G -l2 a
1278 $ hg log -G -l2 a
1279 o changeset: 34:fea3ac5810e0
1279 o changeset: 34:fea3ac5810e0
1280 | parent: 32:d06dffa21a31
1280 | parent: 32:d06dffa21a31
1281 | user: test
1281 | user: test
1282 | date: Thu Jan 01 00:00:34 1970 +0000
1282 | date: Thu Jan 01 00:00:34 1970 +0000
1283 | summary: (34) head
1283 | summary: (34) head
1284 |
1284 |
1285 | o changeset: 33:68608f5145f9
1285 | o changeset: 33:68608f5145f9
1286 | | parent: 18:1aa84d96232a
1286 | | parent: 18:1aa84d96232a
1287 | | user: test
1287 | | user: test
1288 | | date: Thu Jan 01 00:00:33 1970 +0000
1288 | | date: Thu Jan 01 00:00:33 1970 +0000
1289 | | summary: (33) head
1289 | | summary: (33) head
1290 | |
1290 | |
1291
1291
1292 File + limit + -ra:b, (b - a) < limit:
1292 File + limit + -ra:b, (b - a) < limit:
1293 $ hg log -G -l3000 -r32:tip a
1293 $ hg log -G -l3000 -r32:tip a
1294 o changeset: 34:fea3ac5810e0
1294 o changeset: 34:fea3ac5810e0
1295 | parent: 32:d06dffa21a31
1295 | parent: 32:d06dffa21a31
1296 | user: test
1296 | user: test
1297 | date: Thu Jan 01 00:00:34 1970 +0000
1297 | date: Thu Jan 01 00:00:34 1970 +0000
1298 | summary: (34) head
1298 | summary: (34) head
1299 |
1299 |
1300 | o changeset: 33:68608f5145f9
1300 | o changeset: 33:68608f5145f9
1301 | | parent: 18:1aa84d96232a
1301 | | parent: 18:1aa84d96232a
1302 | | user: test
1302 | | user: test
1303 | | date: Thu Jan 01 00:00:33 1970 +0000
1303 | | date: Thu Jan 01 00:00:33 1970 +0000
1304 | | summary: (33) head
1304 | | summary: (33) head
1305 | |
1305 | |
1306 o | changeset: 32:d06dffa21a31
1306 o | changeset: 32:d06dffa21a31
1307 |\ \ parent: 27:886ed638191b
1307 |\ \ parent: 27:886ed638191b
1308 | | | parent: 31:621d83e11f67
1308 | | | parent: 31:621d83e11f67
1309 | | | user: test
1309 | | | user: test
1310 | | | date: Thu Jan 01 00:00:32 1970 +0000
1310 | | | date: Thu Jan 01 00:00:32 1970 +0000
1311 | | | summary: (32) expand
1311 | | | summary: (32) expand
1312 | | |
1312 | | |
1313
1313
1314 Point out a common and an uncommon unshown parent
1314 Point out a common and an uncommon unshown parent
1315
1315
1316 $ hg log -G -r 'rev(8) or rev(9)'
1316 $ hg log -G -r 'rev(8) or rev(9)'
1317 o changeset: 9:7010c0af0a35
1317 o changeset: 9:7010c0af0a35
1318 |\ parent: 7:b632bb1b1224
1318 |\ parent: 7:b632bb1b1224
1319 | | parent: 8:7a0b11f71937
1319 | | parent: 8:7a0b11f71937
1320 | | user: test
1320 | | user: test
1321 | | date: Thu Jan 01 00:00:09 1970 +0000
1321 | | date: Thu Jan 01 00:00:09 1970 +0000
1322 | | summary: (9) expand
1322 | | summary: (9) expand
1323 | |
1323 | |
1324 o | changeset: 8:7a0b11f71937
1324 o | changeset: 8:7a0b11f71937
1325 |\| parent: 0:e6eb3150255d
1325 |\| parent: 0:e6eb3150255d
1326 | | parent: 7:b632bb1b1224
1326 | | parent: 7:b632bb1b1224
1327 | | user: test
1327 | | user: test
1328 | | date: Thu Jan 01 00:00:08 1970 +0000
1328 | | date: Thu Jan 01 00:00:08 1970 +0000
1329 | | summary: (8) merge two known; one immediate left, one far right
1329 | | summary: (8) merge two known; one immediate left, one far right
1330 | |
1330 | |
1331
1331
1332 File + limit + -ra:b, b < tip:
1332 File + limit + -ra:b, b < tip:
1333
1333
1334 $ hg log -G -l1 -r32:34 a
1334 $ hg log -G -l1 -r32:34 a
1335 o changeset: 34:fea3ac5810e0
1335 o changeset: 34:fea3ac5810e0
1336 | parent: 32:d06dffa21a31
1336 | parent: 32:d06dffa21a31
1337 | user: test
1337 | user: test
1338 | date: Thu Jan 01 00:00:34 1970 +0000
1338 | date: Thu Jan 01 00:00:34 1970 +0000
1339 | summary: (34) head
1339 | summary: (34) head
1340 |
1340 |
1341
1341
1342 file(File) + limit + -ra:b, b < tip:
1342 file(File) + limit + -ra:b, b < tip:
1343
1343
1344 $ hg log -G -l1 -r32:34 -r 'file("a")'
1344 $ hg log -G -l1 -r32:34 -r 'file("a")'
1345 o changeset: 34:fea3ac5810e0
1345 o changeset: 34:fea3ac5810e0
1346 | parent: 32:d06dffa21a31
1346 | parent: 32:d06dffa21a31
1347 | user: test
1347 | user: test
1348 | date: Thu Jan 01 00:00:34 1970 +0000
1348 | date: Thu Jan 01 00:00:34 1970 +0000
1349 | summary: (34) head
1349 | summary: (34) head
1350 |
1350 |
1351
1351
1352 limit(file(File) and a::b), b < tip:
1352 limit(file(File) and a::b), b < tip:
1353
1353
1354 $ hg log -G -r 'limit(file("a") and 32::34, 1)'
1354 $ hg log -G -r 'limit(file("a") and 32::34, 1)'
1355 o changeset: 32:d06dffa21a31
1355 o changeset: 32:d06dffa21a31
1356 |\ parent: 27:886ed638191b
1356 |\ parent: 27:886ed638191b
1357 | | parent: 31:621d83e11f67
1357 | | parent: 31:621d83e11f67
1358 | | user: test
1358 | | user: test
1359 | | date: Thu Jan 01 00:00:32 1970 +0000
1359 | | date: Thu Jan 01 00:00:32 1970 +0000
1360 | | summary: (32) expand
1360 | | summary: (32) expand
1361 | |
1361 | |
1362
1362
1363 File + limit + -ra:b, b < tip:
1363 File + limit + -ra:b, b < tip:
1364
1364
1365 $ hg log -G -r 'limit(file("a") and 34::32, 1)'
1365 $ hg log -G -r 'limit(file("a") and 34::32, 1)'
1366
1366
1367 File + limit + -ra:b, b < tip, (b - a) < limit:
1367 File + limit + -ra:b, b < tip, (b - a) < limit:
1368
1368
1369 $ hg log -G -l10 -r33:34 a
1369 $ hg log -G -l10 -r33:34 a
1370 o changeset: 34:fea3ac5810e0
1370 o changeset: 34:fea3ac5810e0
1371 | parent: 32:d06dffa21a31
1371 | parent: 32:d06dffa21a31
1372 | user: test
1372 | user: test
1373 | date: Thu Jan 01 00:00:34 1970 +0000
1373 | date: Thu Jan 01 00:00:34 1970 +0000
1374 | summary: (34) head
1374 | summary: (34) head
1375 |
1375 |
1376 | o changeset: 33:68608f5145f9
1376 | o changeset: 33:68608f5145f9
1377 | | parent: 18:1aa84d96232a
1377 | | parent: 18:1aa84d96232a
1378 | | user: test
1378 | | user: test
1379 | | date: Thu Jan 01 00:00:33 1970 +0000
1379 | | date: Thu Jan 01 00:00:33 1970 +0000
1380 | | summary: (33) head
1380 | | summary: (33) head
1381 | |
1381 | |
1382
1382
1383 Do not crash or produce strange graphs if history is buggy
1383 Do not crash or produce strange graphs if history is buggy
1384
1384
1385 $ hg branch branch
1385 $ hg branch branch
1386 marked working directory as branch branch
1386 marked working directory as branch branch
1387 (branches are permanent and global, did you want a bookmark?)
1387 (branches are permanent and global, did you want a bookmark?)
1388 $ commit 36 "buggy merge: identical parents" 35 35
1388 $ commit 36 "buggy merge: identical parents" 35 35
1389 $ hg log -G -l5
1389 $ hg log -G -l5
1390 @ changeset: 36:08a19a744424
1390 @ changeset: 36:08a19a744424
1391 | branch: branch
1391 | branch: branch
1392 | tag: tip
1392 | tag: tip
1393 | parent: 35:9159c3644c5e
1393 | parent: 35:9159c3644c5e
1394 | parent: 35:9159c3644c5e
1394 | parent: 35:9159c3644c5e
1395 | user: test
1395 | user: test
1396 | date: Thu Jan 01 00:00:36 1970 +0000
1396 | date: Thu Jan 01 00:00:36 1970 +0000
1397 | summary: (36) buggy merge: identical parents
1397 | summary: (36) buggy merge: identical parents
1398 |
1398 |
1399 o changeset: 35:9159c3644c5e
1399 o changeset: 35:9159c3644c5e
1400 | user: test
1400 | user: test
1401 | date: Thu Jan 01 00:00:00 1970 +0000
1401 | date: Thu Jan 01 00:00:00 1970 +0000
1402 | summary: 0
1402 | summary: 0
1403 |
1403 |
1404 o changeset: 34:fea3ac5810e0
1404 o changeset: 34:fea3ac5810e0
1405 | parent: 32:d06dffa21a31
1405 | parent: 32:d06dffa21a31
1406 | user: test
1406 | user: test
1407 | date: Thu Jan 01 00:00:34 1970 +0000
1407 | date: Thu Jan 01 00:00:34 1970 +0000
1408 | summary: (34) head
1408 | summary: (34) head
1409 |
1409 |
1410 | o changeset: 33:68608f5145f9
1410 | o changeset: 33:68608f5145f9
1411 | | parent: 18:1aa84d96232a
1411 | | parent: 18:1aa84d96232a
1412 | | user: test
1412 | | user: test
1413 | | date: Thu Jan 01 00:00:33 1970 +0000
1413 | | date: Thu Jan 01 00:00:33 1970 +0000
1414 | | summary: (33) head
1414 | | summary: (33) head
1415 | |
1415 | |
1416 o | changeset: 32:d06dffa21a31
1416 o | changeset: 32:d06dffa21a31
1417 |\ \ parent: 27:886ed638191b
1417 |\ \ parent: 27:886ed638191b
1418 | | | parent: 31:621d83e11f67
1418 | | | parent: 31:621d83e11f67
1419 | | | user: test
1419 | | | user: test
1420 | | | date: Thu Jan 01 00:00:32 1970 +0000
1420 | | | date: Thu Jan 01 00:00:32 1970 +0000
1421 | | | summary: (32) expand
1421 | | | summary: (32) expand
1422 | | |
1422 | | |
1423
1423
1424 Test log -G options
1424 Test log -G options
1425
1425
1426 $ testlog() {
1426 $ testlog() {
1427 > hg log -G --print-revset "$@"
1427 > hg log -G --print-revset "$@"
1428 > hg log --template 'nodetag {rev}\n' "$@" | grep nodetag \
1428 > hg log --template 'nodetag {rev}\n' "$@" | grep nodetag \
1429 > | sed 's/.*nodetag/nodetag/' > log.nodes
1429 > | sed 's/.*nodetag/nodetag/' > log.nodes
1430 > hg log -G --template 'nodetag {rev}\n' "$@" | grep nodetag \
1430 > hg log -G --template 'nodetag {rev}\n' "$@" | grep nodetag \
1431 > | sed 's/.*nodetag/nodetag/' > glog.nodes
1431 > | sed 's/.*nodetag/nodetag/' > glog.nodes
1432 > diff -u log.nodes glog.nodes | grep '^[-+@ ]' || :
1432 > diff -u log.nodes glog.nodes | grep '^[-+@ ]' || :
1433 > }
1433 > }
1434
1434
1435 glog always reorders nodes which explains the difference with log
1435 glog always reorders nodes which explains the difference with log
1436
1436
1437 $ testlog -r 27 -r 25 -r 21 -r 34 -r 32 -r 31
1437 $ testlog -r 27 -r 25 -r 21 -r 34 -r 32 -r 31
1438 ['27', '25', '21', '34', '32', '31']
1438 ['27', '25', '21', '34', '32', '31']
1439 []
1439 []
1440 --- log.nodes * (glob)
1440 --- log.nodes * (glob)
1441 +++ glog.nodes * (glob)
1441 +++ glog.nodes * (glob)
1442 @@ -1,6 +1,6 @@
1442 @@ -1,6 +1,6 @@
1443 -nodetag 27
1443 -nodetag 27
1444 -nodetag 25
1444 -nodetag 25
1445 -nodetag 21
1445 -nodetag 21
1446 nodetag 34
1446 nodetag 34
1447 nodetag 32
1447 nodetag 32
1448 nodetag 31
1448 nodetag 31
1449 +nodetag 27
1449 +nodetag 27
1450 +nodetag 25
1450 +nodetag 25
1451 +nodetag 21
1451 +nodetag 21
1452 $ testlog -u test -u not-a-user
1452 $ testlog -u test -u not-a-user
1453 []
1453 []
1454 (group
1454 (group
1455 (group
1455 (group
1456 (or
1456 (or
1457 (func
1457 (func
1458 ('symbol', 'user')
1458 ('symbol', 'user')
1459 ('string', 'test'))
1459 ('string', 'test'))
1460 (func
1460 (func
1461 ('symbol', 'user')
1461 ('symbol', 'user')
1462 ('string', 'not-a-user')))))
1462 ('string', 'not-a-user')))))
1463 $ testlog -b not-a-branch
1463 $ testlog -b not-a-branch
1464 abort: unknown revision 'not-a-branch'!
1464 abort: unknown revision 'not-a-branch'!
1465 abort: unknown revision 'not-a-branch'!
1465 abort: unknown revision 'not-a-branch'!
1466 abort: unknown revision 'not-a-branch'!
1466 abort: unknown revision 'not-a-branch'!
1467 $ testlog -b 35 -b 36 --only-branch branch
1467 $ testlog -b 35 -b 36 --only-branch branch
1468 []
1468 []
1469 (group
1469 (group
1470 (group
1470 (group
1471 (or
1471 (or
1472 (or
1472 (or
1473 (func
1473 (func
1474 ('symbol', 'branch')
1474 ('symbol', 'branch')
1475 ('string', 'default'))
1475 ('string', 'default'))
1476 (func
1476 (func
1477 ('symbol', 'branch')
1477 ('symbol', 'branch')
1478 ('string', 'branch')))
1478 ('string', 'branch')))
1479 (func
1479 (func
1480 ('symbol', 'branch')
1480 ('symbol', 'branch')
1481 ('string', 'branch')))))
1481 ('string', 'branch')))))
1482 $ testlog -k expand -k merge
1482 $ testlog -k expand -k merge
1483 []
1483 []
1484 (group
1484 (group
1485 (group
1485 (group
1486 (or
1486 (or
1487 (func
1487 (func
1488 ('symbol', 'keyword')
1488 ('symbol', 'keyword')
1489 ('string', 'expand'))
1489 ('string', 'expand'))
1490 (func
1490 (func
1491 ('symbol', 'keyword')
1491 ('symbol', 'keyword')
1492 ('string', 'merge')))))
1492 ('string', 'merge')))))
1493 $ testlog --only-merges
1493 $ testlog --only-merges
1494 []
1494 []
1495 (group
1495 (group
1496 (func
1496 (func
1497 ('symbol', 'merge')
1497 ('symbol', 'merge')
1498 None))
1498 None))
1499 $ testlog --no-merges
1499 $ testlog --no-merges
1500 []
1500 []
1501 (group
1501 (group
1502 (not
1502 (not
1503 (func
1503 (func
1504 ('symbol', 'merge')
1504 ('symbol', 'merge')
1505 None)))
1505 None)))
1506 $ testlog --date '2 0 to 4 0'
1506 $ testlog --date '2 0 to 4 0'
1507 []
1507 []
1508 (group
1508 (group
1509 (func
1509 (func
1510 ('symbol', 'date')
1510 ('symbol', 'date')
1511 ('string', '2 0 to 4 0')))
1511 ('string', '2 0 to 4 0')))
1512 $ hg log -G -d 'brace ) in a date'
1512 $ hg log -G -d 'brace ) in a date'
1513 abort: invalid date: 'brace ) in a date'
1513 abort: invalid date: 'brace ) in a date'
1514 [255]
1514 [255]
1515 $ testlog --prune 31 --prune 32
1515 $ testlog --prune 31 --prune 32
1516 []
1516 []
1517 (group
1517 (group
1518 (group
1518 (group
1519 (and
1519 (and
1520 (not
1520 (not
1521 (group
1521 (group
1522 (or
1522 (or
1523 ('string', '31')
1523 ('string', '31')
1524 (func
1524 (func
1525 ('symbol', 'ancestors')
1525 ('symbol', 'ancestors')
1526 ('string', '31')))))
1526 ('string', '31')))))
1527 (not
1527 (not
1528 (group
1528 (group
1529 (or
1529 (or
1530 ('string', '32')
1530 ('string', '32')
1531 (func
1531 (func
1532 ('symbol', 'ancestors')
1532 ('symbol', 'ancestors')
1533 ('string', '32'))))))))
1533 ('string', '32'))))))))
1534
1534
1535 Dedicated repo for --follow and paths filtering. The g is crafted to
1535 Dedicated repo for --follow and paths filtering. The g is crafted to
1536 have 2 filelog topological heads in a linear changeset graph.
1536 have 2 filelog topological heads in a linear changeset graph.
1537
1537
1538 $ cd ..
1538 $ cd ..
1539 $ hg init follow
1539 $ hg init follow
1540 $ cd follow
1540 $ cd follow
1541 $ testlog --follow
1541 $ testlog --follow
1542 []
1542 []
1543 []
1543 []
1544 $ testlog -rnull
1544 $ testlog -rnull
1545 ['null']
1545 ['null']
1546 []
1546 []
1547 $ echo a > a
1547 $ echo a > a
1548 $ echo aa > aa
1548 $ echo aa > aa
1549 $ echo f > f
1549 $ echo f > f
1550 $ hg ci -Am "add a" a aa f
1550 $ hg ci -Am "add a" a aa f
1551 $ hg cp a b
1551 $ hg cp a b
1552 $ hg cp f g
1552 $ hg cp f g
1553 $ hg ci -m "copy a b"
1553 $ hg ci -m "copy a b"
1554 $ mkdir dir
1554 $ mkdir dir
1555 $ hg mv b dir
1555 $ hg mv b dir
1556 $ echo g >> g
1556 $ echo g >> g
1557 $ echo f >> f
1557 $ echo f >> f
1558 $ hg ci -m "mv b dir/b"
1558 $ hg ci -m "mv b dir/b"
1559 $ hg mv a b
1559 $ hg mv a b
1560 $ hg cp -f f g
1560 $ hg cp -f f g
1561 $ echo a > d
1561 $ echo a > d
1562 $ hg add d
1562 $ hg add d
1563 $ hg ci -m "mv a b; add d"
1563 $ hg ci -m "mv a b; add d"
1564 $ hg mv dir/b e
1564 $ hg mv dir/b e
1565 $ hg ci -m "mv dir/b e"
1565 $ hg ci -m "mv dir/b e"
1566 $ hg log -G --template '({rev}) {desc|firstline}\n'
1566 $ hg log -G --template '({rev}) {desc|firstline}\n'
1567 @ (4) mv dir/b e
1567 @ (4) mv dir/b e
1568 |
1568 |
1569 o (3) mv a b; add d
1569 o (3) mv a b; add d
1570 |
1570 |
1571 o (2) mv b dir/b
1571 o (2) mv b dir/b
1572 |
1572 |
1573 o (1) copy a b
1573 o (1) copy a b
1574 |
1574 |
1575 o (0) add a
1575 o (0) add a
1576
1576
1577
1577
1578 $ testlog a
1578 $ testlog a
1579 []
1579 []
1580 (group
1580 (group
1581 (group
1581 (group
1582 (func
1582 (func
1583 ('symbol', 'filelog')
1583 ('symbol', 'filelog')
1584 ('string', 'a'))))
1584 ('string', 'a'))))
1585 $ testlog a b
1585 $ testlog a b
1586 []
1586 []
1587 (group
1587 (group
1588 (group
1588 (group
1589 (or
1589 (or
1590 (func
1590 (func
1591 ('symbol', 'filelog')
1591 ('symbol', 'filelog')
1592 ('string', 'a'))
1592 ('string', 'a'))
1593 (func
1593 (func
1594 ('symbol', 'filelog')
1594 ('symbol', 'filelog')
1595 ('string', 'b')))))
1595 ('string', 'b')))))
1596
1596
1597 Test falling back to slow path for non-existing files
1597 Test falling back to slow path for non-existing files
1598
1598
1599 $ testlog a c
1599 $ testlog a c
1600 []
1600 []
1601 (group
1601 (group
1602 (func
1602 (func
1603 ('symbol', '_matchfiles')
1603 ('symbol', '_matchfiles')
1604 (list
1604 (list
1605 (list
1605 (list
1606 (list
1606 (list
1607 ('string', 'r:')
1607 ('string', 'r:')
1608 ('string', 'd:relpath'))
1608 ('string', 'd:relpath'))
1609 ('string', 'p:a'))
1609 ('string', 'p:a'))
1610 ('string', 'p:c'))))
1610 ('string', 'p:c'))))
1611
1611
1612 Test multiple --include/--exclude/paths
1612 Test multiple --include/--exclude/paths
1613
1613
1614 $ testlog --include a --include e --exclude b --exclude e a e
1614 $ testlog --include a --include e --exclude b --exclude e a e
1615 []
1615 []
1616 (group
1616 (group
1617 (func
1617 (func
1618 ('symbol', '_matchfiles')
1618 ('symbol', '_matchfiles')
1619 (list
1619 (list
1620 (list
1620 (list
1621 (list
1621 (list
1622 (list
1622 (list
1623 (list
1623 (list
1624 (list
1624 (list
1625 (list
1625 (list
1626 ('string', 'r:')
1626 ('string', 'r:')
1627 ('string', 'd:relpath'))
1627 ('string', 'd:relpath'))
1628 ('string', 'p:a'))
1628 ('string', 'p:a'))
1629 ('string', 'p:e'))
1629 ('string', 'p:e'))
1630 ('string', 'i:a'))
1630 ('string', 'i:a'))
1631 ('string', 'i:e'))
1631 ('string', 'i:e'))
1632 ('string', 'x:b'))
1632 ('string', 'x:b'))
1633 ('string', 'x:e'))))
1633 ('string', 'x:e'))))
1634
1634
1635 Test glob expansion of pats
1635 Test glob expansion of pats
1636
1636
1637 $ expandglobs=`$PYTHON -c "import mercurial.util; \
1637 $ expandglobs=`$PYTHON -c "import mercurial.util; \
1638 > print mercurial.util.expandglobs and 'true' or 'false'"`
1638 > print mercurial.util.expandglobs and 'true' or 'false'"`
1639 $ if [ $expandglobs = "true" ]; then
1639 $ if [ $expandglobs = "true" ]; then
1640 > testlog 'a*';
1640 > testlog 'a*';
1641 > else
1641 > else
1642 > testlog a*;
1642 > testlog a*;
1643 > fi;
1643 > fi;
1644 []
1644 []
1645 (group
1645 (group
1646 (group
1646 (group
1647 (func
1647 (func
1648 ('symbol', 'filelog')
1648 ('symbol', 'filelog')
1649 ('string', 'aa'))))
1649 ('string', 'aa'))))
1650
1650
1651 Test --follow on a non-existent directory
1651 Test --follow on a non-existent directory
1652
1652
1653 $ testlog -f dir
1653 $ testlog -f dir
1654 abort: cannot follow file not in parent revision: "dir"
1654 abort: cannot follow file not in parent revision: "dir"
1655 abort: cannot follow file not in parent revision: "dir"
1655 abort: cannot follow file not in parent revision: "dir"
1656 abort: cannot follow file not in parent revision: "dir"
1656 abort: cannot follow file not in parent revision: "dir"
1657
1657
1658 Test --follow on a directory
1658 Test --follow on a directory
1659
1659
1660 $ hg up -q '.^'
1660 $ hg up -q '.^'
1661 $ testlog -f dir
1661 $ testlog -f dir
1662 []
1662 []
1663 (group
1663 (group
1664 (and
1664 (and
1665 (func
1665 (func
1666 ('symbol', 'ancestors')
1666 ('symbol', 'ancestors')
1667 ('symbol', '.'))
1667 ('symbol', '.'))
1668 (func
1668 (func
1669 ('symbol', '_matchfiles')
1669 ('symbol', '_matchfiles')
1670 (list
1670 (list
1671 (list
1671 (list
1672 ('string', 'r:')
1672 ('string', 'r:')
1673 ('string', 'd:relpath'))
1673 ('string', 'd:relpath'))
1674 ('string', 'p:dir')))))
1674 ('string', 'p:dir')))))
1675 $ hg up -q tip
1675 $ hg up -q tip
1676
1676
1677 Test --follow on file not in parent revision
1677 Test --follow on file not in parent revision
1678
1678
1679 $ testlog -f a
1679 $ testlog -f a
1680 abort: cannot follow file not in parent revision: "a"
1680 abort: cannot follow file not in parent revision: "a"
1681 abort: cannot follow file not in parent revision: "a"
1681 abort: cannot follow file not in parent revision: "a"
1682 abort: cannot follow file not in parent revision: "a"
1682 abort: cannot follow file not in parent revision: "a"
1683
1683
1684 Test --follow and patterns
1684 Test --follow and patterns
1685
1685
1686 $ testlog -f 'glob:*'
1686 $ testlog -f 'glob:*'
1687 []
1687 []
1688 (group
1688 (group
1689 (and
1689 (and
1690 (func
1690 (func
1691 ('symbol', 'ancestors')
1691 ('symbol', 'ancestors')
1692 ('symbol', '.'))
1692 ('symbol', '.'))
1693 (func
1693 (func
1694 ('symbol', '_matchfiles')
1694 ('symbol', '_matchfiles')
1695 (list
1695 (list
1696 (list
1696 (list
1697 ('string', 'r:')
1697 ('string', 'r:')
1698 ('string', 'd:relpath'))
1698 ('string', 'd:relpath'))
1699 ('string', 'p:glob:*')))))
1699 ('string', 'p:glob:*')))))
1700
1700
1701 Test --follow on a single rename
1701 Test --follow on a single rename
1702
1702
1703 $ hg up -q 2
1703 $ hg up -q 2
1704 $ testlog -f a
1704 $ testlog -f a
1705 []
1705 []
1706 (group
1706 (group
1707 (group
1707 (group
1708 (func
1708 (func
1709 ('symbol', 'follow')
1709 ('symbol', 'follow')
1710 ('string', 'a'))))
1710 ('string', 'a'))))
1711
1711
1712 Test --follow and multiple renames
1712 Test --follow and multiple renames
1713
1713
1714 $ hg up -q tip
1714 $ hg up -q tip
1715 $ testlog -f e
1715 $ testlog -f e
1716 []
1716 []
1717 (group
1717 (group
1718 (group
1718 (group
1719 (func
1719 (func
1720 ('symbol', 'follow')
1720 ('symbol', 'follow')
1721 ('string', 'e'))))
1721 ('string', 'e'))))
1722
1722
1723 Test --follow and multiple filelog heads
1723 Test --follow and multiple filelog heads
1724
1724
1725 $ hg up -q 2
1725 $ hg up -q 2
1726 $ testlog -f g
1726 $ testlog -f g
1727 []
1727 []
1728 (group
1728 (group
1729 (group
1729 (group
1730 (func
1730 (func
1731 ('symbol', 'follow')
1731 ('symbol', 'follow')
1732 ('string', 'g'))))
1732 ('string', 'g'))))
1733 $ cat log.nodes
1733 $ cat log.nodes
1734 nodetag 2
1734 nodetag 2
1735 nodetag 1
1735 nodetag 1
1736 nodetag 0
1736 nodetag 0
1737 $ hg up -q tip
1737 $ hg up -q tip
1738 $ testlog -f g
1738 $ testlog -f g
1739 []
1739 []
1740 (group
1740 (group
1741 (group
1741 (group
1742 (func
1742 (func
1743 ('symbol', 'follow')
1743 ('symbol', 'follow')
1744 ('string', 'g'))))
1744 ('string', 'g'))))
1745 $ cat log.nodes
1745 $ cat log.nodes
1746 nodetag 3
1746 nodetag 3
1747 nodetag 2
1747 nodetag 2
1748 nodetag 0
1748 nodetag 0
1749
1749
1750 Test --follow and multiple files
1750 Test --follow and multiple files
1751
1751
1752 $ testlog -f g e
1752 $ testlog -f g e
1753 []
1753 []
1754 (group
1754 (group
1755 (group
1755 (group
1756 (or
1756 (or
1757 (func
1757 (func
1758 ('symbol', 'follow')
1758 ('symbol', 'follow')
1759 ('string', 'g'))
1759 ('string', 'g'))
1760 (func
1760 (func
1761 ('symbol', 'follow')
1761 ('symbol', 'follow')
1762 ('string', 'e')))))
1762 ('string', 'e')))))
1763 $ cat log.nodes
1763 $ cat log.nodes
1764 nodetag 4
1764 nodetag 4
1765 nodetag 3
1765 nodetag 3
1766 nodetag 2
1766 nodetag 2
1767 nodetag 1
1767 nodetag 1
1768 nodetag 0
1768 nodetag 0
1769
1769
1770 Test --follow null parent
1771
1772 $ hg up -q null
1773 $ testlog -f
1774 []
1775 []
1776
1770 Test --follow-first
1777 Test --follow-first
1771
1778
1772 $ hg up -q 3
1779 $ hg up -q 3
1773 $ echo ee > e
1780 $ echo ee > e
1774 $ hg ci -Am "add another e" e
1781 $ hg ci -Am "add another e" e
1775 created new head
1782 created new head
1776 $ hg merge --tool internal:other 4
1783 $ hg merge --tool internal:other 4
1777 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
1784 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
1778 (branch merge, don't forget to commit)
1785 (branch merge, don't forget to commit)
1779 $ echo merge > e
1786 $ echo merge > e
1780 $ hg ci -m "merge 5 and 4"
1787 $ hg ci -m "merge 5 and 4"
1781 $ testlog --follow-first
1788 $ testlog --follow-first
1782 []
1789 []
1783 (group
1790 (group
1784 (func
1791 (func
1785 ('symbol', '_firstancestors')
1792 ('symbol', '_firstancestors')
1786 (func
1793 (func
1787 ('symbol', 'rev')
1794 ('symbol', 'rev')
1788 ('symbol', '6'))))
1795 ('symbol', '6'))))
1789
1796
1790 Cannot compare with log --follow-first FILE as it never worked
1797 Cannot compare with log --follow-first FILE as it never worked
1791
1798
1792 $ hg log -G --print-revset --follow-first e
1799 $ hg log -G --print-revset --follow-first e
1793 []
1800 []
1794 (group
1801 (group
1795 (group
1802 (group
1796 (func
1803 (func
1797 ('symbol', '_followfirst')
1804 ('symbol', '_followfirst')
1798 ('string', 'e'))))
1805 ('string', 'e'))))
1799 $ hg log -G --follow-first e --template '{rev} {desc|firstline}\n'
1806 $ hg log -G --follow-first e --template '{rev} {desc|firstline}\n'
1800 @ 6 merge 5 and 4
1807 @ 6 merge 5 and 4
1801 |\
1808 |\
1802 o | 5 add another e
1809 o | 5 add another e
1803 | |
1810 | |
1804
1811
1805 Test --copies
1812 Test --copies
1806
1813
1807 $ hg log -G --copies --template "{rev} {desc|firstline} \
1814 $ hg log -G --copies --template "{rev} {desc|firstline} \
1808 > copies: {file_copies_switch}\n"
1815 > copies: {file_copies_switch}\n"
1809 @ 6 merge 5 and 4 copies:
1816 @ 6 merge 5 and 4 copies:
1810 |\
1817 |\
1811 | o 5 add another e copies:
1818 | o 5 add another e copies:
1812 | |
1819 | |
1813 o | 4 mv dir/b e copies: e (dir/b)
1820 o | 4 mv dir/b e copies: e (dir/b)
1814 |/
1821 |/
1815 o 3 mv a b; add d copies: b (a)g (f)
1822 o 3 mv a b; add d copies: b (a)g (f)
1816 |
1823 |
1817 o 2 mv b dir/b copies: dir/b (b)
1824 o 2 mv b dir/b copies: dir/b (b)
1818 |
1825 |
1819 o 1 copy a b copies: b (a)g (f)
1826 o 1 copy a b copies: b (a)g (f)
1820 |
1827 |
1821 o 0 add a copies:
1828 o 0 add a copies:
1822
1829
1823 Test "set:..." and parent revision
1830 Test "set:..." and parent revision
1824
1831
1825 $ hg up -q 4
1832 $ hg up -q 4
1826 $ testlog "set:copied()"
1833 $ testlog "set:copied()"
1827 []
1834 []
1828 (group
1835 (group
1829 (func
1836 (func
1830 ('symbol', '_matchfiles')
1837 ('symbol', '_matchfiles')
1831 (list
1838 (list
1832 (list
1839 (list
1833 ('string', 'r:')
1840 ('string', 'r:')
1834 ('string', 'd:relpath'))
1841 ('string', 'd:relpath'))
1835 ('string', 'p:set:copied()'))))
1842 ('string', 'p:set:copied()'))))
1836 $ testlog --include "set:copied()"
1843 $ testlog --include "set:copied()"
1837 []
1844 []
1838 (group
1845 (group
1839 (func
1846 (func
1840 ('symbol', '_matchfiles')
1847 ('symbol', '_matchfiles')
1841 (list
1848 (list
1842 (list
1849 (list
1843 ('string', 'r:')
1850 ('string', 'r:')
1844 ('string', 'd:relpath'))
1851 ('string', 'd:relpath'))
1845 ('string', 'i:set:copied()'))))
1852 ('string', 'i:set:copied()'))))
1846 $ testlog -r "sort(file('set:copied()'), -rev)"
1853 $ testlog -r "sort(file('set:copied()'), -rev)"
1847 ["sort(file('set:copied()'), -rev)"]
1854 ["sort(file('set:copied()'), -rev)"]
1848 []
1855 []
1849
1856
1850 Test --removed
1857 Test --removed
1851
1858
1852 $ testlog --removed
1859 $ testlog --removed
1853 []
1860 []
1854 []
1861 []
1855 $ testlog --removed a
1862 $ testlog --removed a
1856 []
1863 []
1857 (group
1864 (group
1858 (func
1865 (func
1859 ('symbol', '_matchfiles')
1866 ('symbol', '_matchfiles')
1860 (list
1867 (list
1861 (list
1868 (list
1862 ('string', 'r:')
1869 ('string', 'r:')
1863 ('string', 'd:relpath'))
1870 ('string', 'd:relpath'))
1864 ('string', 'p:a'))))
1871 ('string', 'p:a'))))
1865 $ testlog --removed --follow a
1872 $ testlog --removed --follow a
1866 []
1873 []
1867 (group
1874 (group
1868 (and
1875 (and
1869 (func
1876 (func
1870 ('symbol', 'ancestors')
1877 ('symbol', 'ancestors')
1871 ('symbol', '.'))
1878 ('symbol', '.'))
1872 (func
1879 (func
1873 ('symbol', '_matchfiles')
1880 ('symbol', '_matchfiles')
1874 (list
1881 (list
1875 (list
1882 (list
1876 ('string', 'r:')
1883 ('string', 'r:')
1877 ('string', 'd:relpath'))
1884 ('string', 'd:relpath'))
1878 ('string', 'p:a')))))
1885 ('string', 'p:a')))))
1879
1886
1880 Test --patch and --stat with --follow and --follow-first
1887 Test --patch and --stat with --follow and --follow-first
1881
1888
1882 $ hg up -q 3
1889 $ hg up -q 3
1883 $ hg log -G --git --patch b
1890 $ hg log -G --git --patch b
1884 o changeset: 1:216d4c92cf98
1891 o changeset: 1:216d4c92cf98
1885 | user: test
1892 | user: test
1886 | date: Thu Jan 01 00:00:00 1970 +0000
1893 | date: Thu Jan 01 00:00:00 1970 +0000
1887 | summary: copy a b
1894 | summary: copy a b
1888 |
1895 |
1889 | diff --git a/a b/b
1896 | diff --git a/a b/b
1890 | copy from a
1897 | copy from a
1891 | copy to b
1898 | copy to b
1892 |
1899 |
1893
1900
1894 $ hg log -G --git --stat b
1901 $ hg log -G --git --stat b
1895 o changeset: 1:216d4c92cf98
1902 o changeset: 1:216d4c92cf98
1896 | user: test
1903 | user: test
1897 | date: Thu Jan 01 00:00:00 1970 +0000
1904 | date: Thu Jan 01 00:00:00 1970 +0000
1898 | summary: copy a b
1905 | summary: copy a b
1899 |
1906 |
1900 | b | 0
1907 | b | 0
1901 | 1 files changed, 0 insertions(+), 0 deletions(-)
1908 | 1 files changed, 0 insertions(+), 0 deletions(-)
1902 |
1909 |
1903
1910
1904 $ hg log -G --git --patch --follow b
1911 $ hg log -G --git --patch --follow b
1905 o changeset: 1:216d4c92cf98
1912 o changeset: 1:216d4c92cf98
1906 | user: test
1913 | user: test
1907 | date: Thu Jan 01 00:00:00 1970 +0000
1914 | date: Thu Jan 01 00:00:00 1970 +0000
1908 | summary: copy a b
1915 | summary: copy a b
1909 |
1916 |
1910 | diff --git a/a b/b
1917 | diff --git a/a b/b
1911 | copy from a
1918 | copy from a
1912 | copy to b
1919 | copy to b
1913 |
1920 |
1914 o changeset: 0:f8035bb17114
1921 o changeset: 0:f8035bb17114
1915 user: test
1922 user: test
1916 date: Thu Jan 01 00:00:00 1970 +0000
1923 date: Thu Jan 01 00:00:00 1970 +0000
1917 summary: add a
1924 summary: add a
1918
1925
1919 diff --git a/a b/a
1926 diff --git a/a b/a
1920 new file mode 100644
1927 new file mode 100644
1921 --- /dev/null
1928 --- /dev/null
1922 +++ b/a
1929 +++ b/a
1923 @@ -0,0 +1,1 @@
1930 @@ -0,0 +1,1 @@
1924 +a
1931 +a
1925
1932
1926
1933
1927 $ hg log -G --git --stat --follow b
1934 $ hg log -G --git --stat --follow b
1928 o changeset: 1:216d4c92cf98
1935 o changeset: 1:216d4c92cf98
1929 | user: test
1936 | user: test
1930 | date: Thu Jan 01 00:00:00 1970 +0000
1937 | date: Thu Jan 01 00:00:00 1970 +0000
1931 | summary: copy a b
1938 | summary: copy a b
1932 |
1939 |
1933 | b | 0
1940 | b | 0
1934 | 1 files changed, 0 insertions(+), 0 deletions(-)
1941 | 1 files changed, 0 insertions(+), 0 deletions(-)
1935 |
1942 |
1936 o changeset: 0:f8035bb17114
1943 o changeset: 0:f8035bb17114
1937 user: test
1944 user: test
1938 date: Thu Jan 01 00:00:00 1970 +0000
1945 date: Thu Jan 01 00:00:00 1970 +0000
1939 summary: add a
1946 summary: add a
1940
1947
1941 a | 1 +
1948 a | 1 +
1942 1 files changed, 1 insertions(+), 0 deletions(-)
1949 1 files changed, 1 insertions(+), 0 deletions(-)
1943
1950
1944
1951
1945 $ hg up -q 6
1952 $ hg up -q 6
1946 $ hg log -G --git --patch --follow-first e
1953 $ hg log -G --git --patch --follow-first e
1947 @ changeset: 6:fc281d8ff18d
1954 @ changeset: 6:fc281d8ff18d
1948 |\ tag: tip
1955 |\ tag: tip
1949 | | parent: 5:99b31f1c2782
1956 | | parent: 5:99b31f1c2782
1950 | | parent: 4:17d952250a9d
1957 | | parent: 4:17d952250a9d
1951 | | user: test
1958 | | user: test
1952 | | date: Thu Jan 01 00:00:00 1970 +0000
1959 | | date: Thu Jan 01 00:00:00 1970 +0000
1953 | | summary: merge 5 and 4
1960 | | summary: merge 5 and 4
1954 | |
1961 | |
1955 | | diff --git a/e b/e
1962 | | diff --git a/e b/e
1956 | | --- a/e
1963 | | --- a/e
1957 | | +++ b/e
1964 | | +++ b/e
1958 | | @@ -1,1 +1,1 @@
1965 | | @@ -1,1 +1,1 @@
1959 | | -ee
1966 | | -ee
1960 | | +merge
1967 | | +merge
1961 | |
1968 | |
1962 o | changeset: 5:99b31f1c2782
1969 o | changeset: 5:99b31f1c2782
1963 | | parent: 3:5918b8d165d1
1970 | | parent: 3:5918b8d165d1
1964 | | user: test
1971 | | user: test
1965 | | date: Thu Jan 01 00:00:00 1970 +0000
1972 | | date: Thu Jan 01 00:00:00 1970 +0000
1966 | | summary: add another e
1973 | | summary: add another e
1967 | |
1974 | |
1968 | | diff --git a/e b/e
1975 | | diff --git a/e b/e
1969 | | new file mode 100644
1976 | | new file mode 100644
1970 | | --- /dev/null
1977 | | --- /dev/null
1971 | | +++ b/e
1978 | | +++ b/e
1972 | | @@ -0,0 +1,1 @@
1979 | | @@ -0,0 +1,1 @@
1973 | | +ee
1980 | | +ee
1974 | |
1981 | |
1975
1982
1976 Test old-style --rev
1983 Test old-style --rev
1977
1984
1978 $ hg tag 'foo-bar'
1985 $ hg tag 'foo-bar'
1979 $ testlog -r 'foo-bar'
1986 $ testlog -r 'foo-bar'
1980 ['foo-bar']
1987 ['foo-bar']
1981 []
1988 []
1982
1989
1983 Test --follow and forward --rev
1990 Test --follow and forward --rev
1984
1991
1985 $ hg up -q 6
1992 $ hg up -q 6
1986 $ echo g > g
1993 $ echo g > g
1987 $ hg ci -Am 'add g' g
1994 $ hg ci -Am 'add g' g
1988 created new head
1995 created new head
1989 $ hg up -q 2
1996 $ hg up -q 2
1990 $ hg log -G --template "{rev} {desc|firstline}\n"
1997 $ hg log -G --template "{rev} {desc|firstline}\n"
1991 o 8 add g
1998 o 8 add g
1992 |
1999 |
1993 | o 7 Added tag foo-bar for changeset fc281d8ff18d
2000 | o 7 Added tag foo-bar for changeset fc281d8ff18d
1994 |/
2001 |/
1995 o 6 merge 5 and 4
2002 o 6 merge 5 and 4
1996 |\
2003 |\
1997 | o 5 add another e
2004 | o 5 add another e
1998 | |
2005 | |
1999 o | 4 mv dir/b e
2006 o | 4 mv dir/b e
2000 |/
2007 |/
2001 o 3 mv a b; add d
2008 o 3 mv a b; add d
2002 |
2009 |
2003 @ 2 mv b dir/b
2010 @ 2 mv b dir/b
2004 |
2011 |
2005 o 1 copy a b
2012 o 1 copy a b
2006 |
2013 |
2007 o 0 add a
2014 o 0 add a
2008
2015
2009 $ hg export 'all()'
2016 $ hg export 'all()'
2010 # HG changeset patch
2017 # HG changeset patch
2011 # User test
2018 # User test
2012 # Date 0 0
2019 # Date 0 0
2013 # Thu Jan 01 00:00:00 1970 +0000
2020 # Thu Jan 01 00:00:00 1970 +0000
2014 # Node ID f8035bb17114da16215af3436ec5222428ace8ee
2021 # Node ID f8035bb17114da16215af3436ec5222428ace8ee
2015 # Parent 0000000000000000000000000000000000000000
2022 # Parent 0000000000000000000000000000000000000000
2016 add a
2023 add a
2017
2024
2018 diff -r 000000000000 -r f8035bb17114 a
2025 diff -r 000000000000 -r f8035bb17114 a
2019 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2026 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2020 +++ b/a Thu Jan 01 00:00:00 1970 +0000
2027 +++ b/a Thu Jan 01 00:00:00 1970 +0000
2021 @@ -0,0 +1,1 @@
2028 @@ -0,0 +1,1 @@
2022 +a
2029 +a
2023 diff -r 000000000000 -r f8035bb17114 aa
2030 diff -r 000000000000 -r f8035bb17114 aa
2024 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2031 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2025 +++ b/aa Thu Jan 01 00:00:00 1970 +0000
2032 +++ b/aa Thu Jan 01 00:00:00 1970 +0000
2026 @@ -0,0 +1,1 @@
2033 @@ -0,0 +1,1 @@
2027 +aa
2034 +aa
2028 diff -r 000000000000 -r f8035bb17114 f
2035 diff -r 000000000000 -r f8035bb17114 f
2029 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2036 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2030 +++ b/f Thu Jan 01 00:00:00 1970 +0000
2037 +++ b/f Thu Jan 01 00:00:00 1970 +0000
2031 @@ -0,0 +1,1 @@
2038 @@ -0,0 +1,1 @@
2032 +f
2039 +f
2033 # HG changeset patch
2040 # HG changeset patch
2034 # User test
2041 # User test
2035 # Date 0 0
2042 # Date 0 0
2036 # Thu Jan 01 00:00:00 1970 +0000
2043 # Thu Jan 01 00:00:00 1970 +0000
2037 # Node ID 216d4c92cf98ff2b4641d508b76b529f3d424c92
2044 # Node ID 216d4c92cf98ff2b4641d508b76b529f3d424c92
2038 # Parent f8035bb17114da16215af3436ec5222428ace8ee
2045 # Parent f8035bb17114da16215af3436ec5222428ace8ee
2039 copy a b
2046 copy a b
2040
2047
2041 diff -r f8035bb17114 -r 216d4c92cf98 b
2048 diff -r f8035bb17114 -r 216d4c92cf98 b
2042 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2049 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2043 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2050 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2044 @@ -0,0 +1,1 @@
2051 @@ -0,0 +1,1 @@
2045 +a
2052 +a
2046 diff -r f8035bb17114 -r 216d4c92cf98 g
2053 diff -r f8035bb17114 -r 216d4c92cf98 g
2047 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2054 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2048 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2055 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2049 @@ -0,0 +1,1 @@
2056 @@ -0,0 +1,1 @@
2050 +f
2057 +f
2051 # HG changeset patch
2058 # HG changeset patch
2052 # User test
2059 # User test
2053 # Date 0 0
2060 # Date 0 0
2054 # Thu Jan 01 00:00:00 1970 +0000
2061 # Thu Jan 01 00:00:00 1970 +0000
2055 # Node ID bb573313a9e8349099b6ea2b2fb1fc7f424446f3
2062 # Node ID bb573313a9e8349099b6ea2b2fb1fc7f424446f3
2056 # Parent 216d4c92cf98ff2b4641d508b76b529f3d424c92
2063 # Parent 216d4c92cf98ff2b4641d508b76b529f3d424c92
2057 mv b dir/b
2064 mv b dir/b
2058
2065
2059 diff -r 216d4c92cf98 -r bb573313a9e8 b
2066 diff -r 216d4c92cf98 -r bb573313a9e8 b
2060 --- a/b Thu Jan 01 00:00:00 1970 +0000
2067 --- a/b Thu Jan 01 00:00:00 1970 +0000
2061 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2068 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2062 @@ -1,1 +0,0 @@
2069 @@ -1,1 +0,0 @@
2063 -a
2070 -a
2064 diff -r 216d4c92cf98 -r bb573313a9e8 dir/b
2071 diff -r 216d4c92cf98 -r bb573313a9e8 dir/b
2065 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2072 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2066 +++ b/dir/b Thu Jan 01 00:00:00 1970 +0000
2073 +++ b/dir/b Thu Jan 01 00:00:00 1970 +0000
2067 @@ -0,0 +1,1 @@
2074 @@ -0,0 +1,1 @@
2068 +a
2075 +a
2069 diff -r 216d4c92cf98 -r bb573313a9e8 f
2076 diff -r 216d4c92cf98 -r bb573313a9e8 f
2070 --- a/f Thu Jan 01 00:00:00 1970 +0000
2077 --- a/f Thu Jan 01 00:00:00 1970 +0000
2071 +++ b/f Thu Jan 01 00:00:00 1970 +0000
2078 +++ b/f Thu Jan 01 00:00:00 1970 +0000
2072 @@ -1,1 +1,2 @@
2079 @@ -1,1 +1,2 @@
2073 f
2080 f
2074 +f
2081 +f
2075 diff -r 216d4c92cf98 -r bb573313a9e8 g
2082 diff -r 216d4c92cf98 -r bb573313a9e8 g
2076 --- a/g Thu Jan 01 00:00:00 1970 +0000
2083 --- a/g Thu Jan 01 00:00:00 1970 +0000
2077 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2084 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2078 @@ -1,1 +1,2 @@
2085 @@ -1,1 +1,2 @@
2079 f
2086 f
2080 +g
2087 +g
2081 # HG changeset patch
2088 # HG changeset patch
2082 # User test
2089 # User test
2083 # Date 0 0
2090 # Date 0 0
2084 # Thu Jan 01 00:00:00 1970 +0000
2091 # Thu Jan 01 00:00:00 1970 +0000
2085 # Node ID 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2092 # Node ID 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2086 # Parent bb573313a9e8349099b6ea2b2fb1fc7f424446f3
2093 # Parent bb573313a9e8349099b6ea2b2fb1fc7f424446f3
2087 mv a b; add d
2094 mv a b; add d
2088
2095
2089 diff -r bb573313a9e8 -r 5918b8d165d1 a
2096 diff -r bb573313a9e8 -r 5918b8d165d1 a
2090 --- a/a Thu Jan 01 00:00:00 1970 +0000
2097 --- a/a Thu Jan 01 00:00:00 1970 +0000
2091 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2098 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2092 @@ -1,1 +0,0 @@
2099 @@ -1,1 +0,0 @@
2093 -a
2100 -a
2094 diff -r bb573313a9e8 -r 5918b8d165d1 b
2101 diff -r bb573313a9e8 -r 5918b8d165d1 b
2095 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2102 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2096 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2103 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2097 @@ -0,0 +1,1 @@
2104 @@ -0,0 +1,1 @@
2098 +a
2105 +a
2099 diff -r bb573313a9e8 -r 5918b8d165d1 d
2106 diff -r bb573313a9e8 -r 5918b8d165d1 d
2100 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2107 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2101 +++ b/d Thu Jan 01 00:00:00 1970 +0000
2108 +++ b/d Thu Jan 01 00:00:00 1970 +0000
2102 @@ -0,0 +1,1 @@
2109 @@ -0,0 +1,1 @@
2103 +a
2110 +a
2104 diff -r bb573313a9e8 -r 5918b8d165d1 g
2111 diff -r bb573313a9e8 -r 5918b8d165d1 g
2105 --- a/g Thu Jan 01 00:00:00 1970 +0000
2112 --- a/g Thu Jan 01 00:00:00 1970 +0000
2106 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2113 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2107 @@ -1,2 +1,2 @@
2114 @@ -1,2 +1,2 @@
2108 f
2115 f
2109 -g
2116 -g
2110 +f
2117 +f
2111 # HG changeset patch
2118 # HG changeset patch
2112 # User test
2119 # User test
2113 # Date 0 0
2120 # Date 0 0
2114 # Thu Jan 01 00:00:00 1970 +0000
2121 # Thu Jan 01 00:00:00 1970 +0000
2115 # Node ID 17d952250a9d03cc3dc77b199ab60e959b9b0260
2122 # Node ID 17d952250a9d03cc3dc77b199ab60e959b9b0260
2116 # Parent 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2123 # Parent 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2117 mv dir/b e
2124 mv dir/b e
2118
2125
2119 diff -r 5918b8d165d1 -r 17d952250a9d dir/b
2126 diff -r 5918b8d165d1 -r 17d952250a9d dir/b
2120 --- a/dir/b Thu Jan 01 00:00:00 1970 +0000
2127 --- a/dir/b Thu Jan 01 00:00:00 1970 +0000
2121 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2128 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2122 @@ -1,1 +0,0 @@
2129 @@ -1,1 +0,0 @@
2123 -a
2130 -a
2124 diff -r 5918b8d165d1 -r 17d952250a9d e
2131 diff -r 5918b8d165d1 -r 17d952250a9d e
2125 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2132 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2126 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2133 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2127 @@ -0,0 +1,1 @@
2134 @@ -0,0 +1,1 @@
2128 +a
2135 +a
2129 # HG changeset patch
2136 # HG changeset patch
2130 # User test
2137 # User test
2131 # Date 0 0
2138 # Date 0 0
2132 # Thu Jan 01 00:00:00 1970 +0000
2139 # Thu Jan 01 00:00:00 1970 +0000
2133 # Node ID 99b31f1c2782e2deb1723cef08930f70fc84b37b
2140 # Node ID 99b31f1c2782e2deb1723cef08930f70fc84b37b
2134 # Parent 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2141 # Parent 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2135 add another e
2142 add another e
2136
2143
2137 diff -r 5918b8d165d1 -r 99b31f1c2782 e
2144 diff -r 5918b8d165d1 -r 99b31f1c2782 e
2138 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2145 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2139 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2146 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2140 @@ -0,0 +1,1 @@
2147 @@ -0,0 +1,1 @@
2141 +ee
2148 +ee
2142 # HG changeset patch
2149 # HG changeset patch
2143 # User test
2150 # User test
2144 # Date 0 0
2151 # Date 0 0
2145 # Thu Jan 01 00:00:00 1970 +0000
2152 # Thu Jan 01 00:00:00 1970 +0000
2146 # Node ID fc281d8ff18d999ad6497b3d27390bcd695dcc73
2153 # Node ID fc281d8ff18d999ad6497b3d27390bcd695dcc73
2147 # Parent 99b31f1c2782e2deb1723cef08930f70fc84b37b
2154 # Parent 99b31f1c2782e2deb1723cef08930f70fc84b37b
2148 # Parent 17d952250a9d03cc3dc77b199ab60e959b9b0260
2155 # Parent 17d952250a9d03cc3dc77b199ab60e959b9b0260
2149 merge 5 and 4
2156 merge 5 and 4
2150
2157
2151 diff -r 99b31f1c2782 -r fc281d8ff18d dir/b
2158 diff -r 99b31f1c2782 -r fc281d8ff18d dir/b
2152 --- a/dir/b Thu Jan 01 00:00:00 1970 +0000
2159 --- a/dir/b Thu Jan 01 00:00:00 1970 +0000
2153 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2160 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2154 @@ -1,1 +0,0 @@
2161 @@ -1,1 +0,0 @@
2155 -a
2162 -a
2156 diff -r 99b31f1c2782 -r fc281d8ff18d e
2163 diff -r 99b31f1c2782 -r fc281d8ff18d e
2157 --- a/e Thu Jan 01 00:00:00 1970 +0000
2164 --- a/e Thu Jan 01 00:00:00 1970 +0000
2158 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2165 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2159 @@ -1,1 +1,1 @@
2166 @@ -1,1 +1,1 @@
2160 -ee
2167 -ee
2161 +merge
2168 +merge
2162 # HG changeset patch
2169 # HG changeset patch
2163 # User test
2170 # User test
2164 # Date 0 0
2171 # Date 0 0
2165 # Thu Jan 01 00:00:00 1970 +0000
2172 # Thu Jan 01 00:00:00 1970 +0000
2166 # Node ID 02dbb8e276b8ab7abfd07cab50c901647e75c2dd
2173 # Node ID 02dbb8e276b8ab7abfd07cab50c901647e75c2dd
2167 # Parent fc281d8ff18d999ad6497b3d27390bcd695dcc73
2174 # Parent fc281d8ff18d999ad6497b3d27390bcd695dcc73
2168 Added tag foo-bar for changeset fc281d8ff18d
2175 Added tag foo-bar for changeset fc281d8ff18d
2169
2176
2170 diff -r fc281d8ff18d -r 02dbb8e276b8 .hgtags
2177 diff -r fc281d8ff18d -r 02dbb8e276b8 .hgtags
2171 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2178 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2172 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2179 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2173 @@ -0,0 +1,1 @@
2180 @@ -0,0 +1,1 @@
2174 +fc281d8ff18d999ad6497b3d27390bcd695dcc73 foo-bar
2181 +fc281d8ff18d999ad6497b3d27390bcd695dcc73 foo-bar
2175 # HG changeset patch
2182 # HG changeset patch
2176 # User test
2183 # User test
2177 # Date 0 0
2184 # Date 0 0
2178 # Thu Jan 01 00:00:00 1970 +0000
2185 # Thu Jan 01 00:00:00 1970 +0000
2179 # Node ID 24c2e826ddebf80f9dcd60b856bdb8e6715c5449
2186 # Node ID 24c2e826ddebf80f9dcd60b856bdb8e6715c5449
2180 # Parent fc281d8ff18d999ad6497b3d27390bcd695dcc73
2187 # Parent fc281d8ff18d999ad6497b3d27390bcd695dcc73
2181 add g
2188 add g
2182
2189
2183 diff -r fc281d8ff18d -r 24c2e826ddeb g
2190 diff -r fc281d8ff18d -r 24c2e826ddeb g
2184 --- a/g Thu Jan 01 00:00:00 1970 +0000
2191 --- a/g Thu Jan 01 00:00:00 1970 +0000
2185 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2192 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2186 @@ -1,2 +1,1 @@
2193 @@ -1,2 +1,1 @@
2187 -f
2194 -f
2188 -f
2195 -f
2189 +g
2196 +g
2190 $ testlog --follow -r6 -r8 -r5 -r7 -r4
2197 $ testlog --follow -r6 -r8 -r5 -r7 -r4
2191 ['6', '8', '5', '7', '4']
2198 ['6', '8', '5', '7', '4']
2192 (group
2199 (group
2193 (func
2200 (func
2194 ('symbol', 'descendants')
2201 ('symbol', 'descendants')
2195 (func
2202 (func
2196 ('symbol', 'rev')
2203 ('symbol', 'rev')
2197 ('symbol', '6'))))
2204 ('symbol', '6'))))
2198 --- log.nodes * (glob)
2205 --- log.nodes * (glob)
2199 +++ glog.nodes * (glob)
2206 +++ glog.nodes * (glob)
2200 @@ -1,3 +1,3 @@
2207 @@ -1,3 +1,3 @@
2201 -nodetag 6
2208 -nodetag 6
2202 nodetag 8
2209 nodetag 8
2203 nodetag 7
2210 nodetag 7
2204 +nodetag 6
2211 +nodetag 6
2205
2212
2206 Test --follow-first and forward --rev
2213 Test --follow-first and forward --rev
2207
2214
2208 $ testlog --follow-first -r6 -r8 -r5 -r7 -r4
2215 $ testlog --follow-first -r6 -r8 -r5 -r7 -r4
2209 ['6', '8', '5', '7', '4']
2216 ['6', '8', '5', '7', '4']
2210 (group
2217 (group
2211 (func
2218 (func
2212 ('symbol', '_firstdescendants')
2219 ('symbol', '_firstdescendants')
2213 (func
2220 (func
2214 ('symbol', 'rev')
2221 ('symbol', 'rev')
2215 ('symbol', '6'))))
2222 ('symbol', '6'))))
2216 --- log.nodes * (glob)
2223 --- log.nodes * (glob)
2217 +++ glog.nodes * (glob)
2224 +++ glog.nodes * (glob)
2218 @@ -1,3 +1,3 @@
2225 @@ -1,3 +1,3 @@
2219 -nodetag 6
2226 -nodetag 6
2220 nodetag 8
2227 nodetag 8
2221 nodetag 7
2228 nodetag 7
2222 +nodetag 6
2229 +nodetag 6
2223
2230
2224 Test --follow and backward --rev
2231 Test --follow and backward --rev
2225
2232
2226 $ testlog --follow -r6 -r5 -r7 -r8 -r4
2233 $ testlog --follow -r6 -r5 -r7 -r8 -r4
2227 ['6', '5', '7', '8', '4']
2234 ['6', '5', '7', '8', '4']
2228 (group
2235 (group
2229 (func
2236 (func
2230 ('symbol', 'ancestors')
2237 ('symbol', 'ancestors')
2231 (func
2238 (func
2232 ('symbol', 'rev')
2239 ('symbol', 'rev')
2233 ('symbol', '6'))))
2240 ('symbol', '6'))))
2234
2241
2235 Test --follow-first and backward --rev
2242 Test --follow-first and backward --rev
2236
2243
2237 $ testlog --follow-first -r6 -r5 -r7 -r8 -r4
2244 $ testlog --follow-first -r6 -r5 -r7 -r8 -r4
2238 ['6', '5', '7', '8', '4']
2245 ['6', '5', '7', '8', '4']
2239 (group
2246 (group
2240 (func
2247 (func
2241 ('symbol', '_firstancestors')
2248 ('symbol', '_firstancestors')
2242 (func
2249 (func
2243 ('symbol', 'rev')
2250 ('symbol', 'rev')
2244 ('symbol', '6'))))
2251 ('symbol', '6'))))
2245
2252
2246 Test subdir
2253 Test subdir
2247
2254
2248 $ hg up -q 3
2255 $ hg up -q 3
2249 $ cd dir
2256 $ cd dir
2250 $ testlog .
2257 $ testlog .
2251 []
2258 []
2252 (group
2259 (group
2253 (func
2260 (func
2254 ('symbol', '_matchfiles')
2261 ('symbol', '_matchfiles')
2255 (list
2262 (list
2256 (list
2263 (list
2257 ('string', 'r:')
2264 ('string', 'r:')
2258 ('string', 'd:relpath'))
2265 ('string', 'd:relpath'))
2259 ('string', 'p:.'))))
2266 ('string', 'p:.'))))
2260 $ testlog ../b
2267 $ testlog ../b
2261 []
2268 []
2262 (group
2269 (group
2263 (group
2270 (group
2264 (func
2271 (func
2265 ('symbol', 'filelog')
2272 ('symbol', 'filelog')
2266 ('string', '../b'))))
2273 ('string', '../b'))))
2267 $ testlog -f ../b
2274 $ testlog -f ../b
2268 []
2275 []
2269 (group
2276 (group
2270 (group
2277 (group
2271 (func
2278 (func
2272 ('symbol', 'follow')
2279 ('symbol', 'follow')
2273 ('string', 'b'))))
2280 ('string', 'b'))))
2274 $ cd ..
2281 $ cd ..
2275
2282
2276 Test --hidden
2283 Test --hidden
2277 (enable obsolete)
2284 (enable obsolete)
2278
2285
2279 $ cat >> $HGRCPATH << EOF
2286 $ cat >> $HGRCPATH << EOF
2280 > [experimental]
2287 > [experimental]
2281 > evolution=createmarkers
2288 > evolution=createmarkers
2282 > EOF
2289 > EOF
2283
2290
2284 $ hg debugobsolete `hg id --debug -i -r 8`
2291 $ hg debugobsolete `hg id --debug -i -r 8`
2285 $ testlog
2292 $ testlog
2286 []
2293 []
2287 []
2294 []
2288 $ testlog --hidden
2295 $ testlog --hidden
2289 []
2296 []
2290 []
2297 []
2291 $ hg log -G --template '{rev} {desc}\n'
2298 $ hg log -G --template '{rev} {desc}\n'
2292 o 7 Added tag foo-bar for changeset fc281d8ff18d
2299 o 7 Added tag foo-bar for changeset fc281d8ff18d
2293 |
2300 |
2294 o 6 merge 5 and 4
2301 o 6 merge 5 and 4
2295 |\
2302 |\
2296 | o 5 add another e
2303 | o 5 add another e
2297 | |
2304 | |
2298 o | 4 mv dir/b e
2305 o | 4 mv dir/b e
2299 |/
2306 |/
2300 @ 3 mv a b; add d
2307 @ 3 mv a b; add d
2301 |
2308 |
2302 o 2 mv b dir/b
2309 o 2 mv b dir/b
2303 |
2310 |
2304 o 1 copy a b
2311 o 1 copy a b
2305 |
2312 |
2306 o 0 add a
2313 o 0 add a
2307
2314
2308
2315
2309 A template without trailing newline should do something sane
2316 A template without trailing newline should do something sane
2310
2317
2311 $ hg log -G -r ::2 --template '{rev} {desc}'
2318 $ hg log -G -r ::2 --template '{rev} {desc}'
2312 o 2 mv b dir/b
2319 o 2 mv b dir/b
2313 |
2320 |
2314 o 1 copy a b
2321 o 1 copy a b
2315 |
2322 |
2316 o 0 add a
2323 o 0 add a
2317
2324
2318
2325
2319 Extra newlines must be preserved
2326 Extra newlines must be preserved
2320
2327
2321 $ hg log -G -r ::2 --template '\n{rev} {desc}\n\n'
2328 $ hg log -G -r ::2 --template '\n{rev} {desc}\n\n'
2322 o
2329 o
2323 | 2 mv b dir/b
2330 | 2 mv b dir/b
2324 |
2331 |
2325 o
2332 o
2326 | 1 copy a b
2333 | 1 copy a b
2327 |
2334 |
2328 o
2335 o
2329 0 add a
2336 0 add a
2330
2337
2331
2338
2332 The almost-empty template should do something sane too ...
2339 The almost-empty template should do something sane too ...
2333
2340
2334 $ hg log -G -r ::2 --template '\n'
2341 $ hg log -G -r ::2 --template '\n'
2335 o
2342 o
2336 |
2343 |
2337 o
2344 o
2338 |
2345 |
2339 o
2346 o
2340
2347
2341
2348
2342 issue3772
2349 issue3772
2343
2350
2344 $ hg log -G -r :null
2351 $ hg log -G -r :null
2345 o changeset: 0:f8035bb17114
2352 o changeset: 0:f8035bb17114
2346 | user: test
2353 | user: test
2347 | date: Thu Jan 01 00:00:00 1970 +0000
2354 | date: Thu Jan 01 00:00:00 1970 +0000
2348 | summary: add a
2355 | summary: add a
2349 |
2356 |
2350 o changeset: -1:000000000000
2357 o changeset: -1:000000000000
2351 user:
2358 user:
2352 date: Thu Jan 01 00:00:00 1970 +0000
2359 date: Thu Jan 01 00:00:00 1970 +0000
2353
2360
2354 $ hg log -G -r null:null
2361 $ hg log -G -r null:null
2355 o changeset: -1:000000000000
2362 o changeset: -1:000000000000
2356 user:
2363 user:
2357 date: Thu Jan 01 00:00:00 1970 +0000
2364 date: Thu Jan 01 00:00:00 1970 +0000
2358
2365
2359
2366
2360 $ cd ..
2367 $ cd ..
@@ -1,182 +1,186 b''
1 $ hg init t
1 $ hg init t
2 $ cd t
2 $ cd t
3 $ echo import > port
3 $ echo import > port
4 $ hg add port
4 $ hg add port
5 $ hg commit -m 0 -u spam -d '0 0'
5 $ hg commit -m 0 -u spam -d '0 0'
6 $ echo export >> port
6 $ echo export >> port
7 $ hg commit -m 1 -u eggs -d '1 0'
7 $ hg commit -m 1 -u eggs -d '1 0'
8 $ echo export > port
8 $ echo export > port
9 $ echo vaportight >> port
9 $ echo vaportight >> port
10 $ echo 'import/export' >> port
10 $ echo 'import/export' >> port
11 $ hg commit -m 2 -u spam -d '2 0'
11 $ hg commit -m 2 -u spam -d '2 0'
12 $ echo 'import/export' >> port
12 $ echo 'import/export' >> port
13 $ hg commit -m 3 -u eggs -d '3 0'
13 $ hg commit -m 3 -u eggs -d '3 0'
14 $ head -n 3 port > port1
14 $ head -n 3 port > port1
15 $ mv port1 port
15 $ mv port1 port
16 $ hg commit -m 4 -u spam -d '4 0'
16 $ hg commit -m 4 -u spam -d '4 0'
17
17
18 pattern error
18 pattern error
19
19
20 $ hg grep '**test**'
20 $ hg grep '**test**'
21 grep: invalid match pattern: nothing to repeat
21 grep: invalid match pattern: nothing to repeat
22 [1]
22 [1]
23
23
24 simple
24 simple
25
25
26 $ hg grep '.*'
26 $ hg grep '.*'
27 port:4:export
27 port:4:export
28 port:4:vaportight
28 port:4:vaportight
29 port:4:import/export
29 port:4:import/export
30 $ hg grep port port
30 $ hg grep port port
31 port:4:export
31 port:4:export
32 port:4:vaportight
32 port:4:vaportight
33 port:4:import/export
33 port:4:import/export
34
34
35 simple with color
35 simple with color
36
36
37 $ hg --config extensions.color= grep --config color.mode=ansi \
37 $ hg --config extensions.color= grep --config color.mode=ansi \
38 > --color=always port port
38 > --color=always port port
39 \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc)
39 \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc)
40 \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc)
40 \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc)
41 \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc)
41 \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc)
42
42
43 all
43 all
44
44
45 $ hg grep --traceback --all -nu port port
45 $ hg grep --traceback --all -nu port port
46 port:4:4:-:spam:import/export
46 port:4:4:-:spam:import/export
47 port:3:4:+:eggs:import/export
47 port:3:4:+:eggs:import/export
48 port:2:1:-:spam:import
48 port:2:1:-:spam:import
49 port:2:2:-:spam:export
49 port:2:2:-:spam:export
50 port:2:1:+:spam:export
50 port:2:1:+:spam:export
51 port:2:2:+:spam:vaportight
51 port:2:2:+:spam:vaportight
52 port:2:3:+:spam:import/export
52 port:2:3:+:spam:import/export
53 port:1:2:+:eggs:export
53 port:1:2:+:eggs:export
54 port:0:1:+:spam:import
54 port:0:1:+:spam:import
55
55
56 other
56 other
57
57
58 $ hg grep -l port port
58 $ hg grep -l port port
59 port:4
59 port:4
60 $ hg grep import port
60 $ hg grep import port
61 port:4:import/export
61 port:4:import/export
62
62
63 $ hg cp port port2
63 $ hg cp port port2
64 $ hg commit -m 4 -u spam -d '5 0'
64 $ hg commit -m 4 -u spam -d '5 0'
65
65
66 follow
66 follow
67
67
68 $ hg grep --traceback -f 'import\n\Z' port2
68 $ hg grep --traceback -f 'import\n\Z' port2
69 port:0:import
69 port:0:import
70
70
71 $ echo deport >> port2
71 $ echo deport >> port2
72 $ hg commit -m 5 -u eggs -d '6 0'
72 $ hg commit -m 5 -u eggs -d '6 0'
73 $ hg grep -f --all -nu port port2
73 $ hg grep -f --all -nu port port2
74 port2:6:4:+:eggs:deport
74 port2:6:4:+:eggs:deport
75 port:4:4:-:spam:import/export
75 port:4:4:-:spam:import/export
76 port:3:4:+:eggs:import/export
76 port:3:4:+:eggs:import/export
77 port:2:1:-:spam:import
77 port:2:1:-:spam:import
78 port:2:2:-:spam:export
78 port:2:2:-:spam:export
79 port:2:1:+:spam:export
79 port:2:1:+:spam:export
80 port:2:2:+:spam:vaportight
80 port:2:2:+:spam:vaportight
81 port:2:3:+:spam:import/export
81 port:2:3:+:spam:import/export
82 port:1:2:+:eggs:export
82 port:1:2:+:eggs:export
83 port:0:1:+:spam:import
83 port:0:1:+:spam:import
84
84
85 $ hg up -q null
86 $ hg grep -f port
87 [1]
88
85 $ cd ..
89 $ cd ..
86 $ hg init t2
90 $ hg init t2
87 $ cd t2
91 $ cd t2
88 $ hg grep foobar foo
92 $ hg grep foobar foo
89 [1]
93 [1]
90 $ hg grep foobar
94 $ hg grep foobar
91 [1]
95 [1]
92 $ echo blue >> color
96 $ echo blue >> color
93 $ echo black >> color
97 $ echo black >> color
94 $ hg add color
98 $ hg add color
95 $ hg ci -m 0
99 $ hg ci -m 0
96 $ echo orange >> color
100 $ echo orange >> color
97 $ hg ci -m 1
101 $ hg ci -m 1
98 $ echo black > color
102 $ echo black > color
99 $ hg ci -m 2
103 $ hg ci -m 2
100 $ echo orange >> color
104 $ echo orange >> color
101 $ echo blue >> color
105 $ echo blue >> color
102 $ hg ci -m 3
106 $ hg ci -m 3
103 $ hg grep orange
107 $ hg grep orange
104 color:3:orange
108 color:3:orange
105 $ hg grep --all orange
109 $ hg grep --all orange
106 color:3:+:orange
110 color:3:+:orange
107 color:2:-:orange
111 color:2:-:orange
108 color:1:+:orange
112 color:1:+:orange
109
113
110
114
111 match in last "line" without newline
115 match in last "line" without newline
112
116
113 $ $PYTHON -c 'fp = open("noeol", "wb"); fp.write("no infinite loop"); fp.close();'
117 $ $PYTHON -c 'fp = open("noeol", "wb"); fp.write("no infinite loop"); fp.close();'
114 $ hg ci -Amnoeol
118 $ hg ci -Amnoeol
115 adding noeol
119 adding noeol
116 $ hg grep loop
120 $ hg grep loop
117 noeol:4:no infinite loop
121 noeol:4:no infinite loop
118
122
119 $ cd ..
123 $ cd ..
120
124
121 Issue685: traceback in grep -r after rename
125 Issue685: traceback in grep -r after rename
122
126
123 Got a traceback when using grep on a single
127 Got a traceback when using grep on a single
124 revision with renamed files.
128 revision with renamed files.
125
129
126 $ hg init issue685
130 $ hg init issue685
127 $ cd issue685
131 $ cd issue685
128 $ echo octarine > color
132 $ echo octarine > color
129 $ hg ci -Amcolor
133 $ hg ci -Amcolor
130 adding color
134 adding color
131 $ hg rename color colour
135 $ hg rename color colour
132 $ hg ci -Am rename
136 $ hg ci -Am rename
133 $ hg grep octarine
137 $ hg grep octarine
134 colour:1:octarine
138 colour:1:octarine
135 color:0:octarine
139 color:0:octarine
136
140
137 Used to crash here
141 Used to crash here
138
142
139 $ hg grep -r 1 octarine
143 $ hg grep -r 1 octarine
140 colour:1:octarine
144 colour:1:octarine
141 $ cd ..
145 $ cd ..
142
146
143
147
144 Issue337: test that grep follows parent-child relationships instead
148 Issue337: test that grep follows parent-child relationships instead
145 of just using revision numbers.
149 of just using revision numbers.
146
150
147 $ hg init issue337
151 $ hg init issue337
148 $ cd issue337
152 $ cd issue337
149
153
150 $ echo white > color
154 $ echo white > color
151 $ hg commit -A -m "0 white"
155 $ hg commit -A -m "0 white"
152 adding color
156 adding color
153
157
154 $ echo red > color
158 $ echo red > color
155 $ hg commit -A -m "1 red"
159 $ hg commit -A -m "1 red"
156
160
157 $ hg update 0
161 $ hg update 0
158 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 $ echo black > color
163 $ echo black > color
160 $ hg commit -A -m "2 black"
164 $ hg commit -A -m "2 black"
161 created new head
165 created new head
162
166
163 $ hg update --clean 1
167 $ hg update --clean 1
164 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
165 $ echo blue > color
169 $ echo blue > color
166 $ hg commit -A -m "3 blue"
170 $ hg commit -A -m "3 blue"
167
171
168 $ hg grep --all red
172 $ hg grep --all red
169 color:3:-:red
173 color:3:-:red
170 color:1:+:red
174 color:1:+:red
171
175
172 $ cd ..
176 $ cd ..
173
177
174 $ hg init a
178 $ hg init a
175 $ cd a
179 $ cd a
176 $ cp "$TESTDIR/binfile.bin" .
180 $ cp "$TESTDIR/binfile.bin" .
177 $ hg add binfile.bin
181 $ hg add binfile.bin
178 $ hg ci -m 'add binfile.bin'
182 $ hg ci -m 'add binfile.bin'
179 $ hg grep "MaCam" --all
183 $ hg grep "MaCam" --all
180 binfile.bin:0:+: Binary file matches
184 binfile.bin:0:+: Binary file matches
181
185
182 $ cd ..
186 $ cd ..
@@ -1,1961 +1,1968 b''
1 Log on empty repository: checking consistency
1 Log on empty repository: checking consistency
2
2
3 $ hg init empty
3 $ hg init empty
4 $ cd empty
4 $ cd empty
5 $ hg log
5 $ hg log
6 $ hg log -r 1
6 $ hg log -r 1
7 abort: unknown revision '1'!
7 abort: unknown revision '1'!
8 [255]
8 [255]
9 $ hg log -r -1:0
9 $ hg log -r -1:0
10 abort: unknown revision '-1'!
10 abort: unknown revision '-1'!
11 [255]
11 [255]
12 $ hg log -r 'branch(name)'
12 $ hg log -r 'branch(name)'
13 abort: unknown revision 'name'!
13 abort: unknown revision 'name'!
14 [255]
14 [255]
15 $ hg log -r null -q
15 $ hg log -r null -q
16 -1:000000000000
16 -1:000000000000
17
17
18 The g is crafted to have 2 filelog topological heads in a linear
18 The g is crafted to have 2 filelog topological heads in a linear
19 changeset graph
19 changeset graph
20
20
21 $ hg init a
21 $ hg init a
22 $ cd a
22 $ cd a
23 $ echo a > a
23 $ echo a > a
24 $ echo f > f
24 $ echo f > f
25 $ hg ci -Ama -d '1 0'
25 $ hg ci -Ama -d '1 0'
26 adding a
26 adding a
27 adding f
27 adding f
28
28
29 $ hg cp a b
29 $ hg cp a b
30 $ hg cp f g
30 $ hg cp f g
31 $ hg ci -mb -d '2 0'
31 $ hg ci -mb -d '2 0'
32
32
33 $ mkdir dir
33 $ mkdir dir
34 $ hg mv b dir
34 $ hg mv b dir
35 $ echo g >> g
35 $ echo g >> g
36 $ echo f >> f
36 $ echo f >> f
37 $ hg ci -mc -d '3 0'
37 $ hg ci -mc -d '3 0'
38
38
39 $ hg mv a b
39 $ hg mv a b
40 $ hg cp -f f g
40 $ hg cp -f f g
41 $ echo a > d
41 $ echo a > d
42 $ hg add d
42 $ hg add d
43 $ hg ci -md -d '4 0'
43 $ hg ci -md -d '4 0'
44
44
45 $ hg mv dir/b e
45 $ hg mv dir/b e
46 $ hg ci -me -d '5 0'
46 $ hg ci -me -d '5 0'
47
47
48 Make sure largefiles doesn't interfere with logging a regular file
48 Make sure largefiles doesn't interfere with logging a regular file
49 $ hg log a --config extensions.largefiles=
49 $ hg log a --config extensions.largefiles=
50 changeset: 0:9161b9aeaf16
50 changeset: 0:9161b9aeaf16
51 user: test
51 user: test
52 date: Thu Jan 01 00:00:01 1970 +0000
52 date: Thu Jan 01 00:00:01 1970 +0000
53 summary: a
53 summary: a
54
54
55 $ hg log a
55 $ hg log a
56 changeset: 0:9161b9aeaf16
56 changeset: 0:9161b9aeaf16
57 user: test
57 user: test
58 date: Thu Jan 01 00:00:01 1970 +0000
58 date: Thu Jan 01 00:00:01 1970 +0000
59 summary: a
59 summary: a
60
60
61 log on directory
61 log on directory
62
62
63 $ hg log dir
63 $ hg log dir
64 changeset: 4:7e4639b4691b
64 changeset: 4:7e4639b4691b
65 tag: tip
65 tag: tip
66 user: test
66 user: test
67 date: Thu Jan 01 00:00:05 1970 +0000
67 date: Thu Jan 01 00:00:05 1970 +0000
68 summary: e
68 summary: e
69
69
70 changeset: 2:f8954cd4dc1f
70 changeset: 2:f8954cd4dc1f
71 user: test
71 user: test
72 date: Thu Jan 01 00:00:03 1970 +0000
72 date: Thu Jan 01 00:00:03 1970 +0000
73 summary: c
73 summary: c
74
74
75 $ hg log somethingthatdoesntexist dir
75 $ hg log somethingthatdoesntexist dir
76 changeset: 4:7e4639b4691b
76 changeset: 4:7e4639b4691b
77 tag: tip
77 tag: tip
78 user: test
78 user: test
79 date: Thu Jan 01 00:00:05 1970 +0000
79 date: Thu Jan 01 00:00:05 1970 +0000
80 summary: e
80 summary: e
81
81
82 changeset: 2:f8954cd4dc1f
82 changeset: 2:f8954cd4dc1f
83 user: test
83 user: test
84 date: Thu Jan 01 00:00:03 1970 +0000
84 date: Thu Jan 01 00:00:03 1970 +0000
85 summary: c
85 summary: c
86
86
87
87
88 -f, non-existent directory
88 -f, non-existent directory
89
89
90 $ hg log -f dir
90 $ hg log -f dir
91 abort: cannot follow file not in parent revision: "dir"
91 abort: cannot follow file not in parent revision: "dir"
92 [255]
92 [255]
93
93
94 -f, directory
94 -f, directory
95
95
96 $ hg up -q 3
96 $ hg up -q 3
97 $ hg log -f dir
97 $ hg log -f dir
98 changeset: 2:f8954cd4dc1f
98 changeset: 2:f8954cd4dc1f
99 user: test
99 user: test
100 date: Thu Jan 01 00:00:03 1970 +0000
100 date: Thu Jan 01 00:00:03 1970 +0000
101 summary: c
101 summary: c
102
102
103 -f, directory with --patch
103 -f, directory with --patch
104
104
105 $ hg log -f dir -p
105 $ hg log -f dir -p
106 changeset: 2:f8954cd4dc1f
106 changeset: 2:f8954cd4dc1f
107 user: test
107 user: test
108 date: Thu Jan 01 00:00:03 1970 +0000
108 date: Thu Jan 01 00:00:03 1970 +0000
109 summary: c
109 summary: c
110
110
111 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
111 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
112 --- /dev/null* (glob)
112 --- /dev/null* (glob)
113 +++ b/dir/b* (glob)
113 +++ b/dir/b* (glob)
114 @@ -0,0 +1,1 @@
114 @@ -0,0 +1,1 @@
115 +a
115 +a
116
116
117
117
118 -f, pattern
118 -f, pattern
119
119
120 $ hg log -f -I 'dir**' -p
120 $ hg log -f -I 'dir**' -p
121 changeset: 2:f8954cd4dc1f
121 changeset: 2:f8954cd4dc1f
122 user: test
122 user: test
123 date: Thu Jan 01 00:00:03 1970 +0000
123 date: Thu Jan 01 00:00:03 1970 +0000
124 summary: c
124 summary: c
125
125
126 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
126 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
127 --- /dev/null* (glob)
127 --- /dev/null* (glob)
128 +++ b/dir/b* (glob)
128 +++ b/dir/b* (glob)
129 @@ -0,0 +1,1 @@
129 @@ -0,0 +1,1 @@
130 +a
130 +a
131
131
132 $ hg up -q 4
132 $ hg up -q 4
133
133
134 -f, a wrong style
134 -f, a wrong style
135
135
136 $ hg log -f -l1 --style something
136 $ hg log -f -l1 --style something
137 abort: style 'something' not found
137 abort: style 'something' not found
138 (available styles: bisect, changelog, compact, default, phases, xml)
138 (available styles: bisect, changelog, compact, default, phases, xml)
139 [255]
139 [255]
140
140
141 -f, phases style
141 -f, phases style
142
142
143
143
144 $ hg log -f -l1 --style phases
144 $ hg log -f -l1 --style phases
145 changeset: 4:7e4639b4691b
145 changeset: 4:7e4639b4691b
146 tag: tip
146 tag: tip
147 phase: draft
147 phase: draft
148 user: test
148 user: test
149 date: Thu Jan 01 00:00:05 1970 +0000
149 date: Thu Jan 01 00:00:05 1970 +0000
150 summary: e
150 summary: e
151
151
152
152
153 -f, but no args
153 -f, but no args
154
154
155 $ hg log -f
155 $ hg log -f
156 changeset: 4:7e4639b4691b
156 changeset: 4:7e4639b4691b
157 tag: tip
157 tag: tip
158 user: test
158 user: test
159 date: Thu Jan 01 00:00:05 1970 +0000
159 date: Thu Jan 01 00:00:05 1970 +0000
160 summary: e
160 summary: e
161
161
162 changeset: 3:2ca5ba701980
162 changeset: 3:2ca5ba701980
163 user: test
163 user: test
164 date: Thu Jan 01 00:00:04 1970 +0000
164 date: Thu Jan 01 00:00:04 1970 +0000
165 summary: d
165 summary: d
166
166
167 changeset: 2:f8954cd4dc1f
167 changeset: 2:f8954cd4dc1f
168 user: test
168 user: test
169 date: Thu Jan 01 00:00:03 1970 +0000
169 date: Thu Jan 01 00:00:03 1970 +0000
170 summary: c
170 summary: c
171
171
172 changeset: 1:d89b0a12d229
172 changeset: 1:d89b0a12d229
173 user: test
173 user: test
174 date: Thu Jan 01 00:00:02 1970 +0000
174 date: Thu Jan 01 00:00:02 1970 +0000
175 summary: b
175 summary: b
176
176
177 changeset: 0:9161b9aeaf16
177 changeset: 0:9161b9aeaf16
178 user: test
178 user: test
179 date: Thu Jan 01 00:00:01 1970 +0000
179 date: Thu Jan 01 00:00:01 1970 +0000
180 summary: a
180 summary: a
181
181
182
182
183 one rename
183 one rename
184
184
185 $ hg up -q 2
185 $ hg up -q 2
186 $ hg log -vf a
186 $ hg log -vf a
187 changeset: 0:9161b9aeaf16
187 changeset: 0:9161b9aeaf16
188 user: test
188 user: test
189 date: Thu Jan 01 00:00:01 1970 +0000
189 date: Thu Jan 01 00:00:01 1970 +0000
190 files: a f
190 files: a f
191 description:
191 description:
192 a
192 a
193
193
194
194
195
195
196 many renames
196 many renames
197
197
198 $ hg up -q tip
198 $ hg up -q tip
199 $ hg log -vf e
199 $ hg log -vf e
200 changeset: 4:7e4639b4691b
200 changeset: 4:7e4639b4691b
201 tag: tip
201 tag: tip
202 user: test
202 user: test
203 date: Thu Jan 01 00:00:05 1970 +0000
203 date: Thu Jan 01 00:00:05 1970 +0000
204 files: dir/b e
204 files: dir/b e
205 description:
205 description:
206 e
206 e
207
207
208
208
209 changeset: 2:f8954cd4dc1f
209 changeset: 2:f8954cd4dc1f
210 user: test
210 user: test
211 date: Thu Jan 01 00:00:03 1970 +0000
211 date: Thu Jan 01 00:00:03 1970 +0000
212 files: b dir/b f g
212 files: b dir/b f g
213 description:
213 description:
214 c
214 c
215
215
216
216
217 changeset: 1:d89b0a12d229
217 changeset: 1:d89b0a12d229
218 user: test
218 user: test
219 date: Thu Jan 01 00:00:02 1970 +0000
219 date: Thu Jan 01 00:00:02 1970 +0000
220 files: b g
220 files: b g
221 description:
221 description:
222 b
222 b
223
223
224
224
225 changeset: 0:9161b9aeaf16
225 changeset: 0:9161b9aeaf16
226 user: test
226 user: test
227 date: Thu Jan 01 00:00:01 1970 +0000
227 date: Thu Jan 01 00:00:01 1970 +0000
228 files: a f
228 files: a f
229 description:
229 description:
230 a
230 a
231
231
232
232
233
233
234
234
235 log -pf dir/b
235 log -pf dir/b
236
236
237 $ hg up -q 3
237 $ hg up -q 3
238 $ hg log -pf dir/b
238 $ hg log -pf dir/b
239 changeset: 2:f8954cd4dc1f
239 changeset: 2:f8954cd4dc1f
240 user: test
240 user: test
241 date: Thu Jan 01 00:00:03 1970 +0000
241 date: Thu Jan 01 00:00:03 1970 +0000
242 summary: c
242 summary: c
243
243
244 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
244 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
245 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
245 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
246 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
246 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
247 @@ -0,0 +1,1 @@
247 @@ -0,0 +1,1 @@
248 +a
248 +a
249
249
250 changeset: 1:d89b0a12d229
250 changeset: 1:d89b0a12d229
251 user: test
251 user: test
252 date: Thu Jan 01 00:00:02 1970 +0000
252 date: Thu Jan 01 00:00:02 1970 +0000
253 summary: b
253 summary: b
254
254
255 diff -r 9161b9aeaf16 -r d89b0a12d229 b
255 diff -r 9161b9aeaf16 -r d89b0a12d229 b
256 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
256 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
257 +++ b/b Thu Jan 01 00:00:02 1970 +0000
257 +++ b/b Thu Jan 01 00:00:02 1970 +0000
258 @@ -0,0 +1,1 @@
258 @@ -0,0 +1,1 @@
259 +a
259 +a
260
260
261 changeset: 0:9161b9aeaf16
261 changeset: 0:9161b9aeaf16
262 user: test
262 user: test
263 date: Thu Jan 01 00:00:01 1970 +0000
263 date: Thu Jan 01 00:00:01 1970 +0000
264 summary: a
264 summary: a
265
265
266 diff -r 000000000000 -r 9161b9aeaf16 a
266 diff -r 000000000000 -r 9161b9aeaf16 a
267 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
267 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
268 +++ b/a Thu Jan 01 00:00:01 1970 +0000
268 +++ b/a Thu Jan 01 00:00:01 1970 +0000
269 @@ -0,0 +1,1 @@
269 @@ -0,0 +1,1 @@
270 +a
270 +a
271
271
272
272
273 log -pf b inside dir
273 log -pf b inside dir
274
274
275 $ hg --cwd=dir log -pf b
275 $ hg --cwd=dir log -pf b
276 changeset: 2:f8954cd4dc1f
276 changeset: 2:f8954cd4dc1f
277 user: test
277 user: test
278 date: Thu Jan 01 00:00:03 1970 +0000
278 date: Thu Jan 01 00:00:03 1970 +0000
279 summary: c
279 summary: c
280
280
281 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
281 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
282 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
282 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
283 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
283 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
284 @@ -0,0 +1,1 @@
284 @@ -0,0 +1,1 @@
285 +a
285 +a
286
286
287 changeset: 1:d89b0a12d229
287 changeset: 1:d89b0a12d229
288 user: test
288 user: test
289 date: Thu Jan 01 00:00:02 1970 +0000
289 date: Thu Jan 01 00:00:02 1970 +0000
290 summary: b
290 summary: b
291
291
292 diff -r 9161b9aeaf16 -r d89b0a12d229 b
292 diff -r 9161b9aeaf16 -r d89b0a12d229 b
293 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
293 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
294 +++ b/b Thu Jan 01 00:00:02 1970 +0000
294 +++ b/b Thu Jan 01 00:00:02 1970 +0000
295 @@ -0,0 +1,1 @@
295 @@ -0,0 +1,1 @@
296 +a
296 +a
297
297
298 changeset: 0:9161b9aeaf16
298 changeset: 0:9161b9aeaf16
299 user: test
299 user: test
300 date: Thu Jan 01 00:00:01 1970 +0000
300 date: Thu Jan 01 00:00:01 1970 +0000
301 summary: a
301 summary: a
302
302
303 diff -r 000000000000 -r 9161b9aeaf16 a
303 diff -r 000000000000 -r 9161b9aeaf16 a
304 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
304 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
305 +++ b/a Thu Jan 01 00:00:01 1970 +0000
305 +++ b/a Thu Jan 01 00:00:01 1970 +0000
306 @@ -0,0 +1,1 @@
306 @@ -0,0 +1,1 @@
307 +a
307 +a
308
308
309
309
310 log -pf, but no args
310 log -pf, but no args
311
311
312 $ hg log -pf
312 $ hg log -pf
313 changeset: 3:2ca5ba701980
313 changeset: 3:2ca5ba701980
314 user: test
314 user: test
315 date: Thu Jan 01 00:00:04 1970 +0000
315 date: Thu Jan 01 00:00:04 1970 +0000
316 summary: d
316 summary: d
317
317
318 diff -r f8954cd4dc1f -r 2ca5ba701980 a
318 diff -r f8954cd4dc1f -r 2ca5ba701980 a
319 --- a/a Thu Jan 01 00:00:03 1970 +0000
319 --- a/a Thu Jan 01 00:00:03 1970 +0000
320 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
320 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
321 @@ -1,1 +0,0 @@
321 @@ -1,1 +0,0 @@
322 -a
322 -a
323 diff -r f8954cd4dc1f -r 2ca5ba701980 b
323 diff -r f8954cd4dc1f -r 2ca5ba701980 b
324 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
324 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
325 +++ b/b Thu Jan 01 00:00:04 1970 +0000
325 +++ b/b Thu Jan 01 00:00:04 1970 +0000
326 @@ -0,0 +1,1 @@
326 @@ -0,0 +1,1 @@
327 +a
327 +a
328 diff -r f8954cd4dc1f -r 2ca5ba701980 d
328 diff -r f8954cd4dc1f -r 2ca5ba701980 d
329 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
329 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
330 +++ b/d Thu Jan 01 00:00:04 1970 +0000
330 +++ b/d Thu Jan 01 00:00:04 1970 +0000
331 @@ -0,0 +1,1 @@
331 @@ -0,0 +1,1 @@
332 +a
332 +a
333 diff -r f8954cd4dc1f -r 2ca5ba701980 g
333 diff -r f8954cd4dc1f -r 2ca5ba701980 g
334 --- a/g Thu Jan 01 00:00:03 1970 +0000
334 --- a/g Thu Jan 01 00:00:03 1970 +0000
335 +++ b/g Thu Jan 01 00:00:04 1970 +0000
335 +++ b/g Thu Jan 01 00:00:04 1970 +0000
336 @@ -1,2 +1,2 @@
336 @@ -1,2 +1,2 @@
337 f
337 f
338 -g
338 -g
339 +f
339 +f
340
340
341 changeset: 2:f8954cd4dc1f
341 changeset: 2:f8954cd4dc1f
342 user: test
342 user: test
343 date: Thu Jan 01 00:00:03 1970 +0000
343 date: Thu Jan 01 00:00:03 1970 +0000
344 summary: c
344 summary: c
345
345
346 diff -r d89b0a12d229 -r f8954cd4dc1f b
346 diff -r d89b0a12d229 -r f8954cd4dc1f b
347 --- a/b Thu Jan 01 00:00:02 1970 +0000
347 --- a/b Thu Jan 01 00:00:02 1970 +0000
348 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
348 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
349 @@ -1,1 +0,0 @@
349 @@ -1,1 +0,0 @@
350 -a
350 -a
351 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
351 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
352 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
352 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
353 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
353 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
354 @@ -0,0 +1,1 @@
354 @@ -0,0 +1,1 @@
355 +a
355 +a
356 diff -r d89b0a12d229 -r f8954cd4dc1f f
356 diff -r d89b0a12d229 -r f8954cd4dc1f f
357 --- a/f Thu Jan 01 00:00:02 1970 +0000
357 --- a/f Thu Jan 01 00:00:02 1970 +0000
358 +++ b/f Thu Jan 01 00:00:03 1970 +0000
358 +++ b/f Thu Jan 01 00:00:03 1970 +0000
359 @@ -1,1 +1,2 @@
359 @@ -1,1 +1,2 @@
360 f
360 f
361 +f
361 +f
362 diff -r d89b0a12d229 -r f8954cd4dc1f g
362 diff -r d89b0a12d229 -r f8954cd4dc1f g
363 --- a/g Thu Jan 01 00:00:02 1970 +0000
363 --- a/g Thu Jan 01 00:00:02 1970 +0000
364 +++ b/g Thu Jan 01 00:00:03 1970 +0000
364 +++ b/g Thu Jan 01 00:00:03 1970 +0000
365 @@ -1,1 +1,2 @@
365 @@ -1,1 +1,2 @@
366 f
366 f
367 +g
367 +g
368
368
369 changeset: 1:d89b0a12d229
369 changeset: 1:d89b0a12d229
370 user: test
370 user: test
371 date: Thu Jan 01 00:00:02 1970 +0000
371 date: Thu Jan 01 00:00:02 1970 +0000
372 summary: b
372 summary: b
373
373
374 diff -r 9161b9aeaf16 -r d89b0a12d229 b
374 diff -r 9161b9aeaf16 -r d89b0a12d229 b
375 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
375 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
376 +++ b/b Thu Jan 01 00:00:02 1970 +0000
376 +++ b/b Thu Jan 01 00:00:02 1970 +0000
377 @@ -0,0 +1,1 @@
377 @@ -0,0 +1,1 @@
378 +a
378 +a
379 diff -r 9161b9aeaf16 -r d89b0a12d229 g
379 diff -r 9161b9aeaf16 -r d89b0a12d229 g
380 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
380 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
381 +++ b/g Thu Jan 01 00:00:02 1970 +0000
381 +++ b/g Thu Jan 01 00:00:02 1970 +0000
382 @@ -0,0 +1,1 @@
382 @@ -0,0 +1,1 @@
383 +f
383 +f
384
384
385 changeset: 0:9161b9aeaf16
385 changeset: 0:9161b9aeaf16
386 user: test
386 user: test
387 date: Thu Jan 01 00:00:01 1970 +0000
387 date: Thu Jan 01 00:00:01 1970 +0000
388 summary: a
388 summary: a
389
389
390 diff -r 000000000000 -r 9161b9aeaf16 a
390 diff -r 000000000000 -r 9161b9aeaf16 a
391 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
391 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
392 +++ b/a Thu Jan 01 00:00:01 1970 +0000
392 +++ b/a Thu Jan 01 00:00:01 1970 +0000
393 @@ -0,0 +1,1 @@
393 @@ -0,0 +1,1 @@
394 +a
394 +a
395 diff -r 000000000000 -r 9161b9aeaf16 f
395 diff -r 000000000000 -r 9161b9aeaf16 f
396 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
396 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
397 +++ b/f Thu Jan 01 00:00:01 1970 +0000
397 +++ b/f Thu Jan 01 00:00:01 1970 +0000
398 @@ -0,0 +1,1 @@
398 @@ -0,0 +1,1 @@
399 +f
399 +f
400
400
401
401
402 log -vf dir/b
402 log -vf dir/b
403
403
404 $ hg log -vf dir/b
404 $ hg log -vf dir/b
405 changeset: 2:f8954cd4dc1f
405 changeset: 2:f8954cd4dc1f
406 user: test
406 user: test
407 date: Thu Jan 01 00:00:03 1970 +0000
407 date: Thu Jan 01 00:00:03 1970 +0000
408 files: b dir/b f g
408 files: b dir/b f g
409 description:
409 description:
410 c
410 c
411
411
412
412
413 changeset: 1:d89b0a12d229
413 changeset: 1:d89b0a12d229
414 user: test
414 user: test
415 date: Thu Jan 01 00:00:02 1970 +0000
415 date: Thu Jan 01 00:00:02 1970 +0000
416 files: b g
416 files: b g
417 description:
417 description:
418 b
418 b
419
419
420
420
421 changeset: 0:9161b9aeaf16
421 changeset: 0:9161b9aeaf16
422 user: test
422 user: test
423 date: Thu Jan 01 00:00:01 1970 +0000
423 date: Thu Jan 01 00:00:01 1970 +0000
424 files: a f
424 files: a f
425 description:
425 description:
426 a
426 a
427
427
428
428
429
429
430
430
431 -f and multiple filelog heads
431 -f and multiple filelog heads
432
432
433 $ hg up -q 2
433 $ hg up -q 2
434 $ hg log -f g --template '{rev}\n'
434 $ hg log -f g --template '{rev}\n'
435 2
435 2
436 1
436 1
437 0
437 0
438 $ hg up -q tip
438 $ hg up -q tip
439 $ hg log -f g --template '{rev}\n'
439 $ hg log -f g --template '{rev}\n'
440 3
440 3
441 2
441 2
442 0
442 0
443
443
444
444
445 log copies with --copies
445 log copies with --copies
446
446
447 $ hg log -vC --template '{rev} {file_copies}\n'
447 $ hg log -vC --template '{rev} {file_copies}\n'
448 4 e (dir/b)
448 4 e (dir/b)
449 3 b (a)g (f)
449 3 b (a)g (f)
450 2 dir/b (b)
450 2 dir/b (b)
451 1 b (a)g (f)
451 1 b (a)g (f)
452 0
452 0
453
453
454 log copies switch without --copies, with old filecopy template
454 log copies switch without --copies, with old filecopy template
455
455
456 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
456 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
457 4
457 4
458 3
458 3
459 2
459 2
460 1
460 1
461 0
461 0
462
462
463 log copies switch with --copies
463 log copies switch with --copies
464
464
465 $ hg log -vC --template '{rev} {file_copies_switch}\n'
465 $ hg log -vC --template '{rev} {file_copies_switch}\n'
466 4 e (dir/b)
466 4 e (dir/b)
467 3 b (a)g (f)
467 3 b (a)g (f)
468 2 dir/b (b)
468 2 dir/b (b)
469 1 b (a)g (f)
469 1 b (a)g (f)
470 0
470 0
471
471
472
472
473 log copies with hardcoded style and with --style=default
473 log copies with hardcoded style and with --style=default
474
474
475 $ hg log -vC -r4
475 $ hg log -vC -r4
476 changeset: 4:7e4639b4691b
476 changeset: 4:7e4639b4691b
477 tag: tip
477 tag: tip
478 user: test
478 user: test
479 date: Thu Jan 01 00:00:05 1970 +0000
479 date: Thu Jan 01 00:00:05 1970 +0000
480 files: dir/b e
480 files: dir/b e
481 copies: e (dir/b)
481 copies: e (dir/b)
482 description:
482 description:
483 e
483 e
484
484
485
485
486 $ hg log -vC -r4 --style=default
486 $ hg log -vC -r4 --style=default
487 changeset: 4:7e4639b4691b
487 changeset: 4:7e4639b4691b
488 tag: tip
488 tag: tip
489 user: test
489 user: test
490 date: Thu Jan 01 00:00:05 1970 +0000
490 date: Thu Jan 01 00:00:05 1970 +0000
491 files: dir/b e
491 files: dir/b e
492 copies: e (dir/b)
492 copies: e (dir/b)
493 description:
493 description:
494 e
494 e
495
495
496
496
497 $ hg log -vC -r4 -Tjson
497 $ hg log -vC -r4 -Tjson
498 [
498 [
499 {
499 {
500 "rev": 4,
500 "rev": 4,
501 "node": "7e4639b4691b9f84b81036a8d4fb218ce3c5e3a3",
501 "node": "7e4639b4691b9f84b81036a8d4fb218ce3c5e3a3",
502 "branch": "default",
502 "branch": "default",
503 "phase": "draft",
503 "phase": "draft",
504 "user": "test",
504 "user": "test",
505 "date": [5, 0],
505 "date": [5, 0],
506 "desc": "e",
506 "desc": "e",
507 "bookmarks": [],
507 "bookmarks": [],
508 "tags": ["tip"],
508 "tags": ["tip"],
509 "parents": ["2ca5ba7019804f1f597249caddf22a64d34df0ba"],
509 "parents": ["2ca5ba7019804f1f597249caddf22a64d34df0ba"],
510 "files": ["dir/b", "e"],
510 "files": ["dir/b", "e"],
511 "copies": {"e": "dir/b"}
511 "copies": {"e": "dir/b"}
512 }
512 }
513 ]
513 ]
514
514
515 log copies, non-linear manifest
515 log copies, non-linear manifest
516
516
517 $ hg up -C 3
517 $ hg up -C 3
518 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
518 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
519 $ hg mv dir/b e
519 $ hg mv dir/b e
520 $ echo foo > foo
520 $ echo foo > foo
521 $ hg ci -Ame2 -d '6 0'
521 $ hg ci -Ame2 -d '6 0'
522 adding foo
522 adding foo
523 created new head
523 created new head
524 $ hg log -v --template '{rev} {file_copies}\n' -r 5
524 $ hg log -v --template '{rev} {file_copies}\n' -r 5
525 5 e (dir/b)
525 5 e (dir/b)
526
526
527
527
528 log copies, execute bit set
528 log copies, execute bit set
529
529
530 #if execbit
530 #if execbit
531 $ chmod +x e
531 $ chmod +x e
532 $ hg ci -me3 -d '7 0'
532 $ hg ci -me3 -d '7 0'
533 $ hg log -v --template '{rev} {file_copies}\n' -r 6
533 $ hg log -v --template '{rev} {file_copies}\n' -r 6
534 6
534 6
535 #endif
535 #endif
536
536
537
537
538 log -p d
538 log -p d
539
539
540 $ hg log -pv d
540 $ hg log -pv d
541 changeset: 3:2ca5ba701980
541 changeset: 3:2ca5ba701980
542 user: test
542 user: test
543 date: Thu Jan 01 00:00:04 1970 +0000
543 date: Thu Jan 01 00:00:04 1970 +0000
544 files: a b d g
544 files: a b d g
545 description:
545 description:
546 d
546 d
547
547
548
548
549 diff -r f8954cd4dc1f -r 2ca5ba701980 d
549 diff -r f8954cd4dc1f -r 2ca5ba701980 d
550 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
550 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
551 +++ b/d Thu Jan 01 00:00:04 1970 +0000
551 +++ b/d Thu Jan 01 00:00:04 1970 +0000
552 @@ -0,0 +1,1 @@
552 @@ -0,0 +1,1 @@
553 +a
553 +a
554
554
555
555
556
556
557 log --removed file
557 log --removed file
558
558
559 $ hg log --removed -v a
559 $ hg log --removed -v a
560 changeset: 3:2ca5ba701980
560 changeset: 3:2ca5ba701980
561 user: test
561 user: test
562 date: Thu Jan 01 00:00:04 1970 +0000
562 date: Thu Jan 01 00:00:04 1970 +0000
563 files: a b d g
563 files: a b d g
564 description:
564 description:
565 d
565 d
566
566
567
567
568 changeset: 0:9161b9aeaf16
568 changeset: 0:9161b9aeaf16
569 user: test
569 user: test
570 date: Thu Jan 01 00:00:01 1970 +0000
570 date: Thu Jan 01 00:00:01 1970 +0000
571 files: a f
571 files: a f
572 description:
572 description:
573 a
573 a
574
574
575
575
576
576
577 log --removed revrange file
577 log --removed revrange file
578
578
579 $ hg log --removed -v -r0:2 a
579 $ hg log --removed -v -r0:2 a
580 changeset: 0:9161b9aeaf16
580 changeset: 0:9161b9aeaf16
581 user: test
581 user: test
582 date: Thu Jan 01 00:00:01 1970 +0000
582 date: Thu Jan 01 00:00:01 1970 +0000
583 files: a f
583 files: a f
584 description:
584 description:
585 a
585 a
586
586
587
587
588 $ cd ..
588 $ cd ..
589
589
590 log --follow tests
590 log --follow tests
591
591
592 $ hg init follow
592 $ hg init follow
593 $ cd follow
593 $ cd follow
594
594
595 $ echo base > base
595 $ echo base > base
596 $ hg ci -Ambase -d '1 0'
596 $ hg ci -Ambase -d '1 0'
597 adding base
597 adding base
598
598
599 $ echo r1 >> base
599 $ echo r1 >> base
600 $ hg ci -Amr1 -d '1 0'
600 $ hg ci -Amr1 -d '1 0'
601 $ echo r2 >> base
601 $ echo r2 >> base
602 $ hg ci -Amr2 -d '1 0'
602 $ hg ci -Amr2 -d '1 0'
603
603
604 $ hg up -C 1
604 $ hg up -C 1
605 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
605 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
606 $ echo b1 > b1
606 $ echo b1 > b1
607 $ hg ci -Amb1 -d '1 0'
607 $ hg ci -Amb1 -d '1 0'
608 adding b1
608 adding b1
609 created new head
609 created new head
610
610
611
611
612 log -f
612 log -f
613
613
614 $ hg log -f
614 $ hg log -f
615 changeset: 3:e62f78d544b4
615 changeset: 3:e62f78d544b4
616 tag: tip
616 tag: tip
617 parent: 1:3d5bf5654eda
617 parent: 1:3d5bf5654eda
618 user: test
618 user: test
619 date: Thu Jan 01 00:00:01 1970 +0000
619 date: Thu Jan 01 00:00:01 1970 +0000
620 summary: b1
620 summary: b1
621
621
622 changeset: 1:3d5bf5654eda
622 changeset: 1:3d5bf5654eda
623 user: test
623 user: test
624 date: Thu Jan 01 00:00:01 1970 +0000
624 date: Thu Jan 01 00:00:01 1970 +0000
625 summary: r1
625 summary: r1
626
626
627 changeset: 0:67e992f2c4f3
627 changeset: 0:67e992f2c4f3
628 user: test
628 user: test
629 date: Thu Jan 01 00:00:01 1970 +0000
629 date: Thu Jan 01 00:00:01 1970 +0000
630 summary: base
630 summary: base
631
631
632
632
633
633
634 log -f -r 1:tip
634 log -f -r 1:tip
635
635
636 $ hg up -C 0
636 $ hg up -C 0
637 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
637 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
638 $ echo b2 > b2
638 $ echo b2 > b2
639 $ hg ci -Amb2 -d '1 0'
639 $ hg ci -Amb2 -d '1 0'
640 adding b2
640 adding b2
641 created new head
641 created new head
642 $ hg log -f -r 1:tip
642 $ hg log -f -r 1:tip
643 changeset: 1:3d5bf5654eda
643 changeset: 1:3d5bf5654eda
644 user: test
644 user: test
645 date: Thu Jan 01 00:00:01 1970 +0000
645 date: Thu Jan 01 00:00:01 1970 +0000
646 summary: r1
646 summary: r1
647
647
648 changeset: 2:60c670bf5b30
648 changeset: 2:60c670bf5b30
649 user: test
649 user: test
650 date: Thu Jan 01 00:00:01 1970 +0000
650 date: Thu Jan 01 00:00:01 1970 +0000
651 summary: r2
651 summary: r2
652
652
653 changeset: 3:e62f78d544b4
653 changeset: 3:e62f78d544b4
654 parent: 1:3d5bf5654eda
654 parent: 1:3d5bf5654eda
655 user: test
655 user: test
656 date: Thu Jan 01 00:00:01 1970 +0000
656 date: Thu Jan 01 00:00:01 1970 +0000
657 summary: b1
657 summary: b1
658
658
659
659
660
660
661 log -f -r null
661 log -f -r null
662
662
663 $ hg log -f -r null
663 $ hg log -f -r null
664 changeset: -1:000000000000
664 changeset: -1:000000000000
665 user:
665 user:
666 date: Thu Jan 01 00:00:00 1970 +0000
666 date: Thu Jan 01 00:00:00 1970 +0000
667
667
668 $ hg log -f -r null -G
668 $ hg log -f -r null -G
669 o changeset: -1:000000000000
669 o changeset: -1:000000000000
670 user:
670 user:
671 date: Thu Jan 01 00:00:00 1970 +0000
671 date: Thu Jan 01 00:00:00 1970 +0000
672
672
673
673
674
674
675 log -f with null parent
676
677 $ hg up -C null
678 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
679 $ hg log -f
680
681
675 log -r . with two parents
682 log -r . with two parents
676
683
677 $ hg up -C 3
684 $ hg up -C 3
678 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
685 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
679 $ hg merge tip
686 $ hg merge tip
680 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
687 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
681 (branch merge, don't forget to commit)
688 (branch merge, don't forget to commit)
682 $ hg log -r .
689 $ hg log -r .
683 changeset: 3:e62f78d544b4
690 changeset: 3:e62f78d544b4
684 parent: 1:3d5bf5654eda
691 parent: 1:3d5bf5654eda
685 user: test
692 user: test
686 date: Thu Jan 01 00:00:01 1970 +0000
693 date: Thu Jan 01 00:00:01 1970 +0000
687 summary: b1
694 summary: b1
688
695
689
696
690
697
691 log -r . with one parent
698 log -r . with one parent
692
699
693 $ hg ci -mm12 -d '1 0'
700 $ hg ci -mm12 -d '1 0'
694 $ hg log -r .
701 $ hg log -r .
695 changeset: 5:302e9dd6890d
702 changeset: 5:302e9dd6890d
696 tag: tip
703 tag: tip
697 parent: 3:e62f78d544b4
704 parent: 3:e62f78d544b4
698 parent: 4:ddb82e70d1a1
705 parent: 4:ddb82e70d1a1
699 user: test
706 user: test
700 date: Thu Jan 01 00:00:01 1970 +0000
707 date: Thu Jan 01 00:00:01 1970 +0000
701 summary: m12
708 summary: m12
702
709
703
710
704 $ echo postm >> b1
711 $ echo postm >> b1
705 $ hg ci -Amb1.1 -d'1 0'
712 $ hg ci -Amb1.1 -d'1 0'
706
713
707
714
708 log --follow-first
715 log --follow-first
709
716
710 $ hg log --follow-first
717 $ hg log --follow-first
711 changeset: 6:2404bbcab562
718 changeset: 6:2404bbcab562
712 tag: tip
719 tag: tip
713 user: test
720 user: test
714 date: Thu Jan 01 00:00:01 1970 +0000
721 date: Thu Jan 01 00:00:01 1970 +0000
715 summary: b1.1
722 summary: b1.1
716
723
717 changeset: 5:302e9dd6890d
724 changeset: 5:302e9dd6890d
718 parent: 3:e62f78d544b4
725 parent: 3:e62f78d544b4
719 parent: 4:ddb82e70d1a1
726 parent: 4:ddb82e70d1a1
720 user: test
727 user: test
721 date: Thu Jan 01 00:00:01 1970 +0000
728 date: Thu Jan 01 00:00:01 1970 +0000
722 summary: m12
729 summary: m12
723
730
724 changeset: 3:e62f78d544b4
731 changeset: 3:e62f78d544b4
725 parent: 1:3d5bf5654eda
732 parent: 1:3d5bf5654eda
726 user: test
733 user: test
727 date: Thu Jan 01 00:00:01 1970 +0000
734 date: Thu Jan 01 00:00:01 1970 +0000
728 summary: b1
735 summary: b1
729
736
730 changeset: 1:3d5bf5654eda
737 changeset: 1:3d5bf5654eda
731 user: test
738 user: test
732 date: Thu Jan 01 00:00:01 1970 +0000
739 date: Thu Jan 01 00:00:01 1970 +0000
733 summary: r1
740 summary: r1
734
741
735 changeset: 0:67e992f2c4f3
742 changeset: 0:67e992f2c4f3
736 user: test
743 user: test
737 date: Thu Jan 01 00:00:01 1970 +0000
744 date: Thu Jan 01 00:00:01 1970 +0000
738 summary: base
745 summary: base
739
746
740
747
741
748
742 log -P 2
749 log -P 2
743
750
744 $ hg log -P 2
751 $ hg log -P 2
745 changeset: 6:2404bbcab562
752 changeset: 6:2404bbcab562
746 tag: tip
753 tag: tip
747 user: test
754 user: test
748 date: Thu Jan 01 00:00:01 1970 +0000
755 date: Thu Jan 01 00:00:01 1970 +0000
749 summary: b1.1
756 summary: b1.1
750
757
751 changeset: 5:302e9dd6890d
758 changeset: 5:302e9dd6890d
752 parent: 3:e62f78d544b4
759 parent: 3:e62f78d544b4
753 parent: 4:ddb82e70d1a1
760 parent: 4:ddb82e70d1a1
754 user: test
761 user: test
755 date: Thu Jan 01 00:00:01 1970 +0000
762 date: Thu Jan 01 00:00:01 1970 +0000
756 summary: m12
763 summary: m12
757
764
758 changeset: 4:ddb82e70d1a1
765 changeset: 4:ddb82e70d1a1
759 parent: 0:67e992f2c4f3
766 parent: 0:67e992f2c4f3
760 user: test
767 user: test
761 date: Thu Jan 01 00:00:01 1970 +0000
768 date: Thu Jan 01 00:00:01 1970 +0000
762 summary: b2
769 summary: b2
763
770
764 changeset: 3:e62f78d544b4
771 changeset: 3:e62f78d544b4
765 parent: 1:3d5bf5654eda
772 parent: 1:3d5bf5654eda
766 user: test
773 user: test
767 date: Thu Jan 01 00:00:01 1970 +0000
774 date: Thu Jan 01 00:00:01 1970 +0000
768 summary: b1
775 summary: b1
769
776
770
777
771
778
772 log -r tip -p --git
779 log -r tip -p --git
773
780
774 $ hg log -r tip -p --git
781 $ hg log -r tip -p --git
775 changeset: 6:2404bbcab562
782 changeset: 6:2404bbcab562
776 tag: tip
783 tag: tip
777 user: test
784 user: test
778 date: Thu Jan 01 00:00:01 1970 +0000
785 date: Thu Jan 01 00:00:01 1970 +0000
779 summary: b1.1
786 summary: b1.1
780
787
781 diff --git a/b1 b/b1
788 diff --git a/b1 b/b1
782 --- a/b1
789 --- a/b1
783 +++ b/b1
790 +++ b/b1
784 @@ -1,1 +1,2 @@
791 @@ -1,1 +1,2 @@
785 b1
792 b1
786 +postm
793 +postm
787
794
788
795
789
796
790 log -r ""
797 log -r ""
791
798
792 $ hg log -r ''
799 $ hg log -r ''
793 hg: parse error: empty query
800 hg: parse error: empty query
794 [255]
801 [255]
795
802
796 log -r <some unknown node id>
803 log -r <some unknown node id>
797
804
798 $ hg log -r 1000000000000000000000000000000000000000
805 $ hg log -r 1000000000000000000000000000000000000000
799 abort: unknown revision '1000000000000000000000000000000000000000'!
806 abort: unknown revision '1000000000000000000000000000000000000000'!
800 [255]
807 [255]
801
808
802 log -k r1
809 log -k r1
803
810
804 $ hg log -k r1
811 $ hg log -k r1
805 changeset: 1:3d5bf5654eda
812 changeset: 1:3d5bf5654eda
806 user: test
813 user: test
807 date: Thu Jan 01 00:00:01 1970 +0000
814 date: Thu Jan 01 00:00:01 1970 +0000
808 summary: r1
815 summary: r1
809
816
810 log -p -l2 --color=always
817 log -p -l2 --color=always
811
818
812 $ hg --config extensions.color= --config color.mode=ansi \
819 $ hg --config extensions.color= --config color.mode=ansi \
813 > log -p -l2 --color=always
820 > log -p -l2 --color=always
814 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
821 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
815 tag: tip
822 tag: tip
816 user: test
823 user: test
817 date: Thu Jan 01 00:00:01 1970 +0000
824 date: Thu Jan 01 00:00:01 1970 +0000
818 summary: b1.1
825 summary: b1.1
819
826
820 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
827 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
821 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
828 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
822 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
829 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
823 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
830 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
824 b1
831 b1
825 \x1b[0;32m+postm\x1b[0m (esc)
832 \x1b[0;32m+postm\x1b[0m (esc)
826
833
827 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
834 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
828 parent: 3:e62f78d544b4
835 parent: 3:e62f78d544b4
829 parent: 4:ddb82e70d1a1
836 parent: 4:ddb82e70d1a1
830 user: test
837 user: test
831 date: Thu Jan 01 00:00:01 1970 +0000
838 date: Thu Jan 01 00:00:01 1970 +0000
832 summary: m12
839 summary: m12
833
840
834 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
841 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
835 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
842 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
836 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
843 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
837 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
844 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
838 \x1b[0;32m+b2\x1b[0m (esc)
845 \x1b[0;32m+b2\x1b[0m (esc)
839
846
840
847
841
848
842 log -r tip --stat
849 log -r tip --stat
843
850
844 $ hg log -r tip --stat
851 $ hg log -r tip --stat
845 changeset: 6:2404bbcab562
852 changeset: 6:2404bbcab562
846 tag: tip
853 tag: tip
847 user: test
854 user: test
848 date: Thu Jan 01 00:00:01 1970 +0000
855 date: Thu Jan 01 00:00:01 1970 +0000
849 summary: b1.1
856 summary: b1.1
850
857
851 b1 | 1 +
858 b1 | 1 +
852 1 files changed, 1 insertions(+), 0 deletions(-)
859 1 files changed, 1 insertions(+), 0 deletions(-)
853
860
854
861
855 $ cd ..
862 $ cd ..
856
863
857
864
858 User
865 User
859
866
860 $ hg init usertest
867 $ hg init usertest
861 $ cd usertest
868 $ cd usertest
862
869
863 $ echo a > a
870 $ echo a > a
864 $ hg ci -A -m "a" -u "User One <user1@example.org>"
871 $ hg ci -A -m "a" -u "User One <user1@example.org>"
865 adding a
872 adding a
866 $ echo b > b
873 $ echo b > b
867 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
874 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
868 adding b
875 adding b
869
876
870 $ hg log -u "User One <user1@example.org>"
877 $ hg log -u "User One <user1@example.org>"
871 changeset: 0:29a4c94f1924
878 changeset: 0:29a4c94f1924
872 user: User One <user1@example.org>
879 user: User One <user1@example.org>
873 date: Thu Jan 01 00:00:00 1970 +0000
880 date: Thu Jan 01 00:00:00 1970 +0000
874 summary: a
881 summary: a
875
882
876 $ hg log -u "user1" -u "user2"
883 $ hg log -u "user1" -u "user2"
877 changeset: 1:e834b5e69c0e
884 changeset: 1:e834b5e69c0e
878 tag: tip
885 tag: tip
879 user: User Two <user2@example.org>
886 user: User Two <user2@example.org>
880 date: Thu Jan 01 00:00:00 1970 +0000
887 date: Thu Jan 01 00:00:00 1970 +0000
881 summary: b
888 summary: b
882
889
883 changeset: 0:29a4c94f1924
890 changeset: 0:29a4c94f1924
884 user: User One <user1@example.org>
891 user: User One <user1@example.org>
885 date: Thu Jan 01 00:00:00 1970 +0000
892 date: Thu Jan 01 00:00:00 1970 +0000
886 summary: a
893 summary: a
887
894
888 $ hg log -u "user3"
895 $ hg log -u "user3"
889
896
890 $ cd ..
897 $ cd ..
891
898
892 $ hg init branches
899 $ hg init branches
893 $ cd branches
900 $ cd branches
894
901
895 $ echo a > a
902 $ echo a > a
896 $ hg ci -A -m "commit on default"
903 $ hg ci -A -m "commit on default"
897 adding a
904 adding a
898 $ hg branch test
905 $ hg branch test
899 marked working directory as branch test
906 marked working directory as branch test
900 (branches are permanent and global, did you want a bookmark?)
907 (branches are permanent and global, did you want a bookmark?)
901 $ echo b > b
908 $ echo b > b
902 $ hg ci -A -m "commit on test"
909 $ hg ci -A -m "commit on test"
903 adding b
910 adding b
904
911
905 $ hg up default
912 $ hg up default
906 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
913 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
907 $ echo c > c
914 $ echo c > c
908 $ hg ci -A -m "commit on default"
915 $ hg ci -A -m "commit on default"
909 adding c
916 adding c
910 $ hg up test
917 $ hg up test
911 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
918 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
912 $ echo c > c
919 $ echo c > c
913 $ hg ci -A -m "commit on test"
920 $ hg ci -A -m "commit on test"
914 adding c
921 adding c
915
922
916
923
917 log -b default
924 log -b default
918
925
919 $ hg log -b default
926 $ hg log -b default
920 changeset: 2:c3a4f03cc9a7
927 changeset: 2:c3a4f03cc9a7
921 parent: 0:24427303d56f
928 parent: 0:24427303d56f
922 user: test
929 user: test
923 date: Thu Jan 01 00:00:00 1970 +0000
930 date: Thu Jan 01 00:00:00 1970 +0000
924 summary: commit on default
931 summary: commit on default
925
932
926 changeset: 0:24427303d56f
933 changeset: 0:24427303d56f
927 user: test
934 user: test
928 date: Thu Jan 01 00:00:00 1970 +0000
935 date: Thu Jan 01 00:00:00 1970 +0000
929 summary: commit on default
936 summary: commit on default
930
937
931
938
932
939
933 log -b test
940 log -b test
934
941
935 $ hg log -b test
942 $ hg log -b test
936 changeset: 3:f5d8de11c2e2
943 changeset: 3:f5d8de11c2e2
937 branch: test
944 branch: test
938 tag: tip
945 tag: tip
939 parent: 1:d32277701ccb
946 parent: 1:d32277701ccb
940 user: test
947 user: test
941 date: Thu Jan 01 00:00:00 1970 +0000
948 date: Thu Jan 01 00:00:00 1970 +0000
942 summary: commit on test
949 summary: commit on test
943
950
944 changeset: 1:d32277701ccb
951 changeset: 1:d32277701ccb
945 branch: test
952 branch: test
946 user: test
953 user: test
947 date: Thu Jan 01 00:00:00 1970 +0000
954 date: Thu Jan 01 00:00:00 1970 +0000
948 summary: commit on test
955 summary: commit on test
949
956
950
957
951
958
952 log -b dummy
959 log -b dummy
953
960
954 $ hg log -b dummy
961 $ hg log -b dummy
955 abort: unknown revision 'dummy'!
962 abort: unknown revision 'dummy'!
956 [255]
963 [255]
957
964
958
965
959 log -b .
966 log -b .
960
967
961 $ hg log -b .
968 $ hg log -b .
962 changeset: 3:f5d8de11c2e2
969 changeset: 3:f5d8de11c2e2
963 branch: test
970 branch: test
964 tag: tip
971 tag: tip
965 parent: 1:d32277701ccb
972 parent: 1:d32277701ccb
966 user: test
973 user: test
967 date: Thu Jan 01 00:00:00 1970 +0000
974 date: Thu Jan 01 00:00:00 1970 +0000
968 summary: commit on test
975 summary: commit on test
969
976
970 changeset: 1:d32277701ccb
977 changeset: 1:d32277701ccb
971 branch: test
978 branch: test
972 user: test
979 user: test
973 date: Thu Jan 01 00:00:00 1970 +0000
980 date: Thu Jan 01 00:00:00 1970 +0000
974 summary: commit on test
981 summary: commit on test
975
982
976
983
977
984
978 log -b default -b test
985 log -b default -b test
979
986
980 $ hg log -b default -b test
987 $ hg log -b default -b test
981 changeset: 3:f5d8de11c2e2
988 changeset: 3:f5d8de11c2e2
982 branch: test
989 branch: test
983 tag: tip
990 tag: tip
984 parent: 1:d32277701ccb
991 parent: 1:d32277701ccb
985 user: test
992 user: test
986 date: Thu Jan 01 00:00:00 1970 +0000
993 date: Thu Jan 01 00:00:00 1970 +0000
987 summary: commit on test
994 summary: commit on test
988
995
989 changeset: 2:c3a4f03cc9a7
996 changeset: 2:c3a4f03cc9a7
990 parent: 0:24427303d56f
997 parent: 0:24427303d56f
991 user: test
998 user: test
992 date: Thu Jan 01 00:00:00 1970 +0000
999 date: Thu Jan 01 00:00:00 1970 +0000
993 summary: commit on default
1000 summary: commit on default
994
1001
995 changeset: 1:d32277701ccb
1002 changeset: 1:d32277701ccb
996 branch: test
1003 branch: test
997 user: test
1004 user: test
998 date: Thu Jan 01 00:00:00 1970 +0000
1005 date: Thu Jan 01 00:00:00 1970 +0000
999 summary: commit on test
1006 summary: commit on test
1000
1007
1001 changeset: 0:24427303d56f
1008 changeset: 0:24427303d56f
1002 user: test
1009 user: test
1003 date: Thu Jan 01 00:00:00 1970 +0000
1010 date: Thu Jan 01 00:00:00 1970 +0000
1004 summary: commit on default
1011 summary: commit on default
1005
1012
1006
1013
1007
1014
1008 log -b default -b .
1015 log -b default -b .
1009
1016
1010 $ hg log -b default -b .
1017 $ hg log -b default -b .
1011 changeset: 3:f5d8de11c2e2
1018 changeset: 3:f5d8de11c2e2
1012 branch: test
1019 branch: test
1013 tag: tip
1020 tag: tip
1014 parent: 1:d32277701ccb
1021 parent: 1:d32277701ccb
1015 user: test
1022 user: test
1016 date: Thu Jan 01 00:00:00 1970 +0000
1023 date: Thu Jan 01 00:00:00 1970 +0000
1017 summary: commit on test
1024 summary: commit on test
1018
1025
1019 changeset: 2:c3a4f03cc9a7
1026 changeset: 2:c3a4f03cc9a7
1020 parent: 0:24427303d56f
1027 parent: 0:24427303d56f
1021 user: test
1028 user: test
1022 date: Thu Jan 01 00:00:00 1970 +0000
1029 date: Thu Jan 01 00:00:00 1970 +0000
1023 summary: commit on default
1030 summary: commit on default
1024
1031
1025 changeset: 1:d32277701ccb
1032 changeset: 1:d32277701ccb
1026 branch: test
1033 branch: test
1027 user: test
1034 user: test
1028 date: Thu Jan 01 00:00:00 1970 +0000
1035 date: Thu Jan 01 00:00:00 1970 +0000
1029 summary: commit on test
1036 summary: commit on test
1030
1037
1031 changeset: 0:24427303d56f
1038 changeset: 0:24427303d56f
1032 user: test
1039 user: test
1033 date: Thu Jan 01 00:00:00 1970 +0000
1040 date: Thu Jan 01 00:00:00 1970 +0000
1034 summary: commit on default
1041 summary: commit on default
1035
1042
1036
1043
1037
1044
1038 log -b . -b test
1045 log -b . -b test
1039
1046
1040 $ hg log -b . -b test
1047 $ hg log -b . -b test
1041 changeset: 3:f5d8de11c2e2
1048 changeset: 3:f5d8de11c2e2
1042 branch: test
1049 branch: test
1043 tag: tip
1050 tag: tip
1044 parent: 1:d32277701ccb
1051 parent: 1:d32277701ccb
1045 user: test
1052 user: test
1046 date: Thu Jan 01 00:00:00 1970 +0000
1053 date: Thu Jan 01 00:00:00 1970 +0000
1047 summary: commit on test
1054 summary: commit on test
1048
1055
1049 changeset: 1:d32277701ccb
1056 changeset: 1:d32277701ccb
1050 branch: test
1057 branch: test
1051 user: test
1058 user: test
1052 date: Thu Jan 01 00:00:00 1970 +0000
1059 date: Thu Jan 01 00:00:00 1970 +0000
1053 summary: commit on test
1060 summary: commit on test
1054
1061
1055
1062
1056
1063
1057 log -b 2
1064 log -b 2
1058
1065
1059 $ hg log -b 2
1066 $ hg log -b 2
1060 changeset: 2:c3a4f03cc9a7
1067 changeset: 2:c3a4f03cc9a7
1061 parent: 0:24427303d56f
1068 parent: 0:24427303d56f
1062 user: test
1069 user: test
1063 date: Thu Jan 01 00:00:00 1970 +0000
1070 date: Thu Jan 01 00:00:00 1970 +0000
1064 summary: commit on default
1071 summary: commit on default
1065
1072
1066 changeset: 0:24427303d56f
1073 changeset: 0:24427303d56f
1067 user: test
1074 user: test
1068 date: Thu Jan 01 00:00:00 1970 +0000
1075 date: Thu Jan 01 00:00:00 1970 +0000
1069 summary: commit on default
1076 summary: commit on default
1070
1077
1071 #if gettext
1078 #if gettext
1072
1079
1073 Test that all log names are translated (e.g. branches, bookmarks, tags):
1080 Test that all log names are translated (e.g. branches, bookmarks, tags):
1074
1081
1075 $ hg bookmark babar -r tip
1082 $ hg bookmark babar -r tip
1076
1083
1077 $ HGENCODING=UTF-8 LANGUAGE=de hg log -r tip
1084 $ HGENCODING=UTF-8 LANGUAGE=de hg log -r tip
1078 \xc3\x84nderung: 3:f5d8de11c2e2 (esc)
1085 \xc3\x84nderung: 3:f5d8de11c2e2 (esc)
1079 Zweig: test
1086 Zweig: test
1080 Lesezeichen: babar
1087 Lesezeichen: babar
1081 Marke: tip
1088 Marke: tip
1082 Vorg\xc3\xa4nger: 1:d32277701ccb (esc)
1089 Vorg\xc3\xa4nger: 1:d32277701ccb (esc)
1083 Nutzer: test
1090 Nutzer: test
1084 Datum: Thu Jan 01 00:00:00 1970 +0000
1091 Datum: Thu Jan 01 00:00:00 1970 +0000
1085 Zusammenfassung: commit on test
1092 Zusammenfassung: commit on test
1086
1093
1087 $ hg bookmark -d babar
1094 $ hg bookmark -d babar
1088
1095
1089 #endif
1096 #endif
1090
1097
1091 log -p --cwd dir (in subdir)
1098 log -p --cwd dir (in subdir)
1092
1099
1093 $ mkdir dir
1100 $ mkdir dir
1094 $ hg log -p --cwd dir
1101 $ hg log -p --cwd dir
1095 changeset: 3:f5d8de11c2e2
1102 changeset: 3:f5d8de11c2e2
1096 branch: test
1103 branch: test
1097 tag: tip
1104 tag: tip
1098 parent: 1:d32277701ccb
1105 parent: 1:d32277701ccb
1099 user: test
1106 user: test
1100 date: Thu Jan 01 00:00:00 1970 +0000
1107 date: Thu Jan 01 00:00:00 1970 +0000
1101 summary: commit on test
1108 summary: commit on test
1102
1109
1103 diff -r d32277701ccb -r f5d8de11c2e2 c
1110 diff -r d32277701ccb -r f5d8de11c2e2 c
1104 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1111 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1105 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1112 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1106 @@ -0,0 +1,1 @@
1113 @@ -0,0 +1,1 @@
1107 +c
1114 +c
1108
1115
1109 changeset: 2:c3a4f03cc9a7
1116 changeset: 2:c3a4f03cc9a7
1110 parent: 0:24427303d56f
1117 parent: 0:24427303d56f
1111 user: test
1118 user: test
1112 date: Thu Jan 01 00:00:00 1970 +0000
1119 date: Thu Jan 01 00:00:00 1970 +0000
1113 summary: commit on default
1120 summary: commit on default
1114
1121
1115 diff -r 24427303d56f -r c3a4f03cc9a7 c
1122 diff -r 24427303d56f -r c3a4f03cc9a7 c
1116 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1123 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1117 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1124 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1118 @@ -0,0 +1,1 @@
1125 @@ -0,0 +1,1 @@
1119 +c
1126 +c
1120
1127
1121 changeset: 1:d32277701ccb
1128 changeset: 1:d32277701ccb
1122 branch: test
1129 branch: test
1123 user: test
1130 user: test
1124 date: Thu Jan 01 00:00:00 1970 +0000
1131 date: Thu Jan 01 00:00:00 1970 +0000
1125 summary: commit on test
1132 summary: commit on test
1126
1133
1127 diff -r 24427303d56f -r d32277701ccb b
1134 diff -r 24427303d56f -r d32277701ccb b
1128 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1135 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1129 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1136 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1130 @@ -0,0 +1,1 @@
1137 @@ -0,0 +1,1 @@
1131 +b
1138 +b
1132
1139
1133 changeset: 0:24427303d56f
1140 changeset: 0:24427303d56f
1134 user: test
1141 user: test
1135 date: Thu Jan 01 00:00:00 1970 +0000
1142 date: Thu Jan 01 00:00:00 1970 +0000
1136 summary: commit on default
1143 summary: commit on default
1137
1144
1138 diff -r 000000000000 -r 24427303d56f a
1145 diff -r 000000000000 -r 24427303d56f a
1139 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1146 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1140 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1147 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1141 @@ -0,0 +1,1 @@
1148 @@ -0,0 +1,1 @@
1142 +a
1149 +a
1143
1150
1144
1151
1145
1152
1146 log -p -R repo
1153 log -p -R repo
1147
1154
1148 $ cd dir
1155 $ cd dir
1149 $ hg log -p -R .. ../a
1156 $ hg log -p -R .. ../a
1150 changeset: 0:24427303d56f
1157 changeset: 0:24427303d56f
1151 user: test
1158 user: test
1152 date: Thu Jan 01 00:00:00 1970 +0000
1159 date: Thu Jan 01 00:00:00 1970 +0000
1153 summary: commit on default
1160 summary: commit on default
1154
1161
1155 diff -r 000000000000 -r 24427303d56f a
1162 diff -r 000000000000 -r 24427303d56f a
1156 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1163 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1157 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1164 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1158 @@ -0,0 +1,1 @@
1165 @@ -0,0 +1,1 @@
1159 +a
1166 +a
1160
1167
1161
1168
1162 $ cd ../..
1169 $ cd ../..
1163
1170
1164 $ hg init follow2
1171 $ hg init follow2
1165 $ cd follow2
1172 $ cd follow2
1166
1173
1167 # Build the following history:
1174 # Build the following history:
1168 # tip - o - x - o - x - x
1175 # tip - o - x - o - x - x
1169 # \ /
1176 # \ /
1170 # o - o - o - x
1177 # o - o - o - x
1171 # \ /
1178 # \ /
1172 # o
1179 # o
1173 #
1180 #
1174 # Where "o" is a revision containing "foo" and
1181 # Where "o" is a revision containing "foo" and
1175 # "x" is a revision without "foo"
1182 # "x" is a revision without "foo"
1176
1183
1177 $ touch init
1184 $ touch init
1178 $ hg ci -A -m "init, unrelated"
1185 $ hg ci -A -m "init, unrelated"
1179 adding init
1186 adding init
1180 $ echo 'foo' > init
1187 $ echo 'foo' > init
1181 $ hg ci -m "change, unrelated"
1188 $ hg ci -m "change, unrelated"
1182 $ echo 'foo' > foo
1189 $ echo 'foo' > foo
1183 $ hg ci -A -m "add unrelated old foo"
1190 $ hg ci -A -m "add unrelated old foo"
1184 adding foo
1191 adding foo
1185 $ hg rm foo
1192 $ hg rm foo
1186 $ hg ci -m "delete foo, unrelated"
1193 $ hg ci -m "delete foo, unrelated"
1187 $ echo 'related' > foo
1194 $ echo 'related' > foo
1188 $ hg ci -A -m "add foo, related"
1195 $ hg ci -A -m "add foo, related"
1189 adding foo
1196 adding foo
1190
1197
1191 $ hg up 0
1198 $ hg up 0
1192 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1199 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1193 $ touch branch
1200 $ touch branch
1194 $ hg ci -A -m "first branch, unrelated"
1201 $ hg ci -A -m "first branch, unrelated"
1195 adding branch
1202 adding branch
1196 created new head
1203 created new head
1197 $ touch foo
1204 $ touch foo
1198 $ hg ci -A -m "create foo, related"
1205 $ hg ci -A -m "create foo, related"
1199 adding foo
1206 adding foo
1200 $ echo 'change' > foo
1207 $ echo 'change' > foo
1201 $ hg ci -m "change foo, related"
1208 $ hg ci -m "change foo, related"
1202
1209
1203 $ hg up 6
1210 $ hg up 6
1204 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1211 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1205 $ echo 'change foo in branch' > foo
1212 $ echo 'change foo in branch' > foo
1206 $ hg ci -m "change foo in branch, related"
1213 $ hg ci -m "change foo in branch, related"
1207 created new head
1214 created new head
1208 $ hg merge 7
1215 $ hg merge 7
1209 merging foo
1216 merging foo
1210 warning: conflicts during merge.
1217 warning: conflicts during merge.
1211 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1218 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1212 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1219 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1213 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1220 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1214 [1]
1221 [1]
1215 $ echo 'merge 1' > foo
1222 $ echo 'merge 1' > foo
1216 $ hg resolve -m foo
1223 $ hg resolve -m foo
1217 (no more unresolved files)
1224 (no more unresolved files)
1218 $ hg ci -m "First merge, related"
1225 $ hg ci -m "First merge, related"
1219
1226
1220 $ hg merge 4
1227 $ hg merge 4
1221 merging foo
1228 merging foo
1222 warning: conflicts during merge.
1229 warning: conflicts during merge.
1223 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1230 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1224 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1231 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1225 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1232 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1226 [1]
1233 [1]
1227 $ echo 'merge 2' > foo
1234 $ echo 'merge 2' > foo
1228 $ hg resolve -m foo
1235 $ hg resolve -m foo
1229 (no more unresolved files)
1236 (no more unresolved files)
1230 $ hg ci -m "Last merge, related"
1237 $ hg ci -m "Last merge, related"
1231
1238
1232 $ hg log --graph
1239 $ hg log --graph
1233 @ changeset: 10:4dae8563d2c5
1240 @ changeset: 10:4dae8563d2c5
1234 |\ tag: tip
1241 |\ tag: tip
1235 | | parent: 9:7b35701b003e
1242 | | parent: 9:7b35701b003e
1236 | | parent: 4:88176d361b69
1243 | | parent: 4:88176d361b69
1237 | | user: test
1244 | | user: test
1238 | | date: Thu Jan 01 00:00:00 1970 +0000
1245 | | date: Thu Jan 01 00:00:00 1970 +0000
1239 | | summary: Last merge, related
1246 | | summary: Last merge, related
1240 | |
1247 | |
1241 | o changeset: 9:7b35701b003e
1248 | o changeset: 9:7b35701b003e
1242 | |\ parent: 8:e5416ad8a855
1249 | |\ parent: 8:e5416ad8a855
1243 | | | parent: 7:87fe3144dcfa
1250 | | | parent: 7:87fe3144dcfa
1244 | | | user: test
1251 | | | user: test
1245 | | | date: Thu Jan 01 00:00:00 1970 +0000
1252 | | | date: Thu Jan 01 00:00:00 1970 +0000
1246 | | | summary: First merge, related
1253 | | | summary: First merge, related
1247 | | |
1254 | | |
1248 | | o changeset: 8:e5416ad8a855
1255 | | o changeset: 8:e5416ad8a855
1249 | | | parent: 6:dc6c325fe5ee
1256 | | | parent: 6:dc6c325fe5ee
1250 | | | user: test
1257 | | | user: test
1251 | | | date: Thu Jan 01 00:00:00 1970 +0000
1258 | | | date: Thu Jan 01 00:00:00 1970 +0000
1252 | | | summary: change foo in branch, related
1259 | | | summary: change foo in branch, related
1253 | | |
1260 | | |
1254 | o | changeset: 7:87fe3144dcfa
1261 | o | changeset: 7:87fe3144dcfa
1255 | |/ user: test
1262 | |/ user: test
1256 | | date: Thu Jan 01 00:00:00 1970 +0000
1263 | | date: Thu Jan 01 00:00:00 1970 +0000
1257 | | summary: change foo, related
1264 | | summary: change foo, related
1258 | |
1265 | |
1259 | o changeset: 6:dc6c325fe5ee
1266 | o changeset: 6:dc6c325fe5ee
1260 | | user: test
1267 | | user: test
1261 | | date: Thu Jan 01 00:00:00 1970 +0000
1268 | | date: Thu Jan 01 00:00:00 1970 +0000
1262 | | summary: create foo, related
1269 | | summary: create foo, related
1263 | |
1270 | |
1264 | o changeset: 5:73db34516eb9
1271 | o changeset: 5:73db34516eb9
1265 | | parent: 0:e87515fd044a
1272 | | parent: 0:e87515fd044a
1266 | | user: test
1273 | | user: test
1267 | | date: Thu Jan 01 00:00:00 1970 +0000
1274 | | date: Thu Jan 01 00:00:00 1970 +0000
1268 | | summary: first branch, unrelated
1275 | | summary: first branch, unrelated
1269 | |
1276 | |
1270 o | changeset: 4:88176d361b69
1277 o | changeset: 4:88176d361b69
1271 | | user: test
1278 | | user: test
1272 | | date: Thu Jan 01 00:00:00 1970 +0000
1279 | | date: Thu Jan 01 00:00:00 1970 +0000
1273 | | summary: add foo, related
1280 | | summary: add foo, related
1274 | |
1281 | |
1275 o | changeset: 3:dd78ae4afb56
1282 o | changeset: 3:dd78ae4afb56
1276 | | user: test
1283 | | user: test
1277 | | date: Thu Jan 01 00:00:00 1970 +0000
1284 | | date: Thu Jan 01 00:00:00 1970 +0000
1278 | | summary: delete foo, unrelated
1285 | | summary: delete foo, unrelated
1279 | |
1286 | |
1280 o | changeset: 2:c4c64aedf0f7
1287 o | changeset: 2:c4c64aedf0f7
1281 | | user: test
1288 | | user: test
1282 | | date: Thu Jan 01 00:00:00 1970 +0000
1289 | | date: Thu Jan 01 00:00:00 1970 +0000
1283 | | summary: add unrelated old foo
1290 | | summary: add unrelated old foo
1284 | |
1291 | |
1285 o | changeset: 1:e5faa7440653
1292 o | changeset: 1:e5faa7440653
1286 |/ user: test
1293 |/ user: test
1287 | date: Thu Jan 01 00:00:00 1970 +0000
1294 | date: Thu Jan 01 00:00:00 1970 +0000
1288 | summary: change, unrelated
1295 | summary: change, unrelated
1289 |
1296 |
1290 o changeset: 0:e87515fd044a
1297 o changeset: 0:e87515fd044a
1291 user: test
1298 user: test
1292 date: Thu Jan 01 00:00:00 1970 +0000
1299 date: Thu Jan 01 00:00:00 1970 +0000
1293 summary: init, unrelated
1300 summary: init, unrelated
1294
1301
1295
1302
1296 $ hg --traceback log -f foo
1303 $ hg --traceback log -f foo
1297 changeset: 10:4dae8563d2c5
1304 changeset: 10:4dae8563d2c5
1298 tag: tip
1305 tag: tip
1299 parent: 9:7b35701b003e
1306 parent: 9:7b35701b003e
1300 parent: 4:88176d361b69
1307 parent: 4:88176d361b69
1301 user: test
1308 user: test
1302 date: Thu Jan 01 00:00:00 1970 +0000
1309 date: Thu Jan 01 00:00:00 1970 +0000
1303 summary: Last merge, related
1310 summary: Last merge, related
1304
1311
1305 changeset: 9:7b35701b003e
1312 changeset: 9:7b35701b003e
1306 parent: 8:e5416ad8a855
1313 parent: 8:e5416ad8a855
1307 parent: 7:87fe3144dcfa
1314 parent: 7:87fe3144dcfa
1308 user: test
1315 user: test
1309 date: Thu Jan 01 00:00:00 1970 +0000
1316 date: Thu Jan 01 00:00:00 1970 +0000
1310 summary: First merge, related
1317 summary: First merge, related
1311
1318
1312 changeset: 8:e5416ad8a855
1319 changeset: 8:e5416ad8a855
1313 parent: 6:dc6c325fe5ee
1320 parent: 6:dc6c325fe5ee
1314 user: test
1321 user: test
1315 date: Thu Jan 01 00:00:00 1970 +0000
1322 date: Thu Jan 01 00:00:00 1970 +0000
1316 summary: change foo in branch, related
1323 summary: change foo in branch, related
1317
1324
1318 changeset: 7:87fe3144dcfa
1325 changeset: 7:87fe3144dcfa
1319 user: test
1326 user: test
1320 date: Thu Jan 01 00:00:00 1970 +0000
1327 date: Thu Jan 01 00:00:00 1970 +0000
1321 summary: change foo, related
1328 summary: change foo, related
1322
1329
1323 changeset: 6:dc6c325fe5ee
1330 changeset: 6:dc6c325fe5ee
1324 user: test
1331 user: test
1325 date: Thu Jan 01 00:00:00 1970 +0000
1332 date: Thu Jan 01 00:00:00 1970 +0000
1326 summary: create foo, related
1333 summary: create foo, related
1327
1334
1328 changeset: 4:88176d361b69
1335 changeset: 4:88176d361b69
1329 user: test
1336 user: test
1330 date: Thu Jan 01 00:00:00 1970 +0000
1337 date: Thu Jan 01 00:00:00 1970 +0000
1331 summary: add foo, related
1338 summary: add foo, related
1332
1339
1333
1340
1334 Also check when maxrev < lastrevfilelog
1341 Also check when maxrev < lastrevfilelog
1335
1342
1336 $ hg --traceback log -f -r4 foo
1343 $ hg --traceback log -f -r4 foo
1337 changeset: 4:88176d361b69
1344 changeset: 4:88176d361b69
1338 user: test
1345 user: test
1339 date: Thu Jan 01 00:00:00 1970 +0000
1346 date: Thu Jan 01 00:00:00 1970 +0000
1340 summary: add foo, related
1347 summary: add foo, related
1341
1348
1342 $ cd ..
1349 $ cd ..
1343
1350
1344 Issue2383: hg log showing _less_ differences than hg diff
1351 Issue2383: hg log showing _less_ differences than hg diff
1345
1352
1346 $ hg init issue2383
1353 $ hg init issue2383
1347 $ cd issue2383
1354 $ cd issue2383
1348
1355
1349 Create a test repo:
1356 Create a test repo:
1350
1357
1351 $ echo a > a
1358 $ echo a > a
1352 $ hg ci -Am0
1359 $ hg ci -Am0
1353 adding a
1360 adding a
1354 $ echo b > b
1361 $ echo b > b
1355 $ hg ci -Am1
1362 $ hg ci -Am1
1356 adding b
1363 adding b
1357 $ hg co 0
1364 $ hg co 0
1358 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1365 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1359 $ echo b > a
1366 $ echo b > a
1360 $ hg ci -m2
1367 $ hg ci -m2
1361 created new head
1368 created new head
1362
1369
1363 Merge:
1370 Merge:
1364
1371
1365 $ hg merge
1372 $ hg merge
1366 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1373 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1367 (branch merge, don't forget to commit)
1374 (branch merge, don't forget to commit)
1368
1375
1369 Make sure there's a file listed in the merge to trigger the bug:
1376 Make sure there's a file listed in the merge to trigger the bug:
1370
1377
1371 $ echo c > a
1378 $ echo c > a
1372 $ hg ci -m3
1379 $ hg ci -m3
1373
1380
1374 Two files shown here in diff:
1381 Two files shown here in diff:
1375
1382
1376 $ hg diff --rev 2:3
1383 $ hg diff --rev 2:3
1377 diff -r b09be438c43a -r 8e07aafe1edc a
1384 diff -r b09be438c43a -r 8e07aafe1edc a
1378 --- a/a Thu Jan 01 00:00:00 1970 +0000
1385 --- a/a Thu Jan 01 00:00:00 1970 +0000
1379 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1386 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1380 @@ -1,1 +1,1 @@
1387 @@ -1,1 +1,1 @@
1381 -b
1388 -b
1382 +c
1389 +c
1383 diff -r b09be438c43a -r 8e07aafe1edc b
1390 diff -r b09be438c43a -r 8e07aafe1edc b
1384 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1391 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1385 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1392 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1386 @@ -0,0 +1,1 @@
1393 @@ -0,0 +1,1 @@
1387 +b
1394 +b
1388
1395
1389 Diff here should be the same:
1396 Diff here should be the same:
1390
1397
1391 $ hg log -vpr 3
1398 $ hg log -vpr 3
1392 changeset: 3:8e07aafe1edc
1399 changeset: 3:8e07aafe1edc
1393 tag: tip
1400 tag: tip
1394 parent: 2:b09be438c43a
1401 parent: 2:b09be438c43a
1395 parent: 1:925d80f479bb
1402 parent: 1:925d80f479bb
1396 user: test
1403 user: test
1397 date: Thu Jan 01 00:00:00 1970 +0000
1404 date: Thu Jan 01 00:00:00 1970 +0000
1398 files: a
1405 files: a
1399 description:
1406 description:
1400 3
1407 3
1401
1408
1402
1409
1403 diff -r b09be438c43a -r 8e07aafe1edc a
1410 diff -r b09be438c43a -r 8e07aafe1edc a
1404 --- a/a Thu Jan 01 00:00:00 1970 +0000
1411 --- a/a Thu Jan 01 00:00:00 1970 +0000
1405 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1412 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1406 @@ -1,1 +1,1 @@
1413 @@ -1,1 +1,1 @@
1407 -b
1414 -b
1408 +c
1415 +c
1409 diff -r b09be438c43a -r 8e07aafe1edc b
1416 diff -r b09be438c43a -r 8e07aafe1edc b
1410 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1417 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1411 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1418 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1412 @@ -0,0 +1,1 @@
1419 @@ -0,0 +1,1 @@
1413 +b
1420 +b
1414
1421
1415 $ cd ..
1422 $ cd ..
1416
1423
1417 'hg log -r rev fn' when last(filelog(fn)) != rev
1424 'hg log -r rev fn' when last(filelog(fn)) != rev
1418
1425
1419 $ hg init simplelog
1426 $ hg init simplelog
1420 $ cd simplelog
1427 $ cd simplelog
1421 $ echo f > a
1428 $ echo f > a
1422 $ hg ci -Am'a' -d '0 0'
1429 $ hg ci -Am'a' -d '0 0'
1423 adding a
1430 adding a
1424 $ echo f >> a
1431 $ echo f >> a
1425 $ hg ci -Am'a bis' -d '1 0'
1432 $ hg ci -Am'a bis' -d '1 0'
1426
1433
1427 $ hg log -r0 a
1434 $ hg log -r0 a
1428 changeset: 0:9f758d63dcde
1435 changeset: 0:9f758d63dcde
1429 user: test
1436 user: test
1430 date: Thu Jan 01 00:00:00 1970 +0000
1437 date: Thu Jan 01 00:00:00 1970 +0000
1431 summary: a
1438 summary: a
1432
1439
1433 enable obsolete to test hidden feature
1440 enable obsolete to test hidden feature
1434
1441
1435 $ cat >> $HGRCPATH << EOF
1442 $ cat >> $HGRCPATH << EOF
1436 > [experimental]
1443 > [experimental]
1437 > evolution=createmarkers
1444 > evolution=createmarkers
1438 > EOF
1445 > EOF
1439
1446
1440 $ hg log --template='{rev}:{node}\n'
1447 $ hg log --template='{rev}:{node}\n'
1441 1:a765632148dc55d38c35c4f247c618701886cb2f
1448 1:a765632148dc55d38c35c4f247c618701886cb2f
1442 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1449 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1443 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1450 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1444 $ hg up null -q
1451 $ hg up null -q
1445 $ hg log --template='{rev}:{node}\n'
1452 $ hg log --template='{rev}:{node}\n'
1446 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1453 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1447 $ hg log --template='{rev}:{node}\n' --hidden
1454 $ hg log --template='{rev}:{node}\n' --hidden
1448 1:a765632148dc55d38c35c4f247c618701886cb2f
1455 1:a765632148dc55d38c35c4f247c618701886cb2f
1449 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1456 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1450 $ hg log -r a
1457 $ hg log -r a
1451 abort: hidden revision 'a'!
1458 abort: hidden revision 'a'!
1452 (use --hidden to access hidden revisions)
1459 (use --hidden to access hidden revisions)
1453 [255]
1460 [255]
1454
1461
1455 test that parent prevent a changeset to be hidden
1462 test that parent prevent a changeset to be hidden
1456
1463
1457 $ hg up 1 -q --hidden
1464 $ hg up 1 -q --hidden
1458 $ hg log --template='{rev}:{node}\n'
1465 $ hg log --template='{rev}:{node}\n'
1459 1:a765632148dc55d38c35c4f247c618701886cb2f
1466 1:a765632148dc55d38c35c4f247c618701886cb2f
1460 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1467 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1461
1468
1462 test that second parent prevent a changeset to be hidden too
1469 test that second parent prevent a changeset to be hidden too
1463
1470
1464 $ hg debugsetparents 0 1 # nothing suitable to merge here
1471 $ hg debugsetparents 0 1 # nothing suitable to merge here
1465 $ hg log --template='{rev}:{node}\n'
1472 $ hg log --template='{rev}:{node}\n'
1466 1:a765632148dc55d38c35c4f247c618701886cb2f
1473 1:a765632148dc55d38c35c4f247c618701886cb2f
1467 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1474 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1468 $ hg debugsetparents 1
1475 $ hg debugsetparents 1
1469 $ hg up -q null
1476 $ hg up -q null
1470
1477
1471 bookmarks prevent a changeset being hidden
1478 bookmarks prevent a changeset being hidden
1472
1479
1473 $ hg bookmark --hidden -r 1 X
1480 $ hg bookmark --hidden -r 1 X
1474 $ hg log --template '{rev}:{node}\n'
1481 $ hg log --template '{rev}:{node}\n'
1475 1:a765632148dc55d38c35c4f247c618701886cb2f
1482 1:a765632148dc55d38c35c4f247c618701886cb2f
1476 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1483 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1477 $ hg bookmark -d X
1484 $ hg bookmark -d X
1478
1485
1479 divergent bookmarks are not hidden
1486 divergent bookmarks are not hidden
1480
1487
1481 $ hg bookmark --hidden -r 1 X@foo
1488 $ hg bookmark --hidden -r 1 X@foo
1482 $ hg log --template '{rev}:{node}\n'
1489 $ hg log --template '{rev}:{node}\n'
1483 1:a765632148dc55d38c35c4f247c618701886cb2f
1490 1:a765632148dc55d38c35c4f247c618701886cb2f
1484 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1491 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1485
1492
1486 clear extensions configuration
1493 clear extensions configuration
1487 $ echo '[extensions]' >> $HGRCPATH
1494 $ echo '[extensions]' >> $HGRCPATH
1488 $ echo "obs=!" >> $HGRCPATH
1495 $ echo "obs=!" >> $HGRCPATH
1489 $ cd ..
1496 $ cd ..
1490
1497
1491 test -u/-k for problematic encoding
1498 test -u/-k for problematic encoding
1492 # unicode: cp932:
1499 # unicode: cp932:
1493 # u30A2 0x83 0x41(= 'A')
1500 # u30A2 0x83 0x41(= 'A')
1494 # u30C2 0x83 0x61(= 'a')
1501 # u30C2 0x83 0x61(= 'a')
1495
1502
1496 $ hg init problematicencoding
1503 $ hg init problematicencoding
1497 $ cd problematicencoding
1504 $ cd problematicencoding
1498
1505
1499 $ python > setup.sh <<EOF
1506 $ python > setup.sh <<EOF
1500 > print u'''
1507 > print u'''
1501 > echo a > text
1508 > echo a > text
1502 > hg add text
1509 > hg add text
1503 > hg --encoding utf-8 commit -u '\u30A2' -m none
1510 > hg --encoding utf-8 commit -u '\u30A2' -m none
1504 > echo b > text
1511 > echo b > text
1505 > hg --encoding utf-8 commit -u '\u30C2' -m none
1512 > hg --encoding utf-8 commit -u '\u30C2' -m none
1506 > echo c > text
1513 > echo c > text
1507 > hg --encoding utf-8 commit -u none -m '\u30A2'
1514 > hg --encoding utf-8 commit -u none -m '\u30A2'
1508 > echo d > text
1515 > echo d > text
1509 > hg --encoding utf-8 commit -u none -m '\u30C2'
1516 > hg --encoding utf-8 commit -u none -m '\u30C2'
1510 > '''.encode('utf-8')
1517 > '''.encode('utf-8')
1511 > EOF
1518 > EOF
1512 $ sh < setup.sh
1519 $ sh < setup.sh
1513
1520
1514 test in problematic encoding
1521 test in problematic encoding
1515 $ python > test.sh <<EOF
1522 $ python > test.sh <<EOF
1516 > print u'''
1523 > print u'''
1517 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
1524 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
1518 > echo ====
1525 > echo ====
1519 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
1526 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
1520 > echo ====
1527 > echo ====
1521 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
1528 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
1522 > echo ====
1529 > echo ====
1523 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
1530 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
1524 > '''.encode('cp932')
1531 > '''.encode('cp932')
1525 > EOF
1532 > EOF
1526 $ sh < test.sh
1533 $ sh < test.sh
1527 0
1534 0
1528 ====
1535 ====
1529 1
1536 1
1530 ====
1537 ====
1531 2
1538 2
1532 0
1539 0
1533 ====
1540 ====
1534 3
1541 3
1535 1
1542 1
1536
1543
1537 $ cd ..
1544 $ cd ..
1538
1545
1539 test hg log on non-existent files and on directories
1546 test hg log on non-existent files and on directories
1540 $ hg init issue1340
1547 $ hg init issue1340
1541 $ cd issue1340
1548 $ cd issue1340
1542 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
1549 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
1543 $ echo 1 > d1/f1
1550 $ echo 1 > d1/f1
1544 $ echo 1 > D2/f1
1551 $ echo 1 > D2/f1
1545 $ echo 1 > D3.i/f1
1552 $ echo 1 > D3.i/f1
1546 $ echo 1 > d4.hg/f1
1553 $ echo 1 > d4.hg/f1
1547 $ echo 1 > d5.d/f1
1554 $ echo 1 > d5.d/f1
1548 $ echo 1 > .d6/f1
1555 $ echo 1 > .d6/f1
1549 $ hg -q add .
1556 $ hg -q add .
1550 $ hg commit -m "a bunch of weird directories"
1557 $ hg commit -m "a bunch of weird directories"
1551 $ hg log -l1 d1/f1 | grep changeset
1558 $ hg log -l1 d1/f1 | grep changeset
1552 changeset: 0:65624cd9070a
1559 changeset: 0:65624cd9070a
1553 $ hg log -l1 f1
1560 $ hg log -l1 f1
1554 $ hg log -l1 . | grep changeset
1561 $ hg log -l1 . | grep changeset
1555 changeset: 0:65624cd9070a
1562 changeset: 0:65624cd9070a
1556 $ hg log -l1 ./ | grep changeset
1563 $ hg log -l1 ./ | grep changeset
1557 changeset: 0:65624cd9070a
1564 changeset: 0:65624cd9070a
1558 $ hg log -l1 d1 | grep changeset
1565 $ hg log -l1 d1 | grep changeset
1559 changeset: 0:65624cd9070a
1566 changeset: 0:65624cd9070a
1560 $ hg log -l1 D2 | grep changeset
1567 $ hg log -l1 D2 | grep changeset
1561 changeset: 0:65624cd9070a
1568 changeset: 0:65624cd9070a
1562 $ hg log -l1 D2/f1 | grep changeset
1569 $ hg log -l1 D2/f1 | grep changeset
1563 changeset: 0:65624cd9070a
1570 changeset: 0:65624cd9070a
1564 $ hg log -l1 D3.i | grep changeset
1571 $ hg log -l1 D3.i | grep changeset
1565 changeset: 0:65624cd9070a
1572 changeset: 0:65624cd9070a
1566 $ hg log -l1 D3.i/f1 | grep changeset
1573 $ hg log -l1 D3.i/f1 | grep changeset
1567 changeset: 0:65624cd9070a
1574 changeset: 0:65624cd9070a
1568 $ hg log -l1 d4.hg | grep changeset
1575 $ hg log -l1 d4.hg | grep changeset
1569 changeset: 0:65624cd9070a
1576 changeset: 0:65624cd9070a
1570 $ hg log -l1 d4.hg/f1 | grep changeset
1577 $ hg log -l1 d4.hg/f1 | grep changeset
1571 changeset: 0:65624cd9070a
1578 changeset: 0:65624cd9070a
1572 $ hg log -l1 d5.d | grep changeset
1579 $ hg log -l1 d5.d | grep changeset
1573 changeset: 0:65624cd9070a
1580 changeset: 0:65624cd9070a
1574 $ hg log -l1 d5.d/f1 | grep changeset
1581 $ hg log -l1 d5.d/f1 | grep changeset
1575 changeset: 0:65624cd9070a
1582 changeset: 0:65624cd9070a
1576 $ hg log -l1 .d6 | grep changeset
1583 $ hg log -l1 .d6 | grep changeset
1577 changeset: 0:65624cd9070a
1584 changeset: 0:65624cd9070a
1578 $ hg log -l1 .d6/f1 | grep changeset
1585 $ hg log -l1 .d6/f1 | grep changeset
1579 changeset: 0:65624cd9070a
1586 changeset: 0:65624cd9070a
1580
1587
1581 issue3772: hg log -r :null showing revision 0 as well
1588 issue3772: hg log -r :null showing revision 0 as well
1582
1589
1583 $ hg log -r :null
1590 $ hg log -r :null
1584 changeset: 0:65624cd9070a
1591 changeset: 0:65624cd9070a
1585 tag: tip
1592 tag: tip
1586 user: test
1593 user: test
1587 date: Thu Jan 01 00:00:00 1970 +0000
1594 date: Thu Jan 01 00:00:00 1970 +0000
1588 summary: a bunch of weird directories
1595 summary: a bunch of weird directories
1589
1596
1590 changeset: -1:000000000000
1597 changeset: -1:000000000000
1591 user:
1598 user:
1592 date: Thu Jan 01 00:00:00 1970 +0000
1599 date: Thu Jan 01 00:00:00 1970 +0000
1593
1600
1594 $ hg log -r null:null
1601 $ hg log -r null:null
1595 changeset: -1:000000000000
1602 changeset: -1:000000000000
1596 user:
1603 user:
1597 date: Thu Jan 01 00:00:00 1970 +0000
1604 date: Thu Jan 01 00:00:00 1970 +0000
1598
1605
1599 Check that adding an arbitrary name shows up in log automatically
1606 Check that adding an arbitrary name shows up in log automatically
1600
1607
1601 $ cat > ../names.py <<EOF
1608 $ cat > ../names.py <<EOF
1602 > """A small extension to test adding arbitrary names to a repo"""
1609 > """A small extension to test adding arbitrary names to a repo"""
1603 > from mercurial.namespaces import namespace
1610 > from mercurial.namespaces import namespace
1604 >
1611 >
1605 > def reposetup(ui, repo):
1612 > def reposetup(ui, repo):
1606 > foo = {'foo': repo[0].node()}
1613 > foo = {'foo': repo[0].node()}
1607 > names = lambda r: foo.keys()
1614 > names = lambda r: foo.keys()
1608 > namemap = lambda r, name: foo.get(name)
1615 > namemap = lambda r, name: foo.get(name)
1609 > nodemap = lambda r, node: [name for name, n in foo.iteritems()
1616 > nodemap = lambda r, node: [name for name, n in foo.iteritems()
1610 > if n == node]
1617 > if n == node]
1611 > ns = namespace("bars", templatename="bar", logname="barlog",
1618 > ns = namespace("bars", templatename="bar", logname="barlog",
1612 > colorname="barcolor", listnames=names, namemap=namemap,
1619 > colorname="barcolor", listnames=names, namemap=namemap,
1613 > nodemap=nodemap)
1620 > nodemap=nodemap)
1614 >
1621 >
1615 > repo.names.addnamespace(ns)
1622 > repo.names.addnamespace(ns)
1616 > EOF
1623 > EOF
1617
1624
1618 $ hg --config extensions.names=../names.py log -r 0
1625 $ hg --config extensions.names=../names.py log -r 0
1619 changeset: 0:65624cd9070a
1626 changeset: 0:65624cd9070a
1620 tag: tip
1627 tag: tip
1621 barlog: foo
1628 barlog: foo
1622 user: test
1629 user: test
1623 date: Thu Jan 01 00:00:00 1970 +0000
1630 date: Thu Jan 01 00:00:00 1970 +0000
1624 summary: a bunch of weird directories
1631 summary: a bunch of weird directories
1625
1632
1626 $ hg --config extensions.names=../names.py \
1633 $ hg --config extensions.names=../names.py \
1627 > --config extensions.color= --config color.log.barcolor=red \
1634 > --config extensions.color= --config color.log.barcolor=red \
1628 > --color=always log -r 0
1635 > --color=always log -r 0
1629 \x1b[0;33mchangeset: 0:65624cd9070a\x1b[0m (esc)
1636 \x1b[0;33mchangeset: 0:65624cd9070a\x1b[0m (esc)
1630 tag: tip
1637 tag: tip
1631 \x1b[0;31mbarlog: foo\x1b[0m (esc)
1638 \x1b[0;31mbarlog: foo\x1b[0m (esc)
1632 user: test
1639 user: test
1633 date: Thu Jan 01 00:00:00 1970 +0000
1640 date: Thu Jan 01 00:00:00 1970 +0000
1634 summary: a bunch of weird directories
1641 summary: a bunch of weird directories
1635
1642
1636 $ hg --config extensions.names=../names.py log -r 0 --template '{bars}\n'
1643 $ hg --config extensions.names=../names.py log -r 0 --template '{bars}\n'
1637 foo
1644 foo
1638
1645
1639 $ cd ..
1646 $ cd ..
1640
1647
1641 hg log -f dir across branches
1648 hg log -f dir across branches
1642
1649
1643 $ hg init acrossbranches
1650 $ hg init acrossbranches
1644 $ cd acrossbranches
1651 $ cd acrossbranches
1645 $ mkdir d
1652 $ mkdir d
1646 $ echo a > d/a && hg ci -Aqm a
1653 $ echo a > d/a && hg ci -Aqm a
1647 $ echo b > d/a && hg ci -Aqm b
1654 $ echo b > d/a && hg ci -Aqm b
1648 $ hg up -q 0
1655 $ hg up -q 0
1649 $ echo b > d/a && hg ci -Aqm c
1656 $ echo b > d/a && hg ci -Aqm c
1650 $ hg log -f d -T '{desc}' -G
1657 $ hg log -f d -T '{desc}' -G
1651 @ c
1658 @ c
1652 |
1659 |
1653 o a
1660 o a
1654
1661
1655 Ensure that largefiles doesn't intefere with following a normal file
1662 Ensure that largefiles doesn't intefere with following a normal file
1656 $ hg --config extensions.largefiles= log -f d -T '{desc}' -G
1663 $ hg --config extensions.largefiles= log -f d -T '{desc}' -G
1657 @ c
1664 @ c
1658 |
1665 |
1659 o a
1666 o a
1660
1667
1661 $ hg log -f d/a -T '{desc}' -G
1668 $ hg log -f d/a -T '{desc}' -G
1662 @ c
1669 @ c
1663 |
1670 |
1664 o a
1671 o a
1665
1672
1666 $ cd ..
1673 $ cd ..
1667
1674
1668 hg log -f with linkrev pointing to another branch
1675 hg log -f with linkrev pointing to another branch
1669 -------------------------------------------------
1676 -------------------------------------------------
1670
1677
1671 create history with a filerev whose linkrev points to another branch
1678 create history with a filerev whose linkrev points to another branch
1672
1679
1673 $ hg init branchedlinkrev
1680 $ hg init branchedlinkrev
1674 $ cd branchedlinkrev
1681 $ cd branchedlinkrev
1675 $ echo 1 > a
1682 $ echo 1 > a
1676 $ hg commit -Am 'content1'
1683 $ hg commit -Am 'content1'
1677 adding a
1684 adding a
1678 $ echo 2 > a
1685 $ echo 2 > a
1679 $ hg commit -m 'content2'
1686 $ hg commit -m 'content2'
1680 $ hg up --rev 'desc(content1)'
1687 $ hg up --rev 'desc(content1)'
1681 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1688 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1682 $ echo unrelated > unrelated
1689 $ echo unrelated > unrelated
1683 $ hg commit -Am 'unrelated'
1690 $ hg commit -Am 'unrelated'
1684 adding unrelated
1691 adding unrelated
1685 created new head
1692 created new head
1686 $ hg graft -r 'desc(content2)'
1693 $ hg graft -r 'desc(content2)'
1687 grafting 1:2294ae80ad84 "content2"
1694 grafting 1:2294ae80ad84 "content2"
1688 $ echo 3 > a
1695 $ echo 3 > a
1689 $ hg commit -m 'content3'
1696 $ hg commit -m 'content3'
1690 $ hg log -G
1697 $ hg log -G
1691 @ changeset: 4:50b9b36e9c5d
1698 @ changeset: 4:50b9b36e9c5d
1692 | tag: tip
1699 | tag: tip
1693 | user: test
1700 | user: test
1694 | date: Thu Jan 01 00:00:00 1970 +0000
1701 | date: Thu Jan 01 00:00:00 1970 +0000
1695 | summary: content3
1702 | summary: content3
1696 |
1703 |
1697 o changeset: 3:15b2327059e5
1704 o changeset: 3:15b2327059e5
1698 | user: test
1705 | user: test
1699 | date: Thu Jan 01 00:00:00 1970 +0000
1706 | date: Thu Jan 01 00:00:00 1970 +0000
1700 | summary: content2
1707 | summary: content2
1701 |
1708 |
1702 o changeset: 2:2029acd1168c
1709 o changeset: 2:2029acd1168c
1703 | parent: 0:ae0a3c9f9e95
1710 | parent: 0:ae0a3c9f9e95
1704 | user: test
1711 | user: test
1705 | date: Thu Jan 01 00:00:00 1970 +0000
1712 | date: Thu Jan 01 00:00:00 1970 +0000
1706 | summary: unrelated
1713 | summary: unrelated
1707 |
1714 |
1708 | o changeset: 1:2294ae80ad84
1715 | o changeset: 1:2294ae80ad84
1709 |/ user: test
1716 |/ user: test
1710 | date: Thu Jan 01 00:00:00 1970 +0000
1717 | date: Thu Jan 01 00:00:00 1970 +0000
1711 | summary: content2
1718 | summary: content2
1712 |
1719 |
1713 o changeset: 0:ae0a3c9f9e95
1720 o changeset: 0:ae0a3c9f9e95
1714 user: test
1721 user: test
1715 date: Thu Jan 01 00:00:00 1970 +0000
1722 date: Thu Jan 01 00:00:00 1970 +0000
1716 summary: content1
1723 summary: content1
1717
1724
1718
1725
1719 log -f on the file should list the graft result.
1726 log -f on the file should list the graft result.
1720
1727
1721 $ hg log -Gf a
1728 $ hg log -Gf a
1722 @ changeset: 4:50b9b36e9c5d
1729 @ changeset: 4:50b9b36e9c5d
1723 | tag: tip
1730 | tag: tip
1724 | user: test
1731 | user: test
1725 | date: Thu Jan 01 00:00:00 1970 +0000
1732 | date: Thu Jan 01 00:00:00 1970 +0000
1726 | summary: content3
1733 | summary: content3
1727 |
1734 |
1728 o changeset: 3:15b2327059e5
1735 o changeset: 3:15b2327059e5
1729 | user: test
1736 | user: test
1730 | date: Thu Jan 01 00:00:00 1970 +0000
1737 | date: Thu Jan 01 00:00:00 1970 +0000
1731 | summary: content2
1738 | summary: content2
1732 |
1739 |
1733 o changeset: 0:ae0a3c9f9e95
1740 o changeset: 0:ae0a3c9f9e95
1734 user: test
1741 user: test
1735 date: Thu Jan 01 00:00:00 1970 +0000
1742 date: Thu Jan 01 00:00:00 1970 +0000
1736 summary: content1
1743 summary: content1
1737
1744
1738
1745
1739 plain log lists the original version
1746 plain log lists the original version
1740 (XXX we should probably list both)
1747 (XXX we should probably list both)
1741
1748
1742 $ hg log -G a
1749 $ hg log -G a
1743 @ changeset: 4:50b9b36e9c5d
1750 @ changeset: 4:50b9b36e9c5d
1744 | tag: tip
1751 | tag: tip
1745 | user: test
1752 | user: test
1746 | date: Thu Jan 01 00:00:00 1970 +0000
1753 | date: Thu Jan 01 00:00:00 1970 +0000
1747 | summary: content3
1754 | summary: content3
1748 |
1755 |
1749 | o changeset: 1:2294ae80ad84
1756 | o changeset: 1:2294ae80ad84
1750 |/ user: test
1757 |/ user: test
1751 | date: Thu Jan 01 00:00:00 1970 +0000
1758 | date: Thu Jan 01 00:00:00 1970 +0000
1752 | summary: content2
1759 | summary: content2
1753 |
1760 |
1754 o changeset: 0:ae0a3c9f9e95
1761 o changeset: 0:ae0a3c9f9e95
1755 user: test
1762 user: test
1756 date: Thu Jan 01 00:00:00 1970 +0000
1763 date: Thu Jan 01 00:00:00 1970 +0000
1757 summary: content1
1764 summary: content1
1758
1765
1759
1766
1760 hg log -f from the grafted changeset
1767 hg log -f from the grafted changeset
1761 (The bootstrap should properly take the topology in account)
1768 (The bootstrap should properly take the topology in account)
1762
1769
1763 $ hg up 'desc(content3)^'
1770 $ hg up 'desc(content3)^'
1764 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1771 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1765 $ hg log -Gf a
1772 $ hg log -Gf a
1766 @ changeset: 3:15b2327059e5
1773 @ changeset: 3:15b2327059e5
1767 | user: test
1774 | user: test
1768 | date: Thu Jan 01 00:00:00 1970 +0000
1775 | date: Thu Jan 01 00:00:00 1970 +0000
1769 | summary: content2
1776 | summary: content2
1770 |
1777 |
1771 o changeset: 0:ae0a3c9f9e95
1778 o changeset: 0:ae0a3c9f9e95
1772 user: test
1779 user: test
1773 date: Thu Jan 01 00:00:00 1970 +0000
1780 date: Thu Jan 01 00:00:00 1970 +0000
1774 summary: content1
1781 summary: content1
1775
1782
1776
1783
1777 Test that we use the first non-hidden changeset in that case.
1784 Test that we use the first non-hidden changeset in that case.
1778
1785
1779 (hide the changeset)
1786 (hide the changeset)
1780
1787
1781 $ hg log -T '{node}\n' -r 1
1788 $ hg log -T '{node}\n' -r 1
1782 2294ae80ad8447bc78383182eeac50cb049df623
1789 2294ae80ad8447bc78383182eeac50cb049df623
1783 $ hg debugobsolete 2294ae80ad8447bc78383182eeac50cb049df623
1790 $ hg debugobsolete 2294ae80ad8447bc78383182eeac50cb049df623
1784 $ hg log -G
1791 $ hg log -G
1785 o changeset: 4:50b9b36e9c5d
1792 o changeset: 4:50b9b36e9c5d
1786 | tag: tip
1793 | tag: tip
1787 | user: test
1794 | user: test
1788 | date: Thu Jan 01 00:00:00 1970 +0000
1795 | date: Thu Jan 01 00:00:00 1970 +0000
1789 | summary: content3
1796 | summary: content3
1790 |
1797 |
1791 @ changeset: 3:15b2327059e5
1798 @ changeset: 3:15b2327059e5
1792 | user: test
1799 | user: test
1793 | date: Thu Jan 01 00:00:00 1970 +0000
1800 | date: Thu Jan 01 00:00:00 1970 +0000
1794 | summary: content2
1801 | summary: content2
1795 |
1802 |
1796 o changeset: 2:2029acd1168c
1803 o changeset: 2:2029acd1168c
1797 | parent: 0:ae0a3c9f9e95
1804 | parent: 0:ae0a3c9f9e95
1798 | user: test
1805 | user: test
1799 | date: Thu Jan 01 00:00:00 1970 +0000
1806 | date: Thu Jan 01 00:00:00 1970 +0000
1800 | summary: unrelated
1807 | summary: unrelated
1801 |
1808 |
1802 o changeset: 0:ae0a3c9f9e95
1809 o changeset: 0:ae0a3c9f9e95
1803 user: test
1810 user: test
1804 date: Thu Jan 01 00:00:00 1970 +0000
1811 date: Thu Jan 01 00:00:00 1970 +0000
1805 summary: content1
1812 summary: content1
1806
1813
1807
1814
1808 Check that log on the file does not drop the file revision.
1815 Check that log on the file does not drop the file revision.
1809
1816
1810 $ hg log -G a
1817 $ hg log -G a
1811 o changeset: 4:50b9b36e9c5d
1818 o changeset: 4:50b9b36e9c5d
1812 | tag: tip
1819 | tag: tip
1813 | user: test
1820 | user: test
1814 | date: Thu Jan 01 00:00:00 1970 +0000
1821 | date: Thu Jan 01 00:00:00 1970 +0000
1815 | summary: content3
1822 | summary: content3
1816 |
1823 |
1817 @ changeset: 3:15b2327059e5
1824 @ changeset: 3:15b2327059e5
1818 | user: test
1825 | user: test
1819 | date: Thu Jan 01 00:00:00 1970 +0000
1826 | date: Thu Jan 01 00:00:00 1970 +0000
1820 | summary: content2
1827 | summary: content2
1821 |
1828 |
1822 o changeset: 0:ae0a3c9f9e95
1829 o changeset: 0:ae0a3c9f9e95
1823 user: test
1830 user: test
1824 date: Thu Jan 01 00:00:00 1970 +0000
1831 date: Thu Jan 01 00:00:00 1970 +0000
1825 summary: content1
1832 summary: content1
1826
1833
1827
1834
1828 Even when a head revision is linkrev-shadowed.
1835 Even when a head revision is linkrev-shadowed.
1829
1836
1830 $ hg log -T '{node}\n' -r 4
1837 $ hg log -T '{node}\n' -r 4
1831 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
1838 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
1832 $ hg debugobsolete 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
1839 $ hg debugobsolete 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
1833 $ hg log -G a
1840 $ hg log -G a
1834 @ changeset: 3:15b2327059e5
1841 @ changeset: 3:15b2327059e5
1835 | tag: tip
1842 | tag: tip
1836 | user: test
1843 | user: test
1837 | date: Thu Jan 01 00:00:00 1970 +0000
1844 | date: Thu Jan 01 00:00:00 1970 +0000
1838 | summary: content2
1845 | summary: content2
1839 |
1846 |
1840 o changeset: 0:ae0a3c9f9e95
1847 o changeset: 0:ae0a3c9f9e95
1841 user: test
1848 user: test
1842 date: Thu Jan 01 00:00:00 1970 +0000
1849 date: Thu Jan 01 00:00:00 1970 +0000
1843 summary: content1
1850 summary: content1
1844
1851
1845
1852
1846 $ cd ..
1853 $ cd ..
1847
1854
1848 Even when the file revision is missing from some head:
1855 Even when the file revision is missing from some head:
1849
1856
1850 $ hg init issue4490
1857 $ hg init issue4490
1851 $ cd issue4490
1858 $ cd issue4490
1852 $ echo '[experimental]' >> .hg/hgrc
1859 $ echo '[experimental]' >> .hg/hgrc
1853 $ echo 'evolution=createmarkers' >> .hg/hgrc
1860 $ echo 'evolution=createmarkers' >> .hg/hgrc
1854 $ echo a > a
1861 $ echo a > a
1855 $ hg ci -Am0
1862 $ hg ci -Am0
1856 adding a
1863 adding a
1857 $ echo b > b
1864 $ echo b > b
1858 $ hg ci -Am1
1865 $ hg ci -Am1
1859 adding b
1866 adding b
1860 $ echo B > b
1867 $ echo B > b
1861 $ hg ci --amend -m 1
1868 $ hg ci --amend -m 1
1862 $ hg up 0
1869 $ hg up 0
1863 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1870 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1864 $ echo c > c
1871 $ echo c > c
1865 $ hg ci -Am2
1872 $ hg ci -Am2
1866 adding c
1873 adding c
1867 created new head
1874 created new head
1868 $ hg up 'head() and not .'
1875 $ hg up 'head() and not .'
1869 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1876 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1870 $ hg log -G
1877 $ hg log -G
1871 o changeset: 4:db815d6d32e6
1878 o changeset: 4:db815d6d32e6
1872 | tag: tip
1879 | tag: tip
1873 | parent: 0:f7b1eb17ad24
1880 | parent: 0:f7b1eb17ad24
1874 | user: test
1881 | user: test
1875 | date: Thu Jan 01 00:00:00 1970 +0000
1882 | date: Thu Jan 01 00:00:00 1970 +0000
1876 | summary: 2
1883 | summary: 2
1877 |
1884 |
1878 | @ changeset: 3:9bc8ce7f9356
1885 | @ changeset: 3:9bc8ce7f9356
1879 |/ parent: 0:f7b1eb17ad24
1886 |/ parent: 0:f7b1eb17ad24
1880 | user: test
1887 | user: test
1881 | date: Thu Jan 01 00:00:00 1970 +0000
1888 | date: Thu Jan 01 00:00:00 1970 +0000
1882 | summary: 1
1889 | summary: 1
1883 |
1890 |
1884 o changeset: 0:f7b1eb17ad24
1891 o changeset: 0:f7b1eb17ad24
1885 user: test
1892 user: test
1886 date: Thu Jan 01 00:00:00 1970 +0000
1893 date: Thu Jan 01 00:00:00 1970 +0000
1887 summary: 0
1894 summary: 0
1888
1895
1889 $ hg log -f -G b
1896 $ hg log -f -G b
1890 @ changeset: 3:9bc8ce7f9356
1897 @ changeset: 3:9bc8ce7f9356
1891 | parent: 0:f7b1eb17ad24
1898 | parent: 0:f7b1eb17ad24
1892 | user: test
1899 | user: test
1893 | date: Thu Jan 01 00:00:00 1970 +0000
1900 | date: Thu Jan 01 00:00:00 1970 +0000
1894 | summary: 1
1901 | summary: 1
1895 |
1902 |
1896 $ hg log -G b
1903 $ hg log -G b
1897 @ changeset: 3:9bc8ce7f9356
1904 @ changeset: 3:9bc8ce7f9356
1898 | parent: 0:f7b1eb17ad24
1905 | parent: 0:f7b1eb17ad24
1899 | user: test
1906 | user: test
1900 | date: Thu Jan 01 00:00:00 1970 +0000
1907 | date: Thu Jan 01 00:00:00 1970 +0000
1901 | summary: 1
1908 | summary: 1
1902 |
1909 |
1903 $ cd ..
1910 $ cd ..
1904
1911
1905 Check proper report when the manifest changes but not the file issue4499
1912 Check proper report when the manifest changes but not the file issue4499
1906 ------------------------------------------------------------------------
1913 ------------------------------------------------------------------------
1907
1914
1908 $ hg init issue4499
1915 $ hg init issue4499
1909 $ cd issue4499
1916 $ cd issue4499
1910 $ for f in A B C D F E G H I J K L M N O P Q R S T U; do
1917 $ for f in A B C D F E G H I J K L M N O P Q R S T U; do
1911 > echo 1 > $f;
1918 > echo 1 > $f;
1912 > hg add $f;
1919 > hg add $f;
1913 > done
1920 > done
1914 $ hg commit -m 'A1B1C1'
1921 $ hg commit -m 'A1B1C1'
1915 $ echo 2 > A
1922 $ echo 2 > A
1916 $ echo 2 > B
1923 $ echo 2 > B
1917 $ echo 2 > C
1924 $ echo 2 > C
1918 $ hg commit -m 'A2B2C2'
1925 $ hg commit -m 'A2B2C2'
1919 $ hg up 0
1926 $ hg up 0
1920 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1927 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1921 $ echo 3 > A
1928 $ echo 3 > A
1922 $ echo 2 > B
1929 $ echo 2 > B
1923 $ echo 2 > C
1930 $ echo 2 > C
1924 $ hg commit -m 'A3B2C2'
1931 $ hg commit -m 'A3B2C2'
1925 created new head
1932 created new head
1926
1933
1927 $ hg log -G
1934 $ hg log -G
1928 @ changeset: 2:fe5fc3d0eb17
1935 @ changeset: 2:fe5fc3d0eb17
1929 | tag: tip
1936 | tag: tip
1930 | parent: 0:abf4f0e38563
1937 | parent: 0:abf4f0e38563
1931 | user: test
1938 | user: test
1932 | date: Thu Jan 01 00:00:00 1970 +0000
1939 | date: Thu Jan 01 00:00:00 1970 +0000
1933 | summary: A3B2C2
1940 | summary: A3B2C2
1934 |
1941 |
1935 | o changeset: 1:07dcc6b312c0
1942 | o changeset: 1:07dcc6b312c0
1936 |/ user: test
1943 |/ user: test
1937 | date: Thu Jan 01 00:00:00 1970 +0000
1944 | date: Thu Jan 01 00:00:00 1970 +0000
1938 | summary: A2B2C2
1945 | summary: A2B2C2
1939 |
1946 |
1940 o changeset: 0:abf4f0e38563
1947 o changeset: 0:abf4f0e38563
1941 user: test
1948 user: test
1942 date: Thu Jan 01 00:00:00 1970 +0000
1949 date: Thu Jan 01 00:00:00 1970 +0000
1943 summary: A1B1C1
1950 summary: A1B1C1
1944
1951
1945
1952
1946 Log -f on B should reports current changesets
1953 Log -f on B should reports current changesets
1947
1954
1948 $ hg log -fG B
1955 $ hg log -fG B
1949 @ changeset: 2:fe5fc3d0eb17
1956 @ changeset: 2:fe5fc3d0eb17
1950 | tag: tip
1957 | tag: tip
1951 | parent: 0:abf4f0e38563
1958 | parent: 0:abf4f0e38563
1952 | user: test
1959 | user: test
1953 | date: Thu Jan 01 00:00:00 1970 +0000
1960 | date: Thu Jan 01 00:00:00 1970 +0000
1954 | summary: A3B2C2
1961 | summary: A3B2C2
1955 |
1962 |
1956 o changeset: 0:abf4f0e38563
1963 o changeset: 0:abf4f0e38563
1957 user: test
1964 user: test
1958 date: Thu Jan 01 00:00:00 1970 +0000
1965 date: Thu Jan 01 00:00:00 1970 +0000
1959 summary: A1B1C1
1966 summary: A1B1C1
1960
1967
1961 $ cd ..
1968 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now