##// END OF EJS Templates
log: fix log -f slow path to actually follow history...
Durham Goode -
r23500:9601229e stable
parent child Browse files
Show More
@@ -1,2886 +1,2888 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 'cxtorbool' is one of a ctx to be committed, or a bool whether
116 'cxtorbool' 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 branch = ctx.branch()
905 branch = ctx.branch()
906 # don't show the default branch name
906 # don't show the default branch name
907 if branch != 'default':
907 if branch != 'default':
908 # i18n: column positioning for "hg log"
908 # i18n: column positioning for "hg log"
909 self.ui.write(_("branch: %s\n") % branch,
909 self.ui.write(_("branch: %s\n") % branch,
910 label='log.branch')
910 label='log.branch')
911 for bookmark in self.repo.nodebookmarks(changenode):
911 for bookmark in self.repo.nodebookmarks(changenode):
912 # i18n: column positioning for "hg log"
912 # i18n: column positioning for "hg log"
913 self.ui.write(_("bookmark: %s\n") % bookmark,
913 self.ui.write(_("bookmark: %s\n") % bookmark,
914 label='log.bookmark')
914 label='log.bookmark')
915 for tag in self.repo.nodetags(changenode):
915 for tag in self.repo.nodetags(changenode):
916 # i18n: column positioning for "hg log"
916 # i18n: column positioning for "hg log"
917 self.ui.write(_("tag: %s\n") % tag,
917 self.ui.write(_("tag: %s\n") % tag,
918 label='log.tag')
918 label='log.tag')
919 if self.ui.debugflag:
919 if self.ui.debugflag:
920 # i18n: column positioning for "hg log"
920 # i18n: column positioning for "hg log"
921 self.ui.write(_("phase: %s\n") % _(ctx.phasestr()),
921 self.ui.write(_("phase: %s\n") % _(ctx.phasestr()),
922 label='log.phase')
922 label='log.phase')
923 for parent in parents:
923 for parent in parents:
924 label = 'log.parent changeset.%s' % self.repo[parent[0]].phasestr()
924 label = 'log.parent changeset.%s' % self.repo[parent[0]].phasestr()
925 # i18n: column positioning for "hg log"
925 # i18n: column positioning for "hg log"
926 self.ui.write(_("parent: %d:%s\n") % parent,
926 self.ui.write(_("parent: %d:%s\n") % parent,
927 label=label)
927 label=label)
928
928
929 if self.ui.debugflag:
929 if self.ui.debugflag:
930 mnode = ctx.manifestnode()
930 mnode = ctx.manifestnode()
931 # i18n: column positioning for "hg log"
931 # i18n: column positioning for "hg log"
932 self.ui.write(_("manifest: %d:%s\n") %
932 self.ui.write(_("manifest: %d:%s\n") %
933 (self.repo.manifest.rev(mnode), hex(mnode)),
933 (self.repo.manifest.rev(mnode), hex(mnode)),
934 label='ui.debug log.manifest')
934 label='ui.debug log.manifest')
935 # i18n: column positioning for "hg log"
935 # i18n: column positioning for "hg log"
936 self.ui.write(_("user: %s\n") % ctx.user(),
936 self.ui.write(_("user: %s\n") % ctx.user(),
937 label='log.user')
937 label='log.user')
938 # i18n: column positioning for "hg log"
938 # i18n: column positioning for "hg log"
939 self.ui.write(_("date: %s\n") % date,
939 self.ui.write(_("date: %s\n") % date,
940 label='log.date')
940 label='log.date')
941
941
942 if self.ui.debugflag:
942 if self.ui.debugflag:
943 files = self.repo.status(log.parents(changenode)[0], changenode)[:3]
943 files = self.repo.status(log.parents(changenode)[0], changenode)[:3]
944 for key, value in zip([# i18n: column positioning for "hg log"
944 for key, value in zip([# i18n: column positioning for "hg log"
945 _("files:"),
945 _("files:"),
946 # i18n: column positioning for "hg log"
946 # i18n: column positioning for "hg log"
947 _("files+:"),
947 _("files+:"),
948 # i18n: column positioning for "hg log"
948 # i18n: column positioning for "hg log"
949 _("files-:")], files):
949 _("files-:")], files):
950 if value:
950 if value:
951 self.ui.write("%-12s %s\n" % (key, " ".join(value)),
951 self.ui.write("%-12s %s\n" % (key, " ".join(value)),
952 label='ui.debug log.files')
952 label='ui.debug log.files')
953 elif ctx.files() and self.ui.verbose:
953 elif ctx.files() and self.ui.verbose:
954 # i18n: column positioning for "hg log"
954 # i18n: column positioning for "hg log"
955 self.ui.write(_("files: %s\n") % " ".join(ctx.files()),
955 self.ui.write(_("files: %s\n") % " ".join(ctx.files()),
956 label='ui.note log.files')
956 label='ui.note log.files')
957 if copies and self.ui.verbose:
957 if copies and self.ui.verbose:
958 copies = ['%s (%s)' % c for c in copies]
958 copies = ['%s (%s)' % c for c in copies]
959 # i18n: column positioning for "hg log"
959 # i18n: column positioning for "hg log"
960 self.ui.write(_("copies: %s\n") % ' '.join(copies),
960 self.ui.write(_("copies: %s\n") % ' '.join(copies),
961 label='ui.note log.copies')
961 label='ui.note log.copies')
962
962
963 extra = ctx.extra()
963 extra = ctx.extra()
964 if extra and self.ui.debugflag:
964 if extra and self.ui.debugflag:
965 for key, value in sorted(extra.items()):
965 for key, value in sorted(extra.items()):
966 # i18n: column positioning for "hg log"
966 # i18n: column positioning for "hg log"
967 self.ui.write(_("extra: %s=%s\n")
967 self.ui.write(_("extra: %s=%s\n")
968 % (key, value.encode('string_escape')),
968 % (key, value.encode('string_escape')),
969 label='ui.debug log.extra')
969 label='ui.debug log.extra')
970
970
971 description = ctx.description().strip()
971 description = ctx.description().strip()
972 if description:
972 if description:
973 if self.ui.verbose:
973 if self.ui.verbose:
974 self.ui.write(_("description:\n"),
974 self.ui.write(_("description:\n"),
975 label='ui.note log.description')
975 label='ui.note log.description')
976 self.ui.write(description,
976 self.ui.write(description,
977 label='ui.note log.description')
977 label='ui.note log.description')
978 self.ui.write("\n\n")
978 self.ui.write("\n\n")
979 else:
979 else:
980 # i18n: column positioning for "hg log"
980 # i18n: column positioning for "hg log"
981 self.ui.write(_("summary: %s\n") %
981 self.ui.write(_("summary: %s\n") %
982 description.splitlines()[0],
982 description.splitlines()[0],
983 label='log.summary')
983 label='log.summary')
984 self.ui.write("\n")
984 self.ui.write("\n")
985
985
986 self.showpatch(changenode, matchfn)
986 self.showpatch(changenode, matchfn)
987
987
988 def showpatch(self, node, matchfn):
988 def showpatch(self, node, matchfn):
989 if not matchfn:
989 if not matchfn:
990 matchfn = self.matchfn
990 matchfn = self.matchfn
991 if matchfn:
991 if matchfn:
992 stat = self.diffopts.get('stat')
992 stat = self.diffopts.get('stat')
993 diff = self.diffopts.get('patch')
993 diff = self.diffopts.get('patch')
994 diffopts = patch.diffopts(self.ui, self.diffopts)
994 diffopts = patch.diffopts(self.ui, self.diffopts)
995 prev = self.repo.changelog.parents(node)[0]
995 prev = self.repo.changelog.parents(node)[0]
996 if stat:
996 if stat:
997 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
997 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
998 match=matchfn, stat=True)
998 match=matchfn, stat=True)
999 if diff:
999 if diff:
1000 if stat:
1000 if stat:
1001 self.ui.write("\n")
1001 self.ui.write("\n")
1002 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1002 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1003 match=matchfn, stat=False)
1003 match=matchfn, stat=False)
1004 self.ui.write("\n")
1004 self.ui.write("\n")
1005
1005
1006 def _meaningful_parentrevs(self, log, rev):
1006 def _meaningful_parentrevs(self, log, rev):
1007 """Return list of meaningful (or all if debug) parentrevs for rev.
1007 """Return list of meaningful (or all if debug) parentrevs for rev.
1008
1008
1009 For merges (two non-nullrev revisions) both parents are meaningful.
1009 For merges (two non-nullrev revisions) both parents are meaningful.
1010 Otherwise the first parent revision is considered meaningful if it
1010 Otherwise the first parent revision is considered meaningful if it
1011 is not the preceding revision.
1011 is not the preceding revision.
1012 """
1012 """
1013 parents = log.parentrevs(rev)
1013 parents = log.parentrevs(rev)
1014 if not self.ui.debugflag and parents[1] == nullrev:
1014 if not self.ui.debugflag and parents[1] == nullrev:
1015 if parents[0] >= rev - 1:
1015 if parents[0] >= rev - 1:
1016 parents = []
1016 parents = []
1017 else:
1017 else:
1018 parents = [parents[0]]
1018 parents = [parents[0]]
1019 return parents
1019 return parents
1020
1020
1021 class jsonchangeset(changeset_printer):
1021 class jsonchangeset(changeset_printer):
1022 '''format changeset information.'''
1022 '''format changeset information.'''
1023
1023
1024 def __init__(self, ui, repo, matchfn, diffopts, buffered):
1024 def __init__(self, ui, repo, matchfn, diffopts, buffered):
1025 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
1025 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
1026 self.cache = {}
1026 self.cache = {}
1027 self._first = True
1027 self._first = True
1028
1028
1029 def close(self):
1029 def close(self):
1030 if not self._first:
1030 if not self._first:
1031 self.ui.write("\n]\n")
1031 self.ui.write("\n]\n")
1032 else:
1032 else:
1033 self.ui.write("[]\n")
1033 self.ui.write("[]\n")
1034
1034
1035 def _show(self, ctx, copies, matchfn, props):
1035 def _show(self, ctx, copies, matchfn, props):
1036 '''show a single changeset or file revision'''
1036 '''show a single changeset or file revision'''
1037 hexnode = hex(ctx.node())
1037 hexnode = hex(ctx.node())
1038 rev = ctx.rev()
1038 rev = ctx.rev()
1039 j = encoding.jsonescape
1039 j = encoding.jsonescape
1040
1040
1041 if self._first:
1041 if self._first:
1042 self.ui.write("[\n {")
1042 self.ui.write("[\n {")
1043 self._first = False
1043 self._first = False
1044 else:
1044 else:
1045 self.ui.write(",\n {")
1045 self.ui.write(",\n {")
1046
1046
1047 if self.ui.quiet:
1047 if self.ui.quiet:
1048 self.ui.write('\n "rev": %d' % rev)
1048 self.ui.write('\n "rev": %d' % rev)
1049 self.ui.write(',\n "node": "%s"' % hexnode)
1049 self.ui.write(',\n "node": "%s"' % hexnode)
1050 self.ui.write('\n }')
1050 self.ui.write('\n }')
1051 return
1051 return
1052
1052
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 "branch": "%s"' % j(ctx.branch()))
1055 self.ui.write(',\n "branch": "%s"' % j(ctx.branch()))
1056 self.ui.write(',\n "phase": "%s"' % ctx.phasestr())
1056 self.ui.write(',\n "phase": "%s"' % ctx.phasestr())
1057 self.ui.write(',\n "user": "%s"' % j(ctx.user()))
1057 self.ui.write(',\n "user": "%s"' % j(ctx.user()))
1058 self.ui.write(',\n "date": [%d, %d]' % ctx.date())
1058 self.ui.write(',\n "date": [%d, %d]' % ctx.date())
1059 self.ui.write(',\n "desc": "%s"' % j(ctx.description()))
1059 self.ui.write(',\n "desc": "%s"' % j(ctx.description()))
1060
1060
1061 self.ui.write(',\n "bookmarks": [%s]' %
1061 self.ui.write(',\n "bookmarks": [%s]' %
1062 ", ".join('"%s"' % j(b) for b in ctx.bookmarks()))
1062 ", ".join('"%s"' % j(b) for b in ctx.bookmarks()))
1063 self.ui.write(',\n "tags": [%s]' %
1063 self.ui.write(',\n "tags": [%s]' %
1064 ", ".join('"%s"' % j(t) for t in ctx.tags()))
1064 ", ".join('"%s"' % j(t) for t in ctx.tags()))
1065 self.ui.write(',\n "parents": [%s]' %
1065 self.ui.write(',\n "parents": [%s]' %
1066 ", ".join('"%s"' % c.hex() for c in ctx.parents()))
1066 ", ".join('"%s"' % c.hex() for c in ctx.parents()))
1067
1067
1068 if self.ui.debugflag:
1068 if self.ui.debugflag:
1069 self.ui.write(',\n "manifest": "%s"' % hex(ctx.manifestnode()))
1069 self.ui.write(',\n "manifest": "%s"' % hex(ctx.manifestnode()))
1070
1070
1071 self.ui.write(',\n "extra": {%s}' %
1071 self.ui.write(',\n "extra": {%s}' %
1072 ", ".join('"%s": "%s"' % (j(k), j(v))
1072 ", ".join('"%s": "%s"' % (j(k), j(v))
1073 for k, v in ctx.extra().items()))
1073 for k, v in ctx.extra().items()))
1074
1074
1075 files = ctx.status(ctx.p1())
1075 files = ctx.status(ctx.p1())
1076 self.ui.write(',\n "modified": [%s]' %
1076 self.ui.write(',\n "modified": [%s]' %
1077 ", ".join('"%s"' % j(f) for f in files[0]))
1077 ", ".join('"%s"' % j(f) for f in files[0]))
1078 self.ui.write(',\n "added": [%s]' %
1078 self.ui.write(',\n "added": [%s]' %
1079 ", ".join('"%s"' % j(f) for f in files[1]))
1079 ", ".join('"%s"' % j(f) for f in files[1]))
1080 self.ui.write(',\n "removed": [%s]' %
1080 self.ui.write(',\n "removed": [%s]' %
1081 ", ".join('"%s"' % j(f) for f in files[2]))
1081 ", ".join('"%s"' % j(f) for f in files[2]))
1082
1082
1083 elif self.ui.verbose:
1083 elif self.ui.verbose:
1084 self.ui.write(',\n "files": [%s]' %
1084 self.ui.write(',\n "files": [%s]' %
1085 ", ".join('"%s"' % j(f) for f in ctx.files()))
1085 ", ".join('"%s"' % j(f) for f in ctx.files()))
1086
1086
1087 if copies:
1087 if copies:
1088 self.ui.write(',\n "copies": {%s}' %
1088 self.ui.write(',\n "copies": {%s}' %
1089 ", ".join('"%s": %s' % (j(k), j(copies[k]))
1089 ", ".join('"%s": %s' % (j(k), j(copies[k]))
1090 for k in copies))
1090 for k in copies))
1091
1091
1092 matchfn = self.matchfn
1092 matchfn = self.matchfn
1093 if matchfn:
1093 if matchfn:
1094 stat = self.diffopts.get('stat')
1094 stat = self.diffopts.get('stat')
1095 diff = self.diffopts.get('patch')
1095 diff = self.diffopts.get('patch')
1096 diffopts = patch.diffopts(self.ui, self.diffopts)
1096 diffopts = patch.diffopts(self.ui, self.diffopts)
1097 node, prev = ctx.node(), ctx.p1().node()
1097 node, prev = ctx.node(), ctx.p1().node()
1098 if stat:
1098 if stat:
1099 self.ui.pushbuffer()
1099 self.ui.pushbuffer()
1100 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1100 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
1101 match=matchfn, stat=True)
1101 match=matchfn, stat=True)
1102 self.ui.write(',\n "diffstat": "%s"' % j(self.ui.popbuffer()))
1102 self.ui.write(',\n "diffstat": "%s"' % j(self.ui.popbuffer()))
1103 if diff:
1103 if diff:
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=False)
1106 match=matchfn, stat=False)
1107 self.ui.write(',\n "diff": "%s"' % j(self.ui.popbuffer()))
1107 self.ui.write(',\n "diff": "%s"' % j(self.ui.popbuffer()))
1108
1108
1109 self.ui.write("\n }")
1109 self.ui.write("\n }")
1110
1110
1111 class changeset_templater(changeset_printer):
1111 class changeset_templater(changeset_printer):
1112 '''format changeset information.'''
1112 '''format changeset information.'''
1113
1113
1114 def __init__(self, ui, repo, matchfn, diffopts, tmpl, mapfile, buffered):
1114 def __init__(self, ui, repo, matchfn, diffopts, tmpl, mapfile, buffered):
1115 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
1115 changeset_printer.__init__(self, ui, repo, matchfn, diffopts, buffered)
1116 formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
1116 formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
1117 defaulttempl = {
1117 defaulttempl = {
1118 'parent': '{rev}:{node|formatnode} ',
1118 'parent': '{rev}:{node|formatnode} ',
1119 'manifest': '{rev}:{node|formatnode}',
1119 'manifest': '{rev}:{node|formatnode}',
1120 'file_copy': '{name} ({source})',
1120 'file_copy': '{name} ({source})',
1121 'extra': '{key}={value|stringescape}'
1121 'extra': '{key}={value|stringescape}'
1122 }
1122 }
1123 # filecopy is preserved for compatibility reasons
1123 # filecopy is preserved for compatibility reasons
1124 defaulttempl['filecopy'] = defaulttempl['file_copy']
1124 defaulttempl['filecopy'] = defaulttempl['file_copy']
1125 self.t = templater.templater(mapfile, {'formatnode': formatnode},
1125 self.t = templater.templater(mapfile, {'formatnode': formatnode},
1126 cache=defaulttempl)
1126 cache=defaulttempl)
1127 if tmpl:
1127 if tmpl:
1128 self.t.cache['changeset'] = tmpl
1128 self.t.cache['changeset'] = tmpl
1129
1129
1130 self.cache = {}
1130 self.cache = {}
1131
1131
1132 def _meaningful_parentrevs(self, ctx):
1132 def _meaningful_parentrevs(self, ctx):
1133 """Return list of meaningful (or all if debug) parentrevs for rev.
1133 """Return list of meaningful (or all if debug) parentrevs for rev.
1134 """
1134 """
1135 parents = ctx.parents()
1135 parents = ctx.parents()
1136 if len(parents) > 1:
1136 if len(parents) > 1:
1137 return parents
1137 return parents
1138 if self.ui.debugflag:
1138 if self.ui.debugflag:
1139 return [parents[0], self.repo['null']]
1139 return [parents[0], self.repo['null']]
1140 if parents[0].rev() >= ctx.rev() - 1:
1140 if parents[0].rev() >= ctx.rev() - 1:
1141 return []
1141 return []
1142 return parents
1142 return parents
1143
1143
1144 def _show(self, ctx, copies, matchfn, props):
1144 def _show(self, ctx, copies, matchfn, props):
1145 '''show a single changeset or file revision'''
1145 '''show a single changeset or file revision'''
1146
1146
1147 showlist = templatekw.showlist
1147 showlist = templatekw.showlist
1148
1148
1149 # showparents() behaviour depends on ui trace level which
1149 # showparents() behaviour depends on ui trace level which
1150 # causes unexpected behaviours at templating level and makes
1150 # causes unexpected behaviours at templating level and makes
1151 # it harder to extract it in a standalone function. Its
1151 # it harder to extract it in a standalone function. Its
1152 # behaviour cannot be changed so leave it here for now.
1152 # behaviour cannot be changed so leave it here for now.
1153 def showparents(**args):
1153 def showparents(**args):
1154 ctx = args['ctx']
1154 ctx = args['ctx']
1155 parents = [[('rev', p.rev()),
1155 parents = [[('rev', p.rev()),
1156 ('node', p.hex()),
1156 ('node', p.hex()),
1157 ('phase', p.phasestr())]
1157 ('phase', p.phasestr())]
1158 for p in self._meaningful_parentrevs(ctx)]
1158 for p in self._meaningful_parentrevs(ctx)]
1159 return showlist('parent', parents, **args)
1159 return showlist('parent', parents, **args)
1160
1160
1161 props = props.copy()
1161 props = props.copy()
1162 props.update(templatekw.keywords)
1162 props.update(templatekw.keywords)
1163 props['parents'] = showparents
1163 props['parents'] = showparents
1164 props['templ'] = self.t
1164 props['templ'] = self.t
1165 props['ctx'] = ctx
1165 props['ctx'] = ctx
1166 props['repo'] = self.repo
1166 props['repo'] = self.repo
1167 props['revcache'] = {'copies': copies}
1167 props['revcache'] = {'copies': copies}
1168 props['cache'] = self.cache
1168 props['cache'] = self.cache
1169
1169
1170 # find correct templates for current mode
1170 # find correct templates for current mode
1171
1171
1172 tmplmodes = [
1172 tmplmodes = [
1173 (True, None),
1173 (True, None),
1174 (self.ui.verbose, 'verbose'),
1174 (self.ui.verbose, 'verbose'),
1175 (self.ui.quiet, 'quiet'),
1175 (self.ui.quiet, 'quiet'),
1176 (self.ui.debugflag, 'debug'),
1176 (self.ui.debugflag, 'debug'),
1177 ]
1177 ]
1178
1178
1179 types = {'header': '', 'footer':'', 'changeset': 'changeset'}
1179 types = {'header': '', 'footer':'', 'changeset': 'changeset'}
1180 for mode, postfix in tmplmodes:
1180 for mode, postfix in tmplmodes:
1181 for type in types:
1181 for type in types:
1182 cur = postfix and ('%s_%s' % (type, postfix)) or type
1182 cur = postfix and ('%s_%s' % (type, postfix)) or type
1183 if mode and cur in self.t:
1183 if mode and cur in self.t:
1184 types[type] = cur
1184 types[type] = cur
1185
1185
1186 try:
1186 try:
1187
1187
1188 # write header
1188 # write header
1189 if types['header']:
1189 if types['header']:
1190 h = templater.stringify(self.t(types['header'], **props))
1190 h = templater.stringify(self.t(types['header'], **props))
1191 if self.buffered:
1191 if self.buffered:
1192 self.header[ctx.rev()] = h
1192 self.header[ctx.rev()] = h
1193 else:
1193 else:
1194 if self.lastheader != h:
1194 if self.lastheader != h:
1195 self.lastheader = h
1195 self.lastheader = h
1196 self.ui.write(h)
1196 self.ui.write(h)
1197
1197
1198 # write changeset metadata, then patch if requested
1198 # write changeset metadata, then patch if requested
1199 key = types['changeset']
1199 key = types['changeset']
1200 self.ui.write(templater.stringify(self.t(key, **props)))
1200 self.ui.write(templater.stringify(self.t(key, **props)))
1201 self.showpatch(ctx.node(), matchfn)
1201 self.showpatch(ctx.node(), matchfn)
1202
1202
1203 if types['footer']:
1203 if types['footer']:
1204 if not self.footer:
1204 if not self.footer:
1205 self.footer = templater.stringify(self.t(types['footer'],
1205 self.footer = templater.stringify(self.t(types['footer'],
1206 **props))
1206 **props))
1207
1207
1208 except KeyError, inst:
1208 except KeyError, inst:
1209 msg = _("%s: no key named '%s'")
1209 msg = _("%s: no key named '%s'")
1210 raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
1210 raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
1211 except SyntaxError, inst:
1211 except SyntaxError, inst:
1212 raise util.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
1212 raise util.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
1213
1213
1214 def gettemplate(ui, tmpl, style):
1214 def gettemplate(ui, tmpl, style):
1215 """
1215 """
1216 Find the template matching the given template spec or style.
1216 Find the template matching the given template spec or style.
1217 """
1217 """
1218
1218
1219 # ui settings
1219 # ui settings
1220 if not tmpl and not style: # template are stronger than style
1220 if not tmpl and not style: # template are stronger than style
1221 tmpl = ui.config('ui', 'logtemplate')
1221 tmpl = ui.config('ui', 'logtemplate')
1222 if tmpl:
1222 if tmpl:
1223 try:
1223 try:
1224 tmpl = templater.parsestring(tmpl)
1224 tmpl = templater.parsestring(tmpl)
1225 except SyntaxError:
1225 except SyntaxError:
1226 tmpl = templater.parsestring(tmpl, quoted=False)
1226 tmpl = templater.parsestring(tmpl, quoted=False)
1227 return tmpl, None
1227 return tmpl, None
1228 else:
1228 else:
1229 style = util.expandpath(ui.config('ui', 'style', ''))
1229 style = util.expandpath(ui.config('ui', 'style', ''))
1230
1230
1231 if not tmpl and style:
1231 if not tmpl and style:
1232 mapfile = style
1232 mapfile = style
1233 if not os.path.split(mapfile)[0]:
1233 if not os.path.split(mapfile)[0]:
1234 mapname = (templater.templatepath('map-cmdline.' + mapfile)
1234 mapname = (templater.templatepath('map-cmdline.' + mapfile)
1235 or templater.templatepath(mapfile))
1235 or templater.templatepath(mapfile))
1236 if mapname:
1236 if mapname:
1237 mapfile = mapname
1237 mapfile = mapname
1238 return None, mapfile
1238 return None, mapfile
1239
1239
1240 if not tmpl:
1240 if not tmpl:
1241 return None, None
1241 return None, None
1242
1242
1243 # looks like a literal template?
1243 # looks like a literal template?
1244 if '{' in tmpl:
1244 if '{' in tmpl:
1245 return tmpl, None
1245 return tmpl, None
1246
1246
1247 # perhaps a stock style?
1247 # perhaps a stock style?
1248 if not os.path.split(tmpl)[0]:
1248 if not os.path.split(tmpl)[0]:
1249 mapname = (templater.templatepath('map-cmdline.' + tmpl)
1249 mapname = (templater.templatepath('map-cmdline.' + tmpl)
1250 or templater.templatepath(tmpl))
1250 or templater.templatepath(tmpl))
1251 if mapname and os.path.isfile(mapname):
1251 if mapname and os.path.isfile(mapname):
1252 return None, mapname
1252 return None, mapname
1253
1253
1254 # perhaps it's a reference to [templates]
1254 # perhaps it's a reference to [templates]
1255 t = ui.config('templates', tmpl)
1255 t = ui.config('templates', tmpl)
1256 if t:
1256 if t:
1257 try:
1257 try:
1258 tmpl = templater.parsestring(t)
1258 tmpl = templater.parsestring(t)
1259 except SyntaxError:
1259 except SyntaxError:
1260 tmpl = templater.parsestring(t, quoted=False)
1260 tmpl = templater.parsestring(t, quoted=False)
1261 return tmpl, None
1261 return tmpl, None
1262
1262
1263 if tmpl == 'list':
1263 if tmpl == 'list':
1264 ui.write(_("available styles: %s\n") % templater.stylelist())
1264 ui.write(_("available styles: %s\n") % templater.stylelist())
1265 raise util.Abort(_("specify a template"))
1265 raise util.Abort(_("specify a template"))
1266
1266
1267 # perhaps it's a path to a map or a template
1267 # perhaps it's a path to a map or a template
1268 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
1268 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
1269 # is it a mapfile for a style?
1269 # is it a mapfile for a style?
1270 if os.path.basename(tmpl).startswith("map-"):
1270 if os.path.basename(tmpl).startswith("map-"):
1271 return None, os.path.realpath(tmpl)
1271 return None, os.path.realpath(tmpl)
1272 tmpl = open(tmpl).read()
1272 tmpl = open(tmpl).read()
1273 return tmpl, None
1273 return tmpl, None
1274
1274
1275 # constant string?
1275 # constant string?
1276 return tmpl, None
1276 return tmpl, None
1277
1277
1278 def show_changeset(ui, repo, opts, buffered=False):
1278 def show_changeset(ui, repo, opts, buffered=False):
1279 """show one changeset using template or regular display.
1279 """show one changeset using template or regular display.
1280
1280
1281 Display format will be the first non-empty hit of:
1281 Display format will be the first non-empty hit of:
1282 1. option 'template'
1282 1. option 'template'
1283 2. option 'style'
1283 2. option 'style'
1284 3. [ui] setting 'logtemplate'
1284 3. [ui] setting 'logtemplate'
1285 4. [ui] setting 'style'
1285 4. [ui] setting 'style'
1286 If all of these values are either the unset or the empty string,
1286 If all of these values are either the unset or the empty string,
1287 regular display via changeset_printer() is done.
1287 regular display via changeset_printer() is done.
1288 """
1288 """
1289 # options
1289 # options
1290 matchfn = None
1290 matchfn = None
1291 if opts.get('patch') or opts.get('stat'):
1291 if opts.get('patch') or opts.get('stat'):
1292 matchfn = scmutil.matchall(repo)
1292 matchfn = scmutil.matchall(repo)
1293
1293
1294 if opts.get('template') == 'json':
1294 if opts.get('template') == 'json':
1295 return jsonchangeset(ui, repo, matchfn, opts, buffered)
1295 return jsonchangeset(ui, repo, matchfn, opts, buffered)
1296
1296
1297 tmpl, mapfile = gettemplate(ui, opts.get('template'), opts.get('style'))
1297 tmpl, mapfile = gettemplate(ui, opts.get('template'), opts.get('style'))
1298
1298
1299 if not tmpl and not mapfile:
1299 if not tmpl and not mapfile:
1300 return changeset_printer(ui, repo, matchfn, opts, buffered)
1300 return changeset_printer(ui, repo, matchfn, opts, buffered)
1301
1301
1302 try:
1302 try:
1303 t = changeset_templater(ui, repo, matchfn, opts, tmpl, mapfile,
1303 t = changeset_templater(ui, repo, matchfn, opts, tmpl, mapfile,
1304 buffered)
1304 buffered)
1305 except SyntaxError, inst:
1305 except SyntaxError, inst:
1306 raise util.Abort(inst.args[0])
1306 raise util.Abort(inst.args[0])
1307 return t
1307 return t
1308
1308
1309 def showmarker(ui, marker):
1309 def showmarker(ui, marker):
1310 """utility function to display obsolescence marker in a readable way
1310 """utility function to display obsolescence marker in a readable way
1311
1311
1312 To be used by debug function."""
1312 To be used by debug function."""
1313 ui.write(hex(marker.precnode()))
1313 ui.write(hex(marker.precnode()))
1314 for repl in marker.succnodes():
1314 for repl in marker.succnodes():
1315 ui.write(' ')
1315 ui.write(' ')
1316 ui.write(hex(repl))
1316 ui.write(hex(repl))
1317 ui.write(' %X ' % marker.flags())
1317 ui.write(' %X ' % marker.flags())
1318 parents = marker.parentnodes()
1318 parents = marker.parentnodes()
1319 if parents is not None:
1319 if parents is not None:
1320 ui.write('{%s} ' % ', '.join(hex(p) for p in parents))
1320 ui.write('{%s} ' % ', '.join(hex(p) for p in parents))
1321 ui.write('(%s) ' % util.datestr(marker.date()))
1321 ui.write('(%s) ' % util.datestr(marker.date()))
1322 ui.write('{%s}' % (', '.join('%r: %r' % t for t in
1322 ui.write('{%s}' % (', '.join('%r: %r' % t for t in
1323 sorted(marker.metadata().items())
1323 sorted(marker.metadata().items())
1324 if t[0] != 'date')))
1324 if t[0] != 'date')))
1325 ui.write('\n')
1325 ui.write('\n')
1326
1326
1327 def finddate(ui, repo, date):
1327 def finddate(ui, repo, date):
1328 """Find the tipmost changeset that matches the given date spec"""
1328 """Find the tipmost changeset that matches the given date spec"""
1329
1329
1330 df = util.matchdate(date)
1330 df = util.matchdate(date)
1331 m = scmutil.matchall(repo)
1331 m = scmutil.matchall(repo)
1332 results = {}
1332 results = {}
1333
1333
1334 def prep(ctx, fns):
1334 def prep(ctx, fns):
1335 d = ctx.date()
1335 d = ctx.date()
1336 if df(d[0]):
1336 if df(d[0]):
1337 results[ctx.rev()] = d
1337 results[ctx.rev()] = d
1338
1338
1339 for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
1339 for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
1340 rev = ctx.rev()
1340 rev = ctx.rev()
1341 if rev in results:
1341 if rev in results:
1342 ui.status(_("found revision %s from %s\n") %
1342 ui.status(_("found revision %s from %s\n") %
1343 (rev, util.datestr(results[rev])))
1343 (rev, util.datestr(results[rev])))
1344 return str(rev)
1344 return str(rev)
1345
1345
1346 raise util.Abort(_("revision matching date not found"))
1346 raise util.Abort(_("revision matching date not found"))
1347
1347
1348 def increasingwindows(windowsize=8, sizelimit=512):
1348 def increasingwindows(windowsize=8, sizelimit=512):
1349 while True:
1349 while True:
1350 yield windowsize
1350 yield windowsize
1351 if windowsize < sizelimit:
1351 if windowsize < sizelimit:
1352 windowsize *= 2
1352 windowsize *= 2
1353
1353
1354 class FileWalkError(Exception):
1354 class FileWalkError(Exception):
1355 pass
1355 pass
1356
1356
1357 def walkfilerevs(repo, match, follow, revs, fncache):
1357 def walkfilerevs(repo, match, follow, revs, fncache):
1358 '''Walks the file history for the matched files.
1358 '''Walks the file history for the matched files.
1359
1359
1360 Returns the changeset revs that are involved in the file history.
1360 Returns the changeset revs that are involved in the file history.
1361
1361
1362 Throws FileWalkError if the file history can't be walked using
1362 Throws FileWalkError if the file history can't be walked using
1363 filelogs alone.
1363 filelogs alone.
1364 '''
1364 '''
1365 wanted = set()
1365 wanted = set()
1366 copies = []
1366 copies = []
1367 minrev, maxrev = min(revs), max(revs)
1367 minrev, maxrev = min(revs), max(revs)
1368 def filerevgen(filelog, last):
1368 def filerevgen(filelog, last):
1369 """
1369 """
1370 Only files, no patterns. Check the history of each file.
1370 Only files, no patterns. Check the history of each file.
1371
1371
1372 Examines filelog entries within minrev, maxrev linkrev range
1372 Examines filelog entries within minrev, maxrev linkrev range
1373 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1373 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1374 tuples in backwards order
1374 tuples in backwards order
1375 """
1375 """
1376 cl_count = len(repo)
1376 cl_count = len(repo)
1377 revs = []
1377 revs = []
1378 for j in xrange(0, last + 1):
1378 for j in xrange(0, last + 1):
1379 linkrev = filelog.linkrev(j)
1379 linkrev = filelog.linkrev(j)
1380 if linkrev < minrev:
1380 if linkrev < minrev:
1381 continue
1381 continue
1382 # only yield rev for which we have the changelog, it can
1382 # only yield rev for which we have the changelog, it can
1383 # happen while doing "hg log" during a pull or commit
1383 # happen while doing "hg log" during a pull or commit
1384 if linkrev >= cl_count:
1384 if linkrev >= cl_count:
1385 break
1385 break
1386
1386
1387 parentlinkrevs = []
1387 parentlinkrevs = []
1388 for p in filelog.parentrevs(j):
1388 for p in filelog.parentrevs(j):
1389 if p != nullrev:
1389 if p != nullrev:
1390 parentlinkrevs.append(filelog.linkrev(p))
1390 parentlinkrevs.append(filelog.linkrev(p))
1391 n = filelog.node(j)
1391 n = filelog.node(j)
1392 revs.append((linkrev, parentlinkrevs,
1392 revs.append((linkrev, parentlinkrevs,
1393 follow and filelog.renamed(n)))
1393 follow and filelog.renamed(n)))
1394
1394
1395 return reversed(revs)
1395 return reversed(revs)
1396 def iterfiles():
1396 def iterfiles():
1397 pctx = repo['.']
1397 pctx = repo['.']
1398 for filename in match.files():
1398 for filename in match.files():
1399 if follow:
1399 if follow:
1400 if filename not in pctx:
1400 if filename not in pctx:
1401 raise util.Abort(_('cannot follow file not in parent '
1401 raise util.Abort(_('cannot follow file not in parent '
1402 'revision: "%s"') % filename)
1402 'revision: "%s"') % filename)
1403 yield filename, pctx[filename].filenode()
1403 yield filename, pctx[filename].filenode()
1404 else:
1404 else:
1405 yield filename, None
1405 yield filename, None
1406 for filename_node in copies:
1406 for filename_node in copies:
1407 yield filename_node
1407 yield filename_node
1408
1408
1409 for file_, node in iterfiles():
1409 for file_, node in iterfiles():
1410 filelog = repo.file(file_)
1410 filelog = repo.file(file_)
1411 if not len(filelog):
1411 if not len(filelog):
1412 if node is None:
1412 if node is None:
1413 # A zero count may be a directory or deleted file, so
1413 # A zero count may be a directory or deleted file, so
1414 # try to find matching entries on the slow path.
1414 # try to find matching entries on the slow path.
1415 if follow:
1415 if follow:
1416 raise util.Abort(
1416 raise util.Abort(
1417 _('cannot follow nonexistent file: "%s"') % file_)
1417 _('cannot follow nonexistent file: "%s"') % file_)
1418 raise FileWalkError("Cannot walk via filelog")
1418 raise FileWalkError("Cannot walk via filelog")
1419 else:
1419 else:
1420 continue
1420 continue
1421
1421
1422 if node is None:
1422 if node is None:
1423 last = len(filelog) - 1
1423 last = len(filelog) - 1
1424 else:
1424 else:
1425 last = filelog.rev(node)
1425 last = filelog.rev(node)
1426
1426
1427
1427
1428 # keep track of all ancestors of the file
1428 # keep track of all ancestors of the file
1429 ancestors = set([filelog.linkrev(last)])
1429 ancestors = set([filelog.linkrev(last)])
1430
1430
1431 # iterate from latest to oldest revision
1431 # iterate from latest to oldest revision
1432 for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
1432 for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
1433 if not follow:
1433 if not follow:
1434 if rev > maxrev:
1434 if rev > maxrev:
1435 continue
1435 continue
1436 else:
1436 else:
1437 # Note that last might not be the first interesting
1437 # Note that last might not be the first interesting
1438 # rev to us:
1438 # rev to us:
1439 # if the file has been changed after maxrev, we'll
1439 # if the file has been changed after maxrev, we'll
1440 # have linkrev(last) > maxrev, and we still need
1440 # have linkrev(last) > maxrev, and we still need
1441 # to explore the file graph
1441 # to explore the file graph
1442 if rev not in ancestors:
1442 if rev not in ancestors:
1443 continue
1443 continue
1444 # XXX insert 1327 fix here
1444 # XXX insert 1327 fix here
1445 if flparentlinkrevs:
1445 if flparentlinkrevs:
1446 ancestors.update(flparentlinkrevs)
1446 ancestors.update(flparentlinkrevs)
1447
1447
1448 fncache.setdefault(rev, []).append(file_)
1448 fncache.setdefault(rev, []).append(file_)
1449 wanted.add(rev)
1449 wanted.add(rev)
1450 if copied:
1450 if copied:
1451 copies.append(copied)
1451 copies.append(copied)
1452
1452
1453 return wanted
1453 return wanted
1454
1454
1455 def walkchangerevs(repo, match, opts, prepare):
1455 def walkchangerevs(repo, match, opts, prepare):
1456 '''Iterate over files and the revs in which they changed.
1456 '''Iterate over files and the revs in which they changed.
1457
1457
1458 Callers most commonly need to iterate backwards over the history
1458 Callers most commonly need to iterate backwards over the history
1459 in which they are interested. Doing so has awful (quadratic-looking)
1459 in which they are interested. Doing so has awful (quadratic-looking)
1460 performance, so we use iterators in a "windowed" way.
1460 performance, so we use iterators in a "windowed" way.
1461
1461
1462 We walk a window of revisions in the desired order. Within the
1462 We walk a window of revisions in the desired order. Within the
1463 window, we first walk forwards to gather data, then in the desired
1463 window, we first walk forwards to gather data, then in the desired
1464 order (usually backwards) to display it.
1464 order (usually backwards) to display it.
1465
1465
1466 This function returns an iterator yielding contexts. Before
1466 This function returns an iterator yielding contexts. Before
1467 yielding each context, the iterator will first call the prepare
1467 yielding each context, the iterator will first call the prepare
1468 function on each context in the window in forward order.'''
1468 function on each context in the window in forward order.'''
1469
1469
1470 follow = opts.get('follow') or opts.get('follow_first')
1470 follow = opts.get('follow') or opts.get('follow_first')
1471
1471
1472 if opts.get('rev'):
1472 if opts.get('rev'):
1473 revs = scmutil.revrange(repo, opts.get('rev'))
1473 revs = scmutil.revrange(repo, opts.get('rev'))
1474 elif follow:
1474 elif follow:
1475 revs = repo.revs('reverse(:.)')
1475 revs = repo.revs('reverse(:.)')
1476 else:
1476 else:
1477 revs = revset.spanset(repo)
1477 revs = revset.spanset(repo)
1478 revs.reverse()
1478 revs.reverse()
1479 if not revs:
1479 if not revs:
1480 return []
1480 return []
1481 wanted = set()
1481 wanted = set()
1482 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1482 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1483 fncache = {}
1483 fncache = {}
1484 change = repo.changectx
1484 change = repo.changectx
1485
1485
1486 # First step is to fill wanted, the set of revisions that we want to yield.
1486 # First step is to fill wanted, the set of revisions that we want to yield.
1487 # When it does not induce extra cost, we also fill fncache for revisions in
1487 # When it does not induce extra cost, we also fill fncache for revisions in
1488 # wanted: a cache of filenames that were changed (ctx.files()) and that
1488 # wanted: a cache of filenames that were changed (ctx.files()) and that
1489 # match the file filtering conditions.
1489 # match the file filtering conditions.
1490
1490
1491 if not slowpath and not match.files():
1491 if not slowpath and not match.files():
1492 # No files, no patterns. Display all revs.
1492 # No files, no patterns. Display all revs.
1493 wanted = revs
1493 wanted = revs
1494
1494
1495 if not slowpath and match.files():
1495 if not slowpath and match.files():
1496 # We only have to read through the filelog to find wanted revisions
1496 # We only have to read through the filelog to find wanted revisions
1497
1497
1498 try:
1498 try:
1499 wanted = walkfilerevs(repo, match, follow, revs, fncache)
1499 wanted = walkfilerevs(repo, match, follow, revs, fncache)
1500 except FileWalkError:
1500 except FileWalkError:
1501 slowpath = True
1501 slowpath = True
1502
1502
1503 # We decided to fall back to the slowpath because at least one
1503 # We decided to fall back to the slowpath because at least one
1504 # of the paths was not a file. Check to see if at least one of them
1504 # of the paths was not a file. Check to see if at least one of them
1505 # existed in history, otherwise simply return
1505 # existed in history, otherwise simply return
1506 for path in match.files():
1506 for path in match.files():
1507 if path == '.' or path in repo.store:
1507 if path == '.' or path in repo.store:
1508 break
1508 break
1509 else:
1509 else:
1510 return []
1510 return []
1511
1511
1512 if slowpath:
1512 if slowpath:
1513 # We have to read the changelog to match filenames against
1513 # We have to read the changelog to match filenames against
1514 # changed files
1514 # changed files
1515
1515
1516 if follow:
1516 if follow:
1517 raise util.Abort(_('can only follow copies/renames for explicit '
1517 raise util.Abort(_('can only follow copies/renames for explicit '
1518 'filenames'))
1518 'filenames'))
1519
1519
1520 # The slow path checks files modified in every changeset.
1520 # The slow path checks files modified in every changeset.
1521 # This is really slow on large repos, so compute the set lazily.
1521 # This is really slow on large repos, so compute the set lazily.
1522 class lazywantedset(object):
1522 class lazywantedset(object):
1523 def __init__(self):
1523 def __init__(self):
1524 self.set = set()
1524 self.set = set()
1525 self.revs = set(revs)
1525 self.revs = set(revs)
1526
1526
1527 # No need to worry about locality here because it will be accessed
1527 # No need to worry about locality here because it will be accessed
1528 # in the same order as the increasing window below.
1528 # in the same order as the increasing window below.
1529 def __contains__(self, value):
1529 def __contains__(self, value):
1530 if value in self.set:
1530 if value in self.set:
1531 return True
1531 return True
1532 elif not value in self.revs:
1532 elif not value in self.revs:
1533 return False
1533 return False
1534 else:
1534 else:
1535 self.revs.discard(value)
1535 self.revs.discard(value)
1536 ctx = change(value)
1536 ctx = change(value)
1537 matches = filter(match, ctx.files())
1537 matches = filter(match, ctx.files())
1538 if matches:
1538 if matches:
1539 fncache[value] = matches
1539 fncache[value] = matches
1540 self.set.add(value)
1540 self.set.add(value)
1541 return True
1541 return True
1542 return False
1542 return False
1543
1543
1544 def discard(self, value):
1544 def discard(self, value):
1545 self.revs.discard(value)
1545 self.revs.discard(value)
1546 self.set.discard(value)
1546 self.set.discard(value)
1547
1547
1548 wanted = lazywantedset()
1548 wanted = lazywantedset()
1549
1549
1550 class followfilter(object):
1550 class followfilter(object):
1551 def __init__(self, onlyfirst=False):
1551 def __init__(self, onlyfirst=False):
1552 self.startrev = nullrev
1552 self.startrev = nullrev
1553 self.roots = set()
1553 self.roots = set()
1554 self.onlyfirst = onlyfirst
1554 self.onlyfirst = onlyfirst
1555
1555
1556 def match(self, rev):
1556 def match(self, rev):
1557 def realparents(rev):
1557 def realparents(rev):
1558 if self.onlyfirst:
1558 if self.onlyfirst:
1559 return repo.changelog.parentrevs(rev)[0:1]
1559 return repo.changelog.parentrevs(rev)[0:1]
1560 else:
1560 else:
1561 return filter(lambda x: x != nullrev,
1561 return filter(lambda x: x != nullrev,
1562 repo.changelog.parentrevs(rev))
1562 repo.changelog.parentrevs(rev))
1563
1563
1564 if self.startrev == nullrev:
1564 if self.startrev == nullrev:
1565 self.startrev = rev
1565 self.startrev = rev
1566 return True
1566 return True
1567
1567
1568 if rev > self.startrev:
1568 if rev > self.startrev:
1569 # forward: all descendants
1569 # forward: all descendants
1570 if not self.roots:
1570 if not self.roots:
1571 self.roots.add(self.startrev)
1571 self.roots.add(self.startrev)
1572 for parent in realparents(rev):
1572 for parent in realparents(rev):
1573 if parent in self.roots:
1573 if parent in self.roots:
1574 self.roots.add(rev)
1574 self.roots.add(rev)
1575 return True
1575 return True
1576 else:
1576 else:
1577 # backwards: all parents
1577 # backwards: all parents
1578 if not self.roots:
1578 if not self.roots:
1579 self.roots.update(realparents(self.startrev))
1579 self.roots.update(realparents(self.startrev))
1580 if rev in self.roots:
1580 if rev in self.roots:
1581 self.roots.remove(rev)
1581 self.roots.remove(rev)
1582 self.roots.update(realparents(rev))
1582 self.roots.update(realparents(rev))
1583 return True
1583 return True
1584
1584
1585 return False
1585 return False
1586
1586
1587 # it might be worthwhile to do this in the iterator if the rev range
1587 # it might be worthwhile to do this in the iterator if the rev range
1588 # is descending and the prune args are all within that range
1588 # is descending and the prune args are all within that range
1589 for rev in opts.get('prune', ()):
1589 for rev in opts.get('prune', ()):
1590 rev = repo[rev].rev()
1590 rev = repo[rev].rev()
1591 ff = followfilter()
1591 ff = followfilter()
1592 stop = min(revs[0], revs[-1])
1592 stop = min(revs[0], revs[-1])
1593 for x in xrange(rev, stop - 1, -1):
1593 for x in xrange(rev, stop - 1, -1):
1594 if ff.match(x):
1594 if ff.match(x):
1595 wanted = wanted - [x]
1595 wanted = wanted - [x]
1596
1596
1597 # Now that wanted is correctly initialized, we can iterate over the
1597 # Now that wanted is correctly initialized, we can iterate over the
1598 # revision range, yielding only revisions in wanted.
1598 # revision range, yielding only revisions in wanted.
1599 def iterate():
1599 def iterate():
1600 if follow and not match.files():
1600 if follow and not match.files():
1601 ff = followfilter(onlyfirst=opts.get('follow_first'))
1601 ff = followfilter(onlyfirst=opts.get('follow_first'))
1602 def want(rev):
1602 def want(rev):
1603 return ff.match(rev) and rev in wanted
1603 return ff.match(rev) and rev in wanted
1604 else:
1604 else:
1605 def want(rev):
1605 def want(rev):
1606 return rev in wanted
1606 return rev in wanted
1607
1607
1608 it = iter(revs)
1608 it = iter(revs)
1609 stopiteration = False
1609 stopiteration = False
1610 for windowsize in increasingwindows():
1610 for windowsize in increasingwindows():
1611 nrevs = []
1611 nrevs = []
1612 for i in xrange(windowsize):
1612 for i in xrange(windowsize):
1613 try:
1613 try:
1614 rev = it.next()
1614 rev = it.next()
1615 if want(rev):
1615 if want(rev):
1616 nrevs.append(rev)
1616 nrevs.append(rev)
1617 except (StopIteration):
1617 except (StopIteration):
1618 stopiteration = True
1618 stopiteration = True
1619 break
1619 break
1620 for rev in sorted(nrevs):
1620 for rev in sorted(nrevs):
1621 fns = fncache.get(rev)
1621 fns = fncache.get(rev)
1622 ctx = change(rev)
1622 ctx = change(rev)
1623 if not fns:
1623 if not fns:
1624 def fns_generator():
1624 def fns_generator():
1625 for f in ctx.files():
1625 for f in ctx.files():
1626 if match(f):
1626 if match(f):
1627 yield f
1627 yield f
1628 fns = fns_generator()
1628 fns = fns_generator()
1629 prepare(ctx, fns)
1629 prepare(ctx, fns)
1630 for rev in nrevs:
1630 for rev in nrevs:
1631 yield change(rev)
1631 yield change(rev)
1632
1632
1633 if stopiteration:
1633 if stopiteration:
1634 break
1634 break
1635
1635
1636 return iterate()
1636 return iterate()
1637
1637
1638 def _makefollowlogfilematcher(repo, files, followfirst):
1638 def _makefollowlogfilematcher(repo, files, followfirst):
1639 # When displaying a revision with --patch --follow FILE, we have
1639 # When displaying a revision with --patch --follow FILE, we have
1640 # to know which file of the revision must be diffed. With
1640 # to know which file of the revision must be diffed. With
1641 # --follow, we want the names of the ancestors of FILE in the
1641 # --follow, we want the names of the ancestors of FILE in the
1642 # revision, stored in "fcache". "fcache" is populated by
1642 # revision, stored in "fcache". "fcache" is populated by
1643 # reproducing the graph traversal already done by --follow revset
1643 # reproducing the graph traversal already done by --follow revset
1644 # and relating linkrevs to file names (which is not "correct" but
1644 # and relating linkrevs to file names (which is not "correct" but
1645 # good enough).
1645 # good enough).
1646 fcache = {}
1646 fcache = {}
1647 fcacheready = [False]
1647 fcacheready = [False]
1648 pctx = repo['.']
1648 pctx = repo['.']
1649
1649
1650 def populate():
1650 def populate():
1651 for fn in files:
1651 for fn in files:
1652 for i in ((pctx[fn],), pctx[fn].ancestors(followfirst=followfirst)):
1652 for i in ((pctx[fn],), pctx[fn].ancestors(followfirst=followfirst)):
1653 for c in i:
1653 for c in i:
1654 fcache.setdefault(c.linkrev(), set()).add(c.path())
1654 fcache.setdefault(c.linkrev(), set()).add(c.path())
1655
1655
1656 def filematcher(rev):
1656 def filematcher(rev):
1657 if not fcacheready[0]:
1657 if not fcacheready[0]:
1658 # Lazy initialization
1658 # Lazy initialization
1659 fcacheready[0] = True
1659 fcacheready[0] = True
1660 populate()
1660 populate()
1661 return scmutil.matchfiles(repo, fcache.get(rev, []))
1661 return scmutil.matchfiles(repo, fcache.get(rev, []))
1662
1662
1663 return filematcher
1663 return filematcher
1664
1664
1665 def _makenofollowlogfilematcher(repo, pats, opts):
1665 def _makenofollowlogfilematcher(repo, pats, opts):
1666 '''hook for extensions to override the filematcher for non-follow cases'''
1666 '''hook for extensions to override the filematcher for non-follow cases'''
1667 return None
1667 return None
1668
1668
1669 def _makelogrevset(repo, pats, opts, revs):
1669 def _makelogrevset(repo, pats, opts, revs):
1670 """Return (expr, filematcher) where expr is a revset string built
1670 """Return (expr, filematcher) where expr is a revset string built
1671 from log options and file patterns or None. If --stat or --patch
1671 from log options and file patterns or None. If --stat or --patch
1672 are not passed filematcher is None. Otherwise it is a callable
1672 are not passed filematcher is None. Otherwise it is a callable
1673 taking a revision number and returning a match objects filtering
1673 taking a revision number and returning a match objects filtering
1674 the files to be detailed when displaying the revision.
1674 the files to be detailed when displaying the revision.
1675 """
1675 """
1676 opt2revset = {
1676 opt2revset = {
1677 'no_merges': ('not merge()', None),
1677 'no_merges': ('not merge()', None),
1678 'only_merges': ('merge()', None),
1678 'only_merges': ('merge()', None),
1679 '_ancestors': ('ancestors(%(val)s)', None),
1679 '_ancestors': ('ancestors(%(val)s)', None),
1680 '_fancestors': ('_firstancestors(%(val)s)', None),
1680 '_fancestors': ('_firstancestors(%(val)s)', None),
1681 '_descendants': ('descendants(%(val)s)', None),
1681 '_descendants': ('descendants(%(val)s)', None),
1682 '_fdescendants': ('_firstdescendants(%(val)s)', None),
1682 '_fdescendants': ('_firstdescendants(%(val)s)', None),
1683 '_matchfiles': ('_matchfiles(%(val)s)', None),
1683 '_matchfiles': ('_matchfiles(%(val)s)', None),
1684 'date': ('date(%(val)r)', None),
1684 'date': ('date(%(val)r)', None),
1685 'branch': ('branch(%(val)r)', ' or '),
1685 'branch': ('branch(%(val)r)', ' or '),
1686 '_patslog': ('filelog(%(val)r)', ' or '),
1686 '_patslog': ('filelog(%(val)r)', ' or '),
1687 '_patsfollow': ('follow(%(val)r)', ' or '),
1687 '_patsfollow': ('follow(%(val)r)', ' or '),
1688 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
1688 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
1689 'keyword': ('keyword(%(val)r)', ' or '),
1689 'keyword': ('keyword(%(val)r)', ' or '),
1690 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
1690 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
1691 'user': ('user(%(val)r)', ' or '),
1691 'user': ('user(%(val)r)', ' or '),
1692 }
1692 }
1693
1693
1694 opts = dict(opts)
1694 opts = dict(opts)
1695 # follow or not follow?
1695 # follow or not follow?
1696 follow = opts.get('follow') or opts.get('follow_first')
1696 follow = opts.get('follow') or opts.get('follow_first')
1697 followfirst = opts.get('follow_first') and 1 or 0
1697 followfirst = opts.get('follow_first') and 1 or 0
1698 # --follow with FILE behaviour depends on revs...
1698 # --follow with FILE behaviour depends on revs...
1699 it = iter(revs)
1699 it = iter(revs)
1700 startrev = it.next()
1700 startrev = it.next()
1701 try:
1701 try:
1702 followdescendants = startrev < it.next()
1702 followdescendants = startrev < it.next()
1703 except (StopIteration):
1703 except (StopIteration):
1704 followdescendants = False
1704 followdescendants = False
1705
1705
1706 # branch and only_branch are really aliases and must be handled at
1706 # branch and only_branch are really aliases and must be handled at
1707 # the same time
1707 # the same time
1708 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', [])
1708 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', [])
1709 opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']]
1709 opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']]
1710 # pats/include/exclude are passed to match.match() directly in
1710 # pats/include/exclude are passed to match.match() directly in
1711 # _matchfiles() revset but walkchangerevs() builds its matcher with
1711 # _matchfiles() revset but walkchangerevs() builds its matcher with
1712 # scmutil.match(). The difference is input pats are globbed on
1712 # scmutil.match(). The difference is input pats are globbed on
1713 # platforms without shell expansion (windows).
1713 # platforms without shell expansion (windows).
1714 pctx = repo[None]
1714 pctx = repo[None]
1715 match, pats = scmutil.matchandpats(pctx, pats, opts)
1715 match, pats = scmutil.matchandpats(pctx, pats, opts)
1716 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1716 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1717 if not slowpath:
1717 if not slowpath:
1718 for f in match.files():
1718 for f in match.files():
1719 if follow and f not in pctx:
1719 if follow and f not in pctx:
1720 # If the file exists, it may be a directory, so let it
1720 # If the file exists, it may be a directory, so let it
1721 # take the slow path.
1721 # take the slow path.
1722 if os.path.exists(repo.wjoin(f)):
1722 if os.path.exists(repo.wjoin(f)):
1723 slowpath = True
1723 slowpath = True
1724 continue
1724 continue
1725 else:
1725 else:
1726 raise util.Abort(_('cannot follow file not in parent '
1726 raise util.Abort(_('cannot follow file not in parent '
1727 'revision: "%s"') % f)
1727 'revision: "%s"') % f)
1728 filelog = repo.file(f)
1728 filelog = repo.file(f)
1729 if not filelog:
1729 if not filelog:
1730 # A zero count may be a directory or deleted file, so
1730 # A zero count may be a directory or deleted file, so
1731 # try to find matching entries on the slow path.
1731 # try to find matching entries on the slow path.
1732 if follow:
1732 if follow:
1733 raise util.Abort(
1733 raise util.Abort(
1734 _('cannot follow nonexistent file: "%s"') % f)
1734 _('cannot follow nonexistent file: "%s"') % f)
1735 slowpath = True
1735 slowpath = True
1736
1736
1737 # We decided to fall back to the slowpath because at least one
1737 # We decided to fall back to the slowpath because at least one
1738 # of the paths was not a file. Check to see if at least one of them
1738 # of the paths was not a file. Check to see if at least one of them
1739 # existed in history - in that case, we'll continue down the
1739 # existed in history - in that case, we'll continue down the
1740 # slowpath; otherwise, we can turn off the slowpath
1740 # slowpath; otherwise, we can turn off the slowpath
1741 if slowpath:
1741 if slowpath:
1742 for path in match.files():
1742 for path in match.files():
1743 if path == '.' or path in repo.store:
1743 if path == '.' or path in repo.store:
1744 break
1744 break
1745 else:
1745 else:
1746 slowpath = False
1746 slowpath = False
1747
1747
1748 fpats = ('_patsfollow', '_patsfollowfirst')
1749 fnopats = (('_ancestors', '_fancestors'),
1750 ('_descendants', '_fdescendants'))
1748 if slowpath:
1751 if slowpath:
1749 # See walkchangerevs() slow path.
1752 # See walkchangerevs() slow path.
1750 #
1753 #
1751 # pats/include/exclude cannot be represented as separate
1754 # pats/include/exclude cannot be represented as separate
1752 # revset expressions as their filtering logic applies at file
1755 # revset expressions as their filtering logic applies at file
1753 # level. For instance "-I a -X a" matches a revision touching
1756 # level. For instance "-I a -X a" matches a revision touching
1754 # "a" and "b" while "file(a) and not file(b)" does
1757 # "a" and "b" while "file(a) and not file(b)" does
1755 # not. Besides, filesets are evaluated against the working
1758 # not. Besides, filesets are evaluated against the working
1756 # directory.
1759 # directory.
1757 matchargs = ['r:', 'd:relpath']
1760 matchargs = ['r:', 'd:relpath']
1758 for p in pats:
1761 for p in pats:
1759 matchargs.append('p:' + p)
1762 matchargs.append('p:' + p)
1760 for p in opts.get('include', []):
1763 for p in opts.get('include', []):
1761 matchargs.append('i:' + p)
1764 matchargs.append('i:' + p)
1762 for p in opts.get('exclude', []):
1765 for p in opts.get('exclude', []):
1763 matchargs.append('x:' + p)
1766 matchargs.append('x:' + p)
1764 matchargs = ','.join(('%r' % p) for p in matchargs)
1767 matchargs = ','.join(('%r' % p) for p in matchargs)
1765 opts['_matchfiles'] = matchargs
1768 opts['_matchfiles'] = matchargs
1769 if follow:
1770 opts[fnopats[0][followfirst]] = '.'
1766 else:
1771 else:
1767 if follow:
1772 if follow:
1768 fpats = ('_patsfollow', '_patsfollowfirst')
1769 fnopats = (('_ancestors', '_fancestors'),
1770 ('_descendants', '_fdescendants'))
1771 if pats:
1773 if pats:
1772 # follow() revset interprets its file argument as a
1774 # follow() revset interprets its file argument as a
1773 # manifest entry, so use match.files(), not pats.
1775 # manifest entry, so use match.files(), not pats.
1774 opts[fpats[followfirst]] = list(match.files())
1776 opts[fpats[followfirst]] = list(match.files())
1775 else:
1777 else:
1776 opts[fnopats[followdescendants][followfirst]] = str(startrev)
1778 opts[fnopats[followdescendants][followfirst]] = str(startrev)
1777 else:
1779 else:
1778 opts['_patslog'] = list(pats)
1780 opts['_patslog'] = list(pats)
1779
1781
1780 filematcher = None
1782 filematcher = None
1781 if opts.get('patch') or opts.get('stat'):
1783 if opts.get('patch') or opts.get('stat'):
1782 # When following files, track renames via a special matcher.
1784 # When following files, track renames via a special matcher.
1783 # If we're forced to take the slowpath it means we're following
1785 # If we're forced to take the slowpath it means we're following
1784 # at least one pattern/directory, so don't bother with rename tracking.
1786 # at least one pattern/directory, so don't bother with rename tracking.
1785 if follow and not match.always() and not slowpath:
1787 if follow and not match.always() and not slowpath:
1786 # _makelogfilematcher expects its files argument to be relative to
1788 # _makelogfilematcher expects its files argument to be relative to
1787 # the repo root, so use match.files(), not pats.
1789 # the repo root, so use match.files(), not pats.
1788 filematcher = _makefollowlogfilematcher(repo, match.files(),
1790 filematcher = _makefollowlogfilematcher(repo, match.files(),
1789 followfirst)
1791 followfirst)
1790 else:
1792 else:
1791 filematcher = _makenofollowlogfilematcher(repo, pats, opts)
1793 filematcher = _makenofollowlogfilematcher(repo, pats, opts)
1792 if filematcher is None:
1794 if filematcher is None:
1793 filematcher = lambda rev: match
1795 filematcher = lambda rev: match
1794
1796
1795 expr = []
1797 expr = []
1796 for op, val in opts.iteritems():
1798 for op, val in opts.iteritems():
1797 if not val:
1799 if not val:
1798 continue
1800 continue
1799 if op not in opt2revset:
1801 if op not in opt2revset:
1800 continue
1802 continue
1801 revop, andor = opt2revset[op]
1803 revop, andor = opt2revset[op]
1802 if '%(val)' not in revop:
1804 if '%(val)' not in revop:
1803 expr.append(revop)
1805 expr.append(revop)
1804 else:
1806 else:
1805 if not isinstance(val, list):
1807 if not isinstance(val, list):
1806 e = revop % {'val': val}
1808 e = revop % {'val': val}
1807 else:
1809 else:
1808 e = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
1810 e = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
1809 expr.append(e)
1811 expr.append(e)
1810
1812
1811 if expr:
1813 if expr:
1812 expr = '(' + ' and '.join(expr) + ')'
1814 expr = '(' + ' and '.join(expr) + ')'
1813 else:
1815 else:
1814 expr = None
1816 expr = None
1815 return expr, filematcher
1817 return expr, filematcher
1816
1818
1817 def getgraphlogrevs(repo, pats, opts):
1819 def getgraphlogrevs(repo, pats, opts):
1818 """Return (revs, expr, filematcher) where revs is an iterable of
1820 """Return (revs, expr, filematcher) where revs is an iterable of
1819 revision numbers, expr is a revset string built from log options
1821 revision numbers, expr is a revset string built from log options
1820 and file patterns or None, and used to filter 'revs'. If --stat or
1822 and file patterns or None, and used to filter 'revs'. If --stat or
1821 --patch are not passed filematcher is None. Otherwise it is a
1823 --patch are not passed filematcher is None. Otherwise it is a
1822 callable taking a revision number and returning a match objects
1824 callable taking a revision number and returning a match objects
1823 filtering the files to be detailed when displaying the revision.
1825 filtering the files to be detailed when displaying the revision.
1824 """
1826 """
1825 if not len(repo):
1827 if not len(repo):
1826 return [], None, None
1828 return [], None, None
1827 limit = loglimit(opts)
1829 limit = loglimit(opts)
1828 # Default --rev value depends on --follow but --follow behaviour
1830 # Default --rev value depends on --follow but --follow behaviour
1829 # depends on revisions resolved from --rev...
1831 # depends on revisions resolved from --rev...
1830 follow = opts.get('follow') or opts.get('follow_first')
1832 follow = opts.get('follow') or opts.get('follow_first')
1831 possiblyunsorted = False # whether revs might need sorting
1833 possiblyunsorted = False # whether revs might need sorting
1832 if opts.get('rev'):
1834 if opts.get('rev'):
1833 revs = scmutil.revrange(repo, opts['rev'])
1835 revs = scmutil.revrange(repo, opts['rev'])
1834 # Don't sort here because _makelogrevset might depend on the
1836 # Don't sort here because _makelogrevset might depend on the
1835 # order of revs
1837 # order of revs
1836 possiblyunsorted = True
1838 possiblyunsorted = True
1837 else:
1839 else:
1838 if follow and len(repo) > 0:
1840 if follow and len(repo) > 0:
1839 revs = repo.revs('reverse(:.)')
1841 revs = repo.revs('reverse(:.)')
1840 else:
1842 else:
1841 revs = revset.spanset(repo)
1843 revs = revset.spanset(repo)
1842 revs.reverse()
1844 revs.reverse()
1843 if not revs:
1845 if not revs:
1844 return revset.baseset(), None, None
1846 return revset.baseset(), None, None
1845 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1847 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1846 if possiblyunsorted:
1848 if possiblyunsorted:
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 # Default --rev value depends on --follow but --follow behaviour
1879 # Default --rev value depends on --follow but --follow behaviour
1878 # depends on revisions resolved from --rev...
1880 # depends on revisions resolved from --rev...
1879 follow = opts.get('follow') or opts.get('follow_first')
1881 follow = opts.get('follow') or opts.get('follow_first')
1880 if opts.get('rev'):
1882 if opts.get('rev'):
1881 revs = scmutil.revrange(repo, opts['rev'])
1883 revs = scmutil.revrange(repo, opts['rev'])
1882 elif follow:
1884 elif follow:
1883 revs = repo.revs('reverse(:.)')
1885 revs = repo.revs('reverse(:.)')
1884 else:
1886 else:
1885 revs = revset.spanset(repo)
1887 revs = revset.spanset(repo)
1886 revs.reverse()
1888 revs.reverse()
1887 if not revs:
1889 if not revs:
1888 return revset.baseset([]), None, None
1890 return revset.baseset([]), None, None
1889 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1891 expr, filematcher = _makelogrevset(repo, pats, opts, revs)
1890 if expr:
1892 if expr:
1891 # Revset matchers often operate faster on revisions in changelog
1893 # Revset matchers often operate faster on revisions in changelog
1892 # order, because most filters deal with the changelog.
1894 # order, because most filters deal with the changelog.
1893 if not opts.get('rev'):
1895 if not opts.get('rev'):
1894 revs.reverse()
1896 revs.reverse()
1895 matcher = revset.match(repo.ui, expr)
1897 matcher = revset.match(repo.ui, expr)
1896 # Revset matches can reorder revisions. "A or B" typically returns
1898 # Revset matches can reorder revisions. "A or B" typically returns
1897 # returns the revision matching A then the revision matching B. Sort
1899 # returns the revision matching A then the revision matching B. Sort
1898 # again to fix that.
1900 # again to fix that.
1899 revs = matcher(repo, revs)
1901 revs = matcher(repo, revs)
1900 if not opts.get('rev'):
1902 if not opts.get('rev'):
1901 revs.sort(reverse=True)
1903 revs.sort(reverse=True)
1902 if limit is not None:
1904 if limit is not None:
1903 count = 0
1905 count = 0
1904 limitedrevs = []
1906 limitedrevs = []
1905 it = iter(revs)
1907 it = iter(revs)
1906 while count < limit:
1908 while count < limit:
1907 try:
1909 try:
1908 limitedrevs.append(it.next())
1910 limitedrevs.append(it.next())
1909 except (StopIteration):
1911 except (StopIteration):
1910 break
1912 break
1911 count += 1
1913 count += 1
1912 revs = revset.baseset(limitedrevs)
1914 revs = revset.baseset(limitedrevs)
1913
1915
1914 return revs, expr, filematcher
1916 return revs, expr, filematcher
1915
1917
1916 def displaygraph(ui, dag, displayer, showparents, edgefn, getrenamed=None,
1918 def displaygraph(ui, dag, displayer, showparents, edgefn, getrenamed=None,
1917 filematcher=None):
1919 filematcher=None):
1918 seen, state = [], graphmod.asciistate()
1920 seen, state = [], graphmod.asciistate()
1919 for rev, type, ctx, parents in dag:
1921 for rev, type, ctx, parents in dag:
1920 char = 'o'
1922 char = 'o'
1921 if ctx.node() in showparents:
1923 if ctx.node() in showparents:
1922 char = '@'
1924 char = '@'
1923 elif ctx.obsolete():
1925 elif ctx.obsolete():
1924 char = 'x'
1926 char = 'x'
1925 copies = None
1927 copies = None
1926 if getrenamed and ctx.rev():
1928 if getrenamed and ctx.rev():
1927 copies = []
1929 copies = []
1928 for fn in ctx.files():
1930 for fn in ctx.files():
1929 rename = getrenamed(fn, ctx.rev())
1931 rename = getrenamed(fn, ctx.rev())
1930 if rename:
1932 if rename:
1931 copies.append((fn, rename[0]))
1933 copies.append((fn, rename[0]))
1932 revmatchfn = None
1934 revmatchfn = None
1933 if filematcher is not None:
1935 if filematcher is not None:
1934 revmatchfn = filematcher(ctx.rev())
1936 revmatchfn = filematcher(ctx.rev())
1935 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
1937 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
1936 lines = displayer.hunk.pop(rev).split('\n')
1938 lines = displayer.hunk.pop(rev).split('\n')
1937 if not lines[-1]:
1939 if not lines[-1]:
1938 del lines[-1]
1940 del lines[-1]
1939 displayer.flush(rev)
1941 displayer.flush(rev)
1940 edges = edgefn(type, char, lines, seen, rev, parents)
1942 edges = edgefn(type, char, lines, seen, rev, parents)
1941 for type, char, lines, coldata in edges:
1943 for type, char, lines, coldata in edges:
1942 graphmod.ascii(ui, state, type, char, lines, coldata)
1944 graphmod.ascii(ui, state, type, char, lines, coldata)
1943 displayer.close()
1945 displayer.close()
1944
1946
1945 def graphlog(ui, repo, *pats, **opts):
1947 def graphlog(ui, repo, *pats, **opts):
1946 # Parameters are identical to log command ones
1948 # Parameters are identical to log command ones
1947 revs, expr, filematcher = getgraphlogrevs(repo, pats, opts)
1949 revs, expr, filematcher = getgraphlogrevs(repo, pats, opts)
1948 revdag = graphmod.dagwalker(repo, revs)
1950 revdag = graphmod.dagwalker(repo, revs)
1949
1951
1950 getrenamed = None
1952 getrenamed = None
1951 if opts.get('copies'):
1953 if opts.get('copies'):
1952 endrev = None
1954 endrev = None
1953 if opts.get('rev'):
1955 if opts.get('rev'):
1954 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
1956 endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1
1955 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
1957 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
1956 displayer = show_changeset(ui, repo, opts, buffered=True)
1958 displayer = show_changeset(ui, repo, opts, buffered=True)
1957 showparents = [ctx.node() for ctx in repo[None].parents()]
1959 showparents = [ctx.node() for ctx in repo[None].parents()]
1958 displaygraph(ui, revdag, displayer, showparents,
1960 displaygraph(ui, revdag, displayer, showparents,
1959 graphmod.asciiedges, getrenamed, filematcher)
1961 graphmod.asciiedges, getrenamed, filematcher)
1960
1962
1961 def checkunsupportedgraphflags(pats, opts):
1963 def checkunsupportedgraphflags(pats, opts):
1962 for op in ["newest_first"]:
1964 for op in ["newest_first"]:
1963 if op in opts and opts[op]:
1965 if op in opts and opts[op]:
1964 raise util.Abort(_("-G/--graph option is incompatible with --%s")
1966 raise util.Abort(_("-G/--graph option is incompatible with --%s")
1965 % op.replace("_", "-"))
1967 % op.replace("_", "-"))
1966
1968
1967 def graphrevs(repo, nodes, opts):
1969 def graphrevs(repo, nodes, opts):
1968 limit = loglimit(opts)
1970 limit = loglimit(opts)
1969 nodes.reverse()
1971 nodes.reverse()
1970 if limit is not None:
1972 if limit is not None:
1971 nodes = nodes[:limit]
1973 nodes = nodes[:limit]
1972 return graphmod.nodes(repo, nodes)
1974 return graphmod.nodes(repo, nodes)
1973
1975
1974 def add(ui, repo, match, dryrun, listsubrepos, prefix, explicitonly):
1976 def add(ui, repo, match, dryrun, listsubrepos, prefix, explicitonly):
1975 join = lambda f: os.path.join(prefix, f)
1977 join = lambda f: os.path.join(prefix, f)
1976 bad = []
1978 bad = []
1977 oldbad = match.bad
1979 oldbad = match.bad
1978 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1980 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1979 names = []
1981 names = []
1980 wctx = repo[None]
1982 wctx = repo[None]
1981 cca = None
1983 cca = None
1982 abort, warn = scmutil.checkportabilityalert(ui)
1984 abort, warn = scmutil.checkportabilityalert(ui)
1983 if abort or warn:
1985 if abort or warn:
1984 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
1986 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
1985 for f in repo.walk(match):
1987 for f in repo.walk(match):
1986 exact = match.exact(f)
1988 exact = match.exact(f)
1987 if exact or not explicitonly and f not in repo.dirstate:
1989 if exact or not explicitonly and f not in repo.dirstate:
1988 if cca:
1990 if cca:
1989 cca(f)
1991 cca(f)
1990 names.append(f)
1992 names.append(f)
1991 if ui.verbose or not exact:
1993 if ui.verbose or not exact:
1992 ui.status(_('adding %s\n') % match.rel(join(f)))
1994 ui.status(_('adding %s\n') % match.rel(join(f)))
1993
1995
1994 for subpath in sorted(wctx.substate):
1996 for subpath in sorted(wctx.substate):
1995 sub = wctx.sub(subpath)
1997 sub = wctx.sub(subpath)
1996 try:
1998 try:
1997 submatch = matchmod.narrowmatcher(subpath, match)
1999 submatch = matchmod.narrowmatcher(subpath, match)
1998 if listsubrepos:
2000 if listsubrepos:
1999 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
2001 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
2000 False))
2002 False))
2001 else:
2003 else:
2002 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
2004 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
2003 True))
2005 True))
2004 except error.LookupError:
2006 except error.LookupError:
2005 ui.status(_("skipping missing subrepository: %s\n")
2007 ui.status(_("skipping missing subrepository: %s\n")
2006 % join(subpath))
2008 % join(subpath))
2007
2009
2008 if not dryrun:
2010 if not dryrun:
2009 rejected = wctx.add(names, prefix)
2011 rejected = wctx.add(names, prefix)
2010 bad.extend(f for f in rejected if f in match.files())
2012 bad.extend(f for f in rejected if f in match.files())
2011 return bad
2013 return bad
2012
2014
2013 def forget(ui, repo, match, prefix, explicitonly):
2015 def forget(ui, repo, match, prefix, explicitonly):
2014 join = lambda f: os.path.join(prefix, f)
2016 join = lambda f: os.path.join(prefix, f)
2015 bad = []
2017 bad = []
2016 oldbad = match.bad
2018 oldbad = match.bad
2017 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
2019 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
2018 wctx = repo[None]
2020 wctx = repo[None]
2019 forgot = []
2021 forgot = []
2020 s = repo.status(match=match, clean=True)
2022 s = repo.status(match=match, clean=True)
2021 forget = sorted(s[0] + s[1] + s[3] + s[6])
2023 forget = sorted(s[0] + s[1] + s[3] + s[6])
2022 if explicitonly:
2024 if explicitonly:
2023 forget = [f for f in forget if match.exact(f)]
2025 forget = [f for f in forget if match.exact(f)]
2024
2026
2025 for subpath in sorted(wctx.substate):
2027 for subpath in sorted(wctx.substate):
2026 sub = wctx.sub(subpath)
2028 sub = wctx.sub(subpath)
2027 try:
2029 try:
2028 submatch = matchmod.narrowmatcher(subpath, match)
2030 submatch = matchmod.narrowmatcher(subpath, match)
2029 subbad, subforgot = sub.forget(ui, submatch, prefix)
2031 subbad, subforgot = sub.forget(ui, submatch, prefix)
2030 bad.extend([subpath + '/' + f for f in subbad])
2032 bad.extend([subpath + '/' + f for f in subbad])
2031 forgot.extend([subpath + '/' + f for f in subforgot])
2033 forgot.extend([subpath + '/' + f for f in subforgot])
2032 except error.LookupError:
2034 except error.LookupError:
2033 ui.status(_("skipping missing subrepository: %s\n")
2035 ui.status(_("skipping missing subrepository: %s\n")
2034 % join(subpath))
2036 % join(subpath))
2035
2037
2036 if not explicitonly:
2038 if not explicitonly:
2037 for f in match.files():
2039 for f in match.files():
2038 if f not in repo.dirstate and not os.path.isdir(match.rel(join(f))):
2040 if f not in repo.dirstate and not os.path.isdir(match.rel(join(f))):
2039 if f not in forgot:
2041 if f not in forgot:
2040 if os.path.exists(match.rel(join(f))):
2042 if os.path.exists(match.rel(join(f))):
2041 ui.warn(_('not removing %s: '
2043 ui.warn(_('not removing %s: '
2042 'file is already untracked\n')
2044 'file is already untracked\n')
2043 % match.rel(join(f)))
2045 % match.rel(join(f)))
2044 bad.append(f)
2046 bad.append(f)
2045
2047
2046 for f in forget:
2048 for f in forget:
2047 if ui.verbose or not match.exact(f):
2049 if ui.verbose or not match.exact(f):
2048 ui.status(_('removing %s\n') % match.rel(join(f)))
2050 ui.status(_('removing %s\n') % match.rel(join(f)))
2049
2051
2050 rejected = wctx.forget(forget, prefix)
2052 rejected = wctx.forget(forget, prefix)
2051 bad.extend(f for f in rejected if f in match.files())
2053 bad.extend(f for f in rejected if f in match.files())
2052 forgot.extend(forget)
2054 forgot.extend(forget)
2053 return bad, forgot
2055 return bad, forgot
2054
2056
2055 def cat(ui, repo, ctx, matcher, prefix, **opts):
2057 def cat(ui, repo, ctx, matcher, prefix, **opts):
2056 err = 1
2058 err = 1
2057
2059
2058 def write(path):
2060 def write(path):
2059 fp = makefileobj(repo, opts.get('output'), ctx.node(),
2061 fp = makefileobj(repo, opts.get('output'), ctx.node(),
2060 pathname=os.path.join(prefix, path))
2062 pathname=os.path.join(prefix, path))
2061 data = ctx[path].data()
2063 data = ctx[path].data()
2062 if opts.get('decode'):
2064 if opts.get('decode'):
2063 data = repo.wwritedata(path, data)
2065 data = repo.wwritedata(path, data)
2064 fp.write(data)
2066 fp.write(data)
2065 fp.close()
2067 fp.close()
2066
2068
2067 # Automation often uses hg cat on single files, so special case it
2069 # Automation often uses hg cat on single files, so special case it
2068 # for performance to avoid the cost of parsing the manifest.
2070 # for performance to avoid the cost of parsing the manifest.
2069 if len(matcher.files()) == 1 and not matcher.anypats():
2071 if len(matcher.files()) == 1 and not matcher.anypats():
2070 file = matcher.files()[0]
2072 file = matcher.files()[0]
2071 mf = repo.manifest
2073 mf = repo.manifest
2072 mfnode = ctx._changeset[0]
2074 mfnode = ctx._changeset[0]
2073 if mf.find(mfnode, file)[0]:
2075 if mf.find(mfnode, file)[0]:
2074 write(file)
2076 write(file)
2075 return 0
2077 return 0
2076
2078
2077 # Don't warn about "missing" files that are really in subrepos
2079 # Don't warn about "missing" files that are really in subrepos
2078 bad = matcher.bad
2080 bad = matcher.bad
2079
2081
2080 def badfn(path, msg):
2082 def badfn(path, msg):
2081 for subpath in ctx.substate:
2083 for subpath in ctx.substate:
2082 if path.startswith(subpath):
2084 if path.startswith(subpath):
2083 return
2085 return
2084 bad(path, msg)
2086 bad(path, msg)
2085
2087
2086 matcher.bad = badfn
2088 matcher.bad = badfn
2087
2089
2088 for abs in ctx.walk(matcher):
2090 for abs in ctx.walk(matcher):
2089 write(abs)
2091 write(abs)
2090 err = 0
2092 err = 0
2091
2093
2092 matcher.bad = bad
2094 matcher.bad = bad
2093
2095
2094 for subpath in sorted(ctx.substate):
2096 for subpath in sorted(ctx.substate):
2095 sub = ctx.sub(subpath)
2097 sub = ctx.sub(subpath)
2096 try:
2098 try:
2097 submatch = matchmod.narrowmatcher(subpath, matcher)
2099 submatch = matchmod.narrowmatcher(subpath, matcher)
2098
2100
2099 if not sub.cat(ui, submatch, os.path.join(prefix, sub._path),
2101 if not sub.cat(ui, submatch, os.path.join(prefix, sub._path),
2100 **opts):
2102 **opts):
2101 err = 0
2103 err = 0
2102 except error.RepoLookupError:
2104 except error.RepoLookupError:
2103 ui.status(_("skipping missing subrepository: %s\n")
2105 ui.status(_("skipping missing subrepository: %s\n")
2104 % os.path.join(prefix, subpath))
2106 % os.path.join(prefix, subpath))
2105
2107
2106 return err
2108 return err
2107
2109
2108 def commit(ui, repo, commitfunc, pats, opts):
2110 def commit(ui, repo, commitfunc, pats, opts):
2109 '''commit the specified files or all outstanding changes'''
2111 '''commit the specified files or all outstanding changes'''
2110 date = opts.get('date')
2112 date = opts.get('date')
2111 if date:
2113 if date:
2112 opts['date'] = util.parsedate(date)
2114 opts['date'] = util.parsedate(date)
2113 message = logmessage(ui, opts)
2115 message = logmessage(ui, opts)
2114
2116
2115 # extract addremove carefully -- this function can be called from a command
2117 # extract addremove carefully -- this function can be called from a command
2116 # that doesn't support addremove
2118 # that doesn't support addremove
2117 if opts.get('addremove'):
2119 if opts.get('addremove'):
2118 scmutil.addremove(repo, pats, opts)
2120 scmutil.addremove(repo, pats, opts)
2119
2121
2120 return commitfunc(ui, repo, message,
2122 return commitfunc(ui, repo, message,
2121 scmutil.match(repo[None], pats, opts), opts)
2123 scmutil.match(repo[None], pats, opts), opts)
2122
2124
2123 def amend(ui, repo, commitfunc, old, extra, pats, opts):
2125 def amend(ui, repo, commitfunc, old, extra, pats, opts):
2124 # amend will reuse the existing user if not specified, but the obsolete
2126 # amend will reuse the existing user if not specified, but the obsolete
2125 # marker creation requires that the current user's name is specified.
2127 # marker creation requires that the current user's name is specified.
2126 if obsolete._enabled:
2128 if obsolete._enabled:
2127 ui.username() # raise exception if username not set
2129 ui.username() # raise exception if username not set
2128
2130
2129 ui.note(_('amending changeset %s\n') % old)
2131 ui.note(_('amending changeset %s\n') % old)
2130 base = old.p1()
2132 base = old.p1()
2131
2133
2132 wlock = lock = newid = None
2134 wlock = lock = newid = None
2133 try:
2135 try:
2134 wlock = repo.wlock()
2136 wlock = repo.wlock()
2135 lock = repo.lock()
2137 lock = repo.lock()
2136 tr = repo.transaction('amend')
2138 tr = repo.transaction('amend')
2137 try:
2139 try:
2138 # See if we got a message from -m or -l, if not, open the editor
2140 # See if we got a message from -m or -l, if not, open the editor
2139 # with the message of the changeset to amend
2141 # with the message of the changeset to amend
2140 message = logmessage(ui, opts)
2142 message = logmessage(ui, opts)
2141 # ensure logfile does not conflict with later enforcement of the
2143 # ensure logfile does not conflict with later enforcement of the
2142 # message. potential logfile content has been processed by
2144 # message. potential logfile content has been processed by
2143 # `logmessage` anyway.
2145 # `logmessage` anyway.
2144 opts.pop('logfile')
2146 opts.pop('logfile')
2145 # First, do a regular commit to record all changes in the working
2147 # First, do a regular commit to record all changes in the working
2146 # directory (if there are any)
2148 # directory (if there are any)
2147 ui.callhooks = False
2149 ui.callhooks = False
2148 currentbookmark = repo._bookmarkcurrent
2150 currentbookmark = repo._bookmarkcurrent
2149 try:
2151 try:
2150 repo._bookmarkcurrent = None
2152 repo._bookmarkcurrent = None
2151 opts['message'] = 'temporary amend commit for %s' % old
2153 opts['message'] = 'temporary amend commit for %s' % old
2152 node = commit(ui, repo, commitfunc, pats, opts)
2154 node = commit(ui, repo, commitfunc, pats, opts)
2153 finally:
2155 finally:
2154 repo._bookmarkcurrent = currentbookmark
2156 repo._bookmarkcurrent = currentbookmark
2155 ui.callhooks = True
2157 ui.callhooks = True
2156 ctx = repo[node]
2158 ctx = repo[node]
2157
2159
2158 # Participating changesets:
2160 # Participating changesets:
2159 #
2161 #
2160 # node/ctx o - new (intermediate) commit that contains changes
2162 # node/ctx o - new (intermediate) commit that contains changes
2161 # | from working dir to go into amending commit
2163 # | from working dir to go into amending commit
2162 # | (or a workingctx if there were no changes)
2164 # | (or a workingctx if there were no changes)
2163 # |
2165 # |
2164 # old o - changeset to amend
2166 # old o - changeset to amend
2165 # |
2167 # |
2166 # base o - parent of amending changeset
2168 # base o - parent of amending changeset
2167
2169
2168 # Update extra dict from amended commit (e.g. to preserve graft
2170 # Update extra dict from amended commit (e.g. to preserve graft
2169 # source)
2171 # source)
2170 extra.update(old.extra())
2172 extra.update(old.extra())
2171
2173
2172 # Also update it from the intermediate commit or from the wctx
2174 # Also update it from the intermediate commit or from the wctx
2173 extra.update(ctx.extra())
2175 extra.update(ctx.extra())
2174
2176
2175 if len(old.parents()) > 1:
2177 if len(old.parents()) > 1:
2176 # ctx.files() isn't reliable for merges, so fall back to the
2178 # ctx.files() isn't reliable for merges, so fall back to the
2177 # slower repo.status() method
2179 # slower repo.status() method
2178 files = set([fn for st in repo.status(base, old)[:3]
2180 files = set([fn for st in repo.status(base, old)[:3]
2179 for fn in st])
2181 for fn in st])
2180 else:
2182 else:
2181 files = set(old.files())
2183 files = set(old.files())
2182
2184
2183 # Second, we use either the commit we just did, or if there were no
2185 # Second, we use either the commit we just did, or if there were no
2184 # changes the parent of the working directory as the version of the
2186 # changes the parent of the working directory as the version of the
2185 # files in the final amend commit
2187 # files in the final amend commit
2186 if node:
2188 if node:
2187 ui.note(_('copying changeset %s to %s\n') % (ctx, base))
2189 ui.note(_('copying changeset %s to %s\n') % (ctx, base))
2188
2190
2189 user = ctx.user()
2191 user = ctx.user()
2190 date = ctx.date()
2192 date = ctx.date()
2191 # Recompute copies (avoid recording a -> b -> a)
2193 # Recompute copies (avoid recording a -> b -> a)
2192 copied = copies.pathcopies(base, ctx)
2194 copied = copies.pathcopies(base, ctx)
2193
2195
2194 # Prune files which were reverted by the updates: if old
2196 # Prune files which were reverted by the updates: if old
2195 # introduced file X and our intermediate commit, node,
2197 # introduced file X and our intermediate commit, node,
2196 # renamed that file, then those two files are the same and
2198 # renamed that file, then those two files are the same and
2197 # we can discard X from our list of files. Likewise if X
2199 # we can discard X from our list of files. Likewise if X
2198 # was deleted, it's no longer relevant
2200 # was deleted, it's no longer relevant
2199 files.update(ctx.files())
2201 files.update(ctx.files())
2200
2202
2201 def samefile(f):
2203 def samefile(f):
2202 if f in ctx.manifest():
2204 if f in ctx.manifest():
2203 a = ctx.filectx(f)
2205 a = ctx.filectx(f)
2204 if f in base.manifest():
2206 if f in base.manifest():
2205 b = base.filectx(f)
2207 b = base.filectx(f)
2206 return (not a.cmp(b)
2208 return (not a.cmp(b)
2207 and a.flags() == b.flags())
2209 and a.flags() == b.flags())
2208 else:
2210 else:
2209 return False
2211 return False
2210 else:
2212 else:
2211 return f not in base.manifest()
2213 return f not in base.manifest()
2212 files = [f for f in files if not samefile(f)]
2214 files = [f for f in files if not samefile(f)]
2213
2215
2214 def filectxfn(repo, ctx_, path):
2216 def filectxfn(repo, ctx_, path):
2215 try:
2217 try:
2216 fctx = ctx[path]
2218 fctx = ctx[path]
2217 flags = fctx.flags()
2219 flags = fctx.flags()
2218 mctx = context.memfilectx(repo,
2220 mctx = context.memfilectx(repo,
2219 fctx.path(), fctx.data(),
2221 fctx.path(), fctx.data(),
2220 islink='l' in flags,
2222 islink='l' in flags,
2221 isexec='x' in flags,
2223 isexec='x' in flags,
2222 copied=copied.get(path))
2224 copied=copied.get(path))
2223 return mctx
2225 return mctx
2224 except KeyError:
2226 except KeyError:
2225 return None
2227 return None
2226 else:
2228 else:
2227 ui.note(_('copying changeset %s to %s\n') % (old, base))
2229 ui.note(_('copying changeset %s to %s\n') % (old, base))
2228
2230
2229 # Use version of files as in the old cset
2231 # Use version of files as in the old cset
2230 def filectxfn(repo, ctx_, path):
2232 def filectxfn(repo, ctx_, path):
2231 try:
2233 try:
2232 return old.filectx(path)
2234 return old.filectx(path)
2233 except KeyError:
2235 except KeyError:
2234 return None
2236 return None
2235
2237
2236 user = opts.get('user') or old.user()
2238 user = opts.get('user') or old.user()
2237 date = opts.get('date') or old.date()
2239 date = opts.get('date') or old.date()
2238 editform = mergeeditform(old, 'commit.amend')
2240 editform = mergeeditform(old, 'commit.amend')
2239 editor = getcommiteditor(editform=editform, **opts)
2241 editor = getcommiteditor(editform=editform, **opts)
2240 if not message:
2242 if not message:
2241 editor = getcommiteditor(edit=True, editform=editform)
2243 editor = getcommiteditor(edit=True, editform=editform)
2242 message = old.description()
2244 message = old.description()
2243
2245
2244 pureextra = extra.copy()
2246 pureextra = extra.copy()
2245 extra['amend_source'] = old.hex()
2247 extra['amend_source'] = old.hex()
2246
2248
2247 new = context.memctx(repo,
2249 new = context.memctx(repo,
2248 parents=[base.node(), old.p2().node()],
2250 parents=[base.node(), old.p2().node()],
2249 text=message,
2251 text=message,
2250 files=files,
2252 files=files,
2251 filectxfn=filectxfn,
2253 filectxfn=filectxfn,
2252 user=user,
2254 user=user,
2253 date=date,
2255 date=date,
2254 extra=extra,
2256 extra=extra,
2255 editor=editor)
2257 editor=editor)
2256
2258
2257 newdesc = changelog.stripdesc(new.description())
2259 newdesc = changelog.stripdesc(new.description())
2258 if ((not node)
2260 if ((not node)
2259 and newdesc == old.description()
2261 and newdesc == old.description()
2260 and user == old.user()
2262 and user == old.user()
2261 and date == old.date()
2263 and date == old.date()
2262 and pureextra == old.extra()):
2264 and pureextra == old.extra()):
2263 # nothing changed. continuing here would create a new node
2265 # nothing changed. continuing here would create a new node
2264 # anyway because of the amend_source noise.
2266 # anyway because of the amend_source noise.
2265 #
2267 #
2266 # This not what we expect from amend.
2268 # This not what we expect from amend.
2267 return old.node()
2269 return old.node()
2268
2270
2269 ph = repo.ui.config('phases', 'new-commit', phases.draft)
2271 ph = repo.ui.config('phases', 'new-commit', phases.draft)
2270 try:
2272 try:
2271 if opts.get('secret'):
2273 if opts.get('secret'):
2272 commitphase = 'secret'
2274 commitphase = 'secret'
2273 else:
2275 else:
2274 commitphase = old.phase()
2276 commitphase = old.phase()
2275 repo.ui.setconfig('phases', 'new-commit', commitphase, 'amend')
2277 repo.ui.setconfig('phases', 'new-commit', commitphase, 'amend')
2276 newid = repo.commitctx(new)
2278 newid = repo.commitctx(new)
2277 finally:
2279 finally:
2278 repo.ui.setconfig('phases', 'new-commit', ph, 'amend')
2280 repo.ui.setconfig('phases', 'new-commit', ph, 'amend')
2279 if newid != old.node():
2281 if newid != old.node():
2280 # Reroute the working copy parent to the new changeset
2282 # Reroute the working copy parent to the new changeset
2281 repo.setparents(newid, nullid)
2283 repo.setparents(newid, nullid)
2282
2284
2283 # Move bookmarks from old parent to amend commit
2285 # Move bookmarks from old parent to amend commit
2284 bms = repo.nodebookmarks(old.node())
2286 bms = repo.nodebookmarks(old.node())
2285 if bms:
2287 if bms:
2286 marks = repo._bookmarks
2288 marks = repo._bookmarks
2287 for bm in bms:
2289 for bm in bms:
2288 marks[bm] = newid
2290 marks[bm] = newid
2289 marks.write()
2291 marks.write()
2290 #commit the whole amend process
2292 #commit the whole amend process
2291 createmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt)
2293 createmarkers = obsolete.isenabled(repo, obsolete.createmarkersopt)
2292 if createmarkers and newid != old.node():
2294 if createmarkers and newid != old.node():
2293 # mark the new changeset as successor of the rewritten one
2295 # mark the new changeset as successor of the rewritten one
2294 new = repo[newid]
2296 new = repo[newid]
2295 obs = [(old, (new,))]
2297 obs = [(old, (new,))]
2296 if node:
2298 if node:
2297 obs.append((ctx, ()))
2299 obs.append((ctx, ()))
2298
2300
2299 obsolete.createmarkers(repo, obs)
2301 obsolete.createmarkers(repo, obs)
2300 tr.close()
2302 tr.close()
2301 finally:
2303 finally:
2302 tr.release()
2304 tr.release()
2303 if not createmarkers and newid != old.node():
2305 if not createmarkers and newid != old.node():
2304 # Strip the intermediate commit (if there was one) and the amended
2306 # Strip the intermediate commit (if there was one) and the amended
2305 # commit
2307 # commit
2306 if node:
2308 if node:
2307 ui.note(_('stripping intermediate changeset %s\n') % ctx)
2309 ui.note(_('stripping intermediate changeset %s\n') % ctx)
2308 ui.note(_('stripping amended changeset %s\n') % old)
2310 ui.note(_('stripping amended changeset %s\n') % old)
2309 repair.strip(ui, repo, old.node(), topic='amend-backup')
2311 repair.strip(ui, repo, old.node(), topic='amend-backup')
2310 finally:
2312 finally:
2311 if newid is None:
2313 if newid is None:
2312 repo.dirstate.invalidate()
2314 repo.dirstate.invalidate()
2313 lockmod.release(lock, wlock)
2315 lockmod.release(lock, wlock)
2314 return newid
2316 return newid
2315
2317
2316 def commiteditor(repo, ctx, subs, editform=''):
2318 def commiteditor(repo, ctx, subs, editform=''):
2317 if ctx.description():
2319 if ctx.description():
2318 return ctx.description()
2320 return ctx.description()
2319 return commitforceeditor(repo, ctx, subs, editform=editform)
2321 return commitforceeditor(repo, ctx, subs, editform=editform)
2320
2322
2321 def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None,
2323 def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None,
2322 editform=''):
2324 editform=''):
2323 if not extramsg:
2325 if not extramsg:
2324 extramsg = _("Leave message empty to abort commit.")
2326 extramsg = _("Leave message empty to abort commit.")
2325
2327
2326 forms = [e for e in editform.split('.') if e]
2328 forms = [e for e in editform.split('.') if e]
2327 forms.insert(0, 'changeset')
2329 forms.insert(0, 'changeset')
2328 while forms:
2330 while forms:
2329 tmpl = repo.ui.config('committemplate', '.'.join(forms))
2331 tmpl = repo.ui.config('committemplate', '.'.join(forms))
2330 if tmpl:
2332 if tmpl:
2331 committext = buildcommittemplate(repo, ctx, subs, extramsg, tmpl)
2333 committext = buildcommittemplate(repo, ctx, subs, extramsg, tmpl)
2332 break
2334 break
2333 forms.pop()
2335 forms.pop()
2334 else:
2336 else:
2335 committext = buildcommittext(repo, ctx, subs, extramsg)
2337 committext = buildcommittext(repo, ctx, subs, extramsg)
2336
2338
2337 # run editor in the repository root
2339 # run editor in the repository root
2338 olddir = os.getcwd()
2340 olddir = os.getcwd()
2339 os.chdir(repo.root)
2341 os.chdir(repo.root)
2340 text = repo.ui.edit(committext, ctx.user(), ctx.extra(), editform=editform)
2342 text = repo.ui.edit(committext, ctx.user(), ctx.extra(), editform=editform)
2341 text = re.sub("(?m)^HG:.*(\n|$)", "", text)
2343 text = re.sub("(?m)^HG:.*(\n|$)", "", text)
2342 os.chdir(olddir)
2344 os.chdir(olddir)
2343
2345
2344 if finishdesc:
2346 if finishdesc:
2345 text = finishdesc(text)
2347 text = finishdesc(text)
2346 if not text.strip():
2348 if not text.strip():
2347 raise util.Abort(_("empty commit message"))
2349 raise util.Abort(_("empty commit message"))
2348
2350
2349 return text
2351 return text
2350
2352
2351 def buildcommittemplate(repo, ctx, subs, extramsg, tmpl):
2353 def buildcommittemplate(repo, ctx, subs, extramsg, tmpl):
2352 ui = repo.ui
2354 ui = repo.ui
2353 tmpl, mapfile = gettemplate(ui, tmpl, None)
2355 tmpl, mapfile = gettemplate(ui, tmpl, None)
2354
2356
2355 try:
2357 try:
2356 t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
2358 t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
2357 except SyntaxError, inst:
2359 except SyntaxError, inst:
2358 raise util.Abort(inst.args[0])
2360 raise util.Abort(inst.args[0])
2359
2361
2360 for k, v in repo.ui.configitems('committemplate'):
2362 for k, v in repo.ui.configitems('committemplate'):
2361 if k != 'changeset':
2363 if k != 'changeset':
2362 t.t.cache[k] = v
2364 t.t.cache[k] = v
2363
2365
2364 if not extramsg:
2366 if not extramsg:
2365 extramsg = '' # ensure that extramsg is string
2367 extramsg = '' # ensure that extramsg is string
2366
2368
2367 ui.pushbuffer()
2369 ui.pushbuffer()
2368 t.show(ctx, extramsg=extramsg)
2370 t.show(ctx, extramsg=extramsg)
2369 return ui.popbuffer()
2371 return ui.popbuffer()
2370
2372
2371 def buildcommittext(repo, ctx, subs, extramsg):
2373 def buildcommittext(repo, ctx, subs, extramsg):
2372 edittext = []
2374 edittext = []
2373 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
2375 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
2374 if ctx.description():
2376 if ctx.description():
2375 edittext.append(ctx.description())
2377 edittext.append(ctx.description())
2376 edittext.append("")
2378 edittext.append("")
2377 edittext.append("") # Empty line between message and comments.
2379 edittext.append("") # Empty line between message and comments.
2378 edittext.append(_("HG: Enter commit message."
2380 edittext.append(_("HG: Enter commit message."
2379 " Lines beginning with 'HG:' are removed."))
2381 " Lines beginning with 'HG:' are removed."))
2380 edittext.append("HG: %s" % extramsg)
2382 edittext.append("HG: %s" % extramsg)
2381 edittext.append("HG: --")
2383 edittext.append("HG: --")
2382 edittext.append(_("HG: user: %s") % ctx.user())
2384 edittext.append(_("HG: user: %s") % ctx.user())
2383 if ctx.p2():
2385 if ctx.p2():
2384 edittext.append(_("HG: branch merge"))
2386 edittext.append(_("HG: branch merge"))
2385 if ctx.branch():
2387 if ctx.branch():
2386 edittext.append(_("HG: branch '%s'") % ctx.branch())
2388 edittext.append(_("HG: branch '%s'") % ctx.branch())
2387 if bookmarks.iscurrent(repo):
2389 if bookmarks.iscurrent(repo):
2388 edittext.append(_("HG: bookmark '%s'") % repo._bookmarkcurrent)
2390 edittext.append(_("HG: bookmark '%s'") % repo._bookmarkcurrent)
2389 edittext.extend([_("HG: subrepo %s") % s for s in subs])
2391 edittext.extend([_("HG: subrepo %s") % s for s in subs])
2390 edittext.extend([_("HG: added %s") % f for f in added])
2392 edittext.extend([_("HG: added %s") % f for f in added])
2391 edittext.extend([_("HG: changed %s") % f for f in modified])
2393 edittext.extend([_("HG: changed %s") % f for f in modified])
2392 edittext.extend([_("HG: removed %s") % f for f in removed])
2394 edittext.extend([_("HG: removed %s") % f for f in removed])
2393 if not added and not modified and not removed:
2395 if not added and not modified and not removed:
2394 edittext.append(_("HG: no files changed"))
2396 edittext.append(_("HG: no files changed"))
2395 edittext.append("")
2397 edittext.append("")
2396
2398
2397 return "\n".join(edittext)
2399 return "\n".join(edittext)
2398
2400
2399 def commitstatus(repo, node, branch, bheads=None, opts={}):
2401 def commitstatus(repo, node, branch, bheads=None, opts={}):
2400 ctx = repo[node]
2402 ctx = repo[node]
2401 parents = ctx.parents()
2403 parents = ctx.parents()
2402
2404
2403 if (not opts.get('amend') and bheads and node not in bheads and not
2405 if (not opts.get('amend') and bheads and node not in bheads and not
2404 [x for x in parents if x.node() in bheads and x.branch() == branch]):
2406 [x for x in parents if x.node() in bheads and x.branch() == branch]):
2405 repo.ui.status(_('created new head\n'))
2407 repo.ui.status(_('created new head\n'))
2406 # The message is not printed for initial roots. For the other
2408 # The message is not printed for initial roots. For the other
2407 # changesets, it is printed in the following situations:
2409 # changesets, it is printed in the following situations:
2408 #
2410 #
2409 # Par column: for the 2 parents with ...
2411 # Par column: for the 2 parents with ...
2410 # N: null or no parent
2412 # N: null or no parent
2411 # B: parent is on another named branch
2413 # B: parent is on another named branch
2412 # C: parent is a regular non head changeset
2414 # C: parent is a regular non head changeset
2413 # H: parent was a branch head of the current branch
2415 # H: parent was a branch head of the current branch
2414 # Msg column: whether we print "created new head" message
2416 # Msg column: whether we print "created new head" message
2415 # In the following, it is assumed that there already exists some
2417 # In the following, it is assumed that there already exists some
2416 # initial branch heads of the current branch, otherwise nothing is
2418 # initial branch heads of the current branch, otherwise nothing is
2417 # printed anyway.
2419 # printed anyway.
2418 #
2420 #
2419 # Par Msg Comment
2421 # Par Msg Comment
2420 # N N y additional topo root
2422 # N N y additional topo root
2421 #
2423 #
2422 # B N y additional branch root
2424 # B N y additional branch root
2423 # C N y additional topo head
2425 # C N y additional topo head
2424 # H N n usual case
2426 # H N n usual case
2425 #
2427 #
2426 # B B y weird additional branch root
2428 # B B y weird additional branch root
2427 # C B y branch merge
2429 # C B y branch merge
2428 # H B n merge with named branch
2430 # H B n merge with named branch
2429 #
2431 #
2430 # C C y additional head from merge
2432 # C C y additional head from merge
2431 # C H n merge with a head
2433 # C H n merge with a head
2432 #
2434 #
2433 # H H n head merge: head count decreases
2435 # H H n head merge: head count decreases
2434
2436
2435 if not opts.get('close_branch'):
2437 if not opts.get('close_branch'):
2436 for r in parents:
2438 for r in parents:
2437 if r.closesbranch() and r.branch() == branch:
2439 if r.closesbranch() and r.branch() == branch:
2438 repo.ui.status(_('reopening closed branch head %d\n') % r)
2440 repo.ui.status(_('reopening closed branch head %d\n') % r)
2439
2441
2440 if repo.ui.debugflag:
2442 if repo.ui.debugflag:
2441 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
2443 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
2442 elif repo.ui.verbose:
2444 elif repo.ui.verbose:
2443 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
2445 repo.ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
2444
2446
2445 def revert(ui, repo, ctx, parents, *pats, **opts):
2447 def revert(ui, repo, ctx, parents, *pats, **opts):
2446 parent, p2 = parents
2448 parent, p2 = parents
2447 node = ctx.node()
2449 node = ctx.node()
2448
2450
2449 mf = ctx.manifest()
2451 mf = ctx.manifest()
2450 if node == p2:
2452 if node == p2:
2451 parent = p2
2453 parent = p2
2452 if node == parent:
2454 if node == parent:
2453 pmf = mf
2455 pmf = mf
2454 else:
2456 else:
2455 pmf = None
2457 pmf = None
2456
2458
2457 # need all matching names in dirstate and manifest of target rev,
2459 # need all matching names in dirstate and manifest of target rev,
2458 # so have to walk both. do not print errors if files exist in one
2460 # so have to walk both. do not print errors if files exist in one
2459 # but not other.
2461 # but not other.
2460
2462
2461 # `names` is a mapping for all elements in working copy and target revision
2463 # `names` is a mapping for all elements in working copy and target revision
2462 # The mapping is in the form:
2464 # The mapping is in the form:
2463 # <asb path in repo> -> (<path from CWD>, <exactly specified by matcher?>)
2465 # <asb path in repo> -> (<path from CWD>, <exactly specified by matcher?>)
2464 names = {}
2466 names = {}
2465
2467
2466 wlock = repo.wlock()
2468 wlock = repo.wlock()
2467 try:
2469 try:
2468 ## filling of the `names` mapping
2470 ## filling of the `names` mapping
2469 # walk dirstate to fill `names`
2471 # walk dirstate to fill `names`
2470
2472
2471 m = scmutil.match(repo[None], pats, opts)
2473 m = scmutil.match(repo[None], pats, opts)
2472 if not m.always() or node != parent:
2474 if not m.always() or node != parent:
2473 m.bad = lambda x, y: False
2475 m.bad = lambda x, y: False
2474 for abs in repo.walk(m):
2476 for abs in repo.walk(m):
2475 names[abs] = m.rel(abs), m.exact(abs)
2477 names[abs] = m.rel(abs), m.exact(abs)
2476
2478
2477 # walk target manifest to fill `names`
2479 # walk target manifest to fill `names`
2478
2480
2479 def badfn(path, msg):
2481 def badfn(path, msg):
2480 if path in names:
2482 if path in names:
2481 return
2483 return
2482 if path in ctx.substate:
2484 if path in ctx.substate:
2483 return
2485 return
2484 path_ = path + '/'
2486 path_ = path + '/'
2485 for f in names:
2487 for f in names:
2486 if f.startswith(path_):
2488 if f.startswith(path_):
2487 return
2489 return
2488 ui.warn("%s: %s\n" % (m.rel(path), msg))
2490 ui.warn("%s: %s\n" % (m.rel(path), msg))
2489
2491
2490 m = scmutil.match(ctx, pats, opts)
2492 m = scmutil.match(ctx, pats, opts)
2491 m.bad = badfn
2493 m.bad = badfn
2492 for abs in ctx.walk(m):
2494 for abs in ctx.walk(m):
2493 if abs not in names:
2495 if abs not in names:
2494 names[abs] = m.rel(abs), m.exact(abs)
2496 names[abs] = m.rel(abs), m.exact(abs)
2495
2497
2496 # Find status of all file in `names`.
2498 # Find status of all file in `names`.
2497 m = scmutil.matchfiles(repo, names)
2499 m = scmutil.matchfiles(repo, names)
2498
2500
2499 changes = repo.status(node1=node, match=m,
2501 changes = repo.status(node1=node, match=m,
2500 unknown=True, ignored=True, clean=True)
2502 unknown=True, ignored=True, clean=True)
2501 else:
2503 else:
2502 changes = repo.status(match=m)
2504 changes = repo.status(match=m)
2503 for kind in changes:
2505 for kind in changes:
2504 for abs in kind:
2506 for abs in kind:
2505 names[abs] = m.rel(abs), m.exact(abs)
2507 names[abs] = m.rel(abs), m.exact(abs)
2506
2508
2507 m = scmutil.matchfiles(repo, names)
2509 m = scmutil.matchfiles(repo, names)
2508
2510
2509 modified = set(changes[0])
2511 modified = set(changes[0])
2510 added = set(changes[1])
2512 added = set(changes[1])
2511 removed = set(changes[2])
2513 removed = set(changes[2])
2512 _deleted = set(changes[3])
2514 _deleted = set(changes[3])
2513 unknown = set(changes[4])
2515 unknown = set(changes[4])
2514 unknown.update(changes[5])
2516 unknown.update(changes[5])
2515 clean = set(changes[6])
2517 clean = set(changes[6])
2516 modadded = set()
2518 modadded = set()
2517
2519
2518 # split between files known in target manifest and the others
2520 # split between files known in target manifest and the others
2519 smf = set(mf)
2521 smf = set(mf)
2520
2522
2521 # determine the exact nature of the deleted changesets
2523 # determine the exact nature of the deleted changesets
2522 deladded = _deleted - smf
2524 deladded = _deleted - smf
2523 deleted = _deleted - deladded
2525 deleted = _deleted - deladded
2524
2526
2525 # We need to account for the state of file in the dirstate
2527 # We need to account for the state of file in the dirstate
2526 #
2528 #
2527 # Even, when we revert agains something else than parent. this will
2529 # Even, when we revert agains something else than parent. this will
2528 # slightly alter the behavior of revert (doing back up or not, delete
2530 # slightly alter the behavior of revert (doing back up or not, delete
2529 # or just forget etc)
2531 # or just forget etc)
2530 if parent == node:
2532 if parent == node:
2531 dsmodified = modified
2533 dsmodified = modified
2532 dsadded = added
2534 dsadded = added
2533 dsremoved = removed
2535 dsremoved = removed
2534 # store all local modifications, useful later for rename detection
2536 # store all local modifications, useful later for rename detection
2535 localchanges = dsmodified | dsadded
2537 localchanges = dsmodified | dsadded
2536 modified, added, removed = set(), set(), set()
2538 modified, added, removed = set(), set(), set()
2537 else:
2539 else:
2538 changes = repo.status(node1=parent, match=m)
2540 changes = repo.status(node1=parent, match=m)
2539 dsmodified = set(changes[0])
2541 dsmodified = set(changes[0])
2540 dsadded = set(changes[1])
2542 dsadded = set(changes[1])
2541 dsremoved = set(changes[2])
2543 dsremoved = set(changes[2])
2542 # store all local modifications, useful later for rename detection
2544 # store all local modifications, useful later for rename detection
2543 localchanges = dsmodified | dsadded
2545 localchanges = dsmodified | dsadded
2544
2546
2545 # only take into account for removes between wc and target
2547 # only take into account for removes between wc and target
2546 clean |= dsremoved - removed
2548 clean |= dsremoved - removed
2547 dsremoved &= removed
2549 dsremoved &= removed
2548 # distinct between dirstate remove and other
2550 # distinct between dirstate remove and other
2549 removed -= dsremoved
2551 removed -= dsremoved
2550
2552
2551 modadded = added & dsmodified
2553 modadded = added & dsmodified
2552 added -= modadded
2554 added -= modadded
2553
2555
2554 # tell newly modified apart.
2556 # tell newly modified apart.
2555 dsmodified &= modified
2557 dsmodified &= modified
2556 dsmodified |= modified & dsadded # dirstate added may needs backup
2558 dsmodified |= modified & dsadded # dirstate added may needs backup
2557 modified -= dsmodified
2559 modified -= dsmodified
2558
2560
2559 # We need to wait for some post-processing to update this set
2561 # We need to wait for some post-processing to update this set
2560 # before making the distinction. The dirstate will be used for
2562 # before making the distinction. The dirstate will be used for
2561 # that purpose.
2563 # that purpose.
2562 dsadded = added
2564 dsadded = added
2563
2565
2564 # in case of merge, files that are actually added can be reported as
2566 # in case of merge, files that are actually added can be reported as
2565 # modified, we need to post process the result
2567 # modified, we need to post process the result
2566 if p2 != nullid:
2568 if p2 != nullid:
2567 if pmf is None:
2569 if pmf is None:
2568 # only need parent manifest in the merge case,
2570 # only need parent manifest in the merge case,
2569 # so do not read by default
2571 # so do not read by default
2570 pmf = repo[parent].manifest()
2572 pmf = repo[parent].manifest()
2571 mergeadd = dsmodified - set(pmf)
2573 mergeadd = dsmodified - set(pmf)
2572 dsadded |= mergeadd
2574 dsadded |= mergeadd
2573 dsmodified -= mergeadd
2575 dsmodified -= mergeadd
2574
2576
2575 # if f is a rename, update `names` to also revert the source
2577 # if f is a rename, update `names` to also revert the source
2576 cwd = repo.getcwd()
2578 cwd = repo.getcwd()
2577 for f in localchanges:
2579 for f in localchanges:
2578 src = repo.dirstate.copied(f)
2580 src = repo.dirstate.copied(f)
2579 # XXX should we check for rename down to target node?
2581 # XXX should we check for rename down to target node?
2580 if src and src not in names and repo.dirstate[src] == 'r':
2582 if src and src not in names and repo.dirstate[src] == 'r':
2581 dsremoved.add(src)
2583 dsremoved.add(src)
2582 names[src] = (repo.pathto(src, cwd), True)
2584 names[src] = (repo.pathto(src, cwd), True)
2583
2585
2584 # distinguish between file to forget and the other
2586 # distinguish between file to forget and the other
2585 added = set()
2587 added = set()
2586 for abs in dsadded:
2588 for abs in dsadded:
2587 if repo.dirstate[abs] != 'a':
2589 if repo.dirstate[abs] != 'a':
2588 added.add(abs)
2590 added.add(abs)
2589 dsadded -= added
2591 dsadded -= added
2590
2592
2591 for abs in deladded:
2593 for abs in deladded:
2592 if repo.dirstate[abs] == 'a':
2594 if repo.dirstate[abs] == 'a':
2593 dsadded.add(abs)
2595 dsadded.add(abs)
2594 deladded -= dsadded
2596 deladded -= dsadded
2595
2597
2596 # For files marked as removed, we check if an unknown file is present at
2598 # For files marked as removed, we check if an unknown file is present at
2597 # the same path. If a such file exists it may need to be backed up.
2599 # the same path. If a such file exists it may need to be backed up.
2598 # Making the distinction at this stage helps have simpler backup
2600 # Making the distinction at this stage helps have simpler backup
2599 # logic.
2601 # logic.
2600 removunk = set()
2602 removunk = set()
2601 for abs in removed:
2603 for abs in removed:
2602 target = repo.wjoin(abs)
2604 target = repo.wjoin(abs)
2603 if os.path.lexists(target):
2605 if os.path.lexists(target):
2604 removunk.add(abs)
2606 removunk.add(abs)
2605 removed -= removunk
2607 removed -= removunk
2606
2608
2607 dsremovunk = set()
2609 dsremovunk = set()
2608 for abs in dsremoved:
2610 for abs in dsremoved:
2609 target = repo.wjoin(abs)
2611 target = repo.wjoin(abs)
2610 if os.path.lexists(target):
2612 if os.path.lexists(target):
2611 dsremovunk.add(abs)
2613 dsremovunk.add(abs)
2612 dsremoved -= dsremovunk
2614 dsremoved -= dsremovunk
2613
2615
2614 # action to be actually performed by revert
2616 # action to be actually performed by revert
2615 # (<list of file>, message>) tuple
2617 # (<list of file>, message>) tuple
2616 actions = {'revert': ([], _('reverting %s\n')),
2618 actions = {'revert': ([], _('reverting %s\n')),
2617 'add': ([], _('adding %s\n')),
2619 'add': ([], _('adding %s\n')),
2618 'remove': ([], _('removing %s\n')),
2620 'remove': ([], _('removing %s\n')),
2619 'drop': ([], _('removing %s\n')),
2621 'drop': ([], _('removing %s\n')),
2620 'forget': ([], _('forgetting %s\n')),
2622 'forget': ([], _('forgetting %s\n')),
2621 'undelete': ([], _('undeleting %s\n')),
2623 'undelete': ([], _('undeleting %s\n')),
2622 'noop': (None, _('no changes needed to %s\n')),
2624 'noop': (None, _('no changes needed to %s\n')),
2623 'unknown': (None, _('file not managed: %s\n')),
2625 'unknown': (None, _('file not managed: %s\n')),
2624 }
2626 }
2625
2627
2626 # "constant" that convey the backup strategy.
2628 # "constant" that convey the backup strategy.
2627 # All set to `discard` if `no-backup` is set do avoid checking
2629 # All set to `discard` if `no-backup` is set do avoid checking
2628 # no_backup lower in the code.
2630 # no_backup lower in the code.
2629 # These values are ordered for comparison purposes
2631 # These values are ordered for comparison purposes
2630 backup = 2 # unconditionally do backup
2632 backup = 2 # unconditionally do backup
2631 check = 1 # check if the existing file differs from target
2633 check = 1 # check if the existing file differs from target
2632 discard = 0 # never do backup
2634 discard = 0 # never do backup
2633 if opts.get('no_backup'):
2635 if opts.get('no_backup'):
2634 backup = check = discard
2636 backup = check = discard
2635
2637
2636 backupanddel = actions['remove']
2638 backupanddel = actions['remove']
2637 if not opts.get('no_backup'):
2639 if not opts.get('no_backup'):
2638 backupanddel = actions['drop']
2640 backupanddel = actions['drop']
2639
2641
2640 disptable = (
2642 disptable = (
2641 # dispatch table:
2643 # dispatch table:
2642 # file state
2644 # file state
2643 # action
2645 # action
2644 # make backup
2646 # make backup
2645
2647
2646 ## Sets that results that will change file on disk
2648 ## Sets that results that will change file on disk
2647 # Modified compared to target, no local change
2649 # Modified compared to target, no local change
2648 (modified, actions['revert'], discard),
2650 (modified, actions['revert'], discard),
2649 # Modified compared to target, but local file is deleted
2651 # Modified compared to target, but local file is deleted
2650 (deleted, actions['revert'], discard),
2652 (deleted, actions['revert'], discard),
2651 # Modified compared to target, local change
2653 # Modified compared to target, local change
2652 (dsmodified, actions['revert'], backup),
2654 (dsmodified, actions['revert'], backup),
2653 # Added since target
2655 # Added since target
2654 (added, actions['remove'], discard),
2656 (added, actions['remove'], discard),
2655 # Added in working directory
2657 # Added in working directory
2656 (dsadded, actions['forget'], discard),
2658 (dsadded, actions['forget'], discard),
2657 # Added since target, have local modification
2659 # Added since target, have local modification
2658 (modadded, backupanddel, backup),
2660 (modadded, backupanddel, backup),
2659 # Added since target but file is missing in working directory
2661 # Added since target but file is missing in working directory
2660 (deladded, actions['drop'], discard),
2662 (deladded, actions['drop'], discard),
2661 # Removed since target, before working copy parent
2663 # Removed since target, before working copy parent
2662 (removed, actions['add'], discard),
2664 (removed, actions['add'], discard),
2663 # Same as `removed` but an unknown file exists at the same path
2665 # Same as `removed` but an unknown file exists at the same path
2664 (removunk, actions['add'], check),
2666 (removunk, actions['add'], check),
2665 # Removed since targe, marked as such in working copy parent
2667 # Removed since targe, marked as such in working copy parent
2666 (dsremoved, actions['undelete'], discard),
2668 (dsremoved, actions['undelete'], discard),
2667 # Same as `dsremoved` but an unknown file exists at the same path
2669 # Same as `dsremoved` but an unknown file exists at the same path
2668 (dsremovunk, actions['undelete'], check),
2670 (dsremovunk, actions['undelete'], check),
2669 ## the following sets does not result in any file changes
2671 ## the following sets does not result in any file changes
2670 # File with no modification
2672 # File with no modification
2671 (clean, actions['noop'], discard),
2673 (clean, actions['noop'], discard),
2672 # Existing file, not tracked anywhere
2674 # Existing file, not tracked anywhere
2673 (unknown, actions['unknown'], discard),
2675 (unknown, actions['unknown'], discard),
2674 )
2676 )
2675
2677
2676 needdata = ('revert', 'add', 'undelete')
2678 needdata = ('revert', 'add', 'undelete')
2677 _revertprefetch(repo, ctx, *[actions[name][0] for name in needdata])
2679 _revertprefetch(repo, ctx, *[actions[name][0] for name in needdata])
2678
2680
2679 wctx = repo[None]
2681 wctx = repo[None]
2680 for abs, (rel, exact) in sorted(names.items()):
2682 for abs, (rel, exact) in sorted(names.items()):
2681 # target file to be touch on disk (relative to cwd)
2683 # target file to be touch on disk (relative to cwd)
2682 target = repo.wjoin(abs)
2684 target = repo.wjoin(abs)
2683 # search the entry in the dispatch table.
2685 # search the entry in the dispatch table.
2684 # if the file is in any of these sets, it was touched in the working
2686 # if the file is in any of these sets, it was touched in the working
2685 # directory parent and we are sure it needs to be reverted.
2687 # directory parent and we are sure it needs to be reverted.
2686 for table, (xlist, msg), dobackup in disptable:
2688 for table, (xlist, msg), dobackup in disptable:
2687 if abs not in table:
2689 if abs not in table:
2688 continue
2690 continue
2689 if xlist is not None:
2691 if xlist is not None:
2690 xlist.append(abs)
2692 xlist.append(abs)
2691 if dobackup and (backup <= dobackup
2693 if dobackup and (backup <= dobackup
2692 or wctx[abs].cmp(ctx[abs])):
2694 or wctx[abs].cmp(ctx[abs])):
2693 bakname = "%s.orig" % rel
2695 bakname = "%s.orig" % rel
2694 ui.note(_('saving current version of %s as %s\n') %
2696 ui.note(_('saving current version of %s as %s\n') %
2695 (rel, bakname))
2697 (rel, bakname))
2696 if not opts.get('dry_run'):
2698 if not opts.get('dry_run'):
2697 util.rename(target, bakname)
2699 util.rename(target, bakname)
2698 if ui.verbose or not exact:
2700 if ui.verbose or not exact:
2699 if not isinstance(msg, basestring):
2701 if not isinstance(msg, basestring):
2700 msg = msg(abs)
2702 msg = msg(abs)
2701 ui.status(msg % rel)
2703 ui.status(msg % rel)
2702 elif exact:
2704 elif exact:
2703 ui.warn(msg % rel)
2705 ui.warn(msg % rel)
2704 break
2706 break
2705
2707
2706
2708
2707 if not opts.get('dry_run'):
2709 if not opts.get('dry_run'):
2708 _performrevert(repo, parents, ctx, actions)
2710 _performrevert(repo, parents, ctx, actions)
2709
2711
2710 # get the list of subrepos that must be reverted
2712 # get the list of subrepos that must be reverted
2711 subrepomatch = scmutil.match(ctx, pats, opts)
2713 subrepomatch = scmutil.match(ctx, pats, opts)
2712 targetsubs = sorted(s for s in ctx.substate if subrepomatch(s))
2714 targetsubs = sorted(s for s in ctx.substate if subrepomatch(s))
2713
2715
2714 if targetsubs:
2716 if targetsubs:
2715 # Revert the subrepos on the revert list
2717 # Revert the subrepos on the revert list
2716 for sub in targetsubs:
2718 for sub in targetsubs:
2717 ctx.sub(sub).revert(ui, ctx.substate[sub], *pats, **opts)
2719 ctx.sub(sub).revert(ui, ctx.substate[sub], *pats, **opts)
2718 finally:
2720 finally:
2719 wlock.release()
2721 wlock.release()
2720
2722
2721 def _revertprefetch(repo, ctx, *files):
2723 def _revertprefetch(repo, ctx, *files):
2722 """Let extension changing the storage layer prefetch content"""
2724 """Let extension changing the storage layer prefetch content"""
2723 pass
2725 pass
2724
2726
2725 def _performrevert(repo, parents, ctx, actions):
2727 def _performrevert(repo, parents, ctx, actions):
2726 """function that actually perform all the actions computed for revert
2728 """function that actually perform all the actions computed for revert
2727
2729
2728 This is an independent function to let extension to plug in and react to
2730 This is an independent function to let extension to plug in and react to
2729 the imminent revert.
2731 the imminent revert.
2730
2732
2731 Make sure you have the working directory locked when calling this function.
2733 Make sure you have the working directory locked when calling this function.
2732 """
2734 """
2733 parent, p2 = parents
2735 parent, p2 = parents
2734 node = ctx.node()
2736 node = ctx.node()
2735 def checkout(f):
2737 def checkout(f):
2736 fc = ctx[f]
2738 fc = ctx[f]
2737 repo.wwrite(f, fc.data(), fc.flags())
2739 repo.wwrite(f, fc.data(), fc.flags())
2738
2740
2739 audit_path = pathutil.pathauditor(repo.root)
2741 audit_path = pathutil.pathauditor(repo.root)
2740 for f in actions['forget'][0]:
2742 for f in actions['forget'][0]:
2741 repo.dirstate.drop(f)
2743 repo.dirstate.drop(f)
2742 for f in actions['remove'][0]:
2744 for f in actions['remove'][0]:
2743 audit_path(f)
2745 audit_path(f)
2744 util.unlinkpath(repo.wjoin(f))
2746 util.unlinkpath(repo.wjoin(f))
2745 repo.dirstate.remove(f)
2747 repo.dirstate.remove(f)
2746 for f in actions['drop'][0]:
2748 for f in actions['drop'][0]:
2747 audit_path(f)
2749 audit_path(f)
2748 repo.dirstate.remove(f)
2750 repo.dirstate.remove(f)
2749
2751
2750 normal = None
2752 normal = None
2751 if node == parent:
2753 if node == parent:
2752 # We're reverting to our parent. If possible, we'd like status
2754 # We're reverting to our parent. If possible, we'd like status
2753 # to report the file as clean. We have to use normallookup for
2755 # to report the file as clean. We have to use normallookup for
2754 # merges to avoid losing information about merged/dirty files.
2756 # merges to avoid losing information about merged/dirty files.
2755 if p2 != nullid:
2757 if p2 != nullid:
2756 normal = repo.dirstate.normallookup
2758 normal = repo.dirstate.normallookup
2757 else:
2759 else:
2758 normal = repo.dirstate.normal
2760 normal = repo.dirstate.normal
2759 for f in actions['revert'][0]:
2761 for f in actions['revert'][0]:
2760 checkout(f)
2762 checkout(f)
2761 if normal:
2763 if normal:
2762 normal(f)
2764 normal(f)
2763
2765
2764 for f in actions['add'][0]:
2766 for f in actions['add'][0]:
2765 checkout(f)
2767 checkout(f)
2766 repo.dirstate.add(f)
2768 repo.dirstate.add(f)
2767
2769
2768 normal = repo.dirstate.normallookup
2770 normal = repo.dirstate.normallookup
2769 if node == parent and p2 == nullid:
2771 if node == parent and p2 == nullid:
2770 normal = repo.dirstate.normal
2772 normal = repo.dirstate.normal
2771 for f in actions['undelete'][0]:
2773 for f in actions['undelete'][0]:
2772 checkout(f)
2774 checkout(f)
2773 normal(f)
2775 normal(f)
2774
2776
2775 copied = copies.pathcopies(repo[parent], ctx)
2777 copied = copies.pathcopies(repo[parent], ctx)
2776
2778
2777 for f in actions['add'][0] + actions['undelete'][0] + actions['revert'][0]:
2779 for f in actions['add'][0] + actions['undelete'][0] + actions['revert'][0]:
2778 if f in copied:
2780 if f in copied:
2779 repo.dirstate.copy(copied[f], f)
2781 repo.dirstate.copy(copied[f], f)
2780
2782
2781 def command(table):
2783 def command(table):
2782 """Returns a function object to be used as a decorator for making commands.
2784 """Returns a function object to be used as a decorator for making commands.
2783
2785
2784 This function receives a command table as its argument. The table should
2786 This function receives a command table as its argument. The table should
2785 be a dict.
2787 be a dict.
2786
2788
2787 The returned function can be used as a decorator for adding commands
2789 The returned function can be used as a decorator for adding commands
2788 to that command table. This function accepts multiple arguments to define
2790 to that command table. This function accepts multiple arguments to define
2789 a command.
2791 a command.
2790
2792
2791 The first argument is the command name.
2793 The first argument is the command name.
2792
2794
2793 The options argument is an iterable of tuples defining command arguments.
2795 The options argument is an iterable of tuples defining command arguments.
2794 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
2796 See ``mercurial.fancyopts.fancyopts()`` for the format of each tuple.
2795
2797
2796 The synopsis argument defines a short, one line summary of how to use the
2798 The synopsis argument defines a short, one line summary of how to use the
2797 command. This shows up in the help output.
2799 command. This shows up in the help output.
2798
2800
2799 The norepo argument defines whether the command does not require a
2801 The norepo argument defines whether the command does not require a
2800 local repository. Most commands operate against a repository, thus the
2802 local repository. Most commands operate against a repository, thus the
2801 default is False.
2803 default is False.
2802
2804
2803 The optionalrepo argument defines whether the command optionally requires
2805 The optionalrepo argument defines whether the command optionally requires
2804 a local repository.
2806 a local repository.
2805
2807
2806 The inferrepo argument defines whether to try to find a repository from the
2808 The inferrepo argument defines whether to try to find a repository from the
2807 command line arguments. If True, arguments will be examined for potential
2809 command line arguments. If True, arguments will be examined for potential
2808 repository locations. See ``findrepo()``. If a repository is found, it
2810 repository locations. See ``findrepo()``. If a repository is found, it
2809 will be used.
2811 will be used.
2810 """
2812 """
2811 def cmd(name, options=(), synopsis=None, norepo=False, optionalrepo=False,
2813 def cmd(name, options=(), synopsis=None, norepo=False, optionalrepo=False,
2812 inferrepo=False):
2814 inferrepo=False):
2813 def decorator(func):
2815 def decorator(func):
2814 if synopsis:
2816 if synopsis:
2815 table[name] = func, list(options), synopsis
2817 table[name] = func, list(options), synopsis
2816 else:
2818 else:
2817 table[name] = func, list(options)
2819 table[name] = func, list(options)
2818
2820
2819 if norepo:
2821 if norepo:
2820 # Avoid import cycle.
2822 # Avoid import cycle.
2821 import commands
2823 import commands
2822 commands.norepo += ' %s' % ' '.join(parsealiases(name))
2824 commands.norepo += ' %s' % ' '.join(parsealiases(name))
2823
2825
2824 if optionalrepo:
2826 if optionalrepo:
2825 import commands
2827 import commands
2826 commands.optionalrepo += ' %s' % ' '.join(parsealiases(name))
2828 commands.optionalrepo += ' %s' % ' '.join(parsealiases(name))
2827
2829
2828 if inferrepo:
2830 if inferrepo:
2829 import commands
2831 import commands
2830 commands.inferrepo += ' %s' % ' '.join(parsealiases(name))
2832 commands.inferrepo += ' %s' % ' '.join(parsealiases(name))
2831
2833
2832 return func
2834 return func
2833 return decorator
2835 return decorator
2834
2836
2835 return cmd
2837 return cmd
2836
2838
2837 # a list of (ui, repo, otherpeer, opts, missing) functions called by
2839 # a list of (ui, repo, otherpeer, opts, missing) functions called by
2838 # commands.outgoing. "missing" is "missing" of the result of
2840 # commands.outgoing. "missing" is "missing" of the result of
2839 # "findcommonoutgoing()"
2841 # "findcommonoutgoing()"
2840 outgoinghooks = util.hooks()
2842 outgoinghooks = util.hooks()
2841
2843
2842 # a list of (ui, repo) functions called by commands.summary
2844 # a list of (ui, repo) functions called by commands.summary
2843 summaryhooks = util.hooks()
2845 summaryhooks = util.hooks()
2844
2846
2845 # a list of (ui, repo, opts, changes) functions called by commands.summary.
2847 # a list of (ui, repo, opts, changes) functions called by commands.summary.
2846 #
2848 #
2847 # functions should return tuple of booleans below, if 'changes' is None:
2849 # functions should return tuple of booleans below, if 'changes' is None:
2848 # (whether-incomings-are-needed, whether-outgoings-are-needed)
2850 # (whether-incomings-are-needed, whether-outgoings-are-needed)
2849 #
2851 #
2850 # otherwise, 'changes' is a tuple of tuples below:
2852 # otherwise, 'changes' is a tuple of tuples below:
2851 # - (sourceurl, sourcebranch, sourcepeer, incoming)
2853 # - (sourceurl, sourcebranch, sourcepeer, incoming)
2852 # - (desturl, destbranch, destpeer, outgoing)
2854 # - (desturl, destbranch, destpeer, outgoing)
2853 summaryremotehooks = util.hooks()
2855 summaryremotehooks = util.hooks()
2854
2856
2855 # A list of state files kept by multistep operations like graft.
2857 # A list of state files kept by multistep operations like graft.
2856 # Since graft cannot be aborted, it is considered 'clearable' by update.
2858 # Since graft cannot be aborted, it is considered 'clearable' by update.
2857 # note: bisect is intentionally excluded
2859 # note: bisect is intentionally excluded
2858 # (state file, clearable, allowcommit, error, hint)
2860 # (state file, clearable, allowcommit, error, hint)
2859 unfinishedstates = [
2861 unfinishedstates = [
2860 ('graftstate', True, False, _('graft in progress'),
2862 ('graftstate', True, False, _('graft in progress'),
2861 _("use 'hg graft --continue' or 'hg update' to abort")),
2863 _("use 'hg graft --continue' or 'hg update' to abort")),
2862 ('updatestate', True, False, _('last update was interrupted'),
2864 ('updatestate', True, False, _('last update was interrupted'),
2863 _("use 'hg update' to get a consistent checkout"))
2865 _("use 'hg update' to get a consistent checkout"))
2864 ]
2866 ]
2865
2867
2866 def checkunfinished(repo, commit=False):
2868 def checkunfinished(repo, commit=False):
2867 '''Look for an unfinished multistep operation, like graft, and abort
2869 '''Look for an unfinished multistep operation, like graft, and abort
2868 if found. It's probably good to check this right before
2870 if found. It's probably good to check this right before
2869 bailifchanged().
2871 bailifchanged().
2870 '''
2872 '''
2871 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2873 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2872 if commit and allowcommit:
2874 if commit and allowcommit:
2873 continue
2875 continue
2874 if repo.vfs.exists(f):
2876 if repo.vfs.exists(f):
2875 raise util.Abort(msg, hint=hint)
2877 raise util.Abort(msg, hint=hint)
2876
2878
2877 def clearunfinished(repo):
2879 def clearunfinished(repo):
2878 '''Check for unfinished operations (as above), and clear the ones
2880 '''Check for unfinished operations (as above), and clear the ones
2879 that are clearable.
2881 that are clearable.
2880 '''
2882 '''
2881 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2883 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2882 if not clearable and repo.vfs.exists(f):
2884 if not clearable and repo.vfs.exists(f):
2883 raise util.Abort(msg, hint=hint)
2885 raise util.Abort(msg, hint=hint)
2884 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2886 for f, clearable, allowcommit, msg, hint in unfinishedstates:
2885 if clearable and repo.vfs.exists(f):
2887 if clearable and repo.vfs.exists(f):
2886 util.unlink(repo.join(f))
2888 util.unlink(repo.join(f))
@@ -1,2335 +1,2347 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 $ echo a > a
1544 $ echo a > a
1545 $ echo aa > aa
1545 $ echo aa > aa
1546 $ echo f > f
1546 $ echo f > f
1547 $ hg ci -Am "add a" a aa f
1547 $ hg ci -Am "add a" a aa f
1548 $ hg cp a b
1548 $ hg cp a b
1549 $ hg cp f g
1549 $ hg cp f g
1550 $ hg ci -m "copy a b"
1550 $ hg ci -m "copy a b"
1551 $ mkdir dir
1551 $ mkdir dir
1552 $ hg mv b dir
1552 $ hg mv b dir
1553 $ echo g >> g
1553 $ echo g >> g
1554 $ echo f >> f
1554 $ echo f >> f
1555 $ hg ci -m "mv b dir/b"
1555 $ hg ci -m "mv b dir/b"
1556 $ hg mv a b
1556 $ hg mv a b
1557 $ hg cp -f f g
1557 $ hg cp -f f g
1558 $ echo a > d
1558 $ echo a > d
1559 $ hg add d
1559 $ hg add d
1560 $ hg ci -m "mv a b; add d"
1560 $ hg ci -m "mv a b; add d"
1561 $ hg mv dir/b e
1561 $ hg mv dir/b e
1562 $ hg ci -m "mv dir/b e"
1562 $ hg ci -m "mv dir/b e"
1563 $ hg log -G --template '({rev}) {desc|firstline}\n'
1563 $ hg log -G --template '({rev}) {desc|firstline}\n'
1564 @ (4) mv dir/b e
1564 @ (4) mv dir/b e
1565 |
1565 |
1566 o (3) mv a b; add d
1566 o (3) mv a b; add d
1567 |
1567 |
1568 o (2) mv b dir/b
1568 o (2) mv b dir/b
1569 |
1569 |
1570 o (1) copy a b
1570 o (1) copy a b
1571 |
1571 |
1572 o (0) add a
1572 o (0) add a
1573
1573
1574
1574
1575 $ testlog a
1575 $ testlog a
1576 []
1576 []
1577 (group
1577 (group
1578 (group
1578 (group
1579 (func
1579 (func
1580 ('symbol', 'filelog')
1580 ('symbol', 'filelog')
1581 ('string', 'a'))))
1581 ('string', 'a'))))
1582 $ testlog a b
1582 $ testlog a b
1583 []
1583 []
1584 (group
1584 (group
1585 (group
1585 (group
1586 (or
1586 (or
1587 (func
1587 (func
1588 ('symbol', 'filelog')
1588 ('symbol', 'filelog')
1589 ('string', 'a'))
1589 ('string', 'a'))
1590 (func
1590 (func
1591 ('symbol', 'filelog')
1591 ('symbol', 'filelog')
1592 ('string', 'b')))))
1592 ('string', 'b')))))
1593
1593
1594 Test falling back to slow path for non-existing files
1594 Test falling back to slow path for non-existing files
1595
1595
1596 $ testlog a c
1596 $ testlog a c
1597 []
1597 []
1598 (group
1598 (group
1599 (func
1599 (func
1600 ('symbol', '_matchfiles')
1600 ('symbol', '_matchfiles')
1601 (list
1601 (list
1602 (list
1602 (list
1603 (list
1603 (list
1604 ('string', 'r:')
1604 ('string', 'r:')
1605 ('string', 'd:relpath'))
1605 ('string', 'd:relpath'))
1606 ('string', 'p:a'))
1606 ('string', 'p:a'))
1607 ('string', 'p:c'))))
1607 ('string', 'p:c'))))
1608
1608
1609 Test multiple --include/--exclude/paths
1609 Test multiple --include/--exclude/paths
1610
1610
1611 $ testlog --include a --include e --exclude b --exclude e a e
1611 $ testlog --include a --include e --exclude b --exclude e a e
1612 []
1612 []
1613 (group
1613 (group
1614 (func
1614 (func
1615 ('symbol', '_matchfiles')
1615 ('symbol', '_matchfiles')
1616 (list
1616 (list
1617 (list
1617 (list
1618 (list
1618 (list
1619 (list
1619 (list
1620 (list
1620 (list
1621 (list
1621 (list
1622 (list
1622 (list
1623 ('string', 'r:')
1623 ('string', 'r:')
1624 ('string', 'd:relpath'))
1624 ('string', 'd:relpath'))
1625 ('string', 'p:a'))
1625 ('string', 'p:a'))
1626 ('string', 'p:e'))
1626 ('string', 'p:e'))
1627 ('string', 'i:a'))
1627 ('string', 'i:a'))
1628 ('string', 'i:e'))
1628 ('string', 'i:e'))
1629 ('string', 'x:b'))
1629 ('string', 'x:b'))
1630 ('string', 'x:e'))))
1630 ('string', 'x:e'))))
1631
1631
1632 Test glob expansion of pats
1632 Test glob expansion of pats
1633
1633
1634 $ expandglobs=`$PYTHON -c "import mercurial.util; \
1634 $ expandglobs=`$PYTHON -c "import mercurial.util; \
1635 > print mercurial.util.expandglobs and 'true' or 'false'"`
1635 > print mercurial.util.expandglobs and 'true' or 'false'"`
1636 $ if [ $expandglobs = "true" ]; then
1636 $ if [ $expandglobs = "true" ]; then
1637 > testlog 'a*';
1637 > testlog 'a*';
1638 > else
1638 > else
1639 > testlog a*;
1639 > testlog a*;
1640 > fi;
1640 > fi;
1641 []
1641 []
1642 (group
1642 (group
1643 (group
1643 (group
1644 (func
1644 (func
1645 ('symbol', 'filelog')
1645 ('symbol', 'filelog')
1646 ('string', 'aa'))))
1646 ('string', 'aa'))))
1647
1647
1648 Test --follow on a non-existent directory
1648 Test --follow on a non-existent directory
1649
1649
1650 $ testlog -f dir
1650 $ testlog -f dir
1651 abort: cannot follow file not in parent revision: "dir"
1651 abort: cannot follow file not in parent revision: "dir"
1652 abort: cannot follow file not in parent revision: "dir"
1652 abort: cannot follow file not in parent revision: "dir"
1653 abort: cannot follow file not in parent revision: "dir"
1653 abort: cannot follow file not in parent revision: "dir"
1654
1654
1655 Test --follow on a directory
1655 Test --follow on a directory
1656
1656
1657 $ hg up -q '.^'
1657 $ hg up -q '.^'
1658 $ testlog -f dir
1658 $ testlog -f dir
1659 []
1659 []
1660 (group
1660 (group
1661 (func
1661 (and
1662 ('symbol', '_matchfiles')
1662 (func
1663 (list
1663 ('symbol', '_matchfiles')
1664 (list
1664 (list
1665 ('string', 'r:')
1665 (list
1666 ('string', 'd:relpath'))
1666 ('string', 'r:')
1667 ('string', 'p:dir'))))
1667 ('string', 'd:relpath'))
1668 ('string', 'p:dir')))
1669 (func
1670 ('symbol', 'ancestors')
1671 ('symbol', '.'))))
1668 $ hg up -q tip
1672 $ hg up -q tip
1669
1673
1670 Test --follow on file not in parent revision
1674 Test --follow on file not in parent revision
1671
1675
1672 $ testlog -f a
1676 $ testlog -f a
1673 abort: cannot follow file not in parent revision: "a"
1677 abort: cannot follow file not in parent revision: "a"
1674 abort: cannot follow file not in parent revision: "a"
1678 abort: cannot follow file not in parent revision: "a"
1675 abort: cannot follow file not in parent revision: "a"
1679 abort: cannot follow file not in parent revision: "a"
1676
1680
1677 Test --follow and patterns
1681 Test --follow and patterns
1678
1682
1679 $ testlog -f 'glob:*'
1683 $ testlog -f 'glob:*'
1680 []
1684 []
1681 (group
1685 (group
1682 (func
1686 (and
1683 ('symbol', '_matchfiles')
1687 (func
1684 (list
1688 ('symbol', '_matchfiles')
1685 (list
1689 (list
1686 ('string', 'r:')
1690 (list
1687 ('string', 'd:relpath'))
1691 ('string', 'r:')
1688 ('string', 'p:glob:*'))))
1692 ('string', 'd:relpath'))
1693 ('string', 'p:glob:*')))
1694 (func
1695 ('symbol', 'ancestors')
1696 ('symbol', '.'))))
1689
1697
1690 Test --follow on a single rename
1698 Test --follow on a single rename
1691
1699
1692 $ hg up -q 2
1700 $ hg up -q 2
1693 $ testlog -f a
1701 $ testlog -f a
1694 []
1702 []
1695 (group
1703 (group
1696 (group
1704 (group
1697 (func
1705 (func
1698 ('symbol', 'follow')
1706 ('symbol', 'follow')
1699 ('string', 'a'))))
1707 ('string', 'a'))))
1700
1708
1701 Test --follow and multiple renames
1709 Test --follow and multiple renames
1702
1710
1703 $ hg up -q tip
1711 $ hg up -q tip
1704 $ testlog -f e
1712 $ testlog -f e
1705 []
1713 []
1706 (group
1714 (group
1707 (group
1715 (group
1708 (func
1716 (func
1709 ('symbol', 'follow')
1717 ('symbol', 'follow')
1710 ('string', 'e'))))
1718 ('string', 'e'))))
1711
1719
1712 Test --follow and multiple filelog heads
1720 Test --follow and multiple filelog heads
1713
1721
1714 $ hg up -q 2
1722 $ hg up -q 2
1715 $ testlog -f g
1723 $ testlog -f g
1716 []
1724 []
1717 (group
1725 (group
1718 (group
1726 (group
1719 (func
1727 (func
1720 ('symbol', 'follow')
1728 ('symbol', 'follow')
1721 ('string', 'g'))))
1729 ('string', 'g'))))
1722 $ cat log.nodes
1730 $ cat log.nodes
1723 nodetag 2
1731 nodetag 2
1724 nodetag 1
1732 nodetag 1
1725 nodetag 0
1733 nodetag 0
1726 $ hg up -q tip
1734 $ hg up -q tip
1727 $ testlog -f g
1735 $ testlog -f g
1728 []
1736 []
1729 (group
1737 (group
1730 (group
1738 (group
1731 (func
1739 (func
1732 ('symbol', 'follow')
1740 ('symbol', 'follow')
1733 ('string', 'g'))))
1741 ('string', 'g'))))
1734 $ cat log.nodes
1742 $ cat log.nodes
1735 nodetag 3
1743 nodetag 3
1736 nodetag 2
1744 nodetag 2
1737 nodetag 0
1745 nodetag 0
1738
1746
1739 Test --follow and multiple files
1747 Test --follow and multiple files
1740
1748
1741 $ testlog -f g e
1749 $ testlog -f g e
1742 []
1750 []
1743 (group
1751 (group
1744 (group
1752 (group
1745 (or
1753 (or
1746 (func
1754 (func
1747 ('symbol', 'follow')
1755 ('symbol', 'follow')
1748 ('string', 'g'))
1756 ('string', 'g'))
1749 (func
1757 (func
1750 ('symbol', 'follow')
1758 ('symbol', 'follow')
1751 ('string', 'e')))))
1759 ('string', 'e')))))
1752 $ cat log.nodes
1760 $ cat log.nodes
1753 nodetag 4
1761 nodetag 4
1754 nodetag 3
1762 nodetag 3
1755 nodetag 2
1763 nodetag 2
1756 nodetag 1
1764 nodetag 1
1757 nodetag 0
1765 nodetag 0
1758
1766
1759 Test --follow-first
1767 Test --follow-first
1760
1768
1761 $ hg up -q 3
1769 $ hg up -q 3
1762 $ echo ee > e
1770 $ echo ee > e
1763 $ hg ci -Am "add another e" e
1771 $ hg ci -Am "add another e" e
1764 created new head
1772 created new head
1765 $ hg merge --tool internal:other 4
1773 $ hg merge --tool internal:other 4
1766 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
1774 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
1767 (branch merge, don't forget to commit)
1775 (branch merge, don't forget to commit)
1768 $ echo merge > e
1776 $ echo merge > e
1769 $ hg ci -m "merge 5 and 4"
1777 $ hg ci -m "merge 5 and 4"
1770 $ testlog --follow-first
1778 $ testlog --follow-first
1771 []
1779 []
1772 (group
1780 (group
1773 (func
1781 (func
1774 ('symbol', '_firstancestors')
1782 ('symbol', '_firstancestors')
1775 ('symbol', '6')))
1783 ('symbol', '6')))
1776
1784
1777 Cannot compare with log --follow-first FILE as it never worked
1785 Cannot compare with log --follow-first FILE as it never worked
1778
1786
1779 $ hg log -G --print-revset --follow-first e
1787 $ hg log -G --print-revset --follow-first e
1780 []
1788 []
1781 (group
1789 (group
1782 (group
1790 (group
1783 (func
1791 (func
1784 ('symbol', '_followfirst')
1792 ('symbol', '_followfirst')
1785 ('string', 'e'))))
1793 ('string', 'e'))))
1786 $ hg log -G --follow-first e --template '{rev} {desc|firstline}\n'
1794 $ hg log -G --follow-first e --template '{rev} {desc|firstline}\n'
1787 @ 6 merge 5 and 4
1795 @ 6 merge 5 and 4
1788 |\
1796 |\
1789 o | 5 add another e
1797 o | 5 add another e
1790 | |
1798 | |
1791
1799
1792 Test --copies
1800 Test --copies
1793
1801
1794 $ hg log -G --copies --template "{rev} {desc|firstline} \
1802 $ hg log -G --copies --template "{rev} {desc|firstline} \
1795 > copies: {file_copies_switch}\n"
1803 > copies: {file_copies_switch}\n"
1796 @ 6 merge 5 and 4 copies:
1804 @ 6 merge 5 and 4 copies:
1797 |\
1805 |\
1798 | o 5 add another e copies:
1806 | o 5 add another e copies:
1799 | |
1807 | |
1800 o | 4 mv dir/b e copies: e (dir/b)
1808 o | 4 mv dir/b e copies: e (dir/b)
1801 |/
1809 |/
1802 o 3 mv a b; add d copies: b (a)g (f)
1810 o 3 mv a b; add d copies: b (a)g (f)
1803 |
1811 |
1804 o 2 mv b dir/b copies: dir/b (b)
1812 o 2 mv b dir/b copies: dir/b (b)
1805 |
1813 |
1806 o 1 copy a b copies: b (a)g (f)
1814 o 1 copy a b copies: b (a)g (f)
1807 |
1815 |
1808 o 0 add a copies:
1816 o 0 add a copies:
1809
1817
1810 Test "set:..." and parent revision
1818 Test "set:..." and parent revision
1811
1819
1812 $ hg up -q 4
1820 $ hg up -q 4
1813 $ testlog "set:copied()"
1821 $ testlog "set:copied()"
1814 []
1822 []
1815 (group
1823 (group
1816 (func
1824 (func
1817 ('symbol', '_matchfiles')
1825 ('symbol', '_matchfiles')
1818 (list
1826 (list
1819 (list
1827 (list
1820 ('string', 'r:')
1828 ('string', 'r:')
1821 ('string', 'd:relpath'))
1829 ('string', 'd:relpath'))
1822 ('string', 'p:set:copied()'))))
1830 ('string', 'p:set:copied()'))))
1823 $ testlog --include "set:copied()"
1831 $ testlog --include "set:copied()"
1824 []
1832 []
1825 (group
1833 (group
1826 (func
1834 (func
1827 ('symbol', '_matchfiles')
1835 ('symbol', '_matchfiles')
1828 (list
1836 (list
1829 (list
1837 (list
1830 ('string', 'r:')
1838 ('string', 'r:')
1831 ('string', 'd:relpath'))
1839 ('string', 'd:relpath'))
1832 ('string', 'i:set:copied()'))))
1840 ('string', 'i:set:copied()'))))
1833 $ testlog -r "sort(file('set:copied()'), -rev)"
1841 $ testlog -r "sort(file('set:copied()'), -rev)"
1834 ["sort(file('set:copied()'), -rev)"]
1842 ["sort(file('set:copied()'), -rev)"]
1835 []
1843 []
1836
1844
1837 Test --removed
1845 Test --removed
1838
1846
1839 $ testlog --removed
1847 $ testlog --removed
1840 []
1848 []
1841 []
1849 []
1842 $ testlog --removed a
1850 $ testlog --removed a
1843 []
1851 []
1844 (group
1852 (group
1845 (func
1853 (func
1846 ('symbol', '_matchfiles')
1854 ('symbol', '_matchfiles')
1847 (list
1855 (list
1848 (list
1856 (list
1849 ('string', 'r:')
1857 ('string', 'r:')
1850 ('string', 'd:relpath'))
1858 ('string', 'd:relpath'))
1851 ('string', 'p:a'))))
1859 ('string', 'p:a'))))
1852 $ testlog --removed --follow a
1860 $ testlog --removed --follow a
1853 []
1861 []
1854 (group
1862 (group
1855 (func
1863 (and
1856 ('symbol', '_matchfiles')
1864 (func
1857 (list
1865 ('symbol', '_matchfiles')
1858 (list
1866 (list
1859 ('string', 'r:')
1867 (list
1860 ('string', 'd:relpath'))
1868 ('string', 'r:')
1861 ('string', 'p:a'))))
1869 ('string', 'd:relpath'))
1870 ('string', 'p:a')))
1871 (func
1872 ('symbol', 'ancestors')
1873 ('symbol', '.'))))
1862
1874
1863 Test --patch and --stat with --follow and --follow-first
1875 Test --patch and --stat with --follow and --follow-first
1864
1876
1865 $ hg up -q 3
1877 $ hg up -q 3
1866 $ hg log -G --git --patch b
1878 $ hg log -G --git --patch b
1867 o changeset: 1:216d4c92cf98
1879 o changeset: 1:216d4c92cf98
1868 | user: test
1880 | user: test
1869 | date: Thu Jan 01 00:00:00 1970 +0000
1881 | date: Thu Jan 01 00:00:00 1970 +0000
1870 | summary: copy a b
1882 | summary: copy a b
1871 |
1883 |
1872 | diff --git a/a b/b
1884 | diff --git a/a b/b
1873 | copy from a
1885 | copy from a
1874 | copy to b
1886 | copy to b
1875 |
1887 |
1876
1888
1877 $ hg log -G --git --stat b
1889 $ hg log -G --git --stat b
1878 o changeset: 1:216d4c92cf98
1890 o changeset: 1:216d4c92cf98
1879 | user: test
1891 | user: test
1880 | date: Thu Jan 01 00:00:00 1970 +0000
1892 | date: Thu Jan 01 00:00:00 1970 +0000
1881 | summary: copy a b
1893 | summary: copy a b
1882 |
1894 |
1883 | b | 0
1895 | b | 0
1884 | 1 files changed, 0 insertions(+), 0 deletions(-)
1896 | 1 files changed, 0 insertions(+), 0 deletions(-)
1885 |
1897 |
1886
1898
1887 $ hg log -G --git --patch --follow b
1899 $ hg log -G --git --patch --follow b
1888 o changeset: 1:216d4c92cf98
1900 o changeset: 1:216d4c92cf98
1889 | user: test
1901 | user: test
1890 | date: Thu Jan 01 00:00:00 1970 +0000
1902 | date: Thu Jan 01 00:00:00 1970 +0000
1891 | summary: copy a b
1903 | summary: copy a b
1892 |
1904 |
1893 | diff --git a/a b/b
1905 | diff --git a/a b/b
1894 | copy from a
1906 | copy from a
1895 | copy to b
1907 | copy to b
1896 |
1908 |
1897 o changeset: 0:f8035bb17114
1909 o changeset: 0:f8035bb17114
1898 user: test
1910 user: test
1899 date: Thu Jan 01 00:00:00 1970 +0000
1911 date: Thu Jan 01 00:00:00 1970 +0000
1900 summary: add a
1912 summary: add a
1901
1913
1902 diff --git a/a b/a
1914 diff --git a/a b/a
1903 new file mode 100644
1915 new file mode 100644
1904 --- /dev/null
1916 --- /dev/null
1905 +++ b/a
1917 +++ b/a
1906 @@ -0,0 +1,1 @@
1918 @@ -0,0 +1,1 @@
1907 +a
1919 +a
1908
1920
1909
1921
1910 $ hg log -G --git --stat --follow b
1922 $ hg log -G --git --stat --follow b
1911 o changeset: 1:216d4c92cf98
1923 o changeset: 1:216d4c92cf98
1912 | user: test
1924 | user: test
1913 | date: Thu Jan 01 00:00:00 1970 +0000
1925 | date: Thu Jan 01 00:00:00 1970 +0000
1914 | summary: copy a b
1926 | summary: copy a b
1915 |
1927 |
1916 | b | 0
1928 | b | 0
1917 | 1 files changed, 0 insertions(+), 0 deletions(-)
1929 | 1 files changed, 0 insertions(+), 0 deletions(-)
1918 |
1930 |
1919 o changeset: 0:f8035bb17114
1931 o changeset: 0:f8035bb17114
1920 user: test
1932 user: test
1921 date: Thu Jan 01 00:00:00 1970 +0000
1933 date: Thu Jan 01 00:00:00 1970 +0000
1922 summary: add a
1934 summary: add a
1923
1935
1924 a | 1 +
1936 a | 1 +
1925 1 files changed, 1 insertions(+), 0 deletions(-)
1937 1 files changed, 1 insertions(+), 0 deletions(-)
1926
1938
1927
1939
1928 $ hg up -q 6
1940 $ hg up -q 6
1929 $ hg log -G --git --patch --follow-first e
1941 $ hg log -G --git --patch --follow-first e
1930 @ changeset: 6:fc281d8ff18d
1942 @ changeset: 6:fc281d8ff18d
1931 |\ tag: tip
1943 |\ tag: tip
1932 | | parent: 5:99b31f1c2782
1944 | | parent: 5:99b31f1c2782
1933 | | parent: 4:17d952250a9d
1945 | | parent: 4:17d952250a9d
1934 | | user: test
1946 | | user: test
1935 | | date: Thu Jan 01 00:00:00 1970 +0000
1947 | | date: Thu Jan 01 00:00:00 1970 +0000
1936 | | summary: merge 5 and 4
1948 | | summary: merge 5 and 4
1937 | |
1949 | |
1938 | | diff --git a/e b/e
1950 | | diff --git a/e b/e
1939 | | --- a/e
1951 | | --- a/e
1940 | | +++ b/e
1952 | | +++ b/e
1941 | | @@ -1,1 +1,1 @@
1953 | | @@ -1,1 +1,1 @@
1942 | | -ee
1954 | | -ee
1943 | | +merge
1955 | | +merge
1944 | |
1956 | |
1945 o | changeset: 5:99b31f1c2782
1957 o | changeset: 5:99b31f1c2782
1946 | | parent: 3:5918b8d165d1
1958 | | parent: 3:5918b8d165d1
1947 | | user: test
1959 | | user: test
1948 | | date: Thu Jan 01 00:00:00 1970 +0000
1960 | | date: Thu Jan 01 00:00:00 1970 +0000
1949 | | summary: add another e
1961 | | summary: add another e
1950 | |
1962 | |
1951 | | diff --git a/e b/e
1963 | | diff --git a/e b/e
1952 | | new file mode 100644
1964 | | new file mode 100644
1953 | | --- /dev/null
1965 | | --- /dev/null
1954 | | +++ b/e
1966 | | +++ b/e
1955 | | @@ -0,0 +1,1 @@
1967 | | @@ -0,0 +1,1 @@
1956 | | +ee
1968 | | +ee
1957 | |
1969 | |
1958
1970
1959 Test old-style --rev
1971 Test old-style --rev
1960
1972
1961 $ hg tag 'foo-bar'
1973 $ hg tag 'foo-bar'
1962 $ testlog -r 'foo-bar'
1974 $ testlog -r 'foo-bar'
1963 ['foo-bar']
1975 ['foo-bar']
1964 []
1976 []
1965
1977
1966 Test --follow and forward --rev
1978 Test --follow and forward --rev
1967
1979
1968 $ hg up -q 6
1980 $ hg up -q 6
1969 $ echo g > g
1981 $ echo g > g
1970 $ hg ci -Am 'add g' g
1982 $ hg ci -Am 'add g' g
1971 created new head
1983 created new head
1972 $ hg up -q 2
1984 $ hg up -q 2
1973 $ hg log -G --template "{rev} {desc|firstline}\n"
1985 $ hg log -G --template "{rev} {desc|firstline}\n"
1974 o 8 add g
1986 o 8 add g
1975 |
1987 |
1976 | o 7 Added tag foo-bar for changeset fc281d8ff18d
1988 | o 7 Added tag foo-bar for changeset fc281d8ff18d
1977 |/
1989 |/
1978 o 6 merge 5 and 4
1990 o 6 merge 5 and 4
1979 |\
1991 |\
1980 | o 5 add another e
1992 | o 5 add another e
1981 | |
1993 | |
1982 o | 4 mv dir/b e
1994 o | 4 mv dir/b e
1983 |/
1995 |/
1984 o 3 mv a b; add d
1996 o 3 mv a b; add d
1985 |
1997 |
1986 @ 2 mv b dir/b
1998 @ 2 mv b dir/b
1987 |
1999 |
1988 o 1 copy a b
2000 o 1 copy a b
1989 |
2001 |
1990 o 0 add a
2002 o 0 add a
1991
2003
1992 $ hg export 'all()'
2004 $ hg export 'all()'
1993 # HG changeset patch
2005 # HG changeset patch
1994 # User test
2006 # User test
1995 # Date 0 0
2007 # Date 0 0
1996 # Thu Jan 01 00:00:00 1970 +0000
2008 # Thu Jan 01 00:00:00 1970 +0000
1997 # Node ID f8035bb17114da16215af3436ec5222428ace8ee
2009 # Node ID f8035bb17114da16215af3436ec5222428ace8ee
1998 # Parent 0000000000000000000000000000000000000000
2010 # Parent 0000000000000000000000000000000000000000
1999 add a
2011 add a
2000
2012
2001 diff -r 000000000000 -r f8035bb17114 a
2013 diff -r 000000000000 -r f8035bb17114 a
2002 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2014 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2003 +++ b/a Thu Jan 01 00:00:00 1970 +0000
2015 +++ b/a Thu Jan 01 00:00:00 1970 +0000
2004 @@ -0,0 +1,1 @@
2016 @@ -0,0 +1,1 @@
2005 +a
2017 +a
2006 diff -r 000000000000 -r f8035bb17114 aa
2018 diff -r 000000000000 -r f8035bb17114 aa
2007 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2019 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2008 +++ b/aa Thu Jan 01 00:00:00 1970 +0000
2020 +++ b/aa Thu Jan 01 00:00:00 1970 +0000
2009 @@ -0,0 +1,1 @@
2021 @@ -0,0 +1,1 @@
2010 +aa
2022 +aa
2011 diff -r 000000000000 -r f8035bb17114 f
2023 diff -r 000000000000 -r f8035bb17114 f
2012 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2024 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2013 +++ b/f Thu Jan 01 00:00:00 1970 +0000
2025 +++ b/f Thu Jan 01 00:00:00 1970 +0000
2014 @@ -0,0 +1,1 @@
2026 @@ -0,0 +1,1 @@
2015 +f
2027 +f
2016 # HG changeset patch
2028 # HG changeset patch
2017 # User test
2029 # User test
2018 # Date 0 0
2030 # Date 0 0
2019 # Thu Jan 01 00:00:00 1970 +0000
2031 # Thu Jan 01 00:00:00 1970 +0000
2020 # Node ID 216d4c92cf98ff2b4641d508b76b529f3d424c92
2032 # Node ID 216d4c92cf98ff2b4641d508b76b529f3d424c92
2021 # Parent f8035bb17114da16215af3436ec5222428ace8ee
2033 # Parent f8035bb17114da16215af3436ec5222428ace8ee
2022 copy a b
2034 copy a b
2023
2035
2024 diff -r f8035bb17114 -r 216d4c92cf98 b
2036 diff -r f8035bb17114 -r 216d4c92cf98 b
2025 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2037 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2026 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2038 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2027 @@ -0,0 +1,1 @@
2039 @@ -0,0 +1,1 @@
2028 +a
2040 +a
2029 diff -r f8035bb17114 -r 216d4c92cf98 g
2041 diff -r f8035bb17114 -r 216d4c92cf98 g
2030 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2042 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2031 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2043 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2032 @@ -0,0 +1,1 @@
2044 @@ -0,0 +1,1 @@
2033 +f
2045 +f
2034 # HG changeset patch
2046 # HG changeset patch
2035 # User test
2047 # User test
2036 # Date 0 0
2048 # Date 0 0
2037 # Thu Jan 01 00:00:00 1970 +0000
2049 # Thu Jan 01 00:00:00 1970 +0000
2038 # Node ID bb573313a9e8349099b6ea2b2fb1fc7f424446f3
2050 # Node ID bb573313a9e8349099b6ea2b2fb1fc7f424446f3
2039 # Parent 216d4c92cf98ff2b4641d508b76b529f3d424c92
2051 # Parent 216d4c92cf98ff2b4641d508b76b529f3d424c92
2040 mv b dir/b
2052 mv b dir/b
2041
2053
2042 diff -r 216d4c92cf98 -r bb573313a9e8 b
2054 diff -r 216d4c92cf98 -r bb573313a9e8 b
2043 --- a/b Thu Jan 01 00:00:00 1970 +0000
2055 --- a/b Thu Jan 01 00:00:00 1970 +0000
2044 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2056 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2045 @@ -1,1 +0,0 @@
2057 @@ -1,1 +0,0 @@
2046 -a
2058 -a
2047 diff -r 216d4c92cf98 -r bb573313a9e8 dir/b
2059 diff -r 216d4c92cf98 -r bb573313a9e8 dir/b
2048 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2060 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2049 +++ b/dir/b Thu Jan 01 00:00:00 1970 +0000
2061 +++ b/dir/b Thu Jan 01 00:00:00 1970 +0000
2050 @@ -0,0 +1,1 @@
2062 @@ -0,0 +1,1 @@
2051 +a
2063 +a
2052 diff -r 216d4c92cf98 -r bb573313a9e8 f
2064 diff -r 216d4c92cf98 -r bb573313a9e8 f
2053 --- a/f Thu Jan 01 00:00:00 1970 +0000
2065 --- a/f Thu Jan 01 00:00:00 1970 +0000
2054 +++ b/f Thu Jan 01 00:00:00 1970 +0000
2066 +++ b/f Thu Jan 01 00:00:00 1970 +0000
2055 @@ -1,1 +1,2 @@
2067 @@ -1,1 +1,2 @@
2056 f
2068 f
2057 +f
2069 +f
2058 diff -r 216d4c92cf98 -r bb573313a9e8 g
2070 diff -r 216d4c92cf98 -r bb573313a9e8 g
2059 --- a/g Thu Jan 01 00:00:00 1970 +0000
2071 --- a/g Thu Jan 01 00:00:00 1970 +0000
2060 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2072 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2061 @@ -1,1 +1,2 @@
2073 @@ -1,1 +1,2 @@
2062 f
2074 f
2063 +g
2075 +g
2064 # HG changeset patch
2076 # HG changeset patch
2065 # User test
2077 # User test
2066 # Date 0 0
2078 # Date 0 0
2067 # Thu Jan 01 00:00:00 1970 +0000
2079 # Thu Jan 01 00:00:00 1970 +0000
2068 # Node ID 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2080 # Node ID 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2069 # Parent bb573313a9e8349099b6ea2b2fb1fc7f424446f3
2081 # Parent bb573313a9e8349099b6ea2b2fb1fc7f424446f3
2070 mv a b; add d
2082 mv a b; add d
2071
2083
2072 diff -r bb573313a9e8 -r 5918b8d165d1 a
2084 diff -r bb573313a9e8 -r 5918b8d165d1 a
2073 --- a/a Thu Jan 01 00:00:00 1970 +0000
2085 --- a/a Thu Jan 01 00:00:00 1970 +0000
2074 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2086 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2075 @@ -1,1 +0,0 @@
2087 @@ -1,1 +0,0 @@
2076 -a
2088 -a
2077 diff -r bb573313a9e8 -r 5918b8d165d1 b
2089 diff -r bb573313a9e8 -r 5918b8d165d1 b
2078 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2090 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2079 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2091 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2080 @@ -0,0 +1,1 @@
2092 @@ -0,0 +1,1 @@
2081 +a
2093 +a
2082 diff -r bb573313a9e8 -r 5918b8d165d1 d
2094 diff -r bb573313a9e8 -r 5918b8d165d1 d
2083 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2095 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2084 +++ b/d Thu Jan 01 00:00:00 1970 +0000
2096 +++ b/d Thu Jan 01 00:00:00 1970 +0000
2085 @@ -0,0 +1,1 @@
2097 @@ -0,0 +1,1 @@
2086 +a
2098 +a
2087 diff -r bb573313a9e8 -r 5918b8d165d1 g
2099 diff -r bb573313a9e8 -r 5918b8d165d1 g
2088 --- a/g Thu Jan 01 00:00:00 1970 +0000
2100 --- a/g Thu Jan 01 00:00:00 1970 +0000
2089 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2101 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2090 @@ -1,2 +1,2 @@
2102 @@ -1,2 +1,2 @@
2091 f
2103 f
2092 -g
2104 -g
2093 +f
2105 +f
2094 # HG changeset patch
2106 # HG changeset patch
2095 # User test
2107 # User test
2096 # Date 0 0
2108 # Date 0 0
2097 # Thu Jan 01 00:00:00 1970 +0000
2109 # Thu Jan 01 00:00:00 1970 +0000
2098 # Node ID 17d952250a9d03cc3dc77b199ab60e959b9b0260
2110 # Node ID 17d952250a9d03cc3dc77b199ab60e959b9b0260
2099 # Parent 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2111 # Parent 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2100 mv dir/b e
2112 mv dir/b e
2101
2113
2102 diff -r 5918b8d165d1 -r 17d952250a9d dir/b
2114 diff -r 5918b8d165d1 -r 17d952250a9d dir/b
2103 --- a/dir/b Thu Jan 01 00:00:00 1970 +0000
2115 --- a/dir/b Thu Jan 01 00:00:00 1970 +0000
2104 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2116 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2105 @@ -1,1 +0,0 @@
2117 @@ -1,1 +0,0 @@
2106 -a
2118 -a
2107 diff -r 5918b8d165d1 -r 17d952250a9d e
2119 diff -r 5918b8d165d1 -r 17d952250a9d e
2108 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2120 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2109 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2121 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2110 @@ -0,0 +1,1 @@
2122 @@ -0,0 +1,1 @@
2111 +a
2123 +a
2112 # HG changeset patch
2124 # HG changeset patch
2113 # User test
2125 # User test
2114 # Date 0 0
2126 # Date 0 0
2115 # Thu Jan 01 00:00:00 1970 +0000
2127 # Thu Jan 01 00:00:00 1970 +0000
2116 # Node ID 99b31f1c2782e2deb1723cef08930f70fc84b37b
2128 # Node ID 99b31f1c2782e2deb1723cef08930f70fc84b37b
2117 # Parent 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2129 # Parent 5918b8d165d1364e78a66d02e66caa0133c5d1ed
2118 add another e
2130 add another e
2119
2131
2120 diff -r 5918b8d165d1 -r 99b31f1c2782 e
2132 diff -r 5918b8d165d1 -r 99b31f1c2782 e
2121 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2133 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2122 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2134 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2123 @@ -0,0 +1,1 @@
2135 @@ -0,0 +1,1 @@
2124 +ee
2136 +ee
2125 # HG changeset patch
2137 # HG changeset patch
2126 # User test
2138 # User test
2127 # Date 0 0
2139 # Date 0 0
2128 # Thu Jan 01 00:00:00 1970 +0000
2140 # Thu Jan 01 00:00:00 1970 +0000
2129 # Node ID fc281d8ff18d999ad6497b3d27390bcd695dcc73
2141 # Node ID fc281d8ff18d999ad6497b3d27390bcd695dcc73
2130 # Parent 99b31f1c2782e2deb1723cef08930f70fc84b37b
2142 # Parent 99b31f1c2782e2deb1723cef08930f70fc84b37b
2131 # Parent 17d952250a9d03cc3dc77b199ab60e959b9b0260
2143 # Parent 17d952250a9d03cc3dc77b199ab60e959b9b0260
2132 merge 5 and 4
2144 merge 5 and 4
2133
2145
2134 diff -r 99b31f1c2782 -r fc281d8ff18d dir/b
2146 diff -r 99b31f1c2782 -r fc281d8ff18d dir/b
2135 --- a/dir/b Thu Jan 01 00:00:00 1970 +0000
2147 --- a/dir/b Thu Jan 01 00:00:00 1970 +0000
2136 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2148 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2137 @@ -1,1 +0,0 @@
2149 @@ -1,1 +0,0 @@
2138 -a
2150 -a
2139 diff -r 99b31f1c2782 -r fc281d8ff18d e
2151 diff -r 99b31f1c2782 -r fc281d8ff18d e
2140 --- a/e Thu Jan 01 00:00:00 1970 +0000
2152 --- a/e Thu Jan 01 00:00:00 1970 +0000
2141 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2153 +++ b/e Thu Jan 01 00:00:00 1970 +0000
2142 @@ -1,1 +1,1 @@
2154 @@ -1,1 +1,1 @@
2143 -ee
2155 -ee
2144 +merge
2156 +merge
2145 # HG changeset patch
2157 # HG changeset patch
2146 # User test
2158 # User test
2147 # Date 0 0
2159 # Date 0 0
2148 # Thu Jan 01 00:00:00 1970 +0000
2160 # Thu Jan 01 00:00:00 1970 +0000
2149 # Node ID 02dbb8e276b8ab7abfd07cab50c901647e75c2dd
2161 # Node ID 02dbb8e276b8ab7abfd07cab50c901647e75c2dd
2150 # Parent fc281d8ff18d999ad6497b3d27390bcd695dcc73
2162 # Parent fc281d8ff18d999ad6497b3d27390bcd695dcc73
2151 Added tag foo-bar for changeset fc281d8ff18d
2163 Added tag foo-bar for changeset fc281d8ff18d
2152
2164
2153 diff -r fc281d8ff18d -r 02dbb8e276b8 .hgtags
2165 diff -r fc281d8ff18d -r 02dbb8e276b8 .hgtags
2154 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2166 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2155 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2167 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2156 @@ -0,0 +1,1 @@
2168 @@ -0,0 +1,1 @@
2157 +fc281d8ff18d999ad6497b3d27390bcd695dcc73 foo-bar
2169 +fc281d8ff18d999ad6497b3d27390bcd695dcc73 foo-bar
2158 # HG changeset patch
2170 # HG changeset patch
2159 # User test
2171 # User test
2160 # Date 0 0
2172 # Date 0 0
2161 # Thu Jan 01 00:00:00 1970 +0000
2173 # Thu Jan 01 00:00:00 1970 +0000
2162 # Node ID 24c2e826ddebf80f9dcd60b856bdb8e6715c5449
2174 # Node ID 24c2e826ddebf80f9dcd60b856bdb8e6715c5449
2163 # Parent fc281d8ff18d999ad6497b3d27390bcd695dcc73
2175 # Parent fc281d8ff18d999ad6497b3d27390bcd695dcc73
2164 add g
2176 add g
2165
2177
2166 diff -r fc281d8ff18d -r 24c2e826ddeb g
2178 diff -r fc281d8ff18d -r 24c2e826ddeb g
2167 --- a/g Thu Jan 01 00:00:00 1970 +0000
2179 --- a/g Thu Jan 01 00:00:00 1970 +0000
2168 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2180 +++ b/g Thu Jan 01 00:00:00 1970 +0000
2169 @@ -1,2 +1,1 @@
2181 @@ -1,2 +1,1 @@
2170 -f
2182 -f
2171 -f
2183 -f
2172 +g
2184 +g
2173 $ testlog --follow -r6 -r8 -r5 -r7 -r4
2185 $ testlog --follow -r6 -r8 -r5 -r7 -r4
2174 ['6', '8', '5', '7', '4']
2186 ['6', '8', '5', '7', '4']
2175 (group
2187 (group
2176 (func
2188 (func
2177 ('symbol', 'descendants')
2189 ('symbol', 'descendants')
2178 ('symbol', '6')))
2190 ('symbol', '6')))
2179 --- log.nodes * (glob)
2191 --- log.nodes * (glob)
2180 +++ glog.nodes * (glob)
2192 +++ glog.nodes * (glob)
2181 @@ -1,3 +1,3 @@
2193 @@ -1,3 +1,3 @@
2182 -nodetag 6
2194 -nodetag 6
2183 nodetag 8
2195 nodetag 8
2184 nodetag 7
2196 nodetag 7
2185 +nodetag 6
2197 +nodetag 6
2186
2198
2187 Test --follow-first and forward --rev
2199 Test --follow-first and forward --rev
2188
2200
2189 $ testlog --follow-first -r6 -r8 -r5 -r7 -r4
2201 $ testlog --follow-first -r6 -r8 -r5 -r7 -r4
2190 ['6', '8', '5', '7', '4']
2202 ['6', '8', '5', '7', '4']
2191 (group
2203 (group
2192 (func
2204 (func
2193 ('symbol', '_firstdescendants')
2205 ('symbol', '_firstdescendants')
2194 ('symbol', '6')))
2206 ('symbol', '6')))
2195 --- log.nodes * (glob)
2207 --- log.nodes * (glob)
2196 +++ glog.nodes * (glob)
2208 +++ glog.nodes * (glob)
2197 @@ -1,3 +1,3 @@
2209 @@ -1,3 +1,3 @@
2198 -nodetag 6
2210 -nodetag 6
2199 nodetag 8
2211 nodetag 8
2200 nodetag 7
2212 nodetag 7
2201 +nodetag 6
2213 +nodetag 6
2202
2214
2203 Test --follow and backward --rev
2215 Test --follow and backward --rev
2204
2216
2205 $ testlog --follow -r6 -r5 -r7 -r8 -r4
2217 $ testlog --follow -r6 -r5 -r7 -r8 -r4
2206 ['6', '5', '7', '8', '4']
2218 ['6', '5', '7', '8', '4']
2207 (group
2219 (group
2208 (func
2220 (func
2209 ('symbol', 'ancestors')
2221 ('symbol', 'ancestors')
2210 ('symbol', '6')))
2222 ('symbol', '6')))
2211
2223
2212 Test --follow-first and backward --rev
2224 Test --follow-first and backward --rev
2213
2225
2214 $ testlog --follow-first -r6 -r5 -r7 -r8 -r4
2226 $ testlog --follow-first -r6 -r5 -r7 -r8 -r4
2215 ['6', '5', '7', '8', '4']
2227 ['6', '5', '7', '8', '4']
2216 (group
2228 (group
2217 (func
2229 (func
2218 ('symbol', '_firstancestors')
2230 ('symbol', '_firstancestors')
2219 ('symbol', '6')))
2231 ('symbol', '6')))
2220
2232
2221 Test subdir
2233 Test subdir
2222
2234
2223 $ hg up -q 3
2235 $ hg up -q 3
2224 $ cd dir
2236 $ cd dir
2225 $ testlog .
2237 $ testlog .
2226 []
2238 []
2227 (group
2239 (group
2228 (func
2240 (func
2229 ('symbol', '_matchfiles')
2241 ('symbol', '_matchfiles')
2230 (list
2242 (list
2231 (list
2243 (list
2232 ('string', 'r:')
2244 ('string', 'r:')
2233 ('string', 'd:relpath'))
2245 ('string', 'd:relpath'))
2234 ('string', 'p:.'))))
2246 ('string', 'p:.'))))
2235 $ testlog ../b
2247 $ testlog ../b
2236 []
2248 []
2237 (group
2249 (group
2238 (group
2250 (group
2239 (func
2251 (func
2240 ('symbol', 'filelog')
2252 ('symbol', 'filelog')
2241 ('string', '../b'))))
2253 ('string', '../b'))))
2242 $ testlog -f ../b
2254 $ testlog -f ../b
2243 []
2255 []
2244 (group
2256 (group
2245 (group
2257 (group
2246 (func
2258 (func
2247 ('symbol', 'follow')
2259 ('symbol', 'follow')
2248 ('string', 'b'))))
2260 ('string', 'b'))))
2249 $ cd ..
2261 $ cd ..
2250
2262
2251 Test --hidden
2263 Test --hidden
2252 (enable obsolete)
2264 (enable obsolete)
2253
2265
2254 $ cat >> $HGRCPATH << EOF
2266 $ cat >> $HGRCPATH << EOF
2255 > [experimental]
2267 > [experimental]
2256 > evolution=createmarkers
2268 > evolution=createmarkers
2257 > EOF
2269 > EOF
2258
2270
2259 $ hg debugobsolete `hg id --debug -i -r 8`
2271 $ hg debugobsolete `hg id --debug -i -r 8`
2260 $ testlog
2272 $ testlog
2261 []
2273 []
2262 []
2274 []
2263 $ testlog --hidden
2275 $ testlog --hidden
2264 []
2276 []
2265 []
2277 []
2266 $ hg log -G --template '{rev} {desc}\n'
2278 $ hg log -G --template '{rev} {desc}\n'
2267 o 7 Added tag foo-bar for changeset fc281d8ff18d
2279 o 7 Added tag foo-bar for changeset fc281d8ff18d
2268 |
2280 |
2269 o 6 merge 5 and 4
2281 o 6 merge 5 and 4
2270 |\
2282 |\
2271 | o 5 add another e
2283 | o 5 add another e
2272 | |
2284 | |
2273 o | 4 mv dir/b e
2285 o | 4 mv dir/b e
2274 |/
2286 |/
2275 @ 3 mv a b; add d
2287 @ 3 mv a b; add d
2276 |
2288 |
2277 o 2 mv b dir/b
2289 o 2 mv b dir/b
2278 |
2290 |
2279 o 1 copy a b
2291 o 1 copy a b
2280 |
2292 |
2281 o 0 add a
2293 o 0 add a
2282
2294
2283
2295
2284 A template without trailing newline should do something sane
2296 A template without trailing newline should do something sane
2285
2297
2286 $ hg log -G -r ::2 --template '{rev} {desc}'
2298 $ hg log -G -r ::2 --template '{rev} {desc}'
2287 o 2 mv b dir/b
2299 o 2 mv b dir/b
2288 |
2300 |
2289 o 1 copy a b
2301 o 1 copy a b
2290 |
2302 |
2291 o 0 add a
2303 o 0 add a
2292
2304
2293
2305
2294 Extra newlines must be preserved
2306 Extra newlines must be preserved
2295
2307
2296 $ hg log -G -r ::2 --template '\n{rev} {desc}\n\n'
2308 $ hg log -G -r ::2 --template '\n{rev} {desc}\n\n'
2297 o
2309 o
2298 | 2 mv b dir/b
2310 | 2 mv b dir/b
2299 |
2311 |
2300 o
2312 o
2301 | 1 copy a b
2313 | 1 copy a b
2302 |
2314 |
2303 o
2315 o
2304 0 add a
2316 0 add a
2305
2317
2306
2318
2307 The almost-empty template should do something sane too ...
2319 The almost-empty template should do something sane too ...
2308
2320
2309 $ hg log -G -r ::2 --template '\n'
2321 $ hg log -G -r ::2 --template '\n'
2310 o
2322 o
2311 |
2323 |
2312 o
2324 o
2313 |
2325 |
2314 o
2326 o
2315
2327
2316
2328
2317 issue3772
2329 issue3772
2318
2330
2319 $ hg log -G -r :null
2331 $ hg log -G -r :null
2320 o changeset: 0:f8035bb17114
2332 o changeset: 0:f8035bb17114
2321 | user: test
2333 | user: test
2322 | date: Thu Jan 01 00:00:00 1970 +0000
2334 | date: Thu Jan 01 00:00:00 1970 +0000
2323 | summary: add a
2335 | summary: add a
2324 |
2336 |
2325 o changeset: -1:000000000000
2337 o changeset: -1:000000000000
2326 user:
2338 user:
2327 date: Thu Jan 01 00:00:00 1970 +0000
2339 date: Thu Jan 01 00:00:00 1970 +0000
2328
2340
2329 $ hg log -G -r null:null
2341 $ hg log -G -r null:null
2330 o changeset: -1:000000000000
2342 o changeset: -1:000000000000
2331 user:
2343 user:
2332 date: Thu Jan 01 00:00:00 1970 +0000
2344 date: Thu Jan 01 00:00:00 1970 +0000
2333
2345
2334
2346
2335 $ cd ..
2347 $ cd ..
@@ -1,1545 +1,1566 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 $ hg log a
48 $ hg log a
49 changeset: 0:9161b9aeaf16
49 changeset: 0:9161b9aeaf16
50 user: test
50 user: test
51 date: Thu Jan 01 00:00:01 1970 +0000
51 date: Thu Jan 01 00:00:01 1970 +0000
52 summary: a
52 summary: a
53
53
54 log on directory
54 log on directory
55
55
56 $ hg log dir
56 $ hg log dir
57 changeset: 4:7e4639b4691b
57 changeset: 4:7e4639b4691b
58 tag: tip
58 tag: tip
59 user: test
59 user: test
60 date: Thu Jan 01 00:00:05 1970 +0000
60 date: Thu Jan 01 00:00:05 1970 +0000
61 summary: e
61 summary: e
62
62
63 changeset: 2:f8954cd4dc1f
63 changeset: 2:f8954cd4dc1f
64 user: test
64 user: test
65 date: Thu Jan 01 00:00:03 1970 +0000
65 date: Thu Jan 01 00:00:03 1970 +0000
66 summary: c
66 summary: c
67
67
68 $ hg log somethingthatdoesntexist dir
68 $ hg log somethingthatdoesntexist dir
69 changeset: 4:7e4639b4691b
69 changeset: 4:7e4639b4691b
70 tag: tip
70 tag: tip
71 user: test
71 user: test
72 date: Thu Jan 01 00:00:05 1970 +0000
72 date: Thu Jan 01 00:00:05 1970 +0000
73 summary: e
73 summary: e
74
74
75 changeset: 2:f8954cd4dc1f
75 changeset: 2:f8954cd4dc1f
76 user: test
76 user: test
77 date: Thu Jan 01 00:00:03 1970 +0000
77 date: Thu Jan 01 00:00:03 1970 +0000
78 summary: c
78 summary: c
79
79
80
80
81 -f, non-existent directory
81 -f, non-existent directory
82
82
83 $ hg log -f dir
83 $ hg log -f dir
84 abort: cannot follow file not in parent revision: "dir"
84 abort: cannot follow file not in parent revision: "dir"
85 [255]
85 [255]
86
86
87 -f, directory
87 -f, directory
88
88
89 $ hg up -q 3
89 $ hg up -q 3
90 $ hg log -f dir
90 $ hg log -f dir
91 changeset: 2:f8954cd4dc1f
91 changeset: 2:f8954cd4dc1f
92 user: test
92 user: test
93 date: Thu Jan 01 00:00:03 1970 +0000
93 date: Thu Jan 01 00:00:03 1970 +0000
94 summary: c
94 summary: c
95
95
96 -f, directory with --patch
96 -f, directory with --patch
97
97
98 $ hg log -f dir -p
98 $ hg log -f dir -p
99 changeset: 2:f8954cd4dc1f
99 changeset: 2:f8954cd4dc1f
100 user: test
100 user: test
101 date: Thu Jan 01 00:00:03 1970 +0000
101 date: Thu Jan 01 00:00:03 1970 +0000
102 summary: c
102 summary: c
103
103
104 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
104 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
105 --- /dev/null* (glob)
105 --- /dev/null* (glob)
106 +++ b/dir/b* (glob)
106 +++ b/dir/b* (glob)
107 @@ -0,0 +1,1 @@
107 @@ -0,0 +1,1 @@
108 +a
108 +a
109
109
110
110
111 -f, pattern
111 -f, pattern
112
112
113 $ hg log -f -I 'dir**' -p
113 $ hg log -f -I 'dir**' -p
114 changeset: 2:f8954cd4dc1f
114 changeset: 2:f8954cd4dc1f
115 user: test
115 user: test
116 date: Thu Jan 01 00:00:03 1970 +0000
116 date: Thu Jan 01 00:00:03 1970 +0000
117 summary: c
117 summary: c
118
118
119 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
119 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
120 --- /dev/null* (glob)
120 --- /dev/null* (glob)
121 +++ b/dir/b* (glob)
121 +++ b/dir/b* (glob)
122 @@ -0,0 +1,1 @@
122 @@ -0,0 +1,1 @@
123 +a
123 +a
124
124
125 $ hg up -q 4
125 $ hg up -q 4
126
126
127 -f, a wrong style
127 -f, a wrong style
128
128
129 $ hg log -f -l1 --style something
129 $ hg log -f -l1 --style something
130 abort: style 'something' not found
130 abort: style 'something' not found
131 (available styles: bisect, changelog, compact, default, phases, xml)
131 (available styles: bisect, changelog, compact, default, phases, xml)
132 [255]
132 [255]
133
133
134 -f, phases style
134 -f, phases style
135
135
136
136
137 $ hg log -f -l1 --style phases
137 $ hg log -f -l1 --style phases
138 changeset: 4:7e4639b4691b
138 changeset: 4:7e4639b4691b
139 tag: tip
139 tag: tip
140 phase: draft
140 phase: draft
141 user: test
141 user: test
142 date: Thu Jan 01 00:00:05 1970 +0000
142 date: Thu Jan 01 00:00:05 1970 +0000
143 summary: e
143 summary: e
144
144
145
145
146 -f, but no args
146 -f, but no args
147
147
148 $ hg log -f
148 $ hg log -f
149 changeset: 4:7e4639b4691b
149 changeset: 4:7e4639b4691b
150 tag: tip
150 tag: tip
151 user: test
151 user: test
152 date: Thu Jan 01 00:00:05 1970 +0000
152 date: Thu Jan 01 00:00:05 1970 +0000
153 summary: e
153 summary: e
154
154
155 changeset: 3:2ca5ba701980
155 changeset: 3:2ca5ba701980
156 user: test
156 user: test
157 date: Thu Jan 01 00:00:04 1970 +0000
157 date: Thu Jan 01 00:00:04 1970 +0000
158 summary: d
158 summary: d
159
159
160 changeset: 2:f8954cd4dc1f
160 changeset: 2:f8954cd4dc1f
161 user: test
161 user: test
162 date: Thu Jan 01 00:00:03 1970 +0000
162 date: Thu Jan 01 00:00:03 1970 +0000
163 summary: c
163 summary: c
164
164
165 changeset: 1:d89b0a12d229
165 changeset: 1:d89b0a12d229
166 user: test
166 user: test
167 date: Thu Jan 01 00:00:02 1970 +0000
167 date: Thu Jan 01 00:00:02 1970 +0000
168 summary: b
168 summary: b
169
169
170 changeset: 0:9161b9aeaf16
170 changeset: 0:9161b9aeaf16
171 user: test
171 user: test
172 date: Thu Jan 01 00:00:01 1970 +0000
172 date: Thu Jan 01 00:00:01 1970 +0000
173 summary: a
173 summary: a
174
174
175
175
176 one rename
176 one rename
177
177
178 $ hg up -q 2
178 $ hg up -q 2
179 $ hg log -vf a
179 $ hg log -vf a
180 changeset: 0:9161b9aeaf16
180 changeset: 0:9161b9aeaf16
181 user: test
181 user: test
182 date: Thu Jan 01 00:00:01 1970 +0000
182 date: Thu Jan 01 00:00:01 1970 +0000
183 files: a f
183 files: a f
184 description:
184 description:
185 a
185 a
186
186
187
187
188
188
189 many renames
189 many renames
190
190
191 $ hg up -q tip
191 $ hg up -q tip
192 $ hg log -vf e
192 $ hg log -vf e
193 changeset: 4:7e4639b4691b
193 changeset: 4:7e4639b4691b
194 tag: tip
194 tag: tip
195 user: test
195 user: test
196 date: Thu Jan 01 00:00:05 1970 +0000
196 date: Thu Jan 01 00:00:05 1970 +0000
197 files: dir/b e
197 files: dir/b e
198 description:
198 description:
199 e
199 e
200
200
201
201
202 changeset: 2:f8954cd4dc1f
202 changeset: 2:f8954cd4dc1f
203 user: test
203 user: test
204 date: Thu Jan 01 00:00:03 1970 +0000
204 date: Thu Jan 01 00:00:03 1970 +0000
205 files: b dir/b f g
205 files: b dir/b f g
206 description:
206 description:
207 c
207 c
208
208
209
209
210 changeset: 1:d89b0a12d229
210 changeset: 1:d89b0a12d229
211 user: test
211 user: test
212 date: Thu Jan 01 00:00:02 1970 +0000
212 date: Thu Jan 01 00:00:02 1970 +0000
213 files: b g
213 files: b g
214 description:
214 description:
215 b
215 b
216
216
217
217
218 changeset: 0:9161b9aeaf16
218 changeset: 0:9161b9aeaf16
219 user: test
219 user: test
220 date: Thu Jan 01 00:00:01 1970 +0000
220 date: Thu Jan 01 00:00:01 1970 +0000
221 files: a f
221 files: a f
222 description:
222 description:
223 a
223 a
224
224
225
225
226
226
227
227
228 log -pf dir/b
228 log -pf dir/b
229
229
230 $ hg up -q 3
230 $ hg up -q 3
231 $ hg log -pf dir/b
231 $ hg log -pf dir/b
232 changeset: 2:f8954cd4dc1f
232 changeset: 2:f8954cd4dc1f
233 user: test
233 user: test
234 date: Thu Jan 01 00:00:03 1970 +0000
234 date: Thu Jan 01 00:00:03 1970 +0000
235 summary: c
235 summary: c
236
236
237 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
237 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
238 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
238 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
239 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
239 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
240 @@ -0,0 +1,1 @@
240 @@ -0,0 +1,1 @@
241 +a
241 +a
242
242
243 changeset: 1:d89b0a12d229
243 changeset: 1:d89b0a12d229
244 user: test
244 user: test
245 date: Thu Jan 01 00:00:02 1970 +0000
245 date: Thu Jan 01 00:00:02 1970 +0000
246 summary: b
246 summary: b
247
247
248 diff -r 9161b9aeaf16 -r d89b0a12d229 b
248 diff -r 9161b9aeaf16 -r d89b0a12d229 b
249 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
249 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
250 +++ b/b Thu Jan 01 00:00:02 1970 +0000
250 +++ b/b Thu Jan 01 00:00:02 1970 +0000
251 @@ -0,0 +1,1 @@
251 @@ -0,0 +1,1 @@
252 +a
252 +a
253
253
254 changeset: 0:9161b9aeaf16
254 changeset: 0:9161b9aeaf16
255 user: test
255 user: test
256 date: Thu Jan 01 00:00:01 1970 +0000
256 date: Thu Jan 01 00:00:01 1970 +0000
257 summary: a
257 summary: a
258
258
259 diff -r 000000000000 -r 9161b9aeaf16 a
259 diff -r 000000000000 -r 9161b9aeaf16 a
260 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
260 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
261 +++ b/a Thu Jan 01 00:00:01 1970 +0000
261 +++ b/a Thu Jan 01 00:00:01 1970 +0000
262 @@ -0,0 +1,1 @@
262 @@ -0,0 +1,1 @@
263 +a
263 +a
264
264
265
265
266 log -pf b inside dir
266 log -pf b inside dir
267
267
268 $ hg --cwd=dir log -pf b
268 $ hg --cwd=dir log -pf b
269 changeset: 2:f8954cd4dc1f
269 changeset: 2:f8954cd4dc1f
270 user: test
270 user: test
271 date: Thu Jan 01 00:00:03 1970 +0000
271 date: Thu Jan 01 00:00:03 1970 +0000
272 summary: c
272 summary: c
273
273
274 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
274 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
275 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
275 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
276 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
276 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
277 @@ -0,0 +1,1 @@
277 @@ -0,0 +1,1 @@
278 +a
278 +a
279
279
280 changeset: 1:d89b0a12d229
280 changeset: 1:d89b0a12d229
281 user: test
281 user: test
282 date: Thu Jan 01 00:00:02 1970 +0000
282 date: Thu Jan 01 00:00:02 1970 +0000
283 summary: b
283 summary: b
284
284
285 diff -r 9161b9aeaf16 -r d89b0a12d229 b
285 diff -r 9161b9aeaf16 -r d89b0a12d229 b
286 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
286 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
287 +++ b/b Thu Jan 01 00:00:02 1970 +0000
287 +++ b/b Thu Jan 01 00:00:02 1970 +0000
288 @@ -0,0 +1,1 @@
288 @@ -0,0 +1,1 @@
289 +a
289 +a
290
290
291 changeset: 0:9161b9aeaf16
291 changeset: 0:9161b9aeaf16
292 user: test
292 user: test
293 date: Thu Jan 01 00:00:01 1970 +0000
293 date: Thu Jan 01 00:00:01 1970 +0000
294 summary: a
294 summary: a
295
295
296 diff -r 000000000000 -r 9161b9aeaf16 a
296 diff -r 000000000000 -r 9161b9aeaf16 a
297 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
297 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
298 +++ b/a Thu Jan 01 00:00:01 1970 +0000
298 +++ b/a Thu Jan 01 00:00:01 1970 +0000
299 @@ -0,0 +1,1 @@
299 @@ -0,0 +1,1 @@
300 +a
300 +a
301
301
302
302
303 log -pf, but no args
303 log -pf, but no args
304
304
305 $ hg log -pf
305 $ hg log -pf
306 changeset: 3:2ca5ba701980
306 changeset: 3:2ca5ba701980
307 user: test
307 user: test
308 date: Thu Jan 01 00:00:04 1970 +0000
308 date: Thu Jan 01 00:00:04 1970 +0000
309 summary: d
309 summary: d
310
310
311 diff -r f8954cd4dc1f -r 2ca5ba701980 a
311 diff -r f8954cd4dc1f -r 2ca5ba701980 a
312 --- a/a Thu Jan 01 00:00:03 1970 +0000
312 --- a/a Thu Jan 01 00:00:03 1970 +0000
313 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
313 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
314 @@ -1,1 +0,0 @@
314 @@ -1,1 +0,0 @@
315 -a
315 -a
316 diff -r f8954cd4dc1f -r 2ca5ba701980 b
316 diff -r f8954cd4dc1f -r 2ca5ba701980 b
317 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
317 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
318 +++ b/b Thu Jan 01 00:00:04 1970 +0000
318 +++ b/b Thu Jan 01 00:00:04 1970 +0000
319 @@ -0,0 +1,1 @@
319 @@ -0,0 +1,1 @@
320 +a
320 +a
321 diff -r f8954cd4dc1f -r 2ca5ba701980 d
321 diff -r f8954cd4dc1f -r 2ca5ba701980 d
322 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
322 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
323 +++ b/d Thu Jan 01 00:00:04 1970 +0000
323 +++ b/d Thu Jan 01 00:00:04 1970 +0000
324 @@ -0,0 +1,1 @@
324 @@ -0,0 +1,1 @@
325 +a
325 +a
326 diff -r f8954cd4dc1f -r 2ca5ba701980 g
326 diff -r f8954cd4dc1f -r 2ca5ba701980 g
327 --- a/g Thu Jan 01 00:00:03 1970 +0000
327 --- a/g Thu Jan 01 00:00:03 1970 +0000
328 +++ b/g Thu Jan 01 00:00:04 1970 +0000
328 +++ b/g Thu Jan 01 00:00:04 1970 +0000
329 @@ -1,2 +1,2 @@
329 @@ -1,2 +1,2 @@
330 f
330 f
331 -g
331 -g
332 +f
332 +f
333
333
334 changeset: 2:f8954cd4dc1f
334 changeset: 2:f8954cd4dc1f
335 user: test
335 user: test
336 date: Thu Jan 01 00:00:03 1970 +0000
336 date: Thu Jan 01 00:00:03 1970 +0000
337 summary: c
337 summary: c
338
338
339 diff -r d89b0a12d229 -r f8954cd4dc1f b
339 diff -r d89b0a12d229 -r f8954cd4dc1f b
340 --- a/b Thu Jan 01 00:00:02 1970 +0000
340 --- a/b Thu Jan 01 00:00:02 1970 +0000
341 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
341 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
342 @@ -1,1 +0,0 @@
342 @@ -1,1 +0,0 @@
343 -a
343 -a
344 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
344 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
345 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
345 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
346 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
346 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
347 @@ -0,0 +1,1 @@
347 @@ -0,0 +1,1 @@
348 +a
348 +a
349 diff -r d89b0a12d229 -r f8954cd4dc1f f
349 diff -r d89b0a12d229 -r f8954cd4dc1f f
350 --- a/f Thu Jan 01 00:00:02 1970 +0000
350 --- a/f Thu Jan 01 00:00:02 1970 +0000
351 +++ b/f Thu Jan 01 00:00:03 1970 +0000
351 +++ b/f Thu Jan 01 00:00:03 1970 +0000
352 @@ -1,1 +1,2 @@
352 @@ -1,1 +1,2 @@
353 f
353 f
354 +f
354 +f
355 diff -r d89b0a12d229 -r f8954cd4dc1f g
355 diff -r d89b0a12d229 -r f8954cd4dc1f g
356 --- a/g Thu Jan 01 00:00:02 1970 +0000
356 --- a/g Thu Jan 01 00:00:02 1970 +0000
357 +++ b/g Thu Jan 01 00:00:03 1970 +0000
357 +++ b/g Thu Jan 01 00:00:03 1970 +0000
358 @@ -1,1 +1,2 @@
358 @@ -1,1 +1,2 @@
359 f
359 f
360 +g
360 +g
361
361
362 changeset: 1:d89b0a12d229
362 changeset: 1:d89b0a12d229
363 user: test
363 user: test
364 date: Thu Jan 01 00:00:02 1970 +0000
364 date: Thu Jan 01 00:00:02 1970 +0000
365 summary: b
365 summary: b
366
366
367 diff -r 9161b9aeaf16 -r d89b0a12d229 b
367 diff -r 9161b9aeaf16 -r d89b0a12d229 b
368 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
368 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
369 +++ b/b Thu Jan 01 00:00:02 1970 +0000
369 +++ b/b Thu Jan 01 00:00:02 1970 +0000
370 @@ -0,0 +1,1 @@
370 @@ -0,0 +1,1 @@
371 +a
371 +a
372 diff -r 9161b9aeaf16 -r d89b0a12d229 g
372 diff -r 9161b9aeaf16 -r d89b0a12d229 g
373 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
373 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
374 +++ b/g Thu Jan 01 00:00:02 1970 +0000
374 +++ b/g Thu Jan 01 00:00:02 1970 +0000
375 @@ -0,0 +1,1 @@
375 @@ -0,0 +1,1 @@
376 +f
376 +f
377
377
378 changeset: 0:9161b9aeaf16
378 changeset: 0:9161b9aeaf16
379 user: test
379 user: test
380 date: Thu Jan 01 00:00:01 1970 +0000
380 date: Thu Jan 01 00:00:01 1970 +0000
381 summary: a
381 summary: a
382
382
383 diff -r 000000000000 -r 9161b9aeaf16 a
383 diff -r 000000000000 -r 9161b9aeaf16 a
384 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
384 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
385 +++ b/a Thu Jan 01 00:00:01 1970 +0000
385 +++ b/a Thu Jan 01 00:00:01 1970 +0000
386 @@ -0,0 +1,1 @@
386 @@ -0,0 +1,1 @@
387 +a
387 +a
388 diff -r 000000000000 -r 9161b9aeaf16 f
388 diff -r 000000000000 -r 9161b9aeaf16 f
389 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
389 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
390 +++ b/f Thu Jan 01 00:00:01 1970 +0000
390 +++ b/f Thu Jan 01 00:00:01 1970 +0000
391 @@ -0,0 +1,1 @@
391 @@ -0,0 +1,1 @@
392 +f
392 +f
393
393
394
394
395 log -vf dir/b
395 log -vf dir/b
396
396
397 $ hg log -vf dir/b
397 $ hg log -vf dir/b
398 changeset: 2:f8954cd4dc1f
398 changeset: 2:f8954cd4dc1f
399 user: test
399 user: test
400 date: Thu Jan 01 00:00:03 1970 +0000
400 date: Thu Jan 01 00:00:03 1970 +0000
401 files: b dir/b f g
401 files: b dir/b f g
402 description:
402 description:
403 c
403 c
404
404
405
405
406 changeset: 1:d89b0a12d229
406 changeset: 1:d89b0a12d229
407 user: test
407 user: test
408 date: Thu Jan 01 00:00:02 1970 +0000
408 date: Thu Jan 01 00:00:02 1970 +0000
409 files: b g
409 files: b g
410 description:
410 description:
411 b
411 b
412
412
413
413
414 changeset: 0:9161b9aeaf16
414 changeset: 0:9161b9aeaf16
415 user: test
415 user: test
416 date: Thu Jan 01 00:00:01 1970 +0000
416 date: Thu Jan 01 00:00:01 1970 +0000
417 files: a f
417 files: a f
418 description:
418 description:
419 a
419 a
420
420
421
421
422
422
423
423
424 -f and multiple filelog heads
424 -f and multiple filelog heads
425
425
426 $ hg up -q 2
426 $ hg up -q 2
427 $ hg log -f g --template '{rev}\n'
427 $ hg log -f g --template '{rev}\n'
428 2
428 2
429 1
429 1
430 0
430 0
431 $ hg up -q tip
431 $ hg up -q tip
432 $ hg log -f g --template '{rev}\n'
432 $ hg log -f g --template '{rev}\n'
433 3
433 3
434 2
434 2
435 0
435 0
436
436
437
437
438 log copies with --copies
438 log copies with --copies
439
439
440 $ hg log -vC --template '{rev} {file_copies}\n'
440 $ hg log -vC --template '{rev} {file_copies}\n'
441 4 e (dir/b)
441 4 e (dir/b)
442 3 b (a)g (f)
442 3 b (a)g (f)
443 2 dir/b (b)
443 2 dir/b (b)
444 1 b (a)g (f)
444 1 b (a)g (f)
445 0
445 0
446
446
447 log copies switch without --copies, with old filecopy template
447 log copies switch without --copies, with old filecopy template
448
448
449 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
449 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
450 4
450 4
451 3
451 3
452 2
452 2
453 1
453 1
454 0
454 0
455
455
456 log copies switch with --copies
456 log copies switch with --copies
457
457
458 $ hg log -vC --template '{rev} {file_copies_switch}\n'
458 $ hg log -vC --template '{rev} {file_copies_switch}\n'
459 4 e (dir/b)
459 4 e (dir/b)
460 3 b (a)g (f)
460 3 b (a)g (f)
461 2 dir/b (b)
461 2 dir/b (b)
462 1 b (a)g (f)
462 1 b (a)g (f)
463 0
463 0
464
464
465
465
466 log copies with hardcoded style and with --style=default
466 log copies with hardcoded style and with --style=default
467
467
468 $ hg log -vC -r4
468 $ hg log -vC -r4
469 changeset: 4:7e4639b4691b
469 changeset: 4:7e4639b4691b
470 tag: tip
470 tag: tip
471 user: test
471 user: test
472 date: Thu Jan 01 00:00:05 1970 +0000
472 date: Thu Jan 01 00:00:05 1970 +0000
473 files: dir/b e
473 files: dir/b e
474 copies: e (dir/b)
474 copies: e (dir/b)
475 description:
475 description:
476 e
476 e
477
477
478
478
479 $ hg log -vC -r4 --style=default
479 $ hg log -vC -r4 --style=default
480 changeset: 4:7e4639b4691b
480 changeset: 4:7e4639b4691b
481 tag: tip
481 tag: tip
482 user: test
482 user: test
483 date: Thu Jan 01 00:00:05 1970 +0000
483 date: Thu Jan 01 00:00:05 1970 +0000
484 files: dir/b e
484 files: dir/b e
485 copies: e (dir/b)
485 copies: e (dir/b)
486 description:
486 description:
487 e
487 e
488
488
489
489
490
490
491
491
492 log copies, non-linear manifest
492 log copies, non-linear manifest
493
493
494 $ hg up -C 3
494 $ hg up -C 3
495 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
495 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
496 $ hg mv dir/b e
496 $ hg mv dir/b e
497 $ echo foo > foo
497 $ echo foo > foo
498 $ hg ci -Ame2 -d '6 0'
498 $ hg ci -Ame2 -d '6 0'
499 adding foo
499 adding foo
500 created new head
500 created new head
501 $ hg log -v --template '{rev} {file_copies}\n' -r 5
501 $ hg log -v --template '{rev} {file_copies}\n' -r 5
502 5 e (dir/b)
502 5 e (dir/b)
503
503
504
504
505 log copies, execute bit set
505 log copies, execute bit set
506
506
507 #if execbit
507 #if execbit
508 $ chmod +x e
508 $ chmod +x e
509 $ hg ci -me3 -d '7 0'
509 $ hg ci -me3 -d '7 0'
510 $ hg log -v --template '{rev} {file_copies}\n' -r 6
510 $ hg log -v --template '{rev} {file_copies}\n' -r 6
511 6
511 6
512 #endif
512 #endif
513
513
514
514
515 log -p d
515 log -p d
516
516
517 $ hg log -pv d
517 $ hg log -pv d
518 changeset: 3:2ca5ba701980
518 changeset: 3:2ca5ba701980
519 user: test
519 user: test
520 date: Thu Jan 01 00:00:04 1970 +0000
520 date: Thu Jan 01 00:00:04 1970 +0000
521 files: a b d g
521 files: a b d g
522 description:
522 description:
523 d
523 d
524
524
525
525
526 diff -r f8954cd4dc1f -r 2ca5ba701980 d
526 diff -r f8954cd4dc1f -r 2ca5ba701980 d
527 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
527 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
528 +++ b/d Thu Jan 01 00:00:04 1970 +0000
528 +++ b/d Thu Jan 01 00:00:04 1970 +0000
529 @@ -0,0 +1,1 @@
529 @@ -0,0 +1,1 @@
530 +a
530 +a
531
531
532
532
533
533
534 log --removed file
534 log --removed file
535
535
536 $ hg log --removed -v a
536 $ hg log --removed -v a
537 changeset: 3:2ca5ba701980
537 changeset: 3:2ca5ba701980
538 user: test
538 user: test
539 date: Thu Jan 01 00:00:04 1970 +0000
539 date: Thu Jan 01 00:00:04 1970 +0000
540 files: a b d g
540 files: a b d g
541 description:
541 description:
542 d
542 d
543
543
544
544
545 changeset: 0:9161b9aeaf16
545 changeset: 0:9161b9aeaf16
546 user: test
546 user: test
547 date: Thu Jan 01 00:00:01 1970 +0000
547 date: Thu Jan 01 00:00:01 1970 +0000
548 files: a f
548 files: a f
549 description:
549 description:
550 a
550 a
551
551
552
552
553
553
554 log --removed revrange file
554 log --removed revrange file
555
555
556 $ hg log --removed -v -r0:2 a
556 $ hg log --removed -v -r0:2 a
557 changeset: 0:9161b9aeaf16
557 changeset: 0:9161b9aeaf16
558 user: test
558 user: test
559 date: Thu Jan 01 00:00:01 1970 +0000
559 date: Thu Jan 01 00:00:01 1970 +0000
560 files: a f
560 files: a f
561 description:
561 description:
562 a
562 a
563
563
564
564
565 $ cd ..
565 $ cd ..
566
566
567 log --follow tests
567 log --follow tests
568
568
569 $ hg init follow
569 $ hg init follow
570 $ cd follow
570 $ cd follow
571
571
572 $ echo base > base
572 $ echo base > base
573 $ hg ci -Ambase -d '1 0'
573 $ hg ci -Ambase -d '1 0'
574 adding base
574 adding base
575
575
576 $ echo r1 >> base
576 $ echo r1 >> base
577 $ hg ci -Amr1 -d '1 0'
577 $ hg ci -Amr1 -d '1 0'
578 $ echo r2 >> base
578 $ echo r2 >> base
579 $ hg ci -Amr2 -d '1 0'
579 $ hg ci -Amr2 -d '1 0'
580
580
581 $ hg up -C 1
581 $ hg up -C 1
582 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
582 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
583 $ echo b1 > b1
583 $ echo b1 > b1
584 $ hg ci -Amb1 -d '1 0'
584 $ hg ci -Amb1 -d '1 0'
585 adding b1
585 adding b1
586 created new head
586 created new head
587
587
588
588
589 log -f
589 log -f
590
590
591 $ hg log -f
591 $ hg log -f
592 changeset: 3:e62f78d544b4
592 changeset: 3:e62f78d544b4
593 tag: tip
593 tag: tip
594 parent: 1:3d5bf5654eda
594 parent: 1:3d5bf5654eda
595 user: test
595 user: test
596 date: Thu Jan 01 00:00:01 1970 +0000
596 date: Thu Jan 01 00:00:01 1970 +0000
597 summary: b1
597 summary: b1
598
598
599 changeset: 1:3d5bf5654eda
599 changeset: 1:3d5bf5654eda
600 user: test
600 user: test
601 date: Thu Jan 01 00:00:01 1970 +0000
601 date: Thu Jan 01 00:00:01 1970 +0000
602 summary: r1
602 summary: r1
603
603
604 changeset: 0:67e992f2c4f3
604 changeset: 0:67e992f2c4f3
605 user: test
605 user: test
606 date: Thu Jan 01 00:00:01 1970 +0000
606 date: Thu Jan 01 00:00:01 1970 +0000
607 summary: base
607 summary: base
608
608
609
609
610
610
611 log -f -r 1:tip
611 log -f -r 1:tip
612
612
613 $ hg up -C 0
613 $ hg up -C 0
614 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
614 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
615 $ echo b2 > b2
615 $ echo b2 > b2
616 $ hg ci -Amb2 -d '1 0'
616 $ hg ci -Amb2 -d '1 0'
617 adding b2
617 adding b2
618 created new head
618 created new head
619 $ hg log -f -r 1:tip
619 $ hg log -f -r 1:tip
620 changeset: 1:3d5bf5654eda
620 changeset: 1:3d5bf5654eda
621 user: test
621 user: test
622 date: Thu Jan 01 00:00:01 1970 +0000
622 date: Thu Jan 01 00:00:01 1970 +0000
623 summary: r1
623 summary: r1
624
624
625 changeset: 2:60c670bf5b30
625 changeset: 2:60c670bf5b30
626 user: test
626 user: test
627 date: Thu Jan 01 00:00:01 1970 +0000
627 date: Thu Jan 01 00:00:01 1970 +0000
628 summary: r2
628 summary: r2
629
629
630 changeset: 3:e62f78d544b4
630 changeset: 3:e62f78d544b4
631 parent: 1:3d5bf5654eda
631 parent: 1:3d5bf5654eda
632 user: test
632 user: test
633 date: Thu Jan 01 00:00:01 1970 +0000
633 date: Thu Jan 01 00:00:01 1970 +0000
634 summary: b1
634 summary: b1
635
635
636
636
637
637
638 log -r . with two parents
638 log -r . with two parents
639
639
640 $ hg up -C 3
640 $ hg up -C 3
641 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
641 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
642 $ hg merge tip
642 $ hg merge tip
643 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
643 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
644 (branch merge, don't forget to commit)
644 (branch merge, don't forget to commit)
645 $ hg log -r .
645 $ hg log -r .
646 changeset: 3:e62f78d544b4
646 changeset: 3:e62f78d544b4
647 parent: 1:3d5bf5654eda
647 parent: 1:3d5bf5654eda
648 user: test
648 user: test
649 date: Thu Jan 01 00:00:01 1970 +0000
649 date: Thu Jan 01 00:00:01 1970 +0000
650 summary: b1
650 summary: b1
651
651
652
652
653
653
654 log -r . with one parent
654 log -r . with one parent
655
655
656 $ hg ci -mm12 -d '1 0'
656 $ hg ci -mm12 -d '1 0'
657 $ hg log -r .
657 $ hg log -r .
658 changeset: 5:302e9dd6890d
658 changeset: 5:302e9dd6890d
659 tag: tip
659 tag: tip
660 parent: 3:e62f78d544b4
660 parent: 3:e62f78d544b4
661 parent: 4:ddb82e70d1a1
661 parent: 4:ddb82e70d1a1
662 user: test
662 user: test
663 date: Thu Jan 01 00:00:01 1970 +0000
663 date: Thu Jan 01 00:00:01 1970 +0000
664 summary: m12
664 summary: m12
665
665
666
666
667 $ echo postm >> b1
667 $ echo postm >> b1
668 $ hg ci -Amb1.1 -d'1 0'
668 $ hg ci -Amb1.1 -d'1 0'
669
669
670
670
671 log --follow-first
671 log --follow-first
672
672
673 $ hg log --follow-first
673 $ hg log --follow-first
674 changeset: 6:2404bbcab562
674 changeset: 6:2404bbcab562
675 tag: tip
675 tag: tip
676 user: test
676 user: test
677 date: Thu Jan 01 00:00:01 1970 +0000
677 date: Thu Jan 01 00:00:01 1970 +0000
678 summary: b1.1
678 summary: b1.1
679
679
680 changeset: 5:302e9dd6890d
680 changeset: 5:302e9dd6890d
681 parent: 3:e62f78d544b4
681 parent: 3:e62f78d544b4
682 parent: 4:ddb82e70d1a1
682 parent: 4:ddb82e70d1a1
683 user: test
683 user: test
684 date: Thu Jan 01 00:00:01 1970 +0000
684 date: Thu Jan 01 00:00:01 1970 +0000
685 summary: m12
685 summary: m12
686
686
687 changeset: 3:e62f78d544b4
687 changeset: 3:e62f78d544b4
688 parent: 1:3d5bf5654eda
688 parent: 1:3d5bf5654eda
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: b1
691 summary: b1
692
692
693 changeset: 1:3d5bf5654eda
693 changeset: 1:3d5bf5654eda
694 user: test
694 user: test
695 date: Thu Jan 01 00:00:01 1970 +0000
695 date: Thu Jan 01 00:00:01 1970 +0000
696 summary: r1
696 summary: r1
697
697
698 changeset: 0:67e992f2c4f3
698 changeset: 0:67e992f2c4f3
699 user: test
699 user: test
700 date: Thu Jan 01 00:00:01 1970 +0000
700 date: Thu Jan 01 00:00:01 1970 +0000
701 summary: base
701 summary: base
702
702
703
703
704
704
705 log -P 2
705 log -P 2
706
706
707 $ hg log -P 2
707 $ hg log -P 2
708 changeset: 6:2404bbcab562
708 changeset: 6:2404bbcab562
709 tag: tip
709 tag: tip
710 user: test
710 user: test
711 date: Thu Jan 01 00:00:01 1970 +0000
711 date: Thu Jan 01 00:00:01 1970 +0000
712 summary: b1.1
712 summary: b1.1
713
713
714 changeset: 5:302e9dd6890d
714 changeset: 5:302e9dd6890d
715 parent: 3:e62f78d544b4
715 parent: 3:e62f78d544b4
716 parent: 4:ddb82e70d1a1
716 parent: 4:ddb82e70d1a1
717 user: test
717 user: test
718 date: Thu Jan 01 00:00:01 1970 +0000
718 date: Thu Jan 01 00:00:01 1970 +0000
719 summary: m12
719 summary: m12
720
720
721 changeset: 4:ddb82e70d1a1
721 changeset: 4:ddb82e70d1a1
722 parent: 0:67e992f2c4f3
722 parent: 0:67e992f2c4f3
723 user: test
723 user: test
724 date: Thu Jan 01 00:00:01 1970 +0000
724 date: Thu Jan 01 00:00:01 1970 +0000
725 summary: b2
725 summary: b2
726
726
727 changeset: 3:e62f78d544b4
727 changeset: 3:e62f78d544b4
728 parent: 1:3d5bf5654eda
728 parent: 1:3d5bf5654eda
729 user: test
729 user: test
730 date: Thu Jan 01 00:00:01 1970 +0000
730 date: Thu Jan 01 00:00:01 1970 +0000
731 summary: b1
731 summary: b1
732
732
733
733
734
734
735 log -r tip -p --git
735 log -r tip -p --git
736
736
737 $ hg log -r tip -p --git
737 $ hg log -r tip -p --git
738 changeset: 6:2404bbcab562
738 changeset: 6:2404bbcab562
739 tag: tip
739 tag: tip
740 user: test
740 user: test
741 date: Thu Jan 01 00:00:01 1970 +0000
741 date: Thu Jan 01 00:00:01 1970 +0000
742 summary: b1.1
742 summary: b1.1
743
743
744 diff --git a/b1 b/b1
744 diff --git a/b1 b/b1
745 --- a/b1
745 --- a/b1
746 +++ b/b1
746 +++ b/b1
747 @@ -1,1 +1,2 @@
747 @@ -1,1 +1,2 @@
748 b1
748 b1
749 +postm
749 +postm
750
750
751
751
752
752
753 log -r ""
753 log -r ""
754
754
755 $ hg log -r ''
755 $ hg log -r ''
756 hg: parse error: empty query
756 hg: parse error: empty query
757 [255]
757 [255]
758
758
759 log -r <some unknown node id>
759 log -r <some unknown node id>
760
760
761 $ hg log -r 1000000000000000000000000000000000000000
761 $ hg log -r 1000000000000000000000000000000000000000
762 abort: unknown revision '1000000000000000000000000000000000000000'!
762 abort: unknown revision '1000000000000000000000000000000000000000'!
763 [255]
763 [255]
764
764
765 log -k r1
765 log -k r1
766
766
767 $ hg log -k r1
767 $ hg log -k r1
768 changeset: 1:3d5bf5654eda
768 changeset: 1:3d5bf5654eda
769 user: test
769 user: test
770 date: Thu Jan 01 00:00:01 1970 +0000
770 date: Thu Jan 01 00:00:01 1970 +0000
771 summary: r1
771 summary: r1
772
772
773 log -p -l2 --color=always
773 log -p -l2 --color=always
774
774
775 $ hg --config extensions.color= --config color.mode=ansi \
775 $ hg --config extensions.color= --config color.mode=ansi \
776 > log -p -l2 --color=always
776 > log -p -l2 --color=always
777 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
777 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
778 tag: tip
778 tag: tip
779 user: test
779 user: test
780 date: Thu Jan 01 00:00:01 1970 +0000
780 date: Thu Jan 01 00:00:01 1970 +0000
781 summary: b1.1
781 summary: b1.1
782
782
783 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
783 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
784 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
784 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
785 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
785 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
786 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
786 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
787 b1
787 b1
788 \x1b[0;32m+postm\x1b[0m (esc)
788 \x1b[0;32m+postm\x1b[0m (esc)
789
789
790 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
790 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
791 parent: 3:e62f78d544b4
791 parent: 3:e62f78d544b4
792 parent: 4:ddb82e70d1a1
792 parent: 4:ddb82e70d1a1
793 user: test
793 user: test
794 date: Thu Jan 01 00:00:01 1970 +0000
794 date: Thu Jan 01 00:00:01 1970 +0000
795 summary: m12
795 summary: m12
796
796
797 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
797 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
798 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
798 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
799 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
799 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
800 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
800 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
801 \x1b[0;32m+b2\x1b[0m (esc)
801 \x1b[0;32m+b2\x1b[0m (esc)
802
802
803
803
804
804
805 log -r tip --stat
805 log -r tip --stat
806
806
807 $ hg log -r tip --stat
807 $ hg log -r tip --stat
808 changeset: 6:2404bbcab562
808 changeset: 6:2404bbcab562
809 tag: tip
809 tag: tip
810 user: test
810 user: test
811 date: Thu Jan 01 00:00:01 1970 +0000
811 date: Thu Jan 01 00:00:01 1970 +0000
812 summary: b1.1
812 summary: b1.1
813
813
814 b1 | 1 +
814 b1 | 1 +
815 1 files changed, 1 insertions(+), 0 deletions(-)
815 1 files changed, 1 insertions(+), 0 deletions(-)
816
816
817
817
818 $ cd ..
818 $ cd ..
819
819
820
820
821 User
821 User
822
822
823 $ hg init usertest
823 $ hg init usertest
824 $ cd usertest
824 $ cd usertest
825
825
826 $ echo a > a
826 $ echo a > a
827 $ hg ci -A -m "a" -u "User One <user1@example.org>"
827 $ hg ci -A -m "a" -u "User One <user1@example.org>"
828 adding a
828 adding a
829 $ echo b > b
829 $ echo b > b
830 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
830 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
831 adding b
831 adding b
832
832
833 $ hg log -u "User One <user1@example.org>"
833 $ hg log -u "User One <user1@example.org>"
834 changeset: 0:29a4c94f1924
834 changeset: 0:29a4c94f1924
835 user: User One <user1@example.org>
835 user: User One <user1@example.org>
836 date: Thu Jan 01 00:00:00 1970 +0000
836 date: Thu Jan 01 00:00:00 1970 +0000
837 summary: a
837 summary: a
838
838
839 $ hg log -u "user1" -u "user2"
839 $ hg log -u "user1" -u "user2"
840 changeset: 1:e834b5e69c0e
840 changeset: 1:e834b5e69c0e
841 tag: tip
841 tag: tip
842 user: User Two <user2@example.org>
842 user: User Two <user2@example.org>
843 date: Thu Jan 01 00:00:00 1970 +0000
843 date: Thu Jan 01 00:00:00 1970 +0000
844 summary: b
844 summary: b
845
845
846 changeset: 0:29a4c94f1924
846 changeset: 0:29a4c94f1924
847 user: User One <user1@example.org>
847 user: User One <user1@example.org>
848 date: Thu Jan 01 00:00:00 1970 +0000
848 date: Thu Jan 01 00:00:00 1970 +0000
849 summary: a
849 summary: a
850
850
851 $ hg log -u "user3"
851 $ hg log -u "user3"
852
852
853 $ cd ..
853 $ cd ..
854
854
855 $ hg init branches
855 $ hg init branches
856 $ cd branches
856 $ cd branches
857
857
858 $ echo a > a
858 $ echo a > a
859 $ hg ci -A -m "commit on default"
859 $ hg ci -A -m "commit on default"
860 adding a
860 adding a
861 $ hg branch test
861 $ hg branch test
862 marked working directory as branch test
862 marked working directory as branch test
863 (branches are permanent and global, did you want a bookmark?)
863 (branches are permanent and global, did you want a bookmark?)
864 $ echo b > b
864 $ echo b > b
865 $ hg ci -A -m "commit on test"
865 $ hg ci -A -m "commit on test"
866 adding b
866 adding b
867
867
868 $ hg up default
868 $ hg up default
869 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
869 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
870 $ echo c > c
870 $ echo c > c
871 $ hg ci -A -m "commit on default"
871 $ hg ci -A -m "commit on default"
872 adding c
872 adding c
873 $ hg up test
873 $ hg up test
874 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
874 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
875 $ echo c > c
875 $ echo c > c
876 $ hg ci -A -m "commit on test"
876 $ hg ci -A -m "commit on test"
877 adding c
877 adding c
878
878
879
879
880 log -b default
880 log -b default
881
881
882 $ hg log -b default
882 $ hg log -b default
883 changeset: 2:c3a4f03cc9a7
883 changeset: 2:c3a4f03cc9a7
884 parent: 0:24427303d56f
884 parent: 0:24427303d56f
885 user: test
885 user: test
886 date: Thu Jan 01 00:00:00 1970 +0000
886 date: Thu Jan 01 00:00:00 1970 +0000
887 summary: commit on default
887 summary: commit on default
888
888
889 changeset: 0:24427303d56f
889 changeset: 0:24427303d56f
890 user: test
890 user: test
891 date: Thu Jan 01 00:00:00 1970 +0000
891 date: Thu Jan 01 00:00:00 1970 +0000
892 summary: commit on default
892 summary: commit on default
893
893
894
894
895
895
896 log -b test
896 log -b test
897
897
898 $ hg log -b test
898 $ hg log -b test
899 changeset: 3:f5d8de11c2e2
899 changeset: 3:f5d8de11c2e2
900 branch: test
900 branch: test
901 tag: tip
901 tag: tip
902 parent: 1:d32277701ccb
902 parent: 1:d32277701ccb
903 user: test
903 user: test
904 date: Thu Jan 01 00:00:00 1970 +0000
904 date: Thu Jan 01 00:00:00 1970 +0000
905 summary: commit on test
905 summary: commit on test
906
906
907 changeset: 1:d32277701ccb
907 changeset: 1:d32277701ccb
908 branch: test
908 branch: test
909 user: test
909 user: test
910 date: Thu Jan 01 00:00:00 1970 +0000
910 date: Thu Jan 01 00:00:00 1970 +0000
911 summary: commit on test
911 summary: commit on test
912
912
913
913
914
914
915 log -b dummy
915 log -b dummy
916
916
917 $ hg log -b dummy
917 $ hg log -b dummy
918 abort: unknown revision 'dummy'!
918 abort: unknown revision 'dummy'!
919 [255]
919 [255]
920
920
921
921
922 log -b .
922 log -b .
923
923
924 $ hg log -b .
924 $ hg log -b .
925 changeset: 3:f5d8de11c2e2
925 changeset: 3:f5d8de11c2e2
926 branch: test
926 branch: test
927 tag: tip
927 tag: tip
928 parent: 1:d32277701ccb
928 parent: 1:d32277701ccb
929 user: test
929 user: test
930 date: Thu Jan 01 00:00:00 1970 +0000
930 date: Thu Jan 01 00:00:00 1970 +0000
931 summary: commit on test
931 summary: commit on test
932
932
933 changeset: 1:d32277701ccb
933 changeset: 1:d32277701ccb
934 branch: test
934 branch: test
935 user: test
935 user: test
936 date: Thu Jan 01 00:00:00 1970 +0000
936 date: Thu Jan 01 00:00:00 1970 +0000
937 summary: commit on test
937 summary: commit on test
938
938
939
939
940
940
941 log -b default -b test
941 log -b default -b test
942
942
943 $ hg log -b default -b test
943 $ hg log -b default -b test
944 changeset: 3:f5d8de11c2e2
944 changeset: 3:f5d8de11c2e2
945 branch: test
945 branch: test
946 tag: tip
946 tag: tip
947 parent: 1:d32277701ccb
947 parent: 1:d32277701ccb
948 user: test
948 user: test
949 date: Thu Jan 01 00:00:00 1970 +0000
949 date: Thu Jan 01 00:00:00 1970 +0000
950 summary: commit on test
950 summary: commit on test
951
951
952 changeset: 2:c3a4f03cc9a7
952 changeset: 2:c3a4f03cc9a7
953 parent: 0:24427303d56f
953 parent: 0:24427303d56f
954 user: test
954 user: test
955 date: Thu Jan 01 00:00:00 1970 +0000
955 date: Thu Jan 01 00:00:00 1970 +0000
956 summary: commit on default
956 summary: commit on default
957
957
958 changeset: 1:d32277701ccb
958 changeset: 1:d32277701ccb
959 branch: test
959 branch: test
960 user: test
960 user: test
961 date: Thu Jan 01 00:00:00 1970 +0000
961 date: Thu Jan 01 00:00:00 1970 +0000
962 summary: commit on test
962 summary: commit on test
963
963
964 changeset: 0:24427303d56f
964 changeset: 0:24427303d56f
965 user: test
965 user: test
966 date: Thu Jan 01 00:00:00 1970 +0000
966 date: Thu Jan 01 00:00:00 1970 +0000
967 summary: commit on default
967 summary: commit on default
968
968
969
969
970
970
971 log -b default -b .
971 log -b default -b .
972
972
973 $ hg log -b default -b .
973 $ hg log -b default -b .
974 changeset: 3:f5d8de11c2e2
974 changeset: 3:f5d8de11c2e2
975 branch: test
975 branch: test
976 tag: tip
976 tag: tip
977 parent: 1:d32277701ccb
977 parent: 1:d32277701ccb
978 user: test
978 user: test
979 date: Thu Jan 01 00:00:00 1970 +0000
979 date: Thu Jan 01 00:00:00 1970 +0000
980 summary: commit on test
980 summary: commit on test
981
981
982 changeset: 2:c3a4f03cc9a7
982 changeset: 2:c3a4f03cc9a7
983 parent: 0:24427303d56f
983 parent: 0:24427303d56f
984 user: test
984 user: test
985 date: Thu Jan 01 00:00:00 1970 +0000
985 date: Thu Jan 01 00:00:00 1970 +0000
986 summary: commit on default
986 summary: commit on default
987
987
988 changeset: 1:d32277701ccb
988 changeset: 1:d32277701ccb
989 branch: test
989 branch: test
990 user: test
990 user: test
991 date: Thu Jan 01 00:00:00 1970 +0000
991 date: Thu Jan 01 00:00:00 1970 +0000
992 summary: commit on test
992 summary: commit on test
993
993
994 changeset: 0:24427303d56f
994 changeset: 0:24427303d56f
995 user: test
995 user: test
996 date: Thu Jan 01 00:00:00 1970 +0000
996 date: Thu Jan 01 00:00:00 1970 +0000
997 summary: commit on default
997 summary: commit on default
998
998
999
999
1000
1000
1001 log -b . -b test
1001 log -b . -b test
1002
1002
1003 $ hg log -b . -b test
1003 $ hg log -b . -b test
1004 changeset: 3:f5d8de11c2e2
1004 changeset: 3:f5d8de11c2e2
1005 branch: test
1005 branch: test
1006 tag: tip
1006 tag: tip
1007 parent: 1:d32277701ccb
1007 parent: 1:d32277701ccb
1008 user: test
1008 user: test
1009 date: Thu Jan 01 00:00:00 1970 +0000
1009 date: Thu Jan 01 00:00:00 1970 +0000
1010 summary: commit on test
1010 summary: commit on test
1011
1011
1012 changeset: 1:d32277701ccb
1012 changeset: 1:d32277701ccb
1013 branch: test
1013 branch: test
1014 user: test
1014 user: test
1015 date: Thu Jan 01 00:00:00 1970 +0000
1015 date: Thu Jan 01 00:00:00 1970 +0000
1016 summary: commit on test
1016 summary: commit on test
1017
1017
1018
1018
1019
1019
1020 log -b 2
1020 log -b 2
1021
1021
1022 $ hg log -b 2
1022 $ hg log -b 2
1023 changeset: 2:c3a4f03cc9a7
1023 changeset: 2:c3a4f03cc9a7
1024 parent: 0:24427303d56f
1024 parent: 0:24427303d56f
1025 user: test
1025 user: test
1026 date: Thu Jan 01 00:00:00 1970 +0000
1026 date: Thu Jan 01 00:00:00 1970 +0000
1027 summary: commit on default
1027 summary: commit on default
1028
1028
1029 changeset: 0:24427303d56f
1029 changeset: 0:24427303d56f
1030 user: test
1030 user: test
1031 date: Thu Jan 01 00:00:00 1970 +0000
1031 date: Thu Jan 01 00:00:00 1970 +0000
1032 summary: commit on default
1032 summary: commit on default
1033
1033
1034
1034
1035
1035
1036 log -p --cwd dir (in subdir)
1036 log -p --cwd dir (in subdir)
1037
1037
1038 $ mkdir dir
1038 $ mkdir dir
1039 $ hg log -p --cwd dir
1039 $ hg log -p --cwd dir
1040 changeset: 3:f5d8de11c2e2
1040 changeset: 3:f5d8de11c2e2
1041 branch: test
1041 branch: test
1042 tag: tip
1042 tag: tip
1043 parent: 1:d32277701ccb
1043 parent: 1:d32277701ccb
1044 user: test
1044 user: test
1045 date: Thu Jan 01 00:00:00 1970 +0000
1045 date: Thu Jan 01 00:00:00 1970 +0000
1046 summary: commit on test
1046 summary: commit on test
1047
1047
1048 diff -r d32277701ccb -r f5d8de11c2e2 c
1048 diff -r d32277701ccb -r f5d8de11c2e2 c
1049 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1049 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1050 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1050 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1051 @@ -0,0 +1,1 @@
1051 @@ -0,0 +1,1 @@
1052 +c
1052 +c
1053
1053
1054 changeset: 2:c3a4f03cc9a7
1054 changeset: 2:c3a4f03cc9a7
1055 parent: 0:24427303d56f
1055 parent: 0:24427303d56f
1056 user: test
1056 user: test
1057 date: Thu Jan 01 00:00:00 1970 +0000
1057 date: Thu Jan 01 00:00:00 1970 +0000
1058 summary: commit on default
1058 summary: commit on default
1059
1059
1060 diff -r 24427303d56f -r c3a4f03cc9a7 c
1060 diff -r 24427303d56f -r c3a4f03cc9a7 c
1061 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1061 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1062 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1062 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1063 @@ -0,0 +1,1 @@
1063 @@ -0,0 +1,1 @@
1064 +c
1064 +c
1065
1065
1066 changeset: 1:d32277701ccb
1066 changeset: 1:d32277701ccb
1067 branch: test
1067 branch: test
1068 user: test
1068 user: test
1069 date: Thu Jan 01 00:00:00 1970 +0000
1069 date: Thu Jan 01 00:00:00 1970 +0000
1070 summary: commit on test
1070 summary: commit on test
1071
1071
1072 diff -r 24427303d56f -r d32277701ccb b
1072 diff -r 24427303d56f -r d32277701ccb b
1073 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1073 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1074 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1074 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1075 @@ -0,0 +1,1 @@
1075 @@ -0,0 +1,1 @@
1076 +b
1076 +b
1077
1077
1078 changeset: 0:24427303d56f
1078 changeset: 0:24427303d56f
1079 user: test
1079 user: test
1080 date: Thu Jan 01 00:00:00 1970 +0000
1080 date: Thu Jan 01 00:00:00 1970 +0000
1081 summary: commit on default
1081 summary: commit on default
1082
1082
1083 diff -r 000000000000 -r 24427303d56f a
1083 diff -r 000000000000 -r 24427303d56f a
1084 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1084 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1085 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1085 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1086 @@ -0,0 +1,1 @@
1086 @@ -0,0 +1,1 @@
1087 +a
1087 +a
1088
1088
1089
1089
1090
1090
1091 log -p -R repo
1091 log -p -R repo
1092
1092
1093 $ cd dir
1093 $ cd dir
1094 $ hg log -p -R .. ../a
1094 $ hg log -p -R .. ../a
1095 changeset: 0:24427303d56f
1095 changeset: 0:24427303d56f
1096 user: test
1096 user: test
1097 date: Thu Jan 01 00:00:00 1970 +0000
1097 date: Thu Jan 01 00:00:00 1970 +0000
1098 summary: commit on default
1098 summary: commit on default
1099
1099
1100 diff -r 000000000000 -r 24427303d56f a
1100 diff -r 000000000000 -r 24427303d56f a
1101 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1101 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1102 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1102 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1103 @@ -0,0 +1,1 @@
1103 @@ -0,0 +1,1 @@
1104 +a
1104 +a
1105
1105
1106
1106
1107 $ cd ../..
1107 $ cd ../..
1108
1108
1109 $ hg init follow2
1109 $ hg init follow2
1110 $ cd follow2
1110 $ cd follow2
1111
1111
1112 # Build the following history:
1112 # Build the following history:
1113 # tip - o - x - o - x - x
1113 # tip - o - x - o - x - x
1114 # \ /
1114 # \ /
1115 # o - o - o - x
1115 # o - o - o - x
1116 # \ /
1116 # \ /
1117 # o
1117 # o
1118 #
1118 #
1119 # Where "o" is a revision containing "foo" and
1119 # Where "o" is a revision containing "foo" and
1120 # "x" is a revision without "foo"
1120 # "x" is a revision without "foo"
1121
1121
1122 $ touch init
1122 $ touch init
1123 $ hg ci -A -m "init, unrelated"
1123 $ hg ci -A -m "init, unrelated"
1124 adding init
1124 adding init
1125 $ echo 'foo' > init
1125 $ echo 'foo' > init
1126 $ hg ci -m "change, unrelated"
1126 $ hg ci -m "change, unrelated"
1127 $ echo 'foo' > foo
1127 $ echo 'foo' > foo
1128 $ hg ci -A -m "add unrelated old foo"
1128 $ hg ci -A -m "add unrelated old foo"
1129 adding foo
1129 adding foo
1130 $ hg rm foo
1130 $ hg rm foo
1131 $ hg ci -m "delete foo, unrelated"
1131 $ hg ci -m "delete foo, unrelated"
1132 $ echo 'related' > foo
1132 $ echo 'related' > foo
1133 $ hg ci -A -m "add foo, related"
1133 $ hg ci -A -m "add foo, related"
1134 adding foo
1134 adding foo
1135
1135
1136 $ hg up 0
1136 $ hg up 0
1137 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1137 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1138 $ touch branch
1138 $ touch branch
1139 $ hg ci -A -m "first branch, unrelated"
1139 $ hg ci -A -m "first branch, unrelated"
1140 adding branch
1140 adding branch
1141 created new head
1141 created new head
1142 $ touch foo
1142 $ touch foo
1143 $ hg ci -A -m "create foo, related"
1143 $ hg ci -A -m "create foo, related"
1144 adding foo
1144 adding foo
1145 $ echo 'change' > foo
1145 $ echo 'change' > foo
1146 $ hg ci -m "change foo, related"
1146 $ hg ci -m "change foo, related"
1147
1147
1148 $ hg up 6
1148 $ hg up 6
1149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1150 $ echo 'change foo in branch' > foo
1150 $ echo 'change foo in branch' > foo
1151 $ hg ci -m "change foo in branch, related"
1151 $ hg ci -m "change foo in branch, related"
1152 created new head
1152 created new head
1153 $ hg merge 7
1153 $ hg merge 7
1154 merging foo
1154 merging foo
1155 warning: conflicts during merge.
1155 warning: conflicts during merge.
1156 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1156 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1157 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1157 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1158 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1158 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1159 [1]
1159 [1]
1160 $ echo 'merge 1' > foo
1160 $ echo 'merge 1' > foo
1161 $ hg resolve -m foo
1161 $ hg resolve -m foo
1162 (no more unresolved files)
1162 (no more unresolved files)
1163 $ hg ci -m "First merge, related"
1163 $ hg ci -m "First merge, related"
1164
1164
1165 $ hg merge 4
1165 $ hg merge 4
1166 merging foo
1166 merging foo
1167 warning: conflicts during merge.
1167 warning: conflicts during merge.
1168 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1168 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1169 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1169 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1170 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1170 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1171 [1]
1171 [1]
1172 $ echo 'merge 2' > foo
1172 $ echo 'merge 2' > foo
1173 $ hg resolve -m foo
1173 $ hg resolve -m foo
1174 (no more unresolved files)
1174 (no more unresolved files)
1175 $ hg ci -m "Last merge, related"
1175 $ hg ci -m "Last merge, related"
1176
1176
1177 $ hg log --graph
1177 $ hg log --graph
1178 @ changeset: 10:4dae8563d2c5
1178 @ changeset: 10:4dae8563d2c5
1179 |\ tag: tip
1179 |\ tag: tip
1180 | | parent: 9:7b35701b003e
1180 | | parent: 9:7b35701b003e
1181 | | parent: 4:88176d361b69
1181 | | parent: 4:88176d361b69
1182 | | user: test
1182 | | user: test
1183 | | date: Thu Jan 01 00:00:00 1970 +0000
1183 | | date: Thu Jan 01 00:00:00 1970 +0000
1184 | | summary: Last merge, related
1184 | | summary: Last merge, related
1185 | |
1185 | |
1186 | o changeset: 9:7b35701b003e
1186 | o changeset: 9:7b35701b003e
1187 | |\ parent: 8:e5416ad8a855
1187 | |\ parent: 8:e5416ad8a855
1188 | | | parent: 7:87fe3144dcfa
1188 | | | parent: 7:87fe3144dcfa
1189 | | | user: test
1189 | | | user: test
1190 | | | date: Thu Jan 01 00:00:00 1970 +0000
1190 | | | date: Thu Jan 01 00:00:00 1970 +0000
1191 | | | summary: First merge, related
1191 | | | summary: First merge, related
1192 | | |
1192 | | |
1193 | | o changeset: 8:e5416ad8a855
1193 | | o changeset: 8:e5416ad8a855
1194 | | | parent: 6:dc6c325fe5ee
1194 | | | parent: 6:dc6c325fe5ee
1195 | | | user: test
1195 | | | user: test
1196 | | | date: Thu Jan 01 00:00:00 1970 +0000
1196 | | | date: Thu Jan 01 00:00:00 1970 +0000
1197 | | | summary: change foo in branch, related
1197 | | | summary: change foo in branch, related
1198 | | |
1198 | | |
1199 | o | changeset: 7:87fe3144dcfa
1199 | o | changeset: 7:87fe3144dcfa
1200 | |/ user: test
1200 | |/ user: test
1201 | | date: Thu Jan 01 00:00:00 1970 +0000
1201 | | date: Thu Jan 01 00:00:00 1970 +0000
1202 | | summary: change foo, related
1202 | | summary: change foo, related
1203 | |
1203 | |
1204 | o changeset: 6:dc6c325fe5ee
1204 | o changeset: 6:dc6c325fe5ee
1205 | | user: test
1205 | | user: test
1206 | | date: Thu Jan 01 00:00:00 1970 +0000
1206 | | date: Thu Jan 01 00:00:00 1970 +0000
1207 | | summary: create foo, related
1207 | | summary: create foo, related
1208 | |
1208 | |
1209 | o changeset: 5:73db34516eb9
1209 | o changeset: 5:73db34516eb9
1210 | | parent: 0:e87515fd044a
1210 | | parent: 0:e87515fd044a
1211 | | user: test
1211 | | user: test
1212 | | date: Thu Jan 01 00:00:00 1970 +0000
1212 | | date: Thu Jan 01 00:00:00 1970 +0000
1213 | | summary: first branch, unrelated
1213 | | summary: first branch, unrelated
1214 | |
1214 | |
1215 o | changeset: 4:88176d361b69
1215 o | changeset: 4:88176d361b69
1216 | | user: test
1216 | | user: test
1217 | | date: Thu Jan 01 00:00:00 1970 +0000
1217 | | date: Thu Jan 01 00:00:00 1970 +0000
1218 | | summary: add foo, related
1218 | | summary: add foo, related
1219 | |
1219 | |
1220 o | changeset: 3:dd78ae4afb56
1220 o | changeset: 3:dd78ae4afb56
1221 | | user: test
1221 | | user: test
1222 | | date: Thu Jan 01 00:00:00 1970 +0000
1222 | | date: Thu Jan 01 00:00:00 1970 +0000
1223 | | summary: delete foo, unrelated
1223 | | summary: delete foo, unrelated
1224 | |
1224 | |
1225 o | changeset: 2:c4c64aedf0f7
1225 o | changeset: 2:c4c64aedf0f7
1226 | | user: test
1226 | | user: test
1227 | | date: Thu Jan 01 00:00:00 1970 +0000
1227 | | date: Thu Jan 01 00:00:00 1970 +0000
1228 | | summary: add unrelated old foo
1228 | | summary: add unrelated old foo
1229 | |
1229 | |
1230 o | changeset: 1:e5faa7440653
1230 o | changeset: 1:e5faa7440653
1231 |/ user: test
1231 |/ user: test
1232 | date: Thu Jan 01 00:00:00 1970 +0000
1232 | date: Thu Jan 01 00:00:00 1970 +0000
1233 | summary: change, unrelated
1233 | summary: change, unrelated
1234 |
1234 |
1235 o changeset: 0:e87515fd044a
1235 o changeset: 0:e87515fd044a
1236 user: test
1236 user: test
1237 date: Thu Jan 01 00:00:00 1970 +0000
1237 date: Thu Jan 01 00:00:00 1970 +0000
1238 summary: init, unrelated
1238 summary: init, unrelated
1239
1239
1240
1240
1241 $ hg --traceback log -f foo
1241 $ hg --traceback log -f foo
1242 changeset: 10:4dae8563d2c5
1242 changeset: 10:4dae8563d2c5
1243 tag: tip
1243 tag: tip
1244 parent: 9:7b35701b003e
1244 parent: 9:7b35701b003e
1245 parent: 4:88176d361b69
1245 parent: 4:88176d361b69
1246 user: test
1246 user: test
1247 date: Thu Jan 01 00:00:00 1970 +0000
1247 date: Thu Jan 01 00:00:00 1970 +0000
1248 summary: Last merge, related
1248 summary: Last merge, related
1249
1249
1250 changeset: 9:7b35701b003e
1250 changeset: 9:7b35701b003e
1251 parent: 8:e5416ad8a855
1251 parent: 8:e5416ad8a855
1252 parent: 7:87fe3144dcfa
1252 parent: 7:87fe3144dcfa
1253 user: test
1253 user: test
1254 date: Thu Jan 01 00:00:00 1970 +0000
1254 date: Thu Jan 01 00:00:00 1970 +0000
1255 summary: First merge, related
1255 summary: First merge, related
1256
1256
1257 changeset: 8:e5416ad8a855
1257 changeset: 8:e5416ad8a855
1258 parent: 6:dc6c325fe5ee
1258 parent: 6:dc6c325fe5ee
1259 user: test
1259 user: test
1260 date: Thu Jan 01 00:00:00 1970 +0000
1260 date: Thu Jan 01 00:00:00 1970 +0000
1261 summary: change foo in branch, related
1261 summary: change foo in branch, related
1262
1262
1263 changeset: 7:87fe3144dcfa
1263 changeset: 7:87fe3144dcfa
1264 user: test
1264 user: test
1265 date: Thu Jan 01 00:00:00 1970 +0000
1265 date: Thu Jan 01 00:00:00 1970 +0000
1266 summary: change foo, related
1266 summary: change foo, related
1267
1267
1268 changeset: 6:dc6c325fe5ee
1268 changeset: 6:dc6c325fe5ee
1269 user: test
1269 user: test
1270 date: Thu Jan 01 00:00:00 1970 +0000
1270 date: Thu Jan 01 00:00:00 1970 +0000
1271 summary: create foo, related
1271 summary: create foo, related
1272
1272
1273 changeset: 4:88176d361b69
1273 changeset: 4:88176d361b69
1274 user: test
1274 user: test
1275 date: Thu Jan 01 00:00:00 1970 +0000
1275 date: Thu Jan 01 00:00:00 1970 +0000
1276 summary: add foo, related
1276 summary: add foo, related
1277
1277
1278
1278
1279 Also check when maxrev < lastrevfilelog
1279 Also check when maxrev < lastrevfilelog
1280
1280
1281 $ hg --traceback log -f -r4 foo
1281 $ hg --traceback log -f -r4 foo
1282 changeset: 4:88176d361b69
1282 changeset: 4:88176d361b69
1283 user: test
1283 user: test
1284 date: Thu Jan 01 00:00:00 1970 +0000
1284 date: Thu Jan 01 00:00:00 1970 +0000
1285 summary: add foo, related
1285 summary: add foo, related
1286
1286
1287 $ cd ..
1287 $ cd ..
1288
1288
1289 Issue2383: hg log showing _less_ differences than hg diff
1289 Issue2383: hg log showing _less_ differences than hg diff
1290
1290
1291 $ hg init issue2383
1291 $ hg init issue2383
1292 $ cd issue2383
1292 $ cd issue2383
1293
1293
1294 Create a test repo:
1294 Create a test repo:
1295
1295
1296 $ echo a > a
1296 $ echo a > a
1297 $ hg ci -Am0
1297 $ hg ci -Am0
1298 adding a
1298 adding a
1299 $ echo b > b
1299 $ echo b > b
1300 $ hg ci -Am1
1300 $ hg ci -Am1
1301 adding b
1301 adding b
1302 $ hg co 0
1302 $ hg co 0
1303 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1303 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1304 $ echo b > a
1304 $ echo b > a
1305 $ hg ci -m2
1305 $ hg ci -m2
1306 created new head
1306 created new head
1307
1307
1308 Merge:
1308 Merge:
1309
1309
1310 $ hg merge
1310 $ hg merge
1311 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1311 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1312 (branch merge, don't forget to commit)
1312 (branch merge, don't forget to commit)
1313
1313
1314 Make sure there's a file listed in the merge to trigger the bug:
1314 Make sure there's a file listed in the merge to trigger the bug:
1315
1315
1316 $ echo c > a
1316 $ echo c > a
1317 $ hg ci -m3
1317 $ hg ci -m3
1318
1318
1319 Two files shown here in diff:
1319 Two files shown here in diff:
1320
1320
1321 $ hg diff --rev 2:3
1321 $ hg diff --rev 2:3
1322 diff -r b09be438c43a -r 8e07aafe1edc a
1322 diff -r b09be438c43a -r 8e07aafe1edc a
1323 --- a/a Thu Jan 01 00:00:00 1970 +0000
1323 --- a/a Thu Jan 01 00:00:00 1970 +0000
1324 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1324 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1325 @@ -1,1 +1,1 @@
1325 @@ -1,1 +1,1 @@
1326 -b
1326 -b
1327 +c
1327 +c
1328 diff -r b09be438c43a -r 8e07aafe1edc b
1328 diff -r b09be438c43a -r 8e07aafe1edc b
1329 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1329 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1330 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1330 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1331 @@ -0,0 +1,1 @@
1331 @@ -0,0 +1,1 @@
1332 +b
1332 +b
1333
1333
1334 Diff here should be the same:
1334 Diff here should be the same:
1335
1335
1336 $ hg log -vpr 3
1336 $ hg log -vpr 3
1337 changeset: 3:8e07aafe1edc
1337 changeset: 3:8e07aafe1edc
1338 tag: tip
1338 tag: tip
1339 parent: 2:b09be438c43a
1339 parent: 2:b09be438c43a
1340 parent: 1:925d80f479bb
1340 parent: 1:925d80f479bb
1341 user: test
1341 user: test
1342 date: Thu Jan 01 00:00:00 1970 +0000
1342 date: Thu Jan 01 00:00:00 1970 +0000
1343 files: a
1343 files: a
1344 description:
1344 description:
1345 3
1345 3
1346
1346
1347
1347
1348 diff -r b09be438c43a -r 8e07aafe1edc a
1348 diff -r b09be438c43a -r 8e07aafe1edc a
1349 --- a/a Thu Jan 01 00:00:00 1970 +0000
1349 --- a/a Thu Jan 01 00:00:00 1970 +0000
1350 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1350 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1351 @@ -1,1 +1,1 @@
1351 @@ -1,1 +1,1 @@
1352 -b
1352 -b
1353 +c
1353 +c
1354 diff -r b09be438c43a -r 8e07aafe1edc b
1354 diff -r b09be438c43a -r 8e07aafe1edc b
1355 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1355 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1356 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1356 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1357 @@ -0,0 +1,1 @@
1357 @@ -0,0 +1,1 @@
1358 +b
1358 +b
1359
1359
1360 $ cd ..
1360 $ cd ..
1361
1361
1362 'hg log -r rev fn' when last(filelog(fn)) != rev
1362 'hg log -r rev fn' when last(filelog(fn)) != rev
1363
1363
1364 $ hg init simplelog
1364 $ hg init simplelog
1365 $ cd simplelog
1365 $ cd simplelog
1366 $ echo f > a
1366 $ echo f > a
1367 $ hg ci -Am'a' -d '0 0'
1367 $ hg ci -Am'a' -d '0 0'
1368 adding a
1368 adding a
1369 $ echo f >> a
1369 $ echo f >> a
1370 $ hg ci -Am'a bis' -d '1 0'
1370 $ hg ci -Am'a bis' -d '1 0'
1371
1371
1372 $ hg log -r0 a
1372 $ hg log -r0 a
1373 changeset: 0:9f758d63dcde
1373 changeset: 0:9f758d63dcde
1374 user: test
1374 user: test
1375 date: Thu Jan 01 00:00:00 1970 +0000
1375 date: Thu Jan 01 00:00:00 1970 +0000
1376 summary: a
1376 summary: a
1377
1377
1378 enable obsolete to test hidden feature
1378 enable obsolete to test hidden feature
1379
1379
1380 $ cat >> $HGRCPATH << EOF
1380 $ cat >> $HGRCPATH << EOF
1381 > [experimental]
1381 > [experimental]
1382 > evolution=createmarkers
1382 > evolution=createmarkers
1383 > EOF
1383 > EOF
1384
1384
1385 $ hg log --template='{rev}:{node}\n'
1385 $ hg log --template='{rev}:{node}\n'
1386 1:a765632148dc55d38c35c4f247c618701886cb2f
1386 1:a765632148dc55d38c35c4f247c618701886cb2f
1387 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1387 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1388 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1388 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1389 $ hg up null -q
1389 $ hg up null -q
1390 $ hg log --template='{rev}:{node}\n'
1390 $ hg log --template='{rev}:{node}\n'
1391 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1391 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1392 $ hg log --template='{rev}:{node}\n' --hidden
1392 $ hg log --template='{rev}:{node}\n' --hidden
1393 1:a765632148dc55d38c35c4f247c618701886cb2f
1393 1:a765632148dc55d38c35c4f247c618701886cb2f
1394 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1394 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1395 $ hg log -r a
1395 $ hg log -r a
1396 abort: hidden revision 'a'!
1396 abort: hidden revision 'a'!
1397 (use --hidden to access hidden revisions)
1397 (use --hidden to access hidden revisions)
1398 [255]
1398 [255]
1399
1399
1400 test that parent prevent a changeset to be hidden
1400 test that parent prevent a changeset to be hidden
1401
1401
1402 $ hg up 1 -q --hidden
1402 $ hg up 1 -q --hidden
1403 $ hg log --template='{rev}:{node}\n'
1403 $ hg log --template='{rev}:{node}\n'
1404 1:a765632148dc55d38c35c4f247c618701886cb2f
1404 1:a765632148dc55d38c35c4f247c618701886cb2f
1405 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1405 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1406
1406
1407 test that second parent prevent a changeset to be hidden too
1407 test that second parent prevent a changeset to be hidden too
1408
1408
1409 $ hg debugsetparents 0 1 # nothing suitable to merge here
1409 $ hg debugsetparents 0 1 # nothing suitable to merge here
1410 $ hg log --template='{rev}:{node}\n'
1410 $ hg log --template='{rev}:{node}\n'
1411 1:a765632148dc55d38c35c4f247c618701886cb2f
1411 1:a765632148dc55d38c35c4f247c618701886cb2f
1412 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1412 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1413 $ hg debugsetparents 1
1413 $ hg debugsetparents 1
1414 $ hg up -q null
1414 $ hg up -q null
1415
1415
1416 bookmarks prevent a changeset being hidden
1416 bookmarks prevent a changeset being hidden
1417
1417
1418 $ hg bookmark --hidden -r 1 X
1418 $ hg bookmark --hidden -r 1 X
1419 $ hg log --template '{rev}:{node}\n'
1419 $ hg log --template '{rev}:{node}\n'
1420 1:a765632148dc55d38c35c4f247c618701886cb2f
1420 1:a765632148dc55d38c35c4f247c618701886cb2f
1421 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1421 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1422 $ hg bookmark -d X
1422 $ hg bookmark -d X
1423
1423
1424 divergent bookmarks are not hidden
1424 divergent bookmarks are not hidden
1425
1425
1426 $ hg bookmark --hidden -r 1 X@foo
1426 $ hg bookmark --hidden -r 1 X@foo
1427 $ hg log --template '{rev}:{node}\n'
1427 $ hg log --template '{rev}:{node}\n'
1428 1:a765632148dc55d38c35c4f247c618701886cb2f
1428 1:a765632148dc55d38c35c4f247c618701886cb2f
1429 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1429 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1430
1430
1431 clear extensions configuration
1431 clear extensions configuration
1432 $ echo '[extensions]' >> $HGRCPATH
1432 $ echo '[extensions]' >> $HGRCPATH
1433 $ echo "obs=!" >> $HGRCPATH
1433 $ echo "obs=!" >> $HGRCPATH
1434 $ cd ..
1434 $ cd ..
1435
1435
1436 test -u/-k for problematic encoding
1436 test -u/-k for problematic encoding
1437 # unicode: cp932:
1437 # unicode: cp932:
1438 # u30A2 0x83 0x41(= 'A')
1438 # u30A2 0x83 0x41(= 'A')
1439 # u30C2 0x83 0x61(= 'a')
1439 # u30C2 0x83 0x61(= 'a')
1440
1440
1441 $ hg init problematicencoding
1441 $ hg init problematicencoding
1442 $ cd problematicencoding
1442 $ cd problematicencoding
1443
1443
1444 $ python > setup.sh <<EOF
1444 $ python > setup.sh <<EOF
1445 > print u'''
1445 > print u'''
1446 > echo a > text
1446 > echo a > text
1447 > hg add text
1447 > hg add text
1448 > hg --encoding utf-8 commit -u '\u30A2' -m none
1448 > hg --encoding utf-8 commit -u '\u30A2' -m none
1449 > echo b > text
1449 > echo b > text
1450 > hg --encoding utf-8 commit -u '\u30C2' -m none
1450 > hg --encoding utf-8 commit -u '\u30C2' -m none
1451 > echo c > text
1451 > echo c > text
1452 > hg --encoding utf-8 commit -u none -m '\u30A2'
1452 > hg --encoding utf-8 commit -u none -m '\u30A2'
1453 > echo d > text
1453 > echo d > text
1454 > hg --encoding utf-8 commit -u none -m '\u30C2'
1454 > hg --encoding utf-8 commit -u none -m '\u30C2'
1455 > '''.encode('utf-8')
1455 > '''.encode('utf-8')
1456 > EOF
1456 > EOF
1457 $ sh < setup.sh
1457 $ sh < setup.sh
1458
1458
1459 test in problematic encoding
1459 test in problematic encoding
1460 $ python > test.sh <<EOF
1460 $ python > test.sh <<EOF
1461 > print u'''
1461 > print u'''
1462 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
1462 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
1463 > echo ====
1463 > echo ====
1464 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
1464 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
1465 > echo ====
1465 > echo ====
1466 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
1466 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
1467 > echo ====
1467 > echo ====
1468 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
1468 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
1469 > '''.encode('cp932')
1469 > '''.encode('cp932')
1470 > EOF
1470 > EOF
1471 $ sh < test.sh
1471 $ sh < test.sh
1472 0
1472 0
1473 ====
1473 ====
1474 1
1474 1
1475 ====
1475 ====
1476 2
1476 2
1477 0
1477 0
1478 ====
1478 ====
1479 3
1479 3
1480 1
1480 1
1481
1481
1482 $ cd ..
1482 $ cd ..
1483
1483
1484 test hg log on non-existent files and on directories
1484 test hg log on non-existent files and on directories
1485 $ hg init issue1340
1485 $ hg init issue1340
1486 $ cd issue1340
1486 $ cd issue1340
1487 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
1487 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
1488 $ echo 1 > d1/f1
1488 $ echo 1 > d1/f1
1489 $ echo 1 > D2/f1
1489 $ echo 1 > D2/f1
1490 $ echo 1 > D3.i/f1
1490 $ echo 1 > D3.i/f1
1491 $ echo 1 > d4.hg/f1
1491 $ echo 1 > d4.hg/f1
1492 $ echo 1 > d5.d/f1
1492 $ echo 1 > d5.d/f1
1493 $ echo 1 > .d6/f1
1493 $ echo 1 > .d6/f1
1494 $ hg -q add .
1494 $ hg -q add .
1495 $ hg commit -m "a bunch of weird directories"
1495 $ hg commit -m "a bunch of weird directories"
1496 $ hg log -l1 d1/f1 | grep changeset
1496 $ hg log -l1 d1/f1 | grep changeset
1497 changeset: 0:65624cd9070a
1497 changeset: 0:65624cd9070a
1498 $ hg log -l1 f1
1498 $ hg log -l1 f1
1499 $ hg log -l1 . | grep changeset
1499 $ hg log -l1 . | grep changeset
1500 changeset: 0:65624cd9070a
1500 changeset: 0:65624cd9070a
1501 $ hg log -l1 ./ | grep changeset
1501 $ hg log -l1 ./ | grep changeset
1502 changeset: 0:65624cd9070a
1502 changeset: 0:65624cd9070a
1503 $ hg log -l1 d1 | grep changeset
1503 $ hg log -l1 d1 | grep changeset
1504 changeset: 0:65624cd9070a
1504 changeset: 0:65624cd9070a
1505 $ hg log -l1 D2 | grep changeset
1505 $ hg log -l1 D2 | grep changeset
1506 changeset: 0:65624cd9070a
1506 changeset: 0:65624cd9070a
1507 $ hg log -l1 D2/f1 | grep changeset
1507 $ hg log -l1 D2/f1 | grep changeset
1508 changeset: 0:65624cd9070a
1508 changeset: 0:65624cd9070a
1509 $ hg log -l1 D3.i | grep changeset
1509 $ hg log -l1 D3.i | grep changeset
1510 changeset: 0:65624cd9070a
1510 changeset: 0:65624cd9070a
1511 $ hg log -l1 D3.i/f1 | grep changeset
1511 $ hg log -l1 D3.i/f1 | grep changeset
1512 changeset: 0:65624cd9070a
1512 changeset: 0:65624cd9070a
1513 $ hg log -l1 d4.hg | grep changeset
1513 $ hg log -l1 d4.hg | grep changeset
1514 changeset: 0:65624cd9070a
1514 changeset: 0:65624cd9070a
1515 $ hg log -l1 d4.hg/f1 | grep changeset
1515 $ hg log -l1 d4.hg/f1 | grep changeset
1516 changeset: 0:65624cd9070a
1516 changeset: 0:65624cd9070a
1517 $ hg log -l1 d5.d | grep changeset
1517 $ hg log -l1 d5.d | grep changeset
1518 changeset: 0:65624cd9070a
1518 changeset: 0:65624cd9070a
1519 $ hg log -l1 d5.d/f1 | grep changeset
1519 $ hg log -l1 d5.d/f1 | grep changeset
1520 changeset: 0:65624cd9070a
1520 changeset: 0:65624cd9070a
1521 $ hg log -l1 .d6 | grep changeset
1521 $ hg log -l1 .d6 | grep changeset
1522 changeset: 0:65624cd9070a
1522 changeset: 0:65624cd9070a
1523 $ hg log -l1 .d6/f1 | grep changeset
1523 $ hg log -l1 .d6/f1 | grep changeset
1524 changeset: 0:65624cd9070a
1524 changeset: 0:65624cd9070a
1525
1525
1526 issue3772: hg log -r :null showing revision 0 as well
1526 issue3772: hg log -r :null showing revision 0 as well
1527
1527
1528 $ hg log -r :null
1528 $ hg log -r :null
1529 changeset: 0:65624cd9070a
1529 changeset: 0:65624cd9070a
1530 tag: tip
1530 tag: tip
1531 user: test
1531 user: test
1532 date: Thu Jan 01 00:00:00 1970 +0000
1532 date: Thu Jan 01 00:00:00 1970 +0000
1533 summary: a bunch of weird directories
1533 summary: a bunch of weird directories
1534
1534
1535 changeset: -1:000000000000
1535 changeset: -1:000000000000
1536 user:
1536 user:
1537 date: Thu Jan 01 00:00:00 1970 +0000
1537 date: Thu Jan 01 00:00:00 1970 +0000
1538
1538
1539 $ hg log -r null:null
1539 $ hg log -r null:null
1540 changeset: -1:000000000000
1540 changeset: -1:000000000000
1541 user:
1541 user:
1542 date: Thu Jan 01 00:00:00 1970 +0000
1542 date: Thu Jan 01 00:00:00 1970 +0000
1543
1543
1544
1544
1545 $ cd ..
1545 $ cd ..
1546
1547 hg log -f dir across branches
1548
1549 $ hg init acrossbranches
1550 $ cd acrossbranches
1551 $ mkdir d
1552 $ echo a > d/a && hg ci -Aqm a
1553 $ echo b > d/a && hg ci -Aqm b
1554 $ hg up -q 0
1555 $ echo b > d/a && hg ci -Aqm c
1556 $ hg log -f d -T '{desc}' -G
1557 @ c
1558 |
1559 o a
1560
1561 $ hg log -f d/a -T '{desc}' -G
1562 o b
1563 |
1564 o a
1565
1566 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now