##// END OF EJS Templates
templates: adjust white space amount in the output of {whyunstable}...
av6 -
r37725:24fee31f default
parent child Browse files
Show More
@@ -1,827 +1,828 b''
1 # templatekw.py - common changeset template keywords
1 # templatekw.py - common changeset template keywords
2 #
2 #
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2009 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 __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from .i18n import _
10 from .i18n import _
11 from .node import (
11 from .node import (
12 hex,
12 hex,
13 nullid,
13 nullid,
14 )
14 )
15
15
16 from . import (
16 from . import (
17 encoding,
17 encoding,
18 error,
18 error,
19 hbisect,
19 hbisect,
20 i18n,
20 i18n,
21 obsutil,
21 obsutil,
22 patch,
22 patch,
23 pycompat,
23 pycompat,
24 registrar,
24 registrar,
25 scmutil,
25 scmutil,
26 templateutil,
26 templateutil,
27 util,
27 util,
28 )
28 )
29 from .utils import (
29 from .utils import (
30 stringutil,
30 stringutil,
31 )
31 )
32
32
33 _hybrid = templateutil.hybrid
33 _hybrid = templateutil.hybrid
34 _mappable = templateutil.mappable
34 _mappable = templateutil.mappable
35 hybriddict = templateutil.hybriddict
35 hybriddict = templateutil.hybriddict
36 hybridlist = templateutil.hybridlist
36 hybridlist = templateutil.hybridlist
37 compatdict = templateutil.compatdict
37 compatdict = templateutil.compatdict
38 compatlist = templateutil.compatlist
38 compatlist = templateutil.compatlist
39 _showcompatlist = templateutil._showcompatlist
39 _showcompatlist = templateutil._showcompatlist
40
40
41 def _showlist(name, values, templ, mapping, plural=None, separator=' '):
41 def _showlist(name, values, templ, mapping, plural=None, separator=' '):
42 ui = mapping.get('ui')
42 ui = mapping.get('ui')
43 if ui:
43 if ui:
44 ui.deprecwarn("templatekw._showlist() is deprecated, use "
44 ui.deprecwarn("templatekw._showlist() is deprecated, use "
45 "templateutil._showcompatlist()", '4.6')
45 "templateutil._showcompatlist()", '4.6')
46 context = templ # this is actually a template context, not a templater
46 context = templ # this is actually a template context, not a templater
47 return _showcompatlist(context, mapping, name, values, plural, separator)
47 return _showcompatlist(context, mapping, name, values, plural, separator)
48
48
49 def showdict(name, data, mapping, plural=None, key='key', value='value',
49 def showdict(name, data, mapping, plural=None, key='key', value='value',
50 fmt=None, separator=' '):
50 fmt=None, separator=' '):
51 ui = mapping.get('ui')
51 ui = mapping.get('ui')
52 if ui:
52 if ui:
53 ui.deprecwarn("templatekw.showdict() is deprecated, use "
53 ui.deprecwarn("templatekw.showdict() is deprecated, use "
54 "templateutil.compatdict()", '4.6')
54 "templateutil.compatdict()", '4.6')
55 c = [{key: k, value: v} for k, v in data.iteritems()]
55 c = [{key: k, value: v} for k, v in data.iteritems()]
56 f = _showlist(name, c, mapping['templ'], mapping, plural, separator)
56 f = _showlist(name, c, mapping['templ'], mapping, plural, separator)
57 return hybriddict(data, key=key, value=value, fmt=fmt, gen=f)
57 return hybriddict(data, key=key, value=value, fmt=fmt, gen=f)
58
58
59 def showlist(name, values, mapping, plural=None, element=None, separator=' '):
59 def showlist(name, values, mapping, plural=None, element=None, separator=' '):
60 ui = mapping.get('ui')
60 ui = mapping.get('ui')
61 if ui:
61 if ui:
62 ui.deprecwarn("templatekw.showlist() is deprecated, use "
62 ui.deprecwarn("templatekw.showlist() is deprecated, use "
63 "templateutil.compatlist()", '4.6')
63 "templateutil.compatlist()", '4.6')
64 if not element:
64 if not element:
65 element = name
65 element = name
66 f = _showlist(name, values, mapping['templ'], mapping, plural, separator)
66 f = _showlist(name, values, mapping['templ'], mapping, plural, separator)
67 return hybridlist(values, name=element, gen=f)
67 return hybridlist(values, name=element, gen=f)
68
68
69 def getlatesttags(context, mapping, pattern=None):
69 def getlatesttags(context, mapping, pattern=None):
70 '''return date, distance and name for the latest tag of rev'''
70 '''return date, distance and name for the latest tag of rev'''
71 repo = context.resource(mapping, 'repo')
71 repo = context.resource(mapping, 'repo')
72 ctx = context.resource(mapping, 'ctx')
72 ctx = context.resource(mapping, 'ctx')
73 cache = context.resource(mapping, 'cache')
73 cache = context.resource(mapping, 'cache')
74
74
75 cachename = 'latesttags'
75 cachename = 'latesttags'
76 if pattern is not None:
76 if pattern is not None:
77 cachename += '-' + pattern
77 cachename += '-' + pattern
78 match = stringutil.stringmatcher(pattern)[2]
78 match = stringutil.stringmatcher(pattern)[2]
79 else:
79 else:
80 match = util.always
80 match = util.always
81
81
82 if cachename not in cache:
82 if cachename not in cache:
83 # Cache mapping from rev to a tuple with tag date, tag
83 # Cache mapping from rev to a tuple with tag date, tag
84 # distance and tag name
84 # distance and tag name
85 cache[cachename] = {-1: (0, 0, ['null'])}
85 cache[cachename] = {-1: (0, 0, ['null'])}
86 latesttags = cache[cachename]
86 latesttags = cache[cachename]
87
87
88 rev = ctx.rev()
88 rev = ctx.rev()
89 todo = [rev]
89 todo = [rev]
90 while todo:
90 while todo:
91 rev = todo.pop()
91 rev = todo.pop()
92 if rev in latesttags:
92 if rev in latesttags:
93 continue
93 continue
94 ctx = repo[rev]
94 ctx = repo[rev]
95 tags = [t for t in ctx.tags()
95 tags = [t for t in ctx.tags()
96 if (repo.tagtype(t) and repo.tagtype(t) != 'local'
96 if (repo.tagtype(t) and repo.tagtype(t) != 'local'
97 and match(t))]
97 and match(t))]
98 if tags:
98 if tags:
99 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
99 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
100 continue
100 continue
101 try:
101 try:
102 ptags = [latesttags[p.rev()] for p in ctx.parents()]
102 ptags = [latesttags[p.rev()] for p in ctx.parents()]
103 if len(ptags) > 1:
103 if len(ptags) > 1:
104 if ptags[0][2] == ptags[1][2]:
104 if ptags[0][2] == ptags[1][2]:
105 # The tuples are laid out so the right one can be found by
105 # The tuples are laid out so the right one can be found by
106 # comparison in this case.
106 # comparison in this case.
107 pdate, pdist, ptag = max(ptags)
107 pdate, pdist, ptag = max(ptags)
108 else:
108 else:
109 def key(x):
109 def key(x):
110 changessincetag = len(repo.revs('only(%d, %s)',
110 changessincetag = len(repo.revs('only(%d, %s)',
111 ctx.rev(), x[2][0]))
111 ctx.rev(), x[2][0]))
112 # Smallest number of changes since tag wins. Date is
112 # Smallest number of changes since tag wins. Date is
113 # used as tiebreaker.
113 # used as tiebreaker.
114 return [-changessincetag, x[0]]
114 return [-changessincetag, x[0]]
115 pdate, pdist, ptag = max(ptags, key=key)
115 pdate, pdist, ptag = max(ptags, key=key)
116 else:
116 else:
117 pdate, pdist, ptag = ptags[0]
117 pdate, pdist, ptag = ptags[0]
118 except KeyError:
118 except KeyError:
119 # Cache miss - recurse
119 # Cache miss - recurse
120 todo.append(rev)
120 todo.append(rev)
121 todo.extend(p.rev() for p in ctx.parents())
121 todo.extend(p.rev() for p in ctx.parents())
122 continue
122 continue
123 latesttags[rev] = pdate, pdist + 1, ptag
123 latesttags[rev] = pdate, pdist + 1, ptag
124 return latesttags[rev]
124 return latesttags[rev]
125
125
126 def getrenamedfn(repo, endrev=None):
126 def getrenamedfn(repo, endrev=None):
127 rcache = {}
127 rcache = {}
128 if endrev is None:
128 if endrev is None:
129 endrev = len(repo)
129 endrev = len(repo)
130
130
131 def getrenamed(fn, rev):
131 def getrenamed(fn, rev):
132 '''looks up all renames for a file (up to endrev) the first
132 '''looks up all renames for a file (up to endrev) the first
133 time the file is given. It indexes on the changerev and only
133 time the file is given. It indexes on the changerev and only
134 parses the manifest if linkrev != changerev.
134 parses the manifest if linkrev != changerev.
135 Returns rename info for fn at changerev rev.'''
135 Returns rename info for fn at changerev rev.'''
136 if fn not in rcache:
136 if fn not in rcache:
137 rcache[fn] = {}
137 rcache[fn] = {}
138 fl = repo.file(fn)
138 fl = repo.file(fn)
139 for i in fl:
139 for i in fl:
140 lr = fl.linkrev(i)
140 lr = fl.linkrev(i)
141 renamed = fl.renamed(fl.node(i))
141 renamed = fl.renamed(fl.node(i))
142 rcache[fn][lr] = renamed
142 rcache[fn][lr] = renamed
143 if lr >= endrev:
143 if lr >= endrev:
144 break
144 break
145 if rev in rcache[fn]:
145 if rev in rcache[fn]:
146 return rcache[fn][rev]
146 return rcache[fn][rev]
147
147
148 # If linkrev != rev (i.e. rev not found in rcache) fallback to
148 # If linkrev != rev (i.e. rev not found in rcache) fallback to
149 # filectx logic.
149 # filectx logic.
150 try:
150 try:
151 return repo[rev][fn].renamed()
151 return repo[rev][fn].renamed()
152 except error.LookupError:
152 except error.LookupError:
153 return None
153 return None
154
154
155 return getrenamed
155 return getrenamed
156
156
157 def getlogcolumns():
157 def getlogcolumns():
158 """Return a dict of log column labels"""
158 """Return a dict of log column labels"""
159 _ = pycompat.identity # temporarily disable gettext
159 _ = pycompat.identity # temporarily disable gettext
160 # i18n: column positioning for "hg log"
160 # i18n: column positioning for "hg log"
161 columns = _('bookmark: %s\n'
161 columns = _('bookmark: %s\n'
162 'branch: %s\n'
162 'branch: %s\n'
163 'changeset: %s\n'
163 'changeset: %s\n'
164 'copies: %s\n'
164 'copies: %s\n'
165 'date: %s\n'
165 'date: %s\n'
166 'extra: %s=%s\n'
166 'extra: %s=%s\n'
167 'files+: %s\n'
167 'files+: %s\n'
168 'files-: %s\n'
168 'files-: %s\n'
169 'files: %s\n'
169 'files: %s\n'
170 'instability: %s\n'
170 'instability: %s\n'
171 'manifest: %s\n'
171 'manifest: %s\n'
172 'obsolete: %s\n'
172 'obsolete: %s\n'
173 'parent: %s\n'
173 'parent: %s\n'
174 'phase: %s\n'
174 'phase: %s\n'
175 'summary: %s\n'
175 'summary: %s\n'
176 'tag: %s\n'
176 'tag: %s\n'
177 'user: %s\n')
177 'user: %s\n')
178 return dict(zip([s.split(':', 1)[0] for s in columns.splitlines()],
178 return dict(zip([s.split(':', 1)[0] for s in columns.splitlines()],
179 i18n._(columns).splitlines(True)))
179 i18n._(columns).splitlines(True)))
180
180
181 # default templates internally used for rendering of lists
181 # default templates internally used for rendering of lists
182 defaulttempl = {
182 defaulttempl = {
183 'parent': '{rev}:{node|formatnode} ',
183 'parent': '{rev}:{node|formatnode} ',
184 'manifest': '{rev}:{node|formatnode}',
184 'manifest': '{rev}:{node|formatnode}',
185 'file_copy': '{name} ({source})',
185 'file_copy': '{name} ({source})',
186 'envvar': '{key}={value}',
186 'envvar': '{key}={value}',
187 'extra': '{key}={value|stringescape}'
187 'extra': '{key}={value|stringescape}'
188 }
188 }
189 # filecopy is preserved for compatibility reasons
189 # filecopy is preserved for compatibility reasons
190 defaulttempl['filecopy'] = defaulttempl['file_copy']
190 defaulttempl['filecopy'] = defaulttempl['file_copy']
191
191
192 # keywords are callables (see registrar.templatekeyword for details)
192 # keywords are callables (see registrar.templatekeyword for details)
193 keywords = {}
193 keywords = {}
194 templatekeyword = registrar.templatekeyword(keywords)
194 templatekeyword = registrar.templatekeyword(keywords)
195
195
196 @templatekeyword('author', requires={'ctx'})
196 @templatekeyword('author', requires={'ctx'})
197 def showauthor(context, mapping):
197 def showauthor(context, mapping):
198 """String. The unmodified author of the changeset."""
198 """String. The unmodified author of the changeset."""
199 ctx = context.resource(mapping, 'ctx')
199 ctx = context.resource(mapping, 'ctx')
200 return ctx.user()
200 return ctx.user()
201
201
202 @templatekeyword('bisect', requires={'repo', 'ctx'})
202 @templatekeyword('bisect', requires={'repo', 'ctx'})
203 def showbisect(context, mapping):
203 def showbisect(context, mapping):
204 """String. The changeset bisection status."""
204 """String. The changeset bisection status."""
205 repo = context.resource(mapping, 'repo')
205 repo = context.resource(mapping, 'repo')
206 ctx = context.resource(mapping, 'ctx')
206 ctx = context.resource(mapping, 'ctx')
207 return hbisect.label(repo, ctx.node())
207 return hbisect.label(repo, ctx.node())
208
208
209 @templatekeyword('branch', requires={'ctx'})
209 @templatekeyword('branch', requires={'ctx'})
210 def showbranch(context, mapping):
210 def showbranch(context, mapping):
211 """String. The name of the branch on which the changeset was
211 """String. The name of the branch on which the changeset was
212 committed.
212 committed.
213 """
213 """
214 ctx = context.resource(mapping, 'ctx')
214 ctx = context.resource(mapping, 'ctx')
215 return ctx.branch()
215 return ctx.branch()
216
216
217 @templatekeyword('branches', requires={'ctx'})
217 @templatekeyword('branches', requires={'ctx'})
218 def showbranches(context, mapping):
218 def showbranches(context, mapping):
219 """List of strings. The name of the branch on which the
219 """List of strings. The name of the branch on which the
220 changeset was committed. Will be empty if the branch name was
220 changeset was committed. Will be empty if the branch name was
221 default. (DEPRECATED)
221 default. (DEPRECATED)
222 """
222 """
223 ctx = context.resource(mapping, 'ctx')
223 ctx = context.resource(mapping, 'ctx')
224 branch = ctx.branch()
224 branch = ctx.branch()
225 if branch != 'default':
225 if branch != 'default':
226 return compatlist(context, mapping, 'branch', [branch],
226 return compatlist(context, mapping, 'branch', [branch],
227 plural='branches')
227 plural='branches')
228 return compatlist(context, mapping, 'branch', [], plural='branches')
228 return compatlist(context, mapping, 'branch', [], plural='branches')
229
229
230 @templatekeyword('bookmarks', requires={'repo', 'ctx'})
230 @templatekeyword('bookmarks', requires={'repo', 'ctx'})
231 def showbookmarks(context, mapping):
231 def showbookmarks(context, mapping):
232 """List of strings. Any bookmarks associated with the
232 """List of strings. Any bookmarks associated with the
233 changeset. Also sets 'active', the name of the active bookmark.
233 changeset. Also sets 'active', the name of the active bookmark.
234 """
234 """
235 repo = context.resource(mapping, 'repo')
235 repo = context.resource(mapping, 'repo')
236 ctx = context.resource(mapping, 'ctx')
236 ctx = context.resource(mapping, 'ctx')
237 bookmarks = ctx.bookmarks()
237 bookmarks = ctx.bookmarks()
238 active = repo._activebookmark
238 active = repo._activebookmark
239 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
239 makemap = lambda v: {'bookmark': v, 'active': active, 'current': active}
240 f = _showcompatlist(context, mapping, 'bookmark', bookmarks)
240 f = _showcompatlist(context, mapping, 'bookmark', bookmarks)
241 return _hybrid(f, bookmarks, makemap, pycompat.identity)
241 return _hybrid(f, bookmarks, makemap, pycompat.identity)
242
242
243 @templatekeyword('children', requires={'ctx'})
243 @templatekeyword('children', requires={'ctx'})
244 def showchildren(context, mapping):
244 def showchildren(context, mapping):
245 """List of strings. The children of the changeset."""
245 """List of strings. The children of the changeset."""
246 ctx = context.resource(mapping, 'ctx')
246 ctx = context.resource(mapping, 'ctx')
247 childrevs = ['%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()]
247 childrevs = ['%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()]
248 return compatlist(context, mapping, 'children', childrevs, element='child')
248 return compatlist(context, mapping, 'children', childrevs, element='child')
249
249
250 # Deprecated, but kept alive for help generation a purpose.
250 # Deprecated, but kept alive for help generation a purpose.
251 @templatekeyword('currentbookmark', requires={'repo', 'ctx'})
251 @templatekeyword('currentbookmark', requires={'repo', 'ctx'})
252 def showcurrentbookmark(context, mapping):
252 def showcurrentbookmark(context, mapping):
253 """String. The active bookmark, if it is associated with the changeset.
253 """String. The active bookmark, if it is associated with the changeset.
254 (DEPRECATED)"""
254 (DEPRECATED)"""
255 return showactivebookmark(context, mapping)
255 return showactivebookmark(context, mapping)
256
256
257 @templatekeyword('activebookmark', requires={'repo', 'ctx'})
257 @templatekeyword('activebookmark', requires={'repo', 'ctx'})
258 def showactivebookmark(context, mapping):
258 def showactivebookmark(context, mapping):
259 """String. The active bookmark, if it is associated with the changeset."""
259 """String. The active bookmark, if it is associated with the changeset."""
260 repo = context.resource(mapping, 'repo')
260 repo = context.resource(mapping, 'repo')
261 ctx = context.resource(mapping, 'ctx')
261 ctx = context.resource(mapping, 'ctx')
262 active = repo._activebookmark
262 active = repo._activebookmark
263 if active and active in ctx.bookmarks():
263 if active and active in ctx.bookmarks():
264 return active
264 return active
265 return ''
265 return ''
266
266
267 @templatekeyword('date', requires={'ctx'})
267 @templatekeyword('date', requires={'ctx'})
268 def showdate(context, mapping):
268 def showdate(context, mapping):
269 """Date information. The date when the changeset was committed."""
269 """Date information. The date when the changeset was committed."""
270 ctx = context.resource(mapping, 'ctx')
270 ctx = context.resource(mapping, 'ctx')
271 return ctx.date()
271 return ctx.date()
272
272
273 @templatekeyword('desc', requires={'ctx'})
273 @templatekeyword('desc', requires={'ctx'})
274 def showdescription(context, mapping):
274 def showdescription(context, mapping):
275 """String. The text of the changeset description."""
275 """String. The text of the changeset description."""
276 ctx = context.resource(mapping, 'ctx')
276 ctx = context.resource(mapping, 'ctx')
277 s = ctx.description()
277 s = ctx.description()
278 if isinstance(s, encoding.localstr):
278 if isinstance(s, encoding.localstr):
279 # try hard to preserve utf-8 bytes
279 # try hard to preserve utf-8 bytes
280 return encoding.tolocal(encoding.fromlocal(s).strip())
280 return encoding.tolocal(encoding.fromlocal(s).strip())
281 else:
281 else:
282 return s.strip()
282 return s.strip()
283
283
284 @templatekeyword('diffstat', requires={'ctx'})
284 @templatekeyword('diffstat', requires={'ctx'})
285 def showdiffstat(context, mapping):
285 def showdiffstat(context, mapping):
286 """String. Statistics of changes with the following format:
286 """String. Statistics of changes with the following format:
287 "modified files: +added/-removed lines"
287 "modified files: +added/-removed lines"
288 """
288 """
289 ctx = context.resource(mapping, 'ctx')
289 ctx = context.resource(mapping, 'ctx')
290 stats = patch.diffstatdata(util.iterlines(ctx.diff(noprefix=False)))
290 stats = patch.diffstatdata(util.iterlines(ctx.diff(noprefix=False)))
291 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
291 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
292 return '%d: +%d/-%d' % (len(stats), adds, removes)
292 return '%d: +%d/-%d' % (len(stats), adds, removes)
293
293
294 @templatekeyword('envvars', requires={'ui'})
294 @templatekeyword('envvars', requires={'ui'})
295 def showenvvars(context, mapping):
295 def showenvvars(context, mapping):
296 """A dictionary of environment variables. (EXPERIMENTAL)"""
296 """A dictionary of environment variables. (EXPERIMENTAL)"""
297 ui = context.resource(mapping, 'ui')
297 ui = context.resource(mapping, 'ui')
298 env = ui.exportableenviron()
298 env = ui.exportableenviron()
299 env = util.sortdict((k, env[k]) for k in sorted(env))
299 env = util.sortdict((k, env[k]) for k in sorted(env))
300 return compatdict(context, mapping, 'envvar', env, plural='envvars')
300 return compatdict(context, mapping, 'envvar', env, plural='envvars')
301
301
302 @templatekeyword('extras', requires={'ctx'})
302 @templatekeyword('extras', requires={'ctx'})
303 def showextras(context, mapping):
303 def showextras(context, mapping):
304 """List of dicts with key, value entries of the 'extras'
304 """List of dicts with key, value entries of the 'extras'
305 field of this changeset."""
305 field of this changeset."""
306 ctx = context.resource(mapping, 'ctx')
306 ctx = context.resource(mapping, 'ctx')
307 extras = ctx.extra()
307 extras = ctx.extra()
308 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
308 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
309 makemap = lambda k: {'key': k, 'value': extras[k]}
309 makemap = lambda k: {'key': k, 'value': extras[k]}
310 c = [makemap(k) for k in extras]
310 c = [makemap(k) for k in extras]
311 f = _showcompatlist(context, mapping, 'extra', c, plural='extras')
311 f = _showcompatlist(context, mapping, 'extra', c, plural='extras')
312 return _hybrid(f, extras, makemap,
312 return _hybrid(f, extras, makemap,
313 lambda k: '%s=%s' % (k, stringutil.escapestr(extras[k])))
313 lambda k: '%s=%s' % (k, stringutil.escapestr(extras[k])))
314
314
315 def _showfilesbystat(context, mapping, name, index):
315 def _showfilesbystat(context, mapping, name, index):
316 repo = context.resource(mapping, 'repo')
316 repo = context.resource(mapping, 'repo')
317 ctx = context.resource(mapping, 'ctx')
317 ctx = context.resource(mapping, 'ctx')
318 revcache = context.resource(mapping, 'revcache')
318 revcache = context.resource(mapping, 'revcache')
319 if 'files' not in revcache:
319 if 'files' not in revcache:
320 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
320 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
321 files = revcache['files'][index]
321 files = revcache['files'][index]
322 return compatlist(context, mapping, name, files, element='file')
322 return compatlist(context, mapping, name, files, element='file')
323
323
324 @templatekeyword('file_adds', requires={'repo', 'ctx', 'revcache'})
324 @templatekeyword('file_adds', requires={'repo', 'ctx', 'revcache'})
325 def showfileadds(context, mapping):
325 def showfileadds(context, mapping):
326 """List of strings. Files added by this changeset."""
326 """List of strings. Files added by this changeset."""
327 return _showfilesbystat(context, mapping, 'file_add', 1)
327 return _showfilesbystat(context, mapping, 'file_add', 1)
328
328
329 @templatekeyword('file_copies',
329 @templatekeyword('file_copies',
330 requires={'repo', 'ctx', 'cache', 'revcache'})
330 requires={'repo', 'ctx', 'cache', 'revcache'})
331 def showfilecopies(context, mapping):
331 def showfilecopies(context, mapping):
332 """List of strings. Files copied in this changeset with
332 """List of strings. Files copied in this changeset with
333 their sources.
333 their sources.
334 """
334 """
335 repo = context.resource(mapping, 'repo')
335 repo = context.resource(mapping, 'repo')
336 ctx = context.resource(mapping, 'ctx')
336 ctx = context.resource(mapping, 'ctx')
337 cache = context.resource(mapping, 'cache')
337 cache = context.resource(mapping, 'cache')
338 copies = context.resource(mapping, 'revcache').get('copies')
338 copies = context.resource(mapping, 'revcache').get('copies')
339 if copies is None:
339 if copies is None:
340 if 'getrenamed' not in cache:
340 if 'getrenamed' not in cache:
341 cache['getrenamed'] = getrenamedfn(repo)
341 cache['getrenamed'] = getrenamedfn(repo)
342 copies = []
342 copies = []
343 getrenamed = cache['getrenamed']
343 getrenamed = cache['getrenamed']
344 for fn in ctx.files():
344 for fn in ctx.files():
345 rename = getrenamed(fn, ctx.rev())
345 rename = getrenamed(fn, ctx.rev())
346 if rename:
346 if rename:
347 copies.append((fn, rename[0]))
347 copies.append((fn, rename[0]))
348
348
349 copies = util.sortdict(copies)
349 copies = util.sortdict(copies)
350 return compatdict(context, mapping, 'file_copy', copies,
350 return compatdict(context, mapping, 'file_copy', copies,
351 key='name', value='source', fmt='%s (%s)',
351 key='name', value='source', fmt='%s (%s)',
352 plural='file_copies')
352 plural='file_copies')
353
353
354 # showfilecopiesswitch() displays file copies only if copy records are
354 # showfilecopiesswitch() displays file copies only if copy records are
355 # provided before calling the templater, usually with a --copies
355 # provided before calling the templater, usually with a --copies
356 # command line switch.
356 # command line switch.
357 @templatekeyword('file_copies_switch', requires={'revcache'})
357 @templatekeyword('file_copies_switch', requires={'revcache'})
358 def showfilecopiesswitch(context, mapping):
358 def showfilecopiesswitch(context, mapping):
359 """List of strings. Like "file_copies" but displayed
359 """List of strings. Like "file_copies" but displayed
360 only if the --copied switch is set.
360 only if the --copied switch is set.
361 """
361 """
362 copies = context.resource(mapping, 'revcache').get('copies') or []
362 copies = context.resource(mapping, 'revcache').get('copies') or []
363 copies = util.sortdict(copies)
363 copies = util.sortdict(copies)
364 return compatdict(context, mapping, 'file_copy', copies,
364 return compatdict(context, mapping, 'file_copy', copies,
365 key='name', value='source', fmt='%s (%s)',
365 key='name', value='source', fmt='%s (%s)',
366 plural='file_copies')
366 plural='file_copies')
367
367
368 @templatekeyword('file_dels', requires={'repo', 'ctx', 'revcache'})
368 @templatekeyword('file_dels', requires={'repo', 'ctx', 'revcache'})
369 def showfiledels(context, mapping):
369 def showfiledels(context, mapping):
370 """List of strings. Files removed by this changeset."""
370 """List of strings. Files removed by this changeset."""
371 return _showfilesbystat(context, mapping, 'file_del', 2)
371 return _showfilesbystat(context, mapping, 'file_del', 2)
372
372
373 @templatekeyword('file_mods', requires={'repo', 'ctx', 'revcache'})
373 @templatekeyword('file_mods', requires={'repo', 'ctx', 'revcache'})
374 def showfilemods(context, mapping):
374 def showfilemods(context, mapping):
375 """List of strings. Files modified by this changeset."""
375 """List of strings. Files modified by this changeset."""
376 return _showfilesbystat(context, mapping, 'file_mod', 0)
376 return _showfilesbystat(context, mapping, 'file_mod', 0)
377
377
378 @templatekeyword('files', requires={'ctx'})
378 @templatekeyword('files', requires={'ctx'})
379 def showfiles(context, mapping):
379 def showfiles(context, mapping):
380 """List of strings. All files modified, added, or removed by this
380 """List of strings. All files modified, added, or removed by this
381 changeset.
381 changeset.
382 """
382 """
383 ctx = context.resource(mapping, 'ctx')
383 ctx = context.resource(mapping, 'ctx')
384 return compatlist(context, mapping, 'file', ctx.files())
384 return compatlist(context, mapping, 'file', ctx.files())
385
385
386 @templatekeyword('graphnode', requires={'repo', 'ctx'})
386 @templatekeyword('graphnode', requires={'repo', 'ctx'})
387 def showgraphnode(context, mapping):
387 def showgraphnode(context, mapping):
388 """String. The character representing the changeset node in an ASCII
388 """String. The character representing the changeset node in an ASCII
389 revision graph."""
389 revision graph."""
390 repo = context.resource(mapping, 'repo')
390 repo = context.resource(mapping, 'repo')
391 ctx = context.resource(mapping, 'ctx')
391 ctx = context.resource(mapping, 'ctx')
392 return getgraphnode(repo, ctx)
392 return getgraphnode(repo, ctx)
393
393
394 def getgraphnode(repo, ctx):
394 def getgraphnode(repo, ctx):
395 wpnodes = repo.dirstate.parents()
395 wpnodes = repo.dirstate.parents()
396 if wpnodes[1] == nullid:
396 if wpnodes[1] == nullid:
397 wpnodes = wpnodes[:1]
397 wpnodes = wpnodes[:1]
398 if ctx.node() in wpnodes:
398 if ctx.node() in wpnodes:
399 return '@'
399 return '@'
400 elif ctx.obsolete():
400 elif ctx.obsolete():
401 return 'x'
401 return 'x'
402 elif ctx.isunstable():
402 elif ctx.isunstable():
403 return '*'
403 return '*'
404 elif ctx.closesbranch():
404 elif ctx.closesbranch():
405 return '_'
405 return '_'
406 else:
406 else:
407 return 'o'
407 return 'o'
408
408
409 @templatekeyword('graphwidth', requires=())
409 @templatekeyword('graphwidth', requires=())
410 def showgraphwidth(context, mapping):
410 def showgraphwidth(context, mapping):
411 """Integer. The width of the graph drawn by 'log --graph' or zero."""
411 """Integer. The width of the graph drawn by 'log --graph' or zero."""
412 # just hosts documentation; should be overridden by template mapping
412 # just hosts documentation; should be overridden by template mapping
413 return 0
413 return 0
414
414
415 @templatekeyword('index', requires=())
415 @templatekeyword('index', requires=())
416 def showindex(context, mapping):
416 def showindex(context, mapping):
417 """Integer. The current iteration of the loop. (0 indexed)"""
417 """Integer. The current iteration of the loop. (0 indexed)"""
418 # just hosts documentation; should be overridden by template mapping
418 # just hosts documentation; should be overridden by template mapping
419 raise error.Abort(_("can't use index in this context"))
419 raise error.Abort(_("can't use index in this context"))
420
420
421 @templatekeyword('latesttag', requires={'repo', 'ctx', 'cache'})
421 @templatekeyword('latesttag', requires={'repo', 'ctx', 'cache'})
422 def showlatesttag(context, mapping):
422 def showlatesttag(context, mapping):
423 """List of strings. The global tags on the most recent globally
423 """List of strings. The global tags on the most recent globally
424 tagged ancestor of this changeset. If no such tags exist, the list
424 tagged ancestor of this changeset. If no such tags exist, the list
425 consists of the single string "null".
425 consists of the single string "null".
426 """
426 """
427 return showlatesttags(context, mapping, None)
427 return showlatesttags(context, mapping, None)
428
428
429 def showlatesttags(context, mapping, pattern):
429 def showlatesttags(context, mapping, pattern):
430 """helper method for the latesttag keyword and function"""
430 """helper method for the latesttag keyword and function"""
431 latesttags = getlatesttags(context, mapping, pattern)
431 latesttags = getlatesttags(context, mapping, pattern)
432
432
433 # latesttag[0] is an implementation detail for sorting csets on different
433 # latesttag[0] is an implementation detail for sorting csets on different
434 # branches in a stable manner- it is the date the tagged cset was created,
434 # branches in a stable manner- it is the date the tagged cset was created,
435 # not the date the tag was created. Therefore it isn't made visible here.
435 # not the date the tag was created. Therefore it isn't made visible here.
436 makemap = lambda v: {
436 makemap = lambda v: {
437 'changes': _showchangessincetag,
437 'changes': _showchangessincetag,
438 'distance': latesttags[1],
438 'distance': latesttags[1],
439 'latesttag': v, # BC with {latesttag % '{latesttag}'}
439 'latesttag': v, # BC with {latesttag % '{latesttag}'}
440 'tag': v
440 'tag': v
441 }
441 }
442
442
443 tags = latesttags[2]
443 tags = latesttags[2]
444 f = _showcompatlist(context, mapping, 'latesttag', tags, separator=':')
444 f = _showcompatlist(context, mapping, 'latesttag', tags, separator=':')
445 return _hybrid(f, tags, makemap, pycompat.identity)
445 return _hybrid(f, tags, makemap, pycompat.identity)
446
446
447 @templatekeyword('latesttagdistance', requires={'repo', 'ctx', 'cache'})
447 @templatekeyword('latesttagdistance', requires={'repo', 'ctx', 'cache'})
448 def showlatesttagdistance(context, mapping):
448 def showlatesttagdistance(context, mapping):
449 """Integer. Longest path to the latest tag."""
449 """Integer. Longest path to the latest tag."""
450 return getlatesttags(context, mapping)[1]
450 return getlatesttags(context, mapping)[1]
451
451
452 @templatekeyword('changessincelatesttag', requires={'repo', 'ctx', 'cache'})
452 @templatekeyword('changessincelatesttag', requires={'repo', 'ctx', 'cache'})
453 def showchangessincelatesttag(context, mapping):
453 def showchangessincelatesttag(context, mapping):
454 """Integer. All ancestors not in the latest tag."""
454 """Integer. All ancestors not in the latest tag."""
455 tag = getlatesttags(context, mapping)[2][0]
455 tag = getlatesttags(context, mapping)[2][0]
456 mapping = context.overlaymap(mapping, {'tag': tag})
456 mapping = context.overlaymap(mapping, {'tag': tag})
457 return _showchangessincetag(context, mapping)
457 return _showchangessincetag(context, mapping)
458
458
459 def _showchangessincetag(context, mapping):
459 def _showchangessincetag(context, mapping):
460 repo = context.resource(mapping, 'repo')
460 repo = context.resource(mapping, 'repo')
461 ctx = context.resource(mapping, 'ctx')
461 ctx = context.resource(mapping, 'ctx')
462 offset = 0
462 offset = 0
463 revs = [ctx.rev()]
463 revs = [ctx.rev()]
464 tag = context.symbol(mapping, 'tag')
464 tag = context.symbol(mapping, 'tag')
465
465
466 # The only() revset doesn't currently support wdir()
466 # The only() revset doesn't currently support wdir()
467 if ctx.rev() is None:
467 if ctx.rev() is None:
468 offset = 1
468 offset = 1
469 revs = [p.rev() for p in ctx.parents()]
469 revs = [p.rev() for p in ctx.parents()]
470
470
471 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
471 return len(repo.revs('only(%ld, %s)', revs, tag)) + offset
472
472
473 # teach templater latesttags.changes is switched to (context, mapping) API
473 # teach templater latesttags.changes is switched to (context, mapping) API
474 _showchangessincetag._requires = {'repo', 'ctx'}
474 _showchangessincetag._requires = {'repo', 'ctx'}
475
475
476 @templatekeyword('manifest', requires={'repo', 'ctx'})
476 @templatekeyword('manifest', requires={'repo', 'ctx'})
477 def showmanifest(context, mapping):
477 def showmanifest(context, mapping):
478 repo = context.resource(mapping, 'repo')
478 repo = context.resource(mapping, 'repo')
479 ctx = context.resource(mapping, 'ctx')
479 ctx = context.resource(mapping, 'ctx')
480 mnode = ctx.manifestnode()
480 mnode = ctx.manifestnode()
481 if mnode is None:
481 if mnode is None:
482 # just avoid crash, we might want to use the 'ff...' hash in future
482 # just avoid crash, we might want to use the 'ff...' hash in future
483 return
483 return
484 mrev = repo.manifestlog._revlog.rev(mnode)
484 mrev = repo.manifestlog._revlog.rev(mnode)
485 mhex = hex(mnode)
485 mhex = hex(mnode)
486 mapping = context.overlaymap(mapping, {'rev': mrev, 'node': mhex})
486 mapping = context.overlaymap(mapping, {'rev': mrev, 'node': mhex})
487 f = context.process('manifest', mapping)
487 f = context.process('manifest', mapping)
488 # TODO: perhaps 'ctx' should be dropped from mapping because manifest
488 # TODO: perhaps 'ctx' should be dropped from mapping because manifest
489 # rev and node are completely different from changeset's.
489 # rev and node are completely different from changeset's.
490 return _mappable(f, None, f, lambda x: {'rev': mrev, 'node': mhex})
490 return _mappable(f, None, f, lambda x: {'rev': mrev, 'node': mhex})
491
491
492 @templatekeyword('obsfate', requires={'ui', 'repo', 'ctx'})
492 @templatekeyword('obsfate', requires={'ui', 'repo', 'ctx'})
493 def showobsfate(context, mapping):
493 def showobsfate(context, mapping):
494 # this function returns a list containing pre-formatted obsfate strings.
494 # this function returns a list containing pre-formatted obsfate strings.
495 #
495 #
496 # This function will be replaced by templates fragments when we will have
496 # This function will be replaced by templates fragments when we will have
497 # the verbosity templatekw available.
497 # the verbosity templatekw available.
498 succsandmarkers = showsuccsandmarkers(context, mapping)
498 succsandmarkers = showsuccsandmarkers(context, mapping)
499
499
500 ui = context.resource(mapping, 'ui')
500 ui = context.resource(mapping, 'ui')
501 repo = context.resource(mapping, 'repo')
501 repo = context.resource(mapping, 'repo')
502 values = []
502 values = []
503
503
504 for x in succsandmarkers.tovalue(context, mapping):
504 for x in succsandmarkers.tovalue(context, mapping):
505 v = obsutil.obsfateprinter(ui, repo, x['successors'], x['markers'],
505 v = obsutil.obsfateprinter(ui, repo, x['successors'], x['markers'],
506 scmutil.formatchangeid)
506 scmutil.formatchangeid)
507 values.append(v)
507 values.append(v)
508
508
509 return compatlist(context, mapping, "fate", values)
509 return compatlist(context, mapping, "fate", values)
510
510
511 def shownames(context, mapping, namespace):
511 def shownames(context, mapping, namespace):
512 """helper method to generate a template keyword for a namespace"""
512 """helper method to generate a template keyword for a namespace"""
513 repo = context.resource(mapping, 'repo')
513 repo = context.resource(mapping, 'repo')
514 ctx = context.resource(mapping, 'ctx')
514 ctx = context.resource(mapping, 'ctx')
515 ns = repo.names[namespace]
515 ns = repo.names[namespace]
516 names = ns.names(repo, ctx.node())
516 names = ns.names(repo, ctx.node())
517 return compatlist(context, mapping, ns.templatename, names,
517 return compatlist(context, mapping, ns.templatename, names,
518 plural=namespace)
518 plural=namespace)
519
519
520 @templatekeyword('namespaces', requires={'repo', 'ctx'})
520 @templatekeyword('namespaces', requires={'repo', 'ctx'})
521 def shownamespaces(context, mapping):
521 def shownamespaces(context, mapping):
522 """Dict of lists. Names attached to this changeset per
522 """Dict of lists. Names attached to this changeset per
523 namespace."""
523 namespace."""
524 repo = context.resource(mapping, 'repo')
524 repo = context.resource(mapping, 'repo')
525 ctx = context.resource(mapping, 'ctx')
525 ctx = context.resource(mapping, 'ctx')
526
526
527 namespaces = util.sortdict()
527 namespaces = util.sortdict()
528 def makensmapfn(ns):
528 def makensmapfn(ns):
529 # 'name' for iterating over namespaces, templatename for local reference
529 # 'name' for iterating over namespaces, templatename for local reference
530 return lambda v: {'name': v, ns.templatename: v}
530 return lambda v: {'name': v, ns.templatename: v}
531
531
532 for k, ns in repo.names.iteritems():
532 for k, ns in repo.names.iteritems():
533 names = ns.names(repo, ctx.node())
533 names = ns.names(repo, ctx.node())
534 f = _showcompatlist(context, mapping, 'name', names)
534 f = _showcompatlist(context, mapping, 'name', names)
535 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
535 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
536
536
537 f = _showcompatlist(context, mapping, 'namespace', list(namespaces))
537 f = _showcompatlist(context, mapping, 'namespace', list(namespaces))
538
538
539 def makemap(ns):
539 def makemap(ns):
540 return {
540 return {
541 'namespace': ns,
541 'namespace': ns,
542 'names': namespaces[ns],
542 'names': namespaces[ns],
543 'builtin': repo.names[ns].builtin,
543 'builtin': repo.names[ns].builtin,
544 'colorname': repo.names[ns].colorname,
544 'colorname': repo.names[ns].colorname,
545 }
545 }
546
546
547 return _hybrid(f, namespaces, makemap, pycompat.identity)
547 return _hybrid(f, namespaces, makemap, pycompat.identity)
548
548
549 @templatekeyword('node', requires={'ctx'})
549 @templatekeyword('node', requires={'ctx'})
550 def shownode(context, mapping):
550 def shownode(context, mapping):
551 """String. The changeset identification hash, as a 40 hexadecimal
551 """String. The changeset identification hash, as a 40 hexadecimal
552 digit string.
552 digit string.
553 """
553 """
554 ctx = context.resource(mapping, 'ctx')
554 ctx = context.resource(mapping, 'ctx')
555 return ctx.hex()
555 return ctx.hex()
556
556
557 @templatekeyword('obsolete', requires={'ctx'})
557 @templatekeyword('obsolete', requires={'ctx'})
558 def showobsolete(context, mapping):
558 def showobsolete(context, mapping):
559 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
559 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
560 ctx = context.resource(mapping, 'ctx')
560 ctx = context.resource(mapping, 'ctx')
561 if ctx.obsolete():
561 if ctx.obsolete():
562 return 'obsolete'
562 return 'obsolete'
563 return ''
563 return ''
564
564
565 @templatekeyword('peerurls', requires={'repo'})
565 @templatekeyword('peerurls', requires={'repo'})
566 def showpeerurls(context, mapping):
566 def showpeerurls(context, mapping):
567 """A dictionary of repository locations defined in the [paths] section
567 """A dictionary of repository locations defined in the [paths] section
568 of your configuration file."""
568 of your configuration file."""
569 repo = context.resource(mapping, 'repo')
569 repo = context.resource(mapping, 'repo')
570 # see commands.paths() for naming of dictionary keys
570 # see commands.paths() for naming of dictionary keys
571 paths = repo.ui.paths
571 paths = repo.ui.paths
572 urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems()))
572 urls = util.sortdict((k, p.rawloc) for k, p in sorted(paths.iteritems()))
573 def makemap(k):
573 def makemap(k):
574 p = paths[k]
574 p = paths[k]
575 d = {'name': k, 'url': p.rawloc}
575 d = {'name': k, 'url': p.rawloc}
576 d.update((o, v) for o, v in sorted(p.suboptions.iteritems()))
576 d.update((o, v) for o, v in sorted(p.suboptions.iteritems()))
577 return d
577 return d
578 return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k]))
578 return _hybrid(None, urls, makemap, lambda k: '%s=%s' % (k, urls[k]))
579
579
580 @templatekeyword("predecessors", requires={'repo', 'ctx'})
580 @templatekeyword("predecessors", requires={'repo', 'ctx'})
581 def showpredecessors(context, mapping):
581 def showpredecessors(context, mapping):
582 """Returns the list if the closest visible successors. (EXPERIMENTAL)"""
582 """Returns the list if the closest visible successors. (EXPERIMENTAL)"""
583 repo = context.resource(mapping, 'repo')
583 repo = context.resource(mapping, 'repo')
584 ctx = context.resource(mapping, 'ctx')
584 ctx = context.resource(mapping, 'ctx')
585 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
585 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
586 predecessors = map(hex, predecessors)
586 predecessors = map(hex, predecessors)
587
587
588 return _hybrid(None, predecessors,
588 return _hybrid(None, predecessors,
589 lambda x: {'ctx': repo[x]},
589 lambda x: {'ctx': repo[x]},
590 lambda x: scmutil.formatchangeid(repo[x]))
590 lambda x: scmutil.formatchangeid(repo[x]))
591
591
592 @templatekeyword('reporoot', requires={'repo'})
592 @templatekeyword('reporoot', requires={'repo'})
593 def showreporoot(context, mapping):
593 def showreporoot(context, mapping):
594 """String. The root directory of the current repository."""
594 """String. The root directory of the current repository."""
595 repo = context.resource(mapping, 'repo')
595 repo = context.resource(mapping, 'repo')
596 return repo.root
596 return repo.root
597
597
598 @templatekeyword("successorssets", requires={'repo', 'ctx'})
598 @templatekeyword("successorssets", requires={'repo', 'ctx'})
599 def showsuccessorssets(context, mapping):
599 def showsuccessorssets(context, mapping):
600 """Returns a string of sets of successors for a changectx. Format used
600 """Returns a string of sets of successors for a changectx. Format used
601 is: [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and ctx2
601 is: [ctx1, ctx2], [ctx3] if ctx has been splitted into ctx1 and ctx2
602 while also diverged into ctx3. (EXPERIMENTAL)"""
602 while also diverged into ctx3. (EXPERIMENTAL)"""
603 repo = context.resource(mapping, 'repo')
603 repo = context.resource(mapping, 'repo')
604 ctx = context.resource(mapping, 'ctx')
604 ctx = context.resource(mapping, 'ctx')
605 if not ctx.obsolete():
605 if not ctx.obsolete():
606 return ''
606 return ''
607
607
608 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
608 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
609 ssets = [[hex(n) for n in ss] for ss in ssets]
609 ssets = [[hex(n) for n in ss] for ss in ssets]
610
610
611 data = []
611 data = []
612 for ss in ssets:
612 for ss in ssets:
613 h = _hybrid(None, ss, lambda x: {'ctx': repo[x]},
613 h = _hybrid(None, ss, lambda x: {'ctx': repo[x]},
614 lambda x: scmutil.formatchangeid(repo[x]))
614 lambda x: scmutil.formatchangeid(repo[x]))
615 data.append(h)
615 data.append(h)
616
616
617 # Format the successorssets
617 # Format the successorssets
618 def render(d):
618 def render(d):
619 return templateutil.stringify(context, mapping, d)
619 return templateutil.stringify(context, mapping, d)
620
620
621 def gen(data):
621 def gen(data):
622 yield "; ".join(render(d) for d in data)
622 yield "; ".join(render(d) for d in data)
623
623
624 return _hybrid(gen(data), data, lambda x: {'successorset': x},
624 return _hybrid(gen(data), data, lambda x: {'successorset': x},
625 pycompat.identity)
625 pycompat.identity)
626
626
627 @templatekeyword("succsandmarkers", requires={'repo', 'ctx'})
627 @templatekeyword("succsandmarkers", requires={'repo', 'ctx'})
628 def showsuccsandmarkers(context, mapping):
628 def showsuccsandmarkers(context, mapping):
629 """Returns a list of dict for each final successor of ctx. The dict
629 """Returns a list of dict for each final successor of ctx. The dict
630 contains successors node id in "successors" keys and the list of
630 contains successors node id in "successors" keys and the list of
631 obs-markers from ctx to the set of successors in "markers".
631 obs-markers from ctx to the set of successors in "markers".
632 (EXPERIMENTAL)
632 (EXPERIMENTAL)
633 """
633 """
634 repo = context.resource(mapping, 'repo')
634 repo = context.resource(mapping, 'repo')
635 ctx = context.resource(mapping, 'ctx')
635 ctx = context.resource(mapping, 'ctx')
636
636
637 values = obsutil.successorsandmarkers(repo, ctx)
637 values = obsutil.successorsandmarkers(repo, ctx)
638
638
639 if values is None:
639 if values is None:
640 values = []
640 values = []
641
641
642 # Format successors and markers to avoid exposing binary to templates
642 # Format successors and markers to avoid exposing binary to templates
643 data = []
643 data = []
644 for i in values:
644 for i in values:
645 # Format successors
645 # Format successors
646 successors = i['successors']
646 successors = i['successors']
647
647
648 successors = [hex(n) for n in successors]
648 successors = [hex(n) for n in successors]
649 successors = _hybrid(None, successors,
649 successors = _hybrid(None, successors,
650 lambda x: {'ctx': repo[x]},
650 lambda x: {'ctx': repo[x]},
651 lambda x: scmutil.formatchangeid(repo[x]))
651 lambda x: scmutil.formatchangeid(repo[x]))
652
652
653 # Format markers
653 # Format markers
654 finalmarkers = []
654 finalmarkers = []
655 for m in i['markers']:
655 for m in i['markers']:
656 hexprec = hex(m[0])
656 hexprec = hex(m[0])
657 hexsucs = tuple(hex(n) for n in m[1])
657 hexsucs = tuple(hex(n) for n in m[1])
658 hexparents = None
658 hexparents = None
659 if m[5] is not None:
659 if m[5] is not None:
660 hexparents = tuple(hex(n) for n in m[5])
660 hexparents = tuple(hex(n) for n in m[5])
661 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
661 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
662 finalmarkers.append(newmarker)
662 finalmarkers.append(newmarker)
663
663
664 data.append({'successors': successors, 'markers': finalmarkers})
664 data.append({'successors': successors, 'markers': finalmarkers})
665
665
666 return templateutil.mappinglist(data)
666 return templateutil.mappinglist(data)
667
667
668 @templatekeyword('p1rev', requires={'ctx'})
668 @templatekeyword('p1rev', requires={'ctx'})
669 def showp1rev(context, mapping):
669 def showp1rev(context, mapping):
670 """Integer. The repository-local revision number of the changeset's
670 """Integer. The repository-local revision number of the changeset's
671 first parent, or -1 if the changeset has no parents."""
671 first parent, or -1 if the changeset has no parents."""
672 ctx = context.resource(mapping, 'ctx')
672 ctx = context.resource(mapping, 'ctx')
673 return ctx.p1().rev()
673 return ctx.p1().rev()
674
674
675 @templatekeyword('p2rev', requires={'ctx'})
675 @templatekeyword('p2rev', requires={'ctx'})
676 def showp2rev(context, mapping):
676 def showp2rev(context, mapping):
677 """Integer. The repository-local revision number of the changeset's
677 """Integer. The repository-local revision number of the changeset's
678 second parent, or -1 if the changeset has no second parent."""
678 second parent, or -1 if the changeset has no second parent."""
679 ctx = context.resource(mapping, 'ctx')
679 ctx = context.resource(mapping, 'ctx')
680 return ctx.p2().rev()
680 return ctx.p2().rev()
681
681
682 @templatekeyword('p1node', requires={'ctx'})
682 @templatekeyword('p1node', requires={'ctx'})
683 def showp1node(context, mapping):
683 def showp1node(context, mapping):
684 """String. The identification hash of the changeset's first parent,
684 """String. The identification hash of the changeset's first parent,
685 as a 40 digit hexadecimal string. If the changeset has no parents, all
685 as a 40 digit hexadecimal string. If the changeset has no parents, all
686 digits are 0."""
686 digits are 0."""
687 ctx = context.resource(mapping, 'ctx')
687 ctx = context.resource(mapping, 'ctx')
688 return ctx.p1().hex()
688 return ctx.p1().hex()
689
689
690 @templatekeyword('p2node', requires={'ctx'})
690 @templatekeyword('p2node', requires={'ctx'})
691 def showp2node(context, mapping):
691 def showp2node(context, mapping):
692 """String. The identification hash of the changeset's second
692 """String. The identification hash of the changeset's second
693 parent, as a 40 digit hexadecimal string. If the changeset has no second
693 parent, as a 40 digit hexadecimal string. If the changeset has no second
694 parent, all digits are 0."""
694 parent, all digits are 0."""
695 ctx = context.resource(mapping, 'ctx')
695 ctx = context.resource(mapping, 'ctx')
696 return ctx.p2().hex()
696 return ctx.p2().hex()
697
697
698 @templatekeyword('parents', requires={'repo', 'ctx'})
698 @templatekeyword('parents', requires={'repo', 'ctx'})
699 def showparents(context, mapping):
699 def showparents(context, mapping):
700 """List of strings. The parents of the changeset in "rev:node"
700 """List of strings. The parents of the changeset in "rev:node"
701 format. If the changeset has only one "natural" parent (the predecessor
701 format. If the changeset has only one "natural" parent (the predecessor
702 revision) nothing is shown."""
702 revision) nothing is shown."""
703 repo = context.resource(mapping, 'repo')
703 repo = context.resource(mapping, 'repo')
704 ctx = context.resource(mapping, 'ctx')
704 ctx = context.resource(mapping, 'ctx')
705 pctxs = scmutil.meaningfulparents(repo, ctx)
705 pctxs = scmutil.meaningfulparents(repo, ctx)
706 prevs = [p.rev() for p in pctxs]
706 prevs = [p.rev() for p in pctxs]
707 parents = [[('rev', p.rev()),
707 parents = [[('rev', p.rev()),
708 ('node', p.hex()),
708 ('node', p.hex()),
709 ('phase', p.phasestr())]
709 ('phase', p.phasestr())]
710 for p in pctxs]
710 for p in pctxs]
711 f = _showcompatlist(context, mapping, 'parent', parents)
711 f = _showcompatlist(context, mapping, 'parent', parents)
712 return _hybrid(f, prevs, lambda x: {'ctx': repo[x]},
712 return _hybrid(f, prevs, lambda x: {'ctx': repo[x]},
713 lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
713 lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
714
714
715 @templatekeyword('phase', requires={'ctx'})
715 @templatekeyword('phase', requires={'ctx'})
716 def showphase(context, mapping):
716 def showphase(context, mapping):
717 """String. The changeset phase name."""
717 """String. The changeset phase name."""
718 ctx = context.resource(mapping, 'ctx')
718 ctx = context.resource(mapping, 'ctx')
719 return ctx.phasestr()
719 return ctx.phasestr()
720
720
721 @templatekeyword('phaseidx', requires={'ctx'})
721 @templatekeyword('phaseidx', requires={'ctx'})
722 def showphaseidx(context, mapping):
722 def showphaseidx(context, mapping):
723 """Integer. The changeset phase index. (ADVANCED)"""
723 """Integer. The changeset phase index. (ADVANCED)"""
724 ctx = context.resource(mapping, 'ctx')
724 ctx = context.resource(mapping, 'ctx')
725 return ctx.phase()
725 return ctx.phase()
726
726
727 @templatekeyword('rev', requires={'ctx'})
727 @templatekeyword('rev', requires={'ctx'})
728 def showrev(context, mapping):
728 def showrev(context, mapping):
729 """Integer. The repository-local changeset revision number."""
729 """Integer. The repository-local changeset revision number."""
730 ctx = context.resource(mapping, 'ctx')
730 ctx = context.resource(mapping, 'ctx')
731 return scmutil.intrev(ctx)
731 return scmutil.intrev(ctx)
732
732
733 def showrevslist(context, mapping, name, revs):
733 def showrevslist(context, mapping, name, revs):
734 """helper to generate a list of revisions in which a mapped template will
734 """helper to generate a list of revisions in which a mapped template will
735 be evaluated"""
735 be evaluated"""
736 repo = context.resource(mapping, 'repo')
736 repo = context.resource(mapping, 'repo')
737 f = _showcompatlist(context, mapping, name, ['%d' % r for r in revs])
737 f = _showcompatlist(context, mapping, name, ['%d' % r for r in revs])
738 return _hybrid(f, revs,
738 return _hybrid(f, revs,
739 lambda x: {name: x, 'ctx': repo[x]},
739 lambda x: {name: x, 'ctx': repo[x]},
740 pycompat.identity, keytype=int)
740 pycompat.identity, keytype=int)
741
741
742 @templatekeyword('subrepos', requires={'ctx'})
742 @templatekeyword('subrepos', requires={'ctx'})
743 def showsubrepos(context, mapping):
743 def showsubrepos(context, mapping):
744 """List of strings. Updated subrepositories in the changeset."""
744 """List of strings. Updated subrepositories in the changeset."""
745 ctx = context.resource(mapping, 'ctx')
745 ctx = context.resource(mapping, 'ctx')
746 substate = ctx.substate
746 substate = ctx.substate
747 if not substate:
747 if not substate:
748 return compatlist(context, mapping, 'subrepo', [])
748 return compatlist(context, mapping, 'subrepo', [])
749 psubstate = ctx.parents()[0].substate or {}
749 psubstate = ctx.parents()[0].substate or {}
750 subrepos = []
750 subrepos = []
751 for sub in substate:
751 for sub in substate:
752 if sub not in psubstate or substate[sub] != psubstate[sub]:
752 if sub not in psubstate or substate[sub] != psubstate[sub]:
753 subrepos.append(sub) # modified or newly added in ctx
753 subrepos.append(sub) # modified or newly added in ctx
754 for sub in psubstate:
754 for sub in psubstate:
755 if sub not in substate:
755 if sub not in substate:
756 subrepos.append(sub) # removed in ctx
756 subrepos.append(sub) # removed in ctx
757 return compatlist(context, mapping, 'subrepo', sorted(subrepos))
757 return compatlist(context, mapping, 'subrepo', sorted(subrepos))
758
758
759 # don't remove "showtags" definition, even though namespaces will put
759 # don't remove "showtags" definition, even though namespaces will put
760 # a helper function for "tags" keyword into "keywords" map automatically,
760 # a helper function for "tags" keyword into "keywords" map automatically,
761 # because online help text is built without namespaces initialization
761 # because online help text is built without namespaces initialization
762 @templatekeyword('tags', requires={'repo', 'ctx'})
762 @templatekeyword('tags', requires={'repo', 'ctx'})
763 def showtags(context, mapping):
763 def showtags(context, mapping):
764 """List of strings. Any tags associated with the changeset."""
764 """List of strings. Any tags associated with the changeset."""
765 return shownames(context, mapping, 'tags')
765 return shownames(context, mapping, 'tags')
766
766
767 @templatekeyword('termwidth', requires={'ui'})
767 @templatekeyword('termwidth', requires={'ui'})
768 def showtermwidth(context, mapping):
768 def showtermwidth(context, mapping):
769 """Integer. The width of the current terminal."""
769 """Integer. The width of the current terminal."""
770 ui = context.resource(mapping, 'ui')
770 ui = context.resource(mapping, 'ui')
771 return ui.termwidth()
771 return ui.termwidth()
772
772
773 @templatekeyword('instabilities', requires={'ctx'})
773 @templatekeyword('instabilities', requires={'ctx'})
774 def showinstabilities(context, mapping):
774 def showinstabilities(context, mapping):
775 """List of strings. Evolution instabilities affecting the changeset.
775 """List of strings. Evolution instabilities affecting the changeset.
776 (EXPERIMENTAL)
776 (EXPERIMENTAL)
777 """
777 """
778 ctx = context.resource(mapping, 'ctx')
778 ctx = context.resource(mapping, 'ctx')
779 return compatlist(context, mapping, 'instability', ctx.instabilities(),
779 return compatlist(context, mapping, 'instability', ctx.instabilities(),
780 plural='instabilities')
780 plural='instabilities')
781
781
782 @templatekeyword('verbosity', requires={'ui'})
782 @templatekeyword('verbosity', requires={'ui'})
783 def showverbosity(context, mapping):
783 def showverbosity(context, mapping):
784 """String. The current output verbosity in 'debug', 'quiet', 'verbose',
784 """String. The current output verbosity in 'debug', 'quiet', 'verbose',
785 or ''."""
785 or ''."""
786 ui = context.resource(mapping, 'ui')
786 ui = context.resource(mapping, 'ui')
787 # see logcmdutil.changesettemplater for priority of these flags
787 # see logcmdutil.changesettemplater for priority of these flags
788 if ui.debugflag:
788 if ui.debugflag:
789 return 'debug'
789 return 'debug'
790 elif ui.quiet:
790 elif ui.quiet:
791 return 'quiet'
791 return 'quiet'
792 elif ui.verbose:
792 elif ui.verbose:
793 return 'verbose'
793 return 'verbose'
794 return ''
794 return ''
795
795
796 @templatekeyword('whyunstable', requires={'repo', 'ctx'})
796 @templatekeyword('whyunstable', requires={'repo', 'ctx'})
797 def showwhyunstable(context, mapping):
797 def showwhyunstable(context, mapping):
798 """List of dicts explaining all instabilities of a changeset.
798 """List of dicts explaining all instabilities of a changeset.
799 (EXPERIMENTAL)
799 (EXPERIMENTAL)
800 """
800 """
801 repo = context.resource(mapping, 'repo')
801 repo = context.resource(mapping, 'repo')
802 ctx = context.resource(mapping, 'ctx')
802 ctx = context.resource(mapping, 'ctx')
803
803
804 def formatnode(ctx):
804 def formatnode(ctx):
805 return ' %s (%s)' % (scmutil.formatchangeid(ctx), ctx.phasestr())
805 return '%s (%s)' % (scmutil.formatchangeid(ctx), ctx.phasestr())
806
806
807 entries = obsutil.whyunstable(repo, ctx)
807 entries = obsutil.whyunstable(repo, ctx)
808
808
809 for entry in entries:
809 for entry in entries:
810 if entry.get('divergentnodes'):
810 if entry.get('divergentnodes'):
811 dnodes = entry['divergentnodes']
811 dnodes = entry['divergentnodes']
812 dnhybrid = _hybrid(None, [dnode.hex() for dnode in dnodes],
812 dnhybrid = _hybrid(None, [dnode.hex() for dnode in dnodes],
813 lambda x: {'ctx': repo[x]},
813 lambda x: {'ctx': repo[x]},
814 lambda x: formatnode(repo[x]))
814 lambda x: formatnode(repo[x]))
815 entry['divergentnodes'] = dnhybrid
815 entry['divergentnodes'] = dnhybrid
816
816
817 tmpl = '{instability}:{divergentnodes} {reason} {node|short}'
817 tmpl = ('{instability}:{if(divergentnodes, " ")}{divergentnodes} '
818 '{reason} {node|short}')
818 return templateutil.mappinglist(entries, tmpl=tmpl, sep='\n')
819 return templateutil.mappinglist(entries, tmpl=tmpl, sep='\n')
819
820
820 def loadkeyword(ui, extname, registrarobj):
821 def loadkeyword(ui, extname, registrarobj):
821 """Load template keyword from specified registrarobj
822 """Load template keyword from specified registrarobj
822 """
823 """
823 for name, func in registrarobj._table.iteritems():
824 for name, func in registrarobj._table.iteritems():
824 keywords[name] = func
825 keywords[name] = func
825
826
826 # tell hggettext to extract docstrings from these functions:
827 # tell hggettext to extract docstrings from these functions:
827 i18nfunctions = keywords.values()
828 i18nfunctions = keywords.values()
@@ -1,756 +1,766 b''
1 Test file dedicated to testing the divergent troubles from obsolete changeset.
1 Test file dedicated to testing the divergent troubles from obsolete changeset.
2
2
3 This is the most complex troubles from far so we isolate it in a dedicated
3 This is the most complex troubles from far so we isolate it in a dedicated
4 file.
4 file.
5
5
6 Enable obsolete
6 Enable obsolete
7
7
8 $ cat >> $HGRCPATH << EOF
8 $ cat >> $HGRCPATH << EOF
9 > [ui]
9 > [ui]
10 > logtemplate = {rev}:{node|short} {desc}{if(obsfate, " [{join(obsfate, "; ")}]")}\n
10 > logtemplate = {rev}:{node|short} {desc}{if(obsfate, " [{join(obsfate, "; ")}]")}\n
11 > [experimental]
11 > [experimental]
12 > evolution.createmarkers=True
12 > evolution.createmarkers=True
13 > [extensions]
13 > [extensions]
14 > drawdag=$TESTDIR/drawdag.py
14 > drawdag=$TESTDIR/drawdag.py
15 > [alias]
15 > [alias]
16 > debugobsolete = debugobsolete -d '0 0'
16 > debugobsolete = debugobsolete -d '0 0'
17 > [phases]
17 > [phases]
18 > publish=False
18 > publish=False
19 > [templates]
19 > [templates]
20 > wuentryshort = '{instability}:{divergentnodes} {reason} {node|shortest}\n'
20 > wuentryshort = '{instability}:{if(divergentnodes, " ")}{divergentnodes} {reason} {node|shortest}\n'
21 > whyunstableshort = '{whyunstable % wuentryshort}'
21 > whyunstableshort = '{whyunstable % wuentryshort}'
22 > wuentryshorter = '{instability}:{divergentnodes % " {node|shortest} ({phase})"} {reason} {node|shortest}\n'
22 > wuentryshorter = '{instability}:{divergentnodes % " {node|shortest} ({phase})"} {reason} {node|shortest}\n'
23 > whyunstableshorter = '{whyunstable % wuentryshorter}'
23 > whyunstableshorter = '{whyunstable % wuentryshorter}'
24 > EOF
24 > EOF
25
25
26
26
27 $ mkcommit() {
27 $ mkcommit() {
28 > echo "$1" > "$1"
28 > echo "$1" > "$1"
29 > hg add "$1"
29 > hg add "$1"
30 > hg ci -m "$1"
30 > hg ci -m "$1"
31 > }
31 > }
32 $ getid() {
32 $ getid() {
33 > hg log --hidden -r "desc('$1')" -T '{node}\n'
33 > hg log --hidden -r "desc('$1')" -T '{node}\n'
34 > }
34 > }
35
35
36 setup repo
36 setup repo
37
37
38 $ hg init reference
38 $ hg init reference
39 $ cd reference
39 $ cd reference
40 $ mkcommit base
40 $ mkcommit base
41 $ mkcommit A_0
41 $ mkcommit A_0
42 $ hg up 0
42 $ hg up 0
43 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
43 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
44 $ mkcommit A_1
44 $ mkcommit A_1
45 created new head
45 created new head
46 $ hg up 0
46 $ hg up 0
47 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
47 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
48 $ mkcommit A_2
48 $ mkcommit A_2
49 created new head
49 created new head
50 $ hg up 0
50 $ hg up 0
51 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
51 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
52 $ cd ..
52 $ cd ..
53
53
54
54
55 $ newcase() {
55 $ newcase() {
56 > hg clone -u 0 -q reference $1
56 > hg clone -u 0 -q reference $1
57 > cd $1
57 > cd $1
58 > }
58 > }
59
59
60 direct divergence
60 direct divergence
61 -----------------
61 -----------------
62
62
63 A_1 have two direct and divergent successors A_1 and A_1
63 A_1 have two direct and divergent successors A_1 and A_1
64
64
65 $ newcase direct
65 $ newcase direct
66 $ hg debugobsolete `getid A_0` `getid A_1`
66 $ hg debugobsolete `getid A_0` `getid A_1`
67 obsoleted 1 changesets
67 obsoleted 1 changesets
68 $ hg debugobsolete `getid A_0` `getid A_2`
68 $ hg debugobsolete `getid A_0` `getid A_2`
69 2 new content-divergent changesets
69 2 new content-divergent changesets
70 $ hg log -G --hidden
70 $ hg log -G --hidden
71 * 3:392fd25390da A_2
71 * 3:392fd25390da A_2
72 |
72 |
73 | * 2:82623d38b9ba A_1
73 | * 2:82623d38b9ba A_1
74 |/
74 |/
75 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
75 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
76 |/
76 |/
77 @ 0:d20a80d4def3 base
77 @ 0:d20a80d4def3 base
78
78
79 $ hg debugsuccessorssets --hidden 'all()'
79 $ hg debugsuccessorssets --hidden 'all()'
80 d20a80d4def3
80 d20a80d4def3
81 d20a80d4def3
81 d20a80d4def3
82 007dc284c1f8
82 007dc284c1f8
83 82623d38b9ba
83 82623d38b9ba
84 392fd25390da
84 392fd25390da
85 82623d38b9ba
85 82623d38b9ba
86 82623d38b9ba
86 82623d38b9ba
87 392fd25390da
87 392fd25390da
88 392fd25390da
88 392fd25390da
89 $ hg log -r 'contentdivergent()'
89 $ hg log -r 'contentdivergent()'
90 2:82623d38b9ba A_1
90 2:82623d38b9ba A_1
91 3:392fd25390da A_2
91 3:392fd25390da A_2
92 $ hg debugsuccessorssets 'all()' --closest
92 $ hg debugsuccessorssets 'all()' --closest
93 d20a80d4def3
93 d20a80d4def3
94 d20a80d4def3
94 d20a80d4def3
95 82623d38b9ba
95 82623d38b9ba
96 82623d38b9ba
96 82623d38b9ba
97 392fd25390da
97 392fd25390da
98 392fd25390da
98 392fd25390da
99 $ hg debugsuccessorssets 'all()' --closest --hidden
99 $ hg debugsuccessorssets 'all()' --closest --hidden
100 d20a80d4def3
100 d20a80d4def3
101 d20a80d4def3
101 d20a80d4def3
102 007dc284c1f8
102 007dc284c1f8
103 82623d38b9ba
103 82623d38b9ba
104 392fd25390da
104 392fd25390da
105 82623d38b9ba
105 82623d38b9ba
106 82623d38b9ba
106 82623d38b9ba
107 392fd25390da
107 392fd25390da
108 392fd25390da
108 392fd25390da
109
109
110 check that mercurial refuse to push
110 check that mercurial refuse to push
111
111
112 $ hg init ../other
112 $ hg init ../other
113 $ hg push ../other
113 $ hg push ../other
114 pushing to ../other
114 pushing to ../other
115 searching for changes
115 searching for changes
116 abort: push includes content-divergent changeset: 392fd25390da!
116 abort: push includes content-divergent changeset: 392fd25390da!
117 [255]
117 [255]
118
118
119 $ cd ..
119 $ cd ..
120
120
121
121
122 indirect divergence with known changeset
122 indirect divergence with known changeset
123 -------------------------------------------
123 -------------------------------------------
124
124
125 $ newcase indirect_known
125 $ newcase indirect_known
126 $ hg debugobsolete `getid A_0` `getid A_1`
126 $ hg debugobsolete `getid A_0` `getid A_1`
127 obsoleted 1 changesets
127 obsoleted 1 changesets
128 $ hg debugobsolete `getid A_0` `getid A_2`
128 $ hg debugobsolete `getid A_0` `getid A_2`
129 2 new content-divergent changesets
129 2 new content-divergent changesets
130 $ mkcommit A_3
130 $ mkcommit A_3
131 created new head
131 created new head
132 $ hg debugobsolete `getid A_2` `getid A_3`
132 $ hg debugobsolete `getid A_2` `getid A_3`
133 obsoleted 1 changesets
133 obsoleted 1 changesets
134 $ hg log -G --hidden
134 $ hg log -G --hidden
135 @ 4:01f36c5a8fda A_3
135 @ 4:01f36c5a8fda A_3
136 |
136 |
137 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda]
137 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda]
138 |/
138 |/
139 | * 2:82623d38b9ba A_1
139 | * 2:82623d38b9ba A_1
140 |/
140 |/
141 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
141 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
142 |/
142 |/
143 o 0:d20a80d4def3 base
143 o 0:d20a80d4def3 base
144
144
145 $ hg debugsuccessorssets --hidden 'all()'
145 $ hg debugsuccessorssets --hidden 'all()'
146 d20a80d4def3
146 d20a80d4def3
147 d20a80d4def3
147 d20a80d4def3
148 007dc284c1f8
148 007dc284c1f8
149 82623d38b9ba
149 82623d38b9ba
150 01f36c5a8fda
150 01f36c5a8fda
151 82623d38b9ba
151 82623d38b9ba
152 82623d38b9ba
152 82623d38b9ba
153 392fd25390da
153 392fd25390da
154 01f36c5a8fda
154 01f36c5a8fda
155 01f36c5a8fda
155 01f36c5a8fda
156 01f36c5a8fda
156 01f36c5a8fda
157 $ hg log -r 'contentdivergent()'
157 $ hg log -r 'contentdivergent()'
158 2:82623d38b9ba A_1
158 2:82623d38b9ba A_1
159 4:01f36c5a8fda A_3
159 4:01f36c5a8fda A_3
160 $ hg debugsuccessorssets 'all()' --closest
160 $ hg debugsuccessorssets 'all()' --closest
161 d20a80d4def3
161 d20a80d4def3
162 d20a80d4def3
162 d20a80d4def3
163 82623d38b9ba
163 82623d38b9ba
164 82623d38b9ba
164 82623d38b9ba
165 01f36c5a8fda
165 01f36c5a8fda
166 01f36c5a8fda
166 01f36c5a8fda
167 $ hg debugsuccessorssets 'all()' --closest --hidden
167 $ hg debugsuccessorssets 'all()' --closest --hidden
168 d20a80d4def3
168 d20a80d4def3
169 d20a80d4def3
169 d20a80d4def3
170 007dc284c1f8
170 007dc284c1f8
171 82623d38b9ba
171 82623d38b9ba
172 392fd25390da
172 392fd25390da
173 82623d38b9ba
173 82623d38b9ba
174 82623d38b9ba
174 82623d38b9ba
175 392fd25390da
175 392fd25390da
176 392fd25390da
176 392fd25390da
177 01f36c5a8fda
177 01f36c5a8fda
178 01f36c5a8fda
178 01f36c5a8fda
179 $ cd ..
179 $ cd ..
180
180
181
181
182 indirect divergence with known changeset
182 indirect divergence with known changeset
183 -------------------------------------------
183 -------------------------------------------
184
184
185 $ newcase indirect_unknown
185 $ newcase indirect_unknown
186 $ hg debugobsolete `getid A_0` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
186 $ hg debugobsolete `getid A_0` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
187 obsoleted 1 changesets
187 obsoleted 1 changesets
188 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid A_1`
188 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid A_1`
189 $ hg debugobsolete `getid A_0` `getid A_2`
189 $ hg debugobsolete `getid A_0` `getid A_2`
190 2 new content-divergent changesets
190 2 new content-divergent changesets
191 $ hg log -G --hidden
191 $ hg log -G --hidden
192 * 3:392fd25390da A_2
192 * 3:392fd25390da A_2
193 |
193 |
194 | * 2:82623d38b9ba A_1
194 | * 2:82623d38b9ba A_1
195 |/
195 |/
196 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
196 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
197 |/
197 |/
198 @ 0:d20a80d4def3 base
198 @ 0:d20a80d4def3 base
199
199
200 $ hg debugsuccessorssets --hidden 'all()'
200 $ hg debugsuccessorssets --hidden 'all()'
201 d20a80d4def3
201 d20a80d4def3
202 d20a80d4def3
202 d20a80d4def3
203 007dc284c1f8
203 007dc284c1f8
204 82623d38b9ba
204 82623d38b9ba
205 392fd25390da
205 392fd25390da
206 82623d38b9ba
206 82623d38b9ba
207 82623d38b9ba
207 82623d38b9ba
208 392fd25390da
208 392fd25390da
209 392fd25390da
209 392fd25390da
210 $ hg log -r 'contentdivergent()'
210 $ hg log -r 'contentdivergent()'
211 2:82623d38b9ba A_1
211 2:82623d38b9ba A_1
212 3:392fd25390da A_2
212 3:392fd25390da A_2
213 $ hg debugsuccessorssets 'all()' --closest
213 $ hg debugsuccessorssets 'all()' --closest
214 d20a80d4def3
214 d20a80d4def3
215 d20a80d4def3
215 d20a80d4def3
216 82623d38b9ba
216 82623d38b9ba
217 82623d38b9ba
217 82623d38b9ba
218 392fd25390da
218 392fd25390da
219 392fd25390da
219 392fd25390da
220 $ hg debugsuccessorssets 'all()' --closest --hidden
220 $ hg debugsuccessorssets 'all()' --closest --hidden
221 d20a80d4def3
221 d20a80d4def3
222 d20a80d4def3
222 d20a80d4def3
223 007dc284c1f8
223 007dc284c1f8
224 82623d38b9ba
224 82623d38b9ba
225 392fd25390da
225 392fd25390da
226 82623d38b9ba
226 82623d38b9ba
227 82623d38b9ba
227 82623d38b9ba
228 392fd25390da
228 392fd25390da
229 392fd25390da
229 392fd25390da
230 $ cd ..
230 $ cd ..
231
231
232 do not take unknown node in account if they are final
232 do not take unknown node in account if they are final
233 -----------------------------------------------------
233 -----------------------------------------------------
234
234
235 $ newcase final-unknown
235 $ newcase final-unknown
236 $ hg debugobsolete `getid A_0` `getid A_1`
236 $ hg debugobsolete `getid A_0` `getid A_1`
237 obsoleted 1 changesets
237 obsoleted 1 changesets
238 $ hg debugobsolete `getid A_1` `getid A_2`
238 $ hg debugobsolete `getid A_1` `getid A_2`
239 obsoleted 1 changesets
239 obsoleted 1 changesets
240 $ hg debugobsolete `getid A_0` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
240 $ hg debugobsolete `getid A_0` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
241 $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccc
241 $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccc
242 $ hg debugobsolete `getid A_1` dddddddddddddddddddddddddddddddddddddddd
242 $ hg debugobsolete `getid A_1` dddddddddddddddddddddddddddddddddddddddd
243
243
244 $ hg debugsuccessorssets --hidden 'desc('A_0')'
244 $ hg debugsuccessorssets --hidden 'desc('A_0')'
245 007dc284c1f8
245 007dc284c1f8
246 392fd25390da
246 392fd25390da
247 $ hg debugsuccessorssets 'desc('A_0')' --closest
247 $ hg debugsuccessorssets 'desc('A_0')' --closest
248 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
248 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
249 007dc284c1f8
249 007dc284c1f8
250 82623d38b9ba
250 82623d38b9ba
251
251
252 $ cd ..
252 $ cd ..
253
253
254 divergence that converge again is not divergence anymore
254 divergence that converge again is not divergence anymore
255 -----------------------------------------------------
255 -----------------------------------------------------
256
256
257 $ newcase converged_divergence
257 $ newcase converged_divergence
258 $ hg debugobsolete `getid A_0` `getid A_1`
258 $ hg debugobsolete `getid A_0` `getid A_1`
259 obsoleted 1 changesets
259 obsoleted 1 changesets
260 $ hg debugobsolete `getid A_0` `getid A_2`
260 $ hg debugobsolete `getid A_0` `getid A_2`
261 2 new content-divergent changesets
261 2 new content-divergent changesets
262 $ mkcommit A_3
262 $ mkcommit A_3
263 created new head
263 created new head
264 $ hg debugobsolete `getid A_1` `getid A_3`
264 $ hg debugobsolete `getid A_1` `getid A_3`
265 obsoleted 1 changesets
265 obsoleted 1 changesets
266 $ hg debugobsolete `getid A_2` `getid A_3`
266 $ hg debugobsolete `getid A_2` `getid A_3`
267 obsoleted 1 changesets
267 obsoleted 1 changesets
268 $ hg log -G --hidden
268 $ hg log -G --hidden
269 @ 4:01f36c5a8fda A_3
269 @ 4:01f36c5a8fda A_3
270 |
270 |
271 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda]
271 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda]
272 |/
272 |/
273 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
273 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
274 |/
274 |/
275 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
275 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
276 |/
276 |/
277 o 0:d20a80d4def3 base
277 o 0:d20a80d4def3 base
278
278
279 $ hg debugsuccessorssets --hidden 'all()'
279 $ hg debugsuccessorssets --hidden 'all()'
280 d20a80d4def3
280 d20a80d4def3
281 d20a80d4def3
281 d20a80d4def3
282 007dc284c1f8
282 007dc284c1f8
283 01f36c5a8fda
283 01f36c5a8fda
284 82623d38b9ba
284 82623d38b9ba
285 01f36c5a8fda
285 01f36c5a8fda
286 392fd25390da
286 392fd25390da
287 01f36c5a8fda
287 01f36c5a8fda
288 01f36c5a8fda
288 01f36c5a8fda
289 01f36c5a8fda
289 01f36c5a8fda
290 $ hg log -r 'contentdivergent()'
290 $ hg log -r 'contentdivergent()'
291 $ hg debugsuccessorssets 'all()' --closest
291 $ hg debugsuccessorssets 'all()' --closest
292 d20a80d4def3
292 d20a80d4def3
293 d20a80d4def3
293 d20a80d4def3
294 01f36c5a8fda
294 01f36c5a8fda
295 01f36c5a8fda
295 01f36c5a8fda
296 $ hg debugsuccessorssets 'all()' --closest --hidden
296 $ hg debugsuccessorssets 'all()' --closest --hidden
297 d20a80d4def3
297 d20a80d4def3
298 d20a80d4def3
298 d20a80d4def3
299 007dc284c1f8
299 007dc284c1f8
300 82623d38b9ba
300 82623d38b9ba
301 392fd25390da
301 392fd25390da
302 82623d38b9ba
302 82623d38b9ba
303 82623d38b9ba
303 82623d38b9ba
304 392fd25390da
304 392fd25390da
305 392fd25390da
305 392fd25390da
306 01f36c5a8fda
306 01f36c5a8fda
307 01f36c5a8fda
307 01f36c5a8fda
308 $ cd ..
308 $ cd ..
309
309
310 split is not divergences
310 split is not divergences
311 -----------------------------
311 -----------------------------
312
312
313 $ newcase split
313 $ newcase split
314 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
314 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
315 obsoleted 1 changesets
315 obsoleted 1 changesets
316 $ hg log -G --hidden
316 $ hg log -G --hidden
317 o 3:392fd25390da A_2
317 o 3:392fd25390da A_2
318 |
318 |
319 | o 2:82623d38b9ba A_1
319 | o 2:82623d38b9ba A_1
320 |/
320 |/
321 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
321 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
322 |/
322 |/
323 @ 0:d20a80d4def3 base
323 @ 0:d20a80d4def3 base
324
324
325 $ hg debugsuccessorssets --hidden 'all()'
325 $ hg debugsuccessorssets --hidden 'all()'
326 d20a80d4def3
326 d20a80d4def3
327 d20a80d4def3
327 d20a80d4def3
328 007dc284c1f8
328 007dc284c1f8
329 82623d38b9ba 392fd25390da
329 82623d38b9ba 392fd25390da
330 82623d38b9ba
330 82623d38b9ba
331 82623d38b9ba
331 82623d38b9ba
332 392fd25390da
332 392fd25390da
333 392fd25390da
333 392fd25390da
334 $ hg log -r 'contentdivergent()'
334 $ hg log -r 'contentdivergent()'
335 $ hg debugsuccessorssets 'all()' --closest
335 $ hg debugsuccessorssets 'all()' --closest
336 d20a80d4def3
336 d20a80d4def3
337 d20a80d4def3
337 d20a80d4def3
338 82623d38b9ba
338 82623d38b9ba
339 82623d38b9ba
339 82623d38b9ba
340 392fd25390da
340 392fd25390da
341 392fd25390da
341 392fd25390da
342 $ hg debugsuccessorssets 'all()' --closest --hidden
342 $ hg debugsuccessorssets 'all()' --closest --hidden
343 d20a80d4def3
343 d20a80d4def3
344 d20a80d4def3
344 d20a80d4def3
345 007dc284c1f8
345 007dc284c1f8
346 82623d38b9ba 392fd25390da
346 82623d38b9ba 392fd25390da
347 82623d38b9ba
347 82623d38b9ba
348 82623d38b9ba
348 82623d38b9ba
349 392fd25390da
349 392fd25390da
350 392fd25390da
350 392fd25390da
351
351
352 Even when subsequent rewriting happen
352 Even when subsequent rewriting happen
353
353
354 $ mkcommit A_3
354 $ mkcommit A_3
355 created new head
355 created new head
356 $ hg debugobsolete `getid A_1` `getid A_3`
356 $ hg debugobsolete `getid A_1` `getid A_3`
357 obsoleted 1 changesets
357 obsoleted 1 changesets
358 $ hg up 0
358 $ hg up 0
359 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
359 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
360 $ mkcommit A_4
360 $ mkcommit A_4
361 created new head
361 created new head
362 $ hg debugobsolete `getid A_2` `getid A_4`
362 $ hg debugobsolete `getid A_2` `getid A_4`
363 obsoleted 1 changesets
363 obsoleted 1 changesets
364 $ hg up 0
364 $ hg up 0
365 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
365 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
366 $ mkcommit A_5
366 $ mkcommit A_5
367 created new head
367 created new head
368 $ hg debugobsolete `getid A_4` `getid A_5`
368 $ hg debugobsolete `getid A_4` `getid A_5`
369 obsoleted 1 changesets
369 obsoleted 1 changesets
370 $ hg log -G --hidden
370 $ hg log -G --hidden
371 @ 6:e442cfc57690 A_5
371 @ 6:e442cfc57690 A_5
372 |
372 |
373 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
373 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
374 |/
374 |/
375 | o 4:01f36c5a8fda A_3
375 | o 4:01f36c5a8fda A_3
376 |/
376 |/
377 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
377 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
378 |/
378 |/
379 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
379 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
380 |/
380 |/
381 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
381 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
382 |/
382 |/
383 o 0:d20a80d4def3 base
383 o 0:d20a80d4def3 base
384
384
385 $ hg debugsuccessorssets --hidden 'all()'
385 $ hg debugsuccessorssets --hidden 'all()'
386 d20a80d4def3
386 d20a80d4def3
387 d20a80d4def3
387 d20a80d4def3
388 007dc284c1f8
388 007dc284c1f8
389 01f36c5a8fda e442cfc57690
389 01f36c5a8fda e442cfc57690
390 82623d38b9ba
390 82623d38b9ba
391 01f36c5a8fda
391 01f36c5a8fda
392 392fd25390da
392 392fd25390da
393 e442cfc57690
393 e442cfc57690
394 01f36c5a8fda
394 01f36c5a8fda
395 01f36c5a8fda
395 01f36c5a8fda
396 6a411f0d7a0a
396 6a411f0d7a0a
397 e442cfc57690
397 e442cfc57690
398 e442cfc57690
398 e442cfc57690
399 e442cfc57690
399 e442cfc57690
400 $ hg debugsuccessorssets 'all()' --closest
400 $ hg debugsuccessorssets 'all()' --closest
401 d20a80d4def3
401 d20a80d4def3
402 d20a80d4def3
402 d20a80d4def3
403 01f36c5a8fda
403 01f36c5a8fda
404 01f36c5a8fda
404 01f36c5a8fda
405 e442cfc57690
405 e442cfc57690
406 e442cfc57690
406 e442cfc57690
407 $ hg debugsuccessorssets 'all()' --closest --hidden
407 $ hg debugsuccessorssets 'all()' --closest --hidden
408 d20a80d4def3
408 d20a80d4def3
409 d20a80d4def3
409 d20a80d4def3
410 007dc284c1f8
410 007dc284c1f8
411 82623d38b9ba 392fd25390da
411 82623d38b9ba 392fd25390da
412 82623d38b9ba
412 82623d38b9ba
413 82623d38b9ba
413 82623d38b9ba
414 392fd25390da
414 392fd25390da
415 392fd25390da
415 392fd25390da
416 01f36c5a8fda
416 01f36c5a8fda
417 01f36c5a8fda
417 01f36c5a8fda
418 6a411f0d7a0a
418 6a411f0d7a0a
419 e442cfc57690
419 e442cfc57690
420 e442cfc57690
420 e442cfc57690
421 e442cfc57690
421 e442cfc57690
422 $ hg log -r 'contentdivergent()'
422 $ hg log -r 'contentdivergent()'
423
423
424 Check more complex obsolescence graft (with divergence)
424 Check more complex obsolescence graft (with divergence)
425
425
426 $ mkcommit B_0; hg up 0
426 $ mkcommit B_0; hg up 0
427 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
427 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
428 $ hg debugobsolete `getid B_0` `getid A_2`
428 $ hg debugobsolete `getid B_0` `getid A_2`
429 obsoleted 1 changesets
429 obsoleted 1 changesets
430 $ mkcommit A_7; hg up 0
430 $ mkcommit A_7; hg up 0
431 created new head
431 created new head
432 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
432 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
433 $ mkcommit A_8; hg up 0
433 $ mkcommit A_8; hg up 0
434 created new head
434 created new head
435 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
435 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
436 $ hg debugobsolete `getid A_5` `getid A_7` `getid A_8`
436 $ hg debugobsolete `getid A_5` `getid A_7` `getid A_8`
437 obsoleted 1 changesets
437 obsoleted 1 changesets
438 $ mkcommit A_9; hg up 0
438 $ mkcommit A_9; hg up 0
439 created new head
439 created new head
440 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
440 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
441 $ hg debugobsolete `getid A_5` `getid A_9`
441 $ hg debugobsolete `getid A_5` `getid A_9`
442 4 new content-divergent changesets
442 4 new content-divergent changesets
443 $ hg log -G --hidden
443 $ hg log -G --hidden
444 * 10:bed64f5d2f5a A_9
444 * 10:bed64f5d2f5a A_9
445 |
445 |
446 | * 9:14608b260df8 A_8
446 | * 9:14608b260df8 A_8
447 |/
447 |/
448 | * 8:7ae126973a96 A_7
448 | * 8:7ae126973a96 A_7
449 |/
449 |/
450 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da]
450 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da]
451 | |
451 | |
452 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a; split as 8:7ae126973a96, 9:14608b260df8]
452 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a; split as 8:7ae126973a96, 9:14608b260df8]
453 |/
453 |/
454 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
454 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
455 |/
455 |/
456 | * 4:01f36c5a8fda A_3
456 | * 4:01f36c5a8fda A_3
457 |/
457 |/
458 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
458 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
459 |/
459 |/
460 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
460 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
461 |/
461 |/
462 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
462 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
463 |/
463 |/
464 @ 0:d20a80d4def3 base
464 @ 0:d20a80d4def3 base
465
465
466 $ hg debugsuccessorssets --hidden 'all()'
466 $ hg debugsuccessorssets --hidden 'all()'
467 d20a80d4def3
467 d20a80d4def3
468 d20a80d4def3
468 d20a80d4def3
469 007dc284c1f8
469 007dc284c1f8
470 01f36c5a8fda bed64f5d2f5a
470 01f36c5a8fda bed64f5d2f5a
471 01f36c5a8fda 7ae126973a96 14608b260df8
471 01f36c5a8fda 7ae126973a96 14608b260df8
472 82623d38b9ba
472 82623d38b9ba
473 01f36c5a8fda
473 01f36c5a8fda
474 392fd25390da
474 392fd25390da
475 bed64f5d2f5a
475 bed64f5d2f5a
476 7ae126973a96 14608b260df8
476 7ae126973a96 14608b260df8
477 01f36c5a8fda
477 01f36c5a8fda
478 01f36c5a8fda
478 01f36c5a8fda
479 6a411f0d7a0a
479 6a411f0d7a0a
480 bed64f5d2f5a
480 bed64f5d2f5a
481 7ae126973a96 14608b260df8
481 7ae126973a96 14608b260df8
482 e442cfc57690
482 e442cfc57690
483 bed64f5d2f5a
483 bed64f5d2f5a
484 7ae126973a96 14608b260df8
484 7ae126973a96 14608b260df8
485 3750ebee865d
485 3750ebee865d
486 bed64f5d2f5a
486 bed64f5d2f5a
487 7ae126973a96 14608b260df8
487 7ae126973a96 14608b260df8
488 7ae126973a96
488 7ae126973a96
489 7ae126973a96
489 7ae126973a96
490 14608b260df8
490 14608b260df8
491 14608b260df8
491 14608b260df8
492 bed64f5d2f5a
492 bed64f5d2f5a
493 bed64f5d2f5a
493 bed64f5d2f5a
494 $ hg debugsuccessorssets 'all()' --closest
494 $ hg debugsuccessorssets 'all()' --closest
495 d20a80d4def3
495 d20a80d4def3
496 d20a80d4def3
496 d20a80d4def3
497 01f36c5a8fda
497 01f36c5a8fda
498 01f36c5a8fda
498 01f36c5a8fda
499 7ae126973a96
499 7ae126973a96
500 7ae126973a96
500 7ae126973a96
501 14608b260df8
501 14608b260df8
502 14608b260df8
502 14608b260df8
503 bed64f5d2f5a
503 bed64f5d2f5a
504 bed64f5d2f5a
504 bed64f5d2f5a
505 $ hg debugsuccessorssets 'all()' --closest --hidden
505 $ hg debugsuccessorssets 'all()' --closest --hidden
506 d20a80d4def3
506 d20a80d4def3
507 d20a80d4def3
507 d20a80d4def3
508 007dc284c1f8
508 007dc284c1f8
509 82623d38b9ba 392fd25390da
509 82623d38b9ba 392fd25390da
510 82623d38b9ba
510 82623d38b9ba
511 82623d38b9ba
511 82623d38b9ba
512 392fd25390da
512 392fd25390da
513 392fd25390da
513 392fd25390da
514 01f36c5a8fda
514 01f36c5a8fda
515 01f36c5a8fda
515 01f36c5a8fda
516 6a411f0d7a0a
516 6a411f0d7a0a
517 e442cfc57690
517 e442cfc57690
518 e442cfc57690
518 e442cfc57690
519 e442cfc57690
519 e442cfc57690
520 3750ebee865d
520 3750ebee865d
521 392fd25390da
521 392fd25390da
522 7ae126973a96
522 7ae126973a96
523 7ae126973a96
523 7ae126973a96
524 14608b260df8
524 14608b260df8
525 14608b260df8
525 14608b260df8
526 bed64f5d2f5a
526 bed64f5d2f5a
527 bed64f5d2f5a
527 bed64f5d2f5a
528 $ hg log -r 'contentdivergent()'
528 $ hg log -r 'contentdivergent()'
529 4:01f36c5a8fda A_3
529 4:01f36c5a8fda A_3
530 8:7ae126973a96 A_7
530 8:7ae126973a96 A_7
531 9:14608b260df8 A_8
531 9:14608b260df8 A_8
532 10:bed64f5d2f5a A_9
532 10:bed64f5d2f5a A_9
533
533
534 $ hg log -r bed64f5d2f5a -T '{whyunstable}\n' | sort
535 content-divergent: 4:01f36c5a8fda (draft) 8:7ae126973a96 (draft) 9:14608b260df8 (draft) predecessor 007dc284c1f8
536 content-divergent: 8:7ae126973a96 (draft) 9:14608b260df8 (draft) predecessor e442cfc57690
537 $ hg log -r bed64f5d2f5a -T whyunstableshort | sort
538 content-divergent: 4:01f36c5a8fda (draft) 8:7ae126973a96 (draft) 9:14608b260df8 (draft) predecessor 007d
539 content-divergent: 8:7ae126973a96 (draft) 9:14608b260df8 (draft) predecessor e442
540 $ hg log -r bed64f5d2f5a -T whyunstableshorter | sort
541 content-divergent: 01f3 (draft) 7ae1 (draft) 1460 (draft) predecessor 007d
542 content-divergent: 7ae1 (draft) 1460 (draft) predecessor e442
543
534 fix the divergence
544 fix the divergence
535
545
536 $ mkcommit A_A; hg up 0
546 $ mkcommit A_A; hg up 0
537 created new head
547 created new head
538 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
548 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
539 $ hg debugobsolete `getid A_9` `getid A_A`
549 $ hg debugobsolete `getid A_9` `getid A_A`
540 obsoleted 1 changesets
550 obsoleted 1 changesets
541 $ hg debugobsolete `getid A_7` `getid A_A`
551 $ hg debugobsolete `getid A_7` `getid A_A`
542 obsoleted 1 changesets
552 obsoleted 1 changesets
543 $ hg debugobsolete `getid A_8` `getid A_A`
553 $ hg debugobsolete `getid A_8` `getid A_A`
544 obsoleted 1 changesets
554 obsoleted 1 changesets
545 $ hg log -G --hidden
555 $ hg log -G --hidden
546 o 11:a139f71be9da A_A
556 o 11:a139f71be9da A_A
547 |
557 |
548 | x 10:bed64f5d2f5a A_9 [rewritten as 11:a139f71be9da]
558 | x 10:bed64f5d2f5a A_9 [rewritten as 11:a139f71be9da]
549 |/
559 |/
550 | x 9:14608b260df8 A_8 [rewritten as 11:a139f71be9da]
560 | x 9:14608b260df8 A_8 [rewritten as 11:a139f71be9da]
551 |/
561 |/
552 | x 8:7ae126973a96 A_7 [rewritten as 11:a139f71be9da]
562 | x 8:7ae126973a96 A_7 [rewritten as 11:a139f71be9da]
553 |/
563 |/
554 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da]
564 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da]
555 | |
565 | |
556 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a; split as 8:7ae126973a96, 9:14608b260df8]
566 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a; split as 8:7ae126973a96, 9:14608b260df8]
557 |/
567 |/
558 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
568 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
559 |/
569 |/
560 | o 4:01f36c5a8fda A_3
570 | o 4:01f36c5a8fda A_3
561 |/
571 |/
562 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
572 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
563 |/
573 |/
564 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
574 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
565 |/
575 |/
566 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
576 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
567 |/
577 |/
568 @ 0:d20a80d4def3 base
578 @ 0:d20a80d4def3 base
569
579
570 $ hg debugsuccessorssets --hidden 'all()'
580 $ hg debugsuccessorssets --hidden 'all()'
571 d20a80d4def3
581 d20a80d4def3
572 d20a80d4def3
582 d20a80d4def3
573 007dc284c1f8
583 007dc284c1f8
574 01f36c5a8fda a139f71be9da
584 01f36c5a8fda a139f71be9da
575 82623d38b9ba
585 82623d38b9ba
576 01f36c5a8fda
586 01f36c5a8fda
577 392fd25390da
587 392fd25390da
578 a139f71be9da
588 a139f71be9da
579 01f36c5a8fda
589 01f36c5a8fda
580 01f36c5a8fda
590 01f36c5a8fda
581 6a411f0d7a0a
591 6a411f0d7a0a
582 a139f71be9da
592 a139f71be9da
583 e442cfc57690
593 e442cfc57690
584 a139f71be9da
594 a139f71be9da
585 3750ebee865d
595 3750ebee865d
586 a139f71be9da
596 a139f71be9da
587 7ae126973a96
597 7ae126973a96
588 a139f71be9da
598 a139f71be9da
589 14608b260df8
599 14608b260df8
590 a139f71be9da
600 a139f71be9da
591 bed64f5d2f5a
601 bed64f5d2f5a
592 a139f71be9da
602 a139f71be9da
593 a139f71be9da
603 a139f71be9da
594 a139f71be9da
604 a139f71be9da
595 $ hg debugsuccessorssets 'all()' --closest
605 $ hg debugsuccessorssets 'all()' --closest
596 d20a80d4def3
606 d20a80d4def3
597 d20a80d4def3
607 d20a80d4def3
598 01f36c5a8fda
608 01f36c5a8fda
599 01f36c5a8fda
609 01f36c5a8fda
600 a139f71be9da
610 a139f71be9da
601 a139f71be9da
611 a139f71be9da
602 $ hg debugsuccessorssets 'all()' --closest --hidden
612 $ hg debugsuccessorssets 'all()' --closest --hidden
603 d20a80d4def3
613 d20a80d4def3
604 d20a80d4def3
614 d20a80d4def3
605 007dc284c1f8
615 007dc284c1f8
606 82623d38b9ba 392fd25390da
616 82623d38b9ba 392fd25390da
607 82623d38b9ba
617 82623d38b9ba
608 82623d38b9ba
618 82623d38b9ba
609 392fd25390da
619 392fd25390da
610 392fd25390da
620 392fd25390da
611 01f36c5a8fda
621 01f36c5a8fda
612 01f36c5a8fda
622 01f36c5a8fda
613 6a411f0d7a0a
623 6a411f0d7a0a
614 e442cfc57690
624 e442cfc57690
615 e442cfc57690
625 e442cfc57690
616 e442cfc57690
626 e442cfc57690
617 3750ebee865d
627 3750ebee865d
618 392fd25390da
628 392fd25390da
619 7ae126973a96
629 7ae126973a96
620 a139f71be9da
630 a139f71be9da
621 14608b260df8
631 14608b260df8
622 a139f71be9da
632 a139f71be9da
623 bed64f5d2f5a
633 bed64f5d2f5a
624 a139f71be9da
634 a139f71be9da
625 a139f71be9da
635 a139f71be9da
626 a139f71be9da
636 a139f71be9da
627 $ hg log -r 'contentdivergent()'
637 $ hg log -r 'contentdivergent()'
628
638
629 #if serve
639 #if serve
630
640
631 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid --config web.view=all \
641 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid --config web.view=all \
632 > -A access.log -E errors.log
642 > -A access.log -E errors.log
633 $ cat hg.pid >> $DAEMON_PIDS
643 $ cat hg.pid >> $DAEMON_PIDS
634
644
635 check an obsolete changeset that was rewritten and also split
645 check an obsolete changeset that was rewritten and also split
636
646
637 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=paper' | egrep 'rewritten|split'
647 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=paper' | egrep 'rewritten|split'
638 <td>rewritten as <a href="/rev/bed64f5d2f5a?style=paper">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span><br>
648 <td>rewritten as <a href="/rev/bed64f5d2f5a?style=paper">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span><br>
639 split as <a href="/rev/7ae126973a96?style=paper">7ae126973a96</a> <a href="/rev/14608b260df8?style=paper">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
649 split as <a href="/rev/7ae126973a96?style=paper">7ae126973a96</a> <a href="/rev/14608b260df8?style=paper">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
640 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=coal' | egrep 'rewritten|split'
650 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=coal' | egrep 'rewritten|split'
641 <td>rewritten as <a href="/rev/bed64f5d2f5a?style=coal">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span><br>
651 <td>rewritten as <a href="/rev/bed64f5d2f5a?style=coal">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span><br>
642 split as <a href="/rev/7ae126973a96?style=coal">7ae126973a96</a> <a href="/rev/14608b260df8?style=coal">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
652 split as <a href="/rev/7ae126973a96?style=coal">7ae126973a96</a> <a href="/rev/14608b260df8?style=coal">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
643 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=gitweb' | egrep 'rewritten|split'
653 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=gitweb' | egrep 'rewritten|split'
644 <td>rewritten as <a class="list" href="/rev/bed64f5d2f5a?style=gitweb">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
654 <td>rewritten as <a class="list" href="/rev/bed64f5d2f5a?style=gitweb">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
645 <td>split as <a class="list" href="/rev/7ae126973a96?style=gitweb">7ae126973a96</a> <a class="list" href="/rev/14608b260df8?style=gitweb">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
655 <td>split as <a class="list" href="/rev/7ae126973a96?style=gitweb">7ae126973a96</a> <a class="list" href="/rev/14608b260df8?style=gitweb">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
646 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=monoblue' | egrep 'rewritten|split'
656 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=monoblue' | egrep 'rewritten|split'
647 <dd>rewritten as <a href="/rev/bed64f5d2f5a?style=monoblue">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></dd>
657 <dd>rewritten as <a href="/rev/bed64f5d2f5a?style=monoblue">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></dd>
648 <dd>split as <a href="/rev/7ae126973a96?style=monoblue">7ae126973a96</a> <a href="/rev/14608b260df8?style=monoblue">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></dd>
658 <dd>split as <a href="/rev/7ae126973a96?style=monoblue">7ae126973a96</a> <a href="/rev/14608b260df8?style=monoblue">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></dd>
649 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=spartan' | egrep 'rewritten|split'
659 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=spartan' | egrep 'rewritten|split'
650 <td class="obsolete">rewritten as <a href="/rev/bed64f5d2f5a?style=spartan">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
660 <td class="obsolete">rewritten as <a href="/rev/bed64f5d2f5a?style=spartan">bed64f5d2f5a</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
651 <td class="obsolete">split as <a href="/rev/7ae126973a96?style=spartan">7ae126973a96</a> <a href="/rev/14608b260df8?style=spartan">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
661 <td class="obsolete">split as <a href="/rev/7ae126973a96?style=spartan">7ae126973a96</a> <a href="/rev/14608b260df8?style=spartan">14608b260df8</a> by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
652
662
653 $ killdaemons.py
663 $ killdaemons.py
654
664
655 #endif
665 #endif
656
666
657 $ cd ..
667 $ cd ..
658
668
659
669
660 Subset does not diverge
670 Subset does not diverge
661 ------------------------------
671 ------------------------------
662
672
663 Do not report divergent successors-set if it is a subset of another
673 Do not report divergent successors-set if it is a subset of another
664 successors-set. (report [A,B] not [A] + [A,B])
674 successors-set. (report [A,B] not [A] + [A,B])
665
675
666 $ newcase subset
676 $ newcase subset
667 $ hg debugobsolete `getid A_0` `getid A_2`
677 $ hg debugobsolete `getid A_0` `getid A_2`
668 obsoleted 1 changesets
678 obsoleted 1 changesets
669 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
679 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
670 $ hg debugsuccessorssets --hidden 'desc('A_0')'
680 $ hg debugsuccessorssets --hidden 'desc('A_0')'
671 007dc284c1f8
681 007dc284c1f8
672 82623d38b9ba 392fd25390da
682 82623d38b9ba 392fd25390da
673 $ hg debugsuccessorssets 'desc('A_0')' --closest
683 $ hg debugsuccessorssets 'desc('A_0')' --closest
674 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
684 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
675 007dc284c1f8
685 007dc284c1f8
676 82623d38b9ba 392fd25390da
686 82623d38b9ba 392fd25390da
677
687
678 $ cd ..
688 $ cd ..
679
689
680 Use scmutil.cleanupnodes API to create divergence
690 Use scmutil.cleanupnodes API to create divergence
681
691
682 $ hg init cleanupnodes
692 $ hg init cleanupnodes
683 $ cd cleanupnodes
693 $ cd cleanupnodes
684 $ hg debugdrawdag <<'EOS'
694 $ hg debugdrawdag <<'EOS'
685 > B1 B3 B4
695 > B1 B3 B4
686 > | \|
696 > | \|
687 > A Z
697 > A Z
688 > EOS
698 > EOS
689
699
690 $ hg update -q B1
700 $ hg update -q B1
691 $ echo 3 >> B
701 $ echo 3 >> B
692 $ hg commit --amend -m B2
702 $ hg commit --amend -m B2
693 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
703 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
694 > from mercurial import registrar, scmutil
704 > from mercurial import registrar, scmutil
695 > cmdtable = {}
705 > cmdtable = {}
696 > command = registrar.command(cmdtable)
706 > command = registrar.command(cmdtable)
697 > @command('cleanup')
707 > @command('cleanup')
698 > def cleanup(ui, repo):
708 > def cleanup(ui, repo):
699 > def node(expr):
709 > def node(expr):
700 > unfi = repo.unfiltered()
710 > unfi = repo.unfiltered()
701 > rev = unfi.revs(expr).first()
711 > rev = unfi.revs(expr).first()
702 > return unfi.changelog.node(rev)
712 > return unfi.changelog.node(rev)
703 > with repo.wlock(), repo.lock(), repo.transaction('delayedstrip'):
713 > with repo.wlock(), repo.lock(), repo.transaction('delayedstrip'):
704 > mapping = {node('desc(B1)'): [node('desc(B3)')],
714 > mapping = {node('desc(B1)'): [node('desc(B3)')],
705 > node('desc(B3)'): [node('desc(B4)')]}
715 > node('desc(B3)'): [node('desc(B4)')]}
706 > scmutil.cleanupnodes(repo, mapping, 'test')
716 > scmutil.cleanupnodes(repo, mapping, 'test')
707 > EOF
717 > EOF
708
718
709 $ rm .hg/localtags
719 $ rm .hg/localtags
710 $ hg cleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
720 $ hg cleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
711 2 new content-divergent changesets
721 2 new content-divergent changesets
712 $ hg log -G -T '{rev}:{node|short} {desc} {instabilities}' -r 'sort(all(), topo)'
722 $ hg log -G -T '{rev}:{node|short} {desc} {instabilities}' -r 'sort(all(), topo)'
713 @ 5:1a2a9b5b0030 B2 content-divergent
723 @ 5:1a2a9b5b0030 B2 content-divergent
714 |
724 |
715 | * 4:70d5a63ca112 B4 content-divergent
725 | * 4:70d5a63ca112 B4 content-divergent
716 | |
726 | |
717 | o 1:48b9aae0607f Z
727 | o 1:48b9aae0607f Z
718 |
728 |
719 o 0:426bada5c675 A
729 o 0:426bada5c675 A
720
730
721 $ hg debugobsolete
731 $ hg debugobsolete
722 a178212c3433c4e77b573f6011e29affb8aefa33 1a2a9b5b0030632400aa78e00388c20f99d3ec44 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
732 a178212c3433c4e77b573f6011e29affb8aefa33 1a2a9b5b0030632400aa78e00388c20f99d3ec44 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
723 a178212c3433c4e77b573f6011e29affb8aefa33 ad6478fb94ecec98b86daae98722865d494ac561 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'test', 'user': 'test'}
733 a178212c3433c4e77b573f6011e29affb8aefa33 ad6478fb94ecec98b86daae98722865d494ac561 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'test', 'user': 'test'}
724 ad6478fb94ecec98b86daae98722865d494ac561 70d5a63ca112acb3764bc1d7320ca90ea688d671 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'test', 'user': 'test'}
734 ad6478fb94ecec98b86daae98722865d494ac561 70d5a63ca112acb3764bc1d7320ca90ea688d671 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'test', 'user': 'test'}
725
735
726 $ hg debugwhyunstable 1a2a9b5b0030
736 $ hg debugwhyunstable 1a2a9b5b0030
727 content-divergent: 70d5a63ca112acb3764bc1d7320ca90ea688d671 (draft) predecessor a178212c3433c4e77b573f6011e29affb8aefa33
737 content-divergent: 70d5a63ca112acb3764bc1d7320ca90ea688d671 (draft) predecessor a178212c3433c4e77b573f6011e29affb8aefa33
728
738
729 $ hg log -r 1a2a9b5b0030 -T '{whyunstable}\n'
739 $ hg log -r 1a2a9b5b0030 -T '{whyunstable}\n'
730 content-divergent: 4:70d5a63ca112 (draft) predecessor a178212c3433
740 content-divergent: 4:70d5a63ca112 (draft) predecessor a178212c3433
731 $ hg log -r 1a2a9b5b0030 -T whyunstableshort
741 $ hg log -r 1a2a9b5b0030 -T whyunstableshort
732 content-divergent: 4:70d5a63ca112 (draft) predecessor a178
742 content-divergent: 4:70d5a63ca112 (draft) predecessor a178
733 $ hg log -r 1a2a9b5b0030 -T whyunstableshorter
743 $ hg log -r 1a2a9b5b0030 -T whyunstableshorter
734 content-divergent: 70d5 (draft) predecessor a178
744 content-divergent: 70d5 (draft) predecessor a178
735
745
736 #if serve
746 #if serve
737
747
738 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
748 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
739 $ cat hg.pid >> $DAEMON_PIDS
749 $ cat hg.pid >> $DAEMON_PIDS
740
750
741 check explanation for a content-divergent changeset
751 check explanation for a content-divergent changeset
742
752
743 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=paper' | grep divergent:
753 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=paper' | grep divergent:
744 <td>content-divergent: <a href="/rev/70d5a63ca112?style=paper">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=paper">a178212c3433</a></td>
754 <td>content-divergent: <a href="/rev/70d5a63ca112?style=paper">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=paper">a178212c3433</a></td>
745 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=coal' | grep divergent:
755 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=coal' | grep divergent:
746 <td>content-divergent: <a href="/rev/70d5a63ca112?style=coal">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=coal">a178212c3433</a></td>
756 <td>content-divergent: <a href="/rev/70d5a63ca112?style=coal">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=coal">a178212c3433</a></td>
747 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=gitweb' | grep divergent:
757 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=gitweb' | grep divergent:
748 <td>content-divergent: <a class="list" href="/rev/70d5a63ca112?style=gitweb">70d5a63ca112</a> (draft) predecessor <a class="list" href="/rev/a178212c3433?style=gitweb">a178212c3433</a></td>
758 <td>content-divergent: <a class="list" href="/rev/70d5a63ca112?style=gitweb">70d5a63ca112</a> (draft) predecessor <a class="list" href="/rev/a178212c3433?style=gitweb">a178212c3433</a></td>
749 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=monoblue' | grep divergent:
759 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=monoblue' | grep divergent:
750 <dd>content-divergent: <a href="/rev/70d5a63ca112?style=monoblue">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=monoblue">a178212c3433</a></dd>
760 <dd>content-divergent: <a href="/rev/70d5a63ca112?style=monoblue">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=monoblue">a178212c3433</a></dd>
751 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=spartan' | grep divergent:
761 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=spartan' | grep divergent:
752 <td class="unstable">content-divergent: <a href="/rev/70d5a63ca112?style=spartan">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=spartan">a178212c3433</a></td>
762 <td class="unstable">content-divergent: <a href="/rev/70d5a63ca112?style=spartan">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=spartan">a178212c3433</a></td>
753
763
754 $ killdaemons.py
764 $ killdaemons.py
755
765
756 #endif
766 #endif
General Comments 0
You need to be logged in to leave comments. Login now