##// END OF EJS Templates
graphlog: use '%' only if there are *unresolved* conflicts...
Martin von Zweigbergk -
r46020:85b03b1e default
parent child Browse files
Show More
@@ -1,992 +1,992 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 wdirid,
14 wdirid,
15 wdirrev,
15 wdirrev,
16 )
16 )
17
17
18 from . import (
18 from . import (
19 diffutil,
19 diffutil,
20 encoding,
20 encoding,
21 error,
21 error,
22 hbisect,
22 hbisect,
23 i18n,
23 i18n,
24 obsutil,
24 obsutil,
25 patch,
25 patch,
26 pycompat,
26 pycompat,
27 registrar,
27 registrar,
28 scmutil,
28 scmutil,
29 templateutil,
29 templateutil,
30 util,
30 util,
31 )
31 )
32 from .utils import stringutil
32 from .utils import stringutil
33
33
34 _hybrid = templateutil.hybrid
34 _hybrid = templateutil.hybrid
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
41
42 def getlatesttags(context, mapping, pattern=None):
42 def getlatesttags(context, mapping, pattern=None):
43 '''return date, distance and name for the latest tag of rev'''
43 '''return date, distance and name for the latest tag of rev'''
44 repo = context.resource(mapping, b'repo')
44 repo = context.resource(mapping, b'repo')
45 ctx = context.resource(mapping, b'ctx')
45 ctx = context.resource(mapping, b'ctx')
46 cache = context.resource(mapping, b'cache')
46 cache = context.resource(mapping, b'cache')
47
47
48 cachename = b'latesttags'
48 cachename = b'latesttags'
49 if pattern is not None:
49 if pattern is not None:
50 cachename += b'-' + pattern
50 cachename += b'-' + pattern
51 match = stringutil.stringmatcher(pattern)[2]
51 match = stringutil.stringmatcher(pattern)[2]
52 else:
52 else:
53 match = util.always
53 match = util.always
54
54
55 if cachename not in cache:
55 if cachename not in cache:
56 # Cache mapping from rev to a tuple with tag date, tag
56 # Cache mapping from rev to a tuple with tag date, tag
57 # distance and tag name
57 # distance and tag name
58 cache[cachename] = {-1: (0, 0, [b'null'])}
58 cache[cachename] = {-1: (0, 0, [b'null'])}
59 latesttags = cache[cachename]
59 latesttags = cache[cachename]
60
60
61 rev = ctx.rev()
61 rev = ctx.rev()
62 todo = [rev]
62 todo = [rev]
63 while todo:
63 while todo:
64 rev = todo.pop()
64 rev = todo.pop()
65 if rev in latesttags:
65 if rev in latesttags:
66 continue
66 continue
67 ctx = repo[rev]
67 ctx = repo[rev]
68 tags = [
68 tags = [
69 t
69 t
70 for t in ctx.tags()
70 for t in ctx.tags()
71 if (repo.tagtype(t) and repo.tagtype(t) != b'local' and match(t))
71 if (repo.tagtype(t) and repo.tagtype(t) != b'local' and match(t))
72 ]
72 ]
73 if tags:
73 if tags:
74 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
74 latesttags[rev] = ctx.date()[0], 0, [t for t in sorted(tags)]
75 continue
75 continue
76 try:
76 try:
77 ptags = [latesttags[p.rev()] for p in ctx.parents()]
77 ptags = [latesttags[p.rev()] for p in ctx.parents()]
78 if len(ptags) > 1:
78 if len(ptags) > 1:
79 if ptags[0][2] == ptags[1][2]:
79 if ptags[0][2] == ptags[1][2]:
80 # The tuples are laid out so the right one can be found by
80 # The tuples are laid out so the right one can be found by
81 # comparison in this case.
81 # comparison in this case.
82 pdate, pdist, ptag = max(ptags)
82 pdate, pdist, ptag = max(ptags)
83 else:
83 else:
84
84
85 def key(x):
85 def key(x):
86 tag = x[2][0]
86 tag = x[2][0]
87 if ctx.rev() is None:
87 if ctx.rev() is None:
88 # only() doesn't support wdir
88 # only() doesn't support wdir
89 prevs = [c.rev() for c in ctx.parents()]
89 prevs = [c.rev() for c in ctx.parents()]
90 changes = repo.revs(b'only(%ld, %s)', prevs, tag)
90 changes = repo.revs(b'only(%ld, %s)', prevs, tag)
91 changessincetag = len(changes) + 1
91 changessincetag = len(changes) + 1
92 else:
92 else:
93 changes = repo.revs(b'only(%d, %s)', ctx.rev(), tag)
93 changes = repo.revs(b'only(%d, %s)', ctx.rev(), tag)
94 changessincetag = len(changes)
94 changessincetag = len(changes)
95 # Smallest number of changes since tag wins. Date is
95 # Smallest number of changes since tag wins. Date is
96 # used as tiebreaker.
96 # used as tiebreaker.
97 return [-changessincetag, x[0]]
97 return [-changessincetag, x[0]]
98
98
99 pdate, pdist, ptag = max(ptags, key=key)
99 pdate, pdist, ptag = max(ptags, key=key)
100 else:
100 else:
101 pdate, pdist, ptag = ptags[0]
101 pdate, pdist, ptag = ptags[0]
102 except KeyError:
102 except KeyError:
103 # Cache miss - recurse
103 # Cache miss - recurse
104 todo.append(rev)
104 todo.append(rev)
105 todo.extend(p.rev() for p in ctx.parents())
105 todo.extend(p.rev() for p in ctx.parents())
106 continue
106 continue
107 latesttags[rev] = pdate, pdist + 1, ptag
107 latesttags[rev] = pdate, pdist + 1, ptag
108 return latesttags[rev]
108 return latesttags[rev]
109
109
110
110
111 def getlogcolumns():
111 def getlogcolumns():
112 """Return a dict of log column labels"""
112 """Return a dict of log column labels"""
113 _ = pycompat.identity # temporarily disable gettext
113 _ = pycompat.identity # temporarily disable gettext
114 # i18n: column positioning for "hg log"
114 # i18n: column positioning for "hg log"
115 columns = _(
115 columns = _(
116 b'bookmark: %s\n'
116 b'bookmark: %s\n'
117 b'branch: %s\n'
117 b'branch: %s\n'
118 b'changeset: %s\n'
118 b'changeset: %s\n'
119 b'copies: %s\n'
119 b'copies: %s\n'
120 b'date: %s\n'
120 b'date: %s\n'
121 b'extra: %s=%s\n'
121 b'extra: %s=%s\n'
122 b'files+: %s\n'
122 b'files+: %s\n'
123 b'files-: %s\n'
123 b'files-: %s\n'
124 b'files: %s\n'
124 b'files: %s\n'
125 b'instability: %s\n'
125 b'instability: %s\n'
126 b'manifest: %s\n'
126 b'manifest: %s\n'
127 b'obsolete: %s\n'
127 b'obsolete: %s\n'
128 b'parent: %s\n'
128 b'parent: %s\n'
129 b'phase: %s\n'
129 b'phase: %s\n'
130 b'summary: %s\n'
130 b'summary: %s\n'
131 b'tag: %s\n'
131 b'tag: %s\n'
132 b'user: %s\n'
132 b'user: %s\n'
133 )
133 )
134 return dict(
134 return dict(
135 zip(
135 zip(
136 [s.split(b':', 1)[0] for s in columns.splitlines()],
136 [s.split(b':', 1)[0] for s in columns.splitlines()],
137 i18n._(columns).splitlines(True),
137 i18n._(columns).splitlines(True),
138 )
138 )
139 )
139 )
140
140
141
141
142 # basic internal templates
142 # basic internal templates
143 _changeidtmpl = b'{rev}:{node|formatnode}'
143 _changeidtmpl = b'{rev}:{node|formatnode}'
144
144
145 # default templates internally used for rendering of lists
145 # default templates internally used for rendering of lists
146 defaulttempl = {
146 defaulttempl = {
147 b'parent': _changeidtmpl + b' ',
147 b'parent': _changeidtmpl + b' ',
148 b'manifest': _changeidtmpl,
148 b'manifest': _changeidtmpl,
149 b'file_copy': b'{name} ({source})',
149 b'file_copy': b'{name} ({source})',
150 b'envvar': b'{key}={value}',
150 b'envvar': b'{key}={value}',
151 b'extra': b'{key}={value|stringescape}',
151 b'extra': b'{key}={value|stringescape}',
152 }
152 }
153 # filecopy is preserved for compatibility reasons
153 # filecopy is preserved for compatibility reasons
154 defaulttempl[b'filecopy'] = defaulttempl[b'file_copy']
154 defaulttempl[b'filecopy'] = defaulttempl[b'file_copy']
155
155
156 # keywords are callables (see registrar.templatekeyword for details)
156 # keywords are callables (see registrar.templatekeyword for details)
157 keywords = {}
157 keywords = {}
158 templatekeyword = registrar.templatekeyword(keywords)
158 templatekeyword = registrar.templatekeyword(keywords)
159
159
160
160
161 @templatekeyword(b'author', requires={b'ctx'})
161 @templatekeyword(b'author', requires={b'ctx'})
162 def showauthor(context, mapping):
162 def showauthor(context, mapping):
163 """Alias for ``{user}``"""
163 """Alias for ``{user}``"""
164 return showuser(context, mapping)
164 return showuser(context, mapping)
165
165
166
166
167 @templatekeyword(b'bisect', requires={b'repo', b'ctx'})
167 @templatekeyword(b'bisect', requires={b'repo', b'ctx'})
168 def showbisect(context, mapping):
168 def showbisect(context, mapping):
169 """String. The changeset bisection status."""
169 """String. The changeset bisection status."""
170 repo = context.resource(mapping, b'repo')
170 repo = context.resource(mapping, b'repo')
171 ctx = context.resource(mapping, b'ctx')
171 ctx = context.resource(mapping, b'ctx')
172 return hbisect.label(repo, ctx.node())
172 return hbisect.label(repo, ctx.node())
173
173
174
174
175 @templatekeyword(b'branch', requires={b'ctx'})
175 @templatekeyword(b'branch', requires={b'ctx'})
176 def showbranch(context, mapping):
176 def showbranch(context, mapping):
177 """String. The name of the branch on which the changeset was
177 """String. The name of the branch on which the changeset was
178 committed.
178 committed.
179 """
179 """
180 ctx = context.resource(mapping, b'ctx')
180 ctx = context.resource(mapping, b'ctx')
181 return ctx.branch()
181 return ctx.branch()
182
182
183
183
184 @templatekeyword(b'branches', requires={b'ctx'})
184 @templatekeyword(b'branches', requires={b'ctx'})
185 def showbranches(context, mapping):
185 def showbranches(context, mapping):
186 """List of strings. The name of the branch on which the
186 """List of strings. The name of the branch on which the
187 changeset was committed. Will be empty if the branch name was
187 changeset was committed. Will be empty if the branch name was
188 default. (DEPRECATED)
188 default. (DEPRECATED)
189 """
189 """
190 ctx = context.resource(mapping, b'ctx')
190 ctx = context.resource(mapping, b'ctx')
191 branch = ctx.branch()
191 branch = ctx.branch()
192 if branch != b'default':
192 if branch != b'default':
193 return compatlist(
193 return compatlist(
194 context, mapping, b'branch', [branch], plural=b'branches'
194 context, mapping, b'branch', [branch], plural=b'branches'
195 )
195 )
196 return compatlist(context, mapping, b'branch', [], plural=b'branches')
196 return compatlist(context, mapping, b'branch', [], plural=b'branches')
197
197
198
198
199 @templatekeyword(b'bookmarks', requires={b'repo', b'ctx'})
199 @templatekeyword(b'bookmarks', requires={b'repo', b'ctx'})
200 def showbookmarks(context, mapping):
200 def showbookmarks(context, mapping):
201 """List of strings. Any bookmarks associated with the
201 """List of strings. Any bookmarks associated with the
202 changeset. Also sets 'active', the name of the active bookmark.
202 changeset. Also sets 'active', the name of the active bookmark.
203 """
203 """
204 repo = context.resource(mapping, b'repo')
204 repo = context.resource(mapping, b'repo')
205 ctx = context.resource(mapping, b'ctx')
205 ctx = context.resource(mapping, b'ctx')
206 bookmarks = ctx.bookmarks()
206 bookmarks = ctx.bookmarks()
207 active = repo._activebookmark
207 active = repo._activebookmark
208 makemap = lambda v: {b'bookmark': v, b'active': active, b'current': active}
208 makemap = lambda v: {b'bookmark': v, b'active': active, b'current': active}
209 f = _showcompatlist(context, mapping, b'bookmark', bookmarks)
209 f = _showcompatlist(context, mapping, b'bookmark', bookmarks)
210 return _hybrid(f, bookmarks, makemap, pycompat.identity)
210 return _hybrid(f, bookmarks, makemap, pycompat.identity)
211
211
212
212
213 @templatekeyword(b'children', requires={b'ctx'})
213 @templatekeyword(b'children', requires={b'ctx'})
214 def showchildren(context, mapping):
214 def showchildren(context, mapping):
215 """List of strings. The children of the changeset."""
215 """List of strings. The children of the changeset."""
216 ctx = context.resource(mapping, b'ctx')
216 ctx = context.resource(mapping, b'ctx')
217 childrevs = [b'%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()]
217 childrevs = [b'%d:%s' % (cctx.rev(), cctx) for cctx in ctx.children()]
218 return compatlist(
218 return compatlist(
219 context, mapping, b'children', childrevs, element=b'child'
219 context, mapping, b'children', childrevs, element=b'child'
220 )
220 )
221
221
222
222
223 # Deprecated, but kept alive for help generation a purpose.
223 # Deprecated, but kept alive for help generation a purpose.
224 @templatekeyword(b'currentbookmark', requires={b'repo', b'ctx'})
224 @templatekeyword(b'currentbookmark', requires={b'repo', b'ctx'})
225 def showcurrentbookmark(context, mapping):
225 def showcurrentbookmark(context, mapping):
226 """String. The active bookmark, if it is associated with the changeset.
226 """String. The active bookmark, if it is associated with the changeset.
227 (DEPRECATED)"""
227 (DEPRECATED)"""
228 return showactivebookmark(context, mapping)
228 return showactivebookmark(context, mapping)
229
229
230
230
231 @templatekeyword(b'activebookmark', requires={b'repo', b'ctx'})
231 @templatekeyword(b'activebookmark', requires={b'repo', b'ctx'})
232 def showactivebookmark(context, mapping):
232 def showactivebookmark(context, mapping):
233 """String. The active bookmark, if it is associated with the changeset."""
233 """String. The active bookmark, if it is associated with the changeset."""
234 repo = context.resource(mapping, b'repo')
234 repo = context.resource(mapping, b'repo')
235 ctx = context.resource(mapping, b'ctx')
235 ctx = context.resource(mapping, b'ctx')
236 active = repo._activebookmark
236 active = repo._activebookmark
237 if active and active in ctx.bookmarks():
237 if active and active in ctx.bookmarks():
238 return active
238 return active
239 return b''
239 return b''
240
240
241
241
242 @templatekeyword(b'date', requires={b'ctx'})
242 @templatekeyword(b'date', requires={b'ctx'})
243 def showdate(context, mapping):
243 def showdate(context, mapping):
244 """Date information. The date when the changeset was committed."""
244 """Date information. The date when the changeset was committed."""
245 ctx = context.resource(mapping, b'ctx')
245 ctx = context.resource(mapping, b'ctx')
246 # the default string format is '<float(unixtime)><tzoffset>' because
246 # the default string format is '<float(unixtime)><tzoffset>' because
247 # python-hglib splits date at decimal separator.
247 # python-hglib splits date at decimal separator.
248 return templateutil.date(ctx.date(), showfmt=b'%d.0%d')
248 return templateutil.date(ctx.date(), showfmt=b'%d.0%d')
249
249
250
250
251 @templatekeyword(b'desc', requires={b'ctx'})
251 @templatekeyword(b'desc', requires={b'ctx'})
252 def showdescription(context, mapping):
252 def showdescription(context, mapping):
253 """String. The text of the changeset description."""
253 """String. The text of the changeset description."""
254 ctx = context.resource(mapping, b'ctx')
254 ctx = context.resource(mapping, b'ctx')
255 s = ctx.description()
255 s = ctx.description()
256 if isinstance(s, encoding.localstr):
256 if isinstance(s, encoding.localstr):
257 # try hard to preserve utf-8 bytes
257 # try hard to preserve utf-8 bytes
258 return encoding.tolocal(encoding.fromlocal(s).strip())
258 return encoding.tolocal(encoding.fromlocal(s).strip())
259 elif isinstance(s, encoding.safelocalstr):
259 elif isinstance(s, encoding.safelocalstr):
260 return encoding.safelocalstr(s.strip())
260 return encoding.safelocalstr(s.strip())
261 else:
261 else:
262 return s.strip()
262 return s.strip()
263
263
264
264
265 @templatekeyword(b'diffstat', requires={b'ui', b'ctx'})
265 @templatekeyword(b'diffstat', requires={b'ui', b'ctx'})
266 def showdiffstat(context, mapping):
266 def showdiffstat(context, mapping):
267 """String. Statistics of changes with the following format:
267 """String. Statistics of changes with the following format:
268 "modified files: +added/-removed lines"
268 "modified files: +added/-removed lines"
269 """
269 """
270 ui = context.resource(mapping, b'ui')
270 ui = context.resource(mapping, b'ui')
271 ctx = context.resource(mapping, b'ctx')
271 ctx = context.resource(mapping, b'ctx')
272 diffopts = diffutil.diffallopts(ui, {b'noprefix': False})
272 diffopts = diffutil.diffallopts(ui, {b'noprefix': False})
273 diff = ctx.diff(opts=diffopts)
273 diff = ctx.diff(opts=diffopts)
274 stats = patch.diffstatdata(util.iterlines(diff))
274 stats = patch.diffstatdata(util.iterlines(diff))
275 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
275 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
276 return b'%d: +%d/-%d' % (len(stats), adds, removes)
276 return b'%d: +%d/-%d' % (len(stats), adds, removes)
277
277
278
278
279 @templatekeyword(b'envvars', requires={b'ui'})
279 @templatekeyword(b'envvars', requires={b'ui'})
280 def showenvvars(context, mapping):
280 def showenvvars(context, mapping):
281 """A dictionary of environment variables. (EXPERIMENTAL)"""
281 """A dictionary of environment variables. (EXPERIMENTAL)"""
282 ui = context.resource(mapping, b'ui')
282 ui = context.resource(mapping, b'ui')
283 env = ui.exportableenviron()
283 env = ui.exportableenviron()
284 env = util.sortdict((k, env[k]) for k in sorted(env))
284 env = util.sortdict((k, env[k]) for k in sorted(env))
285 return compatdict(context, mapping, b'envvar', env, plural=b'envvars')
285 return compatdict(context, mapping, b'envvar', env, plural=b'envvars')
286
286
287
287
288 @templatekeyword(b'extras', requires={b'ctx'})
288 @templatekeyword(b'extras', requires={b'ctx'})
289 def showextras(context, mapping):
289 def showextras(context, mapping):
290 """List of dicts with key, value entries of the 'extras'
290 """List of dicts with key, value entries of the 'extras'
291 field of this changeset."""
291 field of this changeset."""
292 ctx = context.resource(mapping, b'ctx')
292 ctx = context.resource(mapping, b'ctx')
293 extras = ctx.extra()
293 extras = ctx.extra()
294 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
294 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
295 makemap = lambda k: {b'key': k, b'value': extras[k]}
295 makemap = lambda k: {b'key': k, b'value': extras[k]}
296 c = [makemap(k) for k in extras]
296 c = [makemap(k) for k in extras]
297 f = _showcompatlist(context, mapping, b'extra', c, plural=b'extras')
297 f = _showcompatlist(context, mapping, b'extra', c, plural=b'extras')
298 return _hybrid(
298 return _hybrid(
299 f,
299 f,
300 extras,
300 extras,
301 makemap,
301 makemap,
302 lambda k: b'%s=%s' % (k, stringutil.escapestr(extras[k])),
302 lambda k: b'%s=%s' % (k, stringutil.escapestr(extras[k])),
303 )
303 )
304
304
305
305
306 def _getfilestatus(context, mapping, listall=False):
306 def _getfilestatus(context, mapping, listall=False):
307 ctx = context.resource(mapping, b'ctx')
307 ctx = context.resource(mapping, b'ctx')
308 revcache = context.resource(mapping, b'revcache')
308 revcache = context.resource(mapping, b'revcache')
309 if b'filestatus' not in revcache or revcache[b'filestatusall'] < listall:
309 if b'filestatus' not in revcache or revcache[b'filestatusall'] < listall:
310 stat = ctx.p1().status(
310 stat = ctx.p1().status(
311 ctx, listignored=listall, listclean=listall, listunknown=listall
311 ctx, listignored=listall, listclean=listall, listunknown=listall
312 )
312 )
313 revcache[b'filestatus'] = stat
313 revcache[b'filestatus'] = stat
314 revcache[b'filestatusall'] = listall
314 revcache[b'filestatusall'] = listall
315 return revcache[b'filestatus']
315 return revcache[b'filestatus']
316
316
317
317
318 def _getfilestatusmap(context, mapping, listall=False):
318 def _getfilestatusmap(context, mapping, listall=False):
319 revcache = context.resource(mapping, b'revcache')
319 revcache = context.resource(mapping, b'revcache')
320 if b'filestatusmap' not in revcache or revcache[b'filestatusall'] < listall:
320 if b'filestatusmap' not in revcache or revcache[b'filestatusall'] < listall:
321 stat = _getfilestatus(context, mapping, listall=listall)
321 stat = _getfilestatus(context, mapping, listall=listall)
322 revcache[b'filestatusmap'] = statmap = {}
322 revcache[b'filestatusmap'] = statmap = {}
323 for char, files in zip(pycompat.iterbytestr(b'MAR!?IC'), stat):
323 for char, files in zip(pycompat.iterbytestr(b'MAR!?IC'), stat):
324 statmap.update((f, char) for f in files)
324 statmap.update((f, char) for f in files)
325 return revcache[b'filestatusmap'] # {path: statchar}
325 return revcache[b'filestatusmap'] # {path: statchar}
326
326
327
327
328 @templatekeyword(
328 @templatekeyword(
329 b'file_copies', requires={b'repo', b'ctx', b'cache', b'revcache'}
329 b'file_copies', requires={b'repo', b'ctx', b'cache', b'revcache'}
330 )
330 )
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, b'repo')
335 repo = context.resource(mapping, b'repo')
336 ctx = context.resource(mapping, b'ctx')
336 ctx = context.resource(mapping, b'ctx')
337 cache = context.resource(mapping, b'cache')
337 cache = context.resource(mapping, b'cache')
338 copies = context.resource(mapping, b'revcache').get(b'copies')
338 copies = context.resource(mapping, b'revcache').get(b'copies')
339 if copies is None:
339 if copies is None:
340 if b'getcopies' not in cache:
340 if b'getcopies' not in cache:
341 cache[b'getcopies'] = scmutil.getcopiesfn(repo)
341 cache[b'getcopies'] = scmutil.getcopiesfn(repo)
342 getcopies = cache[b'getcopies']
342 getcopies = cache[b'getcopies']
343 copies = getcopies(ctx)
343 copies = getcopies(ctx)
344 return templateutil.compatfilecopiesdict(
344 return templateutil.compatfilecopiesdict(
345 context, mapping, b'file_copy', copies
345 context, mapping, b'file_copy', copies
346 )
346 )
347
347
348
348
349 # showfilecopiesswitch() displays file copies only if copy records are
349 # showfilecopiesswitch() displays file copies only if copy records are
350 # provided before calling the templater, usually with a --copies
350 # provided before calling the templater, usually with a --copies
351 # command line switch.
351 # command line switch.
352 @templatekeyword(b'file_copies_switch', requires={b'revcache'})
352 @templatekeyword(b'file_copies_switch', requires={b'revcache'})
353 def showfilecopiesswitch(context, mapping):
353 def showfilecopiesswitch(context, mapping):
354 """List of strings. Like "file_copies" but displayed
354 """List of strings. Like "file_copies" but displayed
355 only if the --copied switch is set.
355 only if the --copied switch is set.
356 """
356 """
357 copies = context.resource(mapping, b'revcache').get(b'copies') or []
357 copies = context.resource(mapping, b'revcache').get(b'copies') or []
358 return templateutil.compatfilecopiesdict(
358 return templateutil.compatfilecopiesdict(
359 context, mapping, b'file_copy', copies
359 context, mapping, b'file_copy', copies
360 )
360 )
361
361
362
362
363 @templatekeyword(b'file_adds', requires={b'ctx', b'revcache'})
363 @templatekeyword(b'file_adds', requires={b'ctx', b'revcache'})
364 def showfileadds(context, mapping):
364 def showfileadds(context, mapping):
365 """List of strings. Files added by this changeset."""
365 """List of strings. Files added by this changeset."""
366 ctx = context.resource(mapping, b'ctx')
366 ctx = context.resource(mapping, b'ctx')
367 return templateutil.compatfileslist(
367 return templateutil.compatfileslist(
368 context, mapping, b'file_add', ctx.filesadded()
368 context, mapping, b'file_add', ctx.filesadded()
369 )
369 )
370
370
371
371
372 @templatekeyword(b'file_dels', requires={b'ctx', b'revcache'})
372 @templatekeyword(b'file_dels', requires={b'ctx', b'revcache'})
373 def showfiledels(context, mapping):
373 def showfiledels(context, mapping):
374 """List of strings. Files removed by this changeset."""
374 """List of strings. Files removed by this changeset."""
375 ctx = context.resource(mapping, b'ctx')
375 ctx = context.resource(mapping, b'ctx')
376 return templateutil.compatfileslist(
376 return templateutil.compatfileslist(
377 context, mapping, b'file_del', ctx.filesremoved()
377 context, mapping, b'file_del', ctx.filesremoved()
378 )
378 )
379
379
380
380
381 @templatekeyword(b'file_mods', requires={b'ctx', b'revcache'})
381 @templatekeyword(b'file_mods', requires={b'ctx', b'revcache'})
382 def showfilemods(context, mapping):
382 def showfilemods(context, mapping):
383 """List of strings. Files modified by this changeset."""
383 """List of strings. Files modified by this changeset."""
384 ctx = context.resource(mapping, b'ctx')
384 ctx = context.resource(mapping, b'ctx')
385 return templateutil.compatfileslist(
385 return templateutil.compatfileslist(
386 context, mapping, b'file_mod', ctx.filesmodified()
386 context, mapping, b'file_mod', ctx.filesmodified()
387 )
387 )
388
388
389
389
390 @templatekeyword(b'files', requires={b'ctx'})
390 @templatekeyword(b'files', requires={b'ctx'})
391 def showfiles(context, mapping):
391 def showfiles(context, mapping):
392 """List of strings. All files modified, added, or removed by this
392 """List of strings. All files modified, added, or removed by this
393 changeset.
393 changeset.
394 """
394 """
395 ctx = context.resource(mapping, b'ctx')
395 ctx = context.resource(mapping, b'ctx')
396 return templateutil.compatfileslist(context, mapping, b'file', ctx.files())
396 return templateutil.compatfileslist(context, mapping, b'file', ctx.files())
397
397
398
398
399 @templatekeyword(b'graphnode', requires={b'repo', b'ctx', b'cache'})
399 @templatekeyword(b'graphnode', requires={b'repo', b'ctx', b'cache'})
400 def showgraphnode(context, mapping):
400 def showgraphnode(context, mapping):
401 """String. The character representing the changeset node in an ASCII
401 """String. The character representing the changeset node in an ASCII
402 revision graph."""
402 revision graph."""
403 repo = context.resource(mapping, b'repo')
403 repo = context.resource(mapping, b'repo')
404 ctx = context.resource(mapping, b'ctx')
404 ctx = context.resource(mapping, b'ctx')
405 cache = context.resource(mapping, b'cache')
405 cache = context.resource(mapping, b'cache')
406 return getgraphnode(repo, ctx, cache)
406 return getgraphnode(repo, ctx, cache)
407
407
408
408
409 def getgraphnode(repo, ctx, cache):
409 def getgraphnode(repo, ctx, cache):
410 return getgraphnodecurrent(repo, ctx, cache) or getgraphnodesymbol(ctx)
410 return getgraphnodecurrent(repo, ctx, cache) or getgraphnodesymbol(ctx)
411
411
412
412
413 def getgraphnodecurrent(repo, ctx, cache):
413 def getgraphnodecurrent(repo, ctx, cache):
414 wpnodes = repo.dirstate.parents()
414 wpnodes = repo.dirstate.parents()
415 if wpnodes[1] == nullid:
415 if wpnodes[1] == nullid:
416 wpnodes = wpnodes[:1]
416 wpnodes = wpnodes[:1]
417 if ctx.node() in wpnodes:
417 if ctx.node() in wpnodes:
418 return b'@'
418 return b'@'
419 else:
419 else:
420 merge_nodes = cache.get(b'merge_nodes')
420 merge_nodes = cache.get(b'merge_nodes')
421 if merge_nodes is None:
421 if merge_nodes is None:
422 from . import mergestate as mergestatemod
422 from . import mergestate as mergestatemod
423
423
424 mergestate = mergestatemod.mergestate.read(repo)
424 mergestate = mergestatemod.mergestate.read(repo)
425 if mergestate.active():
425 if mergestate.unresolvedcount():
426 merge_nodes = (mergestate.local, mergestate.other)
426 merge_nodes = (mergestate.local, mergestate.other)
427 else:
427 else:
428 merge_nodes = ()
428 merge_nodes = ()
429 cache[b'merge_nodes'] = merge_nodes
429 cache[b'merge_nodes'] = merge_nodes
430
430
431 if ctx.node() in merge_nodes:
431 if ctx.node() in merge_nodes:
432 return b'%'
432 return b'%'
433 return b''
433 return b''
434
434
435
435
436 def getgraphnodesymbol(ctx):
436 def getgraphnodesymbol(ctx):
437 if ctx.obsolete():
437 if ctx.obsolete():
438 return b'x'
438 return b'x'
439 elif ctx.isunstable():
439 elif ctx.isunstable():
440 return b'*'
440 return b'*'
441 elif ctx.closesbranch():
441 elif ctx.closesbranch():
442 return b'_'
442 return b'_'
443 else:
443 else:
444 return b'o'
444 return b'o'
445
445
446
446
447 @templatekeyword(b'graphwidth', requires=())
447 @templatekeyword(b'graphwidth', requires=())
448 def showgraphwidth(context, mapping):
448 def showgraphwidth(context, mapping):
449 """Integer. The width of the graph drawn by 'log --graph' or zero."""
449 """Integer. The width of the graph drawn by 'log --graph' or zero."""
450 # just hosts documentation; should be overridden by template mapping
450 # just hosts documentation; should be overridden by template mapping
451 return 0
451 return 0
452
452
453
453
454 @templatekeyword(b'index', requires=())
454 @templatekeyword(b'index', requires=())
455 def showindex(context, mapping):
455 def showindex(context, mapping):
456 """Integer. The current iteration of the loop. (0 indexed)"""
456 """Integer. The current iteration of the loop. (0 indexed)"""
457 # just hosts documentation; should be overridden by template mapping
457 # just hosts documentation; should be overridden by template mapping
458 raise error.Abort(_(b"can't use index in this context"))
458 raise error.Abort(_(b"can't use index in this context"))
459
459
460
460
461 @templatekeyword(b'latesttag', requires={b'repo', b'ctx', b'cache'})
461 @templatekeyword(b'latesttag', requires={b'repo', b'ctx', b'cache'})
462 def showlatesttag(context, mapping):
462 def showlatesttag(context, mapping):
463 """List of strings. The global tags on the most recent globally
463 """List of strings. The global tags on the most recent globally
464 tagged ancestor of this changeset. If no such tags exist, the list
464 tagged ancestor of this changeset. If no such tags exist, the list
465 consists of the single string "null".
465 consists of the single string "null".
466 """
466 """
467 return showlatesttags(context, mapping, None)
467 return showlatesttags(context, mapping, None)
468
468
469
469
470 def showlatesttags(context, mapping, pattern):
470 def showlatesttags(context, mapping, pattern):
471 """helper method for the latesttag keyword and function"""
471 """helper method for the latesttag keyword and function"""
472 latesttags = getlatesttags(context, mapping, pattern)
472 latesttags = getlatesttags(context, mapping, pattern)
473
473
474 # latesttag[0] is an implementation detail for sorting csets on different
474 # latesttag[0] is an implementation detail for sorting csets on different
475 # branches in a stable manner- it is the date the tagged cset was created,
475 # branches in a stable manner- it is the date the tagged cset was created,
476 # not the date the tag was created. Therefore it isn't made visible here.
476 # not the date the tag was created. Therefore it isn't made visible here.
477 makemap = lambda v: {
477 makemap = lambda v: {
478 b'changes': _showchangessincetag,
478 b'changes': _showchangessincetag,
479 b'distance': latesttags[1],
479 b'distance': latesttags[1],
480 b'latesttag': v, # BC with {latesttag % '{latesttag}'}
480 b'latesttag': v, # BC with {latesttag % '{latesttag}'}
481 b'tag': v,
481 b'tag': v,
482 }
482 }
483
483
484 tags = latesttags[2]
484 tags = latesttags[2]
485 f = _showcompatlist(context, mapping, b'latesttag', tags, separator=b':')
485 f = _showcompatlist(context, mapping, b'latesttag', tags, separator=b':')
486 return _hybrid(f, tags, makemap, pycompat.identity)
486 return _hybrid(f, tags, makemap, pycompat.identity)
487
487
488
488
489 @templatekeyword(b'latesttagdistance', requires={b'repo', b'ctx', b'cache'})
489 @templatekeyword(b'latesttagdistance', requires={b'repo', b'ctx', b'cache'})
490 def showlatesttagdistance(context, mapping):
490 def showlatesttagdistance(context, mapping):
491 """Integer. Longest path to the latest tag."""
491 """Integer. Longest path to the latest tag."""
492 return getlatesttags(context, mapping)[1]
492 return getlatesttags(context, mapping)[1]
493
493
494
494
495 @templatekeyword(b'changessincelatesttag', requires={b'repo', b'ctx', b'cache'})
495 @templatekeyword(b'changessincelatesttag', requires={b'repo', b'ctx', b'cache'})
496 def showchangessincelatesttag(context, mapping):
496 def showchangessincelatesttag(context, mapping):
497 """Integer. All ancestors not in the latest tag."""
497 """Integer. All ancestors not in the latest tag."""
498 tag = getlatesttags(context, mapping)[2][0]
498 tag = getlatesttags(context, mapping)[2][0]
499 mapping = context.overlaymap(mapping, {b'tag': tag})
499 mapping = context.overlaymap(mapping, {b'tag': tag})
500 return _showchangessincetag(context, mapping)
500 return _showchangessincetag(context, mapping)
501
501
502
502
503 def _showchangessincetag(context, mapping):
503 def _showchangessincetag(context, mapping):
504 repo = context.resource(mapping, b'repo')
504 repo = context.resource(mapping, b'repo')
505 ctx = context.resource(mapping, b'ctx')
505 ctx = context.resource(mapping, b'ctx')
506 offset = 0
506 offset = 0
507 revs = [ctx.rev()]
507 revs = [ctx.rev()]
508 tag = context.symbol(mapping, b'tag')
508 tag = context.symbol(mapping, b'tag')
509
509
510 # The only() revset doesn't currently support wdir()
510 # The only() revset doesn't currently support wdir()
511 if ctx.rev() is None:
511 if ctx.rev() is None:
512 offset = 1
512 offset = 1
513 revs = [p.rev() for p in ctx.parents()]
513 revs = [p.rev() for p in ctx.parents()]
514
514
515 return len(repo.revs(b'only(%ld, %s)', revs, tag)) + offset
515 return len(repo.revs(b'only(%ld, %s)', revs, tag)) + offset
516
516
517
517
518 # teach templater latesttags.changes is switched to (context, mapping) API
518 # teach templater latesttags.changes is switched to (context, mapping) API
519 _showchangessincetag._requires = {b'repo', b'ctx'}
519 _showchangessincetag._requires = {b'repo', b'ctx'}
520
520
521
521
522 @templatekeyword(b'manifest', requires={b'repo', b'ctx'})
522 @templatekeyword(b'manifest', requires={b'repo', b'ctx'})
523 def showmanifest(context, mapping):
523 def showmanifest(context, mapping):
524 repo = context.resource(mapping, b'repo')
524 repo = context.resource(mapping, b'repo')
525 ctx = context.resource(mapping, b'ctx')
525 ctx = context.resource(mapping, b'ctx')
526 mnode = ctx.manifestnode()
526 mnode = ctx.manifestnode()
527 if mnode is None:
527 if mnode is None:
528 mnode = wdirid
528 mnode = wdirid
529 mrev = wdirrev
529 mrev = wdirrev
530 else:
530 else:
531 mrev = repo.manifestlog.rev(mnode)
531 mrev = repo.manifestlog.rev(mnode)
532 mhex = hex(mnode)
532 mhex = hex(mnode)
533 mapping = context.overlaymap(mapping, {b'rev': mrev, b'node': mhex})
533 mapping = context.overlaymap(mapping, {b'rev': mrev, b'node': mhex})
534 f = context.process(b'manifest', mapping)
534 f = context.process(b'manifest', mapping)
535 return templateutil.hybriditem(
535 return templateutil.hybriditem(
536 f, None, f, lambda x: {b'rev': mrev, b'node': mhex}
536 f, None, f, lambda x: {b'rev': mrev, b'node': mhex}
537 )
537 )
538
538
539
539
540 @templatekeyword(b'obsfate', requires={b'ui', b'repo', b'ctx'})
540 @templatekeyword(b'obsfate', requires={b'ui', b'repo', b'ctx'})
541 def showobsfate(context, mapping):
541 def showobsfate(context, mapping):
542 # this function returns a list containing pre-formatted obsfate strings.
542 # this function returns a list containing pre-formatted obsfate strings.
543 #
543 #
544 # This function will be replaced by templates fragments when we will have
544 # This function will be replaced by templates fragments when we will have
545 # the verbosity templatekw available.
545 # the verbosity templatekw available.
546 succsandmarkers = showsuccsandmarkers(context, mapping)
546 succsandmarkers = showsuccsandmarkers(context, mapping)
547
547
548 ui = context.resource(mapping, b'ui')
548 ui = context.resource(mapping, b'ui')
549 repo = context.resource(mapping, b'repo')
549 repo = context.resource(mapping, b'repo')
550 values = []
550 values = []
551
551
552 for x in succsandmarkers.tovalue(context, mapping):
552 for x in succsandmarkers.tovalue(context, mapping):
553 v = obsutil.obsfateprinter(
553 v = obsutil.obsfateprinter(
554 ui, repo, x[b'successors'], x[b'markers'], scmutil.formatchangeid
554 ui, repo, x[b'successors'], x[b'markers'], scmutil.formatchangeid
555 )
555 )
556 values.append(v)
556 values.append(v)
557
557
558 return compatlist(context, mapping, b"fate", values)
558 return compatlist(context, mapping, b"fate", values)
559
559
560
560
561 def shownames(context, mapping, namespace):
561 def shownames(context, mapping, namespace):
562 """helper method to generate a template keyword for a namespace"""
562 """helper method to generate a template keyword for a namespace"""
563 repo = context.resource(mapping, b'repo')
563 repo = context.resource(mapping, b'repo')
564 ctx = context.resource(mapping, b'ctx')
564 ctx = context.resource(mapping, b'ctx')
565 ns = repo.names.get(namespace)
565 ns = repo.names.get(namespace)
566 if ns is None:
566 if ns is None:
567 # namespaces.addnamespace() registers new template keyword, but
567 # namespaces.addnamespace() registers new template keyword, but
568 # the registered namespace might not exist in the current repo.
568 # the registered namespace might not exist in the current repo.
569 return
569 return
570 names = ns.names(repo, ctx.node())
570 names = ns.names(repo, ctx.node())
571 return compatlist(
571 return compatlist(
572 context, mapping, ns.templatename, names, plural=namespace
572 context, mapping, ns.templatename, names, plural=namespace
573 )
573 )
574
574
575
575
576 @templatekeyword(b'namespaces', requires={b'repo', b'ctx'})
576 @templatekeyword(b'namespaces', requires={b'repo', b'ctx'})
577 def shownamespaces(context, mapping):
577 def shownamespaces(context, mapping):
578 """Dict of lists. Names attached to this changeset per
578 """Dict of lists. Names attached to this changeset per
579 namespace."""
579 namespace."""
580 repo = context.resource(mapping, b'repo')
580 repo = context.resource(mapping, b'repo')
581 ctx = context.resource(mapping, b'ctx')
581 ctx = context.resource(mapping, b'ctx')
582
582
583 namespaces = util.sortdict()
583 namespaces = util.sortdict()
584
584
585 def makensmapfn(ns):
585 def makensmapfn(ns):
586 # 'name' for iterating over namespaces, templatename for local reference
586 # 'name' for iterating over namespaces, templatename for local reference
587 return lambda v: {b'name': v, ns.templatename: v}
587 return lambda v: {b'name': v, ns.templatename: v}
588
588
589 for k, ns in pycompat.iteritems(repo.names):
589 for k, ns in pycompat.iteritems(repo.names):
590 names = ns.names(repo, ctx.node())
590 names = ns.names(repo, ctx.node())
591 f = _showcompatlist(context, mapping, b'name', names)
591 f = _showcompatlist(context, mapping, b'name', names)
592 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
592 namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
593
593
594 f = _showcompatlist(context, mapping, b'namespace', list(namespaces))
594 f = _showcompatlist(context, mapping, b'namespace', list(namespaces))
595
595
596 def makemap(ns):
596 def makemap(ns):
597 return {
597 return {
598 b'namespace': ns,
598 b'namespace': ns,
599 b'names': namespaces[ns],
599 b'names': namespaces[ns],
600 b'builtin': repo.names[ns].builtin,
600 b'builtin': repo.names[ns].builtin,
601 b'colorname': repo.names[ns].colorname,
601 b'colorname': repo.names[ns].colorname,
602 }
602 }
603
603
604 return _hybrid(f, namespaces, makemap, pycompat.identity)
604 return _hybrid(f, namespaces, makemap, pycompat.identity)
605
605
606
606
607 @templatekeyword(b'negrev', requires={b'repo', b'ctx'})
607 @templatekeyword(b'negrev', requires={b'repo', b'ctx'})
608 def shownegrev(context, mapping):
608 def shownegrev(context, mapping):
609 """Integer. The repository-local changeset negative revision number,
609 """Integer. The repository-local changeset negative revision number,
610 which counts in the opposite direction."""
610 which counts in the opposite direction."""
611 ctx = context.resource(mapping, b'ctx')
611 ctx = context.resource(mapping, b'ctx')
612 rev = ctx.rev()
612 rev = ctx.rev()
613 if rev is None or rev < 0: # wdir() or nullrev?
613 if rev is None or rev < 0: # wdir() or nullrev?
614 return None
614 return None
615 repo = context.resource(mapping, b'repo')
615 repo = context.resource(mapping, b'repo')
616 return rev - len(repo)
616 return rev - len(repo)
617
617
618
618
619 @templatekeyword(b'node', requires={b'ctx'})
619 @templatekeyword(b'node', requires={b'ctx'})
620 def shownode(context, mapping):
620 def shownode(context, mapping):
621 """String. The changeset identification hash, as a 40 hexadecimal
621 """String. The changeset identification hash, as a 40 hexadecimal
622 digit string.
622 digit string.
623 """
623 """
624 ctx = context.resource(mapping, b'ctx')
624 ctx = context.resource(mapping, b'ctx')
625 return ctx.hex()
625 return ctx.hex()
626
626
627
627
628 @templatekeyword(b'obsolete', requires={b'ctx'})
628 @templatekeyword(b'obsolete', requires={b'ctx'})
629 def showobsolete(context, mapping):
629 def showobsolete(context, mapping):
630 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
630 """String. Whether the changeset is obsolete. (EXPERIMENTAL)"""
631 ctx = context.resource(mapping, b'ctx')
631 ctx = context.resource(mapping, b'ctx')
632 if ctx.obsolete():
632 if ctx.obsolete():
633 return b'obsolete'
633 return b'obsolete'
634 return b''
634 return b''
635
635
636
636
637 @templatekeyword(b'path', requires={b'fctx'})
637 @templatekeyword(b'path', requires={b'fctx'})
638 def showpath(context, mapping):
638 def showpath(context, mapping):
639 """String. Repository-absolute path of the current file. (EXPERIMENTAL)"""
639 """String. Repository-absolute path of the current file. (EXPERIMENTAL)"""
640 fctx = context.resource(mapping, b'fctx')
640 fctx = context.resource(mapping, b'fctx')
641 return fctx.path()
641 return fctx.path()
642
642
643
643
644 @templatekeyword(b'peerurls', requires={b'repo'})
644 @templatekeyword(b'peerurls', requires={b'repo'})
645 def showpeerurls(context, mapping):
645 def showpeerurls(context, mapping):
646 """A dictionary of repository locations defined in the [paths] section
646 """A dictionary of repository locations defined in the [paths] section
647 of your configuration file."""
647 of your configuration file."""
648 repo = context.resource(mapping, b'repo')
648 repo = context.resource(mapping, b'repo')
649 # see commands.paths() for naming of dictionary keys
649 # see commands.paths() for naming of dictionary keys
650 paths = repo.ui.paths
650 paths = repo.ui.paths
651 urls = util.sortdict(
651 urls = util.sortdict(
652 (k, p.rawloc) for k, p in sorted(pycompat.iteritems(paths))
652 (k, p.rawloc) for k, p in sorted(pycompat.iteritems(paths))
653 )
653 )
654
654
655 def makemap(k):
655 def makemap(k):
656 p = paths[k]
656 p = paths[k]
657 d = {b'name': k, b'url': p.rawloc}
657 d = {b'name': k, b'url': p.rawloc}
658 d.update((o, v) for o, v in sorted(pycompat.iteritems(p.suboptions)))
658 d.update((o, v) for o, v in sorted(pycompat.iteritems(p.suboptions)))
659 return d
659 return d
660
660
661 return _hybrid(None, urls, makemap, lambda k: b'%s=%s' % (k, urls[k]))
661 return _hybrid(None, urls, makemap, lambda k: b'%s=%s' % (k, urls[k]))
662
662
663
663
664 @templatekeyword(b"predecessors", requires={b'repo', b'ctx'})
664 @templatekeyword(b"predecessors", requires={b'repo', b'ctx'})
665 def showpredecessors(context, mapping):
665 def showpredecessors(context, mapping):
666 """Returns the list of the closest visible predecessors. (EXPERIMENTAL)"""
666 """Returns the list of the closest visible predecessors. (EXPERIMENTAL)"""
667 repo = context.resource(mapping, b'repo')
667 repo = context.resource(mapping, b'repo')
668 ctx = context.resource(mapping, b'ctx')
668 ctx = context.resource(mapping, b'ctx')
669 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
669 predecessors = sorted(obsutil.closestpredecessors(repo, ctx.node()))
670 predecessors = pycompat.maplist(hex, predecessors)
670 predecessors = pycompat.maplist(hex, predecessors)
671
671
672 return _hybrid(
672 return _hybrid(
673 None,
673 None,
674 predecessors,
674 predecessors,
675 lambda x: {b'ctx': repo[x]},
675 lambda x: {b'ctx': repo[x]},
676 lambda x: scmutil.formatchangeid(repo[x]),
676 lambda x: scmutil.formatchangeid(repo[x]),
677 )
677 )
678
678
679
679
680 @templatekeyword(b'reporoot', requires={b'repo'})
680 @templatekeyword(b'reporoot', requires={b'repo'})
681 def showreporoot(context, mapping):
681 def showreporoot(context, mapping):
682 """String. The root directory of the current repository."""
682 """String. The root directory of the current repository."""
683 repo = context.resource(mapping, b'repo')
683 repo = context.resource(mapping, b'repo')
684 return repo.root
684 return repo.root
685
685
686
686
687 @templatekeyword(b'size', requires={b'fctx'})
687 @templatekeyword(b'size', requires={b'fctx'})
688 def showsize(context, mapping):
688 def showsize(context, mapping):
689 """Integer. Size of the current file in bytes. (EXPERIMENTAL)"""
689 """Integer. Size of the current file in bytes. (EXPERIMENTAL)"""
690 fctx = context.resource(mapping, b'fctx')
690 fctx = context.resource(mapping, b'fctx')
691 return fctx.size()
691 return fctx.size()
692
692
693
693
694 # requires 'fctx' to denote {status} depends on (ctx, path) pair
694 # requires 'fctx' to denote {status} depends on (ctx, path) pair
695 @templatekeyword(b'status', requires={b'ctx', b'fctx', b'revcache'})
695 @templatekeyword(b'status', requires={b'ctx', b'fctx', b'revcache'})
696 def showstatus(context, mapping):
696 def showstatus(context, mapping):
697 """String. Status code of the current file. (EXPERIMENTAL)"""
697 """String. Status code of the current file. (EXPERIMENTAL)"""
698 path = templateutil.runsymbol(context, mapping, b'path')
698 path = templateutil.runsymbol(context, mapping, b'path')
699 path = templateutil.stringify(context, mapping, path)
699 path = templateutil.stringify(context, mapping, path)
700 if not path:
700 if not path:
701 return
701 return
702 statmap = _getfilestatusmap(context, mapping)
702 statmap = _getfilestatusmap(context, mapping)
703 if path not in statmap:
703 if path not in statmap:
704 statmap = _getfilestatusmap(context, mapping, listall=True)
704 statmap = _getfilestatusmap(context, mapping, listall=True)
705 return statmap.get(path)
705 return statmap.get(path)
706
706
707
707
708 @templatekeyword(b"successorssets", requires={b'repo', b'ctx'})
708 @templatekeyword(b"successorssets", requires={b'repo', b'ctx'})
709 def showsuccessorssets(context, mapping):
709 def showsuccessorssets(context, mapping):
710 """Returns a string of sets of successors for a changectx. Format used
710 """Returns a string of sets of successors for a changectx. Format used
711 is: [ctx1, ctx2], [ctx3] if ctx has been split into ctx1 and ctx2
711 is: [ctx1, ctx2], [ctx3] if ctx has been split into ctx1 and ctx2
712 while also diverged into ctx3. (EXPERIMENTAL)"""
712 while also diverged into ctx3. (EXPERIMENTAL)"""
713 repo = context.resource(mapping, b'repo')
713 repo = context.resource(mapping, b'repo')
714 ctx = context.resource(mapping, b'ctx')
714 ctx = context.resource(mapping, b'ctx')
715 if not ctx.obsolete():
715 if not ctx.obsolete():
716 return b''
716 return b''
717
717
718 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
718 ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
719 ssets = [[hex(n) for n in ss] for ss in ssets]
719 ssets = [[hex(n) for n in ss] for ss in ssets]
720
720
721 data = []
721 data = []
722 for ss in ssets:
722 for ss in ssets:
723 h = _hybrid(
723 h = _hybrid(
724 None,
724 None,
725 ss,
725 ss,
726 lambda x: {b'ctx': repo[x]},
726 lambda x: {b'ctx': repo[x]},
727 lambda x: scmutil.formatchangeid(repo[x]),
727 lambda x: scmutil.formatchangeid(repo[x]),
728 )
728 )
729 data.append(h)
729 data.append(h)
730
730
731 # Format the successorssets
731 # Format the successorssets
732 def render(d):
732 def render(d):
733 return templateutil.stringify(context, mapping, d)
733 return templateutil.stringify(context, mapping, d)
734
734
735 def gen(data):
735 def gen(data):
736 yield b"; ".join(render(d) for d in data)
736 yield b"; ".join(render(d) for d in data)
737
737
738 return _hybrid(
738 return _hybrid(
739 gen(data), data, lambda x: {b'successorset': x}, pycompat.identity
739 gen(data), data, lambda x: {b'successorset': x}, pycompat.identity
740 )
740 )
741
741
742
742
743 @templatekeyword(b"succsandmarkers", requires={b'repo', b'ctx'})
743 @templatekeyword(b"succsandmarkers", requires={b'repo', b'ctx'})
744 def showsuccsandmarkers(context, mapping):
744 def showsuccsandmarkers(context, mapping):
745 """Returns a list of dict for each final successor of ctx. The dict
745 """Returns a list of dict for each final successor of ctx. The dict
746 contains successors node id in "successors" keys and the list of
746 contains successors node id in "successors" keys and the list of
747 obs-markers from ctx to the set of successors in "markers".
747 obs-markers from ctx to the set of successors in "markers".
748 (EXPERIMENTAL)
748 (EXPERIMENTAL)
749 """
749 """
750 repo = context.resource(mapping, b'repo')
750 repo = context.resource(mapping, b'repo')
751 ctx = context.resource(mapping, b'ctx')
751 ctx = context.resource(mapping, b'ctx')
752
752
753 values = obsutil.successorsandmarkers(repo, ctx)
753 values = obsutil.successorsandmarkers(repo, ctx)
754
754
755 if values is None:
755 if values is None:
756 values = []
756 values = []
757
757
758 # Format successors and markers to avoid exposing binary to templates
758 # Format successors and markers to avoid exposing binary to templates
759 data = []
759 data = []
760 for i in values:
760 for i in values:
761 # Format successors
761 # Format successors
762 successors = i[b'successors']
762 successors = i[b'successors']
763
763
764 successors = [hex(n) for n in successors]
764 successors = [hex(n) for n in successors]
765 successors = _hybrid(
765 successors = _hybrid(
766 None,
766 None,
767 successors,
767 successors,
768 lambda x: {b'ctx': repo[x]},
768 lambda x: {b'ctx': repo[x]},
769 lambda x: scmutil.formatchangeid(repo[x]),
769 lambda x: scmutil.formatchangeid(repo[x]),
770 )
770 )
771
771
772 # Format markers
772 # Format markers
773 finalmarkers = []
773 finalmarkers = []
774 for m in i[b'markers']:
774 for m in i[b'markers']:
775 hexprec = hex(m[0])
775 hexprec = hex(m[0])
776 hexsucs = tuple(hex(n) for n in m[1])
776 hexsucs = tuple(hex(n) for n in m[1])
777 hexparents = None
777 hexparents = None
778 if m[5] is not None:
778 if m[5] is not None:
779 hexparents = tuple(hex(n) for n in m[5])
779 hexparents = tuple(hex(n) for n in m[5])
780 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
780 newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
781 finalmarkers.append(newmarker)
781 finalmarkers.append(newmarker)
782
782
783 data.append({b'successors': successors, b'markers': finalmarkers})
783 data.append({b'successors': successors, b'markers': finalmarkers})
784
784
785 return templateutil.mappinglist(data)
785 return templateutil.mappinglist(data)
786
786
787
787
788 @templatekeyword(b'p1', requires={b'ctx'})
788 @templatekeyword(b'p1', requires={b'ctx'})
789 def showp1(context, mapping):
789 def showp1(context, mapping):
790 """Changeset. The changeset's first parent. ``{p1.rev}`` for the revision
790 """Changeset. The changeset's first parent. ``{p1.rev}`` for the revision
791 number, and ``{p1.node}`` for the identification hash."""
791 number, and ``{p1.node}`` for the identification hash."""
792 ctx = context.resource(mapping, b'ctx')
792 ctx = context.resource(mapping, b'ctx')
793 return templateutil.mappingdict({b'ctx': ctx.p1()}, tmpl=_changeidtmpl)
793 return templateutil.mappingdict({b'ctx': ctx.p1()}, tmpl=_changeidtmpl)
794
794
795
795
796 @templatekeyword(b'p2', requires={b'ctx'})
796 @templatekeyword(b'p2', requires={b'ctx'})
797 def showp2(context, mapping):
797 def showp2(context, mapping):
798 """Changeset. The changeset's second parent. ``{p2.rev}`` for the revision
798 """Changeset. The changeset's second parent. ``{p2.rev}`` for the revision
799 number, and ``{p2.node}`` for the identification hash."""
799 number, and ``{p2.node}`` for the identification hash."""
800 ctx = context.resource(mapping, b'ctx')
800 ctx = context.resource(mapping, b'ctx')
801 return templateutil.mappingdict({b'ctx': ctx.p2()}, tmpl=_changeidtmpl)
801 return templateutil.mappingdict({b'ctx': ctx.p2()}, tmpl=_changeidtmpl)
802
802
803
803
804 @templatekeyword(b'p1rev', requires={b'ctx'})
804 @templatekeyword(b'p1rev', requires={b'ctx'})
805 def showp1rev(context, mapping):
805 def showp1rev(context, mapping):
806 """Integer. The repository-local revision number of the changeset's
806 """Integer. The repository-local revision number of the changeset's
807 first parent, or -1 if the changeset has no parents. (DEPRECATED)"""
807 first parent, or -1 if the changeset has no parents. (DEPRECATED)"""
808 ctx = context.resource(mapping, b'ctx')
808 ctx = context.resource(mapping, b'ctx')
809 return ctx.p1().rev()
809 return ctx.p1().rev()
810
810
811
811
812 @templatekeyword(b'p2rev', requires={b'ctx'})
812 @templatekeyword(b'p2rev', requires={b'ctx'})
813 def showp2rev(context, mapping):
813 def showp2rev(context, mapping):
814 """Integer. The repository-local revision number of the changeset's
814 """Integer. The repository-local revision number of the changeset's
815 second parent, or -1 if the changeset has no second parent. (DEPRECATED)"""
815 second parent, or -1 if the changeset has no second parent. (DEPRECATED)"""
816 ctx = context.resource(mapping, b'ctx')
816 ctx = context.resource(mapping, b'ctx')
817 return ctx.p2().rev()
817 return ctx.p2().rev()
818
818
819
819
820 @templatekeyword(b'p1node', requires={b'ctx'})
820 @templatekeyword(b'p1node', requires={b'ctx'})
821 def showp1node(context, mapping):
821 def showp1node(context, mapping):
822 """String. The identification hash of the changeset's first parent,
822 """String. The identification hash of the changeset's first parent,
823 as a 40 digit hexadecimal string. If the changeset has no parents, all
823 as a 40 digit hexadecimal string. If the changeset has no parents, all
824 digits are 0. (DEPRECATED)"""
824 digits are 0. (DEPRECATED)"""
825 ctx = context.resource(mapping, b'ctx')
825 ctx = context.resource(mapping, b'ctx')
826 return ctx.p1().hex()
826 return ctx.p1().hex()
827
827
828
828
829 @templatekeyword(b'p2node', requires={b'ctx'})
829 @templatekeyword(b'p2node', requires={b'ctx'})
830 def showp2node(context, mapping):
830 def showp2node(context, mapping):
831 """String. The identification hash of the changeset's second
831 """String. The identification hash of the changeset's second
832 parent, as a 40 digit hexadecimal string. If the changeset has no second
832 parent, as a 40 digit hexadecimal string. If the changeset has no second
833 parent, all digits are 0. (DEPRECATED)"""
833 parent, all digits are 0. (DEPRECATED)"""
834 ctx = context.resource(mapping, b'ctx')
834 ctx = context.resource(mapping, b'ctx')
835 return ctx.p2().hex()
835 return ctx.p2().hex()
836
836
837
837
838 @templatekeyword(b'parents', requires={b'repo', b'ctx'})
838 @templatekeyword(b'parents', requires={b'repo', b'ctx'})
839 def showparents(context, mapping):
839 def showparents(context, mapping):
840 """List of strings. The parents of the changeset in "rev:node"
840 """List of strings. The parents of the changeset in "rev:node"
841 format. If the changeset has only one "natural" parent (the predecessor
841 format. If the changeset has only one "natural" parent (the predecessor
842 revision) nothing is shown."""
842 revision) nothing is shown."""
843 repo = context.resource(mapping, b'repo')
843 repo = context.resource(mapping, b'repo')
844 ctx = context.resource(mapping, b'ctx')
844 ctx = context.resource(mapping, b'ctx')
845 pctxs = scmutil.meaningfulparents(repo, ctx)
845 pctxs = scmutil.meaningfulparents(repo, ctx)
846 prevs = [p.rev() for p in pctxs]
846 prevs = [p.rev() for p in pctxs]
847 parents = [
847 parents = [
848 [(b'rev', p.rev()), (b'node', p.hex()), (b'phase', p.phasestr())]
848 [(b'rev', p.rev()), (b'node', p.hex()), (b'phase', p.phasestr())]
849 for p in pctxs
849 for p in pctxs
850 ]
850 ]
851 f = _showcompatlist(context, mapping, b'parent', parents)
851 f = _showcompatlist(context, mapping, b'parent', parents)
852 return _hybrid(
852 return _hybrid(
853 f,
853 f,
854 prevs,
854 prevs,
855 lambda x: {b'ctx': repo[x]},
855 lambda x: {b'ctx': repo[x]},
856 lambda x: scmutil.formatchangeid(repo[x]),
856 lambda x: scmutil.formatchangeid(repo[x]),
857 keytype=int,
857 keytype=int,
858 )
858 )
859
859
860
860
861 @templatekeyword(b'phase', requires={b'ctx'})
861 @templatekeyword(b'phase', requires={b'ctx'})
862 def showphase(context, mapping):
862 def showphase(context, mapping):
863 """String. The changeset phase name."""
863 """String. The changeset phase name."""
864 ctx = context.resource(mapping, b'ctx')
864 ctx = context.resource(mapping, b'ctx')
865 return ctx.phasestr()
865 return ctx.phasestr()
866
866
867
867
868 @templatekeyword(b'phaseidx', requires={b'ctx'})
868 @templatekeyword(b'phaseidx', requires={b'ctx'})
869 def showphaseidx(context, mapping):
869 def showphaseidx(context, mapping):
870 """Integer. The changeset phase index. (ADVANCED)"""
870 """Integer. The changeset phase index. (ADVANCED)"""
871 ctx = context.resource(mapping, b'ctx')
871 ctx = context.resource(mapping, b'ctx')
872 return ctx.phase()
872 return ctx.phase()
873
873
874
874
875 @templatekeyword(b'rev', requires={b'ctx'})
875 @templatekeyword(b'rev', requires={b'ctx'})
876 def showrev(context, mapping):
876 def showrev(context, mapping):
877 """Integer. The repository-local changeset revision number."""
877 """Integer. The repository-local changeset revision number."""
878 ctx = context.resource(mapping, b'ctx')
878 ctx = context.resource(mapping, b'ctx')
879 return scmutil.intrev(ctx)
879 return scmutil.intrev(ctx)
880
880
881
881
882 @templatekeyword(b'subrepos', requires={b'ctx'})
882 @templatekeyword(b'subrepos', requires={b'ctx'})
883 def showsubrepos(context, mapping):
883 def showsubrepos(context, mapping):
884 """List of strings. Updated subrepositories in the changeset."""
884 """List of strings. Updated subrepositories in the changeset."""
885 ctx = context.resource(mapping, b'ctx')
885 ctx = context.resource(mapping, b'ctx')
886 substate = ctx.substate
886 substate = ctx.substate
887 if not substate:
887 if not substate:
888 return compatlist(context, mapping, b'subrepo', [])
888 return compatlist(context, mapping, b'subrepo', [])
889 psubstate = ctx.p1().substate or {}
889 psubstate = ctx.p1().substate or {}
890 subrepos = []
890 subrepos = []
891 for sub in substate:
891 for sub in substate:
892 if sub not in psubstate or substate[sub] != psubstate[sub]:
892 if sub not in psubstate or substate[sub] != psubstate[sub]:
893 subrepos.append(sub) # modified or newly added in ctx
893 subrepos.append(sub) # modified or newly added in ctx
894 for sub in psubstate:
894 for sub in psubstate:
895 if sub not in substate:
895 if sub not in substate:
896 subrepos.append(sub) # removed in ctx
896 subrepos.append(sub) # removed in ctx
897 return compatlist(context, mapping, b'subrepo', sorted(subrepos))
897 return compatlist(context, mapping, b'subrepo', sorted(subrepos))
898
898
899
899
900 # don't remove "showtags" definition, even though namespaces will put
900 # don't remove "showtags" definition, even though namespaces will put
901 # a helper function for "tags" keyword into "keywords" map automatically,
901 # a helper function for "tags" keyword into "keywords" map automatically,
902 # because online help text is built without namespaces initialization
902 # because online help text is built without namespaces initialization
903 @templatekeyword(b'tags', requires={b'repo', b'ctx'})
903 @templatekeyword(b'tags', requires={b'repo', b'ctx'})
904 def showtags(context, mapping):
904 def showtags(context, mapping):
905 """List of strings. Any tags associated with the changeset."""
905 """List of strings. Any tags associated with the changeset."""
906 return shownames(context, mapping, b'tags')
906 return shownames(context, mapping, b'tags')
907
907
908
908
909 @templatekeyword(b'termwidth', requires={b'ui'})
909 @templatekeyword(b'termwidth', requires={b'ui'})
910 def showtermwidth(context, mapping):
910 def showtermwidth(context, mapping):
911 """Integer. The width of the current terminal."""
911 """Integer. The width of the current terminal."""
912 ui = context.resource(mapping, b'ui')
912 ui = context.resource(mapping, b'ui')
913 return ui.termwidth()
913 return ui.termwidth()
914
914
915
915
916 @templatekeyword(b'user', requires={b'ctx'})
916 @templatekeyword(b'user', requires={b'ctx'})
917 def showuser(context, mapping):
917 def showuser(context, mapping):
918 """String. The unmodified author of the changeset."""
918 """String. The unmodified author of the changeset."""
919 ctx = context.resource(mapping, b'ctx')
919 ctx = context.resource(mapping, b'ctx')
920 return ctx.user()
920 return ctx.user()
921
921
922
922
923 @templatekeyword(b'instabilities', requires={b'ctx'})
923 @templatekeyword(b'instabilities', requires={b'ctx'})
924 def showinstabilities(context, mapping):
924 def showinstabilities(context, mapping):
925 """List of strings. Evolution instabilities affecting the changeset.
925 """List of strings. Evolution instabilities affecting the changeset.
926 (EXPERIMENTAL)
926 (EXPERIMENTAL)
927 """
927 """
928 ctx = context.resource(mapping, b'ctx')
928 ctx = context.resource(mapping, b'ctx')
929 return compatlist(
929 return compatlist(
930 context,
930 context,
931 mapping,
931 mapping,
932 b'instability',
932 b'instability',
933 ctx.instabilities(),
933 ctx.instabilities(),
934 plural=b'instabilities',
934 plural=b'instabilities',
935 )
935 )
936
936
937
937
938 @templatekeyword(b'verbosity', requires={b'ui'})
938 @templatekeyword(b'verbosity', requires={b'ui'})
939 def showverbosity(context, mapping):
939 def showverbosity(context, mapping):
940 """String. The current output verbosity in 'debug', 'quiet', 'verbose',
940 """String. The current output verbosity in 'debug', 'quiet', 'verbose',
941 or ''."""
941 or ''."""
942 ui = context.resource(mapping, b'ui')
942 ui = context.resource(mapping, b'ui')
943 # see logcmdutil.changesettemplater for priority of these flags
943 # see logcmdutil.changesettemplater for priority of these flags
944 if ui.debugflag:
944 if ui.debugflag:
945 return b'debug'
945 return b'debug'
946 elif ui.quiet:
946 elif ui.quiet:
947 return b'quiet'
947 return b'quiet'
948 elif ui.verbose:
948 elif ui.verbose:
949 return b'verbose'
949 return b'verbose'
950 return b''
950 return b''
951
951
952
952
953 @templatekeyword(b'whyunstable', requires={b'repo', b'ctx'})
953 @templatekeyword(b'whyunstable', requires={b'repo', b'ctx'})
954 def showwhyunstable(context, mapping):
954 def showwhyunstable(context, mapping):
955 """List of dicts explaining all instabilities of a changeset.
955 """List of dicts explaining all instabilities of a changeset.
956 (EXPERIMENTAL)
956 (EXPERIMENTAL)
957 """
957 """
958 repo = context.resource(mapping, b'repo')
958 repo = context.resource(mapping, b'repo')
959 ctx = context.resource(mapping, b'ctx')
959 ctx = context.resource(mapping, b'ctx')
960
960
961 def formatnode(ctx):
961 def formatnode(ctx):
962 return b'%s (%s)' % (scmutil.formatchangeid(ctx), ctx.phasestr())
962 return b'%s (%s)' % (scmutil.formatchangeid(ctx), ctx.phasestr())
963
963
964 entries = obsutil.whyunstable(repo, ctx)
964 entries = obsutil.whyunstable(repo, ctx)
965
965
966 for entry in entries:
966 for entry in entries:
967 if entry.get(b'divergentnodes'):
967 if entry.get(b'divergentnodes'):
968 dnodes = entry[b'divergentnodes']
968 dnodes = entry[b'divergentnodes']
969 dnhybrid = _hybrid(
969 dnhybrid = _hybrid(
970 None,
970 None,
971 [dnode.hex() for dnode in dnodes],
971 [dnode.hex() for dnode in dnodes],
972 lambda x: {b'ctx': repo[x]},
972 lambda x: {b'ctx': repo[x]},
973 lambda x: formatnode(repo[x]),
973 lambda x: formatnode(repo[x]),
974 )
974 )
975 entry[b'divergentnodes'] = dnhybrid
975 entry[b'divergentnodes'] = dnhybrid
976
976
977 tmpl = (
977 tmpl = (
978 b'{instability}:{if(divergentnodes, " ")}{divergentnodes} '
978 b'{instability}:{if(divergentnodes, " ")}{divergentnodes} '
979 b'{reason} {node|short}'
979 b'{reason} {node|short}'
980 )
980 )
981 return templateutil.mappinglist(entries, tmpl=tmpl, sep=b'\n')
981 return templateutil.mappinglist(entries, tmpl=tmpl, sep=b'\n')
982
982
983
983
984 def loadkeyword(ui, extname, registrarobj):
984 def loadkeyword(ui, extname, registrarobj):
985 """Load template keyword from specified registrarobj
985 """Load template keyword from specified registrarobj
986 """
986 """
987 for name, func in pycompat.iteritems(registrarobj._table):
987 for name, func in pycompat.iteritems(registrarobj._table):
988 keywords[name] = func
988 keywords[name] = func
989
989
990
990
991 # tell hggettext to extract docstrings from these functions:
991 # tell hggettext to extract docstrings from these functions:
992 i18nfunctions = keywords.values()
992 i18nfunctions = keywords.values()
@@ -1,771 +1,771 b''
1 #testcases abortcommand abortflag
1 #testcases abortcommand abortflag
2
2
3 #if abortflag
3 #if abortflag
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [alias]
5 > [alias]
6 > abort = graft --abort
6 > abort = graft --abort
7 > EOF
7 > EOF
8 #endif
8 #endif
9
9
10
10
11 Testing the reading of old format graftstate file with newer mercurial
11 Testing the reading of old format graftstate file with newer mercurial
12
12
13 $ hg init oldgraft
13 $ hg init oldgraft
14 $ cd oldgraft
14 $ cd oldgraft
15 $ for ch in a b c; do echo foo > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
15 $ for ch in a b c; do echo foo > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
16 $ hg log -GT "{rev}:{node|short} {desc}\n"
16 $ hg log -GT "{rev}:{node|short} {desc}\n"
17 @ 2:8be98ac1a569 added c
17 @ 2:8be98ac1a569 added c
18 |
18 |
19 o 1:80e6d2c47cfe added b
19 o 1:80e6d2c47cfe added b
20 |
20 |
21 o 0:f7ad41964313 added a
21 o 0:f7ad41964313 added a
22
22
23 $ hg up 0
23 $ hg up 0
24 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
24 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
25 $ echo bar > b
25 $ echo bar > b
26 $ hg add b
26 $ hg add b
27 $ hg ci -m "bar to b"
27 $ hg ci -m "bar to b"
28 created new head
28 created new head
29 $ hg graft -r 1 -r 2
29 $ hg graft -r 1 -r 2
30 grafting 1:80e6d2c47cfe "added b"
30 grafting 1:80e6d2c47cfe "added b"
31 merging b
31 merging b
32 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
32 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
33 abort: unresolved conflicts, can't continue
33 abort: unresolved conflicts, can't continue
34 (use 'hg resolve' and 'hg graft --continue')
34 (use 'hg resolve' and 'hg graft --continue')
35 [1]
35 [1]
36
36
37 Writing the nodes in old format to graftstate
37 Writing the nodes in old format to graftstate
38
38
39 $ hg log -r 1 -r 2 -T '{node}\n' > .hg/graftstate
39 $ hg log -r 1 -r 2 -T '{node}\n' > .hg/graftstate
40 $ echo foo > b
40 $ echo foo > b
41 $ hg resolve -m
41 $ hg resolve -m
42 (no more unresolved files)
42 (no more unresolved files)
43 continue: hg graft --continue
43 continue: hg graft --continue
44 $ hg graft --continue
44 $ hg graft --continue
45 grafting 1:80e6d2c47cfe "added b"
45 grafting 1:80e6d2c47cfe "added b"
46 grafting 2:8be98ac1a569 "added c"
46 grafting 2:8be98ac1a569 "added c"
47
47
48 Testing that --user is preserved during conflicts and value is reused while
48 Testing that --user is preserved during conflicts and value is reused while
49 running `hg graft --continue`
49 running `hg graft --continue`
50
50
51 $ hg log -G
51 $ hg log -G
52 @ changeset: 5:711e9fa999f1
52 @ changeset: 5:711e9fa999f1
53 | tag: tip
53 | tag: tip
54 | user: test
54 | user: test
55 | date: Thu Jan 01 00:00:00 1970 +0000
55 | date: Thu Jan 01 00:00:00 1970 +0000
56 | summary: added c
56 | summary: added c
57 |
57 |
58 o changeset: 4:e5ad7353b408
58 o changeset: 4:e5ad7353b408
59 | user: test
59 | user: test
60 | date: Thu Jan 01 00:00:00 1970 +0000
60 | date: Thu Jan 01 00:00:00 1970 +0000
61 | summary: added b
61 | summary: added b
62 |
62 |
63 o changeset: 3:9e887f7a939c
63 o changeset: 3:9e887f7a939c
64 | parent: 0:f7ad41964313
64 | parent: 0:f7ad41964313
65 | user: test
65 | user: test
66 | date: Thu Jan 01 00:00:00 1970 +0000
66 | date: Thu Jan 01 00:00:00 1970 +0000
67 | summary: bar to b
67 | summary: bar to b
68 |
68 |
69 | o changeset: 2:8be98ac1a569
69 | o changeset: 2:8be98ac1a569
70 | | user: test
70 | | user: test
71 | | date: Thu Jan 01 00:00:00 1970 +0000
71 | | date: Thu Jan 01 00:00:00 1970 +0000
72 | | summary: added c
72 | | summary: added c
73 | |
73 | |
74 | o changeset: 1:80e6d2c47cfe
74 | o changeset: 1:80e6d2c47cfe
75 |/ user: test
75 |/ user: test
76 | date: Thu Jan 01 00:00:00 1970 +0000
76 | date: Thu Jan 01 00:00:00 1970 +0000
77 | summary: added b
77 | summary: added b
78 |
78 |
79 o changeset: 0:f7ad41964313
79 o changeset: 0:f7ad41964313
80 user: test
80 user: test
81 date: Thu Jan 01 00:00:00 1970 +0000
81 date: Thu Jan 01 00:00:00 1970 +0000
82 summary: added a
82 summary: added a
83
83
84
84
85 $ hg up '.^^'
85 $ hg up '.^^'
86 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
86 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
87
87
88 $ hg graft -r 1 -r 2 --user batman
88 $ hg graft -r 1 -r 2 --user batman
89 grafting 1:80e6d2c47cfe "added b"
89 grafting 1:80e6d2c47cfe "added b"
90 merging b
90 merging b
91 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
91 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
92 abort: unresolved conflicts, can't continue
92 abort: unresolved conflicts, can't continue
93 (use 'hg resolve' and 'hg graft --continue')
93 (use 'hg resolve' and 'hg graft --continue')
94 [1]
94 [1]
95
95
96 $ echo wat > b
96 $ echo wat > b
97 $ hg resolve -m
97 $ hg resolve -m
98 (no more unresolved files)
98 (no more unresolved files)
99 continue: hg graft --continue
99 continue: hg graft --continue
100
100
101 $ hg graft --continue
101 $ hg graft --continue
102 grafting 1:80e6d2c47cfe "added b"
102 grafting 1:80e6d2c47cfe "added b"
103 grafting 2:8be98ac1a569 "added c"
103 grafting 2:8be98ac1a569 "added c"
104
104
105 $ hg log -Gr 3::
105 $ hg log -Gr 3::
106 @ changeset: 7:11a36ffaacf2
106 @ changeset: 7:11a36ffaacf2
107 | tag: tip
107 | tag: tip
108 | user: batman
108 | user: batman
109 | date: Thu Jan 01 00:00:00 1970 +0000
109 | date: Thu Jan 01 00:00:00 1970 +0000
110 | summary: added c
110 | summary: added c
111 |
111 |
112 o changeset: 6:76803afc6511
112 o changeset: 6:76803afc6511
113 | parent: 3:9e887f7a939c
113 | parent: 3:9e887f7a939c
114 | user: batman
114 | user: batman
115 | date: Thu Jan 01 00:00:00 1970 +0000
115 | date: Thu Jan 01 00:00:00 1970 +0000
116 | summary: added b
116 | summary: added b
117 |
117 |
118 | o changeset: 5:711e9fa999f1
118 | o changeset: 5:711e9fa999f1
119 | | user: test
119 | | user: test
120 | | date: Thu Jan 01 00:00:00 1970 +0000
120 | | date: Thu Jan 01 00:00:00 1970 +0000
121 | | summary: added c
121 | | summary: added c
122 | |
122 | |
123 | o changeset: 4:e5ad7353b408
123 | o changeset: 4:e5ad7353b408
124 |/ user: test
124 |/ user: test
125 | date: Thu Jan 01 00:00:00 1970 +0000
125 | date: Thu Jan 01 00:00:00 1970 +0000
126 | summary: added b
126 | summary: added b
127 |
127 |
128 o changeset: 3:9e887f7a939c
128 o changeset: 3:9e887f7a939c
129 | parent: 0:f7ad41964313
129 | parent: 0:f7ad41964313
130 ~ user: test
130 ~ user: test
131 date: Thu Jan 01 00:00:00 1970 +0000
131 date: Thu Jan 01 00:00:00 1970 +0000
132 summary: bar to b
132 summary: bar to b
133
133
134 Test that --date is preserved and reused in `hg graft --continue`
134 Test that --date is preserved and reused in `hg graft --continue`
135
135
136 $ hg up '.^^'
136 $ hg up '.^^'
137 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
137 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
138 $ hg graft -r 1 -r 2 --date '1234560000 120'
138 $ hg graft -r 1 -r 2 --date '1234560000 120'
139 grafting 1:80e6d2c47cfe "added b"
139 grafting 1:80e6d2c47cfe "added b"
140 merging b
140 merging b
141 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
141 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
142 abort: unresolved conflicts, can't continue
142 abort: unresolved conflicts, can't continue
143 (use 'hg resolve' and 'hg graft --continue')
143 (use 'hg resolve' and 'hg graft --continue')
144 [1]
144 [1]
145
145
146 $ echo foobar > b
146 $ echo foobar > b
147 $ hg resolve -m
147 $ hg resolve -m
148 (no more unresolved files)
148 (no more unresolved files)
149 continue: hg graft --continue
149 continue: hg graft --continue
150 $ hg graft --continue
150 $ hg graft --continue
151 grafting 1:80e6d2c47cfe "added b"
151 grafting 1:80e6d2c47cfe "added b"
152 grafting 2:8be98ac1a569 "added c"
152 grafting 2:8be98ac1a569 "added c"
153
153
154 $ hg log -Gr '.^^::.'
154 $ hg log -Gr '.^^::.'
155 @ changeset: 9:1896b76e007a
155 @ changeset: 9:1896b76e007a
156 | tag: tip
156 | tag: tip
157 | user: test
157 | user: test
158 | date: Fri Feb 13 21:18:00 2009 -0002
158 | date: Fri Feb 13 21:18:00 2009 -0002
159 | summary: added c
159 | summary: added c
160 |
160 |
161 o changeset: 8:ce2b4f1632af
161 o changeset: 8:ce2b4f1632af
162 | parent: 3:9e887f7a939c
162 | parent: 3:9e887f7a939c
163 | user: test
163 | user: test
164 | date: Fri Feb 13 21:18:00 2009 -0002
164 | date: Fri Feb 13 21:18:00 2009 -0002
165 | summary: added b
165 | summary: added b
166 |
166 |
167 o changeset: 3:9e887f7a939c
167 o changeset: 3:9e887f7a939c
168 | parent: 0:f7ad41964313
168 | parent: 0:f7ad41964313
169 ~ user: test
169 ~ user: test
170 date: Thu Jan 01 00:00:00 1970 +0000
170 date: Thu Jan 01 00:00:00 1970 +0000
171 summary: bar to b
171 summary: bar to b
172
172
173 Test that --log is preserved and reused in `hg graft --continue`
173 Test that --log is preserved and reused in `hg graft --continue`
174
174
175 $ hg up '.^^'
175 $ hg up '.^^'
176 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
176 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
177 $ hg graft -r 1 -r 2 --log
177 $ hg graft -r 1 -r 2 --log
178 grafting 1:80e6d2c47cfe "added b"
178 grafting 1:80e6d2c47cfe "added b"
179 merging b
179 merging b
180 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
180 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
181 abort: unresolved conflicts, can't continue
181 abort: unresolved conflicts, can't continue
182 (use 'hg resolve' and 'hg graft --continue')
182 (use 'hg resolve' and 'hg graft --continue')
183 [1]
183 [1]
184
184
185 $ echo foobar > b
185 $ echo foobar > b
186 $ hg resolve -m
186 $ hg resolve -m
187 (no more unresolved files)
187 (no more unresolved files)
188 continue: hg graft --continue
188 continue: hg graft --continue
189
189
190 $ hg graft --continue
190 $ hg graft --continue
191 grafting 1:80e6d2c47cfe "added b"
191 grafting 1:80e6d2c47cfe "added b"
192 grafting 2:8be98ac1a569 "added c"
192 grafting 2:8be98ac1a569 "added c"
193
193
194 $ hg log -GT "{rev}:{node|short} {desc}" -r '.^^::.'
194 $ hg log -GT "{rev}:{node|short} {desc}" -r '.^^::.'
195 @ 11:30c1050a58b2 added c
195 @ 11:30c1050a58b2 added c
196 | (grafted from 8be98ac1a56990c2d9ca6861041b8390af7bd6f3)
196 | (grafted from 8be98ac1a56990c2d9ca6861041b8390af7bd6f3)
197 o 10:ec7eda2313e2 added b
197 o 10:ec7eda2313e2 added b
198 | (grafted from 80e6d2c47cfe5b3185519568327a17a061c7efb6)
198 | (grafted from 80e6d2c47cfe5b3185519568327a17a061c7efb6)
199 o 3:9e887f7a939c bar to b
199 o 3:9e887f7a939c bar to b
200 |
200 |
201 ~
201 ~
202
202
203 $ cd ..
203 $ cd ..
204
204
205 Testing the --stop flag of `hg graft` which stops the interrupted graft
205 Testing the --stop flag of `hg graft` which stops the interrupted graft
206
206
207 $ hg init stopgraft
207 $ hg init stopgraft
208 $ cd stopgraft
208 $ cd stopgraft
209 $ for ch in a b c d; do echo $ch > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
209 $ for ch in a b c d; do echo $ch > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
210
210
211 $ hg log -G
211 $ hg log -G
212 @ changeset: 3:9150fe93bec6
212 @ changeset: 3:9150fe93bec6
213 | tag: tip
213 | tag: tip
214 | user: test
214 | user: test
215 | date: Thu Jan 01 00:00:00 1970 +0000
215 | date: Thu Jan 01 00:00:00 1970 +0000
216 | summary: added d
216 | summary: added d
217 |
217 |
218 o changeset: 2:155349b645be
218 o changeset: 2:155349b645be
219 | user: test
219 | user: test
220 | date: Thu Jan 01 00:00:00 1970 +0000
220 | date: Thu Jan 01 00:00:00 1970 +0000
221 | summary: added c
221 | summary: added c
222 |
222 |
223 o changeset: 1:5f6d8a4bf34a
223 o changeset: 1:5f6d8a4bf34a
224 | user: test
224 | user: test
225 | date: Thu Jan 01 00:00:00 1970 +0000
225 | date: Thu Jan 01 00:00:00 1970 +0000
226 | summary: added b
226 | summary: added b
227 |
227 |
228 o changeset: 0:9092f1db7931
228 o changeset: 0:9092f1db7931
229 user: test
229 user: test
230 date: Thu Jan 01 00:00:00 1970 +0000
230 date: Thu Jan 01 00:00:00 1970 +0000
231 summary: added a
231 summary: added a
232
232
233 $ hg up '.^^'
233 $ hg up '.^^'
234 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
234 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
235
235
236 $ echo foo > d
236 $ echo foo > d
237 $ hg ci -Aqm "added foo to d"
237 $ hg ci -Aqm "added foo to d"
238
238
239 $ hg graft --stop
239 $ hg graft --stop
240 abort: no interrupted graft found
240 abort: no interrupted graft found
241 [255]
241 [255]
242
242
243 $ hg graft -r 3
243 $ hg graft -r 3
244 grafting 3:9150fe93bec6 "added d"
244 grafting 3:9150fe93bec6 "added d"
245 merging d
245 merging d
246 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
246 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
247 abort: unresolved conflicts, can't continue
247 abort: unresolved conflicts, can't continue
248 (use 'hg resolve' and 'hg graft --continue')
248 (use 'hg resolve' and 'hg graft --continue')
249 [1]
249 [1]
250
250
251 $ hg graft --stop --continue
251 $ hg graft --stop --continue
252 abort: cannot specify both --stop and --continue
252 abort: cannot specify both --stop and --continue
253 [255]
253 [255]
254
254
255 $ hg graft --stop -U
255 $ hg graft --stop -U
256 abort: cannot specify both --stop and --user
256 abort: cannot specify both --stop and --user
257 [255]
257 [255]
258 $ hg graft --stop --rev 4
258 $ hg graft --stop --rev 4
259 abort: cannot specify both --stop and --rev
259 abort: cannot specify both --stop and --rev
260 [255]
260 [255]
261 $ hg graft --stop --log
261 $ hg graft --stop --log
262 abort: cannot specify both --stop and --log
262 abort: cannot specify both --stop and --log
263 [255]
263 [255]
264
264
265 $ hg graft --stop
265 $ hg graft --stop
266 stopped the interrupted graft
266 stopped the interrupted graft
267 working directory is now at a0deacecd59d
267 working directory is now at a0deacecd59d
268
268
269 $ hg diff
269 $ hg diff
270
270
271 $ hg log -Gr '.'
271 $ hg log -Gr '.'
272 @ changeset: 4:a0deacecd59d
272 @ changeset: 4:a0deacecd59d
273 | tag: tip
273 | tag: tip
274 ~ parent: 1:5f6d8a4bf34a
274 ~ parent: 1:5f6d8a4bf34a
275 user: test
275 user: test
276 date: Thu Jan 01 00:00:00 1970 +0000
276 date: Thu Jan 01 00:00:00 1970 +0000
277 summary: added foo to d
277 summary: added foo to d
278
278
279 $ hg graft -r 2 -r 3
279 $ hg graft -r 2 -r 3
280 grafting 2:155349b645be "added c"
280 grafting 2:155349b645be "added c"
281 grafting 3:9150fe93bec6 "added d"
281 grafting 3:9150fe93bec6 "added d"
282 merging d
282 merging d
283 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
283 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
284 abort: unresolved conflicts, can't continue
284 abort: unresolved conflicts, can't continue
285 (use 'hg resolve' and 'hg graft --continue')
285 (use 'hg resolve' and 'hg graft --continue')
286 [1]
286 [1]
287
287
288 $ hg graft --stop
288 $ hg graft --stop
289 stopped the interrupted graft
289 stopped the interrupted graft
290 working directory is now at 75b447541a9e
290 working directory is now at 75b447541a9e
291
291
292 $ hg diff
292 $ hg diff
293
293
294 $ hg log -G -T "{rev}:{node|short} {desc}"
294 $ hg log -G -T "{rev}:{node|short} {desc}"
295 @ 5:75b447541a9e added c
295 @ 5:75b447541a9e added c
296 |
296 |
297 o 4:a0deacecd59d added foo to d
297 o 4:a0deacecd59d added foo to d
298 |
298 |
299 | o 3:9150fe93bec6 added d
299 | o 3:9150fe93bec6 added d
300 | |
300 | |
301 | o 2:155349b645be added c
301 | o 2:155349b645be added c
302 |/
302 |/
303 o 1:5f6d8a4bf34a added b
303 o 1:5f6d8a4bf34a added b
304 |
304 |
305 o 0:9092f1db7931 added a
305 o 0:9092f1db7931 added a
306
306
307 $ cd ..
307 $ cd ..
308
308
309 Testing the --abort flag for `hg graft` which aborts and rollback to state
309 Testing the --abort flag for `hg graft` which aborts and rollback to state
310 before the graft
310 before the graft
311
311
312 $ hg init abortgraft
312 $ hg init abortgraft
313 $ cd abortgraft
313 $ cd abortgraft
314 $ for ch in a b c d; do echo $ch > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
314 $ for ch in a b c d; do echo $ch > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
315
315
316 $ hg up '.^^'
316 $ hg up '.^^'
317 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
317 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
318
318
319 $ echo x > x
319 $ echo x > x
320 $ hg ci -Aqm "added x"
320 $ hg ci -Aqm "added x"
321 $ hg up '.^'
321 $ hg up '.^'
322 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
322 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
323 $ echo foo > c
323 $ echo foo > c
324 $ hg ci -Aqm "added foo to c"
324 $ hg ci -Aqm "added foo to c"
325
325
326 $ hg log -GT "{rev}:{node|short} {desc}"
326 $ hg log -GT "{rev}:{node|short} {desc}"
327 @ 5:36b793615f78 added foo to c
327 @ 5:36b793615f78 added foo to c
328 |
328 |
329 | o 4:863a25e1a9ea added x
329 | o 4:863a25e1a9ea added x
330 |/
330 |/
331 | o 3:9150fe93bec6 added d
331 | o 3:9150fe93bec6 added d
332 | |
332 | |
333 | o 2:155349b645be added c
333 | o 2:155349b645be added c
334 |/
334 |/
335 o 1:5f6d8a4bf34a added b
335 o 1:5f6d8a4bf34a added b
336 |
336 |
337 o 0:9092f1db7931 added a
337 o 0:9092f1db7931 added a
338
338
339 $ hg up 9150fe93bec6
339 $ hg up 9150fe93bec6
340 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
341
341
342 $ hg abort
342 $ hg abort
343 abort: no interrupted graft to abort (abortflag !)
343 abort: no interrupted graft to abort (abortflag !)
344 abort: no operation in progress (abortcommand !)
344 abort: no operation in progress (abortcommand !)
345 [255]
345 [255]
346
346
347 when stripping is required
347 when stripping is required
348 $ hg graft -r 4 -r 5
348 $ hg graft -r 4 -r 5
349 grafting 4:863a25e1a9ea "added x"
349 grafting 4:863a25e1a9ea "added x"
350 grafting 5:36b793615f78 "added foo to c" (tip)
350 grafting 5:36b793615f78 "added foo to c" (tip)
351 merging c
351 merging c
352 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
352 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
353 abort: unresolved conflicts, can't continue
353 abort: unresolved conflicts, can't continue
354 (use 'hg resolve' and 'hg graft --continue')
354 (use 'hg resolve' and 'hg graft --continue')
355 [1]
355 [1]
356
356
357 $ hg graft --continue --abort
357 $ hg graft --continue --abort
358 abort: cannot specify both --abort and --continue
358 abort: cannot specify both --abort and --continue
359 [255]
359 [255]
360
360
361 $ hg graft --abort --stop
361 $ hg graft --abort --stop
362 abort: cannot specify both --abort and --stop
362 abort: cannot specify both --abort and --stop
363 [255]
363 [255]
364
364
365 $ hg graft --abort --currentuser
365 $ hg graft --abort --currentuser
366 abort: cannot specify both --abort and --user
366 abort: cannot specify both --abort and --user
367 [255]
367 [255]
368
368
369 $ hg graft --abort --edit
369 $ hg graft --abort --edit
370 abort: cannot specify both --abort and --edit
370 abort: cannot specify both --abort and --edit
371 [255]
371 [255]
372
372
373 #if abortcommand
373 #if abortcommand
374 when in dry-run mode
374 when in dry-run mode
375 $ hg abort --dry-run
375 $ hg abort --dry-run
376 graft in progress, will be aborted
376 graft in progress, will be aborted
377 #endif
377 #endif
378
378
379 $ hg abort
379 $ hg abort
380 graft aborted
380 graft aborted
381 working directory is now at 9150fe93bec6
381 working directory is now at 9150fe93bec6
382 $ hg log -GT "{rev}:{node|short} {desc}"
382 $ hg log -GT "{rev}:{node|short} {desc}"
383 o 5:36b793615f78 added foo to c
383 o 5:36b793615f78 added foo to c
384 |
384 |
385 | o 4:863a25e1a9ea added x
385 | o 4:863a25e1a9ea added x
386 |/
386 |/
387 | @ 3:9150fe93bec6 added d
387 | @ 3:9150fe93bec6 added d
388 | |
388 | |
389 | o 2:155349b645be added c
389 | o 2:155349b645be added c
390 |/
390 |/
391 o 1:5f6d8a4bf34a added b
391 o 1:5f6d8a4bf34a added b
392 |
392 |
393 o 0:9092f1db7931 added a
393 o 0:9092f1db7931 added a
394
394
395 when stripping is not required
395 when stripping is not required
396 $ hg graft -r 5
396 $ hg graft -r 5
397 grafting 5:36b793615f78 "added foo to c" (tip)
397 grafting 5:36b793615f78 "added foo to c" (tip)
398 merging c
398 merging c
399 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
399 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
400 abort: unresolved conflicts, can't continue
400 abort: unresolved conflicts, can't continue
401 (use 'hg resolve' and 'hg graft --continue')
401 (use 'hg resolve' and 'hg graft --continue')
402 [1]
402 [1]
403
403
404 $ hg abort
404 $ hg abort
405 graft aborted
405 graft aborted
406 working directory is now at 9150fe93bec6
406 working directory is now at 9150fe93bec6
407 $ hg log -GT "{rev}:{node|short} {desc}"
407 $ hg log -GT "{rev}:{node|short} {desc}"
408 o 5:36b793615f78 added foo to c
408 o 5:36b793615f78 added foo to c
409 |
409 |
410 | o 4:863a25e1a9ea added x
410 | o 4:863a25e1a9ea added x
411 |/
411 |/
412 | @ 3:9150fe93bec6 added d
412 | @ 3:9150fe93bec6 added d
413 | |
413 | |
414 | o 2:155349b645be added c
414 | o 2:155349b645be added c
415 |/
415 |/
416 o 1:5f6d8a4bf34a added b
416 o 1:5f6d8a4bf34a added b
417 |
417 |
418 o 0:9092f1db7931 added a
418 o 0:9092f1db7931 added a
419
419
420 when some of the changesets became public
420 when some of the changesets became public
421
421
422 $ hg graft -r 4 -r 5
422 $ hg graft -r 4 -r 5
423 grafting 4:863a25e1a9ea "added x"
423 grafting 4:863a25e1a9ea "added x"
424 grafting 5:36b793615f78 "added foo to c" (tip)
424 grafting 5:36b793615f78 "added foo to c" (tip)
425 merging c
425 merging c
426 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
426 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
427 abort: unresolved conflicts, can't continue
427 abort: unresolved conflicts, can't continue
428 (use 'hg resolve' and 'hg graft --continue')
428 (use 'hg resolve' and 'hg graft --continue')
429 [1]
429 [1]
430
430
431 $ hg log -GT "{rev}:{node|short} {desc}"
431 $ hg log -GT "{rev}:{node|short} {desc}"
432 @ 6:6ec71c037d94 added x
432 @ 6:6ec71c037d94 added x
433 |
433 |
434 | % 5:36b793615f78 added foo to c
434 | % 5:36b793615f78 added foo to c
435 | |
435 | |
436 | | o 4:863a25e1a9ea added x
436 | | o 4:863a25e1a9ea added x
437 | |/
437 | |/
438 o | 3:9150fe93bec6 added d
438 o | 3:9150fe93bec6 added d
439 | |
439 | |
440 o | 2:155349b645be added c
440 o | 2:155349b645be added c
441 |/
441 |/
442 o 1:5f6d8a4bf34a added b
442 o 1:5f6d8a4bf34a added b
443 |
443 |
444 o 0:9092f1db7931 added a
444 o 0:9092f1db7931 added a
445
445
446 $ hg phase -r 6 --public
446 $ hg phase -r 6 --public
447
447
448 $ hg abort
448 $ hg abort
449 cannot clean up public changesets 6ec71c037d94
449 cannot clean up public changesets 6ec71c037d94
450 graft aborted
450 graft aborted
451 working directory is now at 6ec71c037d94
451 working directory is now at 6ec71c037d94
452
452
453 when we created new changesets on top of existing one
453 when we created new changesets on top of existing one
454
454
455 $ hg up '.^^'
455 $ hg up '.^^'
456 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
456 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
457 $ echo y > y
457 $ echo y > y
458 $ hg ci -Aqm "added y"
458 $ hg ci -Aqm "added y"
459 $ echo z > z
459 $ echo z > z
460 $ hg ci -Aqm "added z"
460 $ hg ci -Aqm "added z"
461
461
462 $ hg up 3
462 $ hg up 3
463 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
463 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
464 $ hg log -GT "{rev}:{node|short} {desc}"
464 $ hg log -GT "{rev}:{node|short} {desc}"
465 o 8:637f9e9bbfd4 added z
465 o 8:637f9e9bbfd4 added z
466 |
466 |
467 o 7:123221671fd4 added y
467 o 7:123221671fd4 added y
468 |
468 |
469 | o 6:6ec71c037d94 added x
469 | o 6:6ec71c037d94 added x
470 | |
470 | |
471 | | o 5:36b793615f78 added foo to c
471 | | o 5:36b793615f78 added foo to c
472 | | |
472 | | |
473 | | | o 4:863a25e1a9ea added x
473 | | | o 4:863a25e1a9ea added x
474 | | |/
474 | | |/
475 | @ | 3:9150fe93bec6 added d
475 | @ | 3:9150fe93bec6 added d
476 |/ /
476 |/ /
477 o / 2:155349b645be added c
477 o / 2:155349b645be added c
478 |/
478 |/
479 o 1:5f6d8a4bf34a added b
479 o 1:5f6d8a4bf34a added b
480 |
480 |
481 o 0:9092f1db7931 added a
481 o 0:9092f1db7931 added a
482
482
483 $ hg graft -r 8 -r 7 -r 5
483 $ hg graft -r 8 -r 7 -r 5
484 grafting 8:637f9e9bbfd4 "added z" (tip)
484 grafting 8:637f9e9bbfd4 "added z" (tip)
485 grafting 7:123221671fd4 "added y"
485 grafting 7:123221671fd4 "added y"
486 grafting 5:36b793615f78 "added foo to c"
486 grafting 5:36b793615f78 "added foo to c"
487 merging c
487 merging c
488 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
488 warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
489 abort: unresolved conflicts, can't continue
489 abort: unresolved conflicts, can't continue
490 (use 'hg resolve' and 'hg graft --continue')
490 (use 'hg resolve' and 'hg graft --continue')
491 [1]
491 [1]
492
492
493 $ cd ..
493 $ cd ..
494 $ hg init pullrepo
494 $ hg init pullrepo
495 $ cd pullrepo
495 $ cd pullrepo
496 $ cat >> .hg/hgrc <<EOF
496 $ cat >> .hg/hgrc <<EOF
497 > [phases]
497 > [phases]
498 > publish=False
498 > publish=False
499 > EOF
499 > EOF
500 $ hg pull ../abortgraft --config phases.publish=False
500 $ hg pull ../abortgraft --config phases.publish=False
501 pulling from ../abortgraft
501 pulling from ../abortgraft
502 requesting all changes
502 requesting all changes
503 adding changesets
503 adding changesets
504 adding manifests
504 adding manifests
505 adding file changes
505 adding file changes
506 added 11 changesets with 9 changes to 8 files (+4 heads)
506 added 11 changesets with 9 changes to 8 files (+4 heads)
507 new changesets 9092f1db7931:6b98ff0062dd (6 drafts)
507 new changesets 9092f1db7931:6b98ff0062dd (6 drafts)
508 (run 'hg heads' to see heads, 'hg merge' to merge)
508 (run 'hg heads' to see heads, 'hg merge' to merge)
509 $ hg up 9
509 $ hg up 9
510 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
510 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
511 $ echo w > w
511 $ echo w > w
512 $ hg ci -Aqm "added w" --config phases.publish=False
512 $ hg ci -Aqm "added w" --config phases.publish=False
513
513
514 $ cd ../abortgraft
514 $ cd ../abortgraft
515 $ hg pull ../pullrepo
515 $ hg pull ../pullrepo
516 pulling from ../pullrepo
516 pulling from ../pullrepo
517 searching for changes
517 searching for changes
518 adding changesets
518 adding changesets
519 adding manifests
519 adding manifests
520 adding file changes
520 adding file changes
521 added 1 changesets with 1 changes to 1 files (+1 heads)
521 added 1 changesets with 1 changes to 1 files (+1 heads)
522 new changesets 311dfc6cf3bf (1 drafts)
522 new changesets 311dfc6cf3bf (1 drafts)
523 (run 'hg heads .' to see heads, 'hg merge' to merge)
523 (run 'hg heads .' to see heads, 'hg merge' to merge)
524
524
525 $ hg abort
525 $ hg abort
526 new changesets detected on destination branch, can't strip
526 new changesets detected on destination branch, can't strip
527 graft aborted
527 graft aborted
528 working directory is now at 6b98ff0062dd
528 working directory is now at 6b98ff0062dd
529
529
530 $ cd ..
530 $ cd ..
531
531
532 ============================
532 ============================
533 Testing --no-commit option:|
533 Testing --no-commit option:|
534 ============================
534 ============================
535
535
536 $ hg init nocommit
536 $ hg init nocommit
537 $ cd nocommit
537 $ cd nocommit
538 $ echo a > a
538 $ echo a > a
539 $ hg ci -qAma
539 $ hg ci -qAma
540 $ echo b > b
540 $ echo b > b
541 $ hg ci -qAmb
541 $ hg ci -qAmb
542 $ hg up -q 0
542 $ hg up -q 0
543 $ echo c > c
543 $ echo c > c
544 $ hg ci -qAmc
544 $ hg ci -qAmc
545 $ hg log -GT "{rev}:{node|short} {desc}\n"
545 $ hg log -GT "{rev}:{node|short} {desc}\n"
546 @ 2:d36c0562f908 c
546 @ 2:d36c0562f908 c
547 |
547 |
548 | o 1:d2ae7f538514 b
548 | o 1:d2ae7f538514 b
549 |/
549 |/
550 o 0:cb9a9f314b8b a
550 o 0:cb9a9f314b8b a
551
551
552
552
553 Check reporting when --no-commit used with non-applicable options:
553 Check reporting when --no-commit used with non-applicable options:
554
554
555 $ hg graft 1 --no-commit -e
555 $ hg graft 1 --no-commit -e
556 abort: cannot specify both --no-commit and --edit
556 abort: cannot specify both --no-commit and --edit
557 [255]
557 [255]
558
558
559 $ hg graft 1 --no-commit --log
559 $ hg graft 1 --no-commit --log
560 abort: cannot specify both --no-commit and --log
560 abort: cannot specify both --no-commit and --log
561 [255]
561 [255]
562
562
563 $ hg graft 1 --no-commit -D
563 $ hg graft 1 --no-commit -D
564 abort: cannot specify both --no-commit and --currentdate
564 abort: cannot specify both --no-commit and --currentdate
565 [255]
565 [255]
566
566
567 Test --no-commit is working:
567 Test --no-commit is working:
568 $ hg graft 1 --no-commit
568 $ hg graft 1 --no-commit
569 grafting 1:d2ae7f538514 "b"
569 grafting 1:d2ae7f538514 "b"
570
570
571 $ hg log -GT "{rev}:{node|short} {desc}\n"
571 $ hg log -GT "{rev}:{node|short} {desc}\n"
572 @ 2:d36c0562f908 c
572 @ 2:d36c0562f908 c
573 |
573 |
574 | o 1:d2ae7f538514 b
574 | o 1:d2ae7f538514 b
575 |/
575 |/
576 o 0:cb9a9f314b8b a
576 o 0:cb9a9f314b8b a
577
577
578
578
579 $ hg diff
579 $ hg diff
580 diff -r d36c0562f908 b
580 diff -r d36c0562f908 b
581 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
581 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
582 +++ b/b Thu Jan 01 00:00:00 1970 +0000
582 +++ b/b Thu Jan 01 00:00:00 1970 +0000
583 @@ -0,0 +1,1 @@
583 @@ -0,0 +1,1 @@
584 +b
584 +b
585
585
586 Prepare wrdir to check --no-commit is resepected after --continue:
586 Prepare wrdir to check --no-commit is resepected after --continue:
587
587
588 $ hg up -qC
588 $ hg up -qC
589 $ echo A>a
589 $ echo A>a
590 $ hg ci -qm "A in file a"
590 $ hg ci -qm "A in file a"
591 $ hg up -q 1
591 $ hg up -q 1
592 $ echo B>a
592 $ echo B>a
593 $ hg ci -qm "B in file a"
593 $ hg ci -qm "B in file a"
594 $ hg log -GT "{rev}:{node|short} {desc}\n"
594 $ hg log -GT "{rev}:{node|short} {desc}\n"
595 @ 4:2aa9ad1006ff B in file a
595 @ 4:2aa9ad1006ff B in file a
596 |
596 |
597 | o 3:09e253b87e17 A in file a
597 | o 3:09e253b87e17 A in file a
598 | |
598 | |
599 | o 2:d36c0562f908 c
599 | o 2:d36c0562f908 c
600 | |
600 | |
601 o | 1:d2ae7f538514 b
601 o | 1:d2ae7f538514 b
602 |/
602 |/
603 o 0:cb9a9f314b8b a
603 o 0:cb9a9f314b8b a
604
604
605
605
606 $ hg graft 3 --no-commit
606 $ hg graft 3 --no-commit
607 grafting 3:09e253b87e17 "A in file a"
607 grafting 3:09e253b87e17 "A in file a"
608 merging a
608 merging a
609 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
609 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
610 abort: unresolved conflicts, can't continue
610 abort: unresolved conflicts, can't continue
611 (use 'hg resolve' and 'hg graft --continue')
611 (use 'hg resolve' and 'hg graft --continue')
612 [1]
612 [1]
613
613
614 Resolve conflict:
614 Resolve conflict:
615 $ echo A>a
615 $ echo A>a
616 $ hg resolve --mark
616 $ hg resolve --mark
617 (no more unresolved files)
617 (no more unresolved files)
618 continue: hg graft --continue
618 continue: hg graft --continue
619
619
620 $ hg graft --continue
620 $ hg graft --continue
621 grafting 3:09e253b87e17 "A in file a"
621 grafting 3:09e253b87e17 "A in file a"
622 $ hg log -GT "{rev}:{node|short} {desc}\n"
622 $ hg log -GT "{rev}:{node|short} {desc}\n"
623 @ 4:2aa9ad1006ff B in file a
623 @ 4:2aa9ad1006ff B in file a
624 |
624 |
625 | % 3:09e253b87e17 A in file a
625 | o 3:09e253b87e17 A in file a
626 | |
626 | |
627 | o 2:d36c0562f908 c
627 | o 2:d36c0562f908 c
628 | |
628 | |
629 o | 1:d2ae7f538514 b
629 o | 1:d2ae7f538514 b
630 |/
630 |/
631 o 0:cb9a9f314b8b a
631 o 0:cb9a9f314b8b a
632
632
633 $ hg diff
633 $ hg diff
634 diff -r 2aa9ad1006ff a
634 diff -r 2aa9ad1006ff a
635 --- a/a Thu Jan 01 00:00:00 1970 +0000
635 --- a/a Thu Jan 01 00:00:00 1970 +0000
636 +++ b/a Thu Jan 01 00:00:00 1970 +0000
636 +++ b/a Thu Jan 01 00:00:00 1970 +0000
637 @@ -1,1 +1,1 @@
637 @@ -1,1 +1,1 @@
638 -B
638 -B
639 +A
639 +A
640
640
641 $ hg up -qC
641 $ hg up -qC
642
642
643 Check --no-commit is resepected when passed with --continue:
643 Check --no-commit is resepected when passed with --continue:
644
644
645 $ hg graft 3
645 $ hg graft 3
646 grafting 3:09e253b87e17 "A in file a"
646 grafting 3:09e253b87e17 "A in file a"
647 merging a
647 merging a
648 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
648 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
649 abort: unresolved conflicts, can't continue
649 abort: unresolved conflicts, can't continue
650 (use 'hg resolve' and 'hg graft --continue')
650 (use 'hg resolve' and 'hg graft --continue')
651 [1]
651 [1]
652
652
653 Resolve conflict:
653 Resolve conflict:
654 $ echo A>a
654 $ echo A>a
655 $ hg resolve --mark
655 $ hg resolve --mark
656 (no more unresolved files)
656 (no more unresolved files)
657 continue: hg graft --continue
657 continue: hg graft --continue
658
658
659 $ hg graft --continue --no-commit
659 $ hg graft --continue --no-commit
660 grafting 3:09e253b87e17 "A in file a"
660 grafting 3:09e253b87e17 "A in file a"
661 $ hg diff
661 $ hg diff
662 diff -r 2aa9ad1006ff a
662 diff -r 2aa9ad1006ff a
663 --- a/a Thu Jan 01 00:00:00 1970 +0000
663 --- a/a Thu Jan 01 00:00:00 1970 +0000
664 +++ b/a Thu Jan 01 00:00:00 1970 +0000
664 +++ b/a Thu Jan 01 00:00:00 1970 +0000
665 @@ -1,1 +1,1 @@
665 @@ -1,1 +1,1 @@
666 -B
666 -B
667 +A
667 +A
668
668
669 $ hg log -GT "{rev}:{node|short} {desc}\n"
669 $ hg log -GT "{rev}:{node|short} {desc}\n"
670 @ 4:2aa9ad1006ff B in file a
670 @ 4:2aa9ad1006ff B in file a
671 |
671 |
672 | % 3:09e253b87e17 A in file a
672 | o 3:09e253b87e17 A in file a
673 | |
673 | |
674 | o 2:d36c0562f908 c
674 | o 2:d36c0562f908 c
675 | |
675 | |
676 o | 1:d2ae7f538514 b
676 o | 1:d2ae7f538514 b
677 |/
677 |/
678 o 0:cb9a9f314b8b a
678 o 0:cb9a9f314b8b a
679
679
680 $ hg up -qC
680 $ hg up -qC
681
681
682 Test --no-commit when graft multiple revisions:
682 Test --no-commit when graft multiple revisions:
683 When there is conflict:
683 When there is conflict:
684 $ hg graft -r "2::3" --no-commit
684 $ hg graft -r "2::3" --no-commit
685 grafting 2:d36c0562f908 "c"
685 grafting 2:d36c0562f908 "c"
686 grafting 3:09e253b87e17 "A in file a"
686 grafting 3:09e253b87e17 "A in file a"
687 merging a
687 merging a
688 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
688 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
689 abort: unresolved conflicts, can't continue
689 abort: unresolved conflicts, can't continue
690 (use 'hg resolve' and 'hg graft --continue')
690 (use 'hg resolve' and 'hg graft --continue')
691 [1]
691 [1]
692
692
693 $ echo A>a
693 $ echo A>a
694 $ hg resolve --mark
694 $ hg resolve --mark
695 (no more unresolved files)
695 (no more unresolved files)
696 continue: hg graft --continue
696 continue: hg graft --continue
697 $ hg graft --continue
697 $ hg graft --continue
698 grafting 3:09e253b87e17 "A in file a"
698 grafting 3:09e253b87e17 "A in file a"
699 $ hg diff
699 $ hg diff
700 diff -r 2aa9ad1006ff a
700 diff -r 2aa9ad1006ff a
701 --- a/a Thu Jan 01 00:00:00 1970 +0000
701 --- a/a Thu Jan 01 00:00:00 1970 +0000
702 +++ b/a Thu Jan 01 00:00:00 1970 +0000
702 +++ b/a Thu Jan 01 00:00:00 1970 +0000
703 @@ -1,1 +1,1 @@
703 @@ -1,1 +1,1 @@
704 -B
704 -B
705 +A
705 +A
706 diff -r 2aa9ad1006ff c
706 diff -r 2aa9ad1006ff c
707 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
707 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
708 +++ b/c Thu Jan 01 00:00:00 1970 +0000
708 +++ b/c Thu Jan 01 00:00:00 1970 +0000
709 @@ -0,0 +1,1 @@
709 @@ -0,0 +1,1 @@
710 +c
710 +c
711
711
712 $ hg log -GT "{rev}:{node|short} {desc}\n"
712 $ hg log -GT "{rev}:{node|short} {desc}\n"
713 @ 4:2aa9ad1006ff B in file a
713 @ 4:2aa9ad1006ff B in file a
714 |
714 |
715 | % 3:09e253b87e17 A in file a
715 | o 3:09e253b87e17 A in file a
716 | |
716 | |
717 | o 2:d36c0562f908 c
717 | o 2:d36c0562f908 c
718 | |
718 | |
719 o | 1:d2ae7f538514 b
719 o | 1:d2ae7f538514 b
720 |/
720 |/
721 o 0:cb9a9f314b8b a
721 o 0:cb9a9f314b8b a
722
722
723 $ hg up -qC
723 $ hg up -qC
724
724
725 When there is no conflict:
725 When there is no conflict:
726 $ echo d>d
726 $ echo d>d
727 $ hg add d -q
727 $ hg add d -q
728 $ hg ci -qmd
728 $ hg ci -qmd
729 $ hg up 3 -q
729 $ hg up 3 -q
730 $ hg log -GT "{rev}:{node|short} {desc}\n"
730 $ hg log -GT "{rev}:{node|short} {desc}\n"
731 o 5:baefa8927fc0 d
731 o 5:baefa8927fc0 d
732 |
732 |
733 o 4:2aa9ad1006ff B in file a
733 o 4:2aa9ad1006ff B in file a
734 |
734 |
735 | @ 3:09e253b87e17 A in file a
735 | @ 3:09e253b87e17 A in file a
736 | |
736 | |
737 | o 2:d36c0562f908 c
737 | o 2:d36c0562f908 c
738 | |
738 | |
739 o | 1:d2ae7f538514 b
739 o | 1:d2ae7f538514 b
740 |/
740 |/
741 o 0:cb9a9f314b8b a
741 o 0:cb9a9f314b8b a
742
742
743
743
744 $ hg graft -r 1 -r 5 --no-commit
744 $ hg graft -r 1 -r 5 --no-commit
745 grafting 1:d2ae7f538514 "b"
745 grafting 1:d2ae7f538514 "b"
746 grafting 5:baefa8927fc0 "d" (tip)
746 grafting 5:baefa8927fc0 "d" (tip)
747 $ hg diff
747 $ hg diff
748 diff -r 09e253b87e17 b
748 diff -r 09e253b87e17 b
749 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
749 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
750 +++ b/b Thu Jan 01 00:00:00 1970 +0000
750 +++ b/b Thu Jan 01 00:00:00 1970 +0000
751 @@ -0,0 +1,1 @@
751 @@ -0,0 +1,1 @@
752 +b
752 +b
753 diff -r 09e253b87e17 d
753 diff -r 09e253b87e17 d
754 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
754 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
755 +++ b/d Thu Jan 01 00:00:00 1970 +0000
755 +++ b/d Thu Jan 01 00:00:00 1970 +0000
756 @@ -0,0 +1,1 @@
756 @@ -0,0 +1,1 @@
757 +d
757 +d
758 $ hg log -GT "{rev}:{node|short} {desc}\n"
758 $ hg log -GT "{rev}:{node|short} {desc}\n"
759 o 5:baefa8927fc0 d
759 o 5:baefa8927fc0 d
760 |
760 |
761 o 4:2aa9ad1006ff B in file a
761 o 4:2aa9ad1006ff B in file a
762 |
762 |
763 | @ 3:09e253b87e17 A in file a
763 | @ 3:09e253b87e17 A in file a
764 | |
764 | |
765 | o 2:d36c0562f908 c
765 | o 2:d36c0562f908 c
766 | |
766 | |
767 o | 1:d2ae7f538514 b
767 o | 1:d2ae7f538514 b
768 |/
768 |/
769 o 0:cb9a9f314b8b a
769 o 0:cb9a9f314b8b a
770
770
771 $ cd ..
771 $ cd ..
@@ -1,776 +1,776 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > rebase=
3 > rebase=
4 > mq=
4 > mq=
5 > drawdag=$TESTDIR/drawdag.py
5 > drawdag=$TESTDIR/drawdag.py
6 >
6 >
7 > [phases]
7 > [phases]
8 > publish=False
8 > publish=False
9 >
9 >
10 > [alias]
10 > [alias]
11 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
11 > tglog = log -G --template "{rev}: {node|short} '{desc}' {branches}\n"
12 > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n"
12 > tglogp = log -G --template "{rev}: {node|short} {phase} '{desc}' {branches}\n"
13 > EOF
13 > EOF
14
14
15 Highest phase of source commits is used:
15 Highest phase of source commits is used:
16
16
17 $ hg init phase
17 $ hg init phase
18 $ cd phase
18 $ cd phase
19 $ hg debugdrawdag << 'EOF'
19 $ hg debugdrawdag << 'EOF'
20 > D
20 > D
21 > |
21 > |
22 > F C
22 > F C
23 > | |
23 > | |
24 > E B
24 > E B
25 > |/
25 > |/
26 > A
26 > A
27 > EOF
27 > EOF
28
28
29 $ hg phase --force --secret D
29 $ hg phase --force --secret D
30
30
31 $ cat > $TESTTMP/editor.sh <<EOF
31 $ cat > $TESTTMP/editor.sh <<EOF
32 > echo "==== before editing"
32 > echo "==== before editing"
33 > cat \$1
33 > cat \$1
34 > echo "===="
34 > echo "===="
35 > echo "edited manually" >> \$1
35 > echo "edited manually" >> \$1
36 > EOF
36 > EOF
37 $ HGEDITOR="sh $TESTTMP/editor.sh" hg rebase --collapse --keepbranches -e --source B --dest F
37 $ HGEDITOR="sh $TESTTMP/editor.sh" hg rebase --collapse --keepbranches -e --source B --dest F
38 rebasing 1:112478962961 "B" (B)
38 rebasing 1:112478962961 "B" (B)
39 rebasing 3:26805aba1e60 "C" (C)
39 rebasing 3:26805aba1e60 "C" (C)
40 rebasing 5:f585351a92f8 "D" (D tip)
40 rebasing 5:f585351a92f8 "D" (D tip)
41 ==== before editing
41 ==== before editing
42 Collapsed revision
42 Collapsed revision
43 * B
43 * B
44 * C
44 * C
45 * D
45 * D
46
46
47
47
48 HG: Enter commit message. Lines beginning with 'HG:' are removed.
48 HG: Enter commit message. Lines beginning with 'HG:' are removed.
49 HG: Leave message empty to abort commit.
49 HG: Leave message empty to abort commit.
50 HG: --
50 HG: --
51 HG: user: test
51 HG: user: test
52 HG: branch 'default'
52 HG: branch 'default'
53 HG: added B
53 HG: added B
54 HG: added C
54 HG: added C
55 HG: added D
55 HG: added D
56 ====
56 ====
57 saved backup bundle to $TESTTMP/phase/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
57 saved backup bundle to $TESTTMP/phase/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
58
58
59 $ hg tglogp
59 $ hg tglogp
60 o 3: 92fa5f5fe108 secret 'Collapsed revision
60 o 3: 92fa5f5fe108 secret 'Collapsed revision
61 | * B
61 | * B
62 | * C
62 | * C
63 | * D
63 | * D
64 |
64 |
65 |
65 |
66 | edited manually'
66 | edited manually'
67 o 2: 64a8289d2492 draft 'F'
67 o 2: 64a8289d2492 draft 'F'
68 |
68 |
69 o 1: 7fb047a69f22 draft 'E'
69 o 1: 7fb047a69f22 draft 'E'
70 |
70 |
71 o 0: 426bada5c675 draft 'A'
71 o 0: 426bada5c675 draft 'A'
72
72
73 $ hg manifest --rev tip
73 $ hg manifest --rev tip
74 A
74 A
75 B
75 B
76 C
76 C
77 D
77 D
78 E
78 E
79 F
79 F
80
80
81 $ cd ..
81 $ cd ..
82
82
83
83
84 Merge gets linearized:
84 Merge gets linearized:
85
85
86 $ hg init linearized-merge
86 $ hg init linearized-merge
87 $ cd linearized-merge
87 $ cd linearized-merge
88
88
89 $ hg debugdrawdag << 'EOF'
89 $ hg debugdrawdag << 'EOF'
90 > F D
90 > F D
91 > |/|
91 > |/|
92 > C B
92 > C B
93 > |/
93 > |/
94 > A
94 > A
95 > EOF
95 > EOF
96
96
97 $ hg phase --force --secret D
97 $ hg phase --force --secret D
98 $ hg rebase --source B --collapse --dest F
98 $ hg rebase --source B --collapse --dest F
99 rebasing 1:112478962961 "B" (B)
99 rebasing 1:112478962961 "B" (B)
100 rebasing 3:4e4f9194f9f1 "D" (D)
100 rebasing 3:4e4f9194f9f1 "D" (D)
101 saved backup bundle to $TESTTMP/linearized-merge/.hg/strip-backup/112478962961-e389075b-rebase.hg
101 saved backup bundle to $TESTTMP/linearized-merge/.hg/strip-backup/112478962961-e389075b-rebase.hg
102
102
103 $ hg tglog
103 $ hg tglog
104 o 3: 5bdc08b7da2b 'Collapsed revision
104 o 3: 5bdc08b7da2b 'Collapsed revision
105 | * B
105 | * B
106 | * D'
106 | * D'
107 o 2: afc707c82df0 'F'
107 o 2: afc707c82df0 'F'
108 |
108 |
109 o 1: dc0947a82db8 'C'
109 o 1: dc0947a82db8 'C'
110 |
110 |
111 o 0: 426bada5c675 'A'
111 o 0: 426bada5c675 'A'
112
112
113 $ hg manifest --rev tip
113 $ hg manifest --rev tip
114 A
114 A
115 B
115 B
116 C
116 C
117 F
117 F
118
118
119 $ cd ..
119 $ cd ..
120
120
121 Custom message:
121 Custom message:
122
122
123 $ hg init message
123 $ hg init message
124 $ cd message
124 $ cd message
125
125
126 $ hg debugdrawdag << 'EOF'
126 $ hg debugdrawdag << 'EOF'
127 > C
127 > C
128 > |
128 > |
129 > D B
129 > D B
130 > |/
130 > |/
131 > A
131 > A
132 > EOF
132 > EOF
133
133
134
134
135 $ hg rebase --base B -m 'custom message'
135 $ hg rebase --base B -m 'custom message'
136 abort: message can only be specified with collapse
136 abort: message can only be specified with collapse
137 [255]
137 [255]
138
138
139 $ cat > $TESTTMP/checkeditform.sh <<EOF
139 $ cat > $TESTTMP/checkeditform.sh <<EOF
140 > env | grep HGEDITFORM
140 > env | grep HGEDITFORM
141 > true
141 > true
142 > EOF
142 > EOF
143 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --source B --collapse -m 'custom message' -e --dest D
143 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --source B --collapse -m 'custom message' -e --dest D
144 rebasing 1:112478962961 "B" (B)
144 rebasing 1:112478962961 "B" (B)
145 rebasing 3:26805aba1e60 "C" (C tip)
145 rebasing 3:26805aba1e60 "C" (C tip)
146 HGEDITFORM=rebase.collapse
146 HGEDITFORM=rebase.collapse
147 saved backup bundle to $TESTTMP/message/.hg/strip-backup/112478962961-f4131707-rebase.hg
147 saved backup bundle to $TESTTMP/message/.hg/strip-backup/112478962961-f4131707-rebase.hg
148
148
149 $ hg tglog
149 $ hg tglog
150 o 2: 2f197b9a08f3 'custom message'
150 o 2: 2f197b9a08f3 'custom message'
151 |
151 |
152 o 1: b18e25de2cf5 'D'
152 o 1: b18e25de2cf5 'D'
153 |
153 |
154 o 0: 426bada5c675 'A'
154 o 0: 426bada5c675 'A'
155
155
156 $ hg manifest --rev tip
156 $ hg manifest --rev tip
157 A
157 A
158 B
158 B
159 C
159 C
160 D
160 D
161
161
162 $ cd ..
162 $ cd ..
163
163
164 Rebase and collapse - more than one external (fail):
164 Rebase and collapse - more than one external (fail):
165
165
166 $ hg init multiple-external-parents
166 $ hg init multiple-external-parents
167 $ cd multiple-external-parents
167 $ cd multiple-external-parents
168
168
169 $ hg debugdrawdag << 'EOF'
169 $ hg debugdrawdag << 'EOF'
170 > G
170 > G
171 > |\
171 > |\
172 > | F
172 > | F
173 > | |
173 > | |
174 > D E
174 > D E
175 > |\|
175 > |\|
176 > H C B
176 > H C B
177 > \|/
177 > \|/
178 > A
178 > A
179 > EOF
179 > EOF
180
180
181 $ hg rebase -s C --dest H --collapse
181 $ hg rebase -s C --dest H --collapse
182 abort: unable to collapse on top of 3, there is more than one external parent: 1, 6
182 abort: unable to collapse on top of 3, there is more than one external parent: 1, 6
183 [255]
183 [255]
184
184
185 Rebase and collapse - E onto H:
185 Rebase and collapse - E onto H:
186
186
187 $ hg rebase -s E --dest H --collapse # root (E) is not a merge
187 $ hg rebase -s E --dest H --collapse # root (E) is not a merge
188 rebasing 5:49cb92066bfd "E" (E)
188 rebasing 5:49cb92066bfd "E" (E)
189 rebasing 6:11abe3fb10b8 "F" (F)
189 rebasing 6:11abe3fb10b8 "F" (F)
190 rebasing 7:64e264db77f0 "G" (G tip)
190 rebasing 7:64e264db77f0 "G" (G tip)
191 saved backup bundle to $TESTTMP/multiple-external-parents/.hg/strip-backup/49cb92066bfd-ee8a8a79-rebase.hg
191 saved backup bundle to $TESTTMP/multiple-external-parents/.hg/strip-backup/49cb92066bfd-ee8a8a79-rebase.hg
192
192
193 $ hg tglog
193 $ hg tglog
194 o 5: 8b2315790719 'Collapsed revision
194 o 5: 8b2315790719 'Collapsed revision
195 |\ * E
195 |\ * E
196 | | * F
196 | | * F
197 | | * G'
197 | | * G'
198 | o 4: 4e4f9194f9f1 'D'
198 | o 4: 4e4f9194f9f1 'D'
199 | |\
199 | |\
200 o | | 3: 575c4b5ec114 'H'
200 o | | 3: 575c4b5ec114 'H'
201 | | |
201 | | |
202 +---o 2: dc0947a82db8 'C'
202 +---o 2: dc0947a82db8 'C'
203 | |
203 | |
204 | o 1: 112478962961 'B'
204 | o 1: 112478962961 'B'
205 |/
205 |/
206 o 0: 426bada5c675 'A'
206 o 0: 426bada5c675 'A'
207
207
208 $ hg manifest --rev tip
208 $ hg manifest --rev tip
209 A
209 A
210 C
210 C
211 E
211 E
212 F
212 F
213 H
213 H
214
214
215 $ cd ..
215 $ cd ..
216
216
217
217
218
218
219
219
220 Test that branchheads cache is updated correctly when doing a strip in which
220 Test that branchheads cache is updated correctly when doing a strip in which
221 the parent of the ancestor node to be stripped does not become a head and also,
221 the parent of the ancestor node to be stripped does not become a head and also,
222 the parent of a node that is a child of the node stripped becomes a head (node
222 the parent of a node that is a child of the node stripped becomes a head (node
223 3). The code is now much simpler and we could just test a simpler scenario
223 3). The code is now much simpler and we could just test a simpler scenario
224 We keep it the test this way in case new complexity is injected.
224 We keep it the test this way in case new complexity is injected.
225
225
226 Create repo b:
226 Create repo b:
227
227
228 $ hg init branch-heads
228 $ hg init branch-heads
229 $ cd branch-heads
229 $ cd branch-heads
230
230
231 $ hg debugdrawdag << 'EOF'
231 $ hg debugdrawdag << 'EOF'
232 > G
232 > G
233 > |\
233 > |\
234 > | F
234 > | F
235 > | |
235 > | |
236 > D E
236 > D E
237 > |\|
237 > |\|
238 > H C B
238 > H C B
239 > \|/
239 > \|/
240 > A
240 > A
241 > EOF
241 > EOF
242
242
243 $ hg heads --template="{rev}:{node} {branch}\n"
243 $ hg heads --template="{rev}:{node} {branch}\n"
244 7:64e264db77f061f16d9132b70c5a58e2461fb630 default
244 7:64e264db77f061f16d9132b70c5a58e2461fb630 default
245 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
245 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
246
246
247 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
247 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
248 64e264db77f061f16d9132b70c5a58e2461fb630 7
248 64e264db77f061f16d9132b70c5a58e2461fb630 7
249 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
249 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
250 64e264db77f061f16d9132b70c5a58e2461fb630 o default
250 64e264db77f061f16d9132b70c5a58e2461fb630 o default
251
251
252 $ hg strip 4
252 $ hg strip 4
253 saved backup bundle to $TESTTMP/branch-heads/.hg/strip-backup/4e4f9194f9f1-5ec4b5e6-backup.hg
253 saved backup bundle to $TESTTMP/branch-heads/.hg/strip-backup/4e4f9194f9f1-5ec4b5e6-backup.hg
254
254
255 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
255 $ cat $TESTTMP/branch-heads/.hg/cache/branch2-served
256 11abe3fb10b8689b560681094b17fe161871d043 5
256 11abe3fb10b8689b560681094b17fe161871d043 5
257 dc0947a82db884575bb76ea10ac97b08536bfa03 o default
257 dc0947a82db884575bb76ea10ac97b08536bfa03 o default
258 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
258 575c4b5ec114d64b681d33f8792853568bfb2b2c o default
259 11abe3fb10b8689b560681094b17fe161871d043 o default
259 11abe3fb10b8689b560681094b17fe161871d043 o default
260
260
261 $ hg heads --template="{rev}:{node} {branch}\n"
261 $ hg heads --template="{rev}:{node} {branch}\n"
262 5:11abe3fb10b8689b560681094b17fe161871d043 default
262 5:11abe3fb10b8689b560681094b17fe161871d043 default
263 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
263 3:575c4b5ec114d64b681d33f8792853568bfb2b2c default
264 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default
264 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default
265
265
266 $ cd ..
266 $ cd ..
267
267
268
268
269
269
270 Preserves external parent
270 Preserves external parent
271
271
272 $ hg init external-parent
272 $ hg init external-parent
273 $ cd external-parent
273 $ cd external-parent
274
274
275 $ hg debugdrawdag << 'EOF'
275 $ hg debugdrawdag << 'EOF'
276 > H
276 > H
277 > |\
277 > |\
278 > | G
278 > | G
279 > | |
279 > | |
280 > | F # F/E = F\n
280 > | F # F/E = F\n
281 > | |
281 > | |
282 > D E # D/D = D\n
282 > D E # D/D = D\n
283 > |\|
283 > |\|
284 > I C B
284 > I C B
285 > \|/
285 > \|/
286 > A
286 > A
287 > EOF
287 > EOF
288
288
289 $ hg rebase -s F --dest I --collapse # root (F) is not a merge
289 $ hg rebase -s F --dest I --collapse # root (F) is not a merge
290 rebasing 6:c82b08f646f1 "F" (F)
290 rebasing 6:c82b08f646f1 "F" (F)
291 file 'E' was deleted in local [dest] but was modified in other [source].
291 file 'E' was deleted in local [dest] but was modified in other [source].
292 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
292 You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
293 What do you want to do? u
293 What do you want to do? u
294 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
294 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
295 [1]
295 [1]
296
296
297 $ echo F > E
297 $ echo F > E
298 $ hg resolve -m
298 $ hg resolve -m
299 (no more unresolved files)
299 (no more unresolved files)
300 continue: hg rebase --continue
300 continue: hg rebase --continue
301 $ hg rebase -c
301 $ hg rebase -c
302 rebasing 6:c82b08f646f1 "F" (F)
302 rebasing 6:c82b08f646f1 "F" (F)
303 rebasing 7:a6db7fa104e1 "G" (G)
303 rebasing 7:a6db7fa104e1 "G" (G)
304 rebasing 8:e1d201b72d91 "H" (H tip)
304 rebasing 8:e1d201b72d91 "H" (H tip)
305 saved backup bundle to $TESTTMP/external-parent/.hg/strip-backup/c82b08f646f1-f2721fbf-rebase.hg
305 saved backup bundle to $TESTTMP/external-parent/.hg/strip-backup/c82b08f646f1-f2721fbf-rebase.hg
306
306
307 $ hg tglog
307 $ hg tglog
308 o 6: 681daa3e686d 'Collapsed revision
308 o 6: 681daa3e686d 'Collapsed revision
309 |\ * F
309 |\ * F
310 | | * G
310 | | * G
311 | | * H'
311 | | * H'
312 | | o 5: 49cb92066bfd 'E'
312 | | o 5: 49cb92066bfd 'E'
313 | | |
313 | | |
314 | o | 4: 09143c0bf13e 'D'
314 | o | 4: 09143c0bf13e 'D'
315 | |\|
315 | |\|
316 o | | 3: 08ebfeb61bac 'I'
316 o | | 3: 08ebfeb61bac 'I'
317 | | |
317 | | |
318 | o | 2: dc0947a82db8 'C'
318 | o | 2: dc0947a82db8 'C'
319 |/ /
319 |/ /
320 | o 1: 112478962961 'B'
320 | o 1: 112478962961 'B'
321 |/
321 |/
322 o 0: 426bada5c675 'A'
322 o 0: 426bada5c675 'A'
323
323
324 $ hg manifest --rev tip
324 $ hg manifest --rev tip
325 A
325 A
326 C
326 C
327 D
327 D
328 E
328 E
329 F
329 F
330 G
330 G
331 I
331 I
332
332
333 $ hg up tip -q
333 $ hg up tip -q
334 $ cat E
334 $ cat E
335 F
335 F
336
336
337 $ cd ..
337 $ cd ..
338
338
339 Rebasing from multiple bases:
339 Rebasing from multiple bases:
340
340
341 $ hg init multiple-bases
341 $ hg init multiple-bases
342 $ cd multiple-bases
342 $ cd multiple-bases
343 $ hg debugdrawdag << 'EOF'
343 $ hg debugdrawdag << 'EOF'
344 > C B
344 > C B
345 > D |/
345 > D |/
346 > |/
346 > |/
347 > A
347 > A
348 > EOF
348 > EOF
349 $ hg rebase --collapse -r 'B+C' -d D
349 $ hg rebase --collapse -r 'B+C' -d D
350 rebasing 1:fc2b737bb2e5 "B" (B)
350 rebasing 1:fc2b737bb2e5 "B" (B)
351 rebasing 2:dc0947a82db8 "C" (C)
351 rebasing 2:dc0947a82db8 "C" (C)
352 saved backup bundle to $TESTTMP/multiple-bases/.hg/strip-backup/dc0947a82db8-b0c1a7ea-rebase.hg
352 saved backup bundle to $TESTTMP/multiple-bases/.hg/strip-backup/dc0947a82db8-b0c1a7ea-rebase.hg
353 $ hg tglog
353 $ hg tglog
354 o 2: 2127ae44d291 'Collapsed revision
354 o 2: 2127ae44d291 'Collapsed revision
355 | * B
355 | * B
356 | * C'
356 | * C'
357 o 1: b18e25de2cf5 'D'
357 o 1: b18e25de2cf5 'D'
358 |
358 |
359 o 0: 426bada5c675 'A'
359 o 0: 426bada5c675 'A'
360
360
361 $ cd ..
361 $ cd ..
362
362
363 With non-contiguous commits:
363 With non-contiguous commits:
364
364
365 $ hg init non-contiguous
365 $ hg init non-contiguous
366 $ cd non-contiguous
366 $ cd non-contiguous
367 $ cat >> .hg/hgrc <<EOF
367 $ cat >> .hg/hgrc <<EOF
368 > [experimental]
368 > [experimental]
369 > evolution=all
369 > evolution=all
370 > EOF
370 > EOF
371
371
372 $ hg debugdrawdag << 'EOF'
372 $ hg debugdrawdag << 'EOF'
373 > F
373 > F
374 > |
374 > |
375 > E
375 > E
376 > |
376 > |
377 > D
377 > D
378 > |
378 > |
379 > C
379 > C
380 > |
380 > |
381 > B G
381 > B G
382 > |/
382 > |/
383 > A
383 > A
384 > EOF
384 > EOF
385
385
386 BROKEN: should be allowed
386 BROKEN: should be allowed
387 $ hg rebase --collapse -r 'B+D+F' -d G
387 $ hg rebase --collapse -r 'B+D+F' -d G
388 abort: unable to collapse on top of 2, there is more than one external parent: 3, 5
388 abort: unable to collapse on top of 2, there is more than one external parent: 3, 5
389 [255]
389 [255]
390 $ cd ..
390 $ cd ..
391
391
392
392
393 $ hg init multiple-external-parents-2
393 $ hg init multiple-external-parents-2
394 $ cd multiple-external-parents-2
394 $ cd multiple-external-parents-2
395 $ hg debugdrawdag << 'EOF'
395 $ hg debugdrawdag << 'EOF'
396 > D G
396 > D G
397 > |\ /|
397 > |\ /|
398 > B C E F
398 > B C E F
399 > \| |/
399 > \| |/
400 > \ H /
400 > \ H /
401 > \|/
401 > \|/
402 > A
402 > A
403 > EOF
403 > EOF
404
404
405 $ hg rebase --collapse -d H -s 'B+F'
405 $ hg rebase --collapse -d H -s 'B+F'
406 abort: unable to collapse on top of 5, there is more than one external parent: 1, 3
406 abort: unable to collapse on top of 5, there is more than one external parent: 1, 3
407 [255]
407 [255]
408 $ cd ..
408 $ cd ..
409
409
410 With internal merge:
410 With internal merge:
411
411
412 $ hg init internal-merge
412 $ hg init internal-merge
413 $ cd internal-merge
413 $ cd internal-merge
414
414
415 $ hg debugdrawdag << 'EOF'
415 $ hg debugdrawdag << 'EOF'
416 > E
416 > E
417 > |\
417 > |\
418 > C D
418 > C D
419 > |/
419 > |/
420 > F B
420 > F B
421 > |/
421 > |/
422 > A
422 > A
423 > EOF
423 > EOF
424
424
425
425
426 $ hg rebase -s B --collapse --dest F
426 $ hg rebase -s B --collapse --dest F
427 rebasing 1:112478962961 "B" (B)
427 rebasing 1:112478962961 "B" (B)
428 rebasing 3:26805aba1e60 "C" (C)
428 rebasing 3:26805aba1e60 "C" (C)
429 rebasing 4:be0ef73c17ad "D" (D)
429 rebasing 4:be0ef73c17ad "D" (D)
430 rebasing 5:02c4367d6973 "E" (E tip)
430 rebasing 5:02c4367d6973 "E" (E tip)
431 saved backup bundle to $TESTTMP/internal-merge/.hg/strip-backup/112478962961-1dfb057b-rebase.hg
431 saved backup bundle to $TESTTMP/internal-merge/.hg/strip-backup/112478962961-1dfb057b-rebase.hg
432
432
433 $ hg tglog
433 $ hg tglog
434 o 2: c0512a1797b0 'Collapsed revision
434 o 2: c0512a1797b0 'Collapsed revision
435 | * B
435 | * B
436 | * C
436 | * C
437 | * D
437 | * D
438 | * E'
438 | * E'
439 o 1: 8908a377a434 'F'
439 o 1: 8908a377a434 'F'
440 |
440 |
441 o 0: 426bada5c675 'A'
441 o 0: 426bada5c675 'A'
442
442
443 $ hg manifest --rev tip
443 $ hg manifest --rev tip
444 A
444 A
445 B
445 B
446 C
446 C
447 D
447 D
448 F
448 F
449 $ cd ..
449 $ cd ..
450
450
451 Interactions between collapse and keepbranches
451 Interactions between collapse and keepbranches
452 $ hg init e
452 $ hg init e
453 $ cd e
453 $ cd e
454 $ echo 'a' > a
454 $ echo 'a' > a
455 $ hg ci -Am 'A'
455 $ hg ci -Am 'A'
456 adding a
456 adding a
457
457
458 $ hg branch 'one'
458 $ hg branch 'one'
459 marked working directory as branch one
459 marked working directory as branch one
460 (branches are permanent and global, did you want a bookmark?)
460 (branches are permanent and global, did you want a bookmark?)
461 $ echo 'b' > b
461 $ echo 'b' > b
462 $ hg ci -Am 'B'
462 $ hg ci -Am 'B'
463 adding b
463 adding b
464
464
465 $ hg branch 'two'
465 $ hg branch 'two'
466 marked working directory as branch two
466 marked working directory as branch two
467 $ echo 'c' > c
467 $ echo 'c' > c
468 $ hg ci -Am 'C'
468 $ hg ci -Am 'C'
469 adding c
469 adding c
470
470
471 $ hg up -q 0
471 $ hg up -q 0
472 $ echo 'd' > d
472 $ echo 'd' > d
473 $ hg ci -Am 'D'
473 $ hg ci -Am 'D'
474 adding d
474 adding d
475
475
476 $ hg tglog
476 $ hg tglog
477 @ 3: 41acb9dca9eb 'D'
477 @ 3: 41acb9dca9eb 'D'
478 |
478 |
479 | o 2: 8ac4a08debf1 'C' two
479 | o 2: 8ac4a08debf1 'C' two
480 | |
480 | |
481 | o 1: 1ba175478953 'B' one
481 | o 1: 1ba175478953 'B' one
482 |/
482 |/
483 o 0: 1994f17a630e 'A'
483 o 0: 1994f17a630e 'A'
484
484
485 $ hg rebase --keepbranches --collapse -s 1 -d 3
485 $ hg rebase --keepbranches --collapse -s 1 -d 3
486 abort: cannot collapse multiple named branches
486 abort: cannot collapse multiple named branches
487 [255]
487 [255]
488
488
489 $ cd ..
489 $ cd ..
490
490
491 Rebase, collapse and copies
491 Rebase, collapse and copies
492
492
493 $ hg init copies
493 $ hg init copies
494 $ cd copies
494 $ cd copies
495 $ hg unbundle "$TESTDIR/bundles/renames.hg"
495 $ hg unbundle "$TESTDIR/bundles/renames.hg"
496 adding changesets
496 adding changesets
497 adding manifests
497 adding manifests
498 adding file changes
498 adding file changes
499 added 4 changesets with 11 changes to 7 files (+1 heads)
499 added 4 changesets with 11 changes to 7 files (+1 heads)
500 new changesets f447d5abf5ea:338e84e2e558 (4 drafts)
500 new changesets f447d5abf5ea:338e84e2e558 (4 drafts)
501 (run 'hg heads' to see heads, 'hg merge' to merge)
501 (run 'hg heads' to see heads, 'hg merge' to merge)
502 $ hg up -q tip
502 $ hg up -q tip
503 $ hg tglog
503 $ hg tglog
504 @ 3: 338e84e2e558 'move2'
504 @ 3: 338e84e2e558 'move2'
505 |
505 |
506 o 2: 6e7340ee38c0 'move1'
506 o 2: 6e7340ee38c0 'move1'
507 |
507 |
508 | o 1: 1352765a01d4 'change'
508 | o 1: 1352765a01d4 'change'
509 |/
509 |/
510 o 0: f447d5abf5ea 'add'
510 o 0: f447d5abf5ea 'add'
511
511
512 $ hg rebase --collapse -d 1
512 $ hg rebase --collapse -d 1
513 rebasing 2:6e7340ee38c0 "move1"
513 rebasing 2:6e7340ee38c0 "move1"
514 merging a and d to d
514 merging a and d to d
515 merging b and e to e
515 merging b and e to e
516 merging c and f to f
516 merging c and f to f
517 rebasing 3:338e84e2e558 "move2" (tip)
517 rebasing 3:338e84e2e558 "move2" (tip)
518 merging f and c to c
518 merging f and c to c
519 merging e and g to g
519 merging e and g to g
520 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/6e7340ee38c0-ef8ef003-rebase.hg
520 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/6e7340ee38c0-ef8ef003-rebase.hg
521 $ hg st
521 $ hg st
522 $ hg st --copies --change tip
522 $ hg st --copies --change tip
523 A d
523 A d
524 a
524 a
525 A g
525 A g
526 b
526 b
527 R b
527 R b
528 $ hg up tip -q
528 $ hg up tip -q
529 $ cat c
529 $ cat c
530 c
530 c
531 c
531 c
532 $ cat d
532 $ cat d
533 a
533 a
534 a
534 a
535 $ cat g
535 $ cat g
536 b
536 b
537 b
537 b
538 $ hg log -r . --template "{file_copies}\n"
538 $ hg log -r . --template "{file_copies}\n"
539 d (a)g (b)
539 d (a)g (b)
540
540
541 Test collapsing a middle revision in-place
541 Test collapsing a middle revision in-place
542
542
543 $ hg tglog
543 $ hg tglog
544 @ 2: 64b456429f67 'Collapsed revision
544 @ 2: 64b456429f67 'Collapsed revision
545 | * move1
545 | * move1
546 | * move2'
546 | * move2'
547 o 1: 1352765a01d4 'change'
547 o 1: 1352765a01d4 'change'
548 |
548 |
549 o 0: f447d5abf5ea 'add'
549 o 0: f447d5abf5ea 'add'
550
550
551 $ hg rebase --collapse -r 1 -d 0
551 $ hg rebase --collapse -r 1 -d 0
552 abort: cannot rebase changeset with children
552 abort: cannot rebase changeset with children
553 (use --keep to keep original changesets)
553 (use --keep to keep original changesets)
554 [255]
554 [255]
555
555
556 Test collapsing in place
556 Test collapsing in place
557
557
558 $ hg rebase --collapse -b . -d 0
558 $ hg rebase --collapse -b . -d 0
559 rebasing 1:1352765a01d4 "change"
559 rebasing 1:1352765a01d4 "change"
560 rebasing 2:64b456429f67 "Collapsed revision" (tip)
560 rebasing 2:64b456429f67 "Collapsed revision" (tip)
561 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/1352765a01d4-45a352ea-rebase.hg
561 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/1352765a01d4-45a352ea-rebase.hg
562 $ hg st --change tip --copies
562 $ hg st --change tip --copies
563 M a
563 M a
564 M c
564 M c
565 A d
565 A d
566 a
566 a
567 A g
567 A g
568 b
568 b
569 R b
569 R b
570 $ hg up tip -q
570 $ hg up tip -q
571 $ cat a
571 $ cat a
572 a
572 a
573 a
573 a
574 $ cat c
574 $ cat c
575 c
575 c
576 c
576 c
577 $ cat d
577 $ cat d
578 a
578 a
579 a
579 a
580 $ cat g
580 $ cat g
581 b
581 b
582 b
582 b
583 $ cd ..
583 $ cd ..
584
584
585
585
586 Test stripping a revision with another child
586 Test stripping a revision with another child
587
587
588 $ hg init f
588 $ hg init f
589 $ cd f
589 $ cd f
590
590
591 $ hg debugdrawdag << 'EOF'
591 $ hg debugdrawdag << 'EOF'
592 > C B
592 > C B
593 > |/
593 > |/
594 > A
594 > A
595 > EOF
595 > EOF
596
596
597 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
597 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
598 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default: C
598 2:dc0947a82db884575bb76ea10ac97b08536bfa03 default: C
599 1:112478962961147124edd43549aedd1a335e44bf default: B
599 1:112478962961147124edd43549aedd1a335e44bf default: B
600
600
601 $ hg strip C
601 $ hg strip C
602 saved backup bundle to $TESTTMP/f/.hg/strip-backup/dc0947a82db8-d21b92a4-backup.hg
602 saved backup bundle to $TESTTMP/f/.hg/strip-backup/dc0947a82db8-d21b92a4-backup.hg
603
603
604 $ hg tglog
604 $ hg tglog
605 o 1: 112478962961 'B'
605 o 1: 112478962961 'B'
606 |
606 |
607 o 0: 426bada5c675 'A'
607 o 0: 426bada5c675 'A'
608
608
609
609
610
610
611 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
611 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
612 1:112478962961147124edd43549aedd1a335e44bf default: B
612 1:112478962961147124edd43549aedd1a335e44bf default: B
613
613
614 $ cd ..
614 $ cd ..
615
615
616 Test collapsing changes that add then remove a file
616 Test collapsing changes that add then remove a file
617
617
618 $ hg init collapseaddremove
618 $ hg init collapseaddremove
619 $ cd collapseaddremove
619 $ cd collapseaddremove
620
620
621 $ touch base
621 $ touch base
622 $ hg commit -Am base
622 $ hg commit -Am base
623 adding base
623 adding base
624 $ touch a
624 $ touch a
625 $ hg commit -Am a
625 $ hg commit -Am a
626 adding a
626 adding a
627 $ hg rm a
627 $ hg rm a
628 $ touch b
628 $ touch b
629 $ hg commit -Am b
629 $ hg commit -Am b
630 adding b
630 adding b
631 $ hg book foo
631 $ hg book foo
632 $ hg rebase -d 0 -r "1::2" --collapse -m collapsed
632 $ hg rebase -d 0 -r "1::2" --collapse -m collapsed
633 rebasing 1:6d8d9f24eec3 "a"
633 rebasing 1:6d8d9f24eec3 "a"
634 rebasing 2:1cc73eca5ecc "b" (foo tip)
634 rebasing 2:1cc73eca5ecc "b" (foo tip)
635 saved backup bundle to $TESTTMP/collapseaddremove/.hg/strip-backup/6d8d9f24eec3-77d3b6e2-rebase.hg
635 saved backup bundle to $TESTTMP/collapseaddremove/.hg/strip-backup/6d8d9f24eec3-77d3b6e2-rebase.hg
636 $ hg log -G --template "{rev}: '{desc}' {bookmarks}"
636 $ hg log -G --template "{rev}: '{desc}' {bookmarks}"
637 @ 1: 'collapsed' foo
637 @ 1: 'collapsed' foo
638 |
638 |
639 o 0: 'base'
639 o 0: 'base'
640
640
641 $ hg manifest --rev tip
641 $ hg manifest --rev tip
642 b
642 b
643 base
643 base
644
644
645 $ cd ..
645 $ cd ..
646
646
647 Test that rebase --collapse will remember message after
647 Test that rebase --collapse will remember message after
648 running into merge conflict and invoking rebase --continue.
648 running into merge conflict and invoking rebase --continue.
649
649
650 $ hg init collapse_remember_message
650 $ hg init collapse_remember_message
651 $ cd collapse_remember_message
651 $ cd collapse_remember_message
652 $ hg debugdrawdag << 'EOF'
652 $ hg debugdrawdag << 'EOF'
653 > C B # B/A = B\n
653 > C B # B/A = B\n
654 > |/ # C/A = C\n
654 > |/ # C/A = C\n
655 > A
655 > A
656 > EOF
656 > EOF
657 $ hg rebase --collapse -m "new message" -b B -d C
657 $ hg rebase --collapse -m "new message" -b B -d C
658 rebasing 1:81e5401e4d37 "B" (B)
658 rebasing 1:81e5401e4d37 "B" (B)
659 merging A
659 merging A
660 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
660 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
661 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
661 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
662 [1]
662 [1]
663 $ rm A.orig
663 $ rm A.orig
664 $ hg resolve --mark A
664 $ hg resolve --mark A
665 (no more unresolved files)
665 (no more unresolved files)
666 continue: hg rebase --continue
666 continue: hg rebase --continue
667 $ hg rebase --continue
667 $ hg rebase --continue
668 rebasing 1:81e5401e4d37 "B" (B)
668 rebasing 1:81e5401e4d37 "B" (B)
669 saved backup bundle to $TESTTMP/collapse_remember_message/.hg/strip-backup/81e5401e4d37-96c3dd30-rebase.hg
669 saved backup bundle to $TESTTMP/collapse_remember_message/.hg/strip-backup/81e5401e4d37-96c3dd30-rebase.hg
670 $ hg log
670 $ hg log
671 changeset: 2:17186933e123
671 changeset: 2:17186933e123
672 tag: tip
672 tag: tip
673 user: test
673 user: test
674 date: Thu Jan 01 00:00:00 1970 +0000
674 date: Thu Jan 01 00:00:00 1970 +0000
675 summary: new message
675 summary: new message
676
676
677 changeset: 1:043039e9df84
677 changeset: 1:043039e9df84
678 tag: C
678 tag: C
679 user: test
679 user: test
680 date: Thu Jan 01 00:00:00 1970 +0000
680 date: Thu Jan 01 00:00:00 1970 +0000
681 summary: C
681 summary: C
682
682
683 changeset: 0:426bada5c675
683 changeset: 0:426bada5c675
684 tag: A
684 tag: A
685 user: test
685 user: test
686 date: Thu Jan 01 00:00:00 1970 +0000
686 date: Thu Jan 01 00:00:00 1970 +0000
687 summary: A
687 summary: A
688
688
689 $ cd ..
689 $ cd ..
690
690
691 Test aborted editor on final message
691 Test aborted editor on final message
692
692
693 $ HGMERGE=:merge3
693 $ HGMERGE=:merge3
694 $ export HGMERGE
694 $ export HGMERGE
695 $ hg init aborted-editor
695 $ hg init aborted-editor
696 $ cd aborted-editor
696 $ cd aborted-editor
697 $ hg debugdrawdag << 'EOF'
697 $ hg debugdrawdag << 'EOF'
698 > C # D/A = D\n
698 > C # D/A = D\n
699 > | # C/A = C\n
699 > | # C/A = C\n
700 > B D # B/A = B\n
700 > B D # B/A = B\n
701 > |/ # A/A = A\n
701 > |/ # A/A = A\n
702 > A
702 > A
703 > EOF
703 > EOF
704 $ hg rebase --collapse -t internal:merge3 -s B -d D
704 $ hg rebase --collapse -t internal:merge3 -s B -d D
705 rebasing 1:f899f3910ce7 "B" (B)
705 rebasing 1:f899f3910ce7 "B" (B)
706 merging A
706 merging A
707 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
707 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
708 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
708 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
709 [1]
709 [1]
710 $ hg tglog
710 $ hg tglog
711 o 3: 63668d570d21 'C'
711 o 3: 63668d570d21 'C'
712 |
712 |
713 | @ 2: 82b8abf9c185 'D'
713 | @ 2: 82b8abf9c185 'D'
714 | |
714 | |
715 % | 1: f899f3910ce7 'B'
715 % | 1: f899f3910ce7 'B'
716 |/
716 |/
717 o 0: 4a2df7238c3b 'A'
717 o 0: 4a2df7238c3b 'A'
718
718
719 $ cat A
719 $ cat A
720 <<<<<<< dest: 82b8abf9c185 D - test: D
720 <<<<<<< dest: 82b8abf9c185 D - test: D
721 D
721 D
722 ||||||| base
722 ||||||| base
723 A
723 A
724 =======
724 =======
725 B
725 B
726 >>>>>>> source: f899f3910ce7 B - test: B
726 >>>>>>> source: f899f3910ce7 B - test: B
727 $ echo BC > A
727 $ echo BC > A
728 $ hg resolve -m
728 $ hg resolve -m
729 (no more unresolved files)
729 (no more unresolved files)
730 continue: hg rebase --continue
730 continue: hg rebase --continue
731 $ hg rebase --continue
731 $ hg rebase --continue
732 rebasing 1:f899f3910ce7 "B" (B)
732 rebasing 1:f899f3910ce7 "B" (B)
733 rebasing 3:63668d570d21 "C" (C tip)
733 rebasing 3:63668d570d21 "C" (C tip)
734 merging A
734 merging A
735 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
735 warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
736 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
736 unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
737 [1]
737 [1]
738 $ hg tglog
738 $ hg tglog
739 % 3: 63668d570d21 'C'
739 % 3: 63668d570d21 'C'
740 |
740 |
741 | @ 2: 82b8abf9c185 'D'
741 | @ 2: 82b8abf9c185 'D'
742 | |
742 | |
743 o | 1: f899f3910ce7 'B'
743 o | 1: f899f3910ce7 'B'
744 |/
744 |/
745 o 0: 4a2df7238c3b 'A'
745 o 0: 4a2df7238c3b 'A'
746
746
747 $ cat A
747 $ cat A
748 <<<<<<< dest: 82b8abf9c185 D - test: D
748 <<<<<<< dest: 82b8abf9c185 D - test: D
749 BC
749 BC
750 ||||||| base
750 ||||||| base
751 B
751 B
752 =======
752 =======
753 C
753 C
754 >>>>>>> source: 63668d570d21 C tip - test: C
754 >>>>>>> source: 63668d570d21 C tip - test: C
755 $ echo BD > A
755 $ echo BD > A
756 $ hg resolve -m
756 $ hg resolve -m
757 (no more unresolved files)
757 (no more unresolved files)
758 continue: hg rebase --continue
758 continue: hg rebase --continue
759 $ HGEDITOR=false hg rebase --continue --config ui.interactive=1
759 $ HGEDITOR=false hg rebase --continue --config ui.interactive=1
760 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
760 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
761 rebasing 3:63668d570d21 "C" (C tip)
761 rebasing 3:63668d570d21 "C" (C tip)
762 abort: edit failed: false exited with status 1
762 abort: edit failed: false exited with status 1
763 [255]
763 [255]
764 $ hg tglog
764 $ hg tglog
765 % 3: 63668d570d21 'C'
765 o 3: 63668d570d21 'C'
766 |
766 |
767 | @ 2: 82b8abf9c185 'D'
767 | @ 2: 82b8abf9c185 'D'
768 | |
768 | |
769 o | 1: f899f3910ce7 'B'
769 o | 1: f899f3910ce7 'B'
770 |/
770 |/
771 o 0: 4a2df7238c3b 'A'
771 o 0: 4a2df7238c3b 'A'
772
772
773 $ hg rebase --continue
773 $ hg rebase --continue
774 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
774 already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
775 already rebased 3:63668d570d21 "C" (C tip) as 82b8abf9c185
775 already rebased 3:63668d570d21 "C" (C tip) as 82b8abf9c185
776 saved backup bundle to $TESTTMP/aborted-editor/.hg/strip-backup/f899f3910ce7-7cab5e15-rebase.hg
776 saved backup bundle to $TESTTMP/aborted-editor/.hg/strip-backup/f899f3910ce7-7cab5e15-rebase.hg
General Comments 0
You need to be logged in to leave comments. Login now