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