##// END OF EJS Templates
graphlog: evaluate FILE/-I/-X filesets on the working dir...
Patrick Mezard -
r16181:1fd352aa default
parent child Browse files
Show More
@@ -1,467 +1,469 b''
1 # ASCII graph log extension for Mercurial
1 # ASCII graph log extension for Mercurial
2 #
2 #
3 # Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
3 # Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
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 '''command to view revision graphs from a shell
8 '''command to view revision graphs from a shell
9
9
10 This extension adds a --graph option to the incoming, outgoing and log
10 This extension adds a --graph option to the incoming, outgoing and log
11 commands. When this options is given, an ASCII representation of the
11 commands. When this options is given, an ASCII representation of the
12 revision graph is also shown.
12 revision graph is also shown.
13 '''
13 '''
14
14
15 from mercurial.cmdutil import show_changeset
15 from mercurial.cmdutil import show_changeset
16 from mercurial.commands import templateopts
16 from mercurial.commands import templateopts
17 from mercurial.i18n import _
17 from mercurial.i18n import _
18 from mercurial.node import nullrev
18 from mercurial.node import nullrev
19 from mercurial import cmdutil, commands, extensions, scmutil
19 from mercurial import cmdutil, commands, extensions, scmutil
20 from mercurial import hg, util, graphmod, templatekw
20 from mercurial import hg, util, graphmod, templatekw
21
21
22 cmdtable = {}
22 cmdtable = {}
23 command = cmdutil.command(cmdtable)
23 command = cmdutil.command(cmdtable)
24
24
25 ASCIIDATA = 'ASC'
25 ASCIIDATA = 'ASC'
26
26
27 def asciiedges(type, char, lines, seen, rev, parents):
27 def asciiedges(type, char, lines, seen, rev, parents):
28 """adds edge info to changelog DAG walk suitable for ascii()"""
28 """adds edge info to changelog DAG walk suitable for ascii()"""
29 if rev not in seen:
29 if rev not in seen:
30 seen.append(rev)
30 seen.append(rev)
31 nodeidx = seen.index(rev)
31 nodeidx = seen.index(rev)
32
32
33 knownparents = []
33 knownparents = []
34 newparents = []
34 newparents = []
35 for parent in parents:
35 for parent in parents:
36 if parent in seen:
36 if parent in seen:
37 knownparents.append(parent)
37 knownparents.append(parent)
38 else:
38 else:
39 newparents.append(parent)
39 newparents.append(parent)
40
40
41 ncols = len(seen)
41 ncols = len(seen)
42 nextseen = seen[:]
42 nextseen = seen[:]
43 nextseen[nodeidx:nodeidx + 1] = newparents
43 nextseen[nodeidx:nodeidx + 1] = newparents
44 edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
44 edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
45
45
46 while len(newparents) > 2:
46 while len(newparents) > 2:
47 # ascii() only knows how to add or remove a single column between two
47 # ascii() only knows how to add or remove a single column between two
48 # calls. Nodes with more than two parents break this constraint so we
48 # calls. Nodes with more than two parents break this constraint so we
49 # introduce intermediate expansion lines to grow the active node list
49 # introduce intermediate expansion lines to grow the active node list
50 # slowly.
50 # slowly.
51 edges.append((nodeidx, nodeidx))
51 edges.append((nodeidx, nodeidx))
52 edges.append((nodeidx, nodeidx + 1))
52 edges.append((nodeidx, nodeidx + 1))
53 nmorecols = 1
53 nmorecols = 1
54 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
54 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
55 char = '\\'
55 char = '\\'
56 lines = []
56 lines = []
57 nodeidx += 1
57 nodeidx += 1
58 ncols += 1
58 ncols += 1
59 edges = []
59 edges = []
60 del newparents[0]
60 del newparents[0]
61
61
62 if len(newparents) > 0:
62 if len(newparents) > 0:
63 edges.append((nodeidx, nodeidx))
63 edges.append((nodeidx, nodeidx))
64 if len(newparents) > 1:
64 if len(newparents) > 1:
65 edges.append((nodeidx, nodeidx + 1))
65 edges.append((nodeidx, nodeidx + 1))
66 nmorecols = len(nextseen) - ncols
66 nmorecols = len(nextseen) - ncols
67 seen[:] = nextseen
67 seen[:] = nextseen
68 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
68 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
69
69
70 def fix_long_right_edges(edges):
70 def fix_long_right_edges(edges):
71 for (i, (start, end)) in enumerate(edges):
71 for (i, (start, end)) in enumerate(edges):
72 if end > start:
72 if end > start:
73 edges[i] = (start, end + 1)
73 edges[i] = (start, end + 1)
74
74
75 def get_nodeline_edges_tail(
75 def get_nodeline_edges_tail(
76 node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
76 node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
77 if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
77 if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
78 # Still going in the same non-vertical direction.
78 # Still going in the same non-vertical direction.
79 if n_columns_diff == -1:
79 if n_columns_diff == -1:
80 start = max(node_index + 1, p_node_index)
80 start = max(node_index + 1, p_node_index)
81 tail = ["|", " "] * (start - node_index - 1)
81 tail = ["|", " "] * (start - node_index - 1)
82 tail.extend(["/", " "] * (n_columns - start))
82 tail.extend(["/", " "] * (n_columns - start))
83 return tail
83 return tail
84 else:
84 else:
85 return ["\\", " "] * (n_columns - node_index - 1)
85 return ["\\", " "] * (n_columns - node_index - 1)
86 else:
86 else:
87 return ["|", " "] * (n_columns - node_index - 1)
87 return ["|", " "] * (n_columns - node_index - 1)
88
88
89 def draw_edges(edges, nodeline, interline):
89 def draw_edges(edges, nodeline, interline):
90 for (start, end) in edges:
90 for (start, end) in edges:
91 if start == end + 1:
91 if start == end + 1:
92 interline[2 * end + 1] = "/"
92 interline[2 * end + 1] = "/"
93 elif start == end - 1:
93 elif start == end - 1:
94 interline[2 * start + 1] = "\\"
94 interline[2 * start + 1] = "\\"
95 elif start == end:
95 elif start == end:
96 interline[2 * start] = "|"
96 interline[2 * start] = "|"
97 else:
97 else:
98 if 2 * end >= len(nodeline):
98 if 2 * end >= len(nodeline):
99 continue
99 continue
100 nodeline[2 * end] = "+"
100 nodeline[2 * end] = "+"
101 if start > end:
101 if start > end:
102 (start, end) = (end, start)
102 (start, end) = (end, start)
103 for i in range(2 * start + 1, 2 * end):
103 for i in range(2 * start + 1, 2 * end):
104 if nodeline[i] != "+":
104 if nodeline[i] != "+":
105 nodeline[i] = "-"
105 nodeline[i] = "-"
106
106
107 def get_padding_line(ni, n_columns, edges):
107 def get_padding_line(ni, n_columns, edges):
108 line = []
108 line = []
109 line.extend(["|", " "] * ni)
109 line.extend(["|", " "] * ni)
110 if (ni, ni - 1) in edges or (ni, ni) in edges:
110 if (ni, ni - 1) in edges or (ni, ni) in edges:
111 # (ni, ni - 1) (ni, ni)
111 # (ni, ni - 1) (ni, ni)
112 # | | | | | | | |
112 # | | | | | | | |
113 # +---o | | o---+
113 # +---o | | o---+
114 # | | c | | c | |
114 # | | c | | c | |
115 # | |/ / | |/ /
115 # | |/ / | |/ /
116 # | | | | | |
116 # | | | | | |
117 c = "|"
117 c = "|"
118 else:
118 else:
119 c = " "
119 c = " "
120 line.extend([c, " "])
120 line.extend([c, " "])
121 line.extend(["|", " "] * (n_columns - ni - 1))
121 line.extend(["|", " "] * (n_columns - ni - 1))
122 return line
122 return line
123
123
124 def asciistate():
124 def asciistate():
125 """returns the initial value for the "state" argument to ascii()"""
125 """returns the initial value for the "state" argument to ascii()"""
126 return [0, 0]
126 return [0, 0]
127
127
128 def ascii(ui, state, type, char, text, coldata):
128 def ascii(ui, state, type, char, text, coldata):
129 """prints an ASCII graph of the DAG
129 """prints an ASCII graph of the DAG
130
130
131 takes the following arguments (one call per node in the graph):
131 takes the following arguments (one call per node in the graph):
132
132
133 - ui to write to
133 - ui to write to
134 - Somewhere to keep the needed state in (init to asciistate())
134 - Somewhere to keep the needed state in (init to asciistate())
135 - Column of the current node in the set of ongoing edges.
135 - Column of the current node in the set of ongoing edges.
136 - Type indicator of node data == ASCIIDATA.
136 - Type indicator of node data == ASCIIDATA.
137 - Payload: (char, lines):
137 - Payload: (char, lines):
138 - Character to use as node's symbol.
138 - Character to use as node's symbol.
139 - List of lines to display as the node's text.
139 - List of lines to display as the node's text.
140 - Edges; a list of (col, next_col) indicating the edges between
140 - Edges; a list of (col, next_col) indicating the edges between
141 the current node and its parents.
141 the current node and its parents.
142 - Number of columns (ongoing edges) in the current revision.
142 - Number of columns (ongoing edges) in the current revision.
143 - The difference between the number of columns (ongoing edges)
143 - The difference between the number of columns (ongoing edges)
144 in the next revision and the number of columns (ongoing edges)
144 in the next revision and the number of columns (ongoing edges)
145 in the current revision. That is: -1 means one column removed;
145 in the current revision. That is: -1 means one column removed;
146 0 means no columns added or removed; 1 means one column added.
146 0 means no columns added or removed; 1 means one column added.
147 """
147 """
148
148
149 idx, edges, ncols, coldiff = coldata
149 idx, edges, ncols, coldiff = coldata
150 assert -2 < coldiff < 2
150 assert -2 < coldiff < 2
151 if coldiff == -1:
151 if coldiff == -1:
152 # Transform
152 # Transform
153 #
153 #
154 # | | | | | |
154 # | | | | | |
155 # o | | into o---+
155 # o | | into o---+
156 # |X / |/ /
156 # |X / |/ /
157 # | | | |
157 # | | | |
158 fix_long_right_edges(edges)
158 fix_long_right_edges(edges)
159
159
160 # add_padding_line says whether to rewrite
160 # add_padding_line says whether to rewrite
161 #
161 #
162 # | | | | | | | |
162 # | | | | | | | |
163 # | o---+ into | o---+
163 # | o---+ into | o---+
164 # | / / | | | # <--- padding line
164 # | / / | | | # <--- padding line
165 # o | | | / /
165 # o | | | / /
166 # o | |
166 # o | |
167 add_padding_line = (len(text) > 2 and coldiff == -1 and
167 add_padding_line = (len(text) > 2 and coldiff == -1 and
168 [x for (x, y) in edges if x + 1 < y])
168 [x for (x, y) in edges if x + 1 < y])
169
169
170 # fix_nodeline_tail says whether to rewrite
170 # fix_nodeline_tail says whether to rewrite
171 #
171 #
172 # | | o | | | | o | |
172 # | | o | | | | o | |
173 # | | |/ / | | |/ /
173 # | | |/ / | | |/ /
174 # | o | | into | o / / # <--- fixed nodeline tail
174 # | o | | into | o / / # <--- fixed nodeline tail
175 # | |/ / | |/ /
175 # | |/ / | |/ /
176 # o | | o | |
176 # o | | o | |
177 fix_nodeline_tail = len(text) <= 2 and not add_padding_line
177 fix_nodeline_tail = len(text) <= 2 and not add_padding_line
178
178
179 # nodeline is the line containing the node character (typically o)
179 # nodeline is the line containing the node character (typically o)
180 nodeline = ["|", " "] * idx
180 nodeline = ["|", " "] * idx
181 nodeline.extend([char, " "])
181 nodeline.extend([char, " "])
182
182
183 nodeline.extend(
183 nodeline.extend(
184 get_nodeline_edges_tail(idx, state[1], ncols, coldiff,
184 get_nodeline_edges_tail(idx, state[1], ncols, coldiff,
185 state[0], fix_nodeline_tail))
185 state[0], fix_nodeline_tail))
186
186
187 # shift_interline is the line containing the non-vertical
187 # shift_interline is the line containing the non-vertical
188 # edges between this entry and the next
188 # edges between this entry and the next
189 shift_interline = ["|", " "] * idx
189 shift_interline = ["|", " "] * idx
190 if coldiff == -1:
190 if coldiff == -1:
191 n_spaces = 1
191 n_spaces = 1
192 edge_ch = "/"
192 edge_ch = "/"
193 elif coldiff == 0:
193 elif coldiff == 0:
194 n_spaces = 2
194 n_spaces = 2
195 edge_ch = "|"
195 edge_ch = "|"
196 else:
196 else:
197 n_spaces = 3
197 n_spaces = 3
198 edge_ch = "\\"
198 edge_ch = "\\"
199 shift_interline.extend(n_spaces * [" "])
199 shift_interline.extend(n_spaces * [" "])
200 shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
200 shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
201
201
202 # draw edges from the current node to its parents
202 # draw edges from the current node to its parents
203 draw_edges(edges, nodeline, shift_interline)
203 draw_edges(edges, nodeline, shift_interline)
204
204
205 # lines is the list of all graph lines to print
205 # lines is the list of all graph lines to print
206 lines = [nodeline]
206 lines = [nodeline]
207 if add_padding_line:
207 if add_padding_line:
208 lines.append(get_padding_line(idx, ncols, edges))
208 lines.append(get_padding_line(idx, ncols, edges))
209 lines.append(shift_interline)
209 lines.append(shift_interline)
210
210
211 # make sure that there are as many graph lines as there are
211 # make sure that there are as many graph lines as there are
212 # log strings
212 # log strings
213 while len(text) < len(lines):
213 while len(text) < len(lines):
214 text.append("")
214 text.append("")
215 if len(lines) < len(text):
215 if len(lines) < len(text):
216 extra_interline = ["|", " "] * (ncols + coldiff)
216 extra_interline = ["|", " "] * (ncols + coldiff)
217 while len(lines) < len(text):
217 while len(lines) < len(text):
218 lines.append(extra_interline)
218 lines.append(extra_interline)
219
219
220 # print lines
220 # print lines
221 indentation_level = max(ncols, ncols + coldiff)
221 indentation_level = max(ncols, ncols + coldiff)
222 for (line, logstr) in zip(lines, text):
222 for (line, logstr) in zip(lines, text):
223 ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
223 ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
224 ui.write(ln.rstrip() + '\n')
224 ui.write(ln.rstrip() + '\n')
225
225
226 # ... and start over
226 # ... and start over
227 state[0] = coldiff
227 state[0] = coldiff
228 state[1] = idx
228 state[1] = idx
229
229
230 def get_revs(repo, rev_opt):
230 def get_revs(repo, rev_opt):
231 if rev_opt:
231 if rev_opt:
232 revs = scmutil.revrange(repo, rev_opt)
232 revs = scmutil.revrange(repo, rev_opt)
233 if len(revs) == 0:
233 if len(revs) == 0:
234 return (nullrev, nullrev)
234 return (nullrev, nullrev)
235 return (max(revs), min(revs))
235 return (max(revs), min(revs))
236 else:
236 else:
237 return (len(repo) - 1, 0)
237 return (len(repo) - 1, 0)
238
238
239 def check_unsupported_flags(pats, opts):
239 def check_unsupported_flags(pats, opts):
240 for op in ["newest_first"]:
240 for op in ["newest_first"]:
241 if op in opts and opts[op]:
241 if op in opts and opts[op]:
242 raise util.Abort(_("-G/--graph option is incompatible with --%s")
242 raise util.Abort(_("-G/--graph option is incompatible with --%s")
243 % op.replace("_", "-"))
243 % op.replace("_", "-"))
244
244
245 def revset(repo, pats, opts):
245 def revset(repo, pats, opts):
246 """Return revset str built of revisions, log options and file patterns.
246 """Return revset str built of revisions, log options and file patterns.
247 """
247 """
248 opt2revset = {
248 opt2revset = {
249 'follow': ('follow()', None),
249 'follow': ('follow()', None),
250 'follow_first': ('_followfirst()', None),
250 'follow_first': ('_followfirst()', None),
251 'no_merges': ('not merge()', None),
251 'no_merges': ('not merge()', None),
252 'only_merges': ('merge()', None),
252 'only_merges': ('merge()', None),
253 'removed': ('removes("*")', None),
253 'removed': ('removes("*")', None),
254 'date': ('date(%(val)r)', None),
254 'date': ('date(%(val)r)', None),
255 'branch': ('branch(%(val)r)', ' or '),
255 'branch': ('branch(%(val)r)', ' or '),
256 '_patslog': ('filelog(%(val)r)', ' or '),
256 '_patslog': ('filelog(%(val)r)', ' or '),
257 '_patsfollow': ('follow(%(val)r)', ' or '),
257 '_patsfollow': ('follow(%(val)r)', ' or '),
258 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
258 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
259 'keyword': ('keyword(%(val)r)', ' or '),
259 'keyword': ('keyword(%(val)r)', ' or '),
260 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
260 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
261 'user': ('user(%(val)r)', ' or '),
261 'user': ('user(%(val)r)', ' or '),
262 'rev': ('%(val)s', ' or '),
262 'rev': ('%(val)s', ' or '),
263 }
263 }
264
264
265 opts = dict(opts)
265 opts = dict(opts)
266 # branch and only_branch are really aliases and must be handled at
266 # branch and only_branch are really aliases and must be handled at
267 # the same time
267 # the same time
268 if 'branch' in opts and 'only_branch' in opts:
268 if 'branch' in opts and 'only_branch' in opts:
269 opts['branch'] = opts['branch'] + opts.pop('only_branch')
269 opts['branch'] = opts['branch'] + opts.pop('only_branch')
270
270
271 follow = opts.get('follow') or opts.get('follow_first')
271 follow = opts.get('follow') or opts.get('follow_first')
272 followfirst = opts.get('follow_first')
272 followfirst = opts.get('follow_first')
273 if 'follow' in opts:
273 if 'follow' in opts:
274 del opts['follow']
274 del opts['follow']
275 if 'follow_first' in opts:
275 if 'follow_first' in opts:
276 del opts['follow_first']
276 del opts['follow_first']
277 # pats/include/exclude are passed to match.match() directly in
277 # pats/include/exclude are passed to match.match() directly in
278 # _matchfile() revset but walkchangerevs() builds its matcher with
278 # _matchfile() revset but walkchangerevs() builds its matcher with
279 # scmutil.match(). The difference is input pats are globbed on
279 # scmutil.match(). The difference is input pats are globbed on
280 # platforms without shell expansion (windows).
280 # platforms without shell expansion (windows).
281 pctx = repo[None]
281 pctx = repo[None]
282 match, pats = scmutil.matchandpats(pctx, pats, opts)
282 match, pats = scmutil.matchandpats(pctx, pats, opts)
283 slowpath = match.anypats() or (match.files() and opts.get('removed'))
283 slowpath = match.anypats() or (match.files() and opts.get('removed'))
284 if not slowpath:
284 if not slowpath:
285 for f in match.files():
285 for f in match.files():
286 if follow and f not in pctx:
286 if follow and f not in pctx:
287 raise util.Abort(_('cannot follow file not in parent '
287 raise util.Abort(_('cannot follow file not in parent '
288 'revision: "%s"') % f)
288 'revision: "%s"') % f)
289 filelog = repo.file(f)
289 filelog = repo.file(f)
290 if not len(filelog):
290 if not len(filelog):
291 # A zero count may be a directory or deleted file, so
291 # A zero count may be a directory or deleted file, so
292 # try to find matching entries on the slow path.
292 # try to find matching entries on the slow path.
293 if follow:
293 if follow:
294 raise util.Abort(
294 raise util.Abort(
295 _('cannot follow nonexistent file: "%s"') % f)
295 _('cannot follow nonexistent file: "%s"') % f)
296 slowpath = True
296 slowpath = True
297 if slowpath:
297 if slowpath:
298 # See cmdutil.walkchangerevs() slow path.
298 # See cmdutil.walkchangerevs() slow path.
299 #
299 #
300 if follow:
300 if follow:
301 raise util.Abort(_('can only follow copies/renames for explicit '
301 raise util.Abort(_('can only follow copies/renames for explicit '
302 'filenames'))
302 'filenames'))
303 # pats/include/exclude cannot be represented as separate
303 # pats/include/exclude cannot be represented as separate
304 # revset expressions as their filtering logic applies at file
304 # revset expressions as their filtering logic applies at file
305 # level. For instance "-I a -X a" matches a revision touching
305 # level. For instance "-I a -X a" matches a revision touching
306 # "a" and "b" while "file(a) and not file(b)" does not.
306 # "a" and "b" while "file(a) and not file(b)" does
307 matchargs = []
307 # not. Besides, filesets are evaluated against the working
308 # directory.
309 matchargs = ['r:']
308 for p in pats:
310 for p in pats:
309 matchargs.append('p:' + p)
311 matchargs.append('p:' + p)
310 for p in opts.get('include', []):
312 for p in opts.get('include', []):
311 matchargs.append('i:' + p)
313 matchargs.append('i:' + p)
312 for p in opts.get('exclude', []):
314 for p in opts.get('exclude', []):
313 matchargs.append('x:' + p)
315 matchargs.append('x:' + p)
314 matchargs = ','.join(('%r' % p) for p in matchargs)
316 matchargs = ','.join(('%r' % p) for p in matchargs)
315 opts['rev'] = opts.get('rev', []) + ['_matchfiles(%s)' % matchargs]
317 opts['rev'] = opts.get('rev', []) + ['_matchfiles(%s)' % matchargs]
316 else:
318 else:
317 if follow:
319 if follow:
318 if followfirst:
320 if followfirst:
319 if pats:
321 if pats:
320 opts['_patsfollowfirst'] = list(pats)
322 opts['_patsfollowfirst'] = list(pats)
321 else:
323 else:
322 opts['follow_first'] = True
324 opts['follow_first'] = True
323 else:
325 else:
324 if pats:
326 if pats:
325 opts['_patsfollow'] = list(pats)
327 opts['_patsfollow'] = list(pats)
326 else:
328 else:
327 opts['follow'] = True
329 opts['follow'] = True
328 else:
330 else:
329 opts['_patslog'] = list(pats)
331 opts['_patslog'] = list(pats)
330
332
331 revset = []
333 revset = []
332 for op, val in opts.iteritems():
334 for op, val in opts.iteritems():
333 if not val:
335 if not val:
334 continue
336 continue
335 if op not in opt2revset:
337 if op not in opt2revset:
336 continue
338 continue
337 revop, andor = opt2revset[op]
339 revop, andor = opt2revset[op]
338 if '%(val)' not in revop:
340 if '%(val)' not in revop:
339 revset.append(revop)
341 revset.append(revop)
340 else:
342 else:
341 if not isinstance(val, list):
343 if not isinstance(val, list):
342 expr = revop % {'val': val}
344 expr = revop % {'val': val}
343 else:
345 else:
344 expr = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
346 expr = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
345 revset.append(expr)
347 revset.append(expr)
346
348
347 if revset:
349 if revset:
348 revset = '(' + ' and '.join(revset) + ')'
350 revset = '(' + ' and '.join(revset) + ')'
349 else:
351 else:
350 revset = 'all()'
352 revset = 'all()'
351 return revset
353 return revset
352
354
353 def generate(ui, dag, displayer, showparents, edgefn, getrenamed=None):
355 def generate(ui, dag, displayer, showparents, edgefn, getrenamed=None):
354 seen, state = [], asciistate()
356 seen, state = [], asciistate()
355 for rev, type, ctx, parents in dag:
357 for rev, type, ctx, parents in dag:
356 char = ctx.node() in showparents and '@' or 'o'
358 char = ctx.node() in showparents and '@' or 'o'
357 copies = None
359 copies = None
358 if getrenamed and ctx.rev():
360 if getrenamed and ctx.rev():
359 copies = []
361 copies = []
360 for fn in ctx.files():
362 for fn in ctx.files():
361 rename = getrenamed(fn, ctx.rev())
363 rename = getrenamed(fn, ctx.rev())
362 if rename:
364 if rename:
363 copies.append((fn, rename[0]))
365 copies.append((fn, rename[0]))
364 displayer.show(ctx, copies=copies)
366 displayer.show(ctx, copies=copies)
365 lines = displayer.hunk.pop(rev).split('\n')[:-1]
367 lines = displayer.hunk.pop(rev).split('\n')[:-1]
366 displayer.flush(rev)
368 displayer.flush(rev)
367 edges = edgefn(type, char, lines, seen, rev, parents)
369 edges = edgefn(type, char, lines, seen, rev, parents)
368 for type, char, lines, coldata in edges:
370 for type, char, lines, coldata in edges:
369 ascii(ui, state, type, char, lines, coldata)
371 ascii(ui, state, type, char, lines, coldata)
370 displayer.close()
372 displayer.close()
371
373
372 @command('glog',
374 @command('glog',
373 [('l', 'limit', '',
375 [('l', 'limit', '',
374 _('limit number of changes displayed'), _('NUM')),
376 _('limit number of changes displayed'), _('NUM')),
375 ('p', 'patch', False, _('show patch')),
377 ('p', 'patch', False, _('show patch')),
376 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
378 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
377 ] + templateopts,
379 ] + templateopts,
378 _('hg glog [OPTION]... [FILE]'))
380 _('hg glog [OPTION]... [FILE]'))
379 def graphlog(ui, repo, *pats, **opts):
381 def graphlog(ui, repo, *pats, **opts):
380 """show revision history alongside an ASCII revision graph
382 """show revision history alongside an ASCII revision graph
381
383
382 Print a revision history alongside a revision graph drawn with
384 Print a revision history alongside a revision graph drawn with
383 ASCII characters.
385 ASCII characters.
384
386
385 Nodes printed as an @ character are parents of the working
387 Nodes printed as an @ character are parents of the working
386 directory.
388 directory.
387 """
389 """
388
390
389 check_unsupported_flags(pats, opts)
391 check_unsupported_flags(pats, opts)
390
392
391 revs = sorted(scmutil.revrange(repo, [revset(repo, pats, opts)]), reverse=1)
393 revs = sorted(scmutil.revrange(repo, [revset(repo, pats, opts)]), reverse=1)
392 limit = cmdutil.loglimit(opts)
394 limit = cmdutil.loglimit(opts)
393 if limit is not None:
395 if limit is not None:
394 revs = revs[:limit]
396 revs = revs[:limit]
395 revdag = graphmod.dagwalker(repo, revs)
397 revdag = graphmod.dagwalker(repo, revs)
396
398
397 getrenamed = None
399 getrenamed = None
398 if opts.get('copies'):
400 if opts.get('copies'):
399 endrev = None
401 endrev = None
400 if opts.get('rev'):
402 if opts.get('rev'):
401 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
403 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
402 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
404 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
403 displayer = show_changeset(ui, repo, opts, buffered=True)
405 displayer = show_changeset(ui, repo, opts, buffered=True)
404 showparents = [ctx.node() for ctx in repo[None].parents()]
406 showparents = [ctx.node() for ctx in repo[None].parents()]
405 generate(ui, revdag, displayer, showparents, asciiedges, getrenamed)
407 generate(ui, revdag, displayer, showparents, asciiedges, getrenamed)
406
408
407 def graphrevs(repo, nodes, opts):
409 def graphrevs(repo, nodes, opts):
408 limit = cmdutil.loglimit(opts)
410 limit = cmdutil.loglimit(opts)
409 nodes.reverse()
411 nodes.reverse()
410 if limit is not None:
412 if limit is not None:
411 nodes = nodes[:limit]
413 nodes = nodes[:limit]
412 return graphmod.nodes(repo, nodes)
414 return graphmod.nodes(repo, nodes)
413
415
414 def goutgoing(ui, repo, dest=None, **opts):
416 def goutgoing(ui, repo, dest=None, **opts):
415 """show the outgoing changesets alongside an ASCII revision graph
417 """show the outgoing changesets alongside an ASCII revision graph
416
418
417 Print the outgoing changesets alongside a revision graph drawn with
419 Print the outgoing changesets alongside a revision graph drawn with
418 ASCII characters.
420 ASCII characters.
419
421
420 Nodes printed as an @ character are parents of the working
422 Nodes printed as an @ character are parents of the working
421 directory.
423 directory.
422 """
424 """
423
425
424 check_unsupported_flags([], opts)
426 check_unsupported_flags([], opts)
425 o = hg._outgoing(ui, repo, dest, opts)
427 o = hg._outgoing(ui, repo, dest, opts)
426 if o is None:
428 if o is None:
427 return
429 return
428
430
429 revdag = graphrevs(repo, o, opts)
431 revdag = graphrevs(repo, o, opts)
430 displayer = show_changeset(ui, repo, opts, buffered=True)
432 displayer = show_changeset(ui, repo, opts, buffered=True)
431 showparents = [ctx.node() for ctx in repo[None].parents()]
433 showparents = [ctx.node() for ctx in repo[None].parents()]
432 generate(ui, revdag, displayer, showparents, asciiedges)
434 generate(ui, revdag, displayer, showparents, asciiedges)
433
435
434 def gincoming(ui, repo, source="default", **opts):
436 def gincoming(ui, repo, source="default", **opts):
435 """show the incoming changesets alongside an ASCII revision graph
437 """show the incoming changesets alongside an ASCII revision graph
436
438
437 Print the incoming changesets alongside a revision graph drawn with
439 Print the incoming changesets alongside a revision graph drawn with
438 ASCII characters.
440 ASCII characters.
439
441
440 Nodes printed as an @ character are parents of the working
442 Nodes printed as an @ character are parents of the working
441 directory.
443 directory.
442 """
444 """
443 def subreporecurse():
445 def subreporecurse():
444 return 1
446 return 1
445
447
446 check_unsupported_flags([], opts)
448 check_unsupported_flags([], opts)
447 def display(other, chlist, displayer):
449 def display(other, chlist, displayer):
448 revdag = graphrevs(other, chlist, opts)
450 revdag = graphrevs(other, chlist, opts)
449 showparents = [ctx.node() for ctx in repo[None].parents()]
451 showparents = [ctx.node() for ctx in repo[None].parents()]
450 generate(ui, revdag, displayer, showparents, asciiedges)
452 generate(ui, revdag, displayer, showparents, asciiedges)
451
453
452 hg._incoming(display, subreporecurse, ui, repo, source, opts, buffered=True)
454 hg._incoming(display, subreporecurse, ui, repo, source, opts, buffered=True)
453
455
454 def uisetup(ui):
456 def uisetup(ui):
455 '''Initialize the extension.'''
457 '''Initialize the extension.'''
456 _wrapcmd('log', commands.table, graphlog)
458 _wrapcmd('log', commands.table, graphlog)
457 _wrapcmd('incoming', commands.table, gincoming)
459 _wrapcmd('incoming', commands.table, gincoming)
458 _wrapcmd('outgoing', commands.table, goutgoing)
460 _wrapcmd('outgoing', commands.table, goutgoing)
459
461
460 def _wrapcmd(cmd, table, wrapfn):
462 def _wrapcmd(cmd, table, wrapfn):
461 '''wrap the command'''
463 '''wrap the command'''
462 def graph(orig, *args, **kwargs):
464 def graph(orig, *args, **kwargs):
463 if kwargs['graph']:
465 if kwargs['graph']:
464 return wrapfn(*args, **kwargs)
466 return wrapfn(*args, **kwargs)
465 return orig(*args, **kwargs)
467 return orig(*args, **kwargs)
466 entry = extensions.wrapcommand(table, cmd, graph)
468 entry = extensions.wrapcommand(table, cmd, graph)
467 entry[1].append(('G', 'graph', None, _("show the revision DAG")))
469 entry[1].append(('G', 'graph', None, _("show the revision DAG")))
@@ -1,1329 +1,1341 b''
1 # revset.py - revision set queries for mercurial
1 # revset.py - revision set queries for mercurial
2 #
2 #
3 # Copyright 2010 Matt Mackall <mpm@selenic.com>
3 # Copyright 2010 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 import re
8 import re
9 import parser, util, error, discovery, hbisect, phases
9 import parser, util, error, discovery, hbisect, phases
10 import node as nodemod
10 import node as nodemod
11 import bookmarks as bookmarksmod
11 import bookmarks as bookmarksmod
12 import match as matchmod
12 import match as matchmod
13 from i18n import _
13 from i18n import _
14 import encoding
14 import encoding
15
15
16 elements = {
16 elements = {
17 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
17 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
18 "~": (18, None, ("ancestor", 18)),
18 "~": (18, None, ("ancestor", 18)),
19 "^": (18, None, ("parent", 18), ("parentpost", 18)),
19 "^": (18, None, ("parent", 18), ("parentpost", 18)),
20 "-": (5, ("negate", 19), ("minus", 5)),
20 "-": (5, ("negate", 19), ("minus", 5)),
21 "::": (17, ("dagrangepre", 17), ("dagrange", 17),
21 "::": (17, ("dagrangepre", 17), ("dagrange", 17),
22 ("dagrangepost", 17)),
22 ("dagrangepost", 17)),
23 "..": (17, ("dagrangepre", 17), ("dagrange", 17),
23 "..": (17, ("dagrangepre", 17), ("dagrange", 17),
24 ("dagrangepost", 17)),
24 ("dagrangepost", 17)),
25 ":": (15, ("rangepre", 15), ("range", 15), ("rangepost", 15)),
25 ":": (15, ("rangepre", 15), ("range", 15), ("rangepost", 15)),
26 "not": (10, ("not", 10)),
26 "not": (10, ("not", 10)),
27 "!": (10, ("not", 10)),
27 "!": (10, ("not", 10)),
28 "and": (5, None, ("and", 5)),
28 "and": (5, None, ("and", 5)),
29 "&": (5, None, ("and", 5)),
29 "&": (5, None, ("and", 5)),
30 "or": (4, None, ("or", 4)),
30 "or": (4, None, ("or", 4)),
31 "|": (4, None, ("or", 4)),
31 "|": (4, None, ("or", 4)),
32 "+": (4, None, ("or", 4)),
32 "+": (4, None, ("or", 4)),
33 ",": (2, None, ("list", 2)),
33 ",": (2, None, ("list", 2)),
34 ")": (0, None, None),
34 ")": (0, None, None),
35 "symbol": (0, ("symbol",), None),
35 "symbol": (0, ("symbol",), None),
36 "string": (0, ("string",), None),
36 "string": (0, ("string",), None),
37 "end": (0, None, None),
37 "end": (0, None, None),
38 }
38 }
39
39
40 keywords = set(['and', 'or', 'not'])
40 keywords = set(['and', 'or', 'not'])
41
41
42 def tokenize(program):
42 def tokenize(program):
43 pos, l = 0, len(program)
43 pos, l = 0, len(program)
44 while pos < l:
44 while pos < l:
45 c = program[pos]
45 c = program[pos]
46 if c.isspace(): # skip inter-token whitespace
46 if c.isspace(): # skip inter-token whitespace
47 pass
47 pass
48 elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
48 elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
49 yield ('::', None, pos)
49 yield ('::', None, pos)
50 pos += 1 # skip ahead
50 pos += 1 # skip ahead
51 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
51 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
52 yield ('..', None, pos)
52 yield ('..', None, pos)
53 pos += 1 # skip ahead
53 pos += 1 # skip ahead
54 elif c in "():,-|&+!~^": # handle simple operators
54 elif c in "():,-|&+!~^": # handle simple operators
55 yield (c, None, pos)
55 yield (c, None, pos)
56 elif (c in '"\'' or c == 'r' and
56 elif (c in '"\'' or c == 'r' and
57 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
57 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
58 if c == 'r':
58 if c == 'r':
59 pos += 1
59 pos += 1
60 c = program[pos]
60 c = program[pos]
61 decode = lambda x: x
61 decode = lambda x: x
62 else:
62 else:
63 decode = lambda x: x.decode('string-escape')
63 decode = lambda x: x.decode('string-escape')
64 pos += 1
64 pos += 1
65 s = pos
65 s = pos
66 while pos < l: # find closing quote
66 while pos < l: # find closing quote
67 d = program[pos]
67 d = program[pos]
68 if d == '\\': # skip over escaped characters
68 if d == '\\': # skip over escaped characters
69 pos += 2
69 pos += 2
70 continue
70 continue
71 if d == c:
71 if d == c:
72 yield ('string', decode(program[s:pos]), s)
72 yield ('string', decode(program[s:pos]), s)
73 break
73 break
74 pos += 1
74 pos += 1
75 else:
75 else:
76 raise error.ParseError(_("unterminated string"), s)
76 raise error.ParseError(_("unterminated string"), s)
77 elif c.isalnum() or c in '._' or ord(c) > 127: # gather up a symbol/keyword
77 elif c.isalnum() or c in '._' or ord(c) > 127: # gather up a symbol/keyword
78 s = pos
78 s = pos
79 pos += 1
79 pos += 1
80 while pos < l: # find end of symbol
80 while pos < l: # find end of symbol
81 d = program[pos]
81 d = program[pos]
82 if not (d.isalnum() or d in "._/" or ord(d) > 127):
82 if not (d.isalnum() or d in "._/" or ord(d) > 127):
83 break
83 break
84 if d == '.' and program[pos - 1] == '.': # special case for ..
84 if d == '.' and program[pos - 1] == '.': # special case for ..
85 pos -= 1
85 pos -= 1
86 break
86 break
87 pos += 1
87 pos += 1
88 sym = program[s:pos]
88 sym = program[s:pos]
89 if sym in keywords: # operator keywords
89 if sym in keywords: # operator keywords
90 yield (sym, None, s)
90 yield (sym, None, s)
91 else:
91 else:
92 yield ('symbol', sym, s)
92 yield ('symbol', sym, s)
93 pos -= 1
93 pos -= 1
94 else:
94 else:
95 raise error.ParseError(_("syntax error"), pos)
95 raise error.ParseError(_("syntax error"), pos)
96 pos += 1
96 pos += 1
97 yield ('end', None, pos)
97 yield ('end', None, pos)
98
98
99 # helpers
99 # helpers
100
100
101 def getstring(x, err):
101 def getstring(x, err):
102 if x and (x[0] == 'string' or x[0] == 'symbol'):
102 if x and (x[0] == 'string' or x[0] == 'symbol'):
103 return x[1]
103 return x[1]
104 raise error.ParseError(err)
104 raise error.ParseError(err)
105
105
106 def getlist(x):
106 def getlist(x):
107 if not x:
107 if not x:
108 return []
108 return []
109 if x[0] == 'list':
109 if x[0] == 'list':
110 return getlist(x[1]) + [x[2]]
110 return getlist(x[1]) + [x[2]]
111 return [x]
111 return [x]
112
112
113 def getargs(x, min, max, err):
113 def getargs(x, min, max, err):
114 l = getlist(x)
114 l = getlist(x)
115 if len(l) < min or (max >= 0 and len(l) > max):
115 if len(l) < min or (max >= 0 and len(l) > max):
116 raise error.ParseError(err)
116 raise error.ParseError(err)
117 return l
117 return l
118
118
119 def getset(repo, subset, x):
119 def getset(repo, subset, x):
120 if not x:
120 if not x:
121 raise error.ParseError(_("missing argument"))
121 raise error.ParseError(_("missing argument"))
122 return methods[x[0]](repo, subset, *x[1:])
122 return methods[x[0]](repo, subset, *x[1:])
123
123
124 # operator methods
124 # operator methods
125
125
126 def stringset(repo, subset, x):
126 def stringset(repo, subset, x):
127 x = repo[x].rev()
127 x = repo[x].rev()
128 if x == -1 and len(subset) == len(repo):
128 if x == -1 and len(subset) == len(repo):
129 return [-1]
129 return [-1]
130 if len(subset) == len(repo) or x in subset:
130 if len(subset) == len(repo) or x in subset:
131 return [x]
131 return [x]
132 return []
132 return []
133
133
134 def symbolset(repo, subset, x):
134 def symbolset(repo, subset, x):
135 if x in symbols:
135 if x in symbols:
136 raise error.ParseError(_("can't use %s here") % x)
136 raise error.ParseError(_("can't use %s here") % x)
137 return stringset(repo, subset, x)
137 return stringset(repo, subset, x)
138
138
139 def rangeset(repo, subset, x, y):
139 def rangeset(repo, subset, x, y):
140 m = getset(repo, subset, x)
140 m = getset(repo, subset, x)
141 if not m:
141 if not m:
142 m = getset(repo, range(len(repo)), x)
142 m = getset(repo, range(len(repo)), x)
143
143
144 n = getset(repo, subset, y)
144 n = getset(repo, subset, y)
145 if not n:
145 if not n:
146 n = getset(repo, range(len(repo)), y)
146 n = getset(repo, range(len(repo)), y)
147
147
148 if not m or not n:
148 if not m or not n:
149 return []
149 return []
150 m, n = m[0], n[-1]
150 m, n = m[0], n[-1]
151
151
152 if m < n:
152 if m < n:
153 r = range(m, n + 1)
153 r = range(m, n + 1)
154 else:
154 else:
155 r = range(m, n - 1, -1)
155 r = range(m, n - 1, -1)
156 s = set(subset)
156 s = set(subset)
157 return [x for x in r if x in s]
157 return [x for x in r if x in s]
158
158
159 def andset(repo, subset, x, y):
159 def andset(repo, subset, x, y):
160 return getset(repo, getset(repo, subset, x), y)
160 return getset(repo, getset(repo, subset, x), y)
161
161
162 def orset(repo, subset, x, y):
162 def orset(repo, subset, x, y):
163 xl = getset(repo, subset, x)
163 xl = getset(repo, subset, x)
164 s = set(xl)
164 s = set(xl)
165 yl = getset(repo, [r for r in subset if r not in s], y)
165 yl = getset(repo, [r for r in subset if r not in s], y)
166 return xl + yl
166 return xl + yl
167
167
168 def notset(repo, subset, x):
168 def notset(repo, subset, x):
169 s = set(getset(repo, subset, x))
169 s = set(getset(repo, subset, x))
170 return [r for r in subset if r not in s]
170 return [r for r in subset if r not in s]
171
171
172 def listset(repo, subset, a, b):
172 def listset(repo, subset, a, b):
173 raise error.ParseError(_("can't use a list in this context"))
173 raise error.ParseError(_("can't use a list in this context"))
174
174
175 def func(repo, subset, a, b):
175 def func(repo, subset, a, b):
176 if a[0] == 'symbol' and a[1] in symbols:
176 if a[0] == 'symbol' and a[1] in symbols:
177 return symbols[a[1]](repo, subset, b)
177 return symbols[a[1]](repo, subset, b)
178 raise error.ParseError(_("not a function: %s") % a[1])
178 raise error.ParseError(_("not a function: %s") % a[1])
179
179
180 # functions
180 # functions
181
181
182 def adds(repo, subset, x):
182 def adds(repo, subset, x):
183 """``adds(pattern)``
183 """``adds(pattern)``
184 Changesets that add a file matching pattern.
184 Changesets that add a file matching pattern.
185 """
185 """
186 # i18n: "adds" is a keyword
186 # i18n: "adds" is a keyword
187 pat = getstring(x, _("adds requires a pattern"))
187 pat = getstring(x, _("adds requires a pattern"))
188 return checkstatus(repo, subset, pat, 1)
188 return checkstatus(repo, subset, pat, 1)
189
189
190 def ancestor(repo, subset, x):
190 def ancestor(repo, subset, x):
191 """``ancestor(single, single)``
191 """``ancestor(single, single)``
192 Greatest common ancestor of the two changesets.
192 Greatest common ancestor of the two changesets.
193 """
193 """
194 # i18n: "ancestor" is a keyword
194 # i18n: "ancestor" is a keyword
195 l = getargs(x, 2, 2, _("ancestor requires two arguments"))
195 l = getargs(x, 2, 2, _("ancestor requires two arguments"))
196 r = range(len(repo))
196 r = range(len(repo))
197 a = getset(repo, r, l[0])
197 a = getset(repo, r, l[0])
198 b = getset(repo, r, l[1])
198 b = getset(repo, r, l[1])
199 if len(a) != 1 or len(b) != 1:
199 if len(a) != 1 or len(b) != 1:
200 # i18n: "ancestor" is a keyword
200 # i18n: "ancestor" is a keyword
201 raise error.ParseError(_("ancestor arguments must be single revisions"))
201 raise error.ParseError(_("ancestor arguments must be single revisions"))
202 an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
202 an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
203
203
204 return [r for r in an if r in subset]
204 return [r for r in an if r in subset]
205
205
206 def ancestors(repo, subset, x):
206 def ancestors(repo, subset, x):
207 """``ancestors(set)``
207 """``ancestors(set)``
208 Changesets that are ancestors of a changeset in set.
208 Changesets that are ancestors of a changeset in set.
209 """
209 """
210 args = getset(repo, range(len(repo)), x)
210 args = getset(repo, range(len(repo)), x)
211 if not args:
211 if not args:
212 return []
212 return []
213 s = set(repo.changelog.ancestors(*args)) | set(args)
213 s = set(repo.changelog.ancestors(*args)) | set(args)
214 return [r for r in subset if r in s]
214 return [r for r in subset if r in s]
215
215
216 def ancestorspec(repo, subset, x, n):
216 def ancestorspec(repo, subset, x, n):
217 """``set~n``
217 """``set~n``
218 Changesets that are the Nth ancestor (first parents only) of a changeset in set.
218 Changesets that are the Nth ancestor (first parents only) of a changeset in set.
219 """
219 """
220 try:
220 try:
221 n = int(n[1])
221 n = int(n[1])
222 except (TypeError, ValueError):
222 except (TypeError, ValueError):
223 raise error.ParseError(_("~ expects a number"))
223 raise error.ParseError(_("~ expects a number"))
224 ps = set()
224 ps = set()
225 cl = repo.changelog
225 cl = repo.changelog
226 for r in getset(repo, subset, x):
226 for r in getset(repo, subset, x):
227 for i in range(n):
227 for i in range(n):
228 r = cl.parentrevs(r)[0]
228 r = cl.parentrevs(r)[0]
229 ps.add(r)
229 ps.add(r)
230 return [r for r in subset if r in ps]
230 return [r for r in subset if r in ps]
231
231
232 def author(repo, subset, x):
232 def author(repo, subset, x):
233 """``author(string)``
233 """``author(string)``
234 Alias for ``user(string)``.
234 Alias for ``user(string)``.
235 """
235 """
236 # i18n: "author" is a keyword
236 # i18n: "author" is a keyword
237 n = encoding.lower(getstring(x, _("author requires a string")))
237 n = encoding.lower(getstring(x, _("author requires a string")))
238 return [r for r in subset if n in encoding.lower(repo[r].user())]
238 return [r for r in subset if n in encoding.lower(repo[r].user())]
239
239
240 def bisect(repo, subset, x):
240 def bisect(repo, subset, x):
241 """``bisect(string)``
241 """``bisect(string)``
242 Changesets marked in the specified bisect status:
242 Changesets marked in the specified bisect status:
243
243
244 - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip
244 - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip
245 - ``goods``, ``bads`` : csets topologicaly good/bad
245 - ``goods``, ``bads`` : csets topologicaly good/bad
246 - ``range`` : csets taking part in the bisection
246 - ``range`` : csets taking part in the bisection
247 - ``pruned`` : csets that are goods, bads or skipped
247 - ``pruned`` : csets that are goods, bads or skipped
248 - ``untested`` : csets whose fate is yet unknown
248 - ``untested`` : csets whose fate is yet unknown
249 - ``ignored`` : csets ignored due to DAG topology
249 - ``ignored`` : csets ignored due to DAG topology
250 """
250 """
251 status = getstring(x, _("bisect requires a string")).lower()
251 status = getstring(x, _("bisect requires a string")).lower()
252 return [r for r in subset if r in hbisect.get(repo, status)]
252 return [r for r in subset if r in hbisect.get(repo, status)]
253
253
254 # Backward-compatibility
254 # Backward-compatibility
255 # - no help entry so that we do not advertise it any more
255 # - no help entry so that we do not advertise it any more
256 def bisected(repo, subset, x):
256 def bisected(repo, subset, x):
257 return bisect(repo, subset, x)
257 return bisect(repo, subset, x)
258
258
259 def bookmark(repo, subset, x):
259 def bookmark(repo, subset, x):
260 """``bookmark([name])``
260 """``bookmark([name])``
261 The named bookmark or all bookmarks.
261 The named bookmark or all bookmarks.
262 """
262 """
263 # i18n: "bookmark" is a keyword
263 # i18n: "bookmark" is a keyword
264 args = getargs(x, 0, 1, _('bookmark takes one or no arguments'))
264 args = getargs(x, 0, 1, _('bookmark takes one or no arguments'))
265 if args:
265 if args:
266 bm = getstring(args[0],
266 bm = getstring(args[0],
267 # i18n: "bookmark" is a keyword
267 # i18n: "bookmark" is a keyword
268 _('the argument to bookmark must be a string'))
268 _('the argument to bookmark must be a string'))
269 bmrev = bookmarksmod.listbookmarks(repo).get(bm, None)
269 bmrev = bookmarksmod.listbookmarks(repo).get(bm, None)
270 if not bmrev:
270 if not bmrev:
271 raise util.Abort(_("bookmark '%s' does not exist") % bm)
271 raise util.Abort(_("bookmark '%s' does not exist") % bm)
272 bmrev = repo[bmrev].rev()
272 bmrev = repo[bmrev].rev()
273 return [r for r in subset if r == bmrev]
273 return [r for r in subset if r == bmrev]
274 bms = set([repo[r].rev()
274 bms = set([repo[r].rev()
275 for r in bookmarksmod.listbookmarks(repo).values()])
275 for r in bookmarksmod.listbookmarks(repo).values()])
276 return [r for r in subset if r in bms]
276 return [r for r in subset if r in bms]
277
277
278 def branch(repo, subset, x):
278 def branch(repo, subset, x):
279 """``branch(string or set)``
279 """``branch(string or set)``
280 All changesets belonging to the given branch or the branches of the given
280 All changesets belonging to the given branch or the branches of the given
281 changesets.
281 changesets.
282 """
282 """
283 try:
283 try:
284 b = getstring(x, '')
284 b = getstring(x, '')
285 if b in repo.branchmap():
285 if b in repo.branchmap():
286 return [r for r in subset if repo[r].branch() == b]
286 return [r for r in subset if repo[r].branch() == b]
287 except error.ParseError:
287 except error.ParseError:
288 # not a string, but another revspec, e.g. tip()
288 # not a string, but another revspec, e.g. tip()
289 pass
289 pass
290
290
291 s = getset(repo, range(len(repo)), x)
291 s = getset(repo, range(len(repo)), x)
292 b = set()
292 b = set()
293 for r in s:
293 for r in s:
294 b.add(repo[r].branch())
294 b.add(repo[r].branch())
295 s = set(s)
295 s = set(s)
296 return [r for r in subset if r in s or repo[r].branch() in b]
296 return [r for r in subset if r in s or repo[r].branch() in b]
297
297
298 def checkstatus(repo, subset, pat, field):
298 def checkstatus(repo, subset, pat, field):
299 m = None
299 m = None
300 s = []
300 s = []
301 fast = not matchmod.patkind(pat)
301 fast = not matchmod.patkind(pat)
302 for r in subset:
302 for r in subset:
303 c = repo[r]
303 c = repo[r]
304 if fast:
304 if fast:
305 if pat not in c.files():
305 if pat not in c.files():
306 continue
306 continue
307 else:
307 else:
308 if not m or matchmod.patkind(pat) == 'set':
308 if not m or matchmod.patkind(pat) == 'set':
309 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
309 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
310 for f in c.files():
310 for f in c.files():
311 if m(f):
311 if m(f):
312 break
312 break
313 else:
313 else:
314 continue
314 continue
315 files = repo.status(c.p1().node(), c.node())[field]
315 files = repo.status(c.p1().node(), c.node())[field]
316 if fast:
316 if fast:
317 if pat in files:
317 if pat in files:
318 s.append(r)
318 s.append(r)
319 else:
319 else:
320 for f in files:
320 for f in files:
321 if m(f):
321 if m(f):
322 s.append(r)
322 s.append(r)
323 break
323 break
324 return s
324 return s
325
325
326 def _children(repo, narrow, s):
326 def _children(repo, narrow, s):
327 cs = set()
327 cs = set()
328 pr = repo.changelog.parentrevs
328 pr = repo.changelog.parentrevs
329 s = set(s)
329 s = set(s)
330 for r in xrange(len(repo)):
330 for r in xrange(len(repo)):
331 for p in pr(r):
331 for p in pr(r):
332 if p in s:
332 if p in s:
333 cs.add(r)
333 cs.add(r)
334 return cs
334 return cs
335
335
336 def children(repo, subset, x):
336 def children(repo, subset, x):
337 """``children(set)``
337 """``children(set)``
338 Child changesets of changesets in set.
338 Child changesets of changesets in set.
339 """
339 """
340 s = getset(repo, range(len(repo)), x)
340 s = getset(repo, range(len(repo)), x)
341 cs = _children(repo, subset, s)
341 cs = _children(repo, subset, s)
342 return [r for r in subset if r in cs]
342 return [r for r in subset if r in cs]
343
343
344 def closed(repo, subset, x):
344 def closed(repo, subset, x):
345 """``closed()``
345 """``closed()``
346 Changeset is closed.
346 Changeset is closed.
347 """
347 """
348 # i18n: "closed" is a keyword
348 # i18n: "closed" is a keyword
349 getargs(x, 0, 0, _("closed takes no arguments"))
349 getargs(x, 0, 0, _("closed takes no arguments"))
350 return [r for r in subset if repo[r].extra().get('close')]
350 return [r for r in subset if repo[r].extra().get('close')]
351
351
352 def contains(repo, subset, x):
352 def contains(repo, subset, x):
353 """``contains(pattern)``
353 """``contains(pattern)``
354 Revision contains a file matching pattern. See :hg:`help patterns`
354 Revision contains a file matching pattern. See :hg:`help patterns`
355 for information about file patterns.
355 for information about file patterns.
356 """
356 """
357 # i18n: "contains" is a keyword
357 # i18n: "contains" is a keyword
358 pat = getstring(x, _("contains requires a pattern"))
358 pat = getstring(x, _("contains requires a pattern"))
359 m = None
359 m = None
360 s = []
360 s = []
361 if not matchmod.patkind(pat):
361 if not matchmod.patkind(pat):
362 for r in subset:
362 for r in subset:
363 if pat in repo[r]:
363 if pat in repo[r]:
364 s.append(r)
364 s.append(r)
365 else:
365 else:
366 for r in subset:
366 for r in subset:
367 c = repo[r]
367 c = repo[r]
368 if not m or matchmod.patkind(pat) == 'set':
368 if not m or matchmod.patkind(pat) == 'set':
369 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
369 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c)
370 for f in c.manifest():
370 for f in c.manifest():
371 if m(f):
371 if m(f):
372 s.append(r)
372 s.append(r)
373 break
373 break
374 return s
374 return s
375
375
376 def date(repo, subset, x):
376 def date(repo, subset, x):
377 """``date(interval)``
377 """``date(interval)``
378 Changesets within the interval, see :hg:`help dates`.
378 Changesets within the interval, see :hg:`help dates`.
379 """
379 """
380 # i18n: "date" is a keyword
380 # i18n: "date" is a keyword
381 ds = getstring(x, _("date requires a string"))
381 ds = getstring(x, _("date requires a string"))
382 dm = util.matchdate(ds)
382 dm = util.matchdate(ds)
383 return [r for r in subset if dm(repo[r].date()[0])]
383 return [r for r in subset if dm(repo[r].date()[0])]
384
384
385 def desc(repo, subset, x):
385 def desc(repo, subset, x):
386 """``desc(string)``
386 """``desc(string)``
387 Search commit message for string. The match is case-insensitive.
387 Search commit message for string. The match is case-insensitive.
388 """
388 """
389 # i18n: "desc" is a keyword
389 # i18n: "desc" is a keyword
390 ds = encoding.lower(getstring(x, _("desc requires a string")))
390 ds = encoding.lower(getstring(x, _("desc requires a string")))
391 l = []
391 l = []
392 for r in subset:
392 for r in subset:
393 c = repo[r]
393 c = repo[r]
394 if ds in encoding.lower(c.description()):
394 if ds in encoding.lower(c.description()):
395 l.append(r)
395 l.append(r)
396 return l
396 return l
397
397
398 def descendants(repo, subset, x):
398 def descendants(repo, subset, x):
399 """``descendants(set)``
399 """``descendants(set)``
400 Changesets which are descendants of changesets in set.
400 Changesets which are descendants of changesets in set.
401 """
401 """
402 args = getset(repo, range(len(repo)), x)
402 args = getset(repo, range(len(repo)), x)
403 if not args:
403 if not args:
404 return []
404 return []
405 s = set(repo.changelog.descendants(*args)) | set(args)
405 s = set(repo.changelog.descendants(*args)) | set(args)
406 return [r for r in subset if r in s]
406 return [r for r in subset if r in s]
407
407
408 def draft(repo, subset, x):
408 def draft(repo, subset, x):
409 """``draft()``
409 """``draft()``
410 Changeset in draft phase."""
410 Changeset in draft phase."""
411 getargs(x, 0, 0, _("draft takes no arguments"))
411 getargs(x, 0, 0, _("draft takes no arguments"))
412 return [r for r in subset if repo._phaserev[r] == phases.draft]
412 return [r for r in subset if repo._phaserev[r] == phases.draft]
413
413
414 def filelog(repo, subset, x):
414 def filelog(repo, subset, x):
415 """``filelog(pattern)``
415 """``filelog(pattern)``
416 Changesets connected to the specified filelog.
416 Changesets connected to the specified filelog.
417 """
417 """
418
418
419 pat = getstring(x, _("filelog requires a pattern"))
419 pat = getstring(x, _("filelog requires a pattern"))
420 m = matchmod.match(repo.root, repo.getcwd(), [pat], default='relpath',
420 m = matchmod.match(repo.root, repo.getcwd(), [pat], default='relpath',
421 ctx=repo[None])
421 ctx=repo[None])
422 s = set()
422 s = set()
423
423
424 if not matchmod.patkind(pat):
424 if not matchmod.patkind(pat):
425 for f in m.files():
425 for f in m.files():
426 fl = repo.file(f)
426 fl = repo.file(f)
427 for fr in fl:
427 for fr in fl:
428 s.add(fl.linkrev(fr))
428 s.add(fl.linkrev(fr))
429 else:
429 else:
430 for f in repo[None]:
430 for f in repo[None]:
431 if m(f):
431 if m(f):
432 fl = repo.file(f)
432 fl = repo.file(f)
433 for fr in fl:
433 for fr in fl:
434 s.add(fl.linkrev(fr))
434 s.add(fl.linkrev(fr))
435
435
436 return [r for r in subset if r in s]
436 return [r for r in subset if r in s]
437
437
438 def first(repo, subset, x):
438 def first(repo, subset, x):
439 """``first(set, [n])``
439 """``first(set, [n])``
440 An alias for limit().
440 An alias for limit().
441 """
441 """
442 return limit(repo, subset, x)
442 return limit(repo, subset, x)
443
443
444 def follow(repo, subset, x):
444 def follow(repo, subset, x):
445 """``follow([file])``
445 """``follow([file])``
446 An alias for ``::.`` (ancestors of the working copy's first parent).
446 An alias for ``::.`` (ancestors of the working copy's first parent).
447 If a filename is specified, the history of the given file is followed,
447 If a filename is specified, the history of the given file is followed,
448 including copies.
448 including copies.
449 """
449 """
450 # i18n: "follow" is a keyword
450 # i18n: "follow" is a keyword
451 l = getargs(x, 0, 1, _("follow takes no arguments or a filename"))
451 l = getargs(x, 0, 1, _("follow takes no arguments or a filename"))
452 c = repo['.']
452 c = repo['.']
453 if l:
453 if l:
454 x = getstring(l[0], _("follow expected a filename"))
454 x = getstring(l[0], _("follow expected a filename"))
455 if x in c:
455 if x in c:
456 cx = c[x]
456 cx = c[x]
457 s = set(ctx.rev() for ctx in cx.ancestors())
457 s = set(ctx.rev() for ctx in cx.ancestors())
458 # include the revision responsible for the most recent version
458 # include the revision responsible for the most recent version
459 s.add(cx.linkrev())
459 s.add(cx.linkrev())
460 else:
460 else:
461 return []
461 return []
462 else:
462 else:
463 s = set(repo.changelog.ancestors(c.rev()))
463 s = set(repo.changelog.ancestors(c.rev()))
464 s.add(c.rev())
464 s.add(c.rev())
465
465
466 return [r for r in subset if r in s]
466 return [r for r in subset if r in s]
467
467
468 def _followfirst(repo, subset, x):
468 def _followfirst(repo, subset, x):
469 # ``followfirst([file])``
469 # ``followfirst([file])``
470 # Like ``follow([file])`` but follows only the first parent of
470 # Like ``follow([file])`` but follows only the first parent of
471 # every revision or file revision.
471 # every revision or file revision.
472 # i18n: "_followfirst" is a keyword
472 # i18n: "_followfirst" is a keyword
473 l = getargs(x, 0, 1, _("_followfirst takes no arguments or a filename"))
473 l = getargs(x, 0, 1, _("_followfirst takes no arguments or a filename"))
474 c = repo['.']
474 c = repo['.']
475 if l:
475 if l:
476 x = getstring(l[0], _("_followfirst expected a filename"))
476 x = getstring(l[0], _("_followfirst expected a filename"))
477 if x not in c:
477 if x not in c:
478 return []
478 return []
479 cx = c[x]
479 cx = c[x]
480 visit = {}
480 visit = {}
481 s = set([cx.linkrev()])
481 s = set([cx.linkrev()])
482 while True:
482 while True:
483 for p in cx.parents()[:1]:
483 for p in cx.parents()[:1]:
484 visit[(p.rev(), p.node())] = p
484 visit[(p.rev(), p.node())] = p
485 if not visit:
485 if not visit:
486 break
486 break
487 cx = visit.pop(max(visit))
487 cx = visit.pop(max(visit))
488 s.add(cx.rev())
488 s.add(cx.rev())
489 else:
489 else:
490 cl = repo.changelog
490 cl = repo.changelog
491 s = set()
491 s = set()
492 visit = [c.rev()]
492 visit = [c.rev()]
493 while visit:
493 while visit:
494 for prev in cl.parentrevs(visit.pop(0))[:1]:
494 for prev in cl.parentrevs(visit.pop(0))[:1]:
495 if prev not in s and prev != nodemod.nullrev:
495 if prev not in s and prev != nodemod.nullrev:
496 visit.append(prev)
496 visit.append(prev)
497 s.add(prev)
497 s.add(prev)
498 s.add(c.rev())
498 s.add(c.rev())
499
499
500 return [r for r in subset if r in s]
500 return [r for r in subset if r in s]
501
501
502 def getall(repo, subset, x):
502 def getall(repo, subset, x):
503 """``all()``
503 """``all()``
504 All changesets, the same as ``0:tip``.
504 All changesets, the same as ``0:tip``.
505 """
505 """
506 # i18n: "all" is a keyword
506 # i18n: "all" is a keyword
507 getargs(x, 0, 0, _("all takes no arguments"))
507 getargs(x, 0, 0, _("all takes no arguments"))
508 return subset
508 return subset
509
509
510 def grep(repo, subset, x):
510 def grep(repo, subset, x):
511 """``grep(regex)``
511 """``grep(regex)``
512 Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``
512 Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``
513 to ensure special escape characters are handled correctly. Unlike
513 to ensure special escape characters are handled correctly. Unlike
514 ``keyword(string)``, the match is case-sensitive.
514 ``keyword(string)``, the match is case-sensitive.
515 """
515 """
516 try:
516 try:
517 # i18n: "grep" is a keyword
517 # i18n: "grep" is a keyword
518 gr = re.compile(getstring(x, _("grep requires a string")))
518 gr = re.compile(getstring(x, _("grep requires a string")))
519 except re.error, e:
519 except re.error, e:
520 raise error.ParseError(_('invalid match pattern: %s') % e)
520 raise error.ParseError(_('invalid match pattern: %s') % e)
521 l = []
521 l = []
522 for r in subset:
522 for r in subset:
523 c = repo[r]
523 c = repo[r]
524 for e in c.files() + [c.user(), c.description()]:
524 for e in c.files() + [c.user(), c.description()]:
525 if gr.search(e):
525 if gr.search(e):
526 l.append(r)
526 l.append(r)
527 break
527 break
528 return l
528 return l
529
529
530 def _matchfiles(repo, subset, x):
530 def _matchfiles(repo, subset, x):
531 # _matchfiles takes a revset list of prefixed arguments:
531 # _matchfiles takes a revset list of prefixed arguments:
532 #
532 #
533 # [p:foo, i:bar, x:baz]
533 # [p:foo, i:bar, x:baz]
534 #
534 #
535 # builds a match object from them and filters subset. Allowed
535 # builds a match object from them and filters subset. Allowed
536 # prefixes are 'p:' for regular patterns, 'i:' for include
536 # prefixes are 'p:' for regular patterns, 'i:' for include
537 # patterns and 'x:' for exclude patterns.
537 # patterns and 'x:' for exclude patterns. Use 'r:' prefix to pass
538 # a revision identifier, or the empty string to reference the
539 # working directory, from which the match object is
540 # initialized. At most one 'r:' argument can be passed.
538
541
539 # i18n: "_matchfiles" is a keyword
542 # i18n: "_matchfiles" is a keyword
540 l = getargs(x, 1, -1, _("_matchfiles requires at least one argument"))
543 l = getargs(x, 1, -1, _("_matchfiles requires at least one argument"))
541 pats, inc, exc = [], [], []
544 pats, inc, exc = [], [], []
542 hasset = False
545 hasset = False
546 rev = None
543 for arg in l:
547 for arg in l:
544 s = getstring(arg, _("_matchfiles requires string arguments"))
548 s = getstring(arg, _("_matchfiles requires string arguments"))
545 prefix, value = s[:2], s[2:]
549 prefix, value = s[:2], s[2:]
546 if prefix == 'p:':
550 if prefix == 'p:':
547 pats.append(value)
551 pats.append(value)
548 elif prefix == 'i:':
552 elif prefix == 'i:':
549 inc.append(value)
553 inc.append(value)
550 elif prefix == 'x:':
554 elif prefix == 'x:':
551 exc.append(value)
555 exc.append(value)
556 elif prefix == 'r:':
557 if rev is not None:
558 raise error.ParseError(_('_matchfiles expected at most one '
559 'revision'))
560 rev = value
552 else:
561 else:
553 raise error.ParseError(_('invalid _matchfiles prefix: %s') % prefix)
562 raise error.ParseError(_('invalid _matchfiles prefix: %s') % prefix)
554 if not hasset and matchmod.patkind(value) == 'set':
563 if not hasset and matchmod.patkind(value) == 'set':
555 hasset = True
564 hasset = True
556 m = None
565 m = None
557 s = []
566 s = []
558 for r in subset:
567 for r in subset:
559 c = repo[r]
568 c = repo[r]
560 if not m or hasset:
569 if not m or (hasset and rev is None):
570 ctx = c
571 if rev is not None:
572 ctx = repo[rev or None]
561 m = matchmod.match(repo.root, repo.getcwd(), pats, include=inc,
573 m = matchmod.match(repo.root, repo.getcwd(), pats, include=inc,
562 exclude=exc, ctx=c)
574 exclude=exc, ctx=ctx)
563 for f in c.files():
575 for f in c.files():
564 if m(f):
576 if m(f):
565 s.append(r)
577 s.append(r)
566 break
578 break
567 return s
579 return s
568
580
569 def hasfile(repo, subset, x):
581 def hasfile(repo, subset, x):
570 """``file(pattern)``
582 """``file(pattern)``
571 Changesets affecting files matched by pattern.
583 Changesets affecting files matched by pattern.
572 """
584 """
573 # i18n: "file" is a keyword
585 # i18n: "file" is a keyword
574 pat = getstring(x, _("file requires a pattern"))
586 pat = getstring(x, _("file requires a pattern"))
575 return _matchfiles(repo, subset, ('string', 'p:' + pat))
587 return _matchfiles(repo, subset, ('string', 'p:' + pat))
576
588
577 def head(repo, subset, x):
589 def head(repo, subset, x):
578 """``head()``
590 """``head()``
579 Changeset is a named branch head.
591 Changeset is a named branch head.
580 """
592 """
581 # i18n: "head" is a keyword
593 # i18n: "head" is a keyword
582 getargs(x, 0, 0, _("head takes no arguments"))
594 getargs(x, 0, 0, _("head takes no arguments"))
583 hs = set()
595 hs = set()
584 for b, ls in repo.branchmap().iteritems():
596 for b, ls in repo.branchmap().iteritems():
585 hs.update(repo[h].rev() for h in ls)
597 hs.update(repo[h].rev() for h in ls)
586 return [r for r in subset if r in hs]
598 return [r for r in subset if r in hs]
587
599
588 def heads(repo, subset, x):
600 def heads(repo, subset, x):
589 """``heads(set)``
601 """``heads(set)``
590 Members of set with no children in set.
602 Members of set with no children in set.
591 """
603 """
592 s = getset(repo, subset, x)
604 s = getset(repo, subset, x)
593 ps = set(parents(repo, subset, x))
605 ps = set(parents(repo, subset, x))
594 return [r for r in s if r not in ps]
606 return [r for r in s if r not in ps]
595
607
596 def keyword(repo, subset, x):
608 def keyword(repo, subset, x):
597 """``keyword(string)``
609 """``keyword(string)``
598 Search commit message, user name, and names of changed files for
610 Search commit message, user name, and names of changed files for
599 string. The match is case-insensitive.
611 string. The match is case-insensitive.
600 """
612 """
601 # i18n: "keyword" is a keyword
613 # i18n: "keyword" is a keyword
602 kw = encoding.lower(getstring(x, _("keyword requires a string")))
614 kw = encoding.lower(getstring(x, _("keyword requires a string")))
603 l = []
615 l = []
604 for r in subset:
616 for r in subset:
605 c = repo[r]
617 c = repo[r]
606 t = " ".join(c.files() + [c.user(), c.description()])
618 t = " ".join(c.files() + [c.user(), c.description()])
607 if kw in encoding.lower(t):
619 if kw in encoding.lower(t):
608 l.append(r)
620 l.append(r)
609 return l
621 return l
610
622
611 def limit(repo, subset, x):
623 def limit(repo, subset, x):
612 """``limit(set, [n])``
624 """``limit(set, [n])``
613 First n members of set, defaulting to 1.
625 First n members of set, defaulting to 1.
614 """
626 """
615 # i18n: "limit" is a keyword
627 # i18n: "limit" is a keyword
616 l = getargs(x, 1, 2, _("limit requires one or two arguments"))
628 l = getargs(x, 1, 2, _("limit requires one or two arguments"))
617 try:
629 try:
618 lim = 1
630 lim = 1
619 if len(l) == 2:
631 if len(l) == 2:
620 # i18n: "limit" is a keyword
632 # i18n: "limit" is a keyword
621 lim = int(getstring(l[1], _("limit requires a number")))
633 lim = int(getstring(l[1], _("limit requires a number")))
622 except (TypeError, ValueError):
634 except (TypeError, ValueError):
623 # i18n: "limit" is a keyword
635 # i18n: "limit" is a keyword
624 raise error.ParseError(_("limit expects a number"))
636 raise error.ParseError(_("limit expects a number"))
625 ss = set(subset)
637 ss = set(subset)
626 os = getset(repo, range(len(repo)), l[0])[:lim]
638 os = getset(repo, range(len(repo)), l[0])[:lim]
627 return [r for r in os if r in ss]
639 return [r for r in os if r in ss]
628
640
629 def last(repo, subset, x):
641 def last(repo, subset, x):
630 """``last(set, [n])``
642 """``last(set, [n])``
631 Last n members of set, defaulting to 1.
643 Last n members of set, defaulting to 1.
632 """
644 """
633 # i18n: "last" is a keyword
645 # i18n: "last" is a keyword
634 l = getargs(x, 1, 2, _("last requires one or two arguments"))
646 l = getargs(x, 1, 2, _("last requires one or two arguments"))
635 try:
647 try:
636 lim = 1
648 lim = 1
637 if len(l) == 2:
649 if len(l) == 2:
638 # i18n: "last" is a keyword
650 # i18n: "last" is a keyword
639 lim = int(getstring(l[1], _("last requires a number")))
651 lim = int(getstring(l[1], _("last requires a number")))
640 except (TypeError, ValueError):
652 except (TypeError, ValueError):
641 # i18n: "last" is a keyword
653 # i18n: "last" is a keyword
642 raise error.ParseError(_("last expects a number"))
654 raise error.ParseError(_("last expects a number"))
643 ss = set(subset)
655 ss = set(subset)
644 os = getset(repo, range(len(repo)), l[0])[-lim:]
656 os = getset(repo, range(len(repo)), l[0])[-lim:]
645 return [r for r in os if r in ss]
657 return [r for r in os if r in ss]
646
658
647 def maxrev(repo, subset, x):
659 def maxrev(repo, subset, x):
648 """``max(set)``
660 """``max(set)``
649 Changeset with highest revision number in set.
661 Changeset with highest revision number in set.
650 """
662 """
651 os = getset(repo, range(len(repo)), x)
663 os = getset(repo, range(len(repo)), x)
652 if os:
664 if os:
653 m = max(os)
665 m = max(os)
654 if m in subset:
666 if m in subset:
655 return [m]
667 return [m]
656 return []
668 return []
657
669
658 def merge(repo, subset, x):
670 def merge(repo, subset, x):
659 """``merge()``
671 """``merge()``
660 Changeset is a merge changeset.
672 Changeset is a merge changeset.
661 """
673 """
662 # i18n: "merge" is a keyword
674 # i18n: "merge" is a keyword
663 getargs(x, 0, 0, _("merge takes no arguments"))
675 getargs(x, 0, 0, _("merge takes no arguments"))
664 cl = repo.changelog
676 cl = repo.changelog
665 return [r for r in subset if cl.parentrevs(r)[1] != -1]
677 return [r for r in subset if cl.parentrevs(r)[1] != -1]
666
678
667 def minrev(repo, subset, x):
679 def minrev(repo, subset, x):
668 """``min(set)``
680 """``min(set)``
669 Changeset with lowest revision number in set.
681 Changeset with lowest revision number in set.
670 """
682 """
671 os = getset(repo, range(len(repo)), x)
683 os = getset(repo, range(len(repo)), x)
672 if os:
684 if os:
673 m = min(os)
685 m = min(os)
674 if m in subset:
686 if m in subset:
675 return [m]
687 return [m]
676 return []
688 return []
677
689
678 def modifies(repo, subset, x):
690 def modifies(repo, subset, x):
679 """``modifies(pattern)``
691 """``modifies(pattern)``
680 Changesets modifying files matched by pattern.
692 Changesets modifying files matched by pattern.
681 """
693 """
682 # i18n: "modifies" is a keyword
694 # i18n: "modifies" is a keyword
683 pat = getstring(x, _("modifies requires a pattern"))
695 pat = getstring(x, _("modifies requires a pattern"))
684 return checkstatus(repo, subset, pat, 0)
696 return checkstatus(repo, subset, pat, 0)
685
697
686 def node(repo, subset, x):
698 def node(repo, subset, x):
687 """``id(string)``
699 """``id(string)``
688 Revision non-ambiguously specified by the given hex string prefix.
700 Revision non-ambiguously specified by the given hex string prefix.
689 """
701 """
690 # i18n: "id" is a keyword
702 # i18n: "id" is a keyword
691 l = getargs(x, 1, 1, _("id requires one argument"))
703 l = getargs(x, 1, 1, _("id requires one argument"))
692 # i18n: "id" is a keyword
704 # i18n: "id" is a keyword
693 n = getstring(l[0], _("id requires a string"))
705 n = getstring(l[0], _("id requires a string"))
694 if len(n) == 40:
706 if len(n) == 40:
695 rn = repo[n].rev()
707 rn = repo[n].rev()
696 else:
708 else:
697 rn = repo.changelog.rev(repo.changelog._partialmatch(n))
709 rn = repo.changelog.rev(repo.changelog._partialmatch(n))
698 return [r for r in subset if r == rn]
710 return [r for r in subset if r == rn]
699
711
700 def outgoing(repo, subset, x):
712 def outgoing(repo, subset, x):
701 """``outgoing([path])``
713 """``outgoing([path])``
702 Changesets not found in the specified destination repository, or the
714 Changesets not found in the specified destination repository, or the
703 default push location.
715 default push location.
704 """
716 """
705 import hg # avoid start-up nasties
717 import hg # avoid start-up nasties
706 # i18n: "outgoing" is a keyword
718 # i18n: "outgoing" is a keyword
707 l = getargs(x, 0, 1, _("outgoing takes one or no arguments"))
719 l = getargs(x, 0, 1, _("outgoing takes one or no arguments"))
708 # i18n: "outgoing" is a keyword
720 # i18n: "outgoing" is a keyword
709 dest = l and getstring(l[0], _("outgoing requires a repository path")) or ''
721 dest = l and getstring(l[0], _("outgoing requires a repository path")) or ''
710 dest = repo.ui.expandpath(dest or 'default-push', dest or 'default')
722 dest = repo.ui.expandpath(dest or 'default-push', dest or 'default')
711 dest, branches = hg.parseurl(dest)
723 dest, branches = hg.parseurl(dest)
712 revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
724 revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
713 if revs:
725 if revs:
714 revs = [repo.lookup(rev) for rev in revs]
726 revs = [repo.lookup(rev) for rev in revs]
715 other = hg.peer(repo, {}, dest)
727 other = hg.peer(repo, {}, dest)
716 repo.ui.pushbuffer()
728 repo.ui.pushbuffer()
717 outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs)
729 outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs)
718 repo.ui.popbuffer()
730 repo.ui.popbuffer()
719 cl = repo.changelog
731 cl = repo.changelog
720 o = set([cl.rev(r) for r in outgoing.missing])
732 o = set([cl.rev(r) for r in outgoing.missing])
721 return [r for r in subset if r in o]
733 return [r for r in subset if r in o]
722
734
723 def p1(repo, subset, x):
735 def p1(repo, subset, x):
724 """``p1([set])``
736 """``p1([set])``
725 First parent of changesets in set, or the working directory.
737 First parent of changesets in set, or the working directory.
726 """
738 """
727 if x is None:
739 if x is None:
728 p = repo[x].p1().rev()
740 p = repo[x].p1().rev()
729 return [r for r in subset if r == p]
741 return [r for r in subset if r == p]
730
742
731 ps = set()
743 ps = set()
732 cl = repo.changelog
744 cl = repo.changelog
733 for r in getset(repo, range(len(repo)), x):
745 for r in getset(repo, range(len(repo)), x):
734 ps.add(cl.parentrevs(r)[0])
746 ps.add(cl.parentrevs(r)[0])
735 return [r for r in subset if r in ps]
747 return [r for r in subset if r in ps]
736
748
737 def p2(repo, subset, x):
749 def p2(repo, subset, x):
738 """``p2([set])``
750 """``p2([set])``
739 Second parent of changesets in set, or the working directory.
751 Second parent of changesets in set, or the working directory.
740 """
752 """
741 if x is None:
753 if x is None:
742 ps = repo[x].parents()
754 ps = repo[x].parents()
743 try:
755 try:
744 p = ps[1].rev()
756 p = ps[1].rev()
745 return [r for r in subset if r == p]
757 return [r for r in subset if r == p]
746 except IndexError:
758 except IndexError:
747 return []
759 return []
748
760
749 ps = set()
761 ps = set()
750 cl = repo.changelog
762 cl = repo.changelog
751 for r in getset(repo, range(len(repo)), x):
763 for r in getset(repo, range(len(repo)), x):
752 ps.add(cl.parentrevs(r)[1])
764 ps.add(cl.parentrevs(r)[1])
753 return [r for r in subset if r in ps]
765 return [r for r in subset if r in ps]
754
766
755 def parents(repo, subset, x):
767 def parents(repo, subset, x):
756 """``parents([set])``
768 """``parents([set])``
757 The set of all parents for all changesets in set, or the working directory.
769 The set of all parents for all changesets in set, or the working directory.
758 """
770 """
759 if x is None:
771 if x is None:
760 ps = tuple(p.rev() for p in repo[x].parents())
772 ps = tuple(p.rev() for p in repo[x].parents())
761 return [r for r in subset if r in ps]
773 return [r for r in subset if r in ps]
762
774
763 ps = set()
775 ps = set()
764 cl = repo.changelog
776 cl = repo.changelog
765 for r in getset(repo, range(len(repo)), x):
777 for r in getset(repo, range(len(repo)), x):
766 ps.update(cl.parentrevs(r))
778 ps.update(cl.parentrevs(r))
767 return [r for r in subset if r in ps]
779 return [r for r in subset if r in ps]
768
780
769 def parentspec(repo, subset, x, n):
781 def parentspec(repo, subset, x, n):
770 """``set^0``
782 """``set^0``
771 The set.
783 The set.
772 ``set^1`` (or ``set^``), ``set^2``
784 ``set^1`` (or ``set^``), ``set^2``
773 First or second parent, respectively, of all changesets in set.
785 First or second parent, respectively, of all changesets in set.
774 """
786 """
775 try:
787 try:
776 n = int(n[1])
788 n = int(n[1])
777 if n not in (0, 1, 2):
789 if n not in (0, 1, 2):
778 raise ValueError
790 raise ValueError
779 except (TypeError, ValueError):
791 except (TypeError, ValueError):
780 raise error.ParseError(_("^ expects a number 0, 1, or 2"))
792 raise error.ParseError(_("^ expects a number 0, 1, or 2"))
781 ps = set()
793 ps = set()
782 cl = repo.changelog
794 cl = repo.changelog
783 for r in getset(repo, subset, x):
795 for r in getset(repo, subset, x):
784 if n == 0:
796 if n == 0:
785 ps.add(r)
797 ps.add(r)
786 elif n == 1:
798 elif n == 1:
787 ps.add(cl.parentrevs(r)[0])
799 ps.add(cl.parentrevs(r)[0])
788 elif n == 2:
800 elif n == 2:
789 parents = cl.parentrevs(r)
801 parents = cl.parentrevs(r)
790 if len(parents) > 1:
802 if len(parents) > 1:
791 ps.add(parents[1])
803 ps.add(parents[1])
792 return [r for r in subset if r in ps]
804 return [r for r in subset if r in ps]
793
805
794 def present(repo, subset, x):
806 def present(repo, subset, x):
795 """``present(set)``
807 """``present(set)``
796 An empty set, if any revision in set isn't found; otherwise,
808 An empty set, if any revision in set isn't found; otherwise,
797 all revisions in set.
809 all revisions in set.
798 """
810 """
799 try:
811 try:
800 return getset(repo, subset, x)
812 return getset(repo, subset, x)
801 except error.RepoLookupError:
813 except error.RepoLookupError:
802 return []
814 return []
803
815
804 def public(repo, subset, x):
816 def public(repo, subset, x):
805 """``public()``
817 """``public()``
806 Changeset in public phase."""
818 Changeset in public phase."""
807 getargs(x, 0, 0, _("public takes no arguments"))
819 getargs(x, 0, 0, _("public takes no arguments"))
808 return [r for r in subset if repo._phaserev[r] == phases.public]
820 return [r for r in subset if repo._phaserev[r] == phases.public]
809
821
810 def remote(repo, subset, x):
822 def remote(repo, subset, x):
811 """``remote([id [,path]])``
823 """``remote([id [,path]])``
812 Local revision that corresponds to the given identifier in a
824 Local revision that corresponds to the given identifier in a
813 remote repository, if present. Here, the '.' identifier is a
825 remote repository, if present. Here, the '.' identifier is a
814 synonym for the current local branch.
826 synonym for the current local branch.
815 """
827 """
816
828
817 import hg # avoid start-up nasties
829 import hg # avoid start-up nasties
818 # i18n: "remote" is a keyword
830 # i18n: "remote" is a keyword
819 l = getargs(x, 0, 2, _("remote takes one, two or no arguments"))
831 l = getargs(x, 0, 2, _("remote takes one, two or no arguments"))
820
832
821 q = '.'
833 q = '.'
822 if len(l) > 0:
834 if len(l) > 0:
823 # i18n: "remote" is a keyword
835 # i18n: "remote" is a keyword
824 q = getstring(l[0], _("remote requires a string id"))
836 q = getstring(l[0], _("remote requires a string id"))
825 if q == '.':
837 if q == '.':
826 q = repo['.'].branch()
838 q = repo['.'].branch()
827
839
828 dest = ''
840 dest = ''
829 if len(l) > 1:
841 if len(l) > 1:
830 # i18n: "remote" is a keyword
842 # i18n: "remote" is a keyword
831 dest = getstring(l[1], _("remote requires a repository path"))
843 dest = getstring(l[1], _("remote requires a repository path"))
832 dest = repo.ui.expandpath(dest or 'default')
844 dest = repo.ui.expandpath(dest or 'default')
833 dest, branches = hg.parseurl(dest)
845 dest, branches = hg.parseurl(dest)
834 revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
846 revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
835 if revs:
847 if revs:
836 revs = [repo.lookup(rev) for rev in revs]
848 revs = [repo.lookup(rev) for rev in revs]
837 other = hg.peer(repo, {}, dest)
849 other = hg.peer(repo, {}, dest)
838 n = other.lookup(q)
850 n = other.lookup(q)
839 if n in repo:
851 if n in repo:
840 r = repo[n].rev()
852 r = repo[n].rev()
841 if r in subset:
853 if r in subset:
842 return [r]
854 return [r]
843 return []
855 return []
844
856
845 def removes(repo, subset, x):
857 def removes(repo, subset, x):
846 """``removes(pattern)``
858 """``removes(pattern)``
847 Changesets which remove files matching pattern.
859 Changesets which remove files matching pattern.
848 """
860 """
849 # i18n: "removes" is a keyword
861 # i18n: "removes" is a keyword
850 pat = getstring(x, _("removes requires a pattern"))
862 pat = getstring(x, _("removes requires a pattern"))
851 return checkstatus(repo, subset, pat, 2)
863 return checkstatus(repo, subset, pat, 2)
852
864
853 def rev(repo, subset, x):
865 def rev(repo, subset, x):
854 """``rev(number)``
866 """``rev(number)``
855 Revision with the given numeric identifier.
867 Revision with the given numeric identifier.
856 """
868 """
857 # i18n: "rev" is a keyword
869 # i18n: "rev" is a keyword
858 l = getargs(x, 1, 1, _("rev requires one argument"))
870 l = getargs(x, 1, 1, _("rev requires one argument"))
859 try:
871 try:
860 # i18n: "rev" is a keyword
872 # i18n: "rev" is a keyword
861 l = int(getstring(l[0], _("rev requires a number")))
873 l = int(getstring(l[0], _("rev requires a number")))
862 except (TypeError, ValueError):
874 except (TypeError, ValueError):
863 # i18n: "rev" is a keyword
875 # i18n: "rev" is a keyword
864 raise error.ParseError(_("rev expects a number"))
876 raise error.ParseError(_("rev expects a number"))
865 return [r for r in subset if r == l]
877 return [r for r in subset if r == l]
866
878
867 def reverse(repo, subset, x):
879 def reverse(repo, subset, x):
868 """``reverse(set)``
880 """``reverse(set)``
869 Reverse order of set.
881 Reverse order of set.
870 """
882 """
871 l = getset(repo, subset, x)
883 l = getset(repo, subset, x)
872 l.reverse()
884 l.reverse()
873 return l
885 return l
874
886
875 def roots(repo, subset, x):
887 def roots(repo, subset, x):
876 """``roots(set)``
888 """``roots(set)``
877 Changesets with no parent changeset in set.
889 Changesets with no parent changeset in set.
878 """
890 """
879 s = getset(repo, xrange(len(repo)), x)
891 s = getset(repo, xrange(len(repo)), x)
880 cs = _children(repo, s, s)
892 cs = _children(repo, s, s)
881 return [r for r in s if r not in cs]
893 return [r for r in s if r not in cs]
882
894
883 def secret(repo, subset, x):
895 def secret(repo, subset, x):
884 """``secret()``
896 """``secret()``
885 Changeset in secret phase."""
897 Changeset in secret phase."""
886 getargs(x, 0, 0, _("secret takes no arguments"))
898 getargs(x, 0, 0, _("secret takes no arguments"))
887 return [r for r in subset if repo._phaserev[r] == phases.secret]
899 return [r for r in subset if repo._phaserev[r] == phases.secret]
888
900
889 def sort(repo, subset, x):
901 def sort(repo, subset, x):
890 """``sort(set[, [-]key...])``
902 """``sort(set[, [-]key...])``
891 Sort set by keys. The default sort order is ascending, specify a key
903 Sort set by keys. The default sort order is ascending, specify a key
892 as ``-key`` to sort in descending order.
904 as ``-key`` to sort in descending order.
893
905
894 The keys can be:
906 The keys can be:
895
907
896 - ``rev`` for the revision number,
908 - ``rev`` for the revision number,
897 - ``branch`` for the branch name,
909 - ``branch`` for the branch name,
898 - ``desc`` for the commit message (description),
910 - ``desc`` for the commit message (description),
899 - ``user`` for user name (``author`` can be used as an alias),
911 - ``user`` for user name (``author`` can be used as an alias),
900 - ``date`` for the commit date
912 - ``date`` for the commit date
901 """
913 """
902 # i18n: "sort" is a keyword
914 # i18n: "sort" is a keyword
903 l = getargs(x, 1, 2, _("sort requires one or two arguments"))
915 l = getargs(x, 1, 2, _("sort requires one or two arguments"))
904 keys = "rev"
916 keys = "rev"
905 if len(l) == 2:
917 if len(l) == 2:
906 keys = getstring(l[1], _("sort spec must be a string"))
918 keys = getstring(l[1], _("sort spec must be a string"))
907
919
908 s = l[0]
920 s = l[0]
909 keys = keys.split()
921 keys = keys.split()
910 l = []
922 l = []
911 def invert(s):
923 def invert(s):
912 return "".join(chr(255 - ord(c)) for c in s)
924 return "".join(chr(255 - ord(c)) for c in s)
913 for r in getset(repo, subset, s):
925 for r in getset(repo, subset, s):
914 c = repo[r]
926 c = repo[r]
915 e = []
927 e = []
916 for k in keys:
928 for k in keys:
917 if k == 'rev':
929 if k == 'rev':
918 e.append(r)
930 e.append(r)
919 elif k == '-rev':
931 elif k == '-rev':
920 e.append(-r)
932 e.append(-r)
921 elif k == 'branch':
933 elif k == 'branch':
922 e.append(c.branch())
934 e.append(c.branch())
923 elif k == '-branch':
935 elif k == '-branch':
924 e.append(invert(c.branch()))
936 e.append(invert(c.branch()))
925 elif k == 'desc':
937 elif k == 'desc':
926 e.append(c.description())
938 e.append(c.description())
927 elif k == '-desc':
939 elif k == '-desc':
928 e.append(invert(c.description()))
940 e.append(invert(c.description()))
929 elif k in 'user author':
941 elif k in 'user author':
930 e.append(c.user())
942 e.append(c.user())
931 elif k in '-user -author':
943 elif k in '-user -author':
932 e.append(invert(c.user()))
944 e.append(invert(c.user()))
933 elif k == 'date':
945 elif k == 'date':
934 e.append(c.date()[0])
946 e.append(c.date()[0])
935 elif k == '-date':
947 elif k == '-date':
936 e.append(-c.date()[0])
948 e.append(-c.date()[0])
937 else:
949 else:
938 raise error.ParseError(_("unknown sort key %r") % k)
950 raise error.ParseError(_("unknown sort key %r") % k)
939 e.append(r)
951 e.append(r)
940 l.append(e)
952 l.append(e)
941 l.sort()
953 l.sort()
942 return [e[-1] for e in l]
954 return [e[-1] for e in l]
943
955
944 def tag(repo, subset, x):
956 def tag(repo, subset, x):
945 """``tag([name])``
957 """``tag([name])``
946 The specified tag by name, or all tagged revisions if no name is given.
958 The specified tag by name, or all tagged revisions if no name is given.
947 """
959 """
948 # i18n: "tag" is a keyword
960 # i18n: "tag" is a keyword
949 args = getargs(x, 0, 1, _("tag takes one or no arguments"))
961 args = getargs(x, 0, 1, _("tag takes one or no arguments"))
950 cl = repo.changelog
962 cl = repo.changelog
951 if args:
963 if args:
952 tn = getstring(args[0],
964 tn = getstring(args[0],
953 # i18n: "tag" is a keyword
965 # i18n: "tag" is a keyword
954 _('the argument to tag must be a string'))
966 _('the argument to tag must be a string'))
955 if not repo.tags().get(tn, None):
967 if not repo.tags().get(tn, None):
956 raise util.Abort(_("tag '%s' does not exist") % tn)
968 raise util.Abort(_("tag '%s' does not exist") % tn)
957 s = set([cl.rev(n) for t, n in repo.tagslist() if t == tn])
969 s = set([cl.rev(n) for t, n in repo.tagslist() if t == tn])
958 else:
970 else:
959 s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
971 s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
960 return [r for r in subset if r in s]
972 return [r for r in subset if r in s]
961
973
962 def tagged(repo, subset, x):
974 def tagged(repo, subset, x):
963 return tag(repo, subset, x)
975 return tag(repo, subset, x)
964
976
965 def user(repo, subset, x):
977 def user(repo, subset, x):
966 """``user(string)``
978 """``user(string)``
967 User name contains string. The match is case-insensitive.
979 User name contains string. The match is case-insensitive.
968 """
980 """
969 return author(repo, subset, x)
981 return author(repo, subset, x)
970
982
971 # for internal use
983 # for internal use
972 def _list(repo, subset, x):
984 def _list(repo, subset, x):
973 s = getstring(x, "internal error")
985 s = getstring(x, "internal error")
974 if not s:
986 if not s:
975 return []
987 return []
976 if not isinstance(subset, set):
988 if not isinstance(subset, set):
977 subset = set(subset)
989 subset = set(subset)
978 ls = [repo[r].rev() for r in s.split('\0')]
990 ls = [repo[r].rev() for r in s.split('\0')]
979 return [r for r in ls if r in subset]
991 return [r for r in ls if r in subset]
980
992
981 symbols = {
993 symbols = {
982 "adds": adds,
994 "adds": adds,
983 "all": getall,
995 "all": getall,
984 "ancestor": ancestor,
996 "ancestor": ancestor,
985 "ancestors": ancestors,
997 "ancestors": ancestors,
986 "author": author,
998 "author": author,
987 "bisect": bisect,
999 "bisect": bisect,
988 "bisected": bisected,
1000 "bisected": bisected,
989 "bookmark": bookmark,
1001 "bookmark": bookmark,
990 "branch": branch,
1002 "branch": branch,
991 "children": children,
1003 "children": children,
992 "closed": closed,
1004 "closed": closed,
993 "contains": contains,
1005 "contains": contains,
994 "date": date,
1006 "date": date,
995 "desc": desc,
1007 "desc": desc,
996 "descendants": descendants,
1008 "descendants": descendants,
997 "draft": draft,
1009 "draft": draft,
998 "file": hasfile,
1010 "file": hasfile,
999 "filelog": filelog,
1011 "filelog": filelog,
1000 "first": first,
1012 "first": first,
1001 "follow": follow,
1013 "follow": follow,
1002 "_followfirst": _followfirst,
1014 "_followfirst": _followfirst,
1003 "grep": grep,
1015 "grep": grep,
1004 "head": head,
1016 "head": head,
1005 "heads": heads,
1017 "heads": heads,
1006 "id": node,
1018 "id": node,
1007 "keyword": keyword,
1019 "keyword": keyword,
1008 "last": last,
1020 "last": last,
1009 "limit": limit,
1021 "limit": limit,
1010 "_matchfiles": _matchfiles,
1022 "_matchfiles": _matchfiles,
1011 "max": maxrev,
1023 "max": maxrev,
1012 "merge": merge,
1024 "merge": merge,
1013 "min": minrev,
1025 "min": minrev,
1014 "modifies": modifies,
1026 "modifies": modifies,
1015 "outgoing": outgoing,
1027 "outgoing": outgoing,
1016 "p1": p1,
1028 "p1": p1,
1017 "p2": p2,
1029 "p2": p2,
1018 "parents": parents,
1030 "parents": parents,
1019 "present": present,
1031 "present": present,
1020 "public": public,
1032 "public": public,
1021 "remote": remote,
1033 "remote": remote,
1022 "removes": removes,
1034 "removes": removes,
1023 "rev": rev,
1035 "rev": rev,
1024 "reverse": reverse,
1036 "reverse": reverse,
1025 "roots": roots,
1037 "roots": roots,
1026 "sort": sort,
1038 "sort": sort,
1027 "secret": secret,
1039 "secret": secret,
1028 "tag": tag,
1040 "tag": tag,
1029 "tagged": tagged,
1041 "tagged": tagged,
1030 "user": user,
1042 "user": user,
1031 "_list": _list,
1043 "_list": _list,
1032 }
1044 }
1033
1045
1034 methods = {
1046 methods = {
1035 "range": rangeset,
1047 "range": rangeset,
1036 "string": stringset,
1048 "string": stringset,
1037 "symbol": symbolset,
1049 "symbol": symbolset,
1038 "and": andset,
1050 "and": andset,
1039 "or": orset,
1051 "or": orset,
1040 "not": notset,
1052 "not": notset,
1041 "list": listset,
1053 "list": listset,
1042 "func": func,
1054 "func": func,
1043 "ancestor": ancestorspec,
1055 "ancestor": ancestorspec,
1044 "parent": parentspec,
1056 "parent": parentspec,
1045 "parentpost": p1,
1057 "parentpost": p1,
1046 }
1058 }
1047
1059
1048 def optimize(x, small):
1060 def optimize(x, small):
1049 if x is None:
1061 if x is None:
1050 return 0, x
1062 return 0, x
1051
1063
1052 smallbonus = 1
1064 smallbonus = 1
1053 if small:
1065 if small:
1054 smallbonus = .5
1066 smallbonus = .5
1055
1067
1056 op = x[0]
1068 op = x[0]
1057 if op == 'minus':
1069 if op == 'minus':
1058 return optimize(('and', x[1], ('not', x[2])), small)
1070 return optimize(('and', x[1], ('not', x[2])), small)
1059 elif op == 'dagrange':
1071 elif op == 'dagrange':
1060 return optimize(('and', ('func', ('symbol', 'descendants'), x[1]),
1072 return optimize(('and', ('func', ('symbol', 'descendants'), x[1]),
1061 ('func', ('symbol', 'ancestors'), x[2])), small)
1073 ('func', ('symbol', 'ancestors'), x[2])), small)
1062 elif op == 'dagrangepre':
1074 elif op == 'dagrangepre':
1063 return optimize(('func', ('symbol', 'ancestors'), x[1]), small)
1075 return optimize(('func', ('symbol', 'ancestors'), x[1]), small)
1064 elif op == 'dagrangepost':
1076 elif op == 'dagrangepost':
1065 return optimize(('func', ('symbol', 'descendants'), x[1]), small)
1077 return optimize(('func', ('symbol', 'descendants'), x[1]), small)
1066 elif op == 'rangepre':
1078 elif op == 'rangepre':
1067 return optimize(('range', ('string', '0'), x[1]), small)
1079 return optimize(('range', ('string', '0'), x[1]), small)
1068 elif op == 'rangepost':
1080 elif op == 'rangepost':
1069 return optimize(('range', x[1], ('string', 'tip')), small)
1081 return optimize(('range', x[1], ('string', 'tip')), small)
1070 elif op == 'negate':
1082 elif op == 'negate':
1071 return optimize(('string',
1083 return optimize(('string',
1072 '-' + getstring(x[1], _("can't negate that"))), small)
1084 '-' + getstring(x[1], _("can't negate that"))), small)
1073 elif op in 'string symbol negate':
1085 elif op in 'string symbol negate':
1074 return smallbonus, x # single revisions are small
1086 return smallbonus, x # single revisions are small
1075 elif op == 'and' or op == 'dagrange':
1087 elif op == 'and' or op == 'dagrange':
1076 wa, ta = optimize(x[1], True)
1088 wa, ta = optimize(x[1], True)
1077 wb, tb = optimize(x[2], True)
1089 wb, tb = optimize(x[2], True)
1078 w = min(wa, wb)
1090 w = min(wa, wb)
1079 if wa > wb:
1091 if wa > wb:
1080 return w, (op, tb, ta)
1092 return w, (op, tb, ta)
1081 return w, (op, ta, tb)
1093 return w, (op, ta, tb)
1082 elif op == 'or':
1094 elif op == 'or':
1083 wa, ta = optimize(x[1], False)
1095 wa, ta = optimize(x[1], False)
1084 wb, tb = optimize(x[2], False)
1096 wb, tb = optimize(x[2], False)
1085 if wb < wa:
1097 if wb < wa:
1086 wb, wa = wa, wb
1098 wb, wa = wa, wb
1087 return max(wa, wb), (op, ta, tb)
1099 return max(wa, wb), (op, ta, tb)
1088 elif op == 'not':
1100 elif op == 'not':
1089 o = optimize(x[1], not small)
1101 o = optimize(x[1], not small)
1090 return o[0], (op, o[1])
1102 return o[0], (op, o[1])
1091 elif op == 'parentpost':
1103 elif op == 'parentpost':
1092 o = optimize(x[1], small)
1104 o = optimize(x[1], small)
1093 return o[0], (op, o[1])
1105 return o[0], (op, o[1])
1094 elif op == 'group':
1106 elif op == 'group':
1095 return optimize(x[1], small)
1107 return optimize(x[1], small)
1096 elif op in 'range list parent ancestorspec':
1108 elif op in 'range list parent ancestorspec':
1097 if op == 'parent':
1109 if op == 'parent':
1098 # x^:y means (x^) : y, not x ^ (:y)
1110 # x^:y means (x^) : y, not x ^ (:y)
1099 post = ('parentpost', x[1])
1111 post = ('parentpost', x[1])
1100 if x[2][0] == 'dagrangepre':
1112 if x[2][0] == 'dagrangepre':
1101 return optimize(('dagrange', post, x[2][1]), small)
1113 return optimize(('dagrange', post, x[2][1]), small)
1102 elif x[2][0] == 'rangepre':
1114 elif x[2][0] == 'rangepre':
1103 return optimize(('range', post, x[2][1]), small)
1115 return optimize(('range', post, x[2][1]), small)
1104
1116
1105 wa, ta = optimize(x[1], small)
1117 wa, ta = optimize(x[1], small)
1106 wb, tb = optimize(x[2], small)
1118 wb, tb = optimize(x[2], small)
1107 return wa + wb, (op, ta, tb)
1119 return wa + wb, (op, ta, tb)
1108 elif op == 'func':
1120 elif op == 'func':
1109 f = getstring(x[1], _("not a symbol"))
1121 f = getstring(x[1], _("not a symbol"))
1110 wa, ta = optimize(x[2], small)
1122 wa, ta = optimize(x[2], small)
1111 if f in ("author branch closed date desc file grep keyword "
1123 if f in ("author branch closed date desc file grep keyword "
1112 "outgoing user"):
1124 "outgoing user"):
1113 w = 10 # slow
1125 w = 10 # slow
1114 elif f in "modifies adds removes":
1126 elif f in "modifies adds removes":
1115 w = 30 # slower
1127 w = 30 # slower
1116 elif f == "contains":
1128 elif f == "contains":
1117 w = 100 # very slow
1129 w = 100 # very slow
1118 elif f == "ancestor":
1130 elif f == "ancestor":
1119 w = 1 * smallbonus
1131 w = 1 * smallbonus
1120 elif f in "reverse limit first":
1132 elif f in "reverse limit first":
1121 w = 0
1133 w = 0
1122 elif f in "sort":
1134 elif f in "sort":
1123 w = 10 # assume most sorts look at changelog
1135 w = 10 # assume most sorts look at changelog
1124 else:
1136 else:
1125 w = 1
1137 w = 1
1126 return w + wa, (op, x[1], ta)
1138 return w + wa, (op, x[1], ta)
1127 return 1, x
1139 return 1, x
1128
1140
1129 class revsetalias(object):
1141 class revsetalias(object):
1130 funcre = re.compile('^([^(]+)\(([^)]+)\)$')
1142 funcre = re.compile('^([^(]+)\(([^)]+)\)$')
1131 args = None
1143 args = None
1132
1144
1133 def __init__(self, name, value):
1145 def __init__(self, name, value):
1134 '''Aliases like:
1146 '''Aliases like:
1135
1147
1136 h = heads(default)
1148 h = heads(default)
1137 b($1) = ancestors($1) - ancestors(default)
1149 b($1) = ancestors($1) - ancestors(default)
1138 '''
1150 '''
1139 m = self.funcre.search(name)
1151 m = self.funcre.search(name)
1140 if m:
1152 if m:
1141 self.name = m.group(1)
1153 self.name = m.group(1)
1142 self.tree = ('func', ('symbol', m.group(1)))
1154 self.tree = ('func', ('symbol', m.group(1)))
1143 self.args = [x.strip() for x in m.group(2).split(',')]
1155 self.args = [x.strip() for x in m.group(2).split(',')]
1144 for arg in self.args:
1156 for arg in self.args:
1145 value = value.replace(arg, repr(arg))
1157 value = value.replace(arg, repr(arg))
1146 else:
1158 else:
1147 self.name = name
1159 self.name = name
1148 self.tree = ('symbol', name)
1160 self.tree = ('symbol', name)
1149
1161
1150 self.replacement, pos = parse(value)
1162 self.replacement, pos = parse(value)
1151 if pos != len(value):
1163 if pos != len(value):
1152 raise error.ParseError(_('invalid token'), pos)
1164 raise error.ParseError(_('invalid token'), pos)
1153
1165
1154 def _getalias(aliases, tree):
1166 def _getalias(aliases, tree):
1155 """If tree looks like an unexpanded alias, return it. Return None
1167 """If tree looks like an unexpanded alias, return it. Return None
1156 otherwise.
1168 otherwise.
1157 """
1169 """
1158 if isinstance(tree, tuple) and tree:
1170 if isinstance(tree, tuple) and tree:
1159 if tree[0] == 'symbol' and len(tree) == 2:
1171 if tree[0] == 'symbol' and len(tree) == 2:
1160 name = tree[1]
1172 name = tree[1]
1161 alias = aliases.get(name)
1173 alias = aliases.get(name)
1162 if alias and alias.args is None and alias.tree == tree:
1174 if alias and alias.args is None and alias.tree == tree:
1163 return alias
1175 return alias
1164 if tree[0] == 'func' and len(tree) > 1:
1176 if tree[0] == 'func' and len(tree) > 1:
1165 if tree[1][0] == 'symbol' and len(tree[1]) == 2:
1177 if tree[1][0] == 'symbol' and len(tree[1]) == 2:
1166 name = tree[1][1]
1178 name = tree[1][1]
1167 alias = aliases.get(name)
1179 alias = aliases.get(name)
1168 if alias and alias.args is not None and alias.tree == tree[:2]:
1180 if alias and alias.args is not None and alias.tree == tree[:2]:
1169 return alias
1181 return alias
1170 return None
1182 return None
1171
1183
1172 def _expandargs(tree, args):
1184 def _expandargs(tree, args):
1173 """Replace all occurences of ('string', name) with the
1185 """Replace all occurences of ('string', name) with the
1174 substitution value of the same name in args, recursively.
1186 substitution value of the same name in args, recursively.
1175 """
1187 """
1176 if not isinstance(tree, tuple):
1188 if not isinstance(tree, tuple):
1177 return tree
1189 return tree
1178 if len(tree) == 2 and tree[0] == 'string':
1190 if len(tree) == 2 and tree[0] == 'string':
1179 return args.get(tree[1], tree)
1191 return args.get(tree[1], tree)
1180 return tuple(_expandargs(t, args) for t in tree)
1192 return tuple(_expandargs(t, args) for t in tree)
1181
1193
1182 def _expandaliases(aliases, tree, expanding):
1194 def _expandaliases(aliases, tree, expanding):
1183 """Expand aliases in tree, recursively.
1195 """Expand aliases in tree, recursively.
1184
1196
1185 'aliases' is a dictionary mapping user defined aliases to
1197 'aliases' is a dictionary mapping user defined aliases to
1186 revsetalias objects.
1198 revsetalias objects.
1187 """
1199 """
1188 if not isinstance(tree, tuple):
1200 if not isinstance(tree, tuple):
1189 # Do not expand raw strings
1201 # Do not expand raw strings
1190 return tree
1202 return tree
1191 alias = _getalias(aliases, tree)
1203 alias = _getalias(aliases, tree)
1192 if alias is not None:
1204 if alias is not None:
1193 if alias in expanding:
1205 if alias in expanding:
1194 raise error.ParseError(_('infinite expansion of revset alias "%s" '
1206 raise error.ParseError(_('infinite expansion of revset alias "%s" '
1195 'detected') % alias.name)
1207 'detected') % alias.name)
1196 expanding.append(alias)
1208 expanding.append(alias)
1197 result = alias.replacement
1209 result = alias.replacement
1198 if alias.args is not None:
1210 if alias.args is not None:
1199 l = getlist(tree[2])
1211 l = getlist(tree[2])
1200 if len(l) != len(alias.args):
1212 if len(l) != len(alias.args):
1201 raise error.ParseError(
1213 raise error.ParseError(
1202 _('invalid number of arguments: %s') % len(l))
1214 _('invalid number of arguments: %s') % len(l))
1203 result = _expandargs(result, dict(zip(alias.args, l)))
1215 result = _expandargs(result, dict(zip(alias.args, l)))
1204 # Recurse in place, the base expression may have been rewritten
1216 # Recurse in place, the base expression may have been rewritten
1205 result = _expandaliases(aliases, result, expanding)
1217 result = _expandaliases(aliases, result, expanding)
1206 expanding.pop()
1218 expanding.pop()
1207 else:
1219 else:
1208 result = tuple(_expandaliases(aliases, t, expanding)
1220 result = tuple(_expandaliases(aliases, t, expanding)
1209 for t in tree)
1221 for t in tree)
1210 return result
1222 return result
1211
1223
1212 def findaliases(ui, tree):
1224 def findaliases(ui, tree):
1213 aliases = {}
1225 aliases = {}
1214 for k, v in ui.configitems('revsetalias'):
1226 for k, v in ui.configitems('revsetalias'):
1215 alias = revsetalias(k, v)
1227 alias = revsetalias(k, v)
1216 aliases[alias.name] = alias
1228 aliases[alias.name] = alias
1217 return _expandaliases(aliases, tree, [])
1229 return _expandaliases(aliases, tree, [])
1218
1230
1219 parse = parser.parser(tokenize, elements).parse
1231 parse = parser.parser(tokenize, elements).parse
1220
1232
1221 def match(ui, spec):
1233 def match(ui, spec):
1222 if not spec:
1234 if not spec:
1223 raise error.ParseError(_("empty query"))
1235 raise error.ParseError(_("empty query"))
1224 tree, pos = parse(spec)
1236 tree, pos = parse(spec)
1225 if (pos != len(spec)):
1237 if (pos != len(spec)):
1226 raise error.ParseError(_("invalid token"), pos)
1238 raise error.ParseError(_("invalid token"), pos)
1227 if ui:
1239 if ui:
1228 tree = findaliases(ui, tree)
1240 tree = findaliases(ui, tree)
1229 weight, tree = optimize(tree, True)
1241 weight, tree = optimize(tree, True)
1230 def mfunc(repo, subset):
1242 def mfunc(repo, subset):
1231 return getset(repo, subset, tree)
1243 return getset(repo, subset, tree)
1232 return mfunc
1244 return mfunc
1233
1245
1234 def formatspec(expr, *args):
1246 def formatspec(expr, *args):
1235 '''
1247 '''
1236 This is a convenience function for using revsets internally, and
1248 This is a convenience function for using revsets internally, and
1237 escapes arguments appropriately. Aliases are intentionally ignored
1249 escapes arguments appropriately. Aliases are intentionally ignored
1238 so that intended expression behavior isn't accidentally subverted.
1250 so that intended expression behavior isn't accidentally subverted.
1239
1251
1240 Supported arguments:
1252 Supported arguments:
1241
1253
1242 %r = revset expression, parenthesized
1254 %r = revset expression, parenthesized
1243 %d = int(arg), no quoting
1255 %d = int(arg), no quoting
1244 %s = string(arg), escaped and single-quoted
1256 %s = string(arg), escaped and single-quoted
1245 %b = arg.branch(), escaped and single-quoted
1257 %b = arg.branch(), escaped and single-quoted
1246 %n = hex(arg), single-quoted
1258 %n = hex(arg), single-quoted
1247 %% = a literal '%'
1259 %% = a literal '%'
1248
1260
1249 Prefixing the type with 'l' specifies a parenthesized list of that type.
1261 Prefixing the type with 'l' specifies a parenthesized list of that type.
1250
1262
1251 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()"))
1263 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()"))
1252 '(10 or 11):: and ((this()) or (that()))'
1264 '(10 or 11):: and ((this()) or (that()))'
1253 >>> formatspec('%d:: and not %d::', 10, 20)
1265 >>> formatspec('%d:: and not %d::', 10, 20)
1254 '10:: and not 20::'
1266 '10:: and not 20::'
1255 >>> formatspec('%ld or %ld', [], [1])
1267 >>> formatspec('%ld or %ld', [], [1])
1256 "_list('') or 1"
1268 "_list('') or 1"
1257 >>> formatspec('keyword(%s)', 'foo\\xe9')
1269 >>> formatspec('keyword(%s)', 'foo\\xe9')
1258 "keyword('foo\\\\xe9')"
1270 "keyword('foo\\\\xe9')"
1259 >>> b = lambda: 'default'
1271 >>> b = lambda: 'default'
1260 >>> b.branch = b
1272 >>> b.branch = b
1261 >>> formatspec('branch(%b)', b)
1273 >>> formatspec('branch(%b)', b)
1262 "branch('default')"
1274 "branch('default')"
1263 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd'])
1275 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd'])
1264 "root(_list('a\\x00b\\x00c\\x00d'))"
1276 "root(_list('a\\x00b\\x00c\\x00d'))"
1265 '''
1277 '''
1266
1278
1267 def quote(s):
1279 def quote(s):
1268 return repr(str(s))
1280 return repr(str(s))
1269
1281
1270 def argtype(c, arg):
1282 def argtype(c, arg):
1271 if c == 'd':
1283 if c == 'd':
1272 return str(int(arg))
1284 return str(int(arg))
1273 elif c == 's':
1285 elif c == 's':
1274 return quote(arg)
1286 return quote(arg)
1275 elif c == 'r':
1287 elif c == 'r':
1276 parse(arg) # make sure syntax errors are confined
1288 parse(arg) # make sure syntax errors are confined
1277 return '(%s)' % arg
1289 return '(%s)' % arg
1278 elif c == 'n':
1290 elif c == 'n':
1279 return quote(nodemod.hex(arg))
1291 return quote(nodemod.hex(arg))
1280 elif c == 'b':
1292 elif c == 'b':
1281 return quote(arg.branch())
1293 return quote(arg.branch())
1282
1294
1283 def listexp(s, t):
1295 def listexp(s, t):
1284 l = len(s)
1296 l = len(s)
1285 if l == 0:
1297 if l == 0:
1286 return "_list('')"
1298 return "_list('')"
1287 elif l == 1:
1299 elif l == 1:
1288 return argtype(t, s[0])
1300 return argtype(t, s[0])
1289 elif t == 'd':
1301 elif t == 'd':
1290 return "_list('%s')" % "\0".join(str(int(a)) for a in s)
1302 return "_list('%s')" % "\0".join(str(int(a)) for a in s)
1291 elif t == 's':
1303 elif t == 's':
1292 return "_list('%s')" % "\0".join(s)
1304 return "_list('%s')" % "\0".join(s)
1293 elif t == 'n':
1305 elif t == 'n':
1294 return "_list('%s')" % "\0".join(nodemod.hex(a) for a in s)
1306 return "_list('%s')" % "\0".join(nodemod.hex(a) for a in s)
1295 elif t == 'b':
1307 elif t == 'b':
1296 return "_list('%s')" % "\0".join(a.branch() for a in s)
1308 return "_list('%s')" % "\0".join(a.branch() for a in s)
1297
1309
1298 m = l // 2
1310 m = l // 2
1299 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t))
1311 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t))
1300
1312
1301 ret = ''
1313 ret = ''
1302 pos = 0
1314 pos = 0
1303 arg = 0
1315 arg = 0
1304 while pos < len(expr):
1316 while pos < len(expr):
1305 c = expr[pos]
1317 c = expr[pos]
1306 if c == '%':
1318 if c == '%':
1307 pos += 1
1319 pos += 1
1308 d = expr[pos]
1320 d = expr[pos]
1309 if d == '%':
1321 if d == '%':
1310 ret += d
1322 ret += d
1311 elif d in 'dsnbr':
1323 elif d in 'dsnbr':
1312 ret += argtype(d, args[arg])
1324 ret += argtype(d, args[arg])
1313 arg += 1
1325 arg += 1
1314 elif d == 'l':
1326 elif d == 'l':
1315 # a list of some type
1327 # a list of some type
1316 pos += 1
1328 pos += 1
1317 d = expr[pos]
1329 d = expr[pos]
1318 ret += listexp(list(args[arg]), d)
1330 ret += listexp(list(args[arg]), d)
1319 arg += 1
1331 arg += 1
1320 else:
1332 else:
1321 raise util.Abort('unexpected revspec format character %s' % d)
1333 raise util.Abort('unexpected revspec format character %s' % d)
1322 else:
1334 else:
1323 ret += c
1335 ret += c
1324 pos += 1
1336 pos += 1
1325
1337
1326 return ret
1338 return ret
1327
1339
1328 # tell hggettext to extract docstrings from these functions:
1340 # tell hggettext to extract docstrings from these functions:
1329 i18nfunctions = symbols.values()
1341 i18nfunctions = symbols.values()
@@ -1,1662 +1,1669 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 $ "$TESTDIR/hghave" no-outer-repo || exit 80
72 $ "$TESTDIR/hghave" no-outer-repo || exit 80
73
73
74 $ commit()
74 $ commit()
75 > {
75 > {
76 > rev=$1
76 > rev=$1
77 > msg=$2
77 > msg=$2
78 > shift 2
78 > shift 2
79 > if [ "$#" -gt 0 ]; then
79 > if [ "$#" -gt 0 ]; then
80 > hg debugsetparents "$@"
80 > hg debugsetparents "$@"
81 > fi
81 > fi
82 > echo $rev > a
82 > echo $rev > a
83 > hg commit -Aqd "$rev 0" -m "($rev) $msg"
83 > hg commit -Aqd "$rev 0" -m "($rev) $msg"
84 > }
84 > }
85
85
86 $ cat > printrevset.py <<EOF
86 $ cat > printrevset.py <<EOF
87 > from mercurial import extensions, revset, commands
87 > from mercurial import extensions, revset, commands
88 > from hgext import graphlog
88 > from hgext import graphlog
89 >
89 >
90 > def uisetup(ui):
90 > def uisetup(ui):
91 > def printrevset(orig, ui, repo, *pats, **opts):
91 > def printrevset(orig, ui, repo, *pats, **opts):
92 > if opts.get('print_revset'):
92 > if opts.get('print_revset'):
93 > expr = graphlog.revset(repo, pats, opts)
93 > expr = graphlog.revset(repo, pats, opts)
94 > tree = revset.parse(expr)[0]
94 > tree = revset.parse(expr)[0]
95 > ui.write(tree, "\n")
95 > ui.write(tree, "\n")
96 > return 0
96 > return 0
97 > return orig(ui, repo, *pats, **opts)
97 > return orig(ui, repo, *pats, **opts)
98 > entry = extensions.wrapcommand(commands.table, 'log', printrevset)
98 > entry = extensions.wrapcommand(commands.table, 'log', printrevset)
99 > entry[1].append(('', 'print-revset', False,
99 > entry[1].append(('', 'print-revset', False,
100 > 'print generated revset and exit (DEPRECATED)'))
100 > 'print generated revset and exit (DEPRECATED)'))
101 > EOF
101 > EOF
102
102
103 $ echo "[extensions]" >> $HGRCPATH
103 $ echo "[extensions]" >> $HGRCPATH
104 $ echo "graphlog=" >> $HGRCPATH
104 $ echo "graphlog=" >> $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 glog
112 $ hg glog
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 glog -q
154 $ hg glog -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 glog
226 $ hg glog
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 glog a
463 $ hg glog 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 glog -r 'file("a")'
701 $ hg glog -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 glog -r 1..0
1133 $ hg glog -r 1..0
1134
1134
1135 From outer space:
1135 From outer space:
1136 $ cd ..
1136 $ cd ..
1137 $ hg glog -l1 repo
1137 $ hg glog -l1 repo
1138 @ changeset: 34:fea3ac5810e0
1138 @ changeset: 34:fea3ac5810e0
1139 | tag: tip
1139 | tag: tip
1140 | parent: 32:d06dffa21a31
1140 | parent: 32:d06dffa21a31
1141 | user: test
1141 | user: test
1142 | date: Thu Jan 01 00:00:34 1970 +0000
1142 | date: Thu Jan 01 00:00:34 1970 +0000
1143 | summary: (34) head
1143 | summary: (34) head
1144 |
1144 |
1145 $ hg glog -l1 repo/a
1145 $ hg glog -l1 repo/a
1146 @ changeset: 34:fea3ac5810e0
1146 @ changeset: 34:fea3ac5810e0
1147 | tag: tip
1147 | tag: tip
1148 | parent: 32:d06dffa21a31
1148 | parent: 32:d06dffa21a31
1149 | user: test
1149 | user: test
1150 | date: Thu Jan 01 00:00:34 1970 +0000
1150 | date: Thu Jan 01 00:00:34 1970 +0000
1151 | summary: (34) head
1151 | summary: (34) head
1152 |
1152 |
1153 $ hg glog -l1 repo/missing
1153 $ hg glog -l1 repo/missing
1154
1154
1155 File log with revs != cset revs:
1155 File log with revs != cset revs:
1156 $ hg init flog
1156 $ hg init flog
1157 $ cd flog
1157 $ cd flog
1158 $ echo one >one
1158 $ echo one >one
1159 $ hg add one
1159 $ hg add one
1160 $ hg commit -mone
1160 $ hg commit -mone
1161 $ echo two >two
1161 $ echo two >two
1162 $ hg add two
1162 $ hg add two
1163 $ hg commit -mtwo
1163 $ hg commit -mtwo
1164 $ echo more >two
1164 $ echo more >two
1165 $ hg commit -mmore
1165 $ hg commit -mmore
1166 $ hg glog two
1166 $ hg glog two
1167 @ changeset: 2:12c28321755b
1167 @ changeset: 2:12c28321755b
1168 | tag: tip
1168 | tag: tip
1169 | user: test
1169 | user: test
1170 | date: Thu Jan 01 00:00:00 1970 +0000
1170 | date: Thu Jan 01 00:00:00 1970 +0000
1171 | summary: more
1171 | summary: more
1172 |
1172 |
1173 o changeset: 1:5ac72c0599bf
1173 o changeset: 1:5ac72c0599bf
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: two
1176 | summary: two
1177 |
1177 |
1178
1178
1179 Issue1896: File log with explicit style
1179 Issue1896: File log with explicit style
1180 $ hg glog --style=default one
1180 $ hg glog --style=default one
1181 o changeset: 0:3d578b4a1f53
1181 o changeset: 0:3d578b4a1f53
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: one
1184 summary: one
1185
1185
1186 Issue2395: glog --style header and footer
1186 Issue2395: glog --style header and footer
1187 $ hg glog --style=xml one
1187 $ hg glog --style=xml one
1188 <?xml version="1.0"?>
1188 <?xml version="1.0"?>
1189 <log>
1189 <log>
1190 o <logentry revision="0" node="3d578b4a1f537d5fcf7301bfa9c0b97adfaa6fb1">
1190 o <logentry revision="0" node="3d578b4a1f537d5fcf7301bfa9c0b97adfaa6fb1">
1191 <author email="test">test</author>
1191 <author email="test">test</author>
1192 <date>1970-01-01T00:00:00+00:00</date>
1192 <date>1970-01-01T00:00:00+00:00</date>
1193 <msg xml:space="preserve">one</msg>
1193 <msg xml:space="preserve">one</msg>
1194 </logentry>
1194 </logentry>
1195 </log>
1195 </log>
1196
1196
1197 $ cd ..
1197 $ cd ..
1198
1198
1199 Incoming and outgoing:
1199 Incoming and outgoing:
1200
1200
1201 $ hg clone -U -r31 repo repo2
1201 $ hg clone -U -r31 repo repo2
1202 adding changesets
1202 adding changesets
1203 adding manifests
1203 adding manifests
1204 adding file changes
1204 adding file changes
1205 added 31 changesets with 31 changes to 1 files
1205 added 31 changesets with 31 changes to 1 files
1206 $ cd repo2
1206 $ cd repo2
1207
1207
1208 $ hg incoming --graph ../repo
1208 $ hg incoming --graph ../repo
1209 comparing with ../repo
1209 comparing with ../repo
1210 searching for changes
1210 searching for changes
1211 o changeset: 34:fea3ac5810e0
1211 o changeset: 34:fea3ac5810e0
1212 | tag: tip
1212 | tag: tip
1213 | parent: 32:d06dffa21a31
1213 | parent: 32:d06dffa21a31
1214 | user: test
1214 | user: test
1215 | date: Thu Jan 01 00:00:34 1970 +0000
1215 | date: Thu Jan 01 00:00:34 1970 +0000
1216 | summary: (34) head
1216 | summary: (34) head
1217 |
1217 |
1218 | o changeset: 33:68608f5145f9
1218 | o changeset: 33:68608f5145f9
1219 | parent: 18:1aa84d96232a
1219 | parent: 18:1aa84d96232a
1220 | user: test
1220 | user: test
1221 | date: Thu Jan 01 00:00:33 1970 +0000
1221 | date: Thu Jan 01 00:00:33 1970 +0000
1222 | summary: (33) head
1222 | summary: (33) head
1223 |
1223 |
1224 o changeset: 32:d06dffa21a31
1224 o changeset: 32:d06dffa21a31
1225 | parent: 27:886ed638191b
1225 | parent: 27:886ed638191b
1226 | parent: 31:621d83e11f67
1226 | parent: 31:621d83e11f67
1227 | user: test
1227 | user: test
1228 | date: Thu Jan 01 00:00:32 1970 +0000
1228 | date: Thu Jan 01 00:00:32 1970 +0000
1229 | summary: (32) expand
1229 | summary: (32) expand
1230 |
1230 |
1231 o changeset: 27:886ed638191b
1231 o changeset: 27:886ed638191b
1232 parent: 21:d42a756af44d
1232 parent: 21:d42a756af44d
1233 user: test
1233 user: test
1234 date: Thu Jan 01 00:00:27 1970 +0000
1234 date: Thu Jan 01 00:00:27 1970 +0000
1235 summary: (27) collapse
1235 summary: (27) collapse
1236
1236
1237 $ cd ..
1237 $ cd ..
1238
1238
1239 $ hg -R repo outgoing --graph repo2
1239 $ hg -R repo outgoing --graph repo2
1240 comparing with repo2
1240 comparing with repo2
1241 searching for changes
1241 searching for changes
1242 @ changeset: 34:fea3ac5810e0
1242 @ changeset: 34:fea3ac5810e0
1243 | tag: tip
1243 | tag: tip
1244 | parent: 32:d06dffa21a31
1244 | parent: 32:d06dffa21a31
1245 | user: test
1245 | user: test
1246 | date: Thu Jan 01 00:00:34 1970 +0000
1246 | date: Thu Jan 01 00:00:34 1970 +0000
1247 | summary: (34) head
1247 | summary: (34) head
1248 |
1248 |
1249 | o changeset: 33:68608f5145f9
1249 | o changeset: 33:68608f5145f9
1250 | parent: 18:1aa84d96232a
1250 | parent: 18:1aa84d96232a
1251 | user: test
1251 | user: test
1252 | date: Thu Jan 01 00:00:33 1970 +0000
1252 | date: Thu Jan 01 00:00:33 1970 +0000
1253 | summary: (33) head
1253 | summary: (33) head
1254 |
1254 |
1255 o changeset: 32:d06dffa21a31
1255 o changeset: 32:d06dffa21a31
1256 | parent: 27:886ed638191b
1256 | parent: 27:886ed638191b
1257 | parent: 31:621d83e11f67
1257 | parent: 31:621d83e11f67
1258 | user: test
1258 | user: test
1259 | date: Thu Jan 01 00:00:32 1970 +0000
1259 | date: Thu Jan 01 00:00:32 1970 +0000
1260 | summary: (32) expand
1260 | summary: (32) expand
1261 |
1261 |
1262 o changeset: 27:886ed638191b
1262 o changeset: 27:886ed638191b
1263 parent: 21:d42a756af44d
1263 parent: 21:d42a756af44d
1264 user: test
1264 user: test
1265 date: Thu Jan 01 00:00:27 1970 +0000
1265 date: Thu Jan 01 00:00:27 1970 +0000
1266 summary: (27) collapse
1266 summary: (27) collapse
1267
1267
1268
1268
1269 File + limit with revs != cset revs:
1269 File + limit with revs != cset revs:
1270 $ cd repo
1270 $ cd repo
1271 $ touch b
1271 $ touch b
1272 $ hg ci -Aqm0
1272 $ hg ci -Aqm0
1273 $ hg glog -l2 a
1273 $ hg glog -l2 a
1274 o changeset: 34:fea3ac5810e0
1274 o changeset: 34:fea3ac5810e0
1275 | parent: 32:d06dffa21a31
1275 | parent: 32:d06dffa21a31
1276 | user: test
1276 | user: test
1277 | date: Thu Jan 01 00:00:34 1970 +0000
1277 | date: Thu Jan 01 00:00:34 1970 +0000
1278 | summary: (34) head
1278 | summary: (34) head
1279 |
1279 |
1280 | o changeset: 33:68608f5145f9
1280 | o changeset: 33:68608f5145f9
1281 | | parent: 18:1aa84d96232a
1281 | | parent: 18:1aa84d96232a
1282 | | user: test
1282 | | user: test
1283 | | date: Thu Jan 01 00:00:33 1970 +0000
1283 | | date: Thu Jan 01 00:00:33 1970 +0000
1284 | | summary: (33) head
1284 | | summary: (33) head
1285 | |
1285 | |
1286
1286
1287 File + limit + -ra:b, (b - a) < limit:
1287 File + limit + -ra:b, (b - a) < limit:
1288 $ hg glog -l3000 -r32:tip a
1288 $ hg glog -l3000 -r32:tip a
1289 o changeset: 34:fea3ac5810e0
1289 o changeset: 34:fea3ac5810e0
1290 | parent: 32:d06dffa21a31
1290 | parent: 32:d06dffa21a31
1291 | user: test
1291 | user: test
1292 | date: Thu Jan 01 00:00:34 1970 +0000
1292 | date: Thu Jan 01 00:00:34 1970 +0000
1293 | summary: (34) head
1293 | summary: (34) head
1294 |
1294 |
1295 | o changeset: 33:68608f5145f9
1295 | o changeset: 33:68608f5145f9
1296 | | parent: 18:1aa84d96232a
1296 | | parent: 18:1aa84d96232a
1297 | | user: test
1297 | | user: test
1298 | | date: Thu Jan 01 00:00:33 1970 +0000
1298 | | date: Thu Jan 01 00:00:33 1970 +0000
1299 | | summary: (33) head
1299 | | summary: (33) head
1300 | |
1300 | |
1301 o | changeset: 32:d06dffa21a31
1301 o | changeset: 32:d06dffa21a31
1302 |\ \ parent: 27:886ed638191b
1302 |\ \ parent: 27:886ed638191b
1303 | | | parent: 31:621d83e11f67
1303 | | | parent: 31:621d83e11f67
1304 | | | user: test
1304 | | | user: test
1305 | | | date: Thu Jan 01 00:00:32 1970 +0000
1305 | | | date: Thu Jan 01 00:00:32 1970 +0000
1306 | | | summary: (32) expand
1306 | | | summary: (32) expand
1307 | | |
1307 | | |
1308
1308
1309 Point out a common and an uncommon unshown parent
1309 Point out a common and an uncommon unshown parent
1310
1310
1311 $ hg glog -r 'rev(8) or rev(9)'
1311 $ hg glog -r 'rev(8) or rev(9)'
1312 o changeset: 9:7010c0af0a35
1312 o changeset: 9:7010c0af0a35
1313 |\ parent: 7:b632bb1b1224
1313 |\ parent: 7:b632bb1b1224
1314 | | parent: 8:7a0b11f71937
1314 | | parent: 8:7a0b11f71937
1315 | | user: test
1315 | | user: test
1316 | | date: Thu Jan 01 00:00:09 1970 +0000
1316 | | date: Thu Jan 01 00:00:09 1970 +0000
1317 | | summary: (9) expand
1317 | | summary: (9) expand
1318 | |
1318 | |
1319 o | changeset: 8:7a0b11f71937
1319 o | changeset: 8:7a0b11f71937
1320 |\| parent: 0:e6eb3150255d
1320 |\| parent: 0:e6eb3150255d
1321 | | parent: 7:b632bb1b1224
1321 | | parent: 7:b632bb1b1224
1322 | | user: test
1322 | | user: test
1323 | | date: Thu Jan 01 00:00:08 1970 +0000
1323 | | date: Thu Jan 01 00:00:08 1970 +0000
1324 | | summary: (8) merge two known; one immediate left, one far right
1324 | | summary: (8) merge two known; one immediate left, one far right
1325 | |
1325 | |
1326
1326
1327 File + limit + -ra:b, b < tip:
1327 File + limit + -ra:b, b < tip:
1328
1328
1329 $ hg glog -l1 -r32:34 a
1329 $ hg glog -l1 -r32:34 a
1330 o changeset: 34:fea3ac5810e0
1330 o changeset: 34:fea3ac5810e0
1331 | parent: 32:d06dffa21a31
1331 | parent: 32:d06dffa21a31
1332 | user: test
1332 | user: test
1333 | date: Thu Jan 01 00:00:34 1970 +0000
1333 | date: Thu Jan 01 00:00:34 1970 +0000
1334 | summary: (34) head
1334 | summary: (34) head
1335 |
1335 |
1336
1336
1337 file(File) + limit + -ra:b, b < tip:
1337 file(File) + limit + -ra:b, b < tip:
1338
1338
1339 $ hg glog -l1 -r32:34 -r 'file("a")'
1339 $ hg glog -l1 -r32:34 -r 'file("a")'
1340 o changeset: 34:fea3ac5810e0
1340 o changeset: 34:fea3ac5810e0
1341 | parent: 32:d06dffa21a31
1341 | parent: 32:d06dffa21a31
1342 | user: test
1342 | user: test
1343 | date: Thu Jan 01 00:00:34 1970 +0000
1343 | date: Thu Jan 01 00:00:34 1970 +0000
1344 | summary: (34) head
1344 | summary: (34) head
1345 |
1345 |
1346
1346
1347 limit(file(File) and a::b), b < tip:
1347 limit(file(File) and a::b), b < tip:
1348
1348
1349 $ hg glog -r 'limit(file("a") and 32::34, 1)'
1349 $ hg glog -r 'limit(file("a") and 32::34, 1)'
1350 o changeset: 32:d06dffa21a31
1350 o changeset: 32:d06dffa21a31
1351 |\ parent: 27:886ed638191b
1351 |\ parent: 27:886ed638191b
1352 | | parent: 31:621d83e11f67
1352 | | parent: 31:621d83e11f67
1353 | | user: test
1353 | | user: test
1354 | | date: Thu Jan 01 00:00:32 1970 +0000
1354 | | date: Thu Jan 01 00:00:32 1970 +0000
1355 | | summary: (32) expand
1355 | | summary: (32) expand
1356 | |
1356 | |
1357
1357
1358 File + limit + -ra:b, b < tip:
1358 File + limit + -ra:b, b < tip:
1359
1359
1360 $ hg glog -r 'limit(file("a") and 34::32, 1)'
1360 $ hg glog -r 'limit(file("a") and 34::32, 1)'
1361
1361
1362 File + limit + -ra:b, b < tip, (b - a) < limit:
1362 File + limit + -ra:b, b < tip, (b - a) < limit:
1363
1363
1364 $ hg glog -l10 -r33:34 a
1364 $ hg glog -l10 -r33:34 a
1365 o changeset: 34:fea3ac5810e0
1365 o changeset: 34:fea3ac5810e0
1366 | parent: 32:d06dffa21a31
1366 | parent: 32:d06dffa21a31
1367 | user: test
1367 | user: test
1368 | date: Thu Jan 01 00:00:34 1970 +0000
1368 | date: Thu Jan 01 00:00:34 1970 +0000
1369 | summary: (34) head
1369 | summary: (34) head
1370 |
1370 |
1371 | o changeset: 33:68608f5145f9
1371 | o changeset: 33:68608f5145f9
1372 | | parent: 18:1aa84d96232a
1372 | | parent: 18:1aa84d96232a
1373 | | user: test
1373 | | user: test
1374 | | date: Thu Jan 01 00:00:33 1970 +0000
1374 | | date: Thu Jan 01 00:00:33 1970 +0000
1375 | | summary: (33) head
1375 | | summary: (33) head
1376 | |
1376 | |
1377
1377
1378 Do not crash or produce strange graphs if history is buggy
1378 Do not crash or produce strange graphs if history is buggy
1379
1379
1380 $ hg branch branch
1380 $ hg branch branch
1381 marked working directory as branch branch
1381 marked working directory as branch branch
1382 (branches are permanent and global, did you want a bookmark?)
1382 (branches are permanent and global, did you want a bookmark?)
1383 $ commit 36 "buggy merge: identical parents" 35 35
1383 $ commit 36 "buggy merge: identical parents" 35 35
1384 $ hg glog -l5
1384 $ hg glog -l5
1385 @ changeset: 36:08a19a744424
1385 @ changeset: 36:08a19a744424
1386 | branch: branch
1386 | branch: branch
1387 | tag: tip
1387 | tag: tip
1388 | parent: 35:9159c3644c5e
1388 | parent: 35:9159c3644c5e
1389 | parent: 35:9159c3644c5e
1389 | parent: 35:9159c3644c5e
1390 | user: test
1390 | user: test
1391 | date: Thu Jan 01 00:00:36 1970 +0000
1391 | date: Thu Jan 01 00:00:36 1970 +0000
1392 | summary: (36) buggy merge: identical parents
1392 | summary: (36) buggy merge: identical parents
1393 |
1393 |
1394 o changeset: 35:9159c3644c5e
1394 o changeset: 35:9159c3644c5e
1395 | user: test
1395 | user: test
1396 | date: Thu Jan 01 00:00:00 1970 +0000
1396 | date: Thu Jan 01 00:00:00 1970 +0000
1397 | summary: 0
1397 | summary: 0
1398 |
1398 |
1399 o changeset: 34:fea3ac5810e0
1399 o changeset: 34:fea3ac5810e0
1400 | parent: 32:d06dffa21a31
1400 | parent: 32:d06dffa21a31
1401 | user: test
1401 | user: test
1402 | date: Thu Jan 01 00:00:34 1970 +0000
1402 | date: Thu Jan 01 00:00:34 1970 +0000
1403 | summary: (34) head
1403 | summary: (34) head
1404 |
1404 |
1405 | o changeset: 33:68608f5145f9
1405 | o changeset: 33:68608f5145f9
1406 | | parent: 18:1aa84d96232a
1406 | | parent: 18:1aa84d96232a
1407 | | user: test
1407 | | user: test
1408 | | date: Thu Jan 01 00:00:33 1970 +0000
1408 | | date: Thu Jan 01 00:00:33 1970 +0000
1409 | | summary: (33) head
1409 | | summary: (33) head
1410 | |
1410 | |
1411 o | changeset: 32:d06dffa21a31
1411 o | changeset: 32:d06dffa21a31
1412 |\ \ parent: 27:886ed638191b
1412 |\ \ parent: 27:886ed638191b
1413 | | | parent: 31:621d83e11f67
1413 | | | parent: 31:621d83e11f67
1414 | | | user: test
1414 | | | user: test
1415 | | | date: Thu Jan 01 00:00:32 1970 +0000
1415 | | | date: Thu Jan 01 00:00:32 1970 +0000
1416 | | | summary: (32) expand
1416 | | | summary: (32) expand
1417 | | |
1417 | | |
1418
1418
1419 Test log -G options
1419 Test log -G options
1420
1420
1421 $ testlog() {
1421 $ testlog() {
1422 > hg log -G --print-revset "$@"
1422 > hg log -G --print-revset "$@"
1423 > hg log --template 'nodetag {rev}\n' "$@" | grep nodetag \
1423 > hg log --template 'nodetag {rev}\n' "$@" | grep nodetag \
1424 > | sed 's/.*nodetag/nodetag/' > log.nodes
1424 > | sed 's/.*nodetag/nodetag/' > log.nodes
1425 > hg log -G --template 'nodetag {rev}\n' "$@" | grep nodetag \
1425 > hg log -G --template 'nodetag {rev}\n' "$@" | grep nodetag \
1426 > | sed 's/.*nodetag/nodetag/' > glog.nodes
1426 > | sed 's/.*nodetag/nodetag/' > glog.nodes
1427 > diff -u log.nodes glog.nodes
1427 > diff -u log.nodes glog.nodes
1428 > }
1428 > }
1429
1429
1430 glog always reorders nodes which explains the difference with log
1430 glog always reorders nodes which explains the difference with log
1431
1431
1432 $ testlog -r 27 -r 25 -r 21 -r 34 -r 32 -r 31
1432 $ testlog -r 27 -r 25 -r 21 -r 34 -r 32 -r 31
1433 ('group', ('group', ('or', ('or', ('or', ('or', ('or', ('symbol', '27'), ('symbol', '25')), ('symbol', '21')), ('symbol', '34')), ('symbol', '32')), ('symbol', '31'))))
1433 ('group', ('group', ('or', ('or', ('or', ('or', ('or', ('symbol', '27'), ('symbol', '25')), ('symbol', '21')), ('symbol', '34')), ('symbol', '32')), ('symbol', '31'))))
1434 --- log.nodes * (glob)
1434 --- log.nodes * (glob)
1435 +++ glog.nodes * (glob)
1435 +++ glog.nodes * (glob)
1436 @@ -1,6 +1,6 @@
1436 @@ -1,6 +1,6 @@
1437 -nodetag 27
1437 -nodetag 27
1438 -nodetag 25
1438 -nodetag 25
1439 -nodetag 21
1439 -nodetag 21
1440 nodetag 34
1440 nodetag 34
1441 nodetag 32
1441 nodetag 32
1442 nodetag 31
1442 nodetag 31
1443 +nodetag 27
1443 +nodetag 27
1444 +nodetag 25
1444 +nodetag 25
1445 +nodetag 21
1445 +nodetag 21
1446 [1]
1446 [1]
1447 $ testlog -u test -u not-a-user
1447 $ testlog -u test -u not-a-user
1448 ('group', ('group', ('or', ('func', ('symbol', 'user'), ('string', 'test')), ('func', ('symbol', 'user'), ('string', 'not-a-user')))))
1448 ('group', ('group', ('or', ('func', ('symbol', 'user'), ('string', 'test')), ('func', ('symbol', 'user'), ('string', 'not-a-user')))))
1449 $ testlog -b not-a-branch
1449 $ testlog -b not-a-branch
1450 ('group', ('group', ('func', ('symbol', 'branch'), ('string', 'not-a-branch'))))
1450 ('group', ('group', ('func', ('symbol', 'branch'), ('string', 'not-a-branch'))))
1451 abort: unknown revision 'not-a-branch'!
1451 abort: unknown revision 'not-a-branch'!
1452 abort: unknown revision 'not-a-branch'!
1452 abort: unknown revision 'not-a-branch'!
1453 $ testlog -b default -b branch --only-branch branch
1453 $ testlog -b default -b branch --only-branch branch
1454 ('group', ('group', ('or', ('or', ('func', ('symbol', 'branch'), ('string', 'default')), ('func', ('symbol', 'branch'), ('string', 'branch'))), ('func', ('symbol', 'branch'), ('string', 'branch')))))
1454 ('group', ('group', ('or', ('or', ('func', ('symbol', 'branch'), ('string', 'default')), ('func', ('symbol', 'branch'), ('string', 'branch'))), ('func', ('symbol', 'branch'), ('string', 'branch')))))
1455 $ testlog -k expand -k merge
1455 $ testlog -k expand -k merge
1456 ('group', ('group', ('or', ('func', ('symbol', 'keyword'), ('string', 'expand')), ('func', ('symbol', 'keyword'), ('string', 'merge')))))
1456 ('group', ('group', ('or', ('func', ('symbol', 'keyword'), ('string', 'expand')), ('func', ('symbol', 'keyword'), ('string', 'merge')))))
1457 $ hg log -G --removed --template 'nodetag {rev}\n' | grep nodetag | wc -l
1457 $ hg log -G --removed --template 'nodetag {rev}\n' | grep nodetag | wc -l
1458 \s*0 (re)
1458 \s*0 (re)
1459 $ hg log -G --only-merges --template 'nodetag {rev}\n' | grep nodetag | wc -l
1459 $ hg log -G --only-merges --template 'nodetag {rev}\n' | grep nodetag | wc -l
1460 \s*28 (re)
1460 \s*28 (re)
1461 $ hg log -G --no-merges --template 'nodetag {rev}\n'
1461 $ hg log -G --no-merges --template 'nodetag {rev}\n'
1462 o nodetag 35
1462 o nodetag 35
1463 |
1463 |
1464 o nodetag 34
1464 o nodetag 34
1465 |\
1465 |\
1466 | \
1466 | \
1467 | |\
1467 | |\
1468 | | \
1468 | | \
1469 | | |\
1469 | | |\
1470 | | | \
1470 | | | \
1471 | | | |\
1471 | | | |\
1472 | | | | \
1472 | | | | \
1473 | | | | |\
1473 | | | | |\
1474 +-+-+-+-----o nodetag 33
1474 +-+-+-+-----o nodetag 33
1475 | | | | | |
1475 | | | | | |
1476 +---------o nodetag 29
1476 +---------o nodetag 29
1477 | | | | |
1477 | | | | |
1478 +-+-+---o nodetag 27
1478 +-+-+---o nodetag 27
1479 | | | |/
1479 | | | |/
1480 | | | o nodetag 3
1480 | | | o nodetag 3
1481 | | |/
1481 | | |/
1482 | | o nodetag 2
1482 | | o nodetag 2
1483 | |/
1483 | |/
1484 | o nodetag 1
1484 | o nodetag 1
1485 |/
1485 |/
1486 o nodetag 0
1486 o nodetag 0
1487
1487
1488 $ hg log -G -d 'brace ) in a date'
1488 $ hg log -G -d 'brace ) in a date'
1489 abort: invalid date: 'brace ) in a date'
1489 abort: invalid date: 'brace ) in a date'
1490 [255]
1490 [255]
1491 $ testlog --prune 31 --prune 32
1491 $ testlog --prune 31 --prune 32
1492 ('group', ('group', ('and', ('not', ('group', ('or', ('string', '31'), ('func', ('symbol', 'ancestors'), ('string', '31'))))), ('not', ('group', ('or', ('string', '32'), ('func', ('symbol', 'ancestors'), ('string', '32'))))))))
1492 ('group', ('group', ('and', ('not', ('group', ('or', ('string', '31'), ('func', ('symbol', 'ancestors'), ('string', '31'))))), ('not', ('group', ('or', ('string', '32'), ('func', ('symbol', 'ancestors'), ('string', '32'))))))))
1493
1493
1494 Dedicated repo for --follow and paths filtering. The g is crafted to
1494 Dedicated repo for --follow and paths filtering. The g is crafted to
1495 have 2 filelog topological heads in a linear changeset graph.
1495 have 2 filelog topological heads in a linear changeset graph.
1496
1496
1497 $ cd ..
1497 $ cd ..
1498 $ hg init follow
1498 $ hg init follow
1499 $ cd follow
1499 $ cd follow
1500 $ echo a > a
1500 $ echo a > a
1501 $ echo aa > aa
1501 $ echo aa > aa
1502 $ echo f > f
1502 $ echo f > f
1503 $ hg ci -Am "add a"
1503 $ hg ci -Am "add a"
1504 adding a
1504 adding a
1505 adding aa
1505 adding aa
1506 adding f
1506 adding f
1507 $ hg cp a b
1507 $ hg cp a b
1508 $ hg cp f g
1508 $ hg cp f g
1509 $ hg ci -m "copy a b"
1509 $ hg ci -m "copy a b"
1510 $ mkdir dir
1510 $ mkdir dir
1511 $ hg mv b dir
1511 $ hg mv b dir
1512 $ echo g >> g
1512 $ echo g >> g
1513 $ echo f >> f
1513 $ echo f >> f
1514 $ hg ci -m "mv b dir/b"
1514 $ hg ci -m "mv b dir/b"
1515 $ hg mv a b
1515 $ hg mv a b
1516 $ hg cp -f f g
1516 $ hg cp -f f g
1517 $ echo a > d
1517 $ echo a > d
1518 $ hg add d
1518 $ hg add d
1519 $ hg ci -m "mv a b; add d"
1519 $ hg ci -m "mv a b; add d"
1520 $ hg mv dir/b e
1520 $ hg mv dir/b e
1521 $ hg ci -m "mv dir/b e"
1521 $ hg ci -m "mv dir/b e"
1522 $ hg glog --template '({rev}) {desc|firstline}\n'
1522 $ hg glog --template '({rev}) {desc|firstline}\n'
1523 @ (4) mv dir/b e
1523 @ (4) mv dir/b e
1524 |
1524 |
1525 o (3) mv a b; add d
1525 o (3) mv a b; add d
1526 |
1526 |
1527 o (2) mv b dir/b
1527 o (2) mv b dir/b
1528 |
1528 |
1529 o (1) copy a b
1529 o (1) copy a b
1530 |
1530 |
1531 o (0) add a
1531 o (0) add a
1532
1532
1533
1533
1534 $ testlog a
1534 $ testlog a
1535 ('group', ('group', ('func', ('symbol', 'filelog'), ('string', 'a'))))
1535 ('group', ('group', ('func', ('symbol', 'filelog'), ('string', 'a'))))
1536 $ testlog a b
1536 $ testlog a b
1537 ('group', ('group', ('or', ('func', ('symbol', 'filelog'), ('string', 'a')), ('func', ('symbol', 'filelog'), ('string', 'b')))))
1537 ('group', ('group', ('or', ('func', ('symbol', 'filelog'), ('string', 'a')), ('func', ('symbol', 'filelog'), ('string', 'b')))))
1538
1538
1539 Test falling back to slow path for non-existing files
1539 Test falling back to slow path for non-existing files
1540
1540
1541 $ testlog a c
1541 $ testlog a c
1542 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('string', 'p:a'), ('string', 'p:c')))))
1542 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('list', ('string', 'r:'), ('string', 'p:a')), ('string', 'p:c')))))
1543
1543
1544 Test multiple --include/--exclude/paths
1544 Test multiple --include/--exclude/paths
1545
1545
1546 $ testlog --include a --include e --exclude b --exclude e a e
1546 $ testlog --include a --include e --exclude b --exclude e a e
1547 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('list', ('list', ('list', ('list', ('string', 'p:a'), ('string', 'p:e')), ('string', 'i:a')), ('string', 'i:e')), ('string', 'x:b')), ('string', 'x:e')))))
1547 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('list', ('list', ('list', ('list', ('list', ('string', 'r:'), ('string', 'p:a')), ('string', 'p:e')), ('string', 'i:a')), ('string', 'i:e')), ('string', 'x:b')), ('string', 'x:e')))))
1548
1548
1549 Test glob expansion of pats
1549 Test glob expansion of pats
1550
1550
1551 $ expandglobs=`python -c "import mercurial.util; \
1551 $ expandglobs=`python -c "import mercurial.util; \
1552 > print mercurial.util.expandglobs and 'true' or 'false'"`
1552 > print mercurial.util.expandglobs and 'true' or 'false'"`
1553 $ if [ $expandglobs = "true" ]; then
1553 $ if [ $expandglobs = "true" ]; then
1554 > testlog 'a*';
1554 > testlog 'a*';
1555 > else
1555 > else
1556 > testlog a*;
1556 > testlog a*;
1557 > fi;
1557 > fi;
1558 ('group', ('group', ('func', ('symbol', 'filelog'), ('string', 'aa'))))
1558 ('group', ('group', ('func', ('symbol', 'filelog'), ('string', 'aa'))))
1559
1559
1560 Test --follow on a directory
1560 Test --follow on a directory
1561
1561
1562 $ testlog -f dir
1562 $ testlog -f dir
1563 abort: cannot follow file not in parent revision: "dir"
1563 abort: cannot follow file not in parent revision: "dir"
1564 abort: cannot follow file not in parent revision: "dir"
1564 abort: cannot follow file not in parent revision: "dir"
1565 abort: cannot follow file not in parent revision: "dir"
1565 abort: cannot follow file not in parent revision: "dir"
1566
1566
1567 Test --follow on file not in parent revision
1567 Test --follow on file not in parent revision
1568
1568
1569 $ testlog -f a
1569 $ testlog -f a
1570 abort: cannot follow file not in parent revision: "a"
1570 abort: cannot follow file not in parent revision: "a"
1571 abort: cannot follow file not in parent revision: "a"
1571 abort: cannot follow file not in parent revision: "a"
1572 abort: cannot follow file not in parent revision: "a"
1572 abort: cannot follow file not in parent revision: "a"
1573
1573
1574 Test --follow and patterns
1574 Test --follow and patterns
1575
1575
1576 $ testlog -f 'glob:*'
1576 $ testlog -f 'glob:*'
1577 abort: can only follow copies/renames for explicit filenames
1577 abort: can only follow copies/renames for explicit filenames
1578 abort: can only follow copies/renames for explicit filenames
1578 abort: can only follow copies/renames for explicit filenames
1579 abort: can only follow copies/renames for explicit filenames
1579 abort: can only follow copies/renames for explicit filenames
1580
1580
1581 Test --follow on a single rename
1581 Test --follow on a single rename
1582
1582
1583 $ hg up -q 2
1583 $ hg up -q 2
1584 $ testlog -f a
1584 $ testlog -f a
1585 ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'a'))))
1585 ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'a'))))
1586
1586
1587 Test --follow and multiple renames
1587 Test --follow and multiple renames
1588
1588
1589 $ hg up -q tip
1589 $ hg up -q tip
1590 $ testlog -f e
1590 $ testlog -f e
1591 ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'e'))))
1591 ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'e'))))
1592
1592
1593 Test --follow and multiple filelog heads
1593 Test --follow and multiple filelog heads
1594
1594
1595 $ hg up -q 2
1595 $ hg up -q 2
1596 $ testlog -f g
1596 $ testlog -f g
1597 ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'g'))))
1597 ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'g'))))
1598 $ cat log.nodes
1598 $ cat log.nodes
1599 nodetag 2
1599 nodetag 2
1600 nodetag 1
1600 nodetag 1
1601 nodetag 0
1601 nodetag 0
1602 $ hg up -q tip
1602 $ hg up -q tip
1603 $ testlog -f g
1603 $ testlog -f g
1604 ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'g'))))
1604 ('group', ('group', ('func', ('symbol', 'follow'), ('string', 'g'))))
1605 $ cat log.nodes
1605 $ cat log.nodes
1606 nodetag 3
1606 nodetag 3
1607 nodetag 2
1607 nodetag 2
1608 nodetag 0
1608 nodetag 0
1609
1609
1610 Test --follow and multiple files
1610 Test --follow and multiple files
1611
1611
1612 $ testlog -f g e
1612 $ testlog -f g e
1613 ('group', ('group', ('or', ('func', ('symbol', 'follow'), ('string', 'g')), ('func', ('symbol', 'follow'), ('string', 'e')))))
1613 ('group', ('group', ('or', ('func', ('symbol', 'follow'), ('string', 'g')), ('func', ('symbol', 'follow'), ('string', 'e')))))
1614 $ cat log.nodes
1614 $ cat log.nodes
1615 nodetag 4
1615 nodetag 4
1616 nodetag 3
1616 nodetag 3
1617 nodetag 2
1617 nodetag 2
1618 nodetag 1
1618 nodetag 1
1619 nodetag 0
1619 nodetag 0
1620
1620
1621 Test --follow-first
1621 Test --follow-first
1622
1622
1623 $ hg up -q 3
1623 $ hg up -q 3
1624 $ echo ee > e
1624 $ echo ee > e
1625 $ hg ci -Am "add another e" e
1625 $ hg ci -Am "add another e" e
1626 created new head
1626 created new head
1627 $ hg merge --tool internal:other 4
1627 $ hg merge --tool internal:other 4
1628 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
1628 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
1629 (branch merge, don't forget to commit)
1629 (branch merge, don't forget to commit)
1630 $ echo merge > e
1630 $ echo merge > e
1631 $ hg ci -m "merge 5 and 4"
1631 $ hg ci -m "merge 5 and 4"
1632 $ testlog --follow-first
1632 $ testlog --follow-first
1633 ('group', ('func', ('symbol', '_followfirst'), None))
1633 ('group', ('func', ('symbol', '_followfirst'), None))
1634
1634
1635 Cannot compare with log --follow-first FILE as it never worked
1635 Cannot compare with log --follow-first FILE as it never worked
1636
1636
1637 $ hg log -G --print-revset --follow-first e
1637 $ hg log -G --print-revset --follow-first e
1638 ('group', ('group', ('func', ('symbol', '_followfirst'), ('string', 'e'))))
1638 ('group', ('group', ('func', ('symbol', '_followfirst'), ('string', 'e'))))
1639 $ hg log -G --follow-first e --template '{rev} {desc|firstline}\n'
1639 $ hg log -G --follow-first e --template '{rev} {desc|firstline}\n'
1640 @ 6 merge 5 and 4
1640 @ 6 merge 5 and 4
1641 |\
1641 |\
1642 o | 5 add another e
1642 o | 5 add another e
1643 | |
1643 | |
1644
1644
1645 Test --copies
1645 Test --copies
1646
1646
1647 $ hg log -G --copies --template "{rev} {desc|firstline} \
1647 $ hg log -G --copies --template "{rev} {desc|firstline} \
1648 > copies: {file_copies_switch}\n"
1648 > copies: {file_copies_switch}\n"
1649 @ 6 merge 5 and 4 copies:
1649 @ 6 merge 5 and 4 copies:
1650 |\
1650 |\
1651 | o 5 add another e copies:
1651 | o 5 add another e copies:
1652 | |
1652 | |
1653 o | 4 mv dir/b e copies: e (dir/b)
1653 o | 4 mv dir/b e copies: e (dir/b)
1654 |/
1654 |/
1655 o 3 mv a b; add d copies: b (a)g (f)
1655 o 3 mv a b; add d copies: b (a)g (f)
1656 |
1656 |
1657 o 2 mv b dir/b copies: dir/b (b)
1657 o 2 mv b dir/b copies: dir/b (b)
1658 |
1658 |
1659 o 1 copy a b copies: b (a)g (f)
1659 o 1 copy a b copies: b (a)g (f)
1660 |
1660 |
1661 o 0 add a copies:
1661 o 0 add a copies:
1662
1662
1663 Test "set:..." and parent revision
1664
1665 $ hg up -q 4
1666 $ testlog --include "set:copied()"
1667 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('string', 'r:'), ('string', 'i:set:copied()')))))
1668 $ testlog -r "sort(file('set:copied()'), -rev)"
1669 ('group', ('group', ('func', ('symbol', 'sort'), ('list', ('func', ('symbol', 'file'), ('string', 'set:copied()')), ('negate', ('symbol', 'rev'))))))
General Comments 0
You need to be logged in to leave comments. Login now