##// END OF EJS Templates
templates: make divergentnodes in whyunstable keyword be a hybrid list
av6 -
r37704:b1b1b062 default
parent child Browse files
Show More
@@ -1,825 +1,827 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 entry['divergentnodes'] = ''.join(formatnode(dnode)
812 dnhybrid = _hybrid(None, [dnode.hex() for dnode in dnodes],
813 for dnode in dnodes)
813 lambda x: {'ctx': repo[x]},
814 lambda x: formatnode(repo[x]))
815 entry['divergentnodes'] = dnhybrid
814
816
815 tmpl = '{instability}:{divergentnodes} {reason} {node|short}'
817 tmpl = '{instability}:{divergentnodes} {reason} {node|short}'
816 return templateutil.mappinglist(entries, tmpl=tmpl, sep='\n')
818 return templateutil.mappinglist(entries, tmpl=tmpl, sep='\n')
817
819
818 def loadkeyword(ui, extname, registrarobj):
820 def loadkeyword(ui, extname, registrarobj):
819 """Load template keyword from specified registrarobj
821 """Load template keyword from specified registrarobj
820 """
822 """
821 for name, func in registrarobj._table.iteritems():
823 for name, func in registrarobj._table.iteritems():
822 keywords[name] = func
824 keywords[name] = func
823
825
824 # tell hggettext to extract docstrings from these functions:
826 # tell hggettext to extract docstrings from these functions:
825 i18nfunctions = keywords.values()
827 i18nfunctions = keywords.values()
@@ -1,749 +1,751 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 > EOF
19 > EOF
20
20
21
21
22 $ mkcommit() {
22 $ mkcommit() {
23 > echo "$1" > "$1"
23 > echo "$1" > "$1"
24 > hg add "$1"
24 > hg add "$1"
25 > hg ci -m "$1"
25 > hg ci -m "$1"
26 > }
26 > }
27 $ getid() {
27 $ getid() {
28 > hg log --hidden -r "desc('$1')" -T '{node}\n'
28 > hg log --hidden -r "desc('$1')" -T '{node}\n'
29 > }
29 > }
30
30
31 setup repo
31 setup repo
32
32
33 $ hg init reference
33 $ hg init reference
34 $ cd reference
34 $ cd reference
35 $ mkcommit base
35 $ mkcommit base
36 $ mkcommit A_0
36 $ mkcommit A_0
37 $ hg up 0
37 $ hg up 0
38 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
38 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
39 $ mkcommit A_1
39 $ mkcommit A_1
40 created new head
40 created new head
41 $ hg up 0
41 $ hg up 0
42 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
42 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
43 $ mkcommit A_2
43 $ mkcommit A_2
44 created new head
44 created new head
45 $ hg up 0
45 $ hg up 0
46 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
46 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
47 $ cd ..
47 $ cd ..
48
48
49
49
50 $ newcase() {
50 $ newcase() {
51 > hg clone -u 0 -q reference $1
51 > hg clone -u 0 -q reference $1
52 > cd $1
52 > cd $1
53 > }
53 > }
54
54
55 direct divergence
55 direct divergence
56 -----------------
56 -----------------
57
57
58 A_1 have two direct and divergent successors A_1 and A_1
58 A_1 have two direct and divergent successors A_1 and A_1
59
59
60 $ newcase direct
60 $ newcase direct
61 $ hg debugobsolete `getid A_0` `getid A_1`
61 $ hg debugobsolete `getid A_0` `getid A_1`
62 obsoleted 1 changesets
62 obsoleted 1 changesets
63 $ hg debugobsolete `getid A_0` `getid A_2`
63 $ hg debugobsolete `getid A_0` `getid A_2`
64 2 new content-divergent changesets
64 2 new content-divergent changesets
65 $ hg log -G --hidden
65 $ hg log -G --hidden
66 * 3:392fd25390da A_2
66 * 3:392fd25390da A_2
67 |
67 |
68 | * 2:82623d38b9ba A_1
68 | * 2:82623d38b9ba A_1
69 |/
69 |/
70 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
70 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
71 |/
71 |/
72 @ 0:d20a80d4def3 base
72 @ 0:d20a80d4def3 base
73
73
74 $ hg debugsuccessorssets --hidden 'all()'
74 $ hg debugsuccessorssets --hidden 'all()'
75 d20a80d4def3
75 d20a80d4def3
76 d20a80d4def3
76 d20a80d4def3
77 007dc284c1f8
77 007dc284c1f8
78 82623d38b9ba
78 82623d38b9ba
79 392fd25390da
79 392fd25390da
80 82623d38b9ba
80 82623d38b9ba
81 82623d38b9ba
81 82623d38b9ba
82 392fd25390da
82 392fd25390da
83 392fd25390da
83 392fd25390da
84 $ hg log -r 'contentdivergent()'
84 $ hg log -r 'contentdivergent()'
85 2:82623d38b9ba A_1
85 2:82623d38b9ba A_1
86 3:392fd25390da A_2
86 3:392fd25390da A_2
87 $ hg debugsuccessorssets 'all()' --closest
87 $ hg debugsuccessorssets 'all()' --closest
88 d20a80d4def3
88 d20a80d4def3
89 d20a80d4def3
89 d20a80d4def3
90 82623d38b9ba
90 82623d38b9ba
91 82623d38b9ba
91 82623d38b9ba
92 392fd25390da
92 392fd25390da
93 392fd25390da
93 392fd25390da
94 $ hg debugsuccessorssets 'all()' --closest --hidden
94 $ hg debugsuccessorssets 'all()' --closest --hidden
95 d20a80d4def3
95 d20a80d4def3
96 d20a80d4def3
96 d20a80d4def3
97 007dc284c1f8
97 007dc284c1f8
98 82623d38b9ba
98 82623d38b9ba
99 392fd25390da
99 392fd25390da
100 82623d38b9ba
100 82623d38b9ba
101 82623d38b9ba
101 82623d38b9ba
102 392fd25390da
102 392fd25390da
103 392fd25390da
103 392fd25390da
104
104
105 check that mercurial refuse to push
105 check that mercurial refuse to push
106
106
107 $ hg init ../other
107 $ hg init ../other
108 $ hg push ../other
108 $ hg push ../other
109 pushing to ../other
109 pushing to ../other
110 searching for changes
110 searching for changes
111 abort: push includes content-divergent changeset: 392fd25390da!
111 abort: push includes content-divergent changeset: 392fd25390da!
112 [255]
112 [255]
113
113
114 $ cd ..
114 $ cd ..
115
115
116
116
117 indirect divergence with known changeset
117 indirect divergence with known changeset
118 -------------------------------------------
118 -------------------------------------------
119
119
120 $ newcase indirect_known
120 $ newcase indirect_known
121 $ hg debugobsolete `getid A_0` `getid A_1`
121 $ hg debugobsolete `getid A_0` `getid A_1`
122 obsoleted 1 changesets
122 obsoleted 1 changesets
123 $ hg debugobsolete `getid A_0` `getid A_2`
123 $ hg debugobsolete `getid A_0` `getid A_2`
124 2 new content-divergent changesets
124 2 new content-divergent changesets
125 $ mkcommit A_3
125 $ mkcommit A_3
126 created new head
126 created new head
127 $ hg debugobsolete `getid A_2` `getid A_3`
127 $ hg debugobsolete `getid A_2` `getid A_3`
128 obsoleted 1 changesets
128 obsoleted 1 changesets
129 $ hg log -G --hidden
129 $ hg log -G --hidden
130 @ 4:01f36c5a8fda A_3
130 @ 4:01f36c5a8fda A_3
131 |
131 |
132 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda]
132 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda]
133 |/
133 |/
134 | * 2:82623d38b9ba A_1
134 | * 2:82623d38b9ba A_1
135 |/
135 |/
136 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
136 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
137 |/
137 |/
138 o 0:d20a80d4def3 base
138 o 0:d20a80d4def3 base
139
139
140 $ hg debugsuccessorssets --hidden 'all()'
140 $ hg debugsuccessorssets --hidden 'all()'
141 d20a80d4def3
141 d20a80d4def3
142 d20a80d4def3
142 d20a80d4def3
143 007dc284c1f8
143 007dc284c1f8
144 82623d38b9ba
144 82623d38b9ba
145 01f36c5a8fda
145 01f36c5a8fda
146 82623d38b9ba
146 82623d38b9ba
147 82623d38b9ba
147 82623d38b9ba
148 392fd25390da
148 392fd25390da
149 01f36c5a8fda
149 01f36c5a8fda
150 01f36c5a8fda
150 01f36c5a8fda
151 01f36c5a8fda
151 01f36c5a8fda
152 $ hg log -r 'contentdivergent()'
152 $ hg log -r 'contentdivergent()'
153 2:82623d38b9ba A_1
153 2:82623d38b9ba A_1
154 4:01f36c5a8fda A_3
154 4:01f36c5a8fda A_3
155 $ hg debugsuccessorssets 'all()' --closest
155 $ hg debugsuccessorssets 'all()' --closest
156 d20a80d4def3
156 d20a80d4def3
157 d20a80d4def3
157 d20a80d4def3
158 82623d38b9ba
158 82623d38b9ba
159 82623d38b9ba
159 82623d38b9ba
160 01f36c5a8fda
160 01f36c5a8fda
161 01f36c5a8fda
161 01f36c5a8fda
162 $ hg debugsuccessorssets 'all()' --closest --hidden
162 $ hg debugsuccessorssets 'all()' --closest --hidden
163 d20a80d4def3
163 d20a80d4def3
164 d20a80d4def3
164 d20a80d4def3
165 007dc284c1f8
165 007dc284c1f8
166 82623d38b9ba
166 82623d38b9ba
167 392fd25390da
167 392fd25390da
168 82623d38b9ba
168 82623d38b9ba
169 82623d38b9ba
169 82623d38b9ba
170 392fd25390da
170 392fd25390da
171 392fd25390da
171 392fd25390da
172 01f36c5a8fda
172 01f36c5a8fda
173 01f36c5a8fda
173 01f36c5a8fda
174 $ cd ..
174 $ cd ..
175
175
176
176
177 indirect divergence with known changeset
177 indirect divergence with known changeset
178 -------------------------------------------
178 -------------------------------------------
179
179
180 $ newcase indirect_unknown
180 $ newcase indirect_unknown
181 $ hg debugobsolete `getid A_0` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
181 $ hg debugobsolete `getid A_0` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
182 obsoleted 1 changesets
182 obsoleted 1 changesets
183 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid A_1`
183 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid A_1`
184 $ hg debugobsolete `getid A_0` `getid A_2`
184 $ hg debugobsolete `getid A_0` `getid A_2`
185 2 new content-divergent changesets
185 2 new content-divergent changesets
186 $ hg log -G --hidden
186 $ hg log -G --hidden
187 * 3:392fd25390da A_2
187 * 3:392fd25390da A_2
188 |
188 |
189 | * 2:82623d38b9ba A_1
189 | * 2:82623d38b9ba A_1
190 |/
190 |/
191 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
191 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
192 |/
192 |/
193 @ 0:d20a80d4def3 base
193 @ 0:d20a80d4def3 base
194
194
195 $ hg debugsuccessorssets --hidden 'all()'
195 $ hg debugsuccessorssets --hidden 'all()'
196 d20a80d4def3
196 d20a80d4def3
197 d20a80d4def3
197 d20a80d4def3
198 007dc284c1f8
198 007dc284c1f8
199 82623d38b9ba
199 82623d38b9ba
200 392fd25390da
200 392fd25390da
201 82623d38b9ba
201 82623d38b9ba
202 82623d38b9ba
202 82623d38b9ba
203 392fd25390da
203 392fd25390da
204 392fd25390da
204 392fd25390da
205 $ hg log -r 'contentdivergent()'
205 $ hg log -r 'contentdivergent()'
206 2:82623d38b9ba A_1
206 2:82623d38b9ba A_1
207 3:392fd25390da A_2
207 3:392fd25390da A_2
208 $ hg debugsuccessorssets 'all()' --closest
208 $ hg debugsuccessorssets 'all()' --closest
209 d20a80d4def3
209 d20a80d4def3
210 d20a80d4def3
210 d20a80d4def3
211 82623d38b9ba
211 82623d38b9ba
212 82623d38b9ba
212 82623d38b9ba
213 392fd25390da
213 392fd25390da
214 392fd25390da
214 392fd25390da
215 $ hg debugsuccessorssets 'all()' --closest --hidden
215 $ hg debugsuccessorssets 'all()' --closest --hidden
216 d20a80d4def3
216 d20a80d4def3
217 d20a80d4def3
217 d20a80d4def3
218 007dc284c1f8
218 007dc284c1f8
219 82623d38b9ba
219 82623d38b9ba
220 392fd25390da
220 392fd25390da
221 82623d38b9ba
221 82623d38b9ba
222 82623d38b9ba
222 82623d38b9ba
223 392fd25390da
223 392fd25390da
224 392fd25390da
224 392fd25390da
225 $ cd ..
225 $ cd ..
226
226
227 do not take unknown node in account if they are final
227 do not take unknown node in account if they are final
228 -----------------------------------------------------
228 -----------------------------------------------------
229
229
230 $ newcase final-unknown
230 $ newcase final-unknown
231 $ hg debugobsolete `getid A_0` `getid A_1`
231 $ hg debugobsolete `getid A_0` `getid A_1`
232 obsoleted 1 changesets
232 obsoleted 1 changesets
233 $ hg debugobsolete `getid A_1` `getid A_2`
233 $ hg debugobsolete `getid A_1` `getid A_2`
234 obsoleted 1 changesets
234 obsoleted 1 changesets
235 $ hg debugobsolete `getid A_0` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
235 $ hg debugobsolete `getid A_0` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
236 $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccc
236 $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccc
237 $ hg debugobsolete `getid A_1` dddddddddddddddddddddddddddddddddddddddd
237 $ hg debugobsolete `getid A_1` dddddddddddddddddddddddddddddddddddddddd
238
238
239 $ hg debugsuccessorssets --hidden 'desc('A_0')'
239 $ hg debugsuccessorssets --hidden 'desc('A_0')'
240 007dc284c1f8
240 007dc284c1f8
241 392fd25390da
241 392fd25390da
242 $ hg debugsuccessorssets 'desc('A_0')' --closest
242 $ hg debugsuccessorssets 'desc('A_0')' --closest
243 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
243 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
244 007dc284c1f8
244 007dc284c1f8
245 82623d38b9ba
245 82623d38b9ba
246
246
247 $ cd ..
247 $ cd ..
248
248
249 divergence that converge again is not divergence anymore
249 divergence that converge again is not divergence anymore
250 -----------------------------------------------------
250 -----------------------------------------------------
251
251
252 $ newcase converged_divergence
252 $ newcase converged_divergence
253 $ hg debugobsolete `getid A_0` `getid A_1`
253 $ hg debugobsolete `getid A_0` `getid A_1`
254 obsoleted 1 changesets
254 obsoleted 1 changesets
255 $ hg debugobsolete `getid A_0` `getid A_2`
255 $ hg debugobsolete `getid A_0` `getid A_2`
256 2 new content-divergent changesets
256 2 new content-divergent changesets
257 $ mkcommit A_3
257 $ mkcommit A_3
258 created new head
258 created new head
259 $ hg debugobsolete `getid A_1` `getid A_3`
259 $ hg debugobsolete `getid A_1` `getid A_3`
260 obsoleted 1 changesets
260 obsoleted 1 changesets
261 $ hg debugobsolete `getid A_2` `getid A_3`
261 $ hg debugobsolete `getid A_2` `getid A_3`
262 obsoleted 1 changesets
262 obsoleted 1 changesets
263 $ hg log -G --hidden
263 $ hg log -G --hidden
264 @ 4:01f36c5a8fda A_3
264 @ 4:01f36c5a8fda A_3
265 |
265 |
266 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda]
266 | x 3:392fd25390da A_2 [rewritten as 4:01f36c5a8fda]
267 |/
267 |/
268 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
268 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
269 |/
269 |/
270 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
270 | x 1:007dc284c1f8 A_0 [rewritten as 2:82623d38b9ba; rewritten as 3:392fd25390da]
271 |/
271 |/
272 o 0:d20a80d4def3 base
272 o 0:d20a80d4def3 base
273
273
274 $ hg debugsuccessorssets --hidden 'all()'
274 $ hg debugsuccessorssets --hidden 'all()'
275 d20a80d4def3
275 d20a80d4def3
276 d20a80d4def3
276 d20a80d4def3
277 007dc284c1f8
277 007dc284c1f8
278 01f36c5a8fda
278 01f36c5a8fda
279 82623d38b9ba
279 82623d38b9ba
280 01f36c5a8fda
280 01f36c5a8fda
281 392fd25390da
281 392fd25390da
282 01f36c5a8fda
282 01f36c5a8fda
283 01f36c5a8fda
283 01f36c5a8fda
284 01f36c5a8fda
284 01f36c5a8fda
285 $ hg log -r 'contentdivergent()'
285 $ hg log -r 'contentdivergent()'
286 $ hg debugsuccessorssets 'all()' --closest
286 $ hg debugsuccessorssets 'all()' --closest
287 d20a80d4def3
287 d20a80d4def3
288 d20a80d4def3
288 d20a80d4def3
289 01f36c5a8fda
289 01f36c5a8fda
290 01f36c5a8fda
290 01f36c5a8fda
291 $ hg debugsuccessorssets 'all()' --closest --hidden
291 $ hg debugsuccessorssets 'all()' --closest --hidden
292 d20a80d4def3
292 d20a80d4def3
293 d20a80d4def3
293 d20a80d4def3
294 007dc284c1f8
294 007dc284c1f8
295 82623d38b9ba
295 82623d38b9ba
296 392fd25390da
296 392fd25390da
297 82623d38b9ba
297 82623d38b9ba
298 82623d38b9ba
298 82623d38b9ba
299 392fd25390da
299 392fd25390da
300 392fd25390da
300 392fd25390da
301 01f36c5a8fda
301 01f36c5a8fda
302 01f36c5a8fda
302 01f36c5a8fda
303 $ cd ..
303 $ cd ..
304
304
305 split is not divergences
305 split is not divergences
306 -----------------------------
306 -----------------------------
307
307
308 $ newcase split
308 $ newcase split
309 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
309 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
310 obsoleted 1 changesets
310 obsoleted 1 changesets
311 $ hg log -G --hidden
311 $ hg log -G --hidden
312 o 3:392fd25390da A_2
312 o 3:392fd25390da A_2
313 |
313 |
314 | o 2:82623d38b9ba A_1
314 | o 2:82623d38b9ba A_1
315 |/
315 |/
316 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
316 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
317 |/
317 |/
318 @ 0:d20a80d4def3 base
318 @ 0:d20a80d4def3 base
319
319
320 $ hg debugsuccessorssets --hidden 'all()'
320 $ hg debugsuccessorssets --hidden 'all()'
321 d20a80d4def3
321 d20a80d4def3
322 d20a80d4def3
322 d20a80d4def3
323 007dc284c1f8
323 007dc284c1f8
324 82623d38b9ba 392fd25390da
324 82623d38b9ba 392fd25390da
325 82623d38b9ba
325 82623d38b9ba
326 82623d38b9ba
326 82623d38b9ba
327 392fd25390da
327 392fd25390da
328 392fd25390da
328 392fd25390da
329 $ hg log -r 'contentdivergent()'
329 $ hg log -r 'contentdivergent()'
330 $ hg debugsuccessorssets 'all()' --closest
330 $ hg debugsuccessorssets 'all()' --closest
331 d20a80d4def3
331 d20a80d4def3
332 d20a80d4def3
332 d20a80d4def3
333 82623d38b9ba
333 82623d38b9ba
334 82623d38b9ba
334 82623d38b9ba
335 392fd25390da
335 392fd25390da
336 392fd25390da
336 392fd25390da
337 $ hg debugsuccessorssets 'all()' --closest --hidden
337 $ hg debugsuccessorssets 'all()' --closest --hidden
338 d20a80d4def3
338 d20a80d4def3
339 d20a80d4def3
339 d20a80d4def3
340 007dc284c1f8
340 007dc284c1f8
341 82623d38b9ba 392fd25390da
341 82623d38b9ba 392fd25390da
342 82623d38b9ba
342 82623d38b9ba
343 82623d38b9ba
343 82623d38b9ba
344 392fd25390da
344 392fd25390da
345 392fd25390da
345 392fd25390da
346
346
347 Even when subsequent rewriting happen
347 Even when subsequent rewriting happen
348
348
349 $ mkcommit A_3
349 $ mkcommit A_3
350 created new head
350 created new head
351 $ hg debugobsolete `getid A_1` `getid A_3`
351 $ hg debugobsolete `getid A_1` `getid A_3`
352 obsoleted 1 changesets
352 obsoleted 1 changesets
353 $ hg up 0
353 $ hg up 0
354 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
354 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
355 $ mkcommit A_4
355 $ mkcommit A_4
356 created new head
356 created new head
357 $ hg debugobsolete `getid A_2` `getid A_4`
357 $ hg debugobsolete `getid A_2` `getid A_4`
358 obsoleted 1 changesets
358 obsoleted 1 changesets
359 $ hg up 0
359 $ hg up 0
360 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
360 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
361 $ mkcommit A_5
361 $ mkcommit A_5
362 created new head
362 created new head
363 $ hg debugobsolete `getid A_4` `getid A_5`
363 $ hg debugobsolete `getid A_4` `getid A_5`
364 obsoleted 1 changesets
364 obsoleted 1 changesets
365 $ hg log -G --hidden
365 $ hg log -G --hidden
366 @ 6:e442cfc57690 A_5
366 @ 6:e442cfc57690 A_5
367 |
367 |
368 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
368 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
369 |/
369 |/
370 | o 4:01f36c5a8fda A_3
370 | o 4:01f36c5a8fda A_3
371 |/
371 |/
372 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
372 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
373 |/
373 |/
374 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
374 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
375 |/
375 |/
376 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
376 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
377 |/
377 |/
378 o 0:d20a80d4def3 base
378 o 0:d20a80d4def3 base
379
379
380 $ hg debugsuccessorssets --hidden 'all()'
380 $ hg debugsuccessorssets --hidden 'all()'
381 d20a80d4def3
381 d20a80d4def3
382 d20a80d4def3
382 d20a80d4def3
383 007dc284c1f8
383 007dc284c1f8
384 01f36c5a8fda e442cfc57690
384 01f36c5a8fda e442cfc57690
385 82623d38b9ba
385 82623d38b9ba
386 01f36c5a8fda
386 01f36c5a8fda
387 392fd25390da
387 392fd25390da
388 e442cfc57690
388 e442cfc57690
389 01f36c5a8fda
389 01f36c5a8fda
390 01f36c5a8fda
390 01f36c5a8fda
391 6a411f0d7a0a
391 6a411f0d7a0a
392 e442cfc57690
392 e442cfc57690
393 e442cfc57690
393 e442cfc57690
394 e442cfc57690
394 e442cfc57690
395 $ hg debugsuccessorssets 'all()' --closest
395 $ hg debugsuccessorssets 'all()' --closest
396 d20a80d4def3
396 d20a80d4def3
397 d20a80d4def3
397 d20a80d4def3
398 01f36c5a8fda
398 01f36c5a8fda
399 01f36c5a8fda
399 01f36c5a8fda
400 e442cfc57690
400 e442cfc57690
401 e442cfc57690
401 e442cfc57690
402 $ hg debugsuccessorssets 'all()' --closest --hidden
402 $ hg debugsuccessorssets 'all()' --closest --hidden
403 d20a80d4def3
403 d20a80d4def3
404 d20a80d4def3
404 d20a80d4def3
405 007dc284c1f8
405 007dc284c1f8
406 82623d38b9ba 392fd25390da
406 82623d38b9ba 392fd25390da
407 82623d38b9ba
407 82623d38b9ba
408 82623d38b9ba
408 82623d38b9ba
409 392fd25390da
409 392fd25390da
410 392fd25390da
410 392fd25390da
411 01f36c5a8fda
411 01f36c5a8fda
412 01f36c5a8fda
412 01f36c5a8fda
413 6a411f0d7a0a
413 6a411f0d7a0a
414 e442cfc57690
414 e442cfc57690
415 e442cfc57690
415 e442cfc57690
416 e442cfc57690
416 e442cfc57690
417 $ hg log -r 'contentdivergent()'
417 $ hg log -r 'contentdivergent()'
418
418
419 Check more complex obsolescence graft (with divergence)
419 Check more complex obsolescence graft (with divergence)
420
420
421 $ mkcommit B_0; hg up 0
421 $ mkcommit B_0; hg up 0
422 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
422 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
423 $ hg debugobsolete `getid B_0` `getid A_2`
423 $ hg debugobsolete `getid B_0` `getid A_2`
424 obsoleted 1 changesets
424 obsoleted 1 changesets
425 $ mkcommit A_7; hg up 0
425 $ mkcommit A_7; hg up 0
426 created new head
426 created new head
427 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
427 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
428 $ mkcommit A_8; hg up 0
428 $ mkcommit A_8; hg up 0
429 created new head
429 created new head
430 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
430 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
431 $ hg debugobsolete `getid A_5` `getid A_7` `getid A_8`
431 $ hg debugobsolete `getid A_5` `getid A_7` `getid A_8`
432 obsoleted 1 changesets
432 obsoleted 1 changesets
433 $ mkcommit A_9; hg up 0
433 $ mkcommit A_9; 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_9`
436 $ hg debugobsolete `getid A_5` `getid A_9`
437 4 new content-divergent changesets
437 4 new content-divergent changesets
438 $ hg log -G --hidden
438 $ hg log -G --hidden
439 * 10:bed64f5d2f5a A_9
439 * 10:bed64f5d2f5a A_9
440 |
440 |
441 | * 9:14608b260df8 A_8
441 | * 9:14608b260df8 A_8
442 |/
442 |/
443 | * 8:7ae126973a96 A_7
443 | * 8:7ae126973a96 A_7
444 |/
444 |/
445 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da]
445 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da]
446 | |
446 | |
447 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a; split as 8:7ae126973a96, 9:14608b260df8]
447 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a; split as 8:7ae126973a96, 9:14608b260df8]
448 |/
448 |/
449 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
449 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
450 |/
450 |/
451 | * 4:01f36c5a8fda A_3
451 | * 4:01f36c5a8fda A_3
452 |/
452 |/
453 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
453 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
454 |/
454 |/
455 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
455 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
456 |/
456 |/
457 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
457 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
458 |/
458 |/
459 @ 0:d20a80d4def3 base
459 @ 0:d20a80d4def3 base
460
460
461 $ hg debugsuccessorssets --hidden 'all()'
461 $ hg debugsuccessorssets --hidden 'all()'
462 d20a80d4def3
462 d20a80d4def3
463 d20a80d4def3
463 d20a80d4def3
464 007dc284c1f8
464 007dc284c1f8
465 01f36c5a8fda bed64f5d2f5a
465 01f36c5a8fda bed64f5d2f5a
466 01f36c5a8fda 7ae126973a96 14608b260df8
466 01f36c5a8fda 7ae126973a96 14608b260df8
467 82623d38b9ba
467 82623d38b9ba
468 01f36c5a8fda
468 01f36c5a8fda
469 392fd25390da
469 392fd25390da
470 bed64f5d2f5a
470 bed64f5d2f5a
471 7ae126973a96 14608b260df8
471 7ae126973a96 14608b260df8
472 01f36c5a8fda
472 01f36c5a8fda
473 01f36c5a8fda
473 01f36c5a8fda
474 6a411f0d7a0a
474 6a411f0d7a0a
475 bed64f5d2f5a
475 bed64f5d2f5a
476 7ae126973a96 14608b260df8
476 7ae126973a96 14608b260df8
477 e442cfc57690
477 e442cfc57690
478 bed64f5d2f5a
478 bed64f5d2f5a
479 7ae126973a96 14608b260df8
479 7ae126973a96 14608b260df8
480 3750ebee865d
480 3750ebee865d
481 bed64f5d2f5a
481 bed64f5d2f5a
482 7ae126973a96 14608b260df8
482 7ae126973a96 14608b260df8
483 7ae126973a96
483 7ae126973a96
484 7ae126973a96
484 7ae126973a96
485 14608b260df8
485 14608b260df8
486 14608b260df8
486 14608b260df8
487 bed64f5d2f5a
487 bed64f5d2f5a
488 bed64f5d2f5a
488 bed64f5d2f5a
489 $ hg debugsuccessorssets 'all()' --closest
489 $ hg debugsuccessorssets 'all()' --closest
490 d20a80d4def3
490 d20a80d4def3
491 d20a80d4def3
491 d20a80d4def3
492 01f36c5a8fda
492 01f36c5a8fda
493 01f36c5a8fda
493 01f36c5a8fda
494 7ae126973a96
494 7ae126973a96
495 7ae126973a96
495 7ae126973a96
496 14608b260df8
496 14608b260df8
497 14608b260df8
497 14608b260df8
498 bed64f5d2f5a
498 bed64f5d2f5a
499 bed64f5d2f5a
499 bed64f5d2f5a
500 $ hg debugsuccessorssets 'all()' --closest --hidden
500 $ hg debugsuccessorssets 'all()' --closest --hidden
501 d20a80d4def3
501 d20a80d4def3
502 d20a80d4def3
502 d20a80d4def3
503 007dc284c1f8
503 007dc284c1f8
504 82623d38b9ba 392fd25390da
504 82623d38b9ba 392fd25390da
505 82623d38b9ba
505 82623d38b9ba
506 82623d38b9ba
506 82623d38b9ba
507 392fd25390da
507 392fd25390da
508 392fd25390da
508 392fd25390da
509 01f36c5a8fda
509 01f36c5a8fda
510 01f36c5a8fda
510 01f36c5a8fda
511 6a411f0d7a0a
511 6a411f0d7a0a
512 e442cfc57690
512 e442cfc57690
513 e442cfc57690
513 e442cfc57690
514 e442cfc57690
514 e442cfc57690
515 3750ebee865d
515 3750ebee865d
516 392fd25390da
516 392fd25390da
517 7ae126973a96
517 7ae126973a96
518 7ae126973a96
518 7ae126973a96
519 14608b260df8
519 14608b260df8
520 14608b260df8
520 14608b260df8
521 bed64f5d2f5a
521 bed64f5d2f5a
522 bed64f5d2f5a
522 bed64f5d2f5a
523 $ hg log -r 'contentdivergent()'
523 $ hg log -r 'contentdivergent()'
524 4:01f36c5a8fda A_3
524 4:01f36c5a8fda A_3
525 8:7ae126973a96 A_7
525 8:7ae126973a96 A_7
526 9:14608b260df8 A_8
526 9:14608b260df8 A_8
527 10:bed64f5d2f5a A_9
527 10:bed64f5d2f5a A_9
528
528
529 fix the divergence
529 fix the divergence
530
530
531 $ mkcommit A_A; hg up 0
531 $ mkcommit A_A; hg up 0
532 created new head
532 created new head
533 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
533 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
534 $ hg debugobsolete `getid A_9` `getid A_A`
534 $ hg debugobsolete `getid A_9` `getid A_A`
535 obsoleted 1 changesets
535 obsoleted 1 changesets
536 $ hg debugobsolete `getid A_7` `getid A_A`
536 $ hg debugobsolete `getid A_7` `getid A_A`
537 obsoleted 1 changesets
537 obsoleted 1 changesets
538 $ hg debugobsolete `getid A_8` `getid A_A`
538 $ hg debugobsolete `getid A_8` `getid A_A`
539 obsoleted 1 changesets
539 obsoleted 1 changesets
540 $ hg log -G --hidden
540 $ hg log -G --hidden
541 o 11:a139f71be9da A_A
541 o 11:a139f71be9da A_A
542 |
542 |
543 | x 10:bed64f5d2f5a A_9 [rewritten as 11:a139f71be9da]
543 | x 10:bed64f5d2f5a A_9 [rewritten as 11:a139f71be9da]
544 |/
544 |/
545 | x 9:14608b260df8 A_8 [rewritten as 11:a139f71be9da]
545 | x 9:14608b260df8 A_8 [rewritten as 11:a139f71be9da]
546 |/
546 |/
547 | x 8:7ae126973a96 A_7 [rewritten as 11:a139f71be9da]
547 | x 8:7ae126973a96 A_7 [rewritten as 11:a139f71be9da]
548 |/
548 |/
549 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da]
549 | x 7:3750ebee865d B_0 [rewritten as 3:392fd25390da]
550 | |
550 | |
551 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a; split as 8:7ae126973a96, 9:14608b260df8]
551 | x 6:e442cfc57690 A_5 [rewritten as 10:bed64f5d2f5a; split as 8:7ae126973a96, 9:14608b260df8]
552 |/
552 |/
553 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
553 | x 5:6a411f0d7a0a A_4 [rewritten as 6:e442cfc57690]
554 |/
554 |/
555 | o 4:01f36c5a8fda A_3
555 | o 4:01f36c5a8fda A_3
556 |/
556 |/
557 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
557 | x 3:392fd25390da A_2 [rewritten as 5:6a411f0d7a0a]
558 |/
558 |/
559 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
559 | x 2:82623d38b9ba A_1 [rewritten as 4:01f36c5a8fda]
560 |/
560 |/
561 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
561 | x 1:007dc284c1f8 A_0 [split as 2:82623d38b9ba, 3:392fd25390da]
562 |/
562 |/
563 @ 0:d20a80d4def3 base
563 @ 0:d20a80d4def3 base
564
564
565 $ hg debugsuccessorssets --hidden 'all()'
565 $ hg debugsuccessorssets --hidden 'all()'
566 d20a80d4def3
566 d20a80d4def3
567 d20a80d4def3
567 d20a80d4def3
568 007dc284c1f8
568 007dc284c1f8
569 01f36c5a8fda a139f71be9da
569 01f36c5a8fda a139f71be9da
570 82623d38b9ba
570 82623d38b9ba
571 01f36c5a8fda
571 01f36c5a8fda
572 392fd25390da
572 392fd25390da
573 a139f71be9da
573 a139f71be9da
574 01f36c5a8fda
574 01f36c5a8fda
575 01f36c5a8fda
575 01f36c5a8fda
576 6a411f0d7a0a
576 6a411f0d7a0a
577 a139f71be9da
577 a139f71be9da
578 e442cfc57690
578 e442cfc57690
579 a139f71be9da
579 a139f71be9da
580 3750ebee865d
580 3750ebee865d
581 a139f71be9da
581 a139f71be9da
582 7ae126973a96
582 7ae126973a96
583 a139f71be9da
583 a139f71be9da
584 14608b260df8
584 14608b260df8
585 a139f71be9da
585 a139f71be9da
586 bed64f5d2f5a
586 bed64f5d2f5a
587 a139f71be9da
587 a139f71be9da
588 a139f71be9da
588 a139f71be9da
589 a139f71be9da
589 a139f71be9da
590 $ hg debugsuccessorssets 'all()' --closest
590 $ hg debugsuccessorssets 'all()' --closest
591 d20a80d4def3
591 d20a80d4def3
592 d20a80d4def3
592 d20a80d4def3
593 01f36c5a8fda
593 01f36c5a8fda
594 01f36c5a8fda
594 01f36c5a8fda
595 a139f71be9da
595 a139f71be9da
596 a139f71be9da
596 a139f71be9da
597 $ hg debugsuccessorssets 'all()' --closest --hidden
597 $ hg debugsuccessorssets 'all()' --closest --hidden
598 d20a80d4def3
598 d20a80d4def3
599 d20a80d4def3
599 d20a80d4def3
600 007dc284c1f8
600 007dc284c1f8
601 82623d38b9ba 392fd25390da
601 82623d38b9ba 392fd25390da
602 82623d38b9ba
602 82623d38b9ba
603 82623d38b9ba
603 82623d38b9ba
604 392fd25390da
604 392fd25390da
605 392fd25390da
605 392fd25390da
606 01f36c5a8fda
606 01f36c5a8fda
607 01f36c5a8fda
607 01f36c5a8fda
608 6a411f0d7a0a
608 6a411f0d7a0a
609 e442cfc57690
609 e442cfc57690
610 e442cfc57690
610 e442cfc57690
611 e442cfc57690
611 e442cfc57690
612 3750ebee865d
612 3750ebee865d
613 392fd25390da
613 392fd25390da
614 7ae126973a96
614 7ae126973a96
615 a139f71be9da
615 a139f71be9da
616 14608b260df8
616 14608b260df8
617 a139f71be9da
617 a139f71be9da
618 bed64f5d2f5a
618 bed64f5d2f5a
619 a139f71be9da
619 a139f71be9da
620 a139f71be9da
620 a139f71be9da
621 a139f71be9da
621 a139f71be9da
622 $ hg log -r 'contentdivergent()'
622 $ hg log -r 'contentdivergent()'
623
623
624 #if serve
624 #if serve
625
625
626 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid --config web.view=all \
626 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid --config web.view=all \
627 > -A access.log -E errors.log
627 > -A access.log -E errors.log
628 $ cat hg.pid >> $DAEMON_PIDS
628 $ cat hg.pid >> $DAEMON_PIDS
629
629
630 check an obsolete changeset that was rewritten and also split
630 check an obsolete changeset that was rewritten and also split
631
631
632 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=paper' | egrep 'rewritten|split'
632 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=paper' | egrep 'rewritten|split'
633 <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>
633 <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>
634 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>
634 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>
635 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=coal' | egrep 'rewritten|split'
635 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=coal' | egrep 'rewritten|split'
636 <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>
636 <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>
637 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>
637 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>
638 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=gitweb' | egrep 'rewritten|split'
638 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=gitweb' | egrep 'rewritten|split'
639 <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>
639 <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>
640 <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>
640 <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>
641 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=monoblue' | egrep 'rewritten|split'
641 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=monoblue' | egrep 'rewritten|split'
642 <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>
642 <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>
643 <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>
643 <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>
644 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=spartan' | egrep 'rewritten|split'
644 $ get-with-headers.py localhost:$HGPORT 'rev/e442cfc57690?style=spartan' | egrep 'rewritten|split'
645 <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>
645 <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>
646 <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>
646 <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>
647
647
648 $ killdaemons.py
648 $ killdaemons.py
649
649
650 #endif
650 #endif
651
651
652 $ cd ..
652 $ cd ..
653
653
654
654
655 Subset does not diverge
655 Subset does not diverge
656 ------------------------------
656 ------------------------------
657
657
658 Do not report divergent successors-set if it is a subset of another
658 Do not report divergent successors-set if it is a subset of another
659 successors-set. (report [A,B] not [A] + [A,B])
659 successors-set. (report [A,B] not [A] + [A,B])
660
660
661 $ newcase subset
661 $ newcase subset
662 $ hg debugobsolete `getid A_0` `getid A_2`
662 $ hg debugobsolete `getid A_0` `getid A_2`
663 obsoleted 1 changesets
663 obsoleted 1 changesets
664 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
664 $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
665 $ hg debugsuccessorssets --hidden 'desc('A_0')'
665 $ hg debugsuccessorssets --hidden 'desc('A_0')'
666 007dc284c1f8
666 007dc284c1f8
667 82623d38b9ba 392fd25390da
667 82623d38b9ba 392fd25390da
668 $ hg debugsuccessorssets 'desc('A_0')' --closest
668 $ hg debugsuccessorssets 'desc('A_0')' --closest
669 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
669 $ hg debugsuccessorssets 'desc('A_0')' --closest --hidden
670 007dc284c1f8
670 007dc284c1f8
671 82623d38b9ba 392fd25390da
671 82623d38b9ba 392fd25390da
672
672
673 $ cd ..
673 $ cd ..
674
674
675 Use scmutil.cleanupnodes API to create divergence
675 Use scmutil.cleanupnodes API to create divergence
676
676
677 $ hg init cleanupnodes
677 $ hg init cleanupnodes
678 $ cd cleanupnodes
678 $ cd cleanupnodes
679 $ hg debugdrawdag <<'EOS'
679 $ hg debugdrawdag <<'EOS'
680 > B1 B3 B4
680 > B1 B3 B4
681 > | \|
681 > | \|
682 > A Z
682 > A Z
683 > EOS
683 > EOS
684
684
685 $ hg update -q B1
685 $ hg update -q B1
686 $ echo 3 >> B
686 $ echo 3 >> B
687 $ hg commit --amend -m B2
687 $ hg commit --amend -m B2
688 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
688 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
689 > from mercurial import registrar, scmutil
689 > from mercurial import registrar, scmutil
690 > cmdtable = {}
690 > cmdtable = {}
691 > command = registrar.command(cmdtable)
691 > command = registrar.command(cmdtable)
692 > @command('cleanup')
692 > @command('cleanup')
693 > def cleanup(ui, repo):
693 > def cleanup(ui, repo):
694 > def node(expr):
694 > def node(expr):
695 > unfi = repo.unfiltered()
695 > unfi = repo.unfiltered()
696 > rev = unfi.revs(expr).first()
696 > rev = unfi.revs(expr).first()
697 > return unfi.changelog.node(rev)
697 > return unfi.changelog.node(rev)
698 > with repo.wlock(), repo.lock(), repo.transaction('delayedstrip'):
698 > with repo.wlock(), repo.lock(), repo.transaction('delayedstrip'):
699 > mapping = {node('desc(B1)'): [node('desc(B3)')],
699 > mapping = {node('desc(B1)'): [node('desc(B3)')],
700 > node('desc(B3)'): [node('desc(B4)')]}
700 > node('desc(B3)'): [node('desc(B4)')]}
701 > scmutil.cleanupnodes(repo, mapping, 'test')
701 > scmutil.cleanupnodes(repo, mapping, 'test')
702 > EOF
702 > EOF
703
703
704 $ rm .hg/localtags
704 $ rm .hg/localtags
705 $ hg cleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
705 $ hg cleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
706 2 new content-divergent changesets
706 2 new content-divergent changesets
707 $ hg log -G -T '{rev}:{node|short} {desc} {instabilities}' -r 'sort(all(), topo)'
707 $ hg log -G -T '{rev}:{node|short} {desc} {instabilities}' -r 'sort(all(), topo)'
708 @ 5:1a2a9b5b0030 B2 content-divergent
708 @ 5:1a2a9b5b0030 B2 content-divergent
709 |
709 |
710 | * 4:70d5a63ca112 B4 content-divergent
710 | * 4:70d5a63ca112 B4 content-divergent
711 | |
711 | |
712 | o 1:48b9aae0607f Z
712 | o 1:48b9aae0607f Z
713 |
713 |
714 o 0:426bada5c675 A
714 o 0:426bada5c675 A
715
715
716 $ hg debugobsolete
716 $ hg debugobsolete
717 a178212c3433c4e77b573f6011e29affb8aefa33 1a2a9b5b0030632400aa78e00388c20f99d3ec44 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
717 a178212c3433c4e77b573f6011e29affb8aefa33 1a2a9b5b0030632400aa78e00388c20f99d3ec44 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
718 a178212c3433c4e77b573f6011e29affb8aefa33 ad6478fb94ecec98b86daae98722865d494ac561 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'test', 'user': 'test'}
718 a178212c3433c4e77b573f6011e29affb8aefa33 ad6478fb94ecec98b86daae98722865d494ac561 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'test', 'user': 'test'}
719 ad6478fb94ecec98b86daae98722865d494ac561 70d5a63ca112acb3764bc1d7320ca90ea688d671 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'test', 'user': 'test'}
719 ad6478fb94ecec98b86daae98722865d494ac561 70d5a63ca112acb3764bc1d7320ca90ea688d671 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'test', 'user': 'test'}
720
720
721 $ hg debugwhyunstable 1a2a9b5b0030
721 $ hg debugwhyunstable 1a2a9b5b0030
722 content-divergent: 70d5a63ca112acb3764bc1d7320ca90ea688d671 (draft) predecessor a178212c3433c4e77b573f6011e29affb8aefa33
722 content-divergent: 70d5a63ca112acb3764bc1d7320ca90ea688d671 (draft) predecessor a178212c3433c4e77b573f6011e29affb8aefa33
723
723
724 $ hg log -r 1a2a9b5b0030 --hidden -T '{whyunstable}\n'
724 $ hg log -r 1a2a9b5b0030 --hidden -T '{whyunstable}\n'
725 content-divergent: 4:70d5a63ca112 (draft) predecessor a178212c3433
725 content-divergent: 4:70d5a63ca112 (draft) predecessor a178212c3433
726 $ hg log -r 1a2a9b5b0030 --hidden -T '{whyunstable%"{instability}:{divergentnodes} {reason} {node}\n"}'
726 $ hg log -r 1a2a9b5b0030 --hidden -T '{whyunstable%"{instability}:{divergentnodes} {reason} {node}\n"}'
727 content-divergent: 4:70d5a63ca112 (draft) predecessor a178212c3433c4e77b573f6011e29affb8aefa33
727 content-divergent: 4:70d5a63ca112 (draft) predecessor a178212c3433c4e77b573f6011e29affb8aefa33
728 $ hg log -r 1a2a9b5b0030 --hidden -T '{whyunstable%"{instability}:{divergentnodes % " {node} ({phase})"} {reason} {node}\n"}'
729 content-divergent: 70d5a63ca112acb3764bc1d7320ca90ea688d671 (draft) predecessor a178212c3433c4e77b573f6011e29affb8aefa33
728
730
729 #if serve
731 #if serve
730
732
731 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
733 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
732 $ cat hg.pid >> $DAEMON_PIDS
734 $ cat hg.pid >> $DAEMON_PIDS
733
735
734 check explanation for a content-divergent changeset
736 check explanation for a content-divergent changeset
735
737
736 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=paper' | grep divergent:
738 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=paper' | grep divergent:
737 <td>content-divergent: <a href="/rev/70d5a63ca112?style=paper">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=paper">a178212c3433</a></td>
739 <td>content-divergent: <a href="/rev/70d5a63ca112?style=paper">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=paper">a178212c3433</a></td>
738 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=coal' | grep divergent:
740 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=coal' | grep divergent:
739 <td>content-divergent: <a href="/rev/70d5a63ca112?style=coal">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=coal">a178212c3433</a></td>
741 <td>content-divergent: <a href="/rev/70d5a63ca112?style=coal">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=coal">a178212c3433</a></td>
740 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=gitweb' | grep divergent:
742 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=gitweb' | grep divergent:
741 <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>
743 <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>
742 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=monoblue' | grep divergent:
744 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=monoblue' | grep divergent:
743 <dd>content-divergent: <a href="/rev/70d5a63ca112?style=monoblue">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=monoblue">a178212c3433</a></dd>
745 <dd>content-divergent: <a href="/rev/70d5a63ca112?style=monoblue">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=monoblue">a178212c3433</a></dd>
744 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=spartan' | grep divergent:
746 $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=spartan' | grep divergent:
745 <td class="unstable">content-divergent: <a href="/rev/70d5a63ca112?style=spartan">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=spartan">a178212c3433</a></td>
747 <td class="unstable">content-divergent: <a href="/rev/70d5a63ca112?style=spartan">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=spartan">a178212c3433</a></td>
746
748
747 $ killdaemons.py
749 $ killdaemons.py
748
750
749 #endif
751 #endif
General Comments 0
You need to be logged in to leave comments. Login now