##// END OF EJS Templates
graphlog: restore FILE glob expansion on Windows...
Patrick Mezard -
r16171:336e6187 default
parent child Browse files
Show More
@@ -1,422 +1,426 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
20 from mercurial import hg, util, graphmod
21
21
22 cmdtable = {}
22 cmdtable = {}
23 command = cmdutil.command(cmdtable)
23 command = cmdutil.command(cmdtable)
24
24
25 ASCIIDATA = 'ASC'
25 ASCIIDATA = 'ASC'
26
26
27 def asciiedges(type, char, lines, seen, rev, parents):
27 def asciiedges(type, char, lines, seen, rev, parents):
28 """adds edge info to changelog DAG walk suitable for ascii()"""
28 """adds edge info to changelog DAG walk suitable for ascii()"""
29 if rev not in seen:
29 if rev not in seen:
30 seen.append(rev)
30 seen.append(rev)
31 nodeidx = seen.index(rev)
31 nodeidx = seen.index(rev)
32
32
33 knownparents = []
33 knownparents = []
34 newparents = []
34 newparents = []
35 for parent in parents:
35 for parent in parents:
36 if parent in seen:
36 if parent in seen:
37 knownparents.append(parent)
37 knownparents.append(parent)
38 else:
38 else:
39 newparents.append(parent)
39 newparents.append(parent)
40
40
41 ncols = len(seen)
41 ncols = len(seen)
42 nextseen = seen[:]
42 nextseen = seen[:]
43 nextseen[nodeidx:nodeidx + 1] = newparents
43 nextseen[nodeidx:nodeidx + 1] = newparents
44 edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
44 edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
45
45
46 while len(newparents) > 2:
46 while len(newparents) > 2:
47 # ascii() only knows how to add or remove a single column between two
47 # ascii() only knows how to add or remove a single column between two
48 # calls. Nodes with more than two parents break this constraint so we
48 # calls. Nodes with more than two parents break this constraint so we
49 # introduce intermediate expansion lines to grow the active node list
49 # introduce intermediate expansion lines to grow the active node list
50 # slowly.
50 # slowly.
51 edges.append((nodeidx, nodeidx))
51 edges.append((nodeidx, nodeidx))
52 edges.append((nodeidx, nodeidx + 1))
52 edges.append((nodeidx, nodeidx + 1))
53 nmorecols = 1
53 nmorecols = 1
54 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
54 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
55 char = '\\'
55 char = '\\'
56 lines = []
56 lines = []
57 nodeidx += 1
57 nodeidx += 1
58 ncols += 1
58 ncols += 1
59 edges = []
59 edges = []
60 del newparents[0]
60 del newparents[0]
61
61
62 if len(newparents) > 0:
62 if len(newparents) > 0:
63 edges.append((nodeidx, nodeidx))
63 edges.append((nodeidx, nodeidx))
64 if len(newparents) > 1:
64 if len(newparents) > 1:
65 edges.append((nodeidx, nodeidx + 1))
65 edges.append((nodeidx, nodeidx + 1))
66 nmorecols = len(nextseen) - ncols
66 nmorecols = len(nextseen) - ncols
67 seen[:] = nextseen
67 seen[:] = nextseen
68 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
68 yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
69
69
70 def fix_long_right_edges(edges):
70 def fix_long_right_edges(edges):
71 for (i, (start, end)) in enumerate(edges):
71 for (i, (start, end)) in enumerate(edges):
72 if end > start:
72 if end > start:
73 edges[i] = (start, end + 1)
73 edges[i] = (start, end + 1)
74
74
75 def get_nodeline_edges_tail(
75 def get_nodeline_edges_tail(
76 node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
76 node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
77 if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
77 if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
78 # Still going in the same non-vertical direction.
78 # Still going in the same non-vertical direction.
79 if n_columns_diff == -1:
79 if n_columns_diff == -1:
80 start = max(node_index + 1, p_node_index)
80 start = max(node_index + 1, p_node_index)
81 tail = ["|", " "] * (start - node_index - 1)
81 tail = ["|", " "] * (start - node_index - 1)
82 tail.extend(["/", " "] * (n_columns - start))
82 tail.extend(["/", " "] * (n_columns - start))
83 return tail
83 return tail
84 else:
84 else:
85 return ["\\", " "] * (n_columns - node_index - 1)
85 return ["\\", " "] * (n_columns - node_index - 1)
86 else:
86 else:
87 return ["|", " "] * (n_columns - node_index - 1)
87 return ["|", " "] * (n_columns - node_index - 1)
88
88
89 def draw_edges(edges, nodeline, interline):
89 def draw_edges(edges, nodeline, interline):
90 for (start, end) in edges:
90 for (start, end) in edges:
91 if start == end + 1:
91 if start == end + 1:
92 interline[2 * end + 1] = "/"
92 interline[2 * end + 1] = "/"
93 elif start == end - 1:
93 elif start == end - 1:
94 interline[2 * start + 1] = "\\"
94 interline[2 * start + 1] = "\\"
95 elif start == end:
95 elif start == end:
96 interline[2 * start] = "|"
96 interline[2 * start] = "|"
97 else:
97 else:
98 if 2 * end >= len(nodeline):
98 if 2 * end >= len(nodeline):
99 continue
99 continue
100 nodeline[2 * end] = "+"
100 nodeline[2 * end] = "+"
101 if start > end:
101 if start > end:
102 (start, end) = (end, start)
102 (start, end) = (end, start)
103 for i in range(2 * start + 1, 2 * end):
103 for i in range(2 * start + 1, 2 * end):
104 if nodeline[i] != "+":
104 if nodeline[i] != "+":
105 nodeline[i] = "-"
105 nodeline[i] = "-"
106
106
107 def get_padding_line(ni, n_columns, edges):
107 def get_padding_line(ni, n_columns, edges):
108 line = []
108 line = []
109 line.extend(["|", " "] * ni)
109 line.extend(["|", " "] * ni)
110 if (ni, ni - 1) in edges or (ni, ni) in edges:
110 if (ni, ni - 1) in edges or (ni, ni) in edges:
111 # (ni, ni - 1) (ni, ni)
111 # (ni, ni - 1) (ni, ni)
112 # | | | | | | | |
112 # | | | | | | | |
113 # +---o | | o---+
113 # +---o | | o---+
114 # | | c | | c | |
114 # | | c | | c | |
115 # | |/ / | |/ /
115 # | |/ / | |/ /
116 # | | | | | |
116 # | | | | | |
117 c = "|"
117 c = "|"
118 else:
118 else:
119 c = " "
119 c = " "
120 line.extend([c, " "])
120 line.extend([c, " "])
121 line.extend(["|", " "] * (n_columns - ni - 1))
121 line.extend(["|", " "] * (n_columns - ni - 1))
122 return line
122 return line
123
123
124 def asciistate():
124 def asciistate():
125 """returns the initial value for the "state" argument to ascii()"""
125 """returns the initial value for the "state" argument to ascii()"""
126 return [0, 0]
126 return [0, 0]
127
127
128 def ascii(ui, state, type, char, text, coldata):
128 def ascii(ui, state, type, char, text, coldata):
129 """prints an ASCII graph of the DAG
129 """prints an ASCII graph of the DAG
130
130
131 takes the following arguments (one call per node in the graph):
131 takes the following arguments (one call per node in the graph):
132
132
133 - ui to write to
133 - ui to write to
134 - Somewhere to keep the needed state in (init to asciistate())
134 - Somewhere to keep the needed state in (init to asciistate())
135 - Column of the current node in the set of ongoing edges.
135 - Column of the current node in the set of ongoing edges.
136 - Type indicator of node data == ASCIIDATA.
136 - Type indicator of node data == ASCIIDATA.
137 - Payload: (char, lines):
137 - Payload: (char, lines):
138 - Character to use as node's symbol.
138 - Character to use as node's symbol.
139 - List of lines to display as the node's text.
139 - List of lines to display as the node's text.
140 - Edges; a list of (col, next_col) indicating the edges between
140 - Edges; a list of (col, next_col) indicating the edges between
141 the current node and its parents.
141 the current node and its parents.
142 - Number of columns (ongoing edges) in the current revision.
142 - Number of columns (ongoing edges) in the current revision.
143 - The difference between the number of columns (ongoing edges)
143 - The difference between the number of columns (ongoing edges)
144 in the next revision and the number of columns (ongoing edges)
144 in the next revision and the number of columns (ongoing edges)
145 in the current revision. That is: -1 means one column removed;
145 in the current revision. That is: -1 means one column removed;
146 0 means no columns added or removed; 1 means one column added.
146 0 means no columns added or removed; 1 means one column added.
147 """
147 """
148
148
149 idx, edges, ncols, coldiff = coldata
149 idx, edges, ncols, coldiff = coldata
150 assert -2 < coldiff < 2
150 assert -2 < coldiff < 2
151 if coldiff == -1:
151 if coldiff == -1:
152 # Transform
152 # Transform
153 #
153 #
154 # | | | | | |
154 # | | | | | |
155 # o | | into o---+
155 # o | | into o---+
156 # |X / |/ /
156 # |X / |/ /
157 # | | | |
157 # | | | |
158 fix_long_right_edges(edges)
158 fix_long_right_edges(edges)
159
159
160 # add_padding_line says whether to rewrite
160 # add_padding_line says whether to rewrite
161 #
161 #
162 # | | | | | | | |
162 # | | | | | | | |
163 # | o---+ into | o---+
163 # | o---+ into | o---+
164 # | / / | | | # <--- padding line
164 # | / / | | | # <--- padding line
165 # o | | | / /
165 # o | | | / /
166 # o | |
166 # o | |
167 add_padding_line = (len(text) > 2 and coldiff == -1 and
167 add_padding_line = (len(text) > 2 and coldiff == -1 and
168 [x for (x, y) in edges if x + 1 < y])
168 [x for (x, y) in edges if x + 1 < y])
169
169
170 # fix_nodeline_tail says whether to rewrite
170 # fix_nodeline_tail says whether to rewrite
171 #
171 #
172 # | | o | | | | o | |
172 # | | o | | | | o | |
173 # | | |/ / | | |/ /
173 # | | |/ / | | |/ /
174 # | o | | into | o / / # <--- fixed nodeline tail
174 # | o | | into | o / / # <--- fixed nodeline tail
175 # | |/ / | |/ /
175 # | |/ / | |/ /
176 # o | | o | |
176 # o | | o | |
177 fix_nodeline_tail = len(text) <= 2 and not add_padding_line
177 fix_nodeline_tail = len(text) <= 2 and not add_padding_line
178
178
179 # nodeline is the line containing the node character (typically o)
179 # nodeline is the line containing the node character (typically o)
180 nodeline = ["|", " "] * idx
180 nodeline = ["|", " "] * idx
181 nodeline.extend([char, " "])
181 nodeline.extend([char, " "])
182
182
183 nodeline.extend(
183 nodeline.extend(
184 get_nodeline_edges_tail(idx, state[1], ncols, coldiff,
184 get_nodeline_edges_tail(idx, state[1], ncols, coldiff,
185 state[0], fix_nodeline_tail))
185 state[0], fix_nodeline_tail))
186
186
187 # shift_interline is the line containing the non-vertical
187 # shift_interline is the line containing the non-vertical
188 # edges between this entry and the next
188 # edges between this entry and the next
189 shift_interline = ["|", " "] * idx
189 shift_interline = ["|", " "] * idx
190 if coldiff == -1:
190 if coldiff == -1:
191 n_spaces = 1
191 n_spaces = 1
192 edge_ch = "/"
192 edge_ch = "/"
193 elif coldiff == 0:
193 elif coldiff == 0:
194 n_spaces = 2
194 n_spaces = 2
195 edge_ch = "|"
195 edge_ch = "|"
196 else:
196 else:
197 n_spaces = 3
197 n_spaces = 3
198 edge_ch = "\\"
198 edge_ch = "\\"
199 shift_interline.extend(n_spaces * [" "])
199 shift_interline.extend(n_spaces * [" "])
200 shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
200 shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
201
201
202 # draw edges from the current node to its parents
202 # draw edges from the current node to its parents
203 draw_edges(edges, nodeline, shift_interline)
203 draw_edges(edges, nodeline, shift_interline)
204
204
205 # lines is the list of all graph lines to print
205 # lines is the list of all graph lines to print
206 lines = [nodeline]
206 lines = [nodeline]
207 if add_padding_line:
207 if add_padding_line:
208 lines.append(get_padding_line(idx, ncols, edges))
208 lines.append(get_padding_line(idx, ncols, edges))
209 lines.append(shift_interline)
209 lines.append(shift_interline)
210
210
211 # make sure that there are as many graph lines as there are
211 # make sure that there are as many graph lines as there are
212 # log strings
212 # log strings
213 while len(text) < len(lines):
213 while len(text) < len(lines):
214 text.append("")
214 text.append("")
215 if len(lines) < len(text):
215 if len(lines) < len(text):
216 extra_interline = ["|", " "] * (ncols + coldiff)
216 extra_interline = ["|", " "] * (ncols + coldiff)
217 while len(lines) < len(text):
217 while len(lines) < len(text):
218 lines.append(extra_interline)
218 lines.append(extra_interline)
219
219
220 # print lines
220 # print lines
221 indentation_level = max(ncols, ncols + coldiff)
221 indentation_level = max(ncols, ncols + coldiff)
222 for (line, logstr) in zip(lines, text):
222 for (line, logstr) in zip(lines, text):
223 ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
223 ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
224 ui.write(ln.rstrip() + '\n')
224 ui.write(ln.rstrip() + '\n')
225
225
226 # ... and start over
226 # ... and start over
227 state[0] = coldiff
227 state[0] = coldiff
228 state[1] = idx
228 state[1] = idx
229
229
230 def get_revs(repo, rev_opt):
230 def get_revs(repo, rev_opt):
231 if rev_opt:
231 if rev_opt:
232 revs = scmutil.revrange(repo, rev_opt)
232 revs = scmutil.revrange(repo, rev_opt)
233 if len(revs) == 0:
233 if len(revs) == 0:
234 return (nullrev, nullrev)
234 return (nullrev, nullrev)
235 return (max(revs), min(revs))
235 return (max(revs), min(revs))
236 else:
236 else:
237 return (len(repo) - 1, 0)
237 return (len(repo) - 1, 0)
238
238
239 def check_unsupported_flags(pats, opts):
239 def check_unsupported_flags(pats, opts):
240 for op in ["follow_first", "copies", "newest_first"]:
240 for op in ["follow_first", "copies", "newest_first"]:
241 if op in opts and opts[op]:
241 if op in opts and opts[op]:
242 raise util.Abort(_("-G/--graph option is incompatible with --%s")
242 raise util.Abort(_("-G/--graph option is incompatible with --%s")
243 % op.replace("_", "-"))
243 % op.replace("_", "-"))
244 if pats and opts.get('follow'):
244 if pats and opts.get('follow'):
245 raise util.Abort(_("-G/--graph option is incompatible with --follow "
245 raise util.Abort(_("-G/--graph option is incompatible with --follow "
246 "with file argument"))
246 "with file argument"))
247
247
248 def revset(repo, pats, opts):
248 def revset(repo, pats, opts):
249 """Return revset str built of revisions, log options and file patterns.
249 """Return revset str built of revisions, log options and file patterns.
250 """
250 """
251 opt2revset = {
251 opt2revset = {
252 'follow': ('follow()', None),
252 'follow': ('follow()', None),
253 'no_merges': ('not merge()', None),
253 'no_merges': ('not merge()', None),
254 'only_merges': ('merge()', None),
254 'only_merges': ('merge()', None),
255 'removed': ('removes("*")', None),
255 'removed': ('removes("*")', None),
256 'date': ('date(%(val)r)', None),
256 'date': ('date(%(val)r)', None),
257 'branch': ('branch(%(val)r)', ' or '),
257 'branch': ('branch(%(val)r)', ' or '),
258 '_patslog': ('filelog(%(val)r)', ' or '),
258 '_patslog': ('filelog(%(val)r)', ' or '),
259 'keyword': ('keyword(%(val)r)', ' or '),
259 'keyword': ('keyword(%(val)r)', ' or '),
260 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
260 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
261 'user': ('user(%(val)r)', ' or '),
261 'user': ('user(%(val)r)', ' or '),
262 'rev': ('%(val)s', ' or '),
262 'rev': ('%(val)s', ' or '),
263 }
263 }
264
264
265 opts = dict(opts)
265 opts = dict(opts)
266 # branch and only_branch are really aliases and must be handled at
266 # branch and only_branch are really aliases and must be handled at
267 # the same time
267 # the same time
268 if 'branch' in opts and 'only_branch' in opts:
268 if 'branch' in opts and 'only_branch' in opts:
269 opts['branch'] = opts['branch'] + opts.pop('only_branch')
269 opts['branch'] = opts['branch'] + opts.pop('only_branch')
270
270
271 match = scmutil.match(repo[None], pats, opts)
271 # pats/include/exclude are passed to match.match() directly in
272 # _matchfile() revset but walkchangerevs() builds its matcher with
273 # scmutil.match(). The difference is input pats are globbed on
274 # platforms without shell expansion (windows).
275 match, pats = scmutil.matchandpats(repo[None], pats, opts)
272 slowpath = match.anypats() or (match.files() and opts.get('removed'))
276 slowpath = match.anypats() or (match.files() and opts.get('removed'))
273 if not slowpath:
277 if not slowpath:
274 for f in match.files():
278 for f in match.files():
275 filelog = repo.file(f)
279 filelog = repo.file(f)
276 if not len(filelog):
280 if not len(filelog):
277 # A zero count may be a directory or deleted file, so
281 # A zero count may be a directory or deleted file, so
278 # try to find matching entries on the slow path.
282 # try to find matching entries on the slow path.
279 slowpath = True
283 slowpath = True
280 if slowpath:
284 if slowpath:
281 # See cmdutil.walkchangerevs() slow path.
285 # See cmdutil.walkchangerevs() slow path.
282 #
286 #
283 # pats/include/exclude cannot be represented as separate
287 # pats/include/exclude cannot be represented as separate
284 # revset expressions as their filtering logic applies at file
288 # revset expressions as their filtering logic applies at file
285 # level. For instance "-I a -X a" matches a revision touching
289 # level. For instance "-I a -X a" matches a revision touching
286 # "a" and "b" while "file(a) and not file(b)" does not.
290 # "a" and "b" while "file(a) and not file(b)" does not.
287 matchargs = []
291 matchargs = []
288 for p in pats:
292 for p in pats:
289 matchargs.append('p:' + p)
293 matchargs.append('p:' + p)
290 for p in opts.get('include', []):
294 for p in opts.get('include', []):
291 matchargs.append('i:' + p)
295 matchargs.append('i:' + p)
292 for p in opts.get('exclude', []):
296 for p in opts.get('exclude', []):
293 matchargs.append('x:' + p)
297 matchargs.append('x:' + p)
294 matchargs = ','.join(('%r' % p) for p in matchargs)
298 matchargs = ','.join(('%r' % p) for p in matchargs)
295 opts['rev'] = opts.get('rev', []) + ['_matchfiles(%s)' % matchargs]
299 opts['rev'] = opts.get('rev', []) + ['_matchfiles(%s)' % matchargs]
296 else:
300 else:
297 opts['_patslog'] = list(pats)
301 opts['_patslog'] = list(pats)
298
302
299 revset = []
303 revset = []
300 for op, val in opts.iteritems():
304 for op, val in opts.iteritems():
301 if not val:
305 if not val:
302 continue
306 continue
303 if op not in opt2revset:
307 if op not in opt2revset:
304 continue
308 continue
305 revop, andor = opt2revset[op]
309 revop, andor = opt2revset[op]
306 if '%(val)' not in revop:
310 if '%(val)' not in revop:
307 revset.append(revop)
311 revset.append(revop)
308 else:
312 else:
309 if not isinstance(val, list):
313 if not isinstance(val, list):
310 expr = revop % {'val': val}
314 expr = revop % {'val': val}
311 else:
315 else:
312 expr = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
316 expr = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
313 revset.append(expr)
317 revset.append(expr)
314
318
315 if revset:
319 if revset:
316 revset = '(' + ' and '.join(revset) + ')'
320 revset = '(' + ' and '.join(revset) + ')'
317 else:
321 else:
318 revset = 'all()'
322 revset = 'all()'
319 return revset
323 return revset
320
324
321 def generate(ui, dag, displayer, showparents, edgefn):
325 def generate(ui, dag, displayer, showparents, edgefn):
322 seen, state = [], asciistate()
326 seen, state = [], asciistate()
323 for rev, type, ctx, parents in dag:
327 for rev, type, ctx, parents in dag:
324 char = ctx.node() in showparents and '@' or 'o'
328 char = ctx.node() in showparents and '@' or 'o'
325 displayer.show(ctx)
329 displayer.show(ctx)
326 lines = displayer.hunk.pop(rev).split('\n')[:-1]
330 lines = displayer.hunk.pop(rev).split('\n')[:-1]
327 displayer.flush(rev)
331 displayer.flush(rev)
328 edges = edgefn(type, char, lines, seen, rev, parents)
332 edges = edgefn(type, char, lines, seen, rev, parents)
329 for type, char, lines, coldata in edges:
333 for type, char, lines, coldata in edges:
330 ascii(ui, state, type, char, lines, coldata)
334 ascii(ui, state, type, char, lines, coldata)
331 displayer.close()
335 displayer.close()
332
336
333 @command('glog',
337 @command('glog',
334 [('l', 'limit', '',
338 [('l', 'limit', '',
335 _('limit number of changes displayed'), _('NUM')),
339 _('limit number of changes displayed'), _('NUM')),
336 ('p', 'patch', False, _('show patch')),
340 ('p', 'patch', False, _('show patch')),
337 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
341 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
338 ] + templateopts,
342 ] + templateopts,
339 _('hg glog [OPTION]... [FILE]'))
343 _('hg glog [OPTION]... [FILE]'))
340 def graphlog(ui, repo, *pats, **opts):
344 def graphlog(ui, repo, *pats, **opts):
341 """show revision history alongside an ASCII revision graph
345 """show revision history alongside an ASCII revision graph
342
346
343 Print a revision history alongside a revision graph drawn with
347 Print a revision history alongside a revision graph drawn with
344 ASCII characters.
348 ASCII characters.
345
349
346 Nodes printed as an @ character are parents of the working
350 Nodes printed as an @ character are parents of the working
347 directory.
351 directory.
348 """
352 """
349
353
350 check_unsupported_flags(pats, opts)
354 check_unsupported_flags(pats, opts)
351
355
352 revs = sorted(scmutil.revrange(repo, [revset(repo, pats, opts)]), reverse=1)
356 revs = sorted(scmutil.revrange(repo, [revset(repo, pats, opts)]), reverse=1)
353 limit = cmdutil.loglimit(opts)
357 limit = cmdutil.loglimit(opts)
354 if limit is not None:
358 if limit is not None:
355 revs = revs[:limit]
359 revs = revs[:limit]
356 revdag = graphmod.dagwalker(repo, revs)
360 revdag = graphmod.dagwalker(repo, revs)
357
361
358 displayer = show_changeset(ui, repo, opts, buffered=True)
362 displayer = show_changeset(ui, repo, opts, buffered=True)
359 showparents = [ctx.node() for ctx in repo[None].parents()]
363 showparents = [ctx.node() for ctx in repo[None].parents()]
360 generate(ui, revdag, displayer, showparents, asciiedges)
364 generate(ui, revdag, displayer, showparents, asciiedges)
361
365
362 def graphrevs(repo, nodes, opts):
366 def graphrevs(repo, nodes, opts):
363 limit = cmdutil.loglimit(opts)
367 limit = cmdutil.loglimit(opts)
364 nodes.reverse()
368 nodes.reverse()
365 if limit is not None:
369 if limit is not None:
366 nodes = nodes[:limit]
370 nodes = nodes[:limit]
367 return graphmod.nodes(repo, nodes)
371 return graphmod.nodes(repo, nodes)
368
372
369 def goutgoing(ui, repo, dest=None, **opts):
373 def goutgoing(ui, repo, dest=None, **opts):
370 """show the outgoing changesets alongside an ASCII revision graph
374 """show the outgoing changesets alongside an ASCII revision graph
371
375
372 Print the outgoing changesets alongside a revision graph drawn with
376 Print the outgoing changesets alongside a revision graph drawn with
373 ASCII characters.
377 ASCII characters.
374
378
375 Nodes printed as an @ character are parents of the working
379 Nodes printed as an @ character are parents of the working
376 directory.
380 directory.
377 """
381 """
378
382
379 check_unsupported_flags([], opts)
383 check_unsupported_flags([], opts)
380 o = hg._outgoing(ui, repo, dest, opts)
384 o = hg._outgoing(ui, repo, dest, opts)
381 if o is None:
385 if o is None:
382 return
386 return
383
387
384 revdag = graphrevs(repo, o, opts)
388 revdag = graphrevs(repo, o, opts)
385 displayer = show_changeset(ui, repo, opts, buffered=True)
389 displayer = show_changeset(ui, repo, opts, buffered=True)
386 showparents = [ctx.node() for ctx in repo[None].parents()]
390 showparents = [ctx.node() for ctx in repo[None].parents()]
387 generate(ui, revdag, displayer, showparents, asciiedges)
391 generate(ui, revdag, displayer, showparents, asciiedges)
388
392
389 def gincoming(ui, repo, source="default", **opts):
393 def gincoming(ui, repo, source="default", **opts):
390 """show the incoming changesets alongside an ASCII revision graph
394 """show the incoming changesets alongside an ASCII revision graph
391
395
392 Print the incoming changesets alongside a revision graph drawn with
396 Print the incoming changesets alongside a revision graph drawn with
393 ASCII characters.
397 ASCII characters.
394
398
395 Nodes printed as an @ character are parents of the working
399 Nodes printed as an @ character are parents of the working
396 directory.
400 directory.
397 """
401 """
398 def subreporecurse():
402 def subreporecurse():
399 return 1
403 return 1
400
404
401 check_unsupported_flags([], opts)
405 check_unsupported_flags([], opts)
402 def display(other, chlist, displayer):
406 def display(other, chlist, displayer):
403 revdag = graphrevs(other, chlist, opts)
407 revdag = graphrevs(other, chlist, opts)
404 showparents = [ctx.node() for ctx in repo[None].parents()]
408 showparents = [ctx.node() for ctx in repo[None].parents()]
405 generate(ui, revdag, displayer, showparents, asciiedges)
409 generate(ui, revdag, displayer, showparents, asciiedges)
406
410
407 hg._incoming(display, subreporecurse, ui, repo, source, opts, buffered=True)
411 hg._incoming(display, subreporecurse, ui, repo, source, opts, buffered=True)
408
412
409 def uisetup(ui):
413 def uisetup(ui):
410 '''Initialize the extension.'''
414 '''Initialize the extension.'''
411 _wrapcmd('log', commands.table, graphlog)
415 _wrapcmd('log', commands.table, graphlog)
412 _wrapcmd('incoming', commands.table, gincoming)
416 _wrapcmd('incoming', commands.table, gincoming)
413 _wrapcmd('outgoing', commands.table, goutgoing)
417 _wrapcmd('outgoing', commands.table, goutgoing)
414
418
415 def _wrapcmd(cmd, table, wrapfn):
419 def _wrapcmd(cmd, table, wrapfn):
416 '''wrap the command'''
420 '''wrap the command'''
417 def graph(orig, *args, **kwargs):
421 def graph(orig, *args, **kwargs):
418 if kwargs['graph']:
422 if kwargs['graph']:
419 return wrapfn(*args, **kwargs)
423 return wrapfn(*args, **kwargs)
420 return orig(*args, **kwargs)
424 return orig(*args, **kwargs)
421 entry = extensions.wrapcommand(table, cmd, graph)
425 entry = extensions.wrapcommand(table, cmd, graph)
422 entry[1].append(('G', 'graph', None, _("show the revision DAG")))
426 entry[1].append(('G', 'graph', None, _("show the revision DAG")))
@@ -1,845 +1,848 b''
1 # scmutil.py - Mercurial core utility functions
1 # scmutil.py - Mercurial core utility functions
2 #
2 #
3 # Copyright Matt Mackall <mpm@selenic.com>
3 # Copyright Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import util, error, osutil, revset, similar, encoding
9 import util, error, osutil, revset, similar, encoding
10 import match as matchmod
10 import match as matchmod
11 import os, errno, re, stat, sys, glob
11 import os, errno, re, stat, sys, glob
12
12
13 def nochangesfound(ui, secretlist=None):
13 def nochangesfound(ui, secretlist=None):
14 '''report no changes for push/pull'''
14 '''report no changes for push/pull'''
15 if secretlist:
15 if secretlist:
16 ui.status(_("no changes found (ignored %d secret changesets)\n")
16 ui.status(_("no changes found (ignored %d secret changesets)\n")
17 % len(secretlist))
17 % len(secretlist))
18 else:
18 else:
19 ui.status(_("no changes found\n"))
19 ui.status(_("no changes found\n"))
20
20
21 def checkfilename(f):
21 def checkfilename(f):
22 '''Check that the filename f is an acceptable filename for a tracked file'''
22 '''Check that the filename f is an acceptable filename for a tracked file'''
23 if '\r' in f or '\n' in f:
23 if '\r' in f or '\n' in f:
24 raise util.Abort(_("'\\n' and '\\r' disallowed in filenames: %r") % f)
24 raise util.Abort(_("'\\n' and '\\r' disallowed in filenames: %r") % f)
25
25
26 def checkportable(ui, f):
26 def checkportable(ui, f):
27 '''Check if filename f is portable and warn or abort depending on config'''
27 '''Check if filename f is portable and warn or abort depending on config'''
28 checkfilename(f)
28 checkfilename(f)
29 abort, warn = checkportabilityalert(ui)
29 abort, warn = checkportabilityalert(ui)
30 if abort or warn:
30 if abort or warn:
31 msg = util.checkwinfilename(f)
31 msg = util.checkwinfilename(f)
32 if msg:
32 if msg:
33 msg = "%s: %r" % (msg, f)
33 msg = "%s: %r" % (msg, f)
34 if abort:
34 if abort:
35 raise util.Abort(msg)
35 raise util.Abort(msg)
36 ui.warn(_("warning: %s\n") % msg)
36 ui.warn(_("warning: %s\n") % msg)
37
37
38 def checkportabilityalert(ui):
38 def checkportabilityalert(ui):
39 '''check if the user's config requests nothing, a warning, or abort for
39 '''check if the user's config requests nothing, a warning, or abort for
40 non-portable filenames'''
40 non-portable filenames'''
41 val = ui.config('ui', 'portablefilenames', 'warn')
41 val = ui.config('ui', 'portablefilenames', 'warn')
42 lval = val.lower()
42 lval = val.lower()
43 bval = util.parsebool(val)
43 bval = util.parsebool(val)
44 abort = os.name == 'nt' or lval == 'abort'
44 abort = os.name == 'nt' or lval == 'abort'
45 warn = bval or lval == 'warn'
45 warn = bval or lval == 'warn'
46 if bval is None and not (warn or abort or lval == 'ignore'):
46 if bval is None and not (warn or abort or lval == 'ignore'):
47 raise error.ConfigError(
47 raise error.ConfigError(
48 _("ui.portablefilenames value is invalid ('%s')") % val)
48 _("ui.portablefilenames value is invalid ('%s')") % val)
49 return abort, warn
49 return abort, warn
50
50
51 class casecollisionauditor(object):
51 class casecollisionauditor(object):
52 def __init__(self, ui, abort, existingiter):
52 def __init__(self, ui, abort, existingiter):
53 self._ui = ui
53 self._ui = ui
54 self._abort = abort
54 self._abort = abort
55 self._map = {}
55 self._map = {}
56 for f in existingiter:
56 for f in existingiter:
57 self._map[encoding.lower(f)] = f
57 self._map[encoding.lower(f)] = f
58
58
59 def __call__(self, f):
59 def __call__(self, f):
60 fl = encoding.lower(f)
60 fl = encoding.lower(f)
61 map = self._map
61 map = self._map
62 if fl in map and map[fl] != f:
62 if fl in map and map[fl] != f:
63 msg = _('possible case-folding collision for %s') % f
63 msg = _('possible case-folding collision for %s') % f
64 if self._abort:
64 if self._abort:
65 raise util.Abort(msg)
65 raise util.Abort(msg)
66 self._ui.warn(_("warning: %s\n") % msg)
66 self._ui.warn(_("warning: %s\n") % msg)
67 map[fl] = f
67 map[fl] = f
68
68
69 class pathauditor(object):
69 class pathauditor(object):
70 '''ensure that a filesystem path contains no banned components.
70 '''ensure that a filesystem path contains no banned components.
71 the following properties of a path are checked:
71 the following properties of a path are checked:
72
72
73 - ends with a directory separator
73 - ends with a directory separator
74 - under top-level .hg
74 - under top-level .hg
75 - starts at the root of a windows drive
75 - starts at the root of a windows drive
76 - contains ".."
76 - contains ".."
77 - traverses a symlink (e.g. a/symlink_here/b)
77 - traverses a symlink (e.g. a/symlink_here/b)
78 - inside a nested repository (a callback can be used to approve
78 - inside a nested repository (a callback can be used to approve
79 some nested repositories, e.g., subrepositories)
79 some nested repositories, e.g., subrepositories)
80 '''
80 '''
81
81
82 def __init__(self, root, callback=None):
82 def __init__(self, root, callback=None):
83 self.audited = set()
83 self.audited = set()
84 self.auditeddir = set()
84 self.auditeddir = set()
85 self.root = root
85 self.root = root
86 self.callback = callback
86 self.callback = callback
87 if os.path.lexists(root) and not util.checkcase(root):
87 if os.path.lexists(root) and not util.checkcase(root):
88 self.normcase = util.normcase
88 self.normcase = util.normcase
89 else:
89 else:
90 self.normcase = lambda x: x
90 self.normcase = lambda x: x
91
91
92 def __call__(self, path):
92 def __call__(self, path):
93 '''Check the relative path.
93 '''Check the relative path.
94 path may contain a pattern (e.g. foodir/**.txt)'''
94 path may contain a pattern (e.g. foodir/**.txt)'''
95
95
96 path = util.localpath(path)
96 path = util.localpath(path)
97 normpath = self.normcase(path)
97 normpath = self.normcase(path)
98 if normpath in self.audited:
98 if normpath in self.audited:
99 return
99 return
100 # AIX ignores "/" at end of path, others raise EISDIR.
100 # AIX ignores "/" at end of path, others raise EISDIR.
101 if util.endswithsep(path):
101 if util.endswithsep(path):
102 raise util.Abort(_("path ends in directory separator: %s") % path)
102 raise util.Abort(_("path ends in directory separator: %s") % path)
103 parts = util.splitpath(path)
103 parts = util.splitpath(path)
104 if (os.path.splitdrive(path)[0]
104 if (os.path.splitdrive(path)[0]
105 or parts[0].lower() in ('.hg', '.hg.', '')
105 or parts[0].lower() in ('.hg', '.hg.', '')
106 or os.pardir in parts):
106 or os.pardir in parts):
107 raise util.Abort(_("path contains illegal component: %s") % path)
107 raise util.Abort(_("path contains illegal component: %s") % path)
108 if '.hg' in path.lower():
108 if '.hg' in path.lower():
109 lparts = [p.lower() for p in parts]
109 lparts = [p.lower() for p in parts]
110 for p in '.hg', '.hg.':
110 for p in '.hg', '.hg.':
111 if p in lparts[1:]:
111 if p in lparts[1:]:
112 pos = lparts.index(p)
112 pos = lparts.index(p)
113 base = os.path.join(*parts[:pos])
113 base = os.path.join(*parts[:pos])
114 raise util.Abort(_("path '%s' is inside nested repo %r")
114 raise util.Abort(_("path '%s' is inside nested repo %r")
115 % (path, base))
115 % (path, base))
116
116
117 normparts = util.splitpath(normpath)
117 normparts = util.splitpath(normpath)
118 assert len(parts) == len(normparts)
118 assert len(parts) == len(normparts)
119
119
120 parts.pop()
120 parts.pop()
121 normparts.pop()
121 normparts.pop()
122 prefixes = []
122 prefixes = []
123 while parts:
123 while parts:
124 prefix = os.sep.join(parts)
124 prefix = os.sep.join(parts)
125 normprefix = os.sep.join(normparts)
125 normprefix = os.sep.join(normparts)
126 if normprefix in self.auditeddir:
126 if normprefix in self.auditeddir:
127 break
127 break
128 curpath = os.path.join(self.root, prefix)
128 curpath = os.path.join(self.root, prefix)
129 try:
129 try:
130 st = os.lstat(curpath)
130 st = os.lstat(curpath)
131 except OSError, err:
131 except OSError, err:
132 # EINVAL can be raised as invalid path syntax under win32.
132 # EINVAL can be raised as invalid path syntax under win32.
133 # They must be ignored for patterns can be checked too.
133 # They must be ignored for patterns can be checked too.
134 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
134 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
135 raise
135 raise
136 else:
136 else:
137 if stat.S_ISLNK(st.st_mode):
137 if stat.S_ISLNK(st.st_mode):
138 raise util.Abort(
138 raise util.Abort(
139 _('path %r traverses symbolic link %r')
139 _('path %r traverses symbolic link %r')
140 % (path, prefix))
140 % (path, prefix))
141 elif (stat.S_ISDIR(st.st_mode) and
141 elif (stat.S_ISDIR(st.st_mode) and
142 os.path.isdir(os.path.join(curpath, '.hg'))):
142 os.path.isdir(os.path.join(curpath, '.hg'))):
143 if not self.callback or not self.callback(curpath):
143 if not self.callback or not self.callback(curpath):
144 raise util.Abort(_("path '%s' is inside nested repo %r") %
144 raise util.Abort(_("path '%s' is inside nested repo %r") %
145 (path, prefix))
145 (path, prefix))
146 prefixes.append(normprefix)
146 prefixes.append(normprefix)
147 parts.pop()
147 parts.pop()
148 normparts.pop()
148 normparts.pop()
149
149
150 self.audited.add(normpath)
150 self.audited.add(normpath)
151 # only add prefixes to the cache after checking everything: we don't
151 # only add prefixes to the cache after checking everything: we don't
152 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
152 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
153 self.auditeddir.update(prefixes)
153 self.auditeddir.update(prefixes)
154
154
155 class abstractopener(object):
155 class abstractopener(object):
156 """Abstract base class; cannot be instantiated"""
156 """Abstract base class; cannot be instantiated"""
157
157
158 def __init__(self, *args, **kwargs):
158 def __init__(self, *args, **kwargs):
159 '''Prevent instantiation; don't call this from subclasses.'''
159 '''Prevent instantiation; don't call this from subclasses.'''
160 raise NotImplementedError('attempted instantiating ' + str(type(self)))
160 raise NotImplementedError('attempted instantiating ' + str(type(self)))
161
161
162 def read(self, path):
162 def read(self, path):
163 fp = self(path, 'rb')
163 fp = self(path, 'rb')
164 try:
164 try:
165 return fp.read()
165 return fp.read()
166 finally:
166 finally:
167 fp.close()
167 fp.close()
168
168
169 def write(self, path, data):
169 def write(self, path, data):
170 fp = self(path, 'wb')
170 fp = self(path, 'wb')
171 try:
171 try:
172 return fp.write(data)
172 return fp.write(data)
173 finally:
173 finally:
174 fp.close()
174 fp.close()
175
175
176 def append(self, path, data):
176 def append(self, path, data):
177 fp = self(path, 'ab')
177 fp = self(path, 'ab')
178 try:
178 try:
179 return fp.write(data)
179 return fp.write(data)
180 finally:
180 finally:
181 fp.close()
181 fp.close()
182
182
183 class opener(abstractopener):
183 class opener(abstractopener):
184 '''Open files relative to a base directory
184 '''Open files relative to a base directory
185
185
186 This class is used to hide the details of COW semantics and
186 This class is used to hide the details of COW semantics and
187 remote file access from higher level code.
187 remote file access from higher level code.
188 '''
188 '''
189 def __init__(self, base, audit=True):
189 def __init__(self, base, audit=True):
190 self.base = base
190 self.base = base
191 self._audit = audit
191 self._audit = audit
192 if audit:
192 if audit:
193 self.auditor = pathauditor(base)
193 self.auditor = pathauditor(base)
194 else:
194 else:
195 self.auditor = util.always
195 self.auditor = util.always
196 self.createmode = None
196 self.createmode = None
197 self._trustnlink = None
197 self._trustnlink = None
198
198
199 @util.propertycache
199 @util.propertycache
200 def _cansymlink(self):
200 def _cansymlink(self):
201 return util.checklink(self.base)
201 return util.checklink(self.base)
202
202
203 def _fixfilemode(self, name):
203 def _fixfilemode(self, name):
204 if self.createmode is None:
204 if self.createmode is None:
205 return
205 return
206 os.chmod(name, self.createmode & 0666)
206 os.chmod(name, self.createmode & 0666)
207
207
208 def __call__(self, path, mode="r", text=False, atomictemp=False):
208 def __call__(self, path, mode="r", text=False, atomictemp=False):
209 if self._audit:
209 if self._audit:
210 r = util.checkosfilename(path)
210 r = util.checkosfilename(path)
211 if r:
211 if r:
212 raise util.Abort("%s: %r" % (r, path))
212 raise util.Abort("%s: %r" % (r, path))
213 self.auditor(path)
213 self.auditor(path)
214 f = os.path.join(self.base, path)
214 f = os.path.join(self.base, path)
215
215
216 if not text and "b" not in mode:
216 if not text and "b" not in mode:
217 mode += "b" # for that other OS
217 mode += "b" # for that other OS
218
218
219 nlink = -1
219 nlink = -1
220 dirname, basename = os.path.split(f)
220 dirname, basename = os.path.split(f)
221 # If basename is empty, then the path is malformed because it points
221 # If basename is empty, then the path is malformed because it points
222 # to a directory. Let the posixfile() call below raise IOError.
222 # to a directory. Let the posixfile() call below raise IOError.
223 if basename and mode not in ('r', 'rb'):
223 if basename and mode not in ('r', 'rb'):
224 if atomictemp:
224 if atomictemp:
225 if not os.path.isdir(dirname):
225 if not os.path.isdir(dirname):
226 util.makedirs(dirname, self.createmode)
226 util.makedirs(dirname, self.createmode)
227 return util.atomictempfile(f, mode, self.createmode)
227 return util.atomictempfile(f, mode, self.createmode)
228 try:
228 try:
229 if 'w' in mode:
229 if 'w' in mode:
230 util.unlink(f)
230 util.unlink(f)
231 nlink = 0
231 nlink = 0
232 else:
232 else:
233 # nlinks() may behave differently for files on Windows
233 # nlinks() may behave differently for files on Windows
234 # shares if the file is open.
234 # shares if the file is open.
235 fd = util.posixfile(f)
235 fd = util.posixfile(f)
236 nlink = util.nlinks(f)
236 nlink = util.nlinks(f)
237 if nlink < 1:
237 if nlink < 1:
238 nlink = 2 # force mktempcopy (issue1922)
238 nlink = 2 # force mktempcopy (issue1922)
239 fd.close()
239 fd.close()
240 except (OSError, IOError), e:
240 except (OSError, IOError), e:
241 if e.errno != errno.ENOENT:
241 if e.errno != errno.ENOENT:
242 raise
242 raise
243 nlink = 0
243 nlink = 0
244 if not os.path.isdir(dirname):
244 if not os.path.isdir(dirname):
245 util.makedirs(dirname, self.createmode)
245 util.makedirs(dirname, self.createmode)
246 if nlink > 0:
246 if nlink > 0:
247 if self._trustnlink is None:
247 if self._trustnlink is None:
248 self._trustnlink = nlink > 1 or util.checknlink(f)
248 self._trustnlink = nlink > 1 or util.checknlink(f)
249 if nlink > 1 or not self._trustnlink:
249 if nlink > 1 or not self._trustnlink:
250 util.rename(util.mktempcopy(f), f)
250 util.rename(util.mktempcopy(f), f)
251 fp = util.posixfile(f, mode)
251 fp = util.posixfile(f, mode)
252 if nlink == 0:
252 if nlink == 0:
253 self._fixfilemode(f)
253 self._fixfilemode(f)
254 return fp
254 return fp
255
255
256 def symlink(self, src, dst):
256 def symlink(self, src, dst):
257 self.auditor(dst)
257 self.auditor(dst)
258 linkname = os.path.join(self.base, dst)
258 linkname = os.path.join(self.base, dst)
259 try:
259 try:
260 os.unlink(linkname)
260 os.unlink(linkname)
261 except OSError:
261 except OSError:
262 pass
262 pass
263
263
264 dirname = os.path.dirname(linkname)
264 dirname = os.path.dirname(linkname)
265 if not os.path.exists(dirname):
265 if not os.path.exists(dirname):
266 util.makedirs(dirname, self.createmode)
266 util.makedirs(dirname, self.createmode)
267
267
268 if self._cansymlink:
268 if self._cansymlink:
269 try:
269 try:
270 os.symlink(src, linkname)
270 os.symlink(src, linkname)
271 except OSError, err:
271 except OSError, err:
272 raise OSError(err.errno, _('could not symlink to %r: %s') %
272 raise OSError(err.errno, _('could not symlink to %r: %s') %
273 (src, err.strerror), linkname)
273 (src, err.strerror), linkname)
274 else:
274 else:
275 f = self(dst, "w")
275 f = self(dst, "w")
276 f.write(src)
276 f.write(src)
277 f.close()
277 f.close()
278 self._fixfilemode(dst)
278 self._fixfilemode(dst)
279
279
280 def audit(self, path):
280 def audit(self, path):
281 self.auditor(path)
281 self.auditor(path)
282
282
283 class filteropener(abstractopener):
283 class filteropener(abstractopener):
284 '''Wrapper opener for filtering filenames with a function.'''
284 '''Wrapper opener for filtering filenames with a function.'''
285
285
286 def __init__(self, opener, filter):
286 def __init__(self, opener, filter):
287 self._filter = filter
287 self._filter = filter
288 self._orig = opener
288 self._orig = opener
289
289
290 def __call__(self, path, *args, **kwargs):
290 def __call__(self, path, *args, **kwargs):
291 return self._orig(self._filter(path), *args, **kwargs)
291 return self._orig(self._filter(path), *args, **kwargs)
292
292
293 def canonpath(root, cwd, myname, auditor=None):
293 def canonpath(root, cwd, myname, auditor=None):
294 '''return the canonical path of myname, given cwd and root'''
294 '''return the canonical path of myname, given cwd and root'''
295 if util.endswithsep(root):
295 if util.endswithsep(root):
296 rootsep = root
296 rootsep = root
297 else:
297 else:
298 rootsep = root + os.sep
298 rootsep = root + os.sep
299 name = myname
299 name = myname
300 if not os.path.isabs(name):
300 if not os.path.isabs(name):
301 name = os.path.join(root, cwd, name)
301 name = os.path.join(root, cwd, name)
302 name = os.path.normpath(name)
302 name = os.path.normpath(name)
303 if auditor is None:
303 if auditor is None:
304 auditor = pathauditor(root)
304 auditor = pathauditor(root)
305 if name != rootsep and name.startswith(rootsep):
305 if name != rootsep and name.startswith(rootsep):
306 name = name[len(rootsep):]
306 name = name[len(rootsep):]
307 auditor(name)
307 auditor(name)
308 return util.pconvert(name)
308 return util.pconvert(name)
309 elif name == root:
309 elif name == root:
310 return ''
310 return ''
311 else:
311 else:
312 # Determine whether `name' is in the hierarchy at or beneath `root',
312 # Determine whether `name' is in the hierarchy at or beneath `root',
313 # by iterating name=dirname(name) until that causes no change (can't
313 # by iterating name=dirname(name) until that causes no change (can't
314 # check name == '/', because that doesn't work on windows). For each
314 # check name == '/', because that doesn't work on windows). For each
315 # `name', compare dev/inode numbers. If they match, the list `rel'
315 # `name', compare dev/inode numbers. If they match, the list `rel'
316 # holds the reversed list of components making up the relative file
316 # holds the reversed list of components making up the relative file
317 # name we want.
317 # name we want.
318 root_st = os.stat(root)
318 root_st = os.stat(root)
319 rel = []
319 rel = []
320 while True:
320 while True:
321 try:
321 try:
322 name_st = os.stat(name)
322 name_st = os.stat(name)
323 except OSError:
323 except OSError:
324 name_st = None
324 name_st = None
325 if name_st and util.samestat(name_st, root_st):
325 if name_st and util.samestat(name_st, root_st):
326 if not rel:
326 if not rel:
327 # name was actually the same as root (maybe a symlink)
327 # name was actually the same as root (maybe a symlink)
328 return ''
328 return ''
329 rel.reverse()
329 rel.reverse()
330 name = os.path.join(*rel)
330 name = os.path.join(*rel)
331 auditor(name)
331 auditor(name)
332 return util.pconvert(name)
332 return util.pconvert(name)
333 dirname, basename = os.path.split(name)
333 dirname, basename = os.path.split(name)
334 rel.append(basename)
334 rel.append(basename)
335 if dirname == name:
335 if dirname == name:
336 break
336 break
337 name = dirname
337 name = dirname
338
338
339 raise util.Abort('%s not under root' % myname)
339 raise util.Abort('%s not under root' % myname)
340
340
341 def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
341 def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
342 '''yield every hg repository under path, recursively.'''
342 '''yield every hg repository under path, recursively.'''
343 def errhandler(err):
343 def errhandler(err):
344 if err.filename == path:
344 if err.filename == path:
345 raise err
345 raise err
346 samestat = getattr(os.path, 'samestat', None)
346 samestat = getattr(os.path, 'samestat', None)
347 if followsym and samestat is not None:
347 if followsym and samestat is not None:
348 def adddir(dirlst, dirname):
348 def adddir(dirlst, dirname):
349 match = False
349 match = False
350 dirstat = os.stat(dirname)
350 dirstat = os.stat(dirname)
351 for lstdirstat in dirlst:
351 for lstdirstat in dirlst:
352 if samestat(dirstat, lstdirstat):
352 if samestat(dirstat, lstdirstat):
353 match = True
353 match = True
354 break
354 break
355 if not match:
355 if not match:
356 dirlst.append(dirstat)
356 dirlst.append(dirstat)
357 return not match
357 return not match
358 else:
358 else:
359 followsym = False
359 followsym = False
360
360
361 if (seen_dirs is None) and followsym:
361 if (seen_dirs is None) and followsym:
362 seen_dirs = []
362 seen_dirs = []
363 adddir(seen_dirs, path)
363 adddir(seen_dirs, path)
364 for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
364 for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
365 dirs.sort()
365 dirs.sort()
366 if '.hg' in dirs:
366 if '.hg' in dirs:
367 yield root # found a repository
367 yield root # found a repository
368 qroot = os.path.join(root, '.hg', 'patches')
368 qroot = os.path.join(root, '.hg', 'patches')
369 if os.path.isdir(os.path.join(qroot, '.hg')):
369 if os.path.isdir(os.path.join(qroot, '.hg')):
370 yield qroot # we have a patch queue repo here
370 yield qroot # we have a patch queue repo here
371 if recurse:
371 if recurse:
372 # avoid recursing inside the .hg directory
372 # avoid recursing inside the .hg directory
373 dirs.remove('.hg')
373 dirs.remove('.hg')
374 else:
374 else:
375 dirs[:] = [] # don't descend further
375 dirs[:] = [] # don't descend further
376 elif followsym:
376 elif followsym:
377 newdirs = []
377 newdirs = []
378 for d in dirs:
378 for d in dirs:
379 fname = os.path.join(root, d)
379 fname = os.path.join(root, d)
380 if adddir(seen_dirs, fname):
380 if adddir(seen_dirs, fname):
381 if os.path.islink(fname):
381 if os.path.islink(fname):
382 for hgname in walkrepos(fname, True, seen_dirs):
382 for hgname in walkrepos(fname, True, seen_dirs):
383 yield hgname
383 yield hgname
384 else:
384 else:
385 newdirs.append(d)
385 newdirs.append(d)
386 dirs[:] = newdirs
386 dirs[:] = newdirs
387
387
388 def osrcpath():
388 def osrcpath():
389 '''return default os-specific hgrc search path'''
389 '''return default os-specific hgrc search path'''
390 path = systemrcpath()
390 path = systemrcpath()
391 path.extend(userrcpath())
391 path.extend(userrcpath())
392 path = [os.path.normpath(f) for f in path]
392 path = [os.path.normpath(f) for f in path]
393 return path
393 return path
394
394
395 _rcpath = None
395 _rcpath = None
396
396
397 def rcpath():
397 def rcpath():
398 '''return hgrc search path. if env var HGRCPATH is set, use it.
398 '''return hgrc search path. if env var HGRCPATH is set, use it.
399 for each item in path, if directory, use files ending in .rc,
399 for each item in path, if directory, use files ending in .rc,
400 else use item.
400 else use item.
401 make HGRCPATH empty to only look in .hg/hgrc of current repo.
401 make HGRCPATH empty to only look in .hg/hgrc of current repo.
402 if no HGRCPATH, use default os-specific path.'''
402 if no HGRCPATH, use default os-specific path.'''
403 global _rcpath
403 global _rcpath
404 if _rcpath is None:
404 if _rcpath is None:
405 if 'HGRCPATH' in os.environ:
405 if 'HGRCPATH' in os.environ:
406 _rcpath = []
406 _rcpath = []
407 for p in os.environ['HGRCPATH'].split(os.pathsep):
407 for p in os.environ['HGRCPATH'].split(os.pathsep):
408 if not p:
408 if not p:
409 continue
409 continue
410 p = util.expandpath(p)
410 p = util.expandpath(p)
411 if os.path.isdir(p):
411 if os.path.isdir(p):
412 for f, kind in osutil.listdir(p):
412 for f, kind in osutil.listdir(p):
413 if f.endswith('.rc'):
413 if f.endswith('.rc'):
414 _rcpath.append(os.path.join(p, f))
414 _rcpath.append(os.path.join(p, f))
415 else:
415 else:
416 _rcpath.append(p)
416 _rcpath.append(p)
417 else:
417 else:
418 _rcpath = osrcpath()
418 _rcpath = osrcpath()
419 return _rcpath
419 return _rcpath
420
420
421 if os.name != 'nt':
421 if os.name != 'nt':
422
422
423 def rcfiles(path):
423 def rcfiles(path):
424 rcs = [os.path.join(path, 'hgrc')]
424 rcs = [os.path.join(path, 'hgrc')]
425 rcdir = os.path.join(path, 'hgrc.d')
425 rcdir = os.path.join(path, 'hgrc.d')
426 try:
426 try:
427 rcs.extend([os.path.join(rcdir, f)
427 rcs.extend([os.path.join(rcdir, f)
428 for f, kind in osutil.listdir(rcdir)
428 for f, kind in osutil.listdir(rcdir)
429 if f.endswith(".rc")])
429 if f.endswith(".rc")])
430 except OSError:
430 except OSError:
431 pass
431 pass
432 return rcs
432 return rcs
433
433
434 def systemrcpath():
434 def systemrcpath():
435 path = []
435 path = []
436 # old mod_python does not set sys.argv
436 # old mod_python does not set sys.argv
437 if len(getattr(sys, 'argv', [])) > 0:
437 if len(getattr(sys, 'argv', [])) > 0:
438 p = os.path.dirname(os.path.dirname(sys.argv[0]))
438 p = os.path.dirname(os.path.dirname(sys.argv[0]))
439 path.extend(rcfiles(os.path.join(p, 'etc/mercurial')))
439 path.extend(rcfiles(os.path.join(p, 'etc/mercurial')))
440 path.extend(rcfiles('/etc/mercurial'))
440 path.extend(rcfiles('/etc/mercurial'))
441 return path
441 return path
442
442
443 def userrcpath():
443 def userrcpath():
444 return [os.path.expanduser('~/.hgrc')]
444 return [os.path.expanduser('~/.hgrc')]
445
445
446 else:
446 else:
447
447
448 _HKEY_LOCAL_MACHINE = 0x80000002L
448 _HKEY_LOCAL_MACHINE = 0x80000002L
449
449
450 def systemrcpath():
450 def systemrcpath():
451 '''return default os-specific hgrc search path'''
451 '''return default os-specific hgrc search path'''
452 rcpath = []
452 rcpath = []
453 filename = util.executablepath()
453 filename = util.executablepath()
454 # Use mercurial.ini found in directory with hg.exe
454 # Use mercurial.ini found in directory with hg.exe
455 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
455 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
456 if os.path.isfile(progrc):
456 if os.path.isfile(progrc):
457 rcpath.append(progrc)
457 rcpath.append(progrc)
458 return rcpath
458 return rcpath
459 # Use hgrc.d found in directory with hg.exe
459 # Use hgrc.d found in directory with hg.exe
460 progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
460 progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
461 if os.path.isdir(progrcd):
461 if os.path.isdir(progrcd):
462 for f, kind in osutil.listdir(progrcd):
462 for f, kind in osutil.listdir(progrcd):
463 if f.endswith('.rc'):
463 if f.endswith('.rc'):
464 rcpath.append(os.path.join(progrcd, f))
464 rcpath.append(os.path.join(progrcd, f))
465 return rcpath
465 return rcpath
466 # else look for a system rcpath in the registry
466 # else look for a system rcpath in the registry
467 value = util.lookupreg('SOFTWARE\\Mercurial', None,
467 value = util.lookupreg('SOFTWARE\\Mercurial', None,
468 _HKEY_LOCAL_MACHINE)
468 _HKEY_LOCAL_MACHINE)
469 if not isinstance(value, str) or not value:
469 if not isinstance(value, str) or not value:
470 return rcpath
470 return rcpath
471 value = util.localpath(value)
471 value = util.localpath(value)
472 for p in value.split(os.pathsep):
472 for p in value.split(os.pathsep):
473 if p.lower().endswith('mercurial.ini'):
473 if p.lower().endswith('mercurial.ini'):
474 rcpath.append(p)
474 rcpath.append(p)
475 elif os.path.isdir(p):
475 elif os.path.isdir(p):
476 for f, kind in osutil.listdir(p):
476 for f, kind in osutil.listdir(p):
477 if f.endswith('.rc'):
477 if f.endswith('.rc'):
478 rcpath.append(os.path.join(p, f))
478 rcpath.append(os.path.join(p, f))
479 return rcpath
479 return rcpath
480
480
481 def userrcpath():
481 def userrcpath():
482 '''return os-specific hgrc search path to the user dir'''
482 '''return os-specific hgrc search path to the user dir'''
483 home = os.path.expanduser('~')
483 home = os.path.expanduser('~')
484 path = [os.path.join(home, 'mercurial.ini'),
484 path = [os.path.join(home, 'mercurial.ini'),
485 os.path.join(home, '.hgrc')]
485 os.path.join(home, '.hgrc')]
486 userprofile = os.environ.get('USERPROFILE')
486 userprofile = os.environ.get('USERPROFILE')
487 if userprofile:
487 if userprofile:
488 path.append(os.path.join(userprofile, 'mercurial.ini'))
488 path.append(os.path.join(userprofile, 'mercurial.ini'))
489 path.append(os.path.join(userprofile, '.hgrc'))
489 path.append(os.path.join(userprofile, '.hgrc'))
490 return path
490 return path
491
491
492 def revsingle(repo, revspec, default='.'):
492 def revsingle(repo, revspec, default='.'):
493 if not revspec:
493 if not revspec:
494 return repo[default]
494 return repo[default]
495
495
496 l = revrange(repo, [revspec])
496 l = revrange(repo, [revspec])
497 if len(l) < 1:
497 if len(l) < 1:
498 raise util.Abort(_('empty revision set'))
498 raise util.Abort(_('empty revision set'))
499 return repo[l[-1]]
499 return repo[l[-1]]
500
500
501 def revpair(repo, revs):
501 def revpair(repo, revs):
502 if not revs:
502 if not revs:
503 return repo.dirstate.p1(), None
503 return repo.dirstate.p1(), None
504
504
505 l = revrange(repo, revs)
505 l = revrange(repo, revs)
506
506
507 if len(l) == 0:
507 if len(l) == 0:
508 return repo.dirstate.p1(), None
508 return repo.dirstate.p1(), None
509
509
510 if len(l) == 1:
510 if len(l) == 1:
511 return repo.lookup(l[0]), None
511 return repo.lookup(l[0]), None
512
512
513 return repo.lookup(l[0]), repo.lookup(l[-1])
513 return repo.lookup(l[0]), repo.lookup(l[-1])
514
514
515 _revrangesep = ':'
515 _revrangesep = ':'
516
516
517 def revrange(repo, revs):
517 def revrange(repo, revs):
518 """Yield revision as strings from a list of revision specifications."""
518 """Yield revision as strings from a list of revision specifications."""
519
519
520 def revfix(repo, val, defval):
520 def revfix(repo, val, defval):
521 if not val and val != 0 and defval is not None:
521 if not val and val != 0 and defval is not None:
522 return defval
522 return defval
523 return repo.changelog.rev(repo.lookup(val))
523 return repo.changelog.rev(repo.lookup(val))
524
524
525 seen, l = set(), []
525 seen, l = set(), []
526 for spec in revs:
526 for spec in revs:
527 # attempt to parse old-style ranges first to deal with
527 # attempt to parse old-style ranges first to deal with
528 # things like old-tag which contain query metacharacters
528 # things like old-tag which contain query metacharacters
529 try:
529 try:
530 if isinstance(spec, int):
530 if isinstance(spec, int):
531 seen.add(spec)
531 seen.add(spec)
532 l.append(spec)
532 l.append(spec)
533 continue
533 continue
534
534
535 if _revrangesep in spec:
535 if _revrangesep in spec:
536 start, end = spec.split(_revrangesep, 1)
536 start, end = spec.split(_revrangesep, 1)
537 start = revfix(repo, start, 0)
537 start = revfix(repo, start, 0)
538 end = revfix(repo, end, len(repo) - 1)
538 end = revfix(repo, end, len(repo) - 1)
539 step = start > end and -1 or 1
539 step = start > end and -1 or 1
540 for rev in xrange(start, end + step, step):
540 for rev in xrange(start, end + step, step):
541 if rev in seen:
541 if rev in seen:
542 continue
542 continue
543 seen.add(rev)
543 seen.add(rev)
544 l.append(rev)
544 l.append(rev)
545 continue
545 continue
546 elif spec and spec in repo: # single unquoted rev
546 elif spec and spec in repo: # single unquoted rev
547 rev = revfix(repo, spec, None)
547 rev = revfix(repo, spec, None)
548 if rev in seen:
548 if rev in seen:
549 continue
549 continue
550 seen.add(rev)
550 seen.add(rev)
551 l.append(rev)
551 l.append(rev)
552 continue
552 continue
553 except error.RepoLookupError:
553 except error.RepoLookupError:
554 pass
554 pass
555
555
556 # fall through to new-style queries if old-style fails
556 # fall through to new-style queries if old-style fails
557 m = revset.match(repo.ui, spec)
557 m = revset.match(repo.ui, spec)
558 for r in m(repo, range(len(repo))):
558 for r in m(repo, range(len(repo))):
559 if r not in seen:
559 if r not in seen:
560 l.append(r)
560 l.append(r)
561 seen.update(l)
561 seen.update(l)
562
562
563 return l
563 return l
564
564
565 def expandpats(pats):
565 def expandpats(pats):
566 if not util.expandglobs:
566 if not util.expandglobs:
567 return list(pats)
567 return list(pats)
568 ret = []
568 ret = []
569 for p in pats:
569 for p in pats:
570 kind, name = matchmod._patsplit(p, None)
570 kind, name = matchmod._patsplit(p, None)
571 if kind is None:
571 if kind is None:
572 try:
572 try:
573 globbed = glob.glob(name)
573 globbed = glob.glob(name)
574 except re.error:
574 except re.error:
575 globbed = [name]
575 globbed = [name]
576 if globbed:
576 if globbed:
577 ret.extend(globbed)
577 ret.extend(globbed)
578 continue
578 continue
579 ret.append(p)
579 ret.append(p)
580 return ret
580 return ret
581
581
582 def match(ctx, pats=[], opts={}, globbed=False, default='relpath'):
582 def matchandpats(ctx, pats=[], opts={}, globbed=False, default='relpath'):
583 if pats == ("",):
583 if pats == ("",):
584 pats = []
584 pats = []
585 if not globbed and default == 'relpath':
585 if not globbed and default == 'relpath':
586 pats = expandpats(pats or [])
586 pats = expandpats(pats or [])
587
587
588 m = ctx.match(pats, opts.get('include'), opts.get('exclude'),
588 m = ctx.match(pats, opts.get('include'), opts.get('exclude'),
589 default)
589 default)
590 def badfn(f, msg):
590 def badfn(f, msg):
591 ctx._repo.ui.warn("%s: %s\n" % (m.rel(f), msg))
591 ctx._repo.ui.warn("%s: %s\n" % (m.rel(f), msg))
592 m.bad = badfn
592 m.bad = badfn
593 return m
593 return m, pats
594
595 def match(ctx, pats=[], opts={}, globbed=False, default='relpath'):
596 return matchandpats(ctx, pats, opts, globbed, default)[0]
594
597
595 def matchall(repo):
598 def matchall(repo):
596 return matchmod.always(repo.root, repo.getcwd())
599 return matchmod.always(repo.root, repo.getcwd())
597
600
598 def matchfiles(repo, files):
601 def matchfiles(repo, files):
599 return matchmod.exact(repo.root, repo.getcwd(), files)
602 return matchmod.exact(repo.root, repo.getcwd(), files)
600
603
601 def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
604 def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
602 if dry_run is None:
605 if dry_run is None:
603 dry_run = opts.get('dry_run')
606 dry_run = opts.get('dry_run')
604 if similarity is None:
607 if similarity is None:
605 similarity = float(opts.get('similarity') or 0)
608 similarity = float(opts.get('similarity') or 0)
606 # we'd use status here, except handling of symlinks and ignore is tricky
609 # we'd use status here, except handling of symlinks and ignore is tricky
607 added, unknown, deleted, removed = [], [], [], []
610 added, unknown, deleted, removed = [], [], [], []
608 audit_path = pathauditor(repo.root)
611 audit_path = pathauditor(repo.root)
609 m = match(repo[None], pats, opts)
612 m = match(repo[None], pats, opts)
610 rejected = []
613 rejected = []
611 m.bad = lambda x, y: rejected.append(x)
614 m.bad = lambda x, y: rejected.append(x)
612
615
613 for abs in repo.walk(m):
616 for abs in repo.walk(m):
614 target = repo.wjoin(abs)
617 target = repo.wjoin(abs)
615 good = True
618 good = True
616 try:
619 try:
617 audit_path(abs)
620 audit_path(abs)
618 except (OSError, util.Abort):
621 except (OSError, util.Abort):
619 good = False
622 good = False
620 rel = m.rel(abs)
623 rel = m.rel(abs)
621 exact = m.exact(abs)
624 exact = m.exact(abs)
622 if good and abs not in repo.dirstate:
625 if good and abs not in repo.dirstate:
623 unknown.append(abs)
626 unknown.append(abs)
624 if repo.ui.verbose or not exact:
627 if repo.ui.verbose or not exact:
625 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
628 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
626 elif repo.dirstate[abs] != 'r' and (not good or not os.path.lexists(target)
629 elif repo.dirstate[abs] != 'r' and (not good or not os.path.lexists(target)
627 or (os.path.isdir(target) and not os.path.islink(target))):
630 or (os.path.isdir(target) and not os.path.islink(target))):
628 deleted.append(abs)
631 deleted.append(abs)
629 if repo.ui.verbose or not exact:
632 if repo.ui.verbose or not exact:
630 repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
633 repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
631 # for finding renames
634 # for finding renames
632 elif repo.dirstate[abs] == 'r':
635 elif repo.dirstate[abs] == 'r':
633 removed.append(abs)
636 removed.append(abs)
634 elif repo.dirstate[abs] == 'a':
637 elif repo.dirstate[abs] == 'a':
635 added.append(abs)
638 added.append(abs)
636 copies = {}
639 copies = {}
637 if similarity > 0:
640 if similarity > 0:
638 for old, new, score in similar.findrenames(repo,
641 for old, new, score in similar.findrenames(repo,
639 added + unknown, removed + deleted, similarity):
642 added + unknown, removed + deleted, similarity):
640 if repo.ui.verbose or not m.exact(old) or not m.exact(new):
643 if repo.ui.verbose or not m.exact(old) or not m.exact(new):
641 repo.ui.status(_('recording removal of %s as rename to %s '
644 repo.ui.status(_('recording removal of %s as rename to %s '
642 '(%d%% similar)\n') %
645 '(%d%% similar)\n') %
643 (m.rel(old), m.rel(new), score * 100))
646 (m.rel(old), m.rel(new), score * 100))
644 copies[new] = old
647 copies[new] = old
645
648
646 if not dry_run:
649 if not dry_run:
647 wctx = repo[None]
650 wctx = repo[None]
648 wlock = repo.wlock()
651 wlock = repo.wlock()
649 try:
652 try:
650 wctx.forget(deleted)
653 wctx.forget(deleted)
651 wctx.add(unknown)
654 wctx.add(unknown)
652 for new, old in copies.iteritems():
655 for new, old in copies.iteritems():
653 wctx.copy(old, new)
656 wctx.copy(old, new)
654 finally:
657 finally:
655 wlock.release()
658 wlock.release()
656
659
657 for f in rejected:
660 for f in rejected:
658 if f in m.files():
661 if f in m.files():
659 return 1
662 return 1
660 return 0
663 return 0
661
664
662 def updatedir(ui, repo, patches, similarity=0):
665 def updatedir(ui, repo, patches, similarity=0):
663 '''Update dirstate after patch application according to metadata'''
666 '''Update dirstate after patch application according to metadata'''
664 if not patches:
667 if not patches:
665 return []
668 return []
666 copies = []
669 copies = []
667 removes = set()
670 removes = set()
668 cfiles = patches.keys()
671 cfiles = patches.keys()
669 cwd = repo.getcwd()
672 cwd = repo.getcwd()
670 if cwd:
673 if cwd:
671 cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
674 cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
672 for f in patches:
675 for f in patches:
673 gp = patches[f]
676 gp = patches[f]
674 if not gp:
677 if not gp:
675 continue
678 continue
676 if gp.op == 'RENAME':
679 if gp.op == 'RENAME':
677 copies.append((gp.oldpath, gp.path))
680 copies.append((gp.oldpath, gp.path))
678 removes.add(gp.oldpath)
681 removes.add(gp.oldpath)
679 elif gp.op == 'COPY':
682 elif gp.op == 'COPY':
680 copies.append((gp.oldpath, gp.path))
683 copies.append((gp.oldpath, gp.path))
681 elif gp.op == 'DELETE':
684 elif gp.op == 'DELETE':
682 removes.add(gp.path)
685 removes.add(gp.path)
683
686
684 wctx = repo[None]
687 wctx = repo[None]
685 for src, dst in copies:
688 for src, dst in copies:
686 dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
689 dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
687 if (not similarity) and removes:
690 if (not similarity) and removes:
688 wctx.remove(sorted(removes), True)
691 wctx.remove(sorted(removes), True)
689
692
690 for f in patches:
693 for f in patches:
691 gp = patches[f]
694 gp = patches[f]
692 if gp and gp.mode:
695 if gp and gp.mode:
693 islink, isexec = gp.mode
696 islink, isexec = gp.mode
694 dst = repo.wjoin(gp.path)
697 dst = repo.wjoin(gp.path)
695 # patch won't create empty files
698 # patch won't create empty files
696 if gp.op == 'ADD' and not os.path.lexists(dst):
699 if gp.op == 'ADD' and not os.path.lexists(dst):
697 flags = (isexec and 'x' or '') + (islink and 'l' or '')
700 flags = (isexec and 'x' or '') + (islink and 'l' or '')
698 repo.wwrite(gp.path, '', flags)
701 repo.wwrite(gp.path, '', flags)
699 util.setflags(dst, islink, isexec)
702 util.setflags(dst, islink, isexec)
700 addremove(repo, cfiles, similarity=similarity)
703 addremove(repo, cfiles, similarity=similarity)
701 files = patches.keys()
704 files = patches.keys()
702 files.extend([r for r in removes if r not in files])
705 files.extend([r for r in removes if r not in files])
703 return sorted(files)
706 return sorted(files)
704
707
705 def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
708 def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
706 """Update the dirstate to reflect the intent of copying src to dst. For
709 """Update the dirstate to reflect the intent of copying src to dst. For
707 different reasons it might not end with dst being marked as copied from src.
710 different reasons it might not end with dst being marked as copied from src.
708 """
711 """
709 origsrc = repo.dirstate.copied(src) or src
712 origsrc = repo.dirstate.copied(src) or src
710 if dst == origsrc: # copying back a copy?
713 if dst == origsrc: # copying back a copy?
711 if repo.dirstate[dst] not in 'mn' and not dryrun:
714 if repo.dirstate[dst] not in 'mn' and not dryrun:
712 repo.dirstate.normallookup(dst)
715 repo.dirstate.normallookup(dst)
713 else:
716 else:
714 if repo.dirstate[origsrc] == 'a' and origsrc == src:
717 if repo.dirstate[origsrc] == 'a' and origsrc == src:
715 if not ui.quiet:
718 if not ui.quiet:
716 ui.warn(_("%s has not been committed yet, so no copy "
719 ui.warn(_("%s has not been committed yet, so no copy "
717 "data will be stored for %s.\n")
720 "data will be stored for %s.\n")
718 % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
721 % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
719 if repo.dirstate[dst] in '?r' and not dryrun:
722 if repo.dirstate[dst] in '?r' and not dryrun:
720 wctx.add([dst])
723 wctx.add([dst])
721 elif not dryrun:
724 elif not dryrun:
722 wctx.copy(origsrc, dst)
725 wctx.copy(origsrc, dst)
723
726
724 def readrequires(opener, supported):
727 def readrequires(opener, supported):
725 '''Reads and parses .hg/requires and checks if all entries found
728 '''Reads and parses .hg/requires and checks if all entries found
726 are in the list of supported features.'''
729 are in the list of supported features.'''
727 requirements = set(opener.read("requires").splitlines())
730 requirements = set(opener.read("requires").splitlines())
728 missings = []
731 missings = []
729 for r in requirements:
732 for r in requirements:
730 if r not in supported:
733 if r not in supported:
731 if not r or not r[0].isalnum():
734 if not r or not r[0].isalnum():
732 raise error.RequirementError(_(".hg/requires file is corrupt"))
735 raise error.RequirementError(_(".hg/requires file is corrupt"))
733 missings.append(r)
736 missings.append(r)
734 missings.sort()
737 missings.sort()
735 if missings:
738 if missings:
736 raise error.RequirementError(_("unknown repository format: "
739 raise error.RequirementError(_("unknown repository format: "
737 "requires features '%s' (upgrade Mercurial)") % "', '".join(missings))
740 "requires features '%s' (upgrade Mercurial)") % "', '".join(missings))
738 return requirements
741 return requirements
739
742
740 class filecacheentry(object):
743 class filecacheentry(object):
741 def __init__(self, path):
744 def __init__(self, path):
742 self.path = path
745 self.path = path
743 self.cachestat = filecacheentry.stat(self.path)
746 self.cachestat = filecacheentry.stat(self.path)
744
747
745 if self.cachestat:
748 if self.cachestat:
746 self._cacheable = self.cachestat.cacheable()
749 self._cacheable = self.cachestat.cacheable()
747 else:
750 else:
748 # None means we don't know yet
751 # None means we don't know yet
749 self._cacheable = None
752 self._cacheable = None
750
753
751 def refresh(self):
754 def refresh(self):
752 if self.cacheable():
755 if self.cacheable():
753 self.cachestat = filecacheentry.stat(self.path)
756 self.cachestat = filecacheentry.stat(self.path)
754
757
755 def cacheable(self):
758 def cacheable(self):
756 if self._cacheable is not None:
759 if self._cacheable is not None:
757 return self._cacheable
760 return self._cacheable
758
761
759 # we don't know yet, assume it is for now
762 # we don't know yet, assume it is for now
760 return True
763 return True
761
764
762 def changed(self):
765 def changed(self):
763 # no point in going further if we can't cache it
766 # no point in going further if we can't cache it
764 if not self.cacheable():
767 if not self.cacheable():
765 return True
768 return True
766
769
767 newstat = filecacheentry.stat(self.path)
770 newstat = filecacheentry.stat(self.path)
768
771
769 # we may not know if it's cacheable yet, check again now
772 # we may not know if it's cacheable yet, check again now
770 if newstat and self._cacheable is None:
773 if newstat and self._cacheable is None:
771 self._cacheable = newstat.cacheable()
774 self._cacheable = newstat.cacheable()
772
775
773 # check again
776 # check again
774 if not self._cacheable:
777 if not self._cacheable:
775 return True
778 return True
776
779
777 if self.cachestat != newstat:
780 if self.cachestat != newstat:
778 self.cachestat = newstat
781 self.cachestat = newstat
779 return True
782 return True
780 else:
783 else:
781 return False
784 return False
782
785
783 @staticmethod
786 @staticmethod
784 def stat(path):
787 def stat(path):
785 try:
788 try:
786 return util.cachestat(path)
789 return util.cachestat(path)
787 except OSError, e:
790 except OSError, e:
788 if e.errno != errno.ENOENT:
791 if e.errno != errno.ENOENT:
789 raise
792 raise
790
793
791 class filecache(object):
794 class filecache(object):
792 '''A property like decorator that tracks a file under .hg/ for updates.
795 '''A property like decorator that tracks a file under .hg/ for updates.
793
796
794 Records stat info when called in _filecache.
797 Records stat info when called in _filecache.
795
798
796 On subsequent calls, compares old stat info with new info, and recreates
799 On subsequent calls, compares old stat info with new info, and recreates
797 the object when needed, updating the new stat info in _filecache.
800 the object when needed, updating the new stat info in _filecache.
798
801
799 Mercurial either atomic renames or appends for files under .hg,
802 Mercurial either atomic renames or appends for files under .hg,
800 so to ensure the cache is reliable we need the filesystem to be able
803 so to ensure the cache is reliable we need the filesystem to be able
801 to tell us if a file has been replaced. If it can't, we fallback to
804 to tell us if a file has been replaced. If it can't, we fallback to
802 recreating the object on every call (essentially the same behaviour as
805 recreating the object on every call (essentially the same behaviour as
803 propertycache).'''
806 propertycache).'''
804 def __init__(self, path, instore=False):
807 def __init__(self, path, instore=False):
805 self.path = path
808 self.path = path
806 self.instore = instore
809 self.instore = instore
807
810
808 def __call__(self, func):
811 def __call__(self, func):
809 self.func = func
812 self.func = func
810 self.name = func.__name__
813 self.name = func.__name__
811 return self
814 return self
812
815
813 def __get__(self, obj, type=None):
816 def __get__(self, obj, type=None):
814 # do we need to check if the file changed?
817 # do we need to check if the file changed?
815 if self.name in obj.__dict__:
818 if self.name in obj.__dict__:
816 return obj.__dict__[self.name]
819 return obj.__dict__[self.name]
817
820
818 entry = obj._filecache.get(self.name)
821 entry = obj._filecache.get(self.name)
819
822
820 if entry:
823 if entry:
821 if entry.changed():
824 if entry.changed():
822 entry.obj = self.func(obj)
825 entry.obj = self.func(obj)
823 else:
826 else:
824 path = self.instore and obj.sjoin(self.path) or obj.join(self.path)
827 path = self.instore and obj.sjoin(self.path) or obj.join(self.path)
825
828
826 # We stat -before- creating the object so our cache doesn't lie if
829 # We stat -before- creating the object so our cache doesn't lie if
827 # a writer modified between the time we read and stat
830 # a writer modified between the time we read and stat
828 entry = filecacheentry(path)
831 entry = filecacheentry(path)
829 entry.obj = self.func(obj)
832 entry.obj = self.func(obj)
830
833
831 obj._filecache[self.name] = entry
834 obj._filecache[self.name] = entry
832
835
833 obj.__dict__[self.name] = entry.obj
836 obj.__dict__[self.name] = entry.obj
834 return entry.obj
837 return entry.obj
835
838
836 def __set__(self, obj, value):
839 def __set__(self, obj, value):
837 if self.name in obj._filecache:
840 if self.name in obj._filecache:
838 obj._filecache[self.name].obj = value # update cached copy
841 obj._filecache[self.name].obj = value # update cached copy
839 obj.__dict__[self.name] = value # update copy returned by obj.x
842 obj.__dict__[self.name] = value # update copy returned by obj.x
840
843
841 def __delete__(self, obj):
844 def __delete__(self, obj):
842 try:
845 try:
843 del obj.__dict__[self.name]
846 del obj.__dict__[self.name]
844 except KeyError:
847 except KeyError:
845 raise AttributeError, self.name
848 raise AttributeError, self.name
@@ -1,1551 +1,1564 b''
1 @ (34) head
1 @ (34) head
2 |
2 |
3 | o (33) head
3 | o (33) head
4 | |
4 | |
5 o | (32) expand
5 o | (32) expand
6 |\ \
6 |\ \
7 | o \ (31) expand
7 | o \ (31) expand
8 | |\ \
8 | |\ \
9 | | o \ (30) expand
9 | | o \ (30) expand
10 | | |\ \
10 | | |\ \
11 | | | o | (29) regular commit
11 | | | o | (29) regular commit
12 | | | | |
12 | | | | |
13 | | o | | (28) merge zero known
13 | | o | | (28) merge zero known
14 | | |\ \ \
14 | | |\ \ \
15 o | | | | | (27) collapse
15 o | | | | | (27) collapse
16 |/ / / / /
16 |/ / / / /
17 | | o---+ (26) merge one known; far right
17 | | o---+ (26) merge one known; far right
18 | | | | |
18 | | | | |
19 +---o | | (25) merge one known; far left
19 +---o | | (25) merge one known; far left
20 | | | | |
20 | | | | |
21 | | o | | (24) merge one known; immediate right
21 | | o | | (24) merge one known; immediate right
22 | | |\| |
22 | | |\| |
23 | | o | | (23) merge one known; immediate left
23 | | o | | (23) merge one known; immediate left
24 | |/| | |
24 | |/| | |
25 +---o---+ (22) merge two known; one far left, one far right
25 +---o---+ (22) merge two known; one far left, one far right
26 | | / /
26 | | / /
27 o | | | (21) expand
27 o | | | (21) expand
28 |\ \ \ \
28 |\ \ \ \
29 | o---+-+ (20) merge two known; two far right
29 | o---+-+ (20) merge two known; two far right
30 | / / /
30 | / / /
31 o | | | (19) expand
31 o | | | (19) expand
32 |\ \ \ \
32 |\ \ \ \
33 +---+---o (18) merge two known; two far left
33 +---+---o (18) merge two known; two far left
34 | | | |
34 | | | |
35 | o | | (17) expand
35 | o | | (17) expand
36 | |\ \ \
36 | |\ \ \
37 | | o---+ (16) merge two known; one immediate right, one near right
37 | | o---+ (16) merge two known; one immediate right, one near right
38 | | |/ /
38 | | |/ /
39 o | | | (15) expand
39 o | | | (15) expand
40 |\ \ \ \
40 |\ \ \ \
41 | o-----+ (14) merge two known; one immediate right, one far right
41 | o-----+ (14) merge two known; one immediate right, one far right
42 | |/ / /
42 | |/ / /
43 o | | | (13) expand
43 o | | | (13) expand
44 |\ \ \ \
44 |\ \ \ \
45 +---o | | (12) merge two known; one immediate right, one far left
45 +---o | | (12) merge two known; one immediate right, one far left
46 | | |/ /
46 | | |/ /
47 | o | | (11) expand
47 | o | | (11) expand
48 | |\ \ \
48 | |\ \ \
49 | | o---+ (10) merge two known; one immediate left, one near right
49 | | o---+ (10) merge two known; one immediate left, one near right
50 | |/ / /
50 | |/ / /
51 o | | | (9) expand
51 o | | | (9) expand
52 |\ \ \ \
52 |\ \ \ \
53 | o-----+ (8) merge two known; one immediate left, one far right
53 | o-----+ (8) merge two known; one immediate left, one far right
54 |/ / / /
54 |/ / / /
55 o | | | (7) expand
55 o | | | (7) expand
56 |\ \ \ \
56 |\ \ \ \
57 +---o | | (6) merge two known; one immediate left, one far left
57 +---o | | (6) merge two known; one immediate left, one far left
58 | |/ / /
58 | |/ / /
59 | o | | (5) expand
59 | o | | (5) expand
60 | |\ \ \
60 | |\ \ \
61 | | o | | (4) merge two known; one immediate left, one immediate right
61 | | o | | (4) merge two known; one immediate left, one immediate right
62 | |/|/ /
62 | |/|/ /
63 | o / / (3) collapse
63 | o / / (3) collapse
64 |/ / /
64 |/ / /
65 o / / (2) collapse
65 o / / (2) collapse
66 |/ /
66 |/ /
67 o / (1) collapse
67 o / (1) collapse
68 |/
68 |/
69 o (0) root
69 o (0) root
70
70
71
71
72 $ "$TESTDIR/hghave" no-outer-repo || exit 80
72 $ "$TESTDIR/hghave" no-outer-repo || exit 80
73
73
74 $ commit()
74 $ commit()
75 > {
75 > {
76 > rev=$1
76 > rev=$1
77 > msg=$2
77 > msg=$2
78 > shift 2
78 > shift 2
79 > if [ "$#" -gt 0 ]; then
79 > if [ "$#" -gt 0 ]; then
80 > hg debugsetparents "$@"
80 > hg debugsetparents "$@"
81 > fi
81 > fi
82 > echo $rev > a
82 > echo $rev > a
83 > hg commit -Aqd "$rev 0" -m "($rev) $msg"
83 > hg commit -Aqd "$rev 0" -m "($rev) $msg"
84 > }
84 > }
85
85
86 $ cat > printrevset.py <<EOF
86 $ cat > printrevset.py <<EOF
87 > from mercurial import extensions, revset, commands
87 > from mercurial import extensions, revset, commands
88 > from hgext import graphlog
88 > from hgext import graphlog
89 >
89 >
90 > def uisetup(ui):
90 > def uisetup(ui):
91 > def printrevset(orig, ui, repo, *pats, **opts):
91 > def printrevset(orig, ui, repo, *pats, **opts):
92 > if opts.get('print_revset'):
92 > if opts.get('print_revset'):
93 > expr = graphlog.revset(repo, pats, opts)
93 > expr = graphlog.revset(repo, pats, opts)
94 > tree = revset.parse(expr)[0]
94 > tree = revset.parse(expr)[0]
95 > ui.write(tree, "\n")
95 > ui.write(tree, "\n")
96 > return 0
96 > return 0
97 > return orig(ui, repo, *pats, **opts)
97 > return orig(ui, repo, *pats, **opts)
98 > entry = extensions.wrapcommand(commands.table, 'log', printrevset)
98 > entry = extensions.wrapcommand(commands.table, 'log', printrevset)
99 > entry[1].append(('', 'print-revset', False,
99 > entry[1].append(('', 'print-revset', False,
100 > 'print generated revset and exit (DEPRECATED)'))
100 > 'print generated revset and exit (DEPRECATED)'))
101 > EOF
101 > EOF
102
102
103 $ echo "[extensions]" >> $HGRCPATH
103 $ echo "[extensions]" >> $HGRCPATH
104 $ echo "graphlog=" >> $HGRCPATH
104 $ echo "graphlog=" >> $HGRCPATH
105 $ echo "printrevset=`pwd`/printrevset.py" >> $HGRCPATH
105 $ echo "printrevset=`pwd`/printrevset.py" >> $HGRCPATH
106
106
107 $ hg init repo
107 $ hg init repo
108 $ cd repo
108 $ cd repo
109
109
110 Empty repo:
110 Empty repo:
111
111
112 $ hg glog
112 $ hg glog
113
113
114
114
115 Building DAG:
115 Building DAG:
116
116
117 $ commit 0 "root"
117 $ commit 0 "root"
118 $ commit 1 "collapse" 0
118 $ commit 1 "collapse" 0
119 $ commit 2 "collapse" 1
119 $ commit 2 "collapse" 1
120 $ commit 3 "collapse" 2
120 $ commit 3 "collapse" 2
121 $ commit 4 "merge two known; one immediate left, one immediate right" 1 3
121 $ commit 4 "merge two known; one immediate left, one immediate right" 1 3
122 $ commit 5 "expand" 3 4
122 $ commit 5 "expand" 3 4
123 $ commit 6 "merge two known; one immediate left, one far left" 2 5
123 $ commit 6 "merge two known; one immediate left, one far left" 2 5
124 $ commit 7 "expand" 2 5
124 $ commit 7 "expand" 2 5
125 $ commit 8 "merge two known; one immediate left, one far right" 0 7
125 $ commit 8 "merge two known; one immediate left, one far right" 0 7
126 $ commit 9 "expand" 7 8
126 $ commit 9 "expand" 7 8
127 $ commit 10 "merge two known; one immediate left, one near right" 0 6
127 $ commit 10 "merge two known; one immediate left, one near right" 0 6
128 $ commit 11 "expand" 6 10
128 $ commit 11 "expand" 6 10
129 $ commit 12 "merge two known; one immediate right, one far left" 1 9
129 $ commit 12 "merge two known; one immediate right, one far left" 1 9
130 $ commit 13 "expand" 9 11
130 $ commit 13 "expand" 9 11
131 $ commit 14 "merge two known; one immediate right, one far right" 0 12
131 $ commit 14 "merge two known; one immediate right, one far right" 0 12
132 $ commit 15 "expand" 13 14
132 $ commit 15 "expand" 13 14
133 $ commit 16 "merge two known; one immediate right, one near right" 0 1
133 $ commit 16 "merge two known; one immediate right, one near right" 0 1
134 $ commit 17 "expand" 12 16
134 $ commit 17 "expand" 12 16
135 $ commit 18 "merge two known; two far left" 1 15
135 $ commit 18 "merge two known; two far left" 1 15
136 $ commit 19 "expand" 15 17
136 $ commit 19 "expand" 15 17
137 $ commit 20 "merge two known; two far right" 0 18
137 $ commit 20 "merge two known; two far right" 0 18
138 $ commit 21 "expand" 19 20
138 $ commit 21 "expand" 19 20
139 $ commit 22 "merge two known; one far left, one far right" 18 21
139 $ commit 22 "merge two known; one far left, one far right" 18 21
140 $ commit 23 "merge one known; immediate left" 1 22
140 $ commit 23 "merge one known; immediate left" 1 22
141 $ commit 24 "merge one known; immediate right" 0 23
141 $ commit 24 "merge one known; immediate right" 0 23
142 $ commit 25 "merge one known; far left" 21 24
142 $ commit 25 "merge one known; far left" 21 24
143 $ commit 26 "merge one known; far right" 18 25
143 $ commit 26 "merge one known; far right" 18 25
144 $ commit 27 "collapse" 21
144 $ commit 27 "collapse" 21
145 $ commit 28 "merge zero known" 1 26
145 $ commit 28 "merge zero known" 1 26
146 $ commit 29 "regular commit" 0
146 $ commit 29 "regular commit" 0
147 $ commit 30 "expand" 28 29
147 $ commit 30 "expand" 28 29
148 $ commit 31 "expand" 21 30
148 $ commit 31 "expand" 21 30
149 $ commit 32 "expand" 27 31
149 $ commit 32 "expand" 27 31
150 $ commit 33 "head" 18
150 $ commit 33 "head" 18
151 $ commit 34 "head" 32
151 $ commit 34 "head" 32
152
152
153
153
154 $ hg glog -q
154 $ hg glog -q
155 @ 34:fea3ac5810e0
155 @ 34:fea3ac5810e0
156 |
156 |
157 | o 33:68608f5145f9
157 | o 33:68608f5145f9
158 | |
158 | |
159 o | 32:d06dffa21a31
159 o | 32:d06dffa21a31
160 |\ \
160 |\ \
161 | o \ 31:621d83e11f67
161 | o \ 31:621d83e11f67
162 | |\ \
162 | |\ \
163 | | o \ 30:6e11cd4b648f
163 | | o \ 30:6e11cd4b648f
164 | | |\ \
164 | | |\ \
165 | | | o | 29:cd9bb2be7593
165 | | | o | 29:cd9bb2be7593
166 | | | | |
166 | | | | |
167 | | o | | 28:44ecd0b9ae99
167 | | o | | 28:44ecd0b9ae99
168 | | |\ \ \
168 | | |\ \ \
169 o | | | | | 27:886ed638191b
169 o | | | | | 27:886ed638191b
170 |/ / / / /
170 |/ / / / /
171 | | o---+ 26:7f25b6c2f0b9
171 | | o---+ 26:7f25b6c2f0b9
172 | | | | |
172 | | | | |
173 +---o | | 25:91da8ed57247
173 +---o | | 25:91da8ed57247
174 | | | | |
174 | | | | |
175 | | o | | 24:a9c19a3d96b7
175 | | o | | 24:a9c19a3d96b7
176 | | |\| |
176 | | |\| |
177 | | o | | 23:a01cddf0766d
177 | | o | | 23:a01cddf0766d
178 | |/| | |
178 | |/| | |
179 +---o---+ 22:e0d9cccacb5d
179 +---o---+ 22:e0d9cccacb5d
180 | | / /
180 | | / /
181 o | | | 21:d42a756af44d
181 o | | | 21:d42a756af44d
182 |\ \ \ \
182 |\ \ \ \
183 | o---+-+ 20:d30ed6450e32
183 | o---+-+ 20:d30ed6450e32
184 | / / /
184 | / / /
185 o | | | 19:31ddc2c1573b
185 o | | | 19:31ddc2c1573b
186 |\ \ \ \
186 |\ \ \ \
187 +---+---o 18:1aa84d96232a
187 +---+---o 18:1aa84d96232a
188 | | | |
188 | | | |
189 | o | | 17:44765d7c06e0
189 | o | | 17:44765d7c06e0
190 | |\ \ \
190 | |\ \ \
191 | | o---+ 16:3677d192927d
191 | | o---+ 16:3677d192927d
192 | | |/ /
192 | | |/ /
193 o | | | 15:1dda3f72782d
193 o | | | 15:1dda3f72782d
194 |\ \ \ \
194 |\ \ \ \
195 | o-----+ 14:8eac370358ef
195 | o-----+ 14:8eac370358ef
196 | |/ / /
196 | |/ / /
197 o | | | 13:22d8966a97e3
197 o | | | 13:22d8966a97e3
198 |\ \ \ \
198 |\ \ \ \
199 +---o | | 12:86b91144a6e9
199 +---o | | 12:86b91144a6e9
200 | | |/ /
200 | | |/ /
201 | o | | 11:832d76e6bdf2
201 | o | | 11:832d76e6bdf2
202 | |\ \ \
202 | |\ \ \
203 | | o---+ 10:74c64d036d72
203 | | o---+ 10:74c64d036d72
204 | |/ / /
204 | |/ / /
205 o | | | 9:7010c0af0a35
205 o | | | 9:7010c0af0a35
206 |\ \ \ \
206 |\ \ \ \
207 | o-----+ 8:7a0b11f71937
207 | o-----+ 8:7a0b11f71937
208 |/ / / /
208 |/ / / /
209 o | | | 7:b632bb1b1224
209 o | | | 7:b632bb1b1224
210 |\ \ \ \
210 |\ \ \ \
211 +---o | | 6:b105a072e251
211 +---o | | 6:b105a072e251
212 | |/ / /
212 | |/ / /
213 | o | | 5:4409d547b708
213 | o | | 5:4409d547b708
214 | |\ \ \
214 | |\ \ \
215 | | o | | 4:26a8bac39d9f
215 | | o | | 4:26a8bac39d9f
216 | |/|/ /
216 | |/|/ /
217 | o / / 3:27eef8ed80b4
217 | o / / 3:27eef8ed80b4
218 |/ / /
218 |/ / /
219 o / / 2:3d9a33b8d1e1
219 o / / 2:3d9a33b8d1e1
220 |/ /
220 |/ /
221 o / 1:6db2ef61d156
221 o / 1:6db2ef61d156
222 |/
222 |/
223 o 0:e6eb3150255d
223 o 0:e6eb3150255d
224
224
225
225
226 $ hg glog
226 $ hg glog
227 @ changeset: 34:fea3ac5810e0
227 @ changeset: 34:fea3ac5810e0
228 | tag: tip
228 | tag: tip
229 | parent: 32:d06dffa21a31
229 | parent: 32:d06dffa21a31
230 | user: test
230 | user: test
231 | date: Thu Jan 01 00:00:34 1970 +0000
231 | date: Thu Jan 01 00:00:34 1970 +0000
232 | summary: (34) head
232 | summary: (34) head
233 |
233 |
234 | o changeset: 33:68608f5145f9
234 | o changeset: 33:68608f5145f9
235 | | parent: 18:1aa84d96232a
235 | | parent: 18:1aa84d96232a
236 | | user: test
236 | | user: test
237 | | date: Thu Jan 01 00:00:33 1970 +0000
237 | | date: Thu Jan 01 00:00:33 1970 +0000
238 | | summary: (33) head
238 | | summary: (33) head
239 | |
239 | |
240 o | changeset: 32:d06dffa21a31
240 o | changeset: 32:d06dffa21a31
241 |\ \ parent: 27:886ed638191b
241 |\ \ parent: 27:886ed638191b
242 | | | parent: 31:621d83e11f67
242 | | | parent: 31:621d83e11f67
243 | | | user: test
243 | | | user: test
244 | | | date: Thu Jan 01 00:00:32 1970 +0000
244 | | | date: Thu Jan 01 00:00:32 1970 +0000
245 | | | summary: (32) expand
245 | | | summary: (32) expand
246 | | |
246 | | |
247 | o | changeset: 31:621d83e11f67
247 | o | changeset: 31:621d83e11f67
248 | |\ \ parent: 21:d42a756af44d
248 | |\ \ parent: 21:d42a756af44d
249 | | | | parent: 30:6e11cd4b648f
249 | | | | parent: 30:6e11cd4b648f
250 | | | | user: test
250 | | | | user: test
251 | | | | date: Thu Jan 01 00:00:31 1970 +0000
251 | | | | date: Thu Jan 01 00:00:31 1970 +0000
252 | | | | summary: (31) expand
252 | | | | summary: (31) expand
253 | | | |
253 | | | |
254 | | o | changeset: 30:6e11cd4b648f
254 | | o | changeset: 30:6e11cd4b648f
255 | | |\ \ parent: 28:44ecd0b9ae99
255 | | |\ \ parent: 28:44ecd0b9ae99
256 | | | | | parent: 29:cd9bb2be7593
256 | | | | | parent: 29:cd9bb2be7593
257 | | | | | user: test
257 | | | | | user: test
258 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
258 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
259 | | | | | summary: (30) expand
259 | | | | | summary: (30) expand
260 | | | | |
260 | | | | |
261 | | | o | changeset: 29:cd9bb2be7593
261 | | | o | changeset: 29:cd9bb2be7593
262 | | | | | parent: 0:e6eb3150255d
262 | | | | | parent: 0:e6eb3150255d
263 | | | | | user: test
263 | | | | | user: test
264 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
264 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
265 | | | | | summary: (29) regular commit
265 | | | | | summary: (29) regular commit
266 | | | | |
266 | | | | |
267 | | o | | changeset: 28:44ecd0b9ae99
267 | | o | | changeset: 28:44ecd0b9ae99
268 | | |\ \ \ parent: 1:6db2ef61d156
268 | | |\ \ \ parent: 1:6db2ef61d156
269 | | | | | | parent: 26:7f25b6c2f0b9
269 | | | | | | parent: 26:7f25b6c2f0b9
270 | | | | | | user: test
270 | | | | | | user: test
271 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
271 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
272 | | | | | | summary: (28) merge zero known
272 | | | | | | summary: (28) merge zero known
273 | | | | | |
273 | | | | | |
274 o | | | | | changeset: 27:886ed638191b
274 o | | | | | changeset: 27:886ed638191b
275 |/ / / / / parent: 21:d42a756af44d
275 |/ / / / / parent: 21:d42a756af44d
276 | | | | | user: test
276 | | | | | user: test
277 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
277 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
278 | | | | | summary: (27) collapse
278 | | | | | summary: (27) collapse
279 | | | | |
279 | | | | |
280 | | o---+ changeset: 26:7f25b6c2f0b9
280 | | o---+ changeset: 26:7f25b6c2f0b9
281 | | | | | parent: 18:1aa84d96232a
281 | | | | | parent: 18:1aa84d96232a
282 | | | | | parent: 25:91da8ed57247
282 | | | | | parent: 25:91da8ed57247
283 | | | | | user: test
283 | | | | | user: test
284 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
284 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
285 | | | | | summary: (26) merge one known; far right
285 | | | | | summary: (26) merge one known; far right
286 | | | | |
286 | | | | |
287 +---o | | changeset: 25:91da8ed57247
287 +---o | | changeset: 25:91da8ed57247
288 | | | | | parent: 21:d42a756af44d
288 | | | | | parent: 21:d42a756af44d
289 | | | | | parent: 24:a9c19a3d96b7
289 | | | | | parent: 24:a9c19a3d96b7
290 | | | | | user: test
290 | | | | | user: test
291 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
291 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
292 | | | | | summary: (25) merge one known; far left
292 | | | | | summary: (25) merge one known; far left
293 | | | | |
293 | | | | |
294 | | o | | changeset: 24:a9c19a3d96b7
294 | | o | | changeset: 24:a9c19a3d96b7
295 | | |\| | parent: 0:e6eb3150255d
295 | | |\| | parent: 0:e6eb3150255d
296 | | | | | parent: 23:a01cddf0766d
296 | | | | | parent: 23:a01cddf0766d
297 | | | | | user: test
297 | | | | | user: test
298 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
298 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
299 | | | | | summary: (24) merge one known; immediate right
299 | | | | | summary: (24) merge one known; immediate right
300 | | | | |
300 | | | | |
301 | | o | | changeset: 23:a01cddf0766d
301 | | o | | changeset: 23:a01cddf0766d
302 | |/| | | parent: 1:6db2ef61d156
302 | |/| | | parent: 1:6db2ef61d156
303 | | | | | parent: 22:e0d9cccacb5d
303 | | | | | parent: 22:e0d9cccacb5d
304 | | | | | user: test
304 | | | | | user: test
305 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
305 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
306 | | | | | summary: (23) merge one known; immediate left
306 | | | | | summary: (23) merge one known; immediate left
307 | | | | |
307 | | | | |
308 +---o---+ changeset: 22:e0d9cccacb5d
308 +---o---+ changeset: 22:e0d9cccacb5d
309 | | | | parent: 18:1aa84d96232a
309 | | | | parent: 18:1aa84d96232a
310 | | / / parent: 21:d42a756af44d
310 | | / / parent: 21:d42a756af44d
311 | | | | user: test
311 | | | | user: test
312 | | | | date: Thu Jan 01 00:00:22 1970 +0000
312 | | | | date: Thu Jan 01 00:00:22 1970 +0000
313 | | | | summary: (22) merge two known; one far left, one far right
313 | | | | summary: (22) merge two known; one far left, one far right
314 | | | |
314 | | | |
315 o | | | changeset: 21:d42a756af44d
315 o | | | changeset: 21:d42a756af44d
316 |\ \ \ \ parent: 19:31ddc2c1573b
316 |\ \ \ \ parent: 19:31ddc2c1573b
317 | | | | | parent: 20:d30ed6450e32
317 | | | | | parent: 20:d30ed6450e32
318 | | | | | user: test
318 | | | | | user: test
319 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
319 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
320 | | | | | summary: (21) expand
320 | | | | | summary: (21) expand
321 | | | | |
321 | | | | |
322 | o---+-+ changeset: 20:d30ed6450e32
322 | o---+-+ changeset: 20:d30ed6450e32
323 | | | | parent: 0:e6eb3150255d
323 | | | | parent: 0:e6eb3150255d
324 | / / / parent: 18:1aa84d96232a
324 | / / / parent: 18:1aa84d96232a
325 | | | | user: test
325 | | | | user: test
326 | | | | date: Thu Jan 01 00:00:20 1970 +0000
326 | | | | date: Thu Jan 01 00:00:20 1970 +0000
327 | | | | summary: (20) merge two known; two far right
327 | | | | summary: (20) merge two known; two far right
328 | | | |
328 | | | |
329 o | | | changeset: 19:31ddc2c1573b
329 o | | | changeset: 19:31ddc2c1573b
330 |\ \ \ \ parent: 15:1dda3f72782d
330 |\ \ \ \ parent: 15:1dda3f72782d
331 | | | | | parent: 17:44765d7c06e0
331 | | | | | parent: 17:44765d7c06e0
332 | | | | | user: test
332 | | | | | user: test
333 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
333 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
334 | | | | | summary: (19) expand
334 | | | | | summary: (19) expand
335 | | | | |
335 | | | | |
336 +---+---o changeset: 18:1aa84d96232a
336 +---+---o changeset: 18:1aa84d96232a
337 | | | | parent: 1:6db2ef61d156
337 | | | | parent: 1:6db2ef61d156
338 | | | | parent: 15:1dda3f72782d
338 | | | | parent: 15:1dda3f72782d
339 | | | | user: test
339 | | | | user: test
340 | | | | date: Thu Jan 01 00:00:18 1970 +0000
340 | | | | date: Thu Jan 01 00:00:18 1970 +0000
341 | | | | summary: (18) merge two known; two far left
341 | | | | summary: (18) merge two known; two far left
342 | | | |
342 | | | |
343 | o | | changeset: 17:44765d7c06e0
343 | o | | changeset: 17:44765d7c06e0
344 | |\ \ \ parent: 12:86b91144a6e9
344 | |\ \ \ parent: 12:86b91144a6e9
345 | | | | | parent: 16:3677d192927d
345 | | | | | parent: 16:3677d192927d
346 | | | | | user: test
346 | | | | | user: test
347 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
347 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
348 | | | | | summary: (17) expand
348 | | | | | summary: (17) expand
349 | | | | |
349 | | | | |
350 | | o---+ changeset: 16:3677d192927d
350 | | o---+ changeset: 16:3677d192927d
351 | | | | | parent: 0:e6eb3150255d
351 | | | | | parent: 0:e6eb3150255d
352 | | |/ / parent: 1:6db2ef61d156
352 | | |/ / parent: 1:6db2ef61d156
353 | | | | user: test
353 | | | | user: test
354 | | | | date: Thu Jan 01 00:00:16 1970 +0000
354 | | | | date: Thu Jan 01 00:00:16 1970 +0000
355 | | | | summary: (16) merge two known; one immediate right, one near right
355 | | | | summary: (16) merge two known; one immediate right, one near right
356 | | | |
356 | | | |
357 o | | | changeset: 15:1dda3f72782d
357 o | | | changeset: 15:1dda3f72782d
358 |\ \ \ \ parent: 13:22d8966a97e3
358 |\ \ \ \ parent: 13:22d8966a97e3
359 | | | | | parent: 14:8eac370358ef
359 | | | | | parent: 14:8eac370358ef
360 | | | | | user: test
360 | | | | | user: test
361 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
361 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
362 | | | | | summary: (15) expand
362 | | | | | summary: (15) expand
363 | | | | |
363 | | | | |
364 | o-----+ changeset: 14:8eac370358ef
364 | o-----+ changeset: 14:8eac370358ef
365 | | | | | parent: 0:e6eb3150255d
365 | | | | | parent: 0:e6eb3150255d
366 | |/ / / parent: 12:86b91144a6e9
366 | |/ / / parent: 12:86b91144a6e9
367 | | | | user: test
367 | | | | user: test
368 | | | | date: Thu Jan 01 00:00:14 1970 +0000
368 | | | | date: Thu Jan 01 00:00:14 1970 +0000
369 | | | | summary: (14) merge two known; one immediate right, one far right
369 | | | | summary: (14) merge two known; one immediate right, one far right
370 | | | |
370 | | | |
371 o | | | changeset: 13:22d8966a97e3
371 o | | | changeset: 13:22d8966a97e3
372 |\ \ \ \ parent: 9:7010c0af0a35
372 |\ \ \ \ parent: 9:7010c0af0a35
373 | | | | | parent: 11:832d76e6bdf2
373 | | | | | parent: 11:832d76e6bdf2
374 | | | | | user: test
374 | | | | | user: test
375 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
375 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
376 | | | | | summary: (13) expand
376 | | | | | summary: (13) expand
377 | | | | |
377 | | | | |
378 +---o | | changeset: 12:86b91144a6e9
378 +---o | | changeset: 12:86b91144a6e9
379 | | |/ / parent: 1:6db2ef61d156
379 | | |/ / parent: 1:6db2ef61d156
380 | | | | parent: 9:7010c0af0a35
380 | | | | parent: 9:7010c0af0a35
381 | | | | user: test
381 | | | | user: test
382 | | | | date: Thu Jan 01 00:00:12 1970 +0000
382 | | | | date: Thu Jan 01 00:00:12 1970 +0000
383 | | | | summary: (12) merge two known; one immediate right, one far left
383 | | | | summary: (12) merge two known; one immediate right, one far left
384 | | | |
384 | | | |
385 | o | | changeset: 11:832d76e6bdf2
385 | o | | changeset: 11:832d76e6bdf2
386 | |\ \ \ parent: 6:b105a072e251
386 | |\ \ \ parent: 6:b105a072e251
387 | | | | | parent: 10:74c64d036d72
387 | | | | | parent: 10:74c64d036d72
388 | | | | | user: test
388 | | | | | user: test
389 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
389 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
390 | | | | | summary: (11) expand
390 | | | | | summary: (11) expand
391 | | | | |
391 | | | | |
392 | | o---+ changeset: 10:74c64d036d72
392 | | o---+ changeset: 10:74c64d036d72
393 | | | | | parent: 0:e6eb3150255d
393 | | | | | parent: 0:e6eb3150255d
394 | |/ / / parent: 6:b105a072e251
394 | |/ / / parent: 6:b105a072e251
395 | | | | user: test
395 | | | | user: test
396 | | | | date: Thu Jan 01 00:00:10 1970 +0000
396 | | | | date: Thu Jan 01 00:00:10 1970 +0000
397 | | | | summary: (10) merge two known; one immediate left, one near right
397 | | | | summary: (10) merge two known; one immediate left, one near right
398 | | | |
398 | | | |
399 o | | | changeset: 9:7010c0af0a35
399 o | | | changeset: 9:7010c0af0a35
400 |\ \ \ \ parent: 7:b632bb1b1224
400 |\ \ \ \ parent: 7:b632bb1b1224
401 | | | | | parent: 8:7a0b11f71937
401 | | | | | parent: 8:7a0b11f71937
402 | | | | | user: test
402 | | | | | user: test
403 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
403 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
404 | | | | | summary: (9) expand
404 | | | | | summary: (9) expand
405 | | | | |
405 | | | | |
406 | o-----+ changeset: 8:7a0b11f71937
406 | o-----+ changeset: 8:7a0b11f71937
407 | | | | | parent: 0:e6eb3150255d
407 | | | | | parent: 0:e6eb3150255d
408 |/ / / / parent: 7:b632bb1b1224
408 |/ / / / parent: 7:b632bb1b1224
409 | | | | user: test
409 | | | | user: test
410 | | | | date: Thu Jan 01 00:00:08 1970 +0000
410 | | | | date: Thu Jan 01 00:00:08 1970 +0000
411 | | | | summary: (8) merge two known; one immediate left, one far right
411 | | | | summary: (8) merge two known; one immediate left, one far right
412 | | | |
412 | | | |
413 o | | | changeset: 7:b632bb1b1224
413 o | | | changeset: 7:b632bb1b1224
414 |\ \ \ \ parent: 2:3d9a33b8d1e1
414 |\ \ \ \ parent: 2:3d9a33b8d1e1
415 | | | | | parent: 5:4409d547b708
415 | | | | | parent: 5:4409d547b708
416 | | | | | user: test
416 | | | | | user: test
417 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
417 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
418 | | | | | summary: (7) expand
418 | | | | | summary: (7) expand
419 | | | | |
419 | | | | |
420 +---o | | changeset: 6:b105a072e251
420 +---o | | changeset: 6:b105a072e251
421 | |/ / / parent: 2:3d9a33b8d1e1
421 | |/ / / parent: 2:3d9a33b8d1e1
422 | | | | parent: 5:4409d547b708
422 | | | | parent: 5:4409d547b708
423 | | | | user: test
423 | | | | user: test
424 | | | | date: Thu Jan 01 00:00:06 1970 +0000
424 | | | | date: Thu Jan 01 00:00:06 1970 +0000
425 | | | | summary: (6) merge two known; one immediate left, one far left
425 | | | | summary: (6) merge two known; one immediate left, one far left
426 | | | |
426 | | | |
427 | o | | changeset: 5:4409d547b708
427 | o | | changeset: 5:4409d547b708
428 | |\ \ \ parent: 3:27eef8ed80b4
428 | |\ \ \ parent: 3:27eef8ed80b4
429 | | | | | parent: 4:26a8bac39d9f
429 | | | | | parent: 4:26a8bac39d9f
430 | | | | | user: test
430 | | | | | user: test
431 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
431 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
432 | | | | | summary: (5) expand
432 | | | | | summary: (5) expand
433 | | | | |
433 | | | | |
434 | | o | | changeset: 4:26a8bac39d9f
434 | | o | | changeset: 4:26a8bac39d9f
435 | |/|/ / parent: 1:6db2ef61d156
435 | |/|/ / parent: 1:6db2ef61d156
436 | | | | parent: 3:27eef8ed80b4
436 | | | | parent: 3:27eef8ed80b4
437 | | | | user: test
437 | | | | user: test
438 | | | | date: Thu Jan 01 00:00:04 1970 +0000
438 | | | | date: Thu Jan 01 00:00:04 1970 +0000
439 | | | | summary: (4) merge two known; one immediate left, one immediate right
439 | | | | summary: (4) merge two known; one immediate left, one immediate right
440 | | | |
440 | | | |
441 | o | | changeset: 3:27eef8ed80b4
441 | o | | changeset: 3:27eef8ed80b4
442 |/ / / user: test
442 |/ / / user: test
443 | | | date: Thu Jan 01 00:00:03 1970 +0000
443 | | | date: Thu Jan 01 00:00:03 1970 +0000
444 | | | summary: (3) collapse
444 | | | summary: (3) collapse
445 | | |
445 | | |
446 o | | changeset: 2:3d9a33b8d1e1
446 o | | changeset: 2:3d9a33b8d1e1
447 |/ / user: test
447 |/ / user: test
448 | | date: Thu Jan 01 00:00:02 1970 +0000
448 | | date: Thu Jan 01 00:00:02 1970 +0000
449 | | summary: (2) collapse
449 | | summary: (2) collapse
450 | |
450 | |
451 o | changeset: 1:6db2ef61d156
451 o | changeset: 1:6db2ef61d156
452 |/ user: test
452 |/ user: test
453 | date: Thu Jan 01 00:00:01 1970 +0000
453 | date: Thu Jan 01 00:00:01 1970 +0000
454 | summary: (1) collapse
454 | summary: (1) collapse
455 |
455 |
456 o changeset: 0:e6eb3150255d
456 o changeset: 0:e6eb3150255d
457 user: test
457 user: test
458 date: Thu Jan 01 00:00:00 1970 +0000
458 date: Thu Jan 01 00:00:00 1970 +0000
459 summary: (0) root
459 summary: (0) root
460
460
461
461
462 File glog:
462 File glog:
463 $ hg glog a
463 $ hg glog a
464 @ changeset: 34:fea3ac5810e0
464 @ changeset: 34:fea3ac5810e0
465 | tag: tip
465 | tag: tip
466 | parent: 32:d06dffa21a31
466 | parent: 32:d06dffa21a31
467 | user: test
467 | user: test
468 | date: Thu Jan 01 00:00:34 1970 +0000
468 | date: Thu Jan 01 00:00:34 1970 +0000
469 | summary: (34) head
469 | summary: (34) head
470 |
470 |
471 | o changeset: 33:68608f5145f9
471 | o changeset: 33:68608f5145f9
472 | | parent: 18:1aa84d96232a
472 | | parent: 18:1aa84d96232a
473 | | user: test
473 | | user: test
474 | | date: Thu Jan 01 00:00:33 1970 +0000
474 | | date: Thu Jan 01 00:00:33 1970 +0000
475 | | summary: (33) head
475 | | summary: (33) head
476 | |
476 | |
477 o | changeset: 32:d06dffa21a31
477 o | changeset: 32:d06dffa21a31
478 |\ \ parent: 27:886ed638191b
478 |\ \ parent: 27:886ed638191b
479 | | | parent: 31:621d83e11f67
479 | | | parent: 31:621d83e11f67
480 | | | user: test
480 | | | user: test
481 | | | date: Thu Jan 01 00:00:32 1970 +0000
481 | | | date: Thu Jan 01 00:00:32 1970 +0000
482 | | | summary: (32) expand
482 | | | summary: (32) expand
483 | | |
483 | | |
484 | o | changeset: 31:621d83e11f67
484 | o | changeset: 31:621d83e11f67
485 | |\ \ parent: 21:d42a756af44d
485 | |\ \ parent: 21:d42a756af44d
486 | | | | parent: 30:6e11cd4b648f
486 | | | | parent: 30:6e11cd4b648f
487 | | | | user: test
487 | | | | user: test
488 | | | | date: Thu Jan 01 00:00:31 1970 +0000
488 | | | | date: Thu Jan 01 00:00:31 1970 +0000
489 | | | | summary: (31) expand
489 | | | | summary: (31) expand
490 | | | |
490 | | | |
491 | | o | changeset: 30:6e11cd4b648f
491 | | o | changeset: 30:6e11cd4b648f
492 | | |\ \ parent: 28:44ecd0b9ae99
492 | | |\ \ parent: 28:44ecd0b9ae99
493 | | | | | parent: 29:cd9bb2be7593
493 | | | | | parent: 29:cd9bb2be7593
494 | | | | | user: test
494 | | | | | user: test
495 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
495 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
496 | | | | | summary: (30) expand
496 | | | | | summary: (30) expand
497 | | | | |
497 | | | | |
498 | | | o | changeset: 29:cd9bb2be7593
498 | | | o | changeset: 29:cd9bb2be7593
499 | | | | | parent: 0:e6eb3150255d
499 | | | | | parent: 0:e6eb3150255d
500 | | | | | user: test
500 | | | | | user: test
501 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
501 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
502 | | | | | summary: (29) regular commit
502 | | | | | summary: (29) regular commit
503 | | | | |
503 | | | | |
504 | | o | | changeset: 28:44ecd0b9ae99
504 | | o | | changeset: 28:44ecd0b9ae99
505 | | |\ \ \ parent: 1:6db2ef61d156
505 | | |\ \ \ parent: 1:6db2ef61d156
506 | | | | | | parent: 26:7f25b6c2f0b9
506 | | | | | | parent: 26:7f25b6c2f0b9
507 | | | | | | user: test
507 | | | | | | user: test
508 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
508 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
509 | | | | | | summary: (28) merge zero known
509 | | | | | | summary: (28) merge zero known
510 | | | | | |
510 | | | | | |
511 o | | | | | changeset: 27:886ed638191b
511 o | | | | | changeset: 27:886ed638191b
512 |/ / / / / parent: 21:d42a756af44d
512 |/ / / / / parent: 21:d42a756af44d
513 | | | | | user: test
513 | | | | | user: test
514 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
514 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
515 | | | | | summary: (27) collapse
515 | | | | | summary: (27) collapse
516 | | | | |
516 | | | | |
517 | | o---+ changeset: 26:7f25b6c2f0b9
517 | | o---+ changeset: 26:7f25b6c2f0b9
518 | | | | | parent: 18:1aa84d96232a
518 | | | | | parent: 18:1aa84d96232a
519 | | | | | parent: 25:91da8ed57247
519 | | | | | parent: 25:91da8ed57247
520 | | | | | user: test
520 | | | | | user: test
521 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
521 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
522 | | | | | summary: (26) merge one known; far right
522 | | | | | summary: (26) merge one known; far right
523 | | | | |
523 | | | | |
524 +---o | | changeset: 25:91da8ed57247
524 +---o | | changeset: 25:91da8ed57247
525 | | | | | parent: 21:d42a756af44d
525 | | | | | parent: 21:d42a756af44d
526 | | | | | parent: 24:a9c19a3d96b7
526 | | | | | parent: 24:a9c19a3d96b7
527 | | | | | user: test
527 | | | | | user: test
528 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
528 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
529 | | | | | summary: (25) merge one known; far left
529 | | | | | summary: (25) merge one known; far left
530 | | | | |
530 | | | | |
531 | | o | | changeset: 24:a9c19a3d96b7
531 | | o | | changeset: 24:a9c19a3d96b7
532 | | |\| | parent: 0:e6eb3150255d
532 | | |\| | parent: 0:e6eb3150255d
533 | | | | | parent: 23:a01cddf0766d
533 | | | | | parent: 23:a01cddf0766d
534 | | | | | user: test
534 | | | | | user: test
535 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
535 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
536 | | | | | summary: (24) merge one known; immediate right
536 | | | | | summary: (24) merge one known; immediate right
537 | | | | |
537 | | | | |
538 | | o | | changeset: 23:a01cddf0766d
538 | | o | | changeset: 23:a01cddf0766d
539 | |/| | | parent: 1:6db2ef61d156
539 | |/| | | parent: 1:6db2ef61d156
540 | | | | | parent: 22:e0d9cccacb5d
540 | | | | | parent: 22:e0d9cccacb5d
541 | | | | | user: test
541 | | | | | user: test
542 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
542 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
543 | | | | | summary: (23) merge one known; immediate left
543 | | | | | summary: (23) merge one known; immediate left
544 | | | | |
544 | | | | |
545 +---o---+ changeset: 22:e0d9cccacb5d
545 +---o---+ changeset: 22:e0d9cccacb5d
546 | | | | parent: 18:1aa84d96232a
546 | | | | parent: 18:1aa84d96232a
547 | | / / parent: 21:d42a756af44d
547 | | / / parent: 21:d42a756af44d
548 | | | | user: test
548 | | | | user: test
549 | | | | date: Thu Jan 01 00:00:22 1970 +0000
549 | | | | date: Thu Jan 01 00:00:22 1970 +0000
550 | | | | summary: (22) merge two known; one far left, one far right
550 | | | | summary: (22) merge two known; one far left, one far right
551 | | | |
551 | | | |
552 o | | | changeset: 21:d42a756af44d
552 o | | | changeset: 21:d42a756af44d
553 |\ \ \ \ parent: 19:31ddc2c1573b
553 |\ \ \ \ parent: 19:31ddc2c1573b
554 | | | | | parent: 20:d30ed6450e32
554 | | | | | parent: 20:d30ed6450e32
555 | | | | | user: test
555 | | | | | user: test
556 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
556 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
557 | | | | | summary: (21) expand
557 | | | | | summary: (21) expand
558 | | | | |
558 | | | | |
559 | o---+-+ changeset: 20:d30ed6450e32
559 | o---+-+ changeset: 20:d30ed6450e32
560 | | | | parent: 0:e6eb3150255d
560 | | | | parent: 0:e6eb3150255d
561 | / / / parent: 18:1aa84d96232a
561 | / / / parent: 18:1aa84d96232a
562 | | | | user: test
562 | | | | user: test
563 | | | | date: Thu Jan 01 00:00:20 1970 +0000
563 | | | | date: Thu Jan 01 00:00:20 1970 +0000
564 | | | | summary: (20) merge two known; two far right
564 | | | | summary: (20) merge two known; two far right
565 | | | |
565 | | | |
566 o | | | changeset: 19:31ddc2c1573b
566 o | | | changeset: 19:31ddc2c1573b
567 |\ \ \ \ parent: 15:1dda3f72782d
567 |\ \ \ \ parent: 15:1dda3f72782d
568 | | | | | parent: 17:44765d7c06e0
568 | | | | | parent: 17:44765d7c06e0
569 | | | | | user: test
569 | | | | | user: test
570 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
570 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
571 | | | | | summary: (19) expand
571 | | | | | summary: (19) expand
572 | | | | |
572 | | | | |
573 +---+---o changeset: 18:1aa84d96232a
573 +---+---o changeset: 18:1aa84d96232a
574 | | | | parent: 1:6db2ef61d156
574 | | | | parent: 1:6db2ef61d156
575 | | | | parent: 15:1dda3f72782d
575 | | | | parent: 15:1dda3f72782d
576 | | | | user: test
576 | | | | user: test
577 | | | | date: Thu Jan 01 00:00:18 1970 +0000
577 | | | | date: Thu Jan 01 00:00:18 1970 +0000
578 | | | | summary: (18) merge two known; two far left
578 | | | | summary: (18) merge two known; two far left
579 | | | |
579 | | | |
580 | o | | changeset: 17:44765d7c06e0
580 | o | | changeset: 17:44765d7c06e0
581 | |\ \ \ parent: 12:86b91144a6e9
581 | |\ \ \ parent: 12:86b91144a6e9
582 | | | | | parent: 16:3677d192927d
582 | | | | | parent: 16:3677d192927d
583 | | | | | user: test
583 | | | | | user: test
584 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
584 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
585 | | | | | summary: (17) expand
585 | | | | | summary: (17) expand
586 | | | | |
586 | | | | |
587 | | o---+ changeset: 16:3677d192927d
587 | | o---+ changeset: 16:3677d192927d
588 | | | | | parent: 0:e6eb3150255d
588 | | | | | parent: 0:e6eb3150255d
589 | | |/ / parent: 1:6db2ef61d156
589 | | |/ / parent: 1:6db2ef61d156
590 | | | | user: test
590 | | | | user: test
591 | | | | date: Thu Jan 01 00:00:16 1970 +0000
591 | | | | date: Thu Jan 01 00:00:16 1970 +0000
592 | | | | summary: (16) merge two known; one immediate right, one near right
592 | | | | summary: (16) merge two known; one immediate right, one near right
593 | | | |
593 | | | |
594 o | | | changeset: 15:1dda3f72782d
594 o | | | changeset: 15:1dda3f72782d
595 |\ \ \ \ parent: 13:22d8966a97e3
595 |\ \ \ \ parent: 13:22d8966a97e3
596 | | | | | parent: 14:8eac370358ef
596 | | | | | parent: 14:8eac370358ef
597 | | | | | user: test
597 | | | | | user: test
598 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
598 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
599 | | | | | summary: (15) expand
599 | | | | | summary: (15) expand
600 | | | | |
600 | | | | |
601 | o-----+ changeset: 14:8eac370358ef
601 | o-----+ changeset: 14:8eac370358ef
602 | | | | | parent: 0:e6eb3150255d
602 | | | | | parent: 0:e6eb3150255d
603 | |/ / / parent: 12:86b91144a6e9
603 | |/ / / parent: 12:86b91144a6e9
604 | | | | user: test
604 | | | | user: test
605 | | | | date: Thu Jan 01 00:00:14 1970 +0000
605 | | | | date: Thu Jan 01 00:00:14 1970 +0000
606 | | | | summary: (14) merge two known; one immediate right, one far right
606 | | | | summary: (14) merge two known; one immediate right, one far right
607 | | | |
607 | | | |
608 o | | | changeset: 13:22d8966a97e3
608 o | | | changeset: 13:22d8966a97e3
609 |\ \ \ \ parent: 9:7010c0af0a35
609 |\ \ \ \ parent: 9:7010c0af0a35
610 | | | | | parent: 11:832d76e6bdf2
610 | | | | | parent: 11:832d76e6bdf2
611 | | | | | user: test
611 | | | | | user: test
612 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
612 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
613 | | | | | summary: (13) expand
613 | | | | | summary: (13) expand
614 | | | | |
614 | | | | |
615 +---o | | changeset: 12:86b91144a6e9
615 +---o | | changeset: 12:86b91144a6e9
616 | | |/ / parent: 1:6db2ef61d156
616 | | |/ / parent: 1:6db2ef61d156
617 | | | | parent: 9:7010c0af0a35
617 | | | | parent: 9:7010c0af0a35
618 | | | | user: test
618 | | | | user: test
619 | | | | date: Thu Jan 01 00:00:12 1970 +0000
619 | | | | date: Thu Jan 01 00:00:12 1970 +0000
620 | | | | summary: (12) merge two known; one immediate right, one far left
620 | | | | summary: (12) merge two known; one immediate right, one far left
621 | | | |
621 | | | |
622 | o | | changeset: 11:832d76e6bdf2
622 | o | | changeset: 11:832d76e6bdf2
623 | |\ \ \ parent: 6:b105a072e251
623 | |\ \ \ parent: 6:b105a072e251
624 | | | | | parent: 10:74c64d036d72
624 | | | | | parent: 10:74c64d036d72
625 | | | | | user: test
625 | | | | | user: test
626 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
626 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
627 | | | | | summary: (11) expand
627 | | | | | summary: (11) expand
628 | | | | |
628 | | | | |
629 | | o---+ changeset: 10:74c64d036d72
629 | | o---+ changeset: 10:74c64d036d72
630 | | | | | parent: 0:e6eb3150255d
630 | | | | | parent: 0:e6eb3150255d
631 | |/ / / parent: 6:b105a072e251
631 | |/ / / parent: 6:b105a072e251
632 | | | | user: test
632 | | | | user: test
633 | | | | date: Thu Jan 01 00:00:10 1970 +0000
633 | | | | date: Thu Jan 01 00:00:10 1970 +0000
634 | | | | summary: (10) merge two known; one immediate left, one near right
634 | | | | summary: (10) merge two known; one immediate left, one near right
635 | | | |
635 | | | |
636 o | | | changeset: 9:7010c0af0a35
636 o | | | changeset: 9:7010c0af0a35
637 |\ \ \ \ parent: 7:b632bb1b1224
637 |\ \ \ \ parent: 7:b632bb1b1224
638 | | | | | parent: 8:7a0b11f71937
638 | | | | | parent: 8:7a0b11f71937
639 | | | | | user: test
639 | | | | | user: test
640 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
640 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
641 | | | | | summary: (9) expand
641 | | | | | summary: (9) expand
642 | | | | |
642 | | | | |
643 | o-----+ changeset: 8:7a0b11f71937
643 | o-----+ changeset: 8:7a0b11f71937
644 | | | | | parent: 0:e6eb3150255d
644 | | | | | parent: 0:e6eb3150255d
645 |/ / / / parent: 7:b632bb1b1224
645 |/ / / / parent: 7:b632bb1b1224
646 | | | | user: test
646 | | | | user: test
647 | | | | date: Thu Jan 01 00:00:08 1970 +0000
647 | | | | date: Thu Jan 01 00:00:08 1970 +0000
648 | | | | summary: (8) merge two known; one immediate left, one far right
648 | | | | summary: (8) merge two known; one immediate left, one far right
649 | | | |
649 | | | |
650 o | | | changeset: 7:b632bb1b1224
650 o | | | changeset: 7:b632bb1b1224
651 |\ \ \ \ parent: 2:3d9a33b8d1e1
651 |\ \ \ \ parent: 2:3d9a33b8d1e1
652 | | | | | parent: 5:4409d547b708
652 | | | | | parent: 5:4409d547b708
653 | | | | | user: test
653 | | | | | user: test
654 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
654 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
655 | | | | | summary: (7) expand
655 | | | | | summary: (7) expand
656 | | | | |
656 | | | | |
657 +---o | | changeset: 6:b105a072e251
657 +---o | | changeset: 6:b105a072e251
658 | |/ / / parent: 2:3d9a33b8d1e1
658 | |/ / / parent: 2:3d9a33b8d1e1
659 | | | | parent: 5:4409d547b708
659 | | | | parent: 5:4409d547b708
660 | | | | user: test
660 | | | | user: test
661 | | | | date: Thu Jan 01 00:00:06 1970 +0000
661 | | | | date: Thu Jan 01 00:00:06 1970 +0000
662 | | | | summary: (6) merge two known; one immediate left, one far left
662 | | | | summary: (6) merge two known; one immediate left, one far left
663 | | | |
663 | | | |
664 | o | | changeset: 5:4409d547b708
664 | o | | changeset: 5:4409d547b708
665 | |\ \ \ parent: 3:27eef8ed80b4
665 | |\ \ \ parent: 3:27eef8ed80b4
666 | | | | | parent: 4:26a8bac39d9f
666 | | | | | parent: 4:26a8bac39d9f
667 | | | | | user: test
667 | | | | | user: test
668 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
668 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
669 | | | | | summary: (5) expand
669 | | | | | summary: (5) expand
670 | | | | |
670 | | | | |
671 | | o | | changeset: 4:26a8bac39d9f
671 | | o | | changeset: 4:26a8bac39d9f
672 | |/|/ / parent: 1:6db2ef61d156
672 | |/|/ / parent: 1:6db2ef61d156
673 | | | | parent: 3:27eef8ed80b4
673 | | | | parent: 3:27eef8ed80b4
674 | | | | user: test
674 | | | | user: test
675 | | | | date: Thu Jan 01 00:00:04 1970 +0000
675 | | | | date: Thu Jan 01 00:00:04 1970 +0000
676 | | | | summary: (4) merge two known; one immediate left, one immediate right
676 | | | | summary: (4) merge two known; one immediate left, one immediate right
677 | | | |
677 | | | |
678 | o | | changeset: 3:27eef8ed80b4
678 | o | | changeset: 3:27eef8ed80b4
679 |/ / / user: test
679 |/ / / user: test
680 | | | date: Thu Jan 01 00:00:03 1970 +0000
680 | | | date: Thu Jan 01 00:00:03 1970 +0000
681 | | | summary: (3) collapse
681 | | | summary: (3) collapse
682 | | |
682 | | |
683 o | | changeset: 2:3d9a33b8d1e1
683 o | | changeset: 2:3d9a33b8d1e1
684 |/ / user: test
684 |/ / user: test
685 | | date: Thu Jan 01 00:00:02 1970 +0000
685 | | date: Thu Jan 01 00:00:02 1970 +0000
686 | | summary: (2) collapse
686 | | summary: (2) collapse
687 | |
687 | |
688 o | changeset: 1:6db2ef61d156
688 o | changeset: 1:6db2ef61d156
689 |/ user: test
689 |/ user: test
690 | date: Thu Jan 01 00:00:01 1970 +0000
690 | date: Thu Jan 01 00:00:01 1970 +0000
691 | summary: (1) collapse
691 | summary: (1) collapse
692 |
692 |
693 o changeset: 0:e6eb3150255d
693 o changeset: 0:e6eb3150255d
694 user: test
694 user: test
695 date: Thu Jan 01 00:00:00 1970 +0000
695 date: Thu Jan 01 00:00:00 1970 +0000
696 summary: (0) root
696 summary: (0) root
697
697
698
698
699 File glog per revset:
699 File glog per revset:
700
700
701 $ hg glog -r 'file("a")'
701 $ hg glog -r 'file("a")'
702 @ changeset: 34:fea3ac5810e0
702 @ changeset: 34:fea3ac5810e0
703 | tag: tip
703 | tag: tip
704 | parent: 32:d06dffa21a31
704 | parent: 32:d06dffa21a31
705 | user: test
705 | user: test
706 | date: Thu Jan 01 00:00:34 1970 +0000
706 | date: Thu Jan 01 00:00:34 1970 +0000
707 | summary: (34) head
707 | summary: (34) head
708 |
708 |
709 | o changeset: 33:68608f5145f9
709 | o changeset: 33:68608f5145f9
710 | | parent: 18:1aa84d96232a
710 | | parent: 18:1aa84d96232a
711 | | user: test
711 | | user: test
712 | | date: Thu Jan 01 00:00:33 1970 +0000
712 | | date: Thu Jan 01 00:00:33 1970 +0000
713 | | summary: (33) head
713 | | summary: (33) head
714 | |
714 | |
715 o | changeset: 32:d06dffa21a31
715 o | changeset: 32:d06dffa21a31
716 |\ \ parent: 27:886ed638191b
716 |\ \ parent: 27:886ed638191b
717 | | | parent: 31:621d83e11f67
717 | | | parent: 31:621d83e11f67
718 | | | user: test
718 | | | user: test
719 | | | date: Thu Jan 01 00:00:32 1970 +0000
719 | | | date: Thu Jan 01 00:00:32 1970 +0000
720 | | | summary: (32) expand
720 | | | summary: (32) expand
721 | | |
721 | | |
722 | o | changeset: 31:621d83e11f67
722 | o | changeset: 31:621d83e11f67
723 | |\ \ parent: 21:d42a756af44d
723 | |\ \ parent: 21:d42a756af44d
724 | | | | parent: 30:6e11cd4b648f
724 | | | | parent: 30:6e11cd4b648f
725 | | | | user: test
725 | | | | user: test
726 | | | | date: Thu Jan 01 00:00:31 1970 +0000
726 | | | | date: Thu Jan 01 00:00:31 1970 +0000
727 | | | | summary: (31) expand
727 | | | | summary: (31) expand
728 | | | |
728 | | | |
729 | | o | changeset: 30:6e11cd4b648f
729 | | o | changeset: 30:6e11cd4b648f
730 | | |\ \ parent: 28:44ecd0b9ae99
730 | | |\ \ parent: 28:44ecd0b9ae99
731 | | | | | parent: 29:cd9bb2be7593
731 | | | | | parent: 29:cd9bb2be7593
732 | | | | | user: test
732 | | | | | user: test
733 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
733 | | | | | date: Thu Jan 01 00:00:30 1970 +0000
734 | | | | | summary: (30) expand
734 | | | | | summary: (30) expand
735 | | | | |
735 | | | | |
736 | | | o | changeset: 29:cd9bb2be7593
736 | | | o | changeset: 29:cd9bb2be7593
737 | | | | | parent: 0:e6eb3150255d
737 | | | | | parent: 0:e6eb3150255d
738 | | | | | user: test
738 | | | | | user: test
739 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
739 | | | | | date: Thu Jan 01 00:00:29 1970 +0000
740 | | | | | summary: (29) regular commit
740 | | | | | summary: (29) regular commit
741 | | | | |
741 | | | | |
742 | | o | | changeset: 28:44ecd0b9ae99
742 | | o | | changeset: 28:44ecd0b9ae99
743 | | |\ \ \ parent: 1:6db2ef61d156
743 | | |\ \ \ parent: 1:6db2ef61d156
744 | | | | | | parent: 26:7f25b6c2f0b9
744 | | | | | | parent: 26:7f25b6c2f0b9
745 | | | | | | user: test
745 | | | | | | user: test
746 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
746 | | | | | | date: Thu Jan 01 00:00:28 1970 +0000
747 | | | | | | summary: (28) merge zero known
747 | | | | | | summary: (28) merge zero known
748 | | | | | |
748 | | | | | |
749 o | | | | | changeset: 27:886ed638191b
749 o | | | | | changeset: 27:886ed638191b
750 |/ / / / / parent: 21:d42a756af44d
750 |/ / / / / parent: 21:d42a756af44d
751 | | | | | user: test
751 | | | | | user: test
752 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
752 | | | | | date: Thu Jan 01 00:00:27 1970 +0000
753 | | | | | summary: (27) collapse
753 | | | | | summary: (27) collapse
754 | | | | |
754 | | | | |
755 | | o---+ changeset: 26:7f25b6c2f0b9
755 | | o---+ changeset: 26:7f25b6c2f0b9
756 | | | | | parent: 18:1aa84d96232a
756 | | | | | parent: 18:1aa84d96232a
757 | | | | | parent: 25:91da8ed57247
757 | | | | | parent: 25:91da8ed57247
758 | | | | | user: test
758 | | | | | user: test
759 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
759 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
760 | | | | | summary: (26) merge one known; far right
760 | | | | | summary: (26) merge one known; far right
761 | | | | |
761 | | | | |
762 +---o | | changeset: 25:91da8ed57247
762 +---o | | changeset: 25:91da8ed57247
763 | | | | | parent: 21:d42a756af44d
763 | | | | | parent: 21:d42a756af44d
764 | | | | | parent: 24:a9c19a3d96b7
764 | | | | | parent: 24:a9c19a3d96b7
765 | | | | | user: test
765 | | | | | user: test
766 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
766 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
767 | | | | | summary: (25) merge one known; far left
767 | | | | | summary: (25) merge one known; far left
768 | | | | |
768 | | | | |
769 | | o | | changeset: 24:a9c19a3d96b7
769 | | o | | changeset: 24:a9c19a3d96b7
770 | | |\| | parent: 0:e6eb3150255d
770 | | |\| | parent: 0:e6eb3150255d
771 | | | | | parent: 23:a01cddf0766d
771 | | | | | parent: 23:a01cddf0766d
772 | | | | | user: test
772 | | | | | user: test
773 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
773 | | | | | date: Thu Jan 01 00:00:24 1970 +0000
774 | | | | | summary: (24) merge one known; immediate right
774 | | | | | summary: (24) merge one known; immediate right
775 | | | | |
775 | | | | |
776 | | o | | changeset: 23:a01cddf0766d
776 | | o | | changeset: 23:a01cddf0766d
777 | |/| | | parent: 1:6db2ef61d156
777 | |/| | | parent: 1:6db2ef61d156
778 | | | | | parent: 22:e0d9cccacb5d
778 | | | | | parent: 22:e0d9cccacb5d
779 | | | | | user: test
779 | | | | | user: test
780 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
780 | | | | | date: Thu Jan 01 00:00:23 1970 +0000
781 | | | | | summary: (23) merge one known; immediate left
781 | | | | | summary: (23) merge one known; immediate left
782 | | | | |
782 | | | | |
783 +---o---+ changeset: 22:e0d9cccacb5d
783 +---o---+ changeset: 22:e0d9cccacb5d
784 | | | | parent: 18:1aa84d96232a
784 | | | | parent: 18:1aa84d96232a
785 | | / / parent: 21:d42a756af44d
785 | | / / parent: 21:d42a756af44d
786 | | | | user: test
786 | | | | user: test
787 | | | | date: Thu Jan 01 00:00:22 1970 +0000
787 | | | | date: Thu Jan 01 00:00:22 1970 +0000
788 | | | | summary: (22) merge two known; one far left, one far right
788 | | | | summary: (22) merge two known; one far left, one far right
789 | | | |
789 | | | |
790 o | | | changeset: 21:d42a756af44d
790 o | | | changeset: 21:d42a756af44d
791 |\ \ \ \ parent: 19:31ddc2c1573b
791 |\ \ \ \ parent: 19:31ddc2c1573b
792 | | | | | parent: 20:d30ed6450e32
792 | | | | | parent: 20:d30ed6450e32
793 | | | | | user: test
793 | | | | | user: test
794 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
794 | | | | | date: Thu Jan 01 00:00:21 1970 +0000
795 | | | | | summary: (21) expand
795 | | | | | summary: (21) expand
796 | | | | |
796 | | | | |
797 | o---+-+ changeset: 20:d30ed6450e32
797 | o---+-+ changeset: 20:d30ed6450e32
798 | | | | parent: 0:e6eb3150255d
798 | | | | parent: 0:e6eb3150255d
799 | / / / parent: 18:1aa84d96232a
799 | / / / parent: 18:1aa84d96232a
800 | | | | user: test
800 | | | | user: test
801 | | | | date: Thu Jan 01 00:00:20 1970 +0000
801 | | | | date: Thu Jan 01 00:00:20 1970 +0000
802 | | | | summary: (20) merge two known; two far right
802 | | | | summary: (20) merge two known; two far right
803 | | | |
803 | | | |
804 o | | | changeset: 19:31ddc2c1573b
804 o | | | changeset: 19:31ddc2c1573b
805 |\ \ \ \ parent: 15:1dda3f72782d
805 |\ \ \ \ parent: 15:1dda3f72782d
806 | | | | | parent: 17:44765d7c06e0
806 | | | | | parent: 17:44765d7c06e0
807 | | | | | user: test
807 | | | | | user: test
808 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
808 | | | | | date: Thu Jan 01 00:00:19 1970 +0000
809 | | | | | summary: (19) expand
809 | | | | | summary: (19) expand
810 | | | | |
810 | | | | |
811 +---+---o changeset: 18:1aa84d96232a
811 +---+---o changeset: 18:1aa84d96232a
812 | | | | parent: 1:6db2ef61d156
812 | | | | parent: 1:6db2ef61d156
813 | | | | parent: 15:1dda3f72782d
813 | | | | parent: 15:1dda3f72782d
814 | | | | user: test
814 | | | | user: test
815 | | | | date: Thu Jan 01 00:00:18 1970 +0000
815 | | | | date: Thu Jan 01 00:00:18 1970 +0000
816 | | | | summary: (18) merge two known; two far left
816 | | | | summary: (18) merge two known; two far left
817 | | | |
817 | | | |
818 | o | | changeset: 17:44765d7c06e0
818 | o | | changeset: 17:44765d7c06e0
819 | |\ \ \ parent: 12:86b91144a6e9
819 | |\ \ \ parent: 12:86b91144a6e9
820 | | | | | parent: 16:3677d192927d
820 | | | | | parent: 16:3677d192927d
821 | | | | | user: test
821 | | | | | user: test
822 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
822 | | | | | date: Thu Jan 01 00:00:17 1970 +0000
823 | | | | | summary: (17) expand
823 | | | | | summary: (17) expand
824 | | | | |
824 | | | | |
825 | | o---+ changeset: 16:3677d192927d
825 | | o---+ changeset: 16:3677d192927d
826 | | | | | parent: 0:e6eb3150255d
826 | | | | | parent: 0:e6eb3150255d
827 | | |/ / parent: 1:6db2ef61d156
827 | | |/ / parent: 1:6db2ef61d156
828 | | | | user: test
828 | | | | user: test
829 | | | | date: Thu Jan 01 00:00:16 1970 +0000
829 | | | | date: Thu Jan 01 00:00:16 1970 +0000
830 | | | | summary: (16) merge two known; one immediate right, one near right
830 | | | | summary: (16) merge two known; one immediate right, one near right
831 | | | |
831 | | | |
832 o | | | changeset: 15:1dda3f72782d
832 o | | | changeset: 15:1dda3f72782d
833 |\ \ \ \ parent: 13:22d8966a97e3
833 |\ \ \ \ parent: 13:22d8966a97e3
834 | | | | | parent: 14:8eac370358ef
834 | | | | | parent: 14:8eac370358ef
835 | | | | | user: test
835 | | | | | user: test
836 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
836 | | | | | date: Thu Jan 01 00:00:15 1970 +0000
837 | | | | | summary: (15) expand
837 | | | | | summary: (15) expand
838 | | | | |
838 | | | | |
839 | o-----+ changeset: 14:8eac370358ef
839 | o-----+ changeset: 14:8eac370358ef
840 | | | | | parent: 0:e6eb3150255d
840 | | | | | parent: 0:e6eb3150255d
841 | |/ / / parent: 12:86b91144a6e9
841 | |/ / / parent: 12:86b91144a6e9
842 | | | | user: test
842 | | | | user: test
843 | | | | date: Thu Jan 01 00:00:14 1970 +0000
843 | | | | date: Thu Jan 01 00:00:14 1970 +0000
844 | | | | summary: (14) merge two known; one immediate right, one far right
844 | | | | summary: (14) merge two known; one immediate right, one far right
845 | | | |
845 | | | |
846 o | | | changeset: 13:22d8966a97e3
846 o | | | changeset: 13:22d8966a97e3
847 |\ \ \ \ parent: 9:7010c0af0a35
847 |\ \ \ \ parent: 9:7010c0af0a35
848 | | | | | parent: 11:832d76e6bdf2
848 | | | | | parent: 11:832d76e6bdf2
849 | | | | | user: test
849 | | | | | user: test
850 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
850 | | | | | date: Thu Jan 01 00:00:13 1970 +0000
851 | | | | | summary: (13) expand
851 | | | | | summary: (13) expand
852 | | | | |
852 | | | | |
853 +---o | | changeset: 12:86b91144a6e9
853 +---o | | changeset: 12:86b91144a6e9
854 | | |/ / parent: 1:6db2ef61d156
854 | | |/ / parent: 1:6db2ef61d156
855 | | | | parent: 9:7010c0af0a35
855 | | | | parent: 9:7010c0af0a35
856 | | | | user: test
856 | | | | user: test
857 | | | | date: Thu Jan 01 00:00:12 1970 +0000
857 | | | | date: Thu Jan 01 00:00:12 1970 +0000
858 | | | | summary: (12) merge two known; one immediate right, one far left
858 | | | | summary: (12) merge two known; one immediate right, one far left
859 | | | |
859 | | | |
860 | o | | changeset: 11:832d76e6bdf2
860 | o | | changeset: 11:832d76e6bdf2
861 | |\ \ \ parent: 6:b105a072e251
861 | |\ \ \ parent: 6:b105a072e251
862 | | | | | parent: 10:74c64d036d72
862 | | | | | parent: 10:74c64d036d72
863 | | | | | user: test
863 | | | | | user: test
864 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
864 | | | | | date: Thu Jan 01 00:00:11 1970 +0000
865 | | | | | summary: (11) expand
865 | | | | | summary: (11) expand
866 | | | | |
866 | | | | |
867 | | o---+ changeset: 10:74c64d036d72
867 | | o---+ changeset: 10:74c64d036d72
868 | | | | | parent: 0:e6eb3150255d
868 | | | | | parent: 0:e6eb3150255d
869 | |/ / / parent: 6:b105a072e251
869 | |/ / / parent: 6:b105a072e251
870 | | | | user: test
870 | | | | user: test
871 | | | | date: Thu Jan 01 00:00:10 1970 +0000
871 | | | | date: Thu Jan 01 00:00:10 1970 +0000
872 | | | | summary: (10) merge two known; one immediate left, one near right
872 | | | | summary: (10) merge two known; one immediate left, one near right
873 | | | |
873 | | | |
874 o | | | changeset: 9:7010c0af0a35
874 o | | | changeset: 9:7010c0af0a35
875 |\ \ \ \ parent: 7:b632bb1b1224
875 |\ \ \ \ parent: 7:b632bb1b1224
876 | | | | | parent: 8:7a0b11f71937
876 | | | | | parent: 8:7a0b11f71937
877 | | | | | user: test
877 | | | | | user: test
878 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
878 | | | | | date: Thu Jan 01 00:00:09 1970 +0000
879 | | | | | summary: (9) expand
879 | | | | | summary: (9) expand
880 | | | | |
880 | | | | |
881 | o-----+ changeset: 8:7a0b11f71937
881 | o-----+ changeset: 8:7a0b11f71937
882 | | | | | parent: 0:e6eb3150255d
882 | | | | | parent: 0:e6eb3150255d
883 |/ / / / parent: 7:b632bb1b1224
883 |/ / / / parent: 7:b632bb1b1224
884 | | | | user: test
884 | | | | user: test
885 | | | | date: Thu Jan 01 00:00:08 1970 +0000
885 | | | | date: Thu Jan 01 00:00:08 1970 +0000
886 | | | | summary: (8) merge two known; one immediate left, one far right
886 | | | | summary: (8) merge two known; one immediate left, one far right
887 | | | |
887 | | | |
888 o | | | changeset: 7:b632bb1b1224
888 o | | | changeset: 7:b632bb1b1224
889 |\ \ \ \ parent: 2:3d9a33b8d1e1
889 |\ \ \ \ parent: 2:3d9a33b8d1e1
890 | | | | | parent: 5:4409d547b708
890 | | | | | parent: 5:4409d547b708
891 | | | | | user: test
891 | | | | | user: test
892 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
892 | | | | | date: Thu Jan 01 00:00:07 1970 +0000
893 | | | | | summary: (7) expand
893 | | | | | summary: (7) expand
894 | | | | |
894 | | | | |
895 +---o | | changeset: 6:b105a072e251
895 +---o | | changeset: 6:b105a072e251
896 | |/ / / parent: 2:3d9a33b8d1e1
896 | |/ / / parent: 2:3d9a33b8d1e1
897 | | | | parent: 5:4409d547b708
897 | | | | parent: 5:4409d547b708
898 | | | | user: test
898 | | | | user: test
899 | | | | date: Thu Jan 01 00:00:06 1970 +0000
899 | | | | date: Thu Jan 01 00:00:06 1970 +0000
900 | | | | summary: (6) merge two known; one immediate left, one far left
900 | | | | summary: (6) merge two known; one immediate left, one far left
901 | | | |
901 | | | |
902 | o | | changeset: 5:4409d547b708
902 | o | | changeset: 5:4409d547b708
903 | |\ \ \ parent: 3:27eef8ed80b4
903 | |\ \ \ parent: 3:27eef8ed80b4
904 | | | | | parent: 4:26a8bac39d9f
904 | | | | | parent: 4:26a8bac39d9f
905 | | | | | user: test
905 | | | | | user: test
906 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
906 | | | | | date: Thu Jan 01 00:00:05 1970 +0000
907 | | | | | summary: (5) expand
907 | | | | | summary: (5) expand
908 | | | | |
908 | | | | |
909 | | o | | changeset: 4:26a8bac39d9f
909 | | o | | changeset: 4:26a8bac39d9f
910 | |/|/ / parent: 1:6db2ef61d156
910 | |/|/ / parent: 1:6db2ef61d156
911 | | | | parent: 3:27eef8ed80b4
911 | | | | parent: 3:27eef8ed80b4
912 | | | | user: test
912 | | | | user: test
913 | | | | date: Thu Jan 01 00:00:04 1970 +0000
913 | | | | date: Thu Jan 01 00:00:04 1970 +0000
914 | | | | summary: (4) merge two known; one immediate left, one immediate right
914 | | | | summary: (4) merge two known; one immediate left, one immediate right
915 | | | |
915 | | | |
916 | o | | changeset: 3:27eef8ed80b4
916 | o | | changeset: 3:27eef8ed80b4
917 |/ / / user: test
917 |/ / / user: test
918 | | | date: Thu Jan 01 00:00:03 1970 +0000
918 | | | date: Thu Jan 01 00:00:03 1970 +0000
919 | | | summary: (3) collapse
919 | | | summary: (3) collapse
920 | | |
920 | | |
921 o | | changeset: 2:3d9a33b8d1e1
921 o | | changeset: 2:3d9a33b8d1e1
922 |/ / user: test
922 |/ / user: test
923 | | date: Thu Jan 01 00:00:02 1970 +0000
923 | | date: Thu Jan 01 00:00:02 1970 +0000
924 | | summary: (2) collapse
924 | | summary: (2) collapse
925 | |
925 | |
926 o | changeset: 1:6db2ef61d156
926 o | changeset: 1:6db2ef61d156
927 |/ user: test
927 |/ user: test
928 | date: Thu Jan 01 00:00:01 1970 +0000
928 | date: Thu Jan 01 00:00:01 1970 +0000
929 | summary: (1) collapse
929 | summary: (1) collapse
930 |
930 |
931 o changeset: 0:e6eb3150255d
931 o changeset: 0:e6eb3150255d
932 user: test
932 user: test
933 date: Thu Jan 01 00:00:00 1970 +0000
933 date: Thu Jan 01 00:00:00 1970 +0000
934 summary: (0) root
934 summary: (0) root
935
935
936
936
937
937
938 File glog per revset (only merges):
938 File glog per revset (only merges):
939
939
940 $ hg log -G -r 'file("a")' -m
940 $ hg log -G -r 'file("a")' -m
941 o changeset: 32:d06dffa21a31
941 o changeset: 32:d06dffa21a31
942 |\ parent: 27:886ed638191b
942 |\ parent: 27:886ed638191b
943 | | parent: 31:621d83e11f67
943 | | parent: 31:621d83e11f67
944 | | user: test
944 | | user: test
945 | | date: Thu Jan 01 00:00:32 1970 +0000
945 | | date: Thu Jan 01 00:00:32 1970 +0000
946 | | summary: (32) expand
946 | | summary: (32) expand
947 | |
947 | |
948 o | changeset: 31:621d83e11f67
948 o | changeset: 31:621d83e11f67
949 |\| parent: 21:d42a756af44d
949 |\| parent: 21:d42a756af44d
950 | | parent: 30:6e11cd4b648f
950 | | parent: 30:6e11cd4b648f
951 | | user: test
951 | | user: test
952 | | date: Thu Jan 01 00:00:31 1970 +0000
952 | | date: Thu Jan 01 00:00:31 1970 +0000
953 | | summary: (31) expand
953 | | summary: (31) expand
954 | |
954 | |
955 o | changeset: 30:6e11cd4b648f
955 o | changeset: 30:6e11cd4b648f
956 |\ \ parent: 28:44ecd0b9ae99
956 |\ \ parent: 28:44ecd0b9ae99
957 | | | parent: 29:cd9bb2be7593
957 | | | parent: 29:cd9bb2be7593
958 | | | user: test
958 | | | user: test
959 | | | date: Thu Jan 01 00:00:30 1970 +0000
959 | | | date: Thu Jan 01 00:00:30 1970 +0000
960 | | | summary: (30) expand
960 | | | summary: (30) expand
961 | | |
961 | | |
962 o | | changeset: 28:44ecd0b9ae99
962 o | | changeset: 28:44ecd0b9ae99
963 |\ \ \ parent: 1:6db2ef61d156
963 |\ \ \ parent: 1:6db2ef61d156
964 | | | | parent: 26:7f25b6c2f0b9
964 | | | | parent: 26:7f25b6c2f0b9
965 | | | | user: test
965 | | | | user: test
966 | | | | date: Thu Jan 01 00:00:28 1970 +0000
966 | | | | date: Thu Jan 01 00:00:28 1970 +0000
967 | | | | summary: (28) merge zero known
967 | | | | summary: (28) merge zero known
968 | | | |
968 | | | |
969 o | | | changeset: 26:7f25b6c2f0b9
969 o | | | changeset: 26:7f25b6c2f0b9
970 |\ \ \ \ parent: 18:1aa84d96232a
970 |\ \ \ \ parent: 18:1aa84d96232a
971 | | | | | parent: 25:91da8ed57247
971 | | | | | parent: 25:91da8ed57247
972 | | | | | user: test
972 | | | | | user: test
973 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
973 | | | | | date: Thu Jan 01 00:00:26 1970 +0000
974 | | | | | summary: (26) merge one known; far right
974 | | | | | summary: (26) merge one known; far right
975 | | | | |
975 | | | | |
976 | o-----+ changeset: 25:91da8ed57247
976 | o-----+ changeset: 25:91da8ed57247
977 | | | | | parent: 21:d42a756af44d
977 | | | | | parent: 21:d42a756af44d
978 | | | | | parent: 24:a9c19a3d96b7
978 | | | | | parent: 24:a9c19a3d96b7
979 | | | | | user: test
979 | | | | | user: test
980 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
980 | | | | | date: Thu Jan 01 00:00:25 1970 +0000
981 | | | | | summary: (25) merge one known; far left
981 | | | | | summary: (25) merge one known; far left
982 | | | | |
982 | | | | |
983 | o | | | changeset: 24:a9c19a3d96b7
983 | o | | | changeset: 24:a9c19a3d96b7
984 | |\ \ \ \ parent: 0:e6eb3150255d
984 | |\ \ \ \ parent: 0:e6eb3150255d
985 | | | | | | parent: 23:a01cddf0766d
985 | | | | | | parent: 23:a01cddf0766d
986 | | | | | | user: test
986 | | | | | | user: test
987 | | | | | | date: Thu Jan 01 00:00:24 1970 +0000
987 | | | | | | date: Thu Jan 01 00:00:24 1970 +0000
988 | | | | | | summary: (24) merge one known; immediate right
988 | | | | | | summary: (24) merge one known; immediate right
989 | | | | | |
989 | | | | | |
990 | o---+ | | changeset: 23:a01cddf0766d
990 | o---+ | | changeset: 23:a01cddf0766d
991 | | | | | | parent: 1:6db2ef61d156
991 | | | | | | parent: 1:6db2ef61d156
992 | | | | | | parent: 22:e0d9cccacb5d
992 | | | | | | parent: 22:e0d9cccacb5d
993 | | | | | | user: test
993 | | | | | | user: test
994 | | | | | | date: Thu Jan 01 00:00:23 1970 +0000
994 | | | | | | date: Thu Jan 01 00:00:23 1970 +0000
995 | | | | | | summary: (23) merge one known; immediate left
995 | | | | | | summary: (23) merge one known; immediate left
996 | | | | | |
996 | | | | | |
997 | o-------+ changeset: 22:e0d9cccacb5d
997 | o-------+ changeset: 22:e0d9cccacb5d
998 | | | | | | parent: 18:1aa84d96232a
998 | | | | | | parent: 18:1aa84d96232a
999 |/ / / / / parent: 21:d42a756af44d
999 |/ / / / / parent: 21:d42a756af44d
1000 | | | | | user: test
1000 | | | | | user: test
1001 | | | | | date: Thu Jan 01 00:00:22 1970 +0000
1001 | | | | | date: Thu Jan 01 00:00:22 1970 +0000
1002 | | | | | summary: (22) merge two known; one far left, one far right
1002 | | | | | summary: (22) merge two known; one far left, one far right
1003 | | | | |
1003 | | | | |
1004 | | | | o changeset: 21:d42a756af44d
1004 | | | | o changeset: 21:d42a756af44d
1005 | | | | |\ parent: 19:31ddc2c1573b
1005 | | | | |\ parent: 19:31ddc2c1573b
1006 | | | | | | parent: 20:d30ed6450e32
1006 | | | | | | parent: 20:d30ed6450e32
1007 | | | | | | user: test
1007 | | | | | | user: test
1008 | | | | | | date: Thu Jan 01 00:00:21 1970 +0000
1008 | | | | | | date: Thu Jan 01 00:00:21 1970 +0000
1009 | | | | | | summary: (21) expand
1009 | | | | | | summary: (21) expand
1010 | | | | | |
1010 | | | | | |
1011 +-+-------o changeset: 20:d30ed6450e32
1011 +-+-------o changeset: 20:d30ed6450e32
1012 | | | | | parent: 0:e6eb3150255d
1012 | | | | | parent: 0:e6eb3150255d
1013 | | | | | parent: 18:1aa84d96232a
1013 | | | | | parent: 18:1aa84d96232a
1014 | | | | | user: test
1014 | | | | | user: test
1015 | | | | | date: Thu Jan 01 00:00:20 1970 +0000
1015 | | | | | date: Thu Jan 01 00:00:20 1970 +0000
1016 | | | | | summary: (20) merge two known; two far right
1016 | | | | | summary: (20) merge two known; two far right
1017 | | | | |
1017 | | | | |
1018 | | | | o changeset: 19:31ddc2c1573b
1018 | | | | o changeset: 19:31ddc2c1573b
1019 | | | | |\ parent: 15:1dda3f72782d
1019 | | | | |\ parent: 15:1dda3f72782d
1020 | | | | | | parent: 17:44765d7c06e0
1020 | | | | | | parent: 17:44765d7c06e0
1021 | | | | | | user: test
1021 | | | | | | user: test
1022 | | | | | | date: Thu Jan 01 00:00:19 1970 +0000
1022 | | | | | | date: Thu Jan 01 00:00:19 1970 +0000
1023 | | | | | | summary: (19) expand
1023 | | | | | | summary: (19) expand
1024 | | | | | |
1024 | | | | | |
1025 o---+---+ | changeset: 18:1aa84d96232a
1025 o---+---+ | changeset: 18:1aa84d96232a
1026 | | | | | parent: 1:6db2ef61d156
1026 | | | | | parent: 1:6db2ef61d156
1027 / / / / / parent: 15:1dda3f72782d
1027 / / / / / parent: 15:1dda3f72782d
1028 | | | | | user: test
1028 | | | | | user: test
1029 | | | | | date: Thu Jan 01 00:00:18 1970 +0000
1029 | | | | | date: Thu Jan 01 00:00:18 1970 +0000
1030 | | | | | summary: (18) merge two known; two far left
1030 | | | | | summary: (18) merge two known; two far left
1031 | | | | |
1031 | | | | |
1032 | | | | o changeset: 17:44765d7c06e0
1032 | | | | o changeset: 17:44765d7c06e0
1033 | | | | |\ parent: 12:86b91144a6e9
1033 | | | | |\ parent: 12:86b91144a6e9
1034 | | | | | | parent: 16:3677d192927d
1034 | | | | | | parent: 16:3677d192927d
1035 | | | | | | user: test
1035 | | | | | | user: test
1036 | | | | | | date: Thu Jan 01 00:00:17 1970 +0000
1036 | | | | | | date: Thu Jan 01 00:00:17 1970 +0000
1037 | | | | | | summary: (17) expand
1037 | | | | | | summary: (17) expand
1038 | | | | | |
1038 | | | | | |
1039 +-+-------o changeset: 16:3677d192927d
1039 +-+-------o changeset: 16:3677d192927d
1040 | | | | | parent: 0:e6eb3150255d
1040 | | | | | parent: 0:e6eb3150255d
1041 | | | | | parent: 1:6db2ef61d156
1041 | | | | | parent: 1:6db2ef61d156
1042 | | | | | user: test
1042 | | | | | user: test
1043 | | | | | date: Thu Jan 01 00:00:16 1970 +0000
1043 | | | | | date: Thu Jan 01 00:00:16 1970 +0000
1044 | | | | | summary: (16) merge two known; one immediate right, one near right
1044 | | | | | summary: (16) merge two known; one immediate right, one near right
1045 | | | | |
1045 | | | | |
1046 | | | o | changeset: 15:1dda3f72782d
1046 | | | o | changeset: 15:1dda3f72782d
1047 | | | |\ \ parent: 13:22d8966a97e3
1047 | | | |\ \ parent: 13:22d8966a97e3
1048 | | | | | | parent: 14:8eac370358ef
1048 | | | | | | parent: 14:8eac370358ef
1049 | | | | | | user: test
1049 | | | | | | user: test
1050 | | | | | | date: Thu Jan 01 00:00:15 1970 +0000
1050 | | | | | | date: Thu Jan 01 00:00:15 1970 +0000
1051 | | | | | | summary: (15) expand
1051 | | | | | | summary: (15) expand
1052 | | | | | |
1052 | | | | | |
1053 +-------o | changeset: 14:8eac370358ef
1053 +-------o | changeset: 14:8eac370358ef
1054 | | | | |/ parent: 0:e6eb3150255d
1054 | | | | |/ parent: 0:e6eb3150255d
1055 | | | | | parent: 12:86b91144a6e9
1055 | | | | | parent: 12:86b91144a6e9
1056 | | | | | user: test
1056 | | | | | user: test
1057 | | | | | date: Thu Jan 01 00:00:14 1970 +0000
1057 | | | | | date: Thu Jan 01 00:00:14 1970 +0000
1058 | | | | | summary: (14) merge two known; one immediate right, one far right
1058 | | | | | summary: (14) merge two known; one immediate right, one far right
1059 | | | | |
1059 | | | | |
1060 | | | o | changeset: 13:22d8966a97e3
1060 | | | o | changeset: 13:22d8966a97e3
1061 | | | |\ \ parent: 9:7010c0af0a35
1061 | | | |\ \ parent: 9:7010c0af0a35
1062 | | | | | | parent: 11:832d76e6bdf2
1062 | | | | | | parent: 11:832d76e6bdf2
1063 | | | | | | user: test
1063 | | | | | | user: test
1064 | | | | | | date: Thu Jan 01 00:00:13 1970 +0000
1064 | | | | | | date: Thu Jan 01 00:00:13 1970 +0000
1065 | | | | | | summary: (13) expand
1065 | | | | | | summary: (13) expand
1066 | | | | | |
1066 | | | | | |
1067 | +---+---o changeset: 12:86b91144a6e9
1067 | +---+---o changeset: 12:86b91144a6e9
1068 | | | | | parent: 1:6db2ef61d156
1068 | | | | | parent: 1:6db2ef61d156
1069 | | | | | parent: 9:7010c0af0a35
1069 | | | | | parent: 9:7010c0af0a35
1070 | | | | | user: test
1070 | | | | | user: test
1071 | | | | | date: Thu Jan 01 00:00:12 1970 +0000
1071 | | | | | date: Thu Jan 01 00:00:12 1970 +0000
1072 | | | | | summary: (12) merge two known; one immediate right, one far left
1072 | | | | | summary: (12) merge two known; one immediate right, one far left
1073 | | | | |
1073 | | | | |
1074 | | | | o changeset: 11:832d76e6bdf2
1074 | | | | o changeset: 11:832d76e6bdf2
1075 | | | | |\ parent: 6:b105a072e251
1075 | | | | |\ parent: 6:b105a072e251
1076 | | | | | | parent: 10:74c64d036d72
1076 | | | | | | parent: 10:74c64d036d72
1077 | | | | | | user: test
1077 | | | | | | user: test
1078 | | | | | | date: Thu Jan 01 00:00:11 1970 +0000
1078 | | | | | | date: Thu Jan 01 00:00:11 1970 +0000
1079 | | | | | | summary: (11) expand
1079 | | | | | | summary: (11) expand
1080 | | | | | |
1080 | | | | | |
1081 +---------o changeset: 10:74c64d036d72
1081 +---------o changeset: 10:74c64d036d72
1082 | | | | |/ parent: 0:e6eb3150255d
1082 | | | | |/ parent: 0:e6eb3150255d
1083 | | | | | parent: 6:b105a072e251
1083 | | | | | parent: 6:b105a072e251
1084 | | | | | user: test
1084 | | | | | user: test
1085 | | | | | date: Thu Jan 01 00:00:10 1970 +0000
1085 | | | | | date: Thu Jan 01 00:00:10 1970 +0000
1086 | | | | | summary: (10) merge two known; one immediate left, one near right
1086 | | | | | summary: (10) merge two known; one immediate left, one near right
1087 | | | | |
1087 | | | | |
1088 | | | o | changeset: 9:7010c0af0a35
1088 | | | o | changeset: 9:7010c0af0a35
1089 | | | |\ \ parent: 7:b632bb1b1224
1089 | | | |\ \ parent: 7:b632bb1b1224
1090 | | | | | | parent: 8:7a0b11f71937
1090 | | | | | | parent: 8:7a0b11f71937
1091 | | | | | | user: test
1091 | | | | | | user: test
1092 | | | | | | date: Thu Jan 01 00:00:09 1970 +0000
1092 | | | | | | date: Thu Jan 01 00:00:09 1970 +0000
1093 | | | | | | summary: (9) expand
1093 | | | | | | summary: (9) expand
1094 | | | | | |
1094 | | | | | |
1095 +-------o | changeset: 8:7a0b11f71937
1095 +-------o | changeset: 8:7a0b11f71937
1096 | | | |/ / parent: 0:e6eb3150255d
1096 | | | |/ / parent: 0:e6eb3150255d
1097 | | | | | parent: 7:b632bb1b1224
1097 | | | | | parent: 7:b632bb1b1224
1098 | | | | | user: test
1098 | | | | | user: test
1099 | | | | | date: Thu Jan 01 00:00:08 1970 +0000
1099 | | | | | date: Thu Jan 01 00:00:08 1970 +0000
1100 | | | | | summary: (8) merge two known; one immediate left, one far right
1100 | | | | | summary: (8) merge two known; one immediate left, one far right
1101 | | | | |
1101 | | | | |
1102 | | | o | changeset: 7:b632bb1b1224
1102 | | | o | changeset: 7:b632bb1b1224
1103 | | | |\ \ parent: 2:3d9a33b8d1e1
1103 | | | |\ \ parent: 2:3d9a33b8d1e1
1104 | | | | | | parent: 5:4409d547b708
1104 | | | | | | parent: 5:4409d547b708
1105 | | | | | | user: test
1105 | | | | | | user: test
1106 | | | | | | date: Thu Jan 01 00:00:07 1970 +0000
1106 | | | | | | date: Thu Jan 01 00:00:07 1970 +0000
1107 | | | | | | summary: (7) expand
1107 | | | | | | summary: (7) expand
1108 | | | | | |
1108 | | | | | |
1109 | | | +---o changeset: 6:b105a072e251
1109 | | | +---o changeset: 6:b105a072e251
1110 | | | | |/ parent: 2:3d9a33b8d1e1
1110 | | | | |/ parent: 2:3d9a33b8d1e1
1111 | | | | | parent: 5:4409d547b708
1111 | | | | | parent: 5:4409d547b708
1112 | | | | | user: test
1112 | | | | | user: test
1113 | | | | | date: Thu Jan 01 00:00:06 1970 +0000
1113 | | | | | date: Thu Jan 01 00:00:06 1970 +0000
1114 | | | | | summary: (6) merge two known; one immediate left, one far left
1114 | | | | | summary: (6) merge two known; one immediate left, one far left
1115 | | | | |
1115 | | | | |
1116 | | | o | changeset: 5:4409d547b708
1116 | | | o | changeset: 5:4409d547b708
1117 | | | |\ \ parent: 3:27eef8ed80b4
1117 | | | |\ \ parent: 3:27eef8ed80b4
1118 | | | | | | parent: 4:26a8bac39d9f
1118 | | | | | | parent: 4:26a8bac39d9f
1119 | | | | | | user: test
1119 | | | | | | user: test
1120 | | | | | | date: Thu Jan 01 00:00:05 1970 +0000
1120 | | | | | | date: Thu Jan 01 00:00:05 1970 +0000
1121 | | | | | | summary: (5) expand
1121 | | | | | | summary: (5) expand
1122 | | | | | |
1122 | | | | | |
1123 | +---o | | changeset: 4:26a8bac39d9f
1123 | +---o | | changeset: 4:26a8bac39d9f
1124 | | | |/ / parent: 1:6db2ef61d156
1124 | | | |/ / parent: 1:6db2ef61d156
1125 | | | | | parent: 3:27eef8ed80b4
1125 | | | | | parent: 3:27eef8ed80b4
1126 | | | | | user: test
1126 | | | | | user: test
1127 | | | | | date: Thu Jan 01 00:00:04 1970 +0000
1127 | | | | | date: Thu Jan 01 00:00:04 1970 +0000
1128 | | | | | summary: (4) merge two known; one immediate left, one immediate right
1128 | | | | | summary: (4) merge two known; one immediate left, one immediate right
1129 | | | | |
1129 | | | | |
1130
1130
1131
1131
1132 Empty revision range - display nothing:
1132 Empty revision range - display nothing:
1133 $ hg glog -r 1..0
1133 $ hg glog -r 1..0
1134
1134
1135 From outer space:
1135 From outer space:
1136 $ cd ..
1136 $ cd ..
1137 $ hg glog -l1 repo
1137 $ hg glog -l1 repo
1138 @ changeset: 34:fea3ac5810e0
1138 @ changeset: 34:fea3ac5810e0
1139 | tag: tip
1139 | tag: tip
1140 | parent: 32:d06dffa21a31
1140 | parent: 32:d06dffa21a31
1141 | user: test
1141 | user: test
1142 | date: Thu Jan 01 00:00:34 1970 +0000
1142 | date: Thu Jan 01 00:00:34 1970 +0000
1143 | summary: (34) head
1143 | summary: (34) head
1144 |
1144 |
1145 $ hg glog -l1 repo/a
1145 $ hg glog -l1 repo/a
1146 @ changeset: 34:fea3ac5810e0
1146 @ changeset: 34:fea3ac5810e0
1147 | tag: tip
1147 | tag: tip
1148 | parent: 32:d06dffa21a31
1148 | parent: 32:d06dffa21a31
1149 | user: test
1149 | user: test
1150 | date: Thu Jan 01 00:00:34 1970 +0000
1150 | date: Thu Jan 01 00:00:34 1970 +0000
1151 | summary: (34) head
1151 | summary: (34) head
1152 |
1152 |
1153 $ hg glog -l1 repo/missing
1153 $ hg glog -l1 repo/missing
1154
1154
1155 File log with revs != cset revs:
1155 File log with revs != cset revs:
1156 $ hg init flog
1156 $ hg init flog
1157 $ cd flog
1157 $ cd flog
1158 $ echo one >one
1158 $ echo one >one
1159 $ hg add one
1159 $ hg add one
1160 $ hg commit -mone
1160 $ hg commit -mone
1161 $ echo two >two
1161 $ echo two >two
1162 $ hg add two
1162 $ hg add two
1163 $ hg commit -mtwo
1163 $ hg commit -mtwo
1164 $ echo more >two
1164 $ echo more >two
1165 $ hg commit -mmore
1165 $ hg commit -mmore
1166 $ hg glog two
1166 $ hg glog two
1167 @ changeset: 2:12c28321755b
1167 @ changeset: 2:12c28321755b
1168 | tag: tip
1168 | tag: tip
1169 | user: test
1169 | user: test
1170 | date: Thu Jan 01 00:00:00 1970 +0000
1170 | date: Thu Jan 01 00:00:00 1970 +0000
1171 | summary: more
1171 | summary: more
1172 |
1172 |
1173 o changeset: 1:5ac72c0599bf
1173 o changeset: 1:5ac72c0599bf
1174 | user: test
1174 | user: test
1175 | date: Thu Jan 01 00:00:00 1970 +0000
1175 | date: Thu Jan 01 00:00:00 1970 +0000
1176 | summary: two
1176 | summary: two
1177 |
1177 |
1178
1178
1179 Issue1896: File log with explicit style
1179 Issue1896: File log with explicit style
1180 $ hg glog --style=default one
1180 $ hg glog --style=default one
1181 o changeset: 0:3d578b4a1f53
1181 o changeset: 0:3d578b4a1f53
1182 user: test
1182 user: test
1183 date: Thu Jan 01 00:00:00 1970 +0000
1183 date: Thu Jan 01 00:00:00 1970 +0000
1184 summary: one
1184 summary: one
1185
1185
1186 Issue2395: glog --style header and footer
1186 Issue2395: glog --style header and footer
1187 $ hg glog --style=xml one
1187 $ hg glog --style=xml one
1188 <?xml version="1.0"?>
1188 <?xml version="1.0"?>
1189 <log>
1189 <log>
1190 o <logentry revision="0" node="3d578b4a1f537d5fcf7301bfa9c0b97adfaa6fb1">
1190 o <logentry revision="0" node="3d578b4a1f537d5fcf7301bfa9c0b97adfaa6fb1">
1191 <author email="test">test</author>
1191 <author email="test">test</author>
1192 <date>1970-01-01T00:00:00+00:00</date>
1192 <date>1970-01-01T00:00:00+00:00</date>
1193 <msg xml:space="preserve">one</msg>
1193 <msg xml:space="preserve">one</msg>
1194 </logentry>
1194 </logentry>
1195 </log>
1195 </log>
1196
1196
1197 $ cd ..
1197 $ cd ..
1198
1198
1199 Incoming and outgoing:
1199 Incoming and outgoing:
1200
1200
1201 $ hg clone -U -r31 repo repo2
1201 $ hg clone -U -r31 repo repo2
1202 adding changesets
1202 adding changesets
1203 adding manifests
1203 adding manifests
1204 adding file changes
1204 adding file changes
1205 added 31 changesets with 31 changes to 1 files
1205 added 31 changesets with 31 changes to 1 files
1206 $ cd repo2
1206 $ cd repo2
1207
1207
1208 $ hg incoming --graph ../repo
1208 $ hg incoming --graph ../repo
1209 comparing with ../repo
1209 comparing with ../repo
1210 searching for changes
1210 searching for changes
1211 o changeset: 34:fea3ac5810e0
1211 o changeset: 34:fea3ac5810e0
1212 | tag: tip
1212 | tag: tip
1213 | parent: 32:d06dffa21a31
1213 | parent: 32:d06dffa21a31
1214 | user: test
1214 | user: test
1215 | date: Thu Jan 01 00:00:34 1970 +0000
1215 | date: Thu Jan 01 00:00:34 1970 +0000
1216 | summary: (34) head
1216 | summary: (34) head
1217 |
1217 |
1218 | o changeset: 33:68608f5145f9
1218 | o changeset: 33:68608f5145f9
1219 | parent: 18:1aa84d96232a
1219 | parent: 18:1aa84d96232a
1220 | user: test
1220 | user: test
1221 | date: Thu Jan 01 00:00:33 1970 +0000
1221 | date: Thu Jan 01 00:00:33 1970 +0000
1222 | summary: (33) head
1222 | summary: (33) head
1223 |
1223 |
1224 o changeset: 32:d06dffa21a31
1224 o changeset: 32:d06dffa21a31
1225 | parent: 27:886ed638191b
1225 | parent: 27:886ed638191b
1226 | parent: 31:621d83e11f67
1226 | parent: 31:621d83e11f67
1227 | user: test
1227 | user: test
1228 | date: Thu Jan 01 00:00:32 1970 +0000
1228 | date: Thu Jan 01 00:00:32 1970 +0000
1229 | summary: (32) expand
1229 | summary: (32) expand
1230 |
1230 |
1231 o changeset: 27:886ed638191b
1231 o changeset: 27:886ed638191b
1232 parent: 21:d42a756af44d
1232 parent: 21:d42a756af44d
1233 user: test
1233 user: test
1234 date: Thu Jan 01 00:00:27 1970 +0000
1234 date: Thu Jan 01 00:00:27 1970 +0000
1235 summary: (27) collapse
1235 summary: (27) collapse
1236
1236
1237 $ cd ..
1237 $ cd ..
1238
1238
1239 $ hg -R repo outgoing --graph repo2
1239 $ hg -R repo outgoing --graph repo2
1240 comparing with repo2
1240 comparing with repo2
1241 searching for changes
1241 searching for changes
1242 @ changeset: 34:fea3ac5810e0
1242 @ changeset: 34:fea3ac5810e0
1243 | tag: tip
1243 | tag: tip
1244 | parent: 32:d06dffa21a31
1244 | parent: 32:d06dffa21a31
1245 | user: test
1245 | user: test
1246 | date: Thu Jan 01 00:00:34 1970 +0000
1246 | date: Thu Jan 01 00:00:34 1970 +0000
1247 | summary: (34) head
1247 | summary: (34) head
1248 |
1248 |
1249 | o changeset: 33:68608f5145f9
1249 | o changeset: 33:68608f5145f9
1250 | parent: 18:1aa84d96232a
1250 | parent: 18:1aa84d96232a
1251 | user: test
1251 | user: test
1252 | date: Thu Jan 01 00:00:33 1970 +0000
1252 | date: Thu Jan 01 00:00:33 1970 +0000
1253 | summary: (33) head
1253 | summary: (33) head
1254 |
1254 |
1255 o changeset: 32:d06dffa21a31
1255 o changeset: 32:d06dffa21a31
1256 | parent: 27:886ed638191b
1256 | parent: 27:886ed638191b
1257 | parent: 31:621d83e11f67
1257 | parent: 31:621d83e11f67
1258 | user: test
1258 | user: test
1259 | date: Thu Jan 01 00:00:32 1970 +0000
1259 | date: Thu Jan 01 00:00:32 1970 +0000
1260 | summary: (32) expand
1260 | summary: (32) expand
1261 |
1261 |
1262 o changeset: 27:886ed638191b
1262 o changeset: 27:886ed638191b
1263 parent: 21:d42a756af44d
1263 parent: 21:d42a756af44d
1264 user: test
1264 user: test
1265 date: Thu Jan 01 00:00:27 1970 +0000
1265 date: Thu Jan 01 00:00:27 1970 +0000
1266 summary: (27) collapse
1266 summary: (27) collapse
1267
1267
1268
1268
1269 File + limit with revs != cset revs:
1269 File + limit with revs != cset revs:
1270 $ cd repo
1270 $ cd repo
1271 $ touch b
1271 $ touch b
1272 $ hg ci -Aqm0
1272 $ hg ci -Aqm0
1273 $ hg glog -l2 a
1273 $ hg glog -l2 a
1274 o changeset: 34:fea3ac5810e0
1274 o changeset: 34:fea3ac5810e0
1275 | parent: 32:d06dffa21a31
1275 | parent: 32:d06dffa21a31
1276 | user: test
1276 | user: test
1277 | date: Thu Jan 01 00:00:34 1970 +0000
1277 | date: Thu Jan 01 00:00:34 1970 +0000
1278 | summary: (34) head
1278 | summary: (34) head
1279 |
1279 |
1280 | o changeset: 33:68608f5145f9
1280 | o changeset: 33:68608f5145f9
1281 | | parent: 18:1aa84d96232a
1281 | | parent: 18:1aa84d96232a
1282 | | user: test
1282 | | user: test
1283 | | date: Thu Jan 01 00:00:33 1970 +0000
1283 | | date: Thu Jan 01 00:00:33 1970 +0000
1284 | | summary: (33) head
1284 | | summary: (33) head
1285 | |
1285 | |
1286
1286
1287 File + limit + -ra:b, (b - a) < limit:
1287 File + limit + -ra:b, (b - a) < limit:
1288 $ hg glog -l3000 -r32:tip a
1288 $ hg glog -l3000 -r32:tip a
1289 o changeset: 34:fea3ac5810e0
1289 o changeset: 34:fea3ac5810e0
1290 | parent: 32:d06dffa21a31
1290 | parent: 32:d06dffa21a31
1291 | user: test
1291 | user: test
1292 | date: Thu Jan 01 00:00:34 1970 +0000
1292 | date: Thu Jan 01 00:00:34 1970 +0000
1293 | summary: (34) head
1293 | summary: (34) head
1294 |
1294 |
1295 | o changeset: 33:68608f5145f9
1295 | o changeset: 33:68608f5145f9
1296 | | parent: 18:1aa84d96232a
1296 | | parent: 18:1aa84d96232a
1297 | | user: test
1297 | | user: test
1298 | | date: Thu Jan 01 00:00:33 1970 +0000
1298 | | date: Thu Jan 01 00:00:33 1970 +0000
1299 | | summary: (33) head
1299 | | summary: (33) head
1300 | |
1300 | |
1301 o | changeset: 32:d06dffa21a31
1301 o | changeset: 32:d06dffa21a31
1302 |\ \ parent: 27:886ed638191b
1302 |\ \ parent: 27:886ed638191b
1303 | | | parent: 31:621d83e11f67
1303 | | | parent: 31:621d83e11f67
1304 | | | user: test
1304 | | | user: test
1305 | | | date: Thu Jan 01 00:00:32 1970 +0000
1305 | | | date: Thu Jan 01 00:00:32 1970 +0000
1306 | | | summary: (32) expand
1306 | | | summary: (32) expand
1307 | | |
1307 | | |
1308
1308
1309 Point out a common and an uncommon unshown parent
1309 Point out a common and an uncommon unshown parent
1310
1310
1311 $ hg glog -r 'rev(8) or rev(9)'
1311 $ hg glog -r 'rev(8) or rev(9)'
1312 o changeset: 9:7010c0af0a35
1312 o changeset: 9:7010c0af0a35
1313 |\ parent: 7:b632bb1b1224
1313 |\ parent: 7:b632bb1b1224
1314 | | parent: 8:7a0b11f71937
1314 | | parent: 8:7a0b11f71937
1315 | | user: test
1315 | | user: test
1316 | | date: Thu Jan 01 00:00:09 1970 +0000
1316 | | date: Thu Jan 01 00:00:09 1970 +0000
1317 | | summary: (9) expand
1317 | | summary: (9) expand
1318 | |
1318 | |
1319 o | changeset: 8:7a0b11f71937
1319 o | changeset: 8:7a0b11f71937
1320 |\| parent: 0:e6eb3150255d
1320 |\| parent: 0:e6eb3150255d
1321 | | parent: 7:b632bb1b1224
1321 | | parent: 7:b632bb1b1224
1322 | | user: test
1322 | | user: test
1323 | | date: Thu Jan 01 00:00:08 1970 +0000
1323 | | date: Thu Jan 01 00:00:08 1970 +0000
1324 | | summary: (8) merge two known; one immediate left, one far right
1324 | | summary: (8) merge two known; one immediate left, one far right
1325 | |
1325 | |
1326
1326
1327 File + limit + -ra:b, b < tip:
1327 File + limit + -ra:b, b < tip:
1328
1328
1329 $ hg glog -l1 -r32:34 a
1329 $ hg glog -l1 -r32:34 a
1330 o changeset: 34:fea3ac5810e0
1330 o changeset: 34:fea3ac5810e0
1331 | parent: 32:d06dffa21a31
1331 | parent: 32:d06dffa21a31
1332 | user: test
1332 | user: test
1333 | date: Thu Jan 01 00:00:34 1970 +0000
1333 | date: Thu Jan 01 00:00:34 1970 +0000
1334 | summary: (34) head
1334 | summary: (34) head
1335 |
1335 |
1336
1336
1337 file(File) + limit + -ra:b, b < tip:
1337 file(File) + limit + -ra:b, b < tip:
1338
1338
1339 $ hg glog -l1 -r32:34 -r 'file("a")'
1339 $ hg glog -l1 -r32:34 -r 'file("a")'
1340 o changeset: 34:fea3ac5810e0
1340 o changeset: 34:fea3ac5810e0
1341 | parent: 32:d06dffa21a31
1341 | parent: 32:d06dffa21a31
1342 | user: test
1342 | user: test
1343 | date: Thu Jan 01 00:00:34 1970 +0000
1343 | date: Thu Jan 01 00:00:34 1970 +0000
1344 | summary: (34) head
1344 | summary: (34) head
1345 |
1345 |
1346
1346
1347 limit(file(File) and a::b), b < tip:
1347 limit(file(File) and a::b), b < tip:
1348
1348
1349 $ hg glog -r 'limit(file("a") and 32::34, 1)'
1349 $ hg glog -r 'limit(file("a") and 32::34, 1)'
1350 o changeset: 32:d06dffa21a31
1350 o changeset: 32:d06dffa21a31
1351 |\ parent: 27:886ed638191b
1351 |\ parent: 27:886ed638191b
1352 | | parent: 31:621d83e11f67
1352 | | parent: 31:621d83e11f67
1353 | | user: test
1353 | | user: test
1354 | | date: Thu Jan 01 00:00:32 1970 +0000
1354 | | date: Thu Jan 01 00:00:32 1970 +0000
1355 | | summary: (32) expand
1355 | | summary: (32) expand
1356 | |
1356 | |
1357
1357
1358 File + limit + -ra:b, b < tip:
1358 File + limit + -ra:b, b < tip:
1359
1359
1360 $ hg glog -r 'limit(file("a") and 34::32, 1)'
1360 $ hg glog -r 'limit(file("a") and 34::32, 1)'
1361
1361
1362 File + limit + -ra:b, b < tip, (b - a) < limit:
1362 File + limit + -ra:b, b < tip, (b - a) < limit:
1363
1363
1364 $ hg glog -l10 -r33:34 a
1364 $ hg glog -l10 -r33:34 a
1365 o changeset: 34:fea3ac5810e0
1365 o changeset: 34:fea3ac5810e0
1366 | parent: 32:d06dffa21a31
1366 | parent: 32:d06dffa21a31
1367 | user: test
1367 | user: test
1368 | date: Thu Jan 01 00:00:34 1970 +0000
1368 | date: Thu Jan 01 00:00:34 1970 +0000
1369 | summary: (34) head
1369 | summary: (34) head
1370 |
1370 |
1371 | o changeset: 33:68608f5145f9
1371 | o changeset: 33:68608f5145f9
1372 | | parent: 18:1aa84d96232a
1372 | | parent: 18:1aa84d96232a
1373 | | user: test
1373 | | user: test
1374 | | date: Thu Jan 01 00:00:33 1970 +0000
1374 | | date: Thu Jan 01 00:00:33 1970 +0000
1375 | | summary: (33) head
1375 | | summary: (33) head
1376 | |
1376 | |
1377
1377
1378 Do not crash or produce strange graphs if history is buggy
1378 Do not crash or produce strange graphs if history is buggy
1379
1379
1380 $ hg branch branch
1380 $ hg branch branch
1381 marked working directory as branch branch
1381 marked working directory as branch branch
1382 (branches are permanent and global, did you want a bookmark?)
1382 (branches are permanent and global, did you want a bookmark?)
1383 $ commit 36 "buggy merge: identical parents" 35 35
1383 $ commit 36 "buggy merge: identical parents" 35 35
1384 $ hg glog -l5
1384 $ hg glog -l5
1385 @ changeset: 36:08a19a744424
1385 @ changeset: 36:08a19a744424
1386 | branch: branch
1386 | branch: branch
1387 | tag: tip
1387 | tag: tip
1388 | parent: 35:9159c3644c5e
1388 | parent: 35:9159c3644c5e
1389 | parent: 35:9159c3644c5e
1389 | parent: 35:9159c3644c5e
1390 | user: test
1390 | user: test
1391 | date: Thu Jan 01 00:00:36 1970 +0000
1391 | date: Thu Jan 01 00:00:36 1970 +0000
1392 | summary: (36) buggy merge: identical parents
1392 | summary: (36) buggy merge: identical parents
1393 |
1393 |
1394 o changeset: 35:9159c3644c5e
1394 o changeset: 35:9159c3644c5e
1395 | user: test
1395 | user: test
1396 | date: Thu Jan 01 00:00:00 1970 +0000
1396 | date: Thu Jan 01 00:00:00 1970 +0000
1397 | summary: 0
1397 | summary: 0
1398 |
1398 |
1399 o changeset: 34:fea3ac5810e0
1399 o changeset: 34:fea3ac5810e0
1400 | parent: 32:d06dffa21a31
1400 | parent: 32:d06dffa21a31
1401 | user: test
1401 | user: test
1402 | date: Thu Jan 01 00:00:34 1970 +0000
1402 | date: Thu Jan 01 00:00:34 1970 +0000
1403 | summary: (34) head
1403 | summary: (34) head
1404 |
1404 |
1405 | o changeset: 33:68608f5145f9
1405 | o changeset: 33:68608f5145f9
1406 | | parent: 18:1aa84d96232a
1406 | | parent: 18:1aa84d96232a
1407 | | user: test
1407 | | user: test
1408 | | date: Thu Jan 01 00:00:33 1970 +0000
1408 | | date: Thu Jan 01 00:00:33 1970 +0000
1409 | | summary: (33) head
1409 | | summary: (33) head
1410 | |
1410 | |
1411 o | changeset: 32:d06dffa21a31
1411 o | changeset: 32:d06dffa21a31
1412 |\ \ parent: 27:886ed638191b
1412 |\ \ parent: 27:886ed638191b
1413 | | | parent: 31:621d83e11f67
1413 | | | parent: 31:621d83e11f67
1414 | | | user: test
1414 | | | user: test
1415 | | | date: Thu Jan 01 00:00:32 1970 +0000
1415 | | | date: Thu Jan 01 00:00:32 1970 +0000
1416 | | | summary: (32) expand
1416 | | | summary: (32) expand
1417 | | |
1417 | | |
1418
1418
1419 Test log -G options
1419 Test log -G options
1420
1420
1421 $ testlog() {
1421 $ testlog() {
1422 > hg log -G --print-revset "$@"
1422 > hg log -G --print-revset "$@"
1423 > hg log --template 'nodetag {rev}\n' "$@" | grep nodetag \
1423 > hg log --template 'nodetag {rev}\n' "$@" | grep nodetag \
1424 > | sed 's/.*nodetag/nodetag/' > log.nodes
1424 > | sed 's/.*nodetag/nodetag/' > log.nodes
1425 > hg log -G --template 'nodetag {rev}\n' "$@" | grep nodetag \
1425 > hg log -G --template 'nodetag {rev}\n' "$@" | grep nodetag \
1426 > | sed 's/.*nodetag/nodetag/' > glog.nodes
1426 > | sed 's/.*nodetag/nodetag/' > glog.nodes
1427 > diff -u log.nodes glog.nodes
1427 > diff -u log.nodes glog.nodes
1428 > }
1428 > }
1429
1429
1430 glog always reorders nodes which explains the difference with log
1430 glog always reorders nodes which explains the difference with log
1431
1431
1432 $ testlog -r 27 -r 25 -r 21 -r 34 -r 32 -r 31
1432 $ testlog -r 27 -r 25 -r 21 -r 34 -r 32 -r 31
1433 ('group', ('group', ('or', ('or', ('or', ('or', ('or', ('symbol', '27'), ('symbol', '25')), ('symbol', '21')), ('symbol', '34')), ('symbol', '32')), ('symbol', '31'))))
1433 ('group', ('group', ('or', ('or', ('or', ('or', ('or', ('symbol', '27'), ('symbol', '25')), ('symbol', '21')), ('symbol', '34')), ('symbol', '32')), ('symbol', '31'))))
1434 --- log.nodes * (glob)
1434 --- log.nodes * (glob)
1435 +++ glog.nodes * (glob)
1435 +++ glog.nodes * (glob)
1436 @@ -1,6 +1,6 @@
1436 @@ -1,6 +1,6 @@
1437 -nodetag 27
1437 -nodetag 27
1438 -nodetag 25
1438 -nodetag 25
1439 -nodetag 21
1439 -nodetag 21
1440 nodetag 34
1440 nodetag 34
1441 nodetag 32
1441 nodetag 32
1442 nodetag 31
1442 nodetag 31
1443 +nodetag 27
1443 +nodetag 27
1444 +nodetag 25
1444 +nodetag 25
1445 +nodetag 21
1445 +nodetag 21
1446 [1]
1446 [1]
1447 $ testlog -u test -u not-a-user
1447 $ testlog -u test -u not-a-user
1448 ('group', ('group', ('or', ('func', ('symbol', 'user'), ('string', 'test')), ('func', ('symbol', 'user'), ('string', 'not-a-user')))))
1448 ('group', ('group', ('or', ('func', ('symbol', 'user'), ('string', 'test')), ('func', ('symbol', 'user'), ('string', 'not-a-user')))))
1449 $ testlog -b not-a-branch
1449 $ testlog -b not-a-branch
1450 ('group', ('group', ('func', ('symbol', 'branch'), ('string', 'not-a-branch'))))
1450 ('group', ('group', ('func', ('symbol', 'branch'), ('string', 'not-a-branch'))))
1451 abort: unknown revision 'not-a-branch'!
1451 abort: unknown revision 'not-a-branch'!
1452 abort: unknown revision 'not-a-branch'!
1452 abort: unknown revision 'not-a-branch'!
1453 $ testlog -b default -b branch --only-branch branch
1453 $ testlog -b default -b branch --only-branch branch
1454 ('group', ('group', ('or', ('or', ('func', ('symbol', 'branch'), ('string', 'default')), ('func', ('symbol', 'branch'), ('string', 'branch'))), ('func', ('symbol', 'branch'), ('string', 'branch')))))
1454 ('group', ('group', ('or', ('or', ('func', ('symbol', 'branch'), ('string', 'default')), ('func', ('symbol', 'branch'), ('string', 'branch'))), ('func', ('symbol', 'branch'), ('string', 'branch')))))
1455 $ testlog -k expand -k merge
1455 $ testlog -k expand -k merge
1456 ('group', ('group', ('or', ('func', ('symbol', 'keyword'), ('string', 'expand')), ('func', ('symbol', 'keyword'), ('string', 'merge')))))
1456 ('group', ('group', ('or', ('func', ('symbol', 'keyword'), ('string', 'expand')), ('func', ('symbol', 'keyword'), ('string', 'merge')))))
1457 $ hg log -G --follow --template 'nodetag {rev}\n' | grep nodetag | wc -l
1457 $ hg log -G --follow --template 'nodetag {rev}\n' | grep nodetag | wc -l
1458 \s*36 (re)
1458 \s*36 (re)
1459 $ hg log -G --removed --template 'nodetag {rev}\n' | grep nodetag | wc -l
1459 $ hg log -G --removed --template 'nodetag {rev}\n' | grep nodetag | wc -l
1460 \s*0 (re)
1460 \s*0 (re)
1461 $ hg log -G --only-merges --template 'nodetag {rev}\n' | grep nodetag | wc -l
1461 $ hg log -G --only-merges --template 'nodetag {rev}\n' | grep nodetag | wc -l
1462 \s*28 (re)
1462 \s*28 (re)
1463 $ hg log -G --no-merges --template 'nodetag {rev}\n'
1463 $ hg log -G --no-merges --template 'nodetag {rev}\n'
1464 o nodetag 35
1464 o nodetag 35
1465 |
1465 |
1466 o nodetag 34
1466 o nodetag 34
1467 |\
1467 |\
1468 | \
1468 | \
1469 | |\
1469 | |\
1470 | | \
1470 | | \
1471 | | |\
1471 | | |\
1472 | | | \
1472 | | | \
1473 | | | |\
1473 | | | |\
1474 | | | | \
1474 | | | | \
1475 | | | | |\
1475 | | | | |\
1476 +-+-+-+-----o nodetag 33
1476 +-+-+-+-----o nodetag 33
1477 | | | | | |
1477 | | | | | |
1478 +---------o nodetag 29
1478 +---------o nodetag 29
1479 | | | | |
1479 | | | | |
1480 +-+-+---o nodetag 27
1480 +-+-+---o nodetag 27
1481 | | | |/
1481 | | | |/
1482 | | | o nodetag 3
1482 | | | o nodetag 3
1483 | | |/
1483 | | |/
1484 | | o nodetag 2
1484 | | o nodetag 2
1485 | |/
1485 | |/
1486 | o nodetag 1
1486 | o nodetag 1
1487 |/
1487 |/
1488 o nodetag 0
1488 o nodetag 0
1489
1489
1490 $ hg log -G -d 'brace ) in a date'
1490 $ hg log -G -d 'brace ) in a date'
1491 abort: invalid date: 'brace ) in a date'
1491 abort: invalid date: 'brace ) in a date'
1492 [255]
1492 [255]
1493 $ hg log -G -P 32 --template '{rev}\n'
1493 $ hg log -G -P 32 --template '{rev}\n'
1494 @ 36
1494 @ 36
1495 |
1495 |
1496 o 35
1496 o 35
1497 |
1497 |
1498 o 34
1498 o 34
1499 |
1499 |
1500 | o 33
1500 | o 33
1501 | |
1501 | |
1502 $ hg log -G --follow a
1502 $ hg log -G --follow a
1503 abort: -G/--graph option is incompatible with --follow with file argument
1503 abort: -G/--graph option is incompatible with --follow with file argument
1504 [255]
1504 [255]
1505
1505
1506
1506
1507 Dedicated repo for --follow and paths filtering
1507 Dedicated repo for --follow and paths filtering
1508
1508
1509 $ cd ..
1509 $ cd ..
1510 $ hg init follow
1510 $ hg init follow
1511 $ cd follow
1511 $ cd follow
1512 $ echo a > a
1512 $ echo a > a
1513 $ echo aa > aa
1513 $ hg ci -Am "add a"
1514 $ hg ci -Am "add a"
1514 adding a
1515 adding a
1516 adding aa
1515 $ hg cp a b
1517 $ hg cp a b
1516 $ hg ci -m "copy a b"
1518 $ hg ci -m "copy a b"
1517 $ mkdir dir
1519 $ mkdir dir
1518 $ hg mv b dir
1520 $ hg mv b dir
1519 $ hg ci -m "mv b dir/b"
1521 $ hg ci -m "mv b dir/b"
1520 $ hg mv a b
1522 $ hg mv a b
1521 $ echo a > d
1523 $ echo a > d
1522 $ hg add d
1524 $ hg add d
1523 $ hg ci -m "mv a b; add d"
1525 $ hg ci -m "mv a b; add d"
1524 $ hg mv dir/b e
1526 $ hg mv dir/b e
1525 $ hg ci -m "mv dir/b e"
1527 $ hg ci -m "mv dir/b e"
1526 $ hg glog --template '({rev}) {desc|firstline}\n'
1528 $ hg glog --template '({rev}) {desc|firstline}\n'
1527 @ (4) mv dir/b e
1529 @ (4) mv dir/b e
1528 |
1530 |
1529 o (3) mv a b; add d
1531 o (3) mv a b; add d
1530 |
1532 |
1531 o (2) mv b dir/b
1533 o (2) mv b dir/b
1532 |
1534 |
1533 o (1) copy a b
1535 o (1) copy a b
1534 |
1536 |
1535 o (0) add a
1537 o (0) add a
1536
1538
1537
1539
1538 $ testlog a
1540 $ testlog a
1539 ('group', ('group', ('func', ('symbol', 'filelog'), ('string', 'a'))))
1541 ('group', ('group', ('func', ('symbol', 'filelog'), ('string', 'a'))))
1540 $ testlog a b
1542 $ testlog a b
1541 ('group', ('group', ('or', ('func', ('symbol', 'filelog'), ('string', 'a')), ('func', ('symbol', 'filelog'), ('string', 'b')))))
1543 ('group', ('group', ('or', ('func', ('symbol', 'filelog'), ('string', 'a')), ('func', ('symbol', 'filelog'), ('string', 'b')))))
1542
1544
1543 Test falling back to slow path for non-existing files
1545 Test falling back to slow path for non-existing files
1544
1546
1545 $ testlog a c
1547 $ testlog a c
1546 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('string', 'p:a'), ('string', 'p:c')))))
1548 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('string', 'p:a'), ('string', 'p:c')))))
1547
1549
1548 Test multiple --include/--exclude/paths
1550 Test multiple --include/--exclude/paths
1549
1551
1550 $ testlog --include a --include e --exclude b --exclude e a e
1552 $ testlog --include a --include e --exclude b --exclude e a e
1551 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('list', ('list', ('list', ('list', ('string', 'p:a'), ('string', 'p:e')), ('string', 'i:a')), ('string', 'i:e')), ('string', 'x:b')), ('string', 'x:e')))))
1553 ('group', ('group', ('func', ('symbol', '_matchfiles'), ('list', ('list', ('list', ('list', ('list', ('string', 'p:a'), ('string', 'p:e')), ('string', 'i:a')), ('string', 'i:e')), ('string', 'x:b')), ('string', 'x:e')))))
1554
1555 Test glob expansion of pats
1556
1557 $ expandglobs=`python -c "import mercurial.util; \
1558 > print mercurial.util.expandglobs and 'true' or 'false'"`
1559 $ if [ $expandglobs = "true" ]; then
1560 > testlog 'a*';
1561 > else
1562 > testlog a*;
1563 > fi;
1564 ('group', ('group', ('func', ('symbol', 'filelog'), ('string', 'aa'))))
General Comments 0
You need to be logged in to leave comments. Login now