##// END OF EJS Templates
templatekw: compare target context and its parent exactly (issue4690)...
FUJIWARA Katsunori -
r25392:ed18f4ac 3.4.1 stable
parent child Browse files
Show More
@@ -1,466 +1,466 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 node import hex
8 from node import hex
9 import patch, util, error
9 import patch, util, error
10 import hbisect
10 import hbisect
11
11
12 # This helper class allows us to handle both:
12 # This helper class allows us to handle both:
13 # "{files}" (legacy command-line-specific list hack) and
13 # "{files}" (legacy command-line-specific list hack) and
14 # "{files % '{file}\n'}" (hgweb-style with inlining and function support)
14 # "{files % '{file}\n'}" (hgweb-style with inlining and function support)
15 # and to access raw values:
15 # and to access raw values:
16 # "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
16 # "{ifcontains(file, files, ...)}", "{ifcontains(key, extras, ...)}"
17 # "{get(extras, key)}"
17 # "{get(extras, key)}"
18
18
19 class _hybrid(object):
19 class _hybrid(object):
20 def __init__(self, gen, values, makemap, joinfmt=None):
20 def __init__(self, gen, values, makemap, joinfmt=None):
21 self.gen = gen
21 self.gen = gen
22 self.values = values
22 self.values = values
23 self._makemap = makemap
23 self._makemap = makemap
24 if joinfmt:
24 if joinfmt:
25 self.joinfmt = joinfmt
25 self.joinfmt = joinfmt
26 else:
26 else:
27 self.joinfmt = lambda x: x.values()[0]
27 self.joinfmt = lambda x: x.values()[0]
28 def __iter__(self):
28 def __iter__(self):
29 return self.gen
29 return self.gen
30 def __call__(self):
30 def __call__(self):
31 makemap = self._makemap
31 makemap = self._makemap
32 for x in self.values:
32 for x in self.values:
33 yield makemap(x)
33 yield makemap(x)
34 def __contains__(self, x):
34 def __contains__(self, x):
35 return x in self.values
35 return x in self.values
36 def __len__(self):
36 def __len__(self):
37 return len(self.values)
37 return len(self.values)
38 def __getattr__(self, name):
38 def __getattr__(self, name):
39 if name != 'get':
39 if name != 'get':
40 raise AttributeError(name)
40 raise AttributeError(name)
41 return getattr(self.values, name)
41 return getattr(self.values, name)
42
42
43 def showlist(name, values, plural=None, element=None, **args):
43 def showlist(name, values, plural=None, element=None, **args):
44 if not element:
44 if not element:
45 element = name
45 element = name
46 f = _showlist(name, values, plural, **args)
46 f = _showlist(name, values, plural, **args)
47 return _hybrid(f, values, lambda x: {element: x})
47 return _hybrid(f, values, lambda x: {element: x})
48
48
49 def _showlist(name, values, plural=None, **args):
49 def _showlist(name, values, plural=None, **args):
50 '''expand set of values.
50 '''expand set of values.
51 name is name of key in template map.
51 name is name of key in template map.
52 values is list of strings or dicts.
52 values is list of strings or dicts.
53 plural is plural of name, if not simply name + 's'.
53 plural is plural of name, if not simply name + 's'.
54
54
55 expansion works like this, given name 'foo'.
55 expansion works like this, given name 'foo'.
56
56
57 if values is empty, expand 'no_foos'.
57 if values is empty, expand 'no_foos'.
58
58
59 if 'foo' not in template map, return values as a string,
59 if 'foo' not in template map, return values as a string,
60 joined by space.
60 joined by space.
61
61
62 expand 'start_foos'.
62 expand 'start_foos'.
63
63
64 for each value, expand 'foo'. if 'last_foo' in template
64 for each value, expand 'foo'. if 'last_foo' in template
65 map, expand it instead of 'foo' for last key.
65 map, expand it instead of 'foo' for last key.
66
66
67 expand 'end_foos'.
67 expand 'end_foos'.
68 '''
68 '''
69 templ = args['templ']
69 templ = args['templ']
70 if plural:
70 if plural:
71 names = plural
71 names = plural
72 else: names = name + 's'
72 else: names = name + 's'
73 if not values:
73 if not values:
74 noname = 'no_' + names
74 noname = 'no_' + names
75 if noname in templ:
75 if noname in templ:
76 yield templ(noname, **args)
76 yield templ(noname, **args)
77 return
77 return
78 if name not in templ:
78 if name not in templ:
79 if isinstance(values[0], str):
79 if isinstance(values[0], str):
80 yield ' '.join(values)
80 yield ' '.join(values)
81 else:
81 else:
82 for v in values:
82 for v in values:
83 yield dict(v, **args)
83 yield dict(v, **args)
84 return
84 return
85 startname = 'start_' + names
85 startname = 'start_' + names
86 if startname in templ:
86 if startname in templ:
87 yield templ(startname, **args)
87 yield templ(startname, **args)
88 vargs = args.copy()
88 vargs = args.copy()
89 def one(v, tag=name):
89 def one(v, tag=name):
90 try:
90 try:
91 vargs.update(v)
91 vargs.update(v)
92 except (AttributeError, ValueError):
92 except (AttributeError, ValueError):
93 try:
93 try:
94 for a, b in v:
94 for a, b in v:
95 vargs[a] = b
95 vargs[a] = b
96 except ValueError:
96 except ValueError:
97 vargs[name] = v
97 vargs[name] = v
98 return templ(tag, **vargs)
98 return templ(tag, **vargs)
99 lastname = 'last_' + name
99 lastname = 'last_' + name
100 if lastname in templ:
100 if lastname in templ:
101 last = values.pop()
101 last = values.pop()
102 else:
102 else:
103 last = None
103 last = None
104 for v in values:
104 for v in values:
105 yield one(v)
105 yield one(v)
106 if last is not None:
106 if last is not None:
107 yield one(last, tag=lastname)
107 yield one(last, tag=lastname)
108 endname = 'end_' + names
108 endname = 'end_' + names
109 if endname in templ:
109 if endname in templ:
110 yield templ(endname, **args)
110 yield templ(endname, **args)
111
111
112 def getfiles(repo, ctx, revcache):
112 def getfiles(repo, ctx, revcache):
113 if 'files' not in revcache:
113 if 'files' not in revcache:
114 revcache['files'] = repo.status(ctx.p1().node(), ctx.node())[:3]
114 revcache['files'] = repo.status(ctx.p1(), ctx)[:3]
115 return revcache['files']
115 return revcache['files']
116
116
117 def getlatesttags(repo, ctx, cache):
117 def getlatesttags(repo, ctx, cache):
118 '''return date, distance and name for the latest tag of rev'''
118 '''return date, distance and name for the latest tag of rev'''
119
119
120 if 'latesttags' not in cache:
120 if 'latesttags' not in cache:
121 # Cache mapping from rev to a tuple with tag date, tag
121 # Cache mapping from rev to a tuple with tag date, tag
122 # distance and tag name
122 # distance and tag name
123 cache['latesttags'] = {-1: (0, 0, 'null')}
123 cache['latesttags'] = {-1: (0, 0, 'null')}
124 latesttags = cache['latesttags']
124 latesttags = cache['latesttags']
125
125
126 rev = ctx.rev()
126 rev = ctx.rev()
127 todo = [rev]
127 todo = [rev]
128 while todo:
128 while todo:
129 rev = todo.pop()
129 rev = todo.pop()
130 if rev in latesttags:
130 if rev in latesttags:
131 continue
131 continue
132 ctx = repo[rev]
132 ctx = repo[rev]
133 tags = [t for t in ctx.tags()
133 tags = [t for t in ctx.tags()
134 if (repo.tagtype(t) and repo.tagtype(t) != 'local')]
134 if (repo.tagtype(t) and repo.tagtype(t) != 'local')]
135 if tags:
135 if tags:
136 latesttags[rev] = ctx.date()[0], 0, ':'.join(sorted(tags))
136 latesttags[rev] = ctx.date()[0], 0, ':'.join(sorted(tags))
137 continue
137 continue
138 try:
138 try:
139 # The tuples are laid out so the right one can be found by
139 # The tuples are laid out so the right one can be found by
140 # comparison.
140 # comparison.
141 pdate, pdist, ptag = max(
141 pdate, pdist, ptag = max(
142 latesttags[p.rev()] for p in ctx.parents())
142 latesttags[p.rev()] for p in ctx.parents())
143 except KeyError:
143 except KeyError:
144 # Cache miss - recurse
144 # Cache miss - recurse
145 todo.append(rev)
145 todo.append(rev)
146 todo.extend(p.rev() for p in ctx.parents())
146 todo.extend(p.rev() for p in ctx.parents())
147 continue
147 continue
148 latesttags[rev] = pdate, pdist + 1, ptag
148 latesttags[rev] = pdate, pdist + 1, ptag
149 return latesttags[rev]
149 return latesttags[rev]
150
150
151 def getrenamedfn(repo, endrev=None):
151 def getrenamedfn(repo, endrev=None):
152 rcache = {}
152 rcache = {}
153 if endrev is None:
153 if endrev is None:
154 endrev = len(repo)
154 endrev = len(repo)
155
155
156 def getrenamed(fn, rev):
156 def getrenamed(fn, rev):
157 '''looks up all renames for a file (up to endrev) the first
157 '''looks up all renames for a file (up to endrev) the first
158 time the file is given. It indexes on the changerev and only
158 time the file is given. It indexes on the changerev and only
159 parses the manifest if linkrev != changerev.
159 parses the manifest if linkrev != changerev.
160 Returns rename info for fn at changerev rev.'''
160 Returns rename info for fn at changerev rev.'''
161 if fn not in rcache:
161 if fn not in rcache:
162 rcache[fn] = {}
162 rcache[fn] = {}
163 fl = repo.file(fn)
163 fl = repo.file(fn)
164 for i in fl:
164 for i in fl:
165 lr = fl.linkrev(i)
165 lr = fl.linkrev(i)
166 renamed = fl.renamed(fl.node(i))
166 renamed = fl.renamed(fl.node(i))
167 rcache[fn][lr] = renamed
167 rcache[fn][lr] = renamed
168 if lr >= endrev:
168 if lr >= endrev:
169 break
169 break
170 if rev in rcache[fn]:
170 if rev in rcache[fn]:
171 return rcache[fn][rev]
171 return rcache[fn][rev]
172
172
173 # If linkrev != rev (i.e. rev not found in rcache) fallback to
173 # If linkrev != rev (i.e. rev not found in rcache) fallback to
174 # filectx logic.
174 # filectx logic.
175 try:
175 try:
176 return repo[rev][fn].renamed()
176 return repo[rev][fn].renamed()
177 except error.LookupError:
177 except error.LookupError:
178 return None
178 return None
179
179
180 return getrenamed
180 return getrenamed
181
181
182
182
183 def showauthor(repo, ctx, templ, **args):
183 def showauthor(repo, ctx, templ, **args):
184 """:author: String. The unmodified author of the changeset."""
184 """:author: String. The unmodified author of the changeset."""
185 return ctx.user()
185 return ctx.user()
186
186
187 def showbisect(repo, ctx, templ, **args):
187 def showbisect(repo, ctx, templ, **args):
188 """:bisect: String. The changeset bisection status."""
188 """:bisect: String. The changeset bisection status."""
189 return hbisect.label(repo, ctx.node())
189 return hbisect.label(repo, ctx.node())
190
190
191 def showbranch(**args):
191 def showbranch(**args):
192 """:branch: String. The name of the branch on which the changeset was
192 """:branch: String. The name of the branch on which the changeset was
193 committed.
193 committed.
194 """
194 """
195 return args['ctx'].branch()
195 return args['ctx'].branch()
196
196
197 def showbranches(**args):
197 def showbranches(**args):
198 """:branches: List of strings. The name of the branch on which the
198 """:branches: List of strings. The name of the branch on which the
199 changeset was committed. Will be empty if the branch name was
199 changeset was committed. Will be empty if the branch name was
200 default.
200 default.
201 """
201 """
202 branch = args['ctx'].branch()
202 branch = args['ctx'].branch()
203 if branch != 'default':
203 if branch != 'default':
204 return showlist('branch', [branch], plural='branches', **args)
204 return showlist('branch', [branch], plural='branches', **args)
205 return showlist('branch', [], plural='branches', **args)
205 return showlist('branch', [], plural='branches', **args)
206
206
207 def showbookmarks(**args):
207 def showbookmarks(**args):
208 """:bookmarks: List of strings. Any bookmarks associated with the
208 """:bookmarks: List of strings. Any bookmarks associated with the
209 changeset.
209 changeset.
210 """
210 """
211 repo = args['ctx']._repo
211 repo = args['ctx']._repo
212 bookmarks = args['ctx'].bookmarks()
212 bookmarks = args['ctx'].bookmarks()
213 current = repo._bookmarkcurrent
213 current = repo._bookmarkcurrent
214 makemap = lambda v: {'bookmark': v, 'current': current}
214 makemap = lambda v: {'bookmark': v, 'current': current}
215 f = _showlist('bookmark', bookmarks, **args)
215 f = _showlist('bookmark', bookmarks, **args)
216 return _hybrid(f, bookmarks, makemap, lambda x: x['bookmark'])
216 return _hybrid(f, bookmarks, makemap, lambda x: x['bookmark'])
217
217
218 def showchildren(**args):
218 def showchildren(**args):
219 """:children: List of strings. The children of the changeset."""
219 """:children: List of strings. The children of the changeset."""
220 ctx = args['ctx']
220 ctx = args['ctx']
221 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
221 childrevs = ['%d:%s' % (cctx, cctx) for cctx in ctx.children()]
222 return showlist('children', childrevs, element='child', **args)
222 return showlist('children', childrevs, element='child', **args)
223
223
224 def showcurrentbookmark(**args):
224 def showcurrentbookmark(**args):
225 """:currentbookmark: String. The active bookmark, if it is
225 """:currentbookmark: String. The active bookmark, if it is
226 associated with the changeset"""
226 associated with the changeset"""
227 import bookmarks as bookmarks # to avoid circular import issues
227 import bookmarks as bookmarks # to avoid circular import issues
228 repo = args['repo']
228 repo = args['repo']
229 if bookmarks.iscurrent(repo):
229 if bookmarks.iscurrent(repo):
230 current = repo._bookmarkcurrent
230 current = repo._bookmarkcurrent
231 if current in args['ctx'].bookmarks():
231 if current in args['ctx'].bookmarks():
232 return current
232 return current
233 return ''
233 return ''
234
234
235 def showdate(repo, ctx, templ, **args):
235 def showdate(repo, ctx, templ, **args):
236 """:date: Date information. The date when the changeset was committed."""
236 """:date: Date information. The date when the changeset was committed."""
237 return ctx.date()
237 return ctx.date()
238
238
239 def showdescription(repo, ctx, templ, **args):
239 def showdescription(repo, ctx, templ, **args):
240 """:desc: String. The text of the changeset description."""
240 """:desc: String. The text of the changeset description."""
241 return ctx.description().strip()
241 return ctx.description().strip()
242
242
243 def showdiffstat(repo, ctx, templ, **args):
243 def showdiffstat(repo, ctx, templ, **args):
244 """:diffstat: String. Statistics of changes with the following format:
244 """:diffstat: String. Statistics of changes with the following format:
245 "modified files: +added/-removed lines"
245 "modified files: +added/-removed lines"
246 """
246 """
247 stats = patch.diffstatdata(util.iterlines(ctx.diff()))
247 stats = patch.diffstatdata(util.iterlines(ctx.diff()))
248 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
248 maxname, maxtotal, adds, removes, binary = patch.diffstatsum(stats)
249 return '%s: +%s/-%s' % (len(stats), adds, removes)
249 return '%s: +%s/-%s' % (len(stats), adds, removes)
250
250
251 def showextras(**args):
251 def showextras(**args):
252 """:extras: List of dicts with key, value entries of the 'extras'
252 """:extras: List of dicts with key, value entries of the 'extras'
253 field of this changeset."""
253 field of this changeset."""
254 extras = args['ctx'].extra()
254 extras = args['ctx'].extra()
255 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
255 extras = util.sortdict((k, extras[k]) for k in sorted(extras))
256 makemap = lambda k: {'key': k, 'value': extras[k]}
256 makemap = lambda k: {'key': k, 'value': extras[k]}
257 c = [makemap(k) for k in extras]
257 c = [makemap(k) for k in extras]
258 f = _showlist('extra', c, plural='extras', **args)
258 f = _showlist('extra', c, plural='extras', **args)
259 return _hybrid(f, extras, makemap,
259 return _hybrid(f, extras, makemap,
260 lambda x: '%s=%s' % (x['key'], x['value']))
260 lambda x: '%s=%s' % (x['key'], x['value']))
261
261
262 def showfileadds(**args):
262 def showfileadds(**args):
263 """:file_adds: List of strings. Files added by this changeset."""
263 """:file_adds: List of strings. Files added by this changeset."""
264 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
264 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
265 return showlist('file_add', getfiles(repo, ctx, revcache)[1],
265 return showlist('file_add', getfiles(repo, ctx, revcache)[1],
266 element='file', **args)
266 element='file', **args)
267
267
268 def showfilecopies(**args):
268 def showfilecopies(**args):
269 """:file_copies: List of strings. Files copied in this changeset with
269 """:file_copies: List of strings. Files copied in this changeset with
270 their sources.
270 their sources.
271 """
271 """
272 cache, ctx = args['cache'], args['ctx']
272 cache, ctx = args['cache'], args['ctx']
273 copies = args['revcache'].get('copies')
273 copies = args['revcache'].get('copies')
274 if copies is None:
274 if copies is None:
275 if 'getrenamed' not in cache:
275 if 'getrenamed' not in cache:
276 cache['getrenamed'] = getrenamedfn(args['repo'])
276 cache['getrenamed'] = getrenamedfn(args['repo'])
277 copies = []
277 copies = []
278 getrenamed = cache['getrenamed']
278 getrenamed = cache['getrenamed']
279 for fn in ctx.files():
279 for fn in ctx.files():
280 rename = getrenamed(fn, ctx.rev())
280 rename = getrenamed(fn, ctx.rev())
281 if rename:
281 if rename:
282 copies.append((fn, rename[0]))
282 copies.append((fn, rename[0]))
283
283
284 copies = util.sortdict(copies)
284 copies = util.sortdict(copies)
285 makemap = lambda k: {'name': k, 'source': copies[k]}
285 makemap = lambda k: {'name': k, 'source': copies[k]}
286 c = [makemap(k) for k in copies]
286 c = [makemap(k) for k in copies]
287 f = _showlist('file_copy', c, plural='file_copies', **args)
287 f = _showlist('file_copy', c, plural='file_copies', **args)
288 return _hybrid(f, copies, makemap,
288 return _hybrid(f, copies, makemap,
289 lambda x: '%s (%s)' % (x['name'], x['source']))
289 lambda x: '%s (%s)' % (x['name'], x['source']))
290
290
291 # showfilecopiesswitch() displays file copies only if copy records are
291 # showfilecopiesswitch() displays file copies only if copy records are
292 # provided before calling the templater, usually with a --copies
292 # provided before calling the templater, usually with a --copies
293 # command line switch.
293 # command line switch.
294 def showfilecopiesswitch(**args):
294 def showfilecopiesswitch(**args):
295 """:file_copies_switch: List of strings. Like "file_copies" but displayed
295 """:file_copies_switch: List of strings. Like "file_copies" but displayed
296 only if the --copied switch is set.
296 only if the --copied switch is set.
297 """
297 """
298 copies = args['revcache'].get('copies') or []
298 copies = args['revcache'].get('copies') or []
299 copies = util.sortdict(copies)
299 copies = util.sortdict(copies)
300 makemap = lambda k: {'name': k, 'source': copies[k]}
300 makemap = lambda k: {'name': k, 'source': copies[k]}
301 c = [makemap(k) for k in copies]
301 c = [makemap(k) for k in copies]
302 f = _showlist('file_copy', c, plural='file_copies', **args)
302 f = _showlist('file_copy', c, plural='file_copies', **args)
303 return _hybrid(f, copies, makemap,
303 return _hybrid(f, copies, makemap,
304 lambda x: '%s (%s)' % (x['name'], x['source']))
304 lambda x: '%s (%s)' % (x['name'], x['source']))
305
305
306 def showfiledels(**args):
306 def showfiledels(**args):
307 """:file_dels: List of strings. Files removed by this changeset."""
307 """:file_dels: List of strings. Files removed by this changeset."""
308 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
308 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
309 return showlist('file_del', getfiles(repo, ctx, revcache)[2],
309 return showlist('file_del', getfiles(repo, ctx, revcache)[2],
310 element='file', **args)
310 element='file', **args)
311
311
312 def showfilemods(**args):
312 def showfilemods(**args):
313 """:file_mods: List of strings. Files modified by this changeset."""
313 """:file_mods: List of strings. Files modified by this changeset."""
314 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
314 repo, ctx, revcache = args['repo'], args['ctx'], args['revcache']
315 return showlist('file_mod', getfiles(repo, ctx, revcache)[0],
315 return showlist('file_mod', getfiles(repo, ctx, revcache)[0],
316 element='file', **args)
316 element='file', **args)
317
317
318 def showfiles(**args):
318 def showfiles(**args):
319 """:files: List of strings. All files modified, added, or removed by this
319 """:files: List of strings. All files modified, added, or removed by this
320 changeset.
320 changeset.
321 """
321 """
322 return showlist('file', args['ctx'].files(), **args)
322 return showlist('file', args['ctx'].files(), **args)
323
323
324 def showlatesttag(repo, ctx, templ, cache, **args):
324 def showlatesttag(repo, ctx, templ, cache, **args):
325 """:latesttag: String. Most recent global tag in the ancestors of this
325 """:latesttag: String. Most recent global tag in the ancestors of this
326 changeset.
326 changeset.
327 """
327 """
328 return getlatesttags(repo, ctx, cache)[2]
328 return getlatesttags(repo, ctx, cache)[2]
329
329
330 def showlatesttagdistance(repo, ctx, templ, cache, **args):
330 def showlatesttagdistance(repo, ctx, templ, cache, **args):
331 """:latesttagdistance: Integer. Longest path to the latest tag."""
331 """:latesttagdistance: Integer. Longest path to the latest tag."""
332 return getlatesttags(repo, ctx, cache)[1]
332 return getlatesttags(repo, ctx, cache)[1]
333
333
334 def showmanifest(**args):
334 def showmanifest(**args):
335 repo, ctx, templ = args['repo'], args['ctx'], args['templ']
335 repo, ctx, templ = args['repo'], args['ctx'], args['templ']
336 mnode = ctx.manifestnode()
336 mnode = ctx.manifestnode()
337 args = args.copy()
337 args = args.copy()
338 args.update({'rev': repo.manifest.rev(mnode), 'node': hex(mnode)})
338 args.update({'rev': repo.manifest.rev(mnode), 'node': hex(mnode)})
339 return templ('manifest', **args)
339 return templ('manifest', **args)
340
340
341 def shownode(repo, ctx, templ, **args):
341 def shownode(repo, ctx, templ, **args):
342 """:node: String. The changeset identification hash, as a 40 hexadecimal
342 """:node: String. The changeset identification hash, as a 40 hexadecimal
343 digit string.
343 digit string.
344 """
344 """
345 return ctx.hex()
345 return ctx.hex()
346
346
347 def showp1rev(repo, ctx, templ, **args):
347 def showp1rev(repo, ctx, templ, **args):
348 """:p1rev: Integer. The repository-local revision number of the changeset's
348 """:p1rev: Integer. The repository-local revision number of the changeset's
349 first parent, or -1 if the changeset has no parents."""
349 first parent, or -1 if the changeset has no parents."""
350 return ctx.p1().rev()
350 return ctx.p1().rev()
351
351
352 def showp2rev(repo, ctx, templ, **args):
352 def showp2rev(repo, ctx, templ, **args):
353 """:p2rev: Integer. The repository-local revision number of the changeset's
353 """:p2rev: Integer. The repository-local revision number of the changeset's
354 second parent, or -1 if the changeset has no second parent."""
354 second parent, or -1 if the changeset has no second parent."""
355 return ctx.p2().rev()
355 return ctx.p2().rev()
356
356
357 def showp1node(repo, ctx, templ, **args):
357 def showp1node(repo, ctx, templ, **args):
358 """:p1node: String. The identification hash of the changeset's first parent,
358 """:p1node: String. The identification hash of the changeset's first parent,
359 as a 40 digit hexadecimal string. If the changeset has no parents, all
359 as a 40 digit hexadecimal string. If the changeset has no parents, all
360 digits are 0."""
360 digits are 0."""
361 return ctx.p1().hex()
361 return ctx.p1().hex()
362
362
363 def showp2node(repo, ctx, templ, **args):
363 def showp2node(repo, ctx, templ, **args):
364 """:p2node: String. The identification hash of the changeset's second
364 """:p2node: String. The identification hash of the changeset's second
365 parent, as a 40 digit hexadecimal string. If the changeset has no second
365 parent, as a 40 digit hexadecimal string. If the changeset has no second
366 parent, all digits are 0."""
366 parent, all digits are 0."""
367 return ctx.p2().hex()
367 return ctx.p2().hex()
368
368
369 def showphase(repo, ctx, templ, **args):
369 def showphase(repo, ctx, templ, **args):
370 """:phase: String. The changeset phase name."""
370 """:phase: String. The changeset phase name."""
371 return ctx.phasestr()
371 return ctx.phasestr()
372
372
373 def showphaseidx(repo, ctx, templ, **args):
373 def showphaseidx(repo, ctx, templ, **args):
374 """:phaseidx: Integer. The changeset phase index."""
374 """:phaseidx: Integer. The changeset phase index."""
375 return ctx.phase()
375 return ctx.phase()
376
376
377 def showrev(repo, ctx, templ, **args):
377 def showrev(repo, ctx, templ, **args):
378 """:rev: Integer. The repository-local changeset revision number."""
378 """:rev: Integer. The repository-local changeset revision number."""
379 return ctx.rev()
379 return ctx.rev()
380
380
381 def showsubrepos(**args):
381 def showsubrepos(**args):
382 """:subrepos: List of strings. Updated subrepositories in the changeset."""
382 """:subrepos: List of strings. Updated subrepositories in the changeset."""
383 ctx = args['ctx']
383 ctx = args['ctx']
384 substate = ctx.substate
384 substate = ctx.substate
385 if not substate:
385 if not substate:
386 return showlist('subrepo', [], **args)
386 return showlist('subrepo', [], **args)
387 psubstate = ctx.parents()[0].substate or {}
387 psubstate = ctx.parents()[0].substate or {}
388 subrepos = []
388 subrepos = []
389 for sub in substate:
389 for sub in substate:
390 if sub not in psubstate or substate[sub] != psubstate[sub]:
390 if sub not in psubstate or substate[sub] != psubstate[sub]:
391 subrepos.append(sub) # modified or newly added in ctx
391 subrepos.append(sub) # modified or newly added in ctx
392 for sub in psubstate:
392 for sub in psubstate:
393 if sub not in substate:
393 if sub not in substate:
394 subrepos.append(sub) # removed in ctx
394 subrepos.append(sub) # removed in ctx
395 return showlist('subrepo', sorted(subrepos), **args)
395 return showlist('subrepo', sorted(subrepos), **args)
396
396
397 def shownames(namespace, **args):
397 def shownames(namespace, **args):
398 """helper method to generate a template keyword for a namespace"""
398 """helper method to generate a template keyword for a namespace"""
399 ctx = args['ctx']
399 ctx = args['ctx']
400 repo = ctx.repo()
400 repo = ctx.repo()
401 ns = repo.names[namespace]
401 ns = repo.names[namespace]
402 names = ns.names(repo, ctx.node())
402 names = ns.names(repo, ctx.node())
403 return showlist(ns.templatename, names, plural=namespace, **args)
403 return showlist(ns.templatename, names, plural=namespace, **args)
404
404
405 # don't remove "showtags" definition, even though namespaces will put
405 # don't remove "showtags" definition, even though namespaces will put
406 # a helper function for "tags" keyword into "keywords" map automatically,
406 # a helper function for "tags" keyword into "keywords" map automatically,
407 # because online help text is built without namespaces initialization
407 # because online help text is built without namespaces initialization
408 def showtags(**args):
408 def showtags(**args):
409 """:tags: List of strings. Any tags associated with the changeset."""
409 """:tags: List of strings. Any tags associated with the changeset."""
410 return shownames('tags', **args)
410 return shownames('tags', **args)
411
411
412 # keywords are callables like:
412 # keywords are callables like:
413 # fn(repo, ctx, templ, cache, revcache, **args)
413 # fn(repo, ctx, templ, cache, revcache, **args)
414 # with:
414 # with:
415 # repo - current repository instance
415 # repo - current repository instance
416 # ctx - the changectx being displayed
416 # ctx - the changectx being displayed
417 # templ - the templater instance
417 # templ - the templater instance
418 # cache - a cache dictionary for the whole templater run
418 # cache - a cache dictionary for the whole templater run
419 # revcache - a cache dictionary for the current revision
419 # revcache - a cache dictionary for the current revision
420 keywords = {
420 keywords = {
421 'author': showauthor,
421 'author': showauthor,
422 'bisect': showbisect,
422 'bisect': showbisect,
423 'branch': showbranch,
423 'branch': showbranch,
424 'branches': showbranches,
424 'branches': showbranches,
425 'bookmarks': showbookmarks,
425 'bookmarks': showbookmarks,
426 'children': showchildren,
426 'children': showchildren,
427 'currentbookmark': showcurrentbookmark,
427 'currentbookmark': showcurrentbookmark,
428 'date': showdate,
428 'date': showdate,
429 'desc': showdescription,
429 'desc': showdescription,
430 'diffstat': showdiffstat,
430 'diffstat': showdiffstat,
431 'extras': showextras,
431 'extras': showextras,
432 'file_adds': showfileadds,
432 'file_adds': showfileadds,
433 'file_copies': showfilecopies,
433 'file_copies': showfilecopies,
434 'file_copies_switch': showfilecopiesswitch,
434 'file_copies_switch': showfilecopiesswitch,
435 'file_dels': showfiledels,
435 'file_dels': showfiledels,
436 'file_mods': showfilemods,
436 'file_mods': showfilemods,
437 'files': showfiles,
437 'files': showfiles,
438 'latesttag': showlatesttag,
438 'latesttag': showlatesttag,
439 'latesttagdistance': showlatesttagdistance,
439 'latesttagdistance': showlatesttagdistance,
440 'manifest': showmanifest,
440 'manifest': showmanifest,
441 'node': shownode,
441 'node': shownode,
442 'p1rev': showp1rev,
442 'p1rev': showp1rev,
443 'p1node': showp1node,
443 'p1node': showp1node,
444 'p2rev': showp2rev,
444 'p2rev': showp2rev,
445 'p2node': showp2node,
445 'p2node': showp2node,
446 'phase': showphase,
446 'phase': showphase,
447 'phaseidx': showphaseidx,
447 'phaseidx': showphaseidx,
448 'rev': showrev,
448 'rev': showrev,
449 'subrepos': showsubrepos,
449 'subrepos': showsubrepos,
450 'tags': showtags,
450 'tags': showtags,
451 }
451 }
452
452
453 def _showparents(**args):
453 def _showparents(**args):
454 """:parents: List of strings. The parents of the changeset in "rev:node"
454 """:parents: List of strings. The parents of the changeset in "rev:node"
455 format. If the changeset has only one "natural" parent (the predecessor
455 format. If the changeset has only one "natural" parent (the predecessor
456 revision) nothing is shown."""
456 revision) nothing is shown."""
457 pass
457 pass
458
458
459 dockeywords = {
459 dockeywords = {
460 'parents': _showparents,
460 'parents': _showparents,
461 }
461 }
462 dockeywords.update(keywords)
462 dockeywords.update(keywords)
463 del dockeywords['branches']
463 del dockeywords['branches']
464
464
465 # tell hggettext to extract docstrings from these functions:
465 # tell hggettext to extract docstrings from these functions:
466 i18nfunctions = dockeywords.values()
466 i18nfunctions = dockeywords.values()
@@ -1,1122 +1,1153 b''
1 $ hg init
1 $ hg init
2
2
3 Setup:
3 Setup:
4
4
5 $ echo a >> a
5 $ echo a >> a
6 $ hg ci -Am 'base'
6 $ hg ci -Am 'base'
7 adding a
7 adding a
8
8
9 Refuse to amend public csets:
9 Refuse to amend public csets:
10
10
11 $ hg phase -r . -p
11 $ hg phase -r . -p
12 $ hg ci --amend
12 $ hg ci --amend
13 abort: cannot amend public changesets
13 abort: cannot amend public changesets
14 [255]
14 [255]
15 $ hg phase -r . -f -d
15 $ hg phase -r . -f -d
16
16
17 $ echo a >> a
17 $ echo a >> a
18 $ hg ci -Am 'base1'
18 $ hg ci -Am 'base1'
19
19
20 Nothing to amend:
20 Nothing to amend:
21
21
22 $ hg ci --amend
22 $ hg ci --amend
23 nothing changed
23 nothing changed
24 [1]
24 [1]
25
25
26 $ cat >> $HGRCPATH <<EOF
26 $ cat >> $HGRCPATH <<EOF
27 > [hooks]
27 > [hooks]
28 > pretxncommit.foo = sh -c "echo \\"pretxncommit \$HG_NODE\\"; hg id -r \$HG_NODE"
28 > pretxncommit.foo = sh -c "echo \\"pretxncommit \$HG_NODE\\"; hg id -r \$HG_NODE"
29 > EOF
29 > EOF
30
30
31 Amending changeset with changes in working dir:
31 Amending changeset with changes in working dir:
32 (and check that --message does not trigger an editor)
32 (and check that --message does not trigger an editor)
33
33
34 $ echo a >> a
34 $ echo a >> a
35 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -m 'amend base1'
35 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -m 'amend base1'
36 pretxncommit 43f1ba15f28a50abf0aae529cf8a16bfced7b149
36 pretxncommit 43f1ba15f28a50abf0aae529cf8a16bfced7b149
37 43f1ba15f28a tip
37 43f1ba15f28a tip
38 saved backup bundle to $TESTTMP/.hg/strip-backup/489edb5b847d-f1bf3ab8-amend-backup.hg (glob)
38 saved backup bundle to $TESTTMP/.hg/strip-backup/489edb5b847d-f1bf3ab8-amend-backup.hg (glob)
39 $ echo 'pretxncommit.foo = ' >> $HGRCPATH
39 $ echo 'pretxncommit.foo = ' >> $HGRCPATH
40 $ hg diff -c .
40 $ hg diff -c .
41 diff -r ad120869acf0 -r 43f1ba15f28a a
41 diff -r ad120869acf0 -r 43f1ba15f28a a
42 --- a/a Thu Jan 01 00:00:00 1970 +0000
42 --- a/a Thu Jan 01 00:00:00 1970 +0000
43 +++ b/a Thu Jan 01 00:00:00 1970 +0000
43 +++ b/a Thu Jan 01 00:00:00 1970 +0000
44 @@ -1,1 +1,3 @@
44 @@ -1,1 +1,3 @@
45 a
45 a
46 +a
46 +a
47 +a
47 +a
48 $ hg log
48 $ hg log
49 changeset: 1:43f1ba15f28a
49 changeset: 1:43f1ba15f28a
50 tag: tip
50 tag: tip
51 user: test
51 user: test
52 date: Thu Jan 01 00:00:00 1970 +0000
52 date: Thu Jan 01 00:00:00 1970 +0000
53 summary: amend base1
53 summary: amend base1
54
54
55 changeset: 0:ad120869acf0
55 changeset: 0:ad120869acf0
56 user: test
56 user: test
57 date: Thu Jan 01 00:00:00 1970 +0000
57 date: Thu Jan 01 00:00:00 1970 +0000
58 summary: base
58 summary: base
59
59
60
60
61 Check proper abort for empty message
61 Check proper abort for empty message
62
62
63 $ cat > editor.sh << '__EOF__'
63 $ cat > editor.sh << '__EOF__'
64 > #!/bin/sh
64 > #!/bin/sh
65 > echo "" > "$1"
65 > echo "" > "$1"
66 > __EOF__
66 > __EOF__
67 $ echo b > b
67 $ echo b > b
68 $ hg add b
68 $ hg add b
69 $ hg summary
69 $ hg summary
70 parent: 1:43f1ba15f28a tip
70 parent: 1:43f1ba15f28a tip
71 amend base1
71 amend base1
72 branch: default
72 branch: default
73 commit: 1 added, 1 unknown
73 commit: 1 added, 1 unknown
74 update: (current)
74 update: (current)
75 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
75 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
76 transaction abort!
76 transaction abort!
77 rollback completed
77 rollback completed
78 abort: empty commit message
78 abort: empty commit message
79 [255]
79 [255]
80 $ hg summary
80 $ hg summary
81 parent: 1:43f1ba15f28a tip
81 parent: 1:43f1ba15f28a tip
82 amend base1
82 amend base1
83 branch: default
83 branch: default
84 commit: 1 added, 1 unknown
84 commit: 1 added, 1 unknown
85 update: (current)
85 update: (current)
86
86
87 Add new file:
87 Add new file:
88 $ hg ci --amend -m 'amend base1 new file'
88 $ hg ci --amend -m 'amend base1 new file'
89 saved backup bundle to $TESTTMP/.hg/strip-backup/43f1ba15f28a-7a3b3496-amend-backup.hg (glob)
89 saved backup bundle to $TESTTMP/.hg/strip-backup/43f1ba15f28a-7a3b3496-amend-backup.hg (glob)
90
90
91 Remove file that was added in amended commit:
91 Remove file that was added in amended commit:
92 (and test logfile option)
92 (and test logfile option)
93 (and test that logfile option do not trigger an editor)
93 (and test that logfile option do not trigger an editor)
94
94
95 $ hg rm b
95 $ hg rm b
96 $ echo 'amend base1 remove new file' > ../logfile
96 $ echo 'amend base1 remove new file' > ../logfile
97 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg ci --amend --logfile ../logfile
97 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg ci --amend --logfile ../logfile
98 saved backup bundle to $TESTTMP/.hg/strip-backup/b8e3cb2b3882-0b55739a-amend-backup.hg (glob)
98 saved backup bundle to $TESTTMP/.hg/strip-backup/b8e3cb2b3882-0b55739a-amend-backup.hg (glob)
99
99
100 $ hg cat b
100 $ hg cat b
101 b: no such file in rev 74609c7f506e
101 b: no such file in rev 74609c7f506e
102 [1]
102 [1]
103
103
104 No changes, just a different message:
104 No changes, just a different message:
105
105
106 $ hg ci -v --amend -m 'no changes, new message'
106 $ hg ci -v --amend -m 'no changes, new message'
107 amending changeset 74609c7f506e
107 amending changeset 74609c7f506e
108 copying changeset 74609c7f506e to ad120869acf0
108 copying changeset 74609c7f506e to ad120869acf0
109 committing files:
109 committing files:
110 a
110 a
111 committing manifest
111 committing manifest
112 committing changelog
112 committing changelog
113 stripping amended changeset 74609c7f506e
113 stripping amended changeset 74609c7f506e
114 1 changesets found
114 1 changesets found
115 uncompressed size of bundle content:
115 uncompressed size of bundle content:
116 250 (changelog)
116 250 (changelog)
117 143 (manifests)
117 143 (manifests)
118 109 a
118 109 a
119 saved backup bundle to $TESTTMP/.hg/strip-backup/74609c7f506e-1bfde511-amend-backup.hg (glob)
119 saved backup bundle to $TESTTMP/.hg/strip-backup/74609c7f506e-1bfde511-amend-backup.hg (glob)
120 1 changesets found
120 1 changesets found
121 uncompressed size of bundle content:
121 uncompressed size of bundle content:
122 246 (changelog)
122 246 (changelog)
123 143 (manifests)
123 143 (manifests)
124 109 a
124 109 a
125 adding branch
125 adding branch
126 adding changesets
126 adding changesets
127 adding manifests
127 adding manifests
128 adding file changes
128 adding file changes
129 added 1 changesets with 1 changes to 1 files
129 added 1 changesets with 1 changes to 1 files
130 committed changeset 1:1cd866679df8
130 committed changeset 1:1cd866679df8
131 $ hg diff -c .
131 $ hg diff -c .
132 diff -r ad120869acf0 -r 1cd866679df8 a
132 diff -r ad120869acf0 -r 1cd866679df8 a
133 --- a/a Thu Jan 01 00:00:00 1970 +0000
133 --- a/a Thu Jan 01 00:00:00 1970 +0000
134 +++ b/a Thu Jan 01 00:00:00 1970 +0000
134 +++ b/a Thu Jan 01 00:00:00 1970 +0000
135 @@ -1,1 +1,3 @@
135 @@ -1,1 +1,3 @@
136 a
136 a
137 +a
137 +a
138 +a
138 +a
139 $ hg log
139 $ hg log
140 changeset: 1:1cd866679df8
140 changeset: 1:1cd866679df8
141 tag: tip
141 tag: tip
142 user: test
142 user: test
143 date: Thu Jan 01 00:00:00 1970 +0000
143 date: Thu Jan 01 00:00:00 1970 +0000
144 summary: no changes, new message
144 summary: no changes, new message
145
145
146 changeset: 0:ad120869acf0
146 changeset: 0:ad120869acf0
147 user: test
147 user: test
148 date: Thu Jan 01 00:00:00 1970 +0000
148 date: Thu Jan 01 00:00:00 1970 +0000
149 summary: base
149 summary: base
150
150
151
151
152 Disable default date on commit so when -d isn't given, the old date is preserved:
152 Disable default date on commit so when -d isn't given, the old date is preserved:
153
153
154 $ echo '[defaults]' >> $HGRCPATH
154 $ echo '[defaults]' >> $HGRCPATH
155 $ echo 'commit=' >> $HGRCPATH
155 $ echo 'commit=' >> $HGRCPATH
156
156
157 Test -u/-d:
157 Test -u/-d:
158
158
159 $ cat > .hg/checkeditform.sh <<EOF
159 $ cat > .hg/checkeditform.sh <<EOF
160 > env | grep HGEDITFORM
160 > env | grep HGEDITFORM
161 > true
161 > true
162 > EOF
162 > EOF
163 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -u foo -d '1 0'
163 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -u foo -d '1 0'
164 HGEDITFORM=commit.amend.normal
164 HGEDITFORM=commit.amend.normal
165 saved backup bundle to $TESTTMP/.hg/strip-backup/1cd866679df8-5f5bcb85-amend-backup.hg (glob)
165 saved backup bundle to $TESTTMP/.hg/strip-backup/1cd866679df8-5f5bcb85-amend-backup.hg (glob)
166 $ echo a >> a
166 $ echo a >> a
167 $ hg ci --amend -u foo -d '1 0'
167 $ hg ci --amend -u foo -d '1 0'
168 saved backup bundle to $TESTTMP/.hg/strip-backup/780e6f23e03d-83b10a27-amend-backup.hg (glob)
168 saved backup bundle to $TESTTMP/.hg/strip-backup/780e6f23e03d-83b10a27-amend-backup.hg (glob)
169 $ hg log -r .
169 $ hg log -r .
170 changeset: 1:5f357c7560ab
170 changeset: 1:5f357c7560ab
171 tag: tip
171 tag: tip
172 user: foo
172 user: foo
173 date: Thu Jan 01 00:00:01 1970 +0000
173 date: Thu Jan 01 00:00:01 1970 +0000
174 summary: no changes, new message
174 summary: no changes, new message
175
175
176
176
177 Open editor with old commit message if a message isn't given otherwise:
177 Open editor with old commit message if a message isn't given otherwise:
178
178
179 $ cat > editor.sh << '__EOF__'
179 $ cat > editor.sh << '__EOF__'
180 > #!/bin/sh
180 > #!/bin/sh
181 > cat $1
181 > cat $1
182 > echo "another precious commit message" > "$1"
182 > echo "another precious commit message" > "$1"
183 > __EOF__
183 > __EOF__
184
184
185 at first, test saving last-message.txt
185 at first, test saving last-message.txt
186
186
187 $ cat > .hg/hgrc << '__EOF__'
187 $ cat > .hg/hgrc << '__EOF__'
188 > [hooks]
188 > [hooks]
189 > pretxncommit.test-saving-last-message = false
189 > pretxncommit.test-saving-last-message = false
190 > __EOF__
190 > __EOF__
191
191
192 $ rm -f .hg/last-message.txt
192 $ rm -f .hg/last-message.txt
193 $ hg commit --amend -v -m "message given from command line"
193 $ hg commit --amend -v -m "message given from command line"
194 amending changeset 5f357c7560ab
194 amending changeset 5f357c7560ab
195 copying changeset 5f357c7560ab to ad120869acf0
195 copying changeset 5f357c7560ab to ad120869acf0
196 committing files:
196 committing files:
197 a
197 a
198 committing manifest
198 committing manifest
199 committing changelog
199 committing changelog
200 running hook pretxncommit.test-saving-last-message: false
200 running hook pretxncommit.test-saving-last-message: false
201 transaction abort!
201 transaction abort!
202 rollback completed
202 rollback completed
203 abort: pretxncommit.test-saving-last-message hook exited with status 1
203 abort: pretxncommit.test-saving-last-message hook exited with status 1
204 [255]
204 [255]
205 $ cat .hg/last-message.txt
205 $ cat .hg/last-message.txt
206 message given from command line (no-eol)
206 message given from command line (no-eol)
207
207
208 $ rm -f .hg/last-message.txt
208 $ rm -f .hg/last-message.txt
209 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
209 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
210 amending changeset 5f357c7560ab
210 amending changeset 5f357c7560ab
211 copying changeset 5f357c7560ab to ad120869acf0
211 copying changeset 5f357c7560ab to ad120869acf0
212 no changes, new message
212 no changes, new message
213
213
214
214
215 HG: Enter commit message. Lines beginning with 'HG:' are removed.
215 HG: Enter commit message. Lines beginning with 'HG:' are removed.
216 HG: Leave message empty to abort commit.
216 HG: Leave message empty to abort commit.
217 HG: --
217 HG: --
218 HG: user: foo
218 HG: user: foo
219 HG: branch 'default'
219 HG: branch 'default'
220 HG: changed a
220 HG: changed a
221 committing files:
221 committing files:
222 a
222 a
223 committing manifest
223 committing manifest
224 committing changelog
224 committing changelog
225 running hook pretxncommit.test-saving-last-message: false
225 running hook pretxncommit.test-saving-last-message: false
226 transaction abort!
226 transaction abort!
227 rollback completed
227 rollback completed
228 abort: pretxncommit.test-saving-last-message hook exited with status 1
228 abort: pretxncommit.test-saving-last-message hook exited with status 1
229 [255]
229 [255]
230
230
231 $ cat .hg/last-message.txt
231 $ cat .hg/last-message.txt
232 another precious commit message
232 another precious commit message
233
233
234 $ cat > .hg/hgrc << '__EOF__'
234 $ cat > .hg/hgrc << '__EOF__'
235 > [hooks]
235 > [hooks]
236 > pretxncommit.test-saving-last-message =
236 > pretxncommit.test-saving-last-message =
237 > __EOF__
237 > __EOF__
238
238
239 then, test editing custom commit message
239 then, test editing custom commit message
240
240
241 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
241 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
242 amending changeset 5f357c7560ab
242 amending changeset 5f357c7560ab
243 copying changeset 5f357c7560ab to ad120869acf0
243 copying changeset 5f357c7560ab to ad120869acf0
244 no changes, new message
244 no changes, new message
245
245
246
246
247 HG: Enter commit message. Lines beginning with 'HG:' are removed.
247 HG: Enter commit message. Lines beginning with 'HG:' are removed.
248 HG: Leave message empty to abort commit.
248 HG: Leave message empty to abort commit.
249 HG: --
249 HG: --
250 HG: user: foo
250 HG: user: foo
251 HG: branch 'default'
251 HG: branch 'default'
252 HG: changed a
252 HG: changed a
253 committing files:
253 committing files:
254 a
254 a
255 committing manifest
255 committing manifest
256 committing changelog
256 committing changelog
257 stripping amended changeset 5f357c7560ab
257 stripping amended changeset 5f357c7560ab
258 1 changesets found
258 1 changesets found
259 uncompressed size of bundle content:
259 uncompressed size of bundle content:
260 238 (changelog)
260 238 (changelog)
261 143 (manifests)
261 143 (manifests)
262 111 a
262 111 a
263 saved backup bundle to $TESTTMP/.hg/strip-backup/5f357c7560ab-e7c84ade-amend-backup.hg (glob)
263 saved backup bundle to $TESTTMP/.hg/strip-backup/5f357c7560ab-e7c84ade-amend-backup.hg (glob)
264 1 changesets found
264 1 changesets found
265 uncompressed size of bundle content:
265 uncompressed size of bundle content:
266 246 (changelog)
266 246 (changelog)
267 143 (manifests)
267 143 (manifests)
268 111 a
268 111 a
269 adding branch
269 adding branch
270 adding changesets
270 adding changesets
271 adding manifests
271 adding manifests
272 adding file changes
272 adding file changes
273 added 1 changesets with 1 changes to 1 files
273 added 1 changesets with 1 changes to 1 files
274 committed changeset 1:7ab3bf440b54
274 committed changeset 1:7ab3bf440b54
275
275
276 Same, but with changes in working dir (different code path):
276 Same, but with changes in working dir (different code path):
277
277
278 $ echo a >> a
278 $ echo a >> a
279 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
279 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend -v
280 amending changeset 7ab3bf440b54
280 amending changeset 7ab3bf440b54
281 committing files:
281 committing files:
282 a
282 a
283 committing manifest
283 committing manifest
284 committing changelog
284 committing changelog
285 copying changeset a0ea9b1a4c8c to ad120869acf0
285 copying changeset a0ea9b1a4c8c to ad120869acf0
286 another precious commit message
286 another precious commit message
287
287
288
288
289 HG: Enter commit message. Lines beginning with 'HG:' are removed.
289 HG: Enter commit message. Lines beginning with 'HG:' are removed.
290 HG: Leave message empty to abort commit.
290 HG: Leave message empty to abort commit.
291 HG: --
291 HG: --
292 HG: user: foo
292 HG: user: foo
293 HG: branch 'default'
293 HG: branch 'default'
294 HG: changed a
294 HG: changed a
295 committing files:
295 committing files:
296 a
296 a
297 committing manifest
297 committing manifest
298 committing changelog
298 committing changelog
299 stripping intermediate changeset a0ea9b1a4c8c
299 stripping intermediate changeset a0ea9b1a4c8c
300 stripping amended changeset 7ab3bf440b54
300 stripping amended changeset 7ab3bf440b54
301 2 changesets found
301 2 changesets found
302 uncompressed size of bundle content:
302 uncompressed size of bundle content:
303 450 (changelog)
303 450 (changelog)
304 282 (manifests)
304 282 (manifests)
305 209 a
305 209 a
306 saved backup bundle to $TESTTMP/.hg/strip-backup/7ab3bf440b54-8e3b5088-amend-backup.hg (glob)
306 saved backup bundle to $TESTTMP/.hg/strip-backup/7ab3bf440b54-8e3b5088-amend-backup.hg (glob)
307 1 changesets found
307 1 changesets found
308 uncompressed size of bundle content:
308 uncompressed size of bundle content:
309 246 (changelog)
309 246 (changelog)
310 143 (manifests)
310 143 (manifests)
311 113 a
311 113 a
312 adding branch
312 adding branch
313 adding changesets
313 adding changesets
314 adding manifests
314 adding manifests
315 adding file changes
315 adding file changes
316 added 1 changesets with 1 changes to 1 files
316 added 1 changesets with 1 changes to 1 files
317 committed changeset 1:ea22a388757c
317 committed changeset 1:ea22a388757c
318
318
319 $ rm editor.sh
319 $ rm editor.sh
320 $ hg log -r .
320 $ hg log -r .
321 changeset: 1:ea22a388757c
321 changeset: 1:ea22a388757c
322 tag: tip
322 tag: tip
323 user: foo
323 user: foo
324 date: Thu Jan 01 00:00:01 1970 +0000
324 date: Thu Jan 01 00:00:01 1970 +0000
325 summary: another precious commit message
325 summary: another precious commit message
326
326
327
327
328 Moving bookmarks, preserve active bookmark:
328 Moving bookmarks, preserve active bookmark:
329
329
330 $ hg book book1
330 $ hg book book1
331 $ hg book book2
331 $ hg book book2
332 $ hg ci --amend -m 'move bookmarks'
332 $ hg ci --amend -m 'move bookmarks'
333 saved backup bundle to $TESTTMP/.hg/strip-backup/ea22a388757c-e51094db-amend-backup.hg (glob)
333 saved backup bundle to $TESTTMP/.hg/strip-backup/ea22a388757c-e51094db-amend-backup.hg (glob)
334 $ hg book
334 $ hg book
335 book1 1:6cec5aa930e2
335 book1 1:6cec5aa930e2
336 * book2 1:6cec5aa930e2
336 * book2 1:6cec5aa930e2
337 $ echo a >> a
337 $ echo a >> a
338 $ hg ci --amend -m 'move bookmarks'
338 $ hg ci --amend -m 'move bookmarks'
339 saved backup bundle to $TESTTMP/.hg/strip-backup/6cec5aa930e2-e9b06de4-amend-backup.hg (glob)
339 saved backup bundle to $TESTTMP/.hg/strip-backup/6cec5aa930e2-e9b06de4-amend-backup.hg (glob)
340 $ hg book
340 $ hg book
341 book1 1:48bb6e53a15f
341 book1 1:48bb6e53a15f
342 * book2 1:48bb6e53a15f
342 * book2 1:48bb6e53a15f
343
343
344 abort does not loose bookmarks
344 abort does not loose bookmarks
345
345
346 $ cat > editor.sh << '__EOF__'
346 $ cat > editor.sh << '__EOF__'
347 > #!/bin/sh
347 > #!/bin/sh
348 > echo "" > "$1"
348 > echo "" > "$1"
349 > __EOF__
349 > __EOF__
350 $ echo a >> a
350 $ echo a >> a
351 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
351 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg commit --amend
352 transaction abort!
352 transaction abort!
353 rollback completed
353 rollback completed
354 abort: empty commit message
354 abort: empty commit message
355 [255]
355 [255]
356 $ hg book
356 $ hg book
357 book1 1:48bb6e53a15f
357 book1 1:48bb6e53a15f
358 * book2 1:48bb6e53a15f
358 * book2 1:48bb6e53a15f
359 $ hg revert -Caq
359 $ hg revert -Caq
360 $ rm editor.sh
360 $ rm editor.sh
361
361
362 $ echo '[defaults]' >> $HGRCPATH
362 $ echo '[defaults]' >> $HGRCPATH
363 $ echo "commit=-d '0 0'" >> $HGRCPATH
363 $ echo "commit=-d '0 0'" >> $HGRCPATH
364
364
365 Moving branches:
365 Moving branches:
366
366
367 $ hg branch foo
367 $ hg branch foo
368 marked working directory as branch foo
368 marked working directory as branch foo
369 (branches are permanent and global, did you want a bookmark?)
369 (branches are permanent and global, did you want a bookmark?)
370 $ echo a >> a
370 $ echo a >> a
371 $ hg ci -m 'branch foo'
371 $ hg ci -m 'branch foo'
372 $ hg branch default -f
372 $ hg branch default -f
373 marked working directory as branch default
373 marked working directory as branch default
374 (branches are permanent and global, did you want a bookmark?)
374 (branches are permanent and global, did you want a bookmark?)
375 $ hg ci --amend -m 'back to default'
375 $ hg ci --amend -m 'back to default'
376 saved backup bundle to $TESTTMP/.hg/strip-backup/8ac881fbf49d-fd962fef-amend-backup.hg (glob)
376 saved backup bundle to $TESTTMP/.hg/strip-backup/8ac881fbf49d-fd962fef-amend-backup.hg (glob)
377 $ hg branches
377 $ hg branches
378 default 2:ce12b0b57d46
378 default 2:ce12b0b57d46
379
379
380 Close branch:
380 Close branch:
381
381
382 $ hg up -q 0
382 $ hg up -q 0
383 $ echo b >> b
383 $ echo b >> b
384 $ hg branch foo
384 $ hg branch foo
385 marked working directory as branch foo
385 marked working directory as branch foo
386 (branches are permanent and global, did you want a bookmark?)
386 (branches are permanent and global, did you want a bookmark?)
387 $ hg ci -Am 'fork'
387 $ hg ci -Am 'fork'
388 adding b
388 adding b
389 $ echo b >> b
389 $ echo b >> b
390 $ hg ci -mb
390 $ hg ci -mb
391 $ hg ci --amend --close-branch -m 'closing branch foo'
391 $ hg ci --amend --close-branch -m 'closing branch foo'
392 saved backup bundle to $TESTTMP/.hg/strip-backup/c962248fa264-6701c392-amend-backup.hg (glob)
392 saved backup bundle to $TESTTMP/.hg/strip-backup/c962248fa264-6701c392-amend-backup.hg (glob)
393
393
394 Same thing, different code path:
394 Same thing, different code path:
395
395
396 $ echo b >> b
396 $ echo b >> b
397 $ hg ci -m 'reopen branch'
397 $ hg ci -m 'reopen branch'
398 reopening closed branch head 4
398 reopening closed branch head 4
399 $ echo b >> b
399 $ echo b >> b
400 $ hg ci --amend --close-branch
400 $ hg ci --amend --close-branch
401 saved backup bundle to $TESTTMP/.hg/strip-backup/027371728205-49c0c55d-amend-backup.hg (glob)
401 saved backup bundle to $TESTTMP/.hg/strip-backup/027371728205-49c0c55d-amend-backup.hg (glob)
402 $ hg branches
402 $ hg branches
403 default 2:ce12b0b57d46
403 default 2:ce12b0b57d46
404
404
405 Refuse to amend during a merge:
405 Refuse to amend during a merge:
406
406
407 $ hg up -q default
407 $ hg up -q default
408 $ hg merge foo
408 $ hg merge foo
409 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
409 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
410 (branch merge, don't forget to commit)
410 (branch merge, don't forget to commit)
411 $ hg ci --amend
411 $ hg ci --amend
412 abort: cannot amend while merging
412 abort: cannot amend while merging
413 [255]
413 [255]
414 $ hg ci -m 'merge'
414 $ hg ci -m 'merge'
415
415
416 Follow copies/renames:
416 Follow copies/renames:
417
417
418 $ hg mv b c
418 $ hg mv b c
419 $ hg ci -m 'b -> c'
419 $ hg ci -m 'b -> c'
420 $ hg mv c d
420 $ hg mv c d
421 $ hg ci --amend -m 'b -> d'
421 $ hg ci --amend -m 'b -> d'
422 saved backup bundle to $TESTTMP/.hg/strip-backup/b8c6eac7f12e-adaaa8b1-amend-backup.hg (glob)
422 saved backup bundle to $TESTTMP/.hg/strip-backup/b8c6eac7f12e-adaaa8b1-amend-backup.hg (glob)
423 $ hg st --rev '.^' --copies d
423 $ hg st --rev '.^' --copies d
424 A d
424 A d
425 b
425 b
426 $ hg cp d e
426 $ hg cp d e
427 $ hg ci -m 'e = d'
427 $ hg ci -m 'e = d'
428 $ hg cp e f
428 $ hg cp e f
429 $ hg ci --amend -m 'f = d'
429 $ hg ci --amend -m 'f = d'
430 saved backup bundle to $TESTTMP/.hg/strip-backup/7f9761d65613-d37aa788-amend-backup.hg (glob)
430 saved backup bundle to $TESTTMP/.hg/strip-backup/7f9761d65613-d37aa788-amend-backup.hg (glob)
431 $ hg st --rev '.^' --copies f
431 $ hg st --rev '.^' --copies f
432 A f
432 A f
433 d
433 d
434
434
435 $ mv f f.orig
435 $ mv f f.orig
436 $ hg rm -A f
436 $ hg rm -A f
437 $ hg ci -m removef
437 $ hg ci -m removef
438 $ hg cp a f
438 $ hg cp a f
439 $ mv f.orig f
439 $ mv f.orig f
440 $ hg ci --amend -m replacef
440 $ hg ci --amend -m replacef
441 saved backup bundle to $TESTTMP/.hg/strip-backup/9e8c5f7e3d95-90259f67-amend-backup.hg (glob)
441 saved backup bundle to $TESTTMP/.hg/strip-backup/9e8c5f7e3d95-90259f67-amend-backup.hg (glob)
442 $ hg st --change . --copies
442 $ hg st --change . --copies
443 $ hg log -r . --template "{file_copies}\n"
443 $ hg log -r . --template "{file_copies}\n"
444
444
445
445
446 Move added file (issue3410):
446 Move added file (issue3410):
447
447
448 $ echo g >> g
448 $ echo g >> g
449 $ hg ci -Am g
449 $ hg ci -Am g
450 adding g
450 adding g
451 $ hg mv g h
451 $ hg mv g h
452 $ hg ci --amend
452 $ hg ci --amend
453 saved backup bundle to $TESTTMP/.hg/strip-backup/24aa8eacce2b-7059e0f1-amend-backup.hg (glob)
453 saved backup bundle to $TESTTMP/.hg/strip-backup/24aa8eacce2b-7059e0f1-amend-backup.hg (glob)
454 $ hg st --change . --copies h
454 $ hg st --change . --copies h
455 A h
455 A h
456 $ hg log -r . --template "{file_copies}\n"
456 $ hg log -r . --template "{file_copies}\n"
457
457
458
458
459 Can't rollback an amend:
459 Can't rollback an amend:
460
460
461 $ hg rollback
461 $ hg rollback
462 no rollback information available
462 no rollback information available
463 [1]
463 [1]
464
464
465 Preserve extra dict (issue3430):
465 Preserve extra dict (issue3430):
466
466
467 $ hg branch a
467 $ hg branch a
468 marked working directory as branch a
468 marked working directory as branch a
469 (branches are permanent and global, did you want a bookmark?)
469 (branches are permanent and global, did you want a bookmark?)
470 $ echo a >> a
470 $ echo a >> a
471 $ hg ci -ma
471 $ hg ci -ma
472 $ hg ci --amend -m "a'"
472 $ hg ci --amend -m "a'"
473 saved backup bundle to $TESTTMP/.hg/strip-backup/3837aa2a2fdb-2be01fd1-amend-backup.hg (glob)
473 saved backup bundle to $TESTTMP/.hg/strip-backup/3837aa2a2fdb-2be01fd1-amend-backup.hg (glob)
474 $ hg log -r . --template "{branch}\n"
474 $ hg log -r . --template "{branch}\n"
475 a
475 a
476 $ hg ci --amend -m "a''"
476 $ hg ci --amend -m "a''"
477 saved backup bundle to $TESTTMP/.hg/strip-backup/c05c06be7514-ed28c4cd-amend-backup.hg (glob)
477 saved backup bundle to $TESTTMP/.hg/strip-backup/c05c06be7514-ed28c4cd-amend-backup.hg (glob)
478 $ hg log -r . --template "{branch}\n"
478 $ hg log -r . --template "{branch}\n"
479 a
479 a
480
480
481 Also preserve other entries in the dict that are in the old commit,
481 Also preserve other entries in the dict that are in the old commit,
482 first graft something so there's an additional entry:
482 first graft something so there's an additional entry:
483
483
484 $ hg up 0 -q
484 $ hg up 0 -q
485 $ echo z > z
485 $ echo z > z
486 $ hg ci -Am 'fork'
486 $ hg ci -Am 'fork'
487 adding z
487 adding z
488 created new head
488 created new head
489 $ hg up 11
489 $ hg up 11
490 5 files updated, 0 files merged, 1 files removed, 0 files unresolved
490 5 files updated, 0 files merged, 1 files removed, 0 files unresolved
491 $ hg graft 12
491 $ hg graft 12
492 grafting 12:2647734878ef "fork" (tip)
492 grafting 12:2647734878ef "fork" (tip)
493 $ hg ci --amend -m 'graft amend'
493 $ hg ci --amend -m 'graft amend'
494 saved backup bundle to $TESTTMP/.hg/strip-backup/bd010aea3f39-eedb103b-amend-backup.hg (glob)
494 saved backup bundle to $TESTTMP/.hg/strip-backup/bd010aea3f39-eedb103b-amend-backup.hg (glob)
495 $ hg log -r . --debug | grep extra
495 $ hg log -r . --debug | grep extra
496 extra: amend_source=bd010aea3f39f3fb2a2f884b9ccb0471cd77398e
496 extra: amend_source=bd010aea3f39f3fb2a2f884b9ccb0471cd77398e
497 extra: branch=a
497 extra: branch=a
498 extra: source=2647734878ef0236dda712fae9c1651cf694ea8a
498 extra: source=2647734878ef0236dda712fae9c1651cf694ea8a
499
499
500 Preserve phase
500 Preserve phase
501
501
502 $ hg phase '.^::.'
502 $ hg phase '.^::.'
503 11: draft
503 11: draft
504 13: draft
504 13: draft
505 $ hg phase --secret --force .
505 $ hg phase --secret --force .
506 $ hg phase '.^::.'
506 $ hg phase '.^::.'
507 11: draft
507 11: draft
508 13: secret
508 13: secret
509 $ hg commit --amend -m 'amend for phase' -q
509 $ hg commit --amend -m 'amend for phase' -q
510 $ hg phase '.^::.'
510 $ hg phase '.^::.'
511 11: draft
511 11: draft
512 13: secret
512 13: secret
513
513
514 Test amend with obsolete
514 Test amend with obsolete
515 ---------------------------
515 ---------------------------
516
516
517 Enable obsolete
517 Enable obsolete
518
518
519 $ cat >> $HGRCPATH << EOF
519 $ cat >> $HGRCPATH << EOF
520 > [experimental]
520 > [experimental]
521 > evolution=createmarkers,allowunstable
521 > evolution=createmarkers,allowunstable
522 > EOF
522 > EOF
523
523
524 Amend with no files changes
524 Amend with no files changes
525
525
526 $ hg id -n
526 $ hg id -n
527 13
527 13
528 $ hg ci --amend -m 'babar'
528 $ hg ci --amend -m 'babar'
529 $ hg id -n
529 $ hg id -n
530 14
530 14
531 $ hg log -Gl 3 --style=compact
531 $ hg log -Gl 3 --style=compact
532 @ 14[tip]:11 b650e6ee8614 1970-01-01 00:00 +0000 test
532 @ 14[tip]:11 b650e6ee8614 1970-01-01 00:00 +0000 test
533 | babar
533 | babar
534 |
534 |
535 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
535 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
536 | | fork
536 | | fork
537 | |
537 | |
538 o | 11 3334b7925910 1970-01-01 00:00 +0000 test
538 o | 11 3334b7925910 1970-01-01 00:00 +0000 test
539 | | a''
539 | | a''
540 | |
540 | |
541 $ hg log -Gl 4 --hidden --style=compact
541 $ hg log -Gl 4 --hidden --style=compact
542 @ 14[tip]:11 b650e6ee8614 1970-01-01 00:00 +0000 test
542 @ 14[tip]:11 b650e6ee8614 1970-01-01 00:00 +0000 test
543 | babar
543 | babar
544 |
544 |
545 | x 13:11 68ff8ff97044 1970-01-01 00:00 +0000 test
545 | x 13:11 68ff8ff97044 1970-01-01 00:00 +0000 test
546 |/ amend for phase
546 |/ amend for phase
547 |
547 |
548 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
548 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
549 | | fork
549 | | fork
550 | |
550 | |
551 o | 11 3334b7925910 1970-01-01 00:00 +0000 test
551 o | 11 3334b7925910 1970-01-01 00:00 +0000 test
552 | | a''
552 | | a''
553 | |
553 | |
554
554
555 Amend with files changes
555 Amend with files changes
556
556
557 (note: the extra commit over 15 is a temporary junk I would be happy to get
557 (note: the extra commit over 15 is a temporary junk I would be happy to get
558 ride of)
558 ride of)
559
559
560 $ echo 'babar' >> a
560 $ echo 'babar' >> a
561 $ hg commit --amend
561 $ hg commit --amend
562 $ hg log -Gl 6 --hidden --style=compact
562 $ hg log -Gl 6 --hidden --style=compact
563 @ 16[tip]:11 9f9e9bccf56c 1970-01-01 00:00 +0000 test
563 @ 16[tip]:11 9f9e9bccf56c 1970-01-01 00:00 +0000 test
564 | babar
564 | babar
565 |
565 |
566 | x 15 90fef497c56f 1970-01-01 00:00 +0000 test
566 | x 15 90fef497c56f 1970-01-01 00:00 +0000 test
567 | | temporary amend commit for b650e6ee8614
567 | | temporary amend commit for b650e6ee8614
568 | |
568 | |
569 | x 14:11 b650e6ee8614 1970-01-01 00:00 +0000 test
569 | x 14:11 b650e6ee8614 1970-01-01 00:00 +0000 test
570 |/ babar
570 |/ babar
571 |
571 |
572 | x 13:11 68ff8ff97044 1970-01-01 00:00 +0000 test
572 | x 13:11 68ff8ff97044 1970-01-01 00:00 +0000 test
573 |/ amend for phase
573 |/ amend for phase
574 |
574 |
575 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
575 | o 12:0 2647734878ef 1970-01-01 00:00 +0000 test
576 | | fork
576 | | fork
577 | |
577 | |
578 o | 11 3334b7925910 1970-01-01 00:00 +0000 test
578 o | 11 3334b7925910 1970-01-01 00:00 +0000 test
579 | | a''
579 | | a''
580 | |
580 | |
581
581
582
582
583 Test that amend does not make it easy to create obsolescence cycle
583 Test that amend does not make it easy to create obsolescence cycle
584 ---------------------------------------------------------------------
584 ---------------------------------------------------------------------
585
585
586 $ hg id -r 14 --hidden
586 $ hg id -r 14 --hidden
587 b650e6ee8614 (a)
587 b650e6ee8614 (a)
588 $ hg revert -ar 14 --hidden
588 $ hg revert -ar 14 --hidden
589 reverting a
589 reverting a
590 $ hg commit --amend
590 $ hg commit --amend
591 $ hg id
591 $ hg id
592 b99e5df575f7 (a) tip
592 b99e5df575f7 (a) tip
593
593
594 Test that rewriting leaving instability behind is allowed
594 Test that rewriting leaving instability behind is allowed
595 ---------------------------------------------------------------------
595 ---------------------------------------------------------------------
596
596
597 $ hg up '.^'
597 $ hg up '.^'
598 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
598 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
599 $ echo 'b' >> a
599 $ echo 'b' >> a
600 $ hg log --style compact -r 'children(.)'
600 $ hg log --style compact -r 'children(.)'
601 18[tip]:11 b99e5df575f7 1970-01-01 00:00 +0000 test
601 18[tip]:11 b99e5df575f7 1970-01-01 00:00 +0000 test
602 babar
602 babar
603
603
604 $ hg commit --amend
604 $ hg commit --amend
605 $ hg log -r 'unstable()'
605 $ hg log -r 'unstable()'
606 changeset: 18:b99e5df575f7
606 changeset: 18:b99e5df575f7
607 branch: a
607 branch: a
608 parent: 11:3334b7925910
608 parent: 11:3334b7925910
609 user: test
609 user: test
610 date: Thu Jan 01 00:00:00 1970 +0000
610 date: Thu Jan 01 00:00:00 1970 +0000
611 summary: babar
611 summary: babar
612
612
613
613
614 Amend a merge changeset (with renames and conflicts from the second parent):
614 Amend a merge changeset (with renames and conflicts from the second parent):
615
615
616 $ hg up -q default
616 $ hg up -q default
617 $ hg branch -q bar
617 $ hg branch -q bar
618 $ hg cp a aa
618 $ hg cp a aa
619 $ hg mv z zz
619 $ hg mv z zz
620 $ echo cc > cc
620 $ echo cc > cc
621 $ hg add cc
621 $ hg add cc
622 $ hg ci -m aazzcc
622 $ hg ci -m aazzcc
623 $ hg up -q default
623 $ hg up -q default
624 $ echo a >> a
624 $ echo a >> a
625 $ echo dd > cc
625 $ echo dd > cc
626 $ hg add cc
626 $ hg add cc
627 $ hg ci -m aa
627 $ hg ci -m aa
628 $ hg merge -q bar
628 $ hg merge -q bar
629 warning: conflicts during merge.
629 warning: conflicts during merge.
630 merging cc incomplete! (edit conflicts, then use 'hg resolve --mark')
630 merging cc incomplete! (edit conflicts, then use 'hg resolve --mark')
631 [1]
631 [1]
632 $ hg resolve -m cc
632 $ hg resolve -m cc
633 (no more unresolved files)
633 (no more unresolved files)
634 $ hg ci -m 'merge bar'
634 $ hg ci -m 'merge bar'
635 $ hg log --config diff.git=1 -pr .
635 $ hg log --config diff.git=1 -pr .
636 changeset: 23:93cd4445f720
636 changeset: 23:93cd4445f720
637 tag: tip
637 tag: tip
638 parent: 22:30d96aeaf27b
638 parent: 22:30d96aeaf27b
639 parent: 21:1aa437659d19
639 parent: 21:1aa437659d19
640 user: test
640 user: test
641 date: Thu Jan 01 00:00:00 1970 +0000
641 date: Thu Jan 01 00:00:00 1970 +0000
642 summary: merge bar
642 summary: merge bar
643
643
644 diff --git a/a b/aa
644 diff --git a/a b/aa
645 copy from a
645 copy from a
646 copy to aa
646 copy to aa
647 diff --git a/cc b/cc
647 diff --git a/cc b/cc
648 --- a/cc
648 --- a/cc
649 +++ b/cc
649 +++ b/cc
650 @@ -1,1 +1,5 @@
650 @@ -1,1 +1,5 @@
651 +<<<<<<< local: 30d96aeaf27b - test: aa
651 +<<<<<<< local: 30d96aeaf27b - test: aa
652 dd
652 dd
653 +=======
653 +=======
654 +cc
654 +cc
655 +>>>>>>> other: 1aa437659d19 bar - test: aazzcc
655 +>>>>>>> other: 1aa437659d19 bar - test: aazzcc
656 diff --git a/z b/zz
656 diff --git a/z b/zz
657 rename from z
657 rename from z
658 rename to zz
658 rename to zz
659
659
660 $ hg debugrename aa
660 $ hg debugrename aa
661 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
661 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
662 $ hg debugrename zz
662 $ hg debugrename zz
663 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
663 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
664 $ hg debugrename cc
664 $ hg debugrename cc
665 cc not renamed
665 cc not renamed
666 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -m 'merge bar (amend message)' --edit
666 $ HGEDITOR="sh .hg/checkeditform.sh" hg ci --amend -m 'merge bar (amend message)' --edit
667 HGEDITFORM=commit.amend.merge
667 HGEDITFORM=commit.amend.merge
668 $ hg log --config diff.git=1 -pr .
668 $ hg log --config diff.git=1 -pr .
669 changeset: 24:832b50f2c271
669 changeset: 24:832b50f2c271
670 tag: tip
670 tag: tip
671 parent: 22:30d96aeaf27b
671 parent: 22:30d96aeaf27b
672 parent: 21:1aa437659d19
672 parent: 21:1aa437659d19
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: merge bar (amend message)
675 summary: merge bar (amend message)
676
676
677 diff --git a/a b/aa
677 diff --git a/a b/aa
678 copy from a
678 copy from a
679 copy to aa
679 copy to aa
680 diff --git a/cc b/cc
680 diff --git a/cc b/cc
681 --- a/cc
681 --- a/cc
682 +++ b/cc
682 +++ b/cc
683 @@ -1,1 +1,5 @@
683 @@ -1,1 +1,5 @@
684 +<<<<<<< local: 30d96aeaf27b - test: aa
684 +<<<<<<< local: 30d96aeaf27b - test: aa
685 dd
685 dd
686 +=======
686 +=======
687 +cc
687 +cc
688 +>>>>>>> other: 1aa437659d19 bar - test: aazzcc
688 +>>>>>>> other: 1aa437659d19 bar - test: aazzcc
689 diff --git a/z b/zz
689 diff --git a/z b/zz
690 rename from z
690 rename from z
691 rename to zz
691 rename to zz
692
692
693 $ hg debugrename aa
693 $ hg debugrename aa
694 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
694 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
695 $ hg debugrename zz
695 $ hg debugrename zz
696 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
696 zz renamed from z:69a1b67522704ec122181c0890bd16e9d3e7516a
697 $ hg debugrename cc
697 $ hg debugrename cc
698 cc not renamed
698 cc not renamed
699 $ hg mv zz z
699 $ hg mv zz z
700 $ hg ci --amend -m 'merge bar (undo rename)'
700 $ hg ci --amend -m 'merge bar (undo rename)'
701 $ hg log --config diff.git=1 -pr .
701 $ hg log --config diff.git=1 -pr .
702 changeset: 26:bdafc5c72f74
702 changeset: 26:bdafc5c72f74
703 tag: tip
703 tag: tip
704 parent: 22:30d96aeaf27b
704 parent: 22:30d96aeaf27b
705 parent: 21:1aa437659d19
705 parent: 21:1aa437659d19
706 user: test
706 user: test
707 date: Thu Jan 01 00:00:00 1970 +0000
707 date: Thu Jan 01 00:00:00 1970 +0000
708 summary: merge bar (undo rename)
708 summary: merge bar (undo rename)
709
709
710 diff --git a/a b/aa
710 diff --git a/a b/aa
711 copy from a
711 copy from a
712 copy to aa
712 copy to aa
713 diff --git a/cc b/cc
713 diff --git a/cc b/cc
714 --- a/cc
714 --- a/cc
715 +++ b/cc
715 +++ b/cc
716 @@ -1,1 +1,5 @@
716 @@ -1,1 +1,5 @@
717 +<<<<<<< local: 30d96aeaf27b - test: aa
717 +<<<<<<< local: 30d96aeaf27b - test: aa
718 dd
718 dd
719 +=======
719 +=======
720 +cc
720 +cc
721 +>>>>>>> other: 1aa437659d19 bar - test: aazzcc
721 +>>>>>>> other: 1aa437659d19 bar - test: aazzcc
722
722
723 $ hg debugrename z
723 $ hg debugrename z
724 z not renamed
724 z not renamed
725
725
726 Amend a merge changeset (with renames during the merge):
726 Amend a merge changeset (with renames during the merge):
727
727
728 $ hg up -q bar
728 $ hg up -q bar
729 $ echo x > x
729 $ echo x > x
730 $ hg add x
730 $ hg add x
731 $ hg ci -m x
731 $ hg ci -m x
732 $ hg up -q default
732 $ hg up -q default
733 $ hg merge -q bar
733 $ hg merge -q bar
734 $ hg mv aa aaa
734 $ hg mv aa aaa
735 $ echo aa >> aaa
735 $ echo aa >> aaa
736 $ hg ci -m 'merge bar again'
736 $ hg ci -m 'merge bar again'
737 $ hg log --config diff.git=1 -pr .
737 $ hg log --config diff.git=1 -pr .
738 changeset: 28:32f19415b634
738 changeset: 28:32f19415b634
739 tag: tip
739 tag: tip
740 parent: 26:bdafc5c72f74
740 parent: 26:bdafc5c72f74
741 parent: 27:4c94d5bc65f5
741 parent: 27:4c94d5bc65f5
742 user: test
742 user: test
743 date: Thu Jan 01 00:00:00 1970 +0000
743 date: Thu Jan 01 00:00:00 1970 +0000
744 summary: merge bar again
744 summary: merge bar again
745
745
746 diff --git a/aa b/aa
746 diff --git a/aa b/aa
747 deleted file mode 100644
747 deleted file mode 100644
748 --- a/aa
748 --- a/aa
749 +++ /dev/null
749 +++ /dev/null
750 @@ -1,2 +0,0 @@
750 @@ -1,2 +0,0 @@
751 -a
751 -a
752 -a
752 -a
753 diff --git a/aaa b/aaa
753 diff --git a/aaa b/aaa
754 new file mode 100644
754 new file mode 100644
755 --- /dev/null
755 --- /dev/null
756 +++ b/aaa
756 +++ b/aaa
757 @@ -0,0 +1,3 @@
757 @@ -0,0 +1,3 @@
758 +a
758 +a
759 +a
759 +a
760 +aa
760 +aa
761 diff --git a/x b/x
761 diff --git a/x b/x
762 new file mode 100644
762 new file mode 100644
763 --- /dev/null
763 --- /dev/null
764 +++ b/x
764 +++ b/x
765 @@ -0,0 +1,1 @@
765 @@ -0,0 +1,1 @@
766 +x
766 +x
767
767
768 $ hg debugrename aaa
768 $ hg debugrename aaa
769 aaa renamed from aa:37d9b5d994eab34eda9c16b195ace52c7b129980
769 aaa renamed from aa:37d9b5d994eab34eda9c16b195ace52c7b129980
770 $ hg mv aaa aa
770 $ hg mv aaa aa
771 $ hg ci --amend -m 'merge bar again (undo rename)'
771 $ hg ci --amend -m 'merge bar again (undo rename)'
772 $ hg log --config diff.git=1 -pr .
772 $ hg log --config diff.git=1 -pr .
773 changeset: 30:1e2a06b3d312
773 changeset: 30:1e2a06b3d312
774 tag: tip
774 tag: tip
775 parent: 26:bdafc5c72f74
775 parent: 26:bdafc5c72f74
776 parent: 27:4c94d5bc65f5
776 parent: 27:4c94d5bc65f5
777 user: test
777 user: test
778 date: Thu Jan 01 00:00:00 1970 +0000
778 date: Thu Jan 01 00:00:00 1970 +0000
779 summary: merge bar again (undo rename)
779 summary: merge bar again (undo rename)
780
780
781 diff --git a/aa b/aa
781 diff --git a/aa b/aa
782 --- a/aa
782 --- a/aa
783 +++ b/aa
783 +++ b/aa
784 @@ -1,2 +1,3 @@
784 @@ -1,2 +1,3 @@
785 a
785 a
786 a
786 a
787 +aa
787 +aa
788 diff --git a/x b/x
788 diff --git a/x b/x
789 new file mode 100644
789 new file mode 100644
790 --- /dev/null
790 --- /dev/null
791 +++ b/x
791 +++ b/x
792 @@ -0,0 +1,1 @@
792 @@ -0,0 +1,1 @@
793 +x
793 +x
794
794
795 $ hg debugrename aa
795 $ hg debugrename aa
796 aa not renamed
796 aa not renamed
797 $ hg debugrename -r '.^' aa
797 $ hg debugrename -r '.^' aa
798 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
798 aa renamed from a:a80d06849b333b8a3d5c445f8ba3142010dcdc9e
799
799
800 Amend a merge changeset (with manifest-level conflicts):
800 Amend a merge changeset (with manifest-level conflicts):
801
801
802 $ hg up -q bar
802 $ hg up -q bar
803 $ hg rm aa
803 $ hg rm aa
804 $ hg ci -m 'rm aa'
804 $ hg ci -m 'rm aa'
805 $ hg up -q default
805 $ hg up -q default
806 $ echo aa >> aa
806 $ echo aa >> aa
807 $ hg ci -m aa
807 $ hg ci -m aa
808 $ hg merge -q bar
808 $ hg merge -q bar
809 local changed aa which remote deleted
809 local changed aa which remote deleted
810 use (c)hanged version or (d)elete? c
810 use (c)hanged version or (d)elete? c
811 $ hg ci -m 'merge bar (with conflicts)'
811 $ hg ci -m 'merge bar (with conflicts)'
812 $ hg log --config diff.git=1 -pr .
812 $ hg log --config diff.git=1 -pr .
813 changeset: 33:97a298b0c59f
813 changeset: 33:97a298b0c59f
814 tag: tip
814 tag: tip
815 parent: 32:3d78ce4226b8
815 parent: 32:3d78ce4226b8
816 parent: 31:67db8847a540
816 parent: 31:67db8847a540
817 user: test
817 user: test
818 date: Thu Jan 01 00:00:00 1970 +0000
818 date: Thu Jan 01 00:00:00 1970 +0000
819 summary: merge bar (with conflicts)
819 summary: merge bar (with conflicts)
820
820
821
821
822 $ hg rm aa
822 $ hg rm aa
823 $ hg ci --amend -m 'merge bar (with conflicts, amended)'
823 $ hg ci --amend -m 'merge bar (with conflicts, amended)'
824 $ hg log --config diff.git=1 -pr .
824 $ hg log --config diff.git=1 -pr .
825 changeset: 35:6de0c1bde1c8
825 changeset: 35:6de0c1bde1c8
826 tag: tip
826 tag: tip
827 parent: 32:3d78ce4226b8
827 parent: 32:3d78ce4226b8
828 parent: 31:67db8847a540
828 parent: 31:67db8847a540
829 user: test
829 user: test
830 date: Thu Jan 01 00:00:00 1970 +0000
830 date: Thu Jan 01 00:00:00 1970 +0000
831 summary: merge bar (with conflicts, amended)
831 summary: merge bar (with conflicts, amended)
832
832
833 diff --git a/aa b/aa
833 diff --git a/aa b/aa
834 deleted file mode 100644
834 deleted file mode 100644
835 --- a/aa
835 --- a/aa
836 +++ /dev/null
836 +++ /dev/null
837 @@ -1,4 +0,0 @@
837 @@ -1,4 +0,0 @@
838 -a
838 -a
839 -a
839 -a
840 -aa
840 -aa
841 -aa
841 -aa
842
842
843 Issue 3445: amending with --close-branch a commit that created a new head should fail
843 Issue 3445: amending with --close-branch a commit that created a new head should fail
844 This shouldn't be possible:
844 This shouldn't be possible:
845
845
846 $ hg up -q default
846 $ hg up -q default
847 $ hg branch closewithamend
847 $ hg branch closewithamend
848 marked working directory as branch closewithamend
848 marked working directory as branch closewithamend
849 (branches are permanent and global, did you want a bookmark?)
849 (branches are permanent and global, did you want a bookmark?)
850 $ echo foo > foo
850 $ echo foo > foo
851 $ hg add foo
851 $ hg add foo
852 $ hg ci -m..
852 $ hg ci -m..
853 $ hg ci --amend --close-branch -m 'closing'
853 $ hg ci --amend --close-branch -m 'closing'
854 abort: can only close branch heads
854 abort: can only close branch heads
855 [255]
855 [255]
856
856
857 This silliness fails:
857 This silliness fails:
858
858
859 $ hg branch silliness
859 $ hg branch silliness
860 marked working directory as branch silliness
860 marked working directory as branch silliness
861 (branches are permanent and global, did you want a bookmark?)
861 (branches are permanent and global, did you want a bookmark?)
862 $ echo b >> b
862 $ echo b >> b
863 $ hg ci --close-branch -m'open and close'
863 $ hg ci --close-branch -m'open and close'
864 abort: can only close branch heads
864 abort: can only close branch heads
865 [255]
865 [255]
866
866
867 Test that amend with --secret creates new secret changeset forcibly
867 Test that amend with --secret creates new secret changeset forcibly
868 ---------------------------------------------------------------------
868 ---------------------------------------------------------------------
869
869
870 $ hg phase '.^::.'
870 $ hg phase '.^::.'
871 35: draft
871 35: draft
872 36: draft
872 36: draft
873 $ hg commit --amend --secret -m 'amend as secret' -q
873 $ hg commit --amend --secret -m 'amend as secret' -q
874 $ hg phase '.^::.'
874 $ hg phase '.^::.'
875 35: draft
875 35: draft
876 38: secret
876 38: secret
877
877
878 Test that amend with --edit invokes editor forcibly
878 Test that amend with --edit invokes editor forcibly
879 ---------------------------------------------------
879 ---------------------------------------------------
880
880
881 $ hg parents --template "{desc}\n"
881 $ hg parents --template "{desc}\n"
882 amend as secret
882 amend as secret
883 $ HGEDITOR=cat hg commit --amend -m "editor should be suppressed"
883 $ HGEDITOR=cat hg commit --amend -m "editor should be suppressed"
884 $ hg parents --template "{desc}\n"
884 $ hg parents --template "{desc}\n"
885 editor should be suppressed
885 editor should be suppressed
886
886
887 $ hg status --rev '.^1::.'
887 $ hg status --rev '.^1::.'
888 A foo
888 A foo
889 $ HGEDITOR=cat hg commit --amend -m "editor should be invoked" --edit
889 $ HGEDITOR=cat hg commit --amend -m "editor should be invoked" --edit
890 editor should be invoked
890 editor should be invoked
891
891
892
892
893 HG: Enter commit message. Lines beginning with 'HG:' are removed.
893 HG: Enter commit message. Lines beginning with 'HG:' are removed.
894 HG: Leave message empty to abort commit.
894 HG: Leave message empty to abort commit.
895 HG: --
895 HG: --
896 HG: user: test
896 HG: user: test
897 HG: branch 'silliness'
897 HG: branch 'silliness'
898 HG: added foo
898 HG: added foo
899 $ hg parents --template "{desc}\n"
899 $ hg parents --template "{desc}\n"
900 editor should be invoked
900 editor should be invoked
901
901
902 Test that "diff()" in committemplate works correctly for amending
902 Test that "diff()" in committemplate works correctly for amending
903 -----------------------------------------------------------------
903 -----------------------------------------------------------------
904
904
905 $ cat >> .hg/hgrc <<EOF
905 $ cat >> .hg/hgrc <<EOF
906 > [committemplate]
906 > [committemplate]
907 > changeset.commit.amend = {desc}\n
907 > changeset.commit.amend = {desc}\n
908 > HG: M: {file_mods}
908 > HG: M: {file_mods}
909 > HG: A: {file_adds}
909 > HG: A: {file_adds}
910 > HG: R: {file_dels}
910 > HG: R: {file_dels}
911 > {splitlines(diff()) % 'HG: {line}\n'}
911 > {splitlines(diff()) % 'HG: {line}\n'}
912 > EOF
912 > EOF
913
913
914 $ hg parents --template "M: {file_mods}\nA: {file_adds}\nR: {file_dels}\n"
914 $ hg parents --template "M: {file_mods}\nA: {file_adds}\nR: {file_dels}\n"
915 M:
915 M:
916 A: foo
916 A: foo
917 R:
917 R:
918 $ hg status -amr
918 $ hg status -amr
919 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo"
919 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo"
920 expecting diff of foo
920 expecting diff of foo
921
921
922 HG: M:
922 HG: M:
923 HG: A: foo
923 HG: A: foo
924 HG: R:
924 HG: R:
925 HG: diff -r 6de0c1bde1c8 foo
925 HG: diff -r 6de0c1bde1c8 foo
926 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
926 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
927 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
927 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
928 HG: @@ -0,0 +1,1 @@
928 HG: @@ -0,0 +1,1 @@
929 HG: +foo
929 HG: +foo
930
930
931 $ echo y > y
931 $ echo y > y
932 $ hg add y
932 $ hg add y
933 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo and y"
933 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of foo and y"
934 expecting diff of foo and y
934 expecting diff of foo and y
935
935
936 HG: M:
936 HG: M:
937 HG: A: foo y
937 HG: A: foo y
938 HG: R:
938 HG: R:
939 HG: diff -r 6de0c1bde1c8 foo
939 HG: diff -r 6de0c1bde1c8 foo
940 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
940 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
941 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
941 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
942 HG: @@ -0,0 +1,1 @@
942 HG: @@ -0,0 +1,1 @@
943 HG: +foo
943 HG: +foo
944 HG: diff -r 6de0c1bde1c8 y
944 HG: diff -r 6de0c1bde1c8 y
945 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
945 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
946 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
946 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
947 HG: @@ -0,0 +1,1 @@
947 HG: @@ -0,0 +1,1 @@
948 HG: +y
948 HG: +y
949
949
950 $ hg rm a
950 $ hg rm a
951 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo and y"
951 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo and y"
952 expecting diff of a, foo and y
952 expecting diff of a, foo and y
953
953
954 HG: M:
954 HG: M:
955 HG: A: foo y
955 HG: A: foo y
956 HG: R: a
956 HG: R: a
957 HG: diff -r 6de0c1bde1c8 a
957 HG: diff -r 6de0c1bde1c8 a
958 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
958 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
959 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
959 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
960 HG: @@ -1,2 +0,0 @@
960 HG: @@ -1,2 +0,0 @@
961 HG: -a
961 HG: -a
962 HG: -a
962 HG: -a
963 HG: diff -r 6de0c1bde1c8 foo
963 HG: diff -r 6de0c1bde1c8 foo
964 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
964 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
965 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
965 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
966 HG: @@ -0,0 +1,1 @@
966 HG: @@ -0,0 +1,1 @@
967 HG: +foo
967 HG: +foo
968 HG: diff -r 6de0c1bde1c8 y
968 HG: diff -r 6de0c1bde1c8 y
969 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
969 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
970 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
970 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
971 HG: @@ -0,0 +1,1 @@
971 HG: @@ -0,0 +1,1 @@
972 HG: +y
972 HG: +y
973
973
974 $ hg rm x
974 $ hg rm x
975 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo, x and y"
975 $ HGEDITOR=cat hg commit --amend -e -m "expecting diff of a, foo, x and y"
976 expecting diff of a, foo, x and y
976 expecting diff of a, foo, x and y
977
977
978 HG: M:
978 HG: M:
979 HG: A: foo y
979 HG: A: foo y
980 HG: R: a x
980 HG: R: a x
981 HG: diff -r 6de0c1bde1c8 a
981 HG: diff -r 6de0c1bde1c8 a
982 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
982 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
983 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
983 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
984 HG: @@ -1,2 +0,0 @@
984 HG: @@ -1,2 +0,0 @@
985 HG: -a
985 HG: -a
986 HG: -a
986 HG: -a
987 HG: diff -r 6de0c1bde1c8 foo
987 HG: diff -r 6de0c1bde1c8 foo
988 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
988 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
989 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
989 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
990 HG: @@ -0,0 +1,1 @@
990 HG: @@ -0,0 +1,1 @@
991 HG: +foo
991 HG: +foo
992 HG: diff -r 6de0c1bde1c8 x
992 HG: diff -r 6de0c1bde1c8 x
993 HG: --- a/x Thu Jan 01 00:00:00 1970 +0000
993 HG: --- a/x Thu Jan 01 00:00:00 1970 +0000
994 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
994 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
995 HG: @@ -1,1 +0,0 @@
995 HG: @@ -1,1 +0,0 @@
996 HG: -x
996 HG: -x
997 HG: diff -r 6de0c1bde1c8 y
997 HG: diff -r 6de0c1bde1c8 y
998 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
998 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
999 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
999 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
1000 HG: @@ -0,0 +1,1 @@
1000 HG: @@ -0,0 +1,1 @@
1001 HG: +y
1001 HG: +y
1002
1002
1003 $ echo cccc >> cc
1004 $ hg status -amr
1005 M cc
1006 $ HGEDITOR=cat hg commit --amend -e -m "cc should be excluded" -X cc
1007 cc should be excluded
1008
1009 HG: M:
1010 HG: A: foo y
1011 HG: R: a x
1012 HG: diff -r 6de0c1bde1c8 a
1013 HG: --- a/a Thu Jan 01 00:00:00 1970 +0000
1014 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1015 HG: @@ -1,2 +0,0 @@
1016 HG: -a
1017 HG: -a
1018 HG: diff -r 6de0c1bde1c8 foo
1019 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1020 HG: +++ b/foo Thu Jan 01 00:00:00 1970 +0000
1021 HG: @@ -0,0 +1,1 @@
1022 HG: +foo
1023 HG: diff -r 6de0c1bde1c8 x
1024 HG: --- a/x Thu Jan 01 00:00:00 1970 +0000
1025 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1026 HG: @@ -1,1 +0,0 @@
1027 HG: -x
1028 HG: diff -r 6de0c1bde1c8 y
1029 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1030 HG: +++ b/y Thu Jan 01 00:00:00 1970 +0000
1031 HG: @@ -0,0 +1,1 @@
1032 HG: +y
1033
1003 Check for issue4405
1034 Check for issue4405
1004 -------------------
1035 -------------------
1005
1036
1006 Setup the repo with a file that gets moved in a second commit.
1037 Setup the repo with a file that gets moved in a second commit.
1007 $ hg init repo
1038 $ hg init repo
1008 $ cd repo
1039 $ cd repo
1009 $ touch a0
1040 $ touch a0
1010 $ hg add a0
1041 $ hg add a0
1011 $ hg commit -m a0
1042 $ hg commit -m a0
1012 $ hg mv a0 a1
1043 $ hg mv a0 a1
1013 $ hg commit -m a1
1044 $ hg commit -m a1
1014 $ hg up -q 0
1045 $ hg up -q 0
1015 $ hg log -G --template '{rev} {desc}'
1046 $ hg log -G --template '{rev} {desc}'
1016 o 1 a1
1047 o 1 a1
1017 |
1048 |
1018 @ 0 a0
1049 @ 0 a0
1019
1050
1020
1051
1021 Now we branch the repro, but re-use the file contents, so we have a divergence
1052 Now we branch the repro, but re-use the file contents, so we have a divergence
1022 in the file revlog topology and the changelog topology.
1053 in the file revlog topology and the changelog topology.
1023 $ hg revert --rev 1 --all
1054 $ hg revert --rev 1 --all
1024 removing a0
1055 removing a0
1025 adding a1
1056 adding a1
1026 $ hg ci -qm 'a1-amend'
1057 $ hg ci -qm 'a1-amend'
1027 $ hg log -G --template '{rev} {desc}'
1058 $ hg log -G --template '{rev} {desc}'
1028 @ 2 a1-amend
1059 @ 2 a1-amend
1029 |
1060 |
1030 | o 1 a1
1061 | o 1 a1
1031 |/
1062 |/
1032 o 0 a0
1063 o 0 a0
1033
1064
1034
1065
1035 The way mercurial does amends is to create a temporary commit (rev 3) and then
1066 The way mercurial does amends is to create a temporary commit (rev 3) and then
1036 fold the new and old commits together into another commit (rev 4). During this
1067 fold the new and old commits together into another commit (rev 4). During this
1037 process, _findlimit is called to check how far back to look for the transitive
1068 process, _findlimit is called to check how far back to look for the transitive
1038 closure of file copy information, but due to the divergence of the filelog
1069 closure of file copy information, but due to the divergence of the filelog
1039 and changelog graph topologies, before _findlimit was fixed, it returned a rev
1070 and changelog graph topologies, before _findlimit was fixed, it returned a rev
1040 which was not far enough back in this case.
1071 which was not far enough back in this case.
1041 $ hg mv a1 a2
1072 $ hg mv a1 a2
1042 $ hg status --copies --rev 0
1073 $ hg status --copies --rev 0
1043 A a2
1074 A a2
1044 a0
1075 a0
1045 R a0
1076 R a0
1046 $ hg ci --amend -q
1077 $ hg ci --amend -q
1047 $ hg log -G --template '{rev} {desc}'
1078 $ hg log -G --template '{rev} {desc}'
1048 @ 4 a1-amend
1079 @ 4 a1-amend
1049 |
1080 |
1050 | o 1 a1
1081 | o 1 a1
1051 |/
1082 |/
1052 o 0 a0
1083 o 0 a0
1053
1084
1054
1085
1055 Before the fix, the copy information was lost.
1086 Before the fix, the copy information was lost.
1056 $ hg status --copies --rev 0
1087 $ hg status --copies --rev 0
1057 A a2
1088 A a2
1058 a0
1089 a0
1059 R a0
1090 R a0
1060 $ cd ..
1091 $ cd ..
1061
1092
1062 Check that amend properly preserve rename from directory rename (issue-4516)
1093 Check that amend properly preserve rename from directory rename (issue-4516)
1063
1094
1064 If a parent of the merge renames a full directory, any files added to the old
1095 If a parent of the merge renames a full directory, any files added to the old
1065 directory in the other parent will be renamed to the new directory. For some
1096 directory in the other parent will be renamed to the new directory. For some
1066 reason, the rename metadata was when amending such merge. This test ensure we
1097 reason, the rename metadata was when amending such merge. This test ensure we
1067 do not regress. We have a dedicated repo because it needs a setup with renamed
1098 do not regress. We have a dedicated repo because it needs a setup with renamed
1068 directory)
1099 directory)
1069
1100
1070 $ hg init issue4516
1101 $ hg init issue4516
1071 $ cd issue4516
1102 $ cd issue4516
1072 $ mkdir olddirname
1103 $ mkdir olddirname
1073 $ echo line1 > olddirname/commonfile.py
1104 $ echo line1 > olddirname/commonfile.py
1074 $ hg add olddirname/commonfile.py
1105 $ hg add olddirname/commonfile.py
1075 $ hg ci -m first
1106 $ hg ci -m first
1076
1107
1077 $ hg branch newdirname
1108 $ hg branch newdirname
1078 marked working directory as branch newdirname
1109 marked working directory as branch newdirname
1079 (branches are permanent and global, did you want a bookmark?)
1110 (branches are permanent and global, did you want a bookmark?)
1080 $ hg mv olddirname newdirname
1111 $ hg mv olddirname newdirname
1081 moving olddirname/commonfile.py to newdirname/commonfile.py (glob)
1112 moving olddirname/commonfile.py to newdirname/commonfile.py (glob)
1082 $ hg ci -m rename
1113 $ hg ci -m rename
1083
1114
1084 $ hg update default
1115 $ hg update default
1085 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1116 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1086 $ echo line1 > olddirname/newfile.py
1117 $ echo line1 > olddirname/newfile.py
1087 $ hg add olddirname/newfile.py
1118 $ hg add olddirname/newfile.py
1088 $ hg ci -m log
1119 $ hg ci -m log
1089
1120
1090 $ hg up newdirname
1121 $ hg up newdirname
1091 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1122 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1092 $ # create newdirname/newfile.py
1123 $ # create newdirname/newfile.py
1093 $ hg merge default
1124 $ hg merge default
1094 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1125 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1095 (branch merge, don't forget to commit)
1126 (branch merge, don't forget to commit)
1096 $ hg ci -m add
1127 $ hg ci -m add
1097 $
1128 $
1098 $ hg debugrename newdirname/newfile.py
1129 $ hg debugrename newdirname/newfile.py
1099 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def (glob)
1130 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def (glob)
1100 $ hg status -C --change .
1131 $ hg status -C --change .
1101 A newdirname/newfile.py
1132 A newdirname/newfile.py
1102 $ hg status -C --rev 1
1133 $ hg status -C --rev 1
1103 A newdirname/newfile.py
1134 A newdirname/newfile.py
1104 $ hg status -C --rev 2
1135 $ hg status -C --rev 2
1105 A newdirname/commonfile.py
1136 A newdirname/commonfile.py
1106 olddirname/commonfile.py
1137 olddirname/commonfile.py
1107 A newdirname/newfile.py
1138 A newdirname/newfile.py
1108 olddirname/newfile.py
1139 olddirname/newfile.py
1109 R olddirname/commonfile.py
1140 R olddirname/commonfile.py
1110 R olddirname/newfile.py
1141 R olddirname/newfile.py
1111 $ hg debugindex newdirname/newfile.py
1142 $ hg debugindex newdirname/newfile.py
1112 rev offset length base linkrev nodeid p1 p2
1143 rev offset length base linkrev nodeid p1 p2
1113 0 0 88 0 3 34a4d536c0c0 000000000000 000000000000
1144 0 0 88 0 3 34a4d536c0c0 000000000000 000000000000
1114
1145
1115 $ echo a >> newdirname/commonfile.py
1146 $ echo a >> newdirname/commonfile.py
1116 $ hg ci --amend -m bug
1147 $ hg ci --amend -m bug
1117 $ hg debugrename newdirname/newfile.py
1148 $ hg debugrename newdirname/newfile.py
1118 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def (glob)
1149 newdirname/newfile.py renamed from olddirname/newfile.py:690b295714aed510803d3020da9c70fca8336def (glob)
1119 $ hg debugindex newdirname/newfile.py
1150 $ hg debugindex newdirname/newfile.py
1120 rev offset length base linkrev nodeid p1 p2
1151 rev offset length base linkrev nodeid p1 p2
1121 0 0 88 0 3 34a4d536c0c0 000000000000 000000000000
1152 0 0 88 0 3 34a4d536c0c0 000000000000 000000000000
1122
1153
@@ -1,604 +1,640 b''
1 commit date test
1 commit date test
2
2
3 $ hg init test
3 $ hg init test
4 $ cd test
4 $ cd test
5 $ echo foo > foo
5 $ echo foo > foo
6 $ hg add foo
6 $ hg add foo
7 $ cat > $TESTTMP/checkeditform.sh <<EOF
7 $ cat > $TESTTMP/checkeditform.sh <<EOF
8 > env | grep HGEDITFORM
8 > env | grep HGEDITFORM
9 > true
9 > true
10 > EOF
10 > EOF
11 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg commit -m ""
11 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg commit -m ""
12 HGEDITFORM=commit.normal.normal
12 HGEDITFORM=commit.normal.normal
13 abort: empty commit message
13 abort: empty commit message
14 [255]
14 [255]
15 $ hg commit -d '0 0' -m commit-1
15 $ hg commit -d '0 0' -m commit-1
16 $ echo foo >> foo
16 $ echo foo >> foo
17 $ hg commit -d '1 4444444' -m commit-3
17 $ hg commit -d '1 4444444' -m commit-3
18 abort: impossible time zone offset: 4444444
18 abort: impossible time zone offset: 4444444
19 [255]
19 [255]
20 $ hg commit -d '1 15.1' -m commit-4
20 $ hg commit -d '1 15.1' -m commit-4
21 abort: invalid date: '1\t15.1'
21 abort: invalid date: '1\t15.1'
22 [255]
22 [255]
23 $ hg commit -d 'foo bar' -m commit-5
23 $ hg commit -d 'foo bar' -m commit-5
24 abort: invalid date: 'foo bar'
24 abort: invalid date: 'foo bar'
25 [255]
25 [255]
26 $ hg commit -d ' 1 4444' -m commit-6
26 $ hg commit -d ' 1 4444' -m commit-6
27 $ hg commit -d '111111111111 0' -m commit-7
27 $ hg commit -d '111111111111 0' -m commit-7
28 abort: date exceeds 32 bits: 111111111111
28 abort: date exceeds 32 bits: 111111111111
29 [255]
29 [255]
30 $ hg commit -d '-7654321 3600' -m commit-7
30 $ hg commit -d '-7654321 3600' -m commit-7
31 abort: negative date value: -7654321
31 abort: negative date value: -7654321
32 [255]
32 [255]
33
33
34 commit added file that has been deleted
34 commit added file that has been deleted
35
35
36 $ echo bar > bar
36 $ echo bar > bar
37 $ hg add bar
37 $ hg add bar
38 $ rm bar
38 $ rm bar
39 $ hg commit -m commit-8
39 $ hg commit -m commit-8
40 nothing changed (1 missing files, see 'hg status')
40 nothing changed (1 missing files, see 'hg status')
41 [1]
41 [1]
42 $ hg commit -m commit-8-2 bar
42 $ hg commit -m commit-8-2 bar
43 abort: bar: file not found!
43 abort: bar: file not found!
44 [255]
44 [255]
45
45
46 $ hg -q revert -a --no-backup
46 $ hg -q revert -a --no-backup
47
47
48 $ mkdir dir
48 $ mkdir dir
49 $ echo boo > dir/file
49 $ echo boo > dir/file
50 $ hg add
50 $ hg add
51 adding dir/file (glob)
51 adding dir/file (glob)
52 $ hg -v commit -m commit-9 dir
52 $ hg -v commit -m commit-9 dir
53 committing files:
53 committing files:
54 dir/file
54 dir/file
55 committing manifest
55 committing manifest
56 committing changelog
56 committing changelog
57 committed changeset 2:d2a76177cb42
57 committed changeset 2:d2a76177cb42
58
58
59 $ echo > dir.file
59 $ echo > dir.file
60 $ hg add
60 $ hg add
61 adding dir.file
61 adding dir.file
62 $ hg commit -m commit-10 dir dir.file
62 $ hg commit -m commit-10 dir dir.file
63 abort: dir: no match under directory!
63 abort: dir: no match under directory!
64 [255]
64 [255]
65
65
66 $ echo >> dir/file
66 $ echo >> dir/file
67 $ mkdir bleh
67 $ mkdir bleh
68 $ mkdir dir2
68 $ mkdir dir2
69 $ cd bleh
69 $ cd bleh
70 $ hg commit -m commit-11 .
70 $ hg commit -m commit-11 .
71 abort: bleh: no match under directory!
71 abort: bleh: no match under directory!
72 [255]
72 [255]
73 $ hg commit -m commit-12 ../dir ../dir2
73 $ hg commit -m commit-12 ../dir ../dir2
74 abort: dir2: no match under directory!
74 abort: dir2: no match under directory!
75 [255]
75 [255]
76 $ hg -v commit -m commit-13 ../dir
76 $ hg -v commit -m commit-13 ../dir
77 committing files:
77 committing files:
78 dir/file
78 dir/file
79 committing manifest
79 committing manifest
80 committing changelog
80 committing changelog
81 committed changeset 3:1cd62a2d8db5
81 committed changeset 3:1cd62a2d8db5
82 $ cd ..
82 $ cd ..
83
83
84 $ hg commit -m commit-14 does-not-exist
84 $ hg commit -m commit-14 does-not-exist
85 abort: does-not-exist: * (glob)
85 abort: does-not-exist: * (glob)
86 [255]
86 [255]
87
87
88 #if symlink
88 #if symlink
89 $ ln -s foo baz
89 $ ln -s foo baz
90 $ hg commit -m commit-15 baz
90 $ hg commit -m commit-15 baz
91 abort: baz: file not tracked!
91 abort: baz: file not tracked!
92 [255]
92 [255]
93 #endif
93 #endif
94
94
95 $ touch quux
95 $ touch quux
96 $ hg commit -m commit-16 quux
96 $ hg commit -m commit-16 quux
97 abort: quux: file not tracked!
97 abort: quux: file not tracked!
98 [255]
98 [255]
99 $ echo >> dir/file
99 $ echo >> dir/file
100 $ hg -v commit -m commit-17 dir/file
100 $ hg -v commit -m commit-17 dir/file
101 committing files:
101 committing files:
102 dir/file
102 dir/file
103 committing manifest
103 committing manifest
104 committing changelog
104 committing changelog
105 committed changeset 4:49176991390e
105 committed changeset 4:49176991390e
106
106
107 An empty date was interpreted as epoch origin
107 An empty date was interpreted as epoch origin
108
108
109 $ echo foo >> foo
109 $ echo foo >> foo
110 $ hg commit -d '' -m commit-no-date
110 $ hg commit -d '' -m commit-no-date
111 $ hg tip --template '{date|isodate}\n' | grep '1970'
111 $ hg tip --template '{date|isodate}\n' | grep '1970'
112 [1]
112 [1]
113
113
114 Make sure we do not obscure unknown requires file entries (issue2649)
114 Make sure we do not obscure unknown requires file entries (issue2649)
115
115
116 $ echo foo >> foo
116 $ echo foo >> foo
117 $ echo fake >> .hg/requires
117 $ echo fake >> .hg/requires
118 $ hg commit -m bla
118 $ hg commit -m bla
119 abort: repository requires features unknown to this Mercurial: fake!
119 abort: repository requires features unknown to this Mercurial: fake!
120 (see http://mercurial.selenic.com/wiki/MissingRequirement for more information)
120 (see http://mercurial.selenic.com/wiki/MissingRequirement for more information)
121 [255]
121 [255]
122
122
123 $ cd ..
123 $ cd ..
124
124
125
125
126 partial subdir commit test
126 partial subdir commit test
127
127
128 $ hg init test2
128 $ hg init test2
129 $ cd test2
129 $ cd test2
130 $ mkdir foo
130 $ mkdir foo
131 $ echo foo > foo/foo
131 $ echo foo > foo/foo
132 $ mkdir bar
132 $ mkdir bar
133 $ echo bar > bar/bar
133 $ echo bar > bar/bar
134 $ hg add
134 $ hg add
135 adding bar/bar (glob)
135 adding bar/bar (glob)
136 adding foo/foo (glob)
136 adding foo/foo (glob)
137 $ HGEDITOR=cat hg ci -e -m commit-subdir-1 foo
137 $ HGEDITOR=cat hg ci -e -m commit-subdir-1 foo
138 commit-subdir-1
138 commit-subdir-1
139
139
140
140
141 HG: Enter commit message. Lines beginning with 'HG:' are removed.
141 HG: Enter commit message. Lines beginning with 'HG:' are removed.
142 HG: Leave message empty to abort commit.
142 HG: Leave message empty to abort commit.
143 HG: --
143 HG: --
144 HG: user: test
144 HG: user: test
145 HG: branch 'default'
145 HG: branch 'default'
146 HG: added foo/foo
146 HG: added foo/foo
147
147
148
148
149 $ hg ci -m commit-subdir-2 bar
149 $ hg ci -m commit-subdir-2 bar
150
150
151 subdir log 1
151 subdir log 1
152
152
153 $ hg log -v foo
153 $ hg log -v foo
154 changeset: 0:f97e73a25882
154 changeset: 0:f97e73a25882
155 user: test
155 user: test
156 date: Thu Jan 01 00:00:00 1970 +0000
156 date: Thu Jan 01 00:00:00 1970 +0000
157 files: foo/foo
157 files: foo/foo
158 description:
158 description:
159 commit-subdir-1
159 commit-subdir-1
160
160
161
161
162
162
163 subdir log 2
163 subdir log 2
164
164
165 $ hg log -v bar
165 $ hg log -v bar
166 changeset: 1:aa809156d50d
166 changeset: 1:aa809156d50d
167 tag: tip
167 tag: tip
168 user: test
168 user: test
169 date: Thu Jan 01 00:00:00 1970 +0000
169 date: Thu Jan 01 00:00:00 1970 +0000
170 files: bar/bar
170 files: bar/bar
171 description:
171 description:
172 commit-subdir-2
172 commit-subdir-2
173
173
174
174
175
175
176 full log
176 full log
177
177
178 $ hg log -v
178 $ hg log -v
179 changeset: 1:aa809156d50d
179 changeset: 1:aa809156d50d
180 tag: tip
180 tag: tip
181 user: test
181 user: test
182 date: Thu Jan 01 00:00:00 1970 +0000
182 date: Thu Jan 01 00:00:00 1970 +0000
183 files: bar/bar
183 files: bar/bar
184 description:
184 description:
185 commit-subdir-2
185 commit-subdir-2
186
186
187
187
188 changeset: 0:f97e73a25882
188 changeset: 0:f97e73a25882
189 user: test
189 user: test
190 date: Thu Jan 01 00:00:00 1970 +0000
190 date: Thu Jan 01 00:00:00 1970 +0000
191 files: foo/foo
191 files: foo/foo
192 description:
192 description:
193 commit-subdir-1
193 commit-subdir-1
194
194
195
195
196 $ cd ..
196 $ cd ..
197
197
198
198
199 dot and subdir commit test
199 dot and subdir commit test
200
200
201 $ hg init test3
201 $ hg init test3
202 $ echo commit-foo-subdir > commit-log-test
202 $ echo commit-foo-subdir > commit-log-test
203 $ cd test3
203 $ cd test3
204 $ mkdir foo
204 $ mkdir foo
205 $ echo foo content > foo/plain-file
205 $ echo foo content > foo/plain-file
206 $ hg add foo/plain-file
206 $ hg add foo/plain-file
207 $ HGEDITOR=cat hg ci --edit -l ../commit-log-test foo
207 $ HGEDITOR=cat hg ci --edit -l ../commit-log-test foo
208 commit-foo-subdir
208 commit-foo-subdir
209
209
210
210
211 HG: Enter commit message. Lines beginning with 'HG:' are removed.
211 HG: Enter commit message. Lines beginning with 'HG:' are removed.
212 HG: Leave message empty to abort commit.
212 HG: Leave message empty to abort commit.
213 HG: --
213 HG: --
214 HG: user: test
214 HG: user: test
215 HG: branch 'default'
215 HG: branch 'default'
216 HG: added foo/plain-file
216 HG: added foo/plain-file
217
217
218
218
219 $ echo modified foo content > foo/plain-file
219 $ echo modified foo content > foo/plain-file
220 $ hg ci -m commit-foo-dot .
220 $ hg ci -m commit-foo-dot .
221
221
222 full log
222 full log
223
223
224 $ hg log -v
224 $ hg log -v
225 changeset: 1:95b38e3a5b2e
225 changeset: 1:95b38e3a5b2e
226 tag: tip
226 tag: tip
227 user: test
227 user: test
228 date: Thu Jan 01 00:00:00 1970 +0000
228 date: Thu Jan 01 00:00:00 1970 +0000
229 files: foo/plain-file
229 files: foo/plain-file
230 description:
230 description:
231 commit-foo-dot
231 commit-foo-dot
232
232
233
233
234 changeset: 0:65d4e9386227
234 changeset: 0:65d4e9386227
235 user: test
235 user: test
236 date: Thu Jan 01 00:00:00 1970 +0000
236 date: Thu Jan 01 00:00:00 1970 +0000
237 files: foo/plain-file
237 files: foo/plain-file
238 description:
238 description:
239 commit-foo-subdir
239 commit-foo-subdir
240
240
241
241
242
242
243 subdir log
243 subdir log
244
244
245 $ cd foo
245 $ cd foo
246 $ hg log .
246 $ hg log .
247 changeset: 1:95b38e3a5b2e
247 changeset: 1:95b38e3a5b2e
248 tag: tip
248 tag: tip
249 user: test
249 user: test
250 date: Thu Jan 01 00:00:00 1970 +0000
250 date: Thu Jan 01 00:00:00 1970 +0000
251 summary: commit-foo-dot
251 summary: commit-foo-dot
252
252
253 changeset: 0:65d4e9386227
253 changeset: 0:65d4e9386227
254 user: test
254 user: test
255 date: Thu Jan 01 00:00:00 1970 +0000
255 date: Thu Jan 01 00:00:00 1970 +0000
256 summary: commit-foo-subdir
256 summary: commit-foo-subdir
257
257
258 $ cd ..
258 $ cd ..
259 $ cd ..
259 $ cd ..
260
260
261 Issue1049: Hg permits partial commit of merge without warning
261 Issue1049: Hg permits partial commit of merge without warning
262
262
263 $ hg init issue1049
263 $ hg init issue1049
264 $ cd issue1049
264 $ cd issue1049
265 $ echo a > a
265 $ echo a > a
266 $ hg ci -Ama
266 $ hg ci -Ama
267 adding a
267 adding a
268 $ echo a >> a
268 $ echo a >> a
269 $ hg ci -mb
269 $ hg ci -mb
270 $ hg up 0
270 $ hg up 0
271 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
271 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
272 $ echo b >> a
272 $ echo b >> a
273 $ hg ci -mc
273 $ hg ci -mc
274 created new head
274 created new head
275 $ HGMERGE=true hg merge
275 $ HGMERGE=true hg merge
276 merging a
276 merging a
277 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
277 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
278 (branch merge, don't forget to commit)
278 (branch merge, don't forget to commit)
279
279
280 should fail because we are specifying a file name
280 should fail because we are specifying a file name
281
281
282 $ hg ci -mmerge a
282 $ hg ci -mmerge a
283 abort: cannot partially commit a merge (do not specify files or patterns)
283 abort: cannot partially commit a merge (do not specify files or patterns)
284 [255]
284 [255]
285
285
286 should fail because we are specifying a pattern
286 should fail because we are specifying a pattern
287
287
288 $ hg ci -mmerge -I a
288 $ hg ci -mmerge -I a
289 abort: cannot partially commit a merge (do not specify files or patterns)
289 abort: cannot partially commit a merge (do not specify files or patterns)
290 [255]
290 [255]
291
291
292 should succeed
292 should succeed
293
293
294 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg ci -mmerge --edit
294 $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg ci -mmerge --edit
295 HGEDITFORM=commit.normal.merge
295 HGEDITFORM=commit.normal.merge
296 $ cd ..
296 $ cd ..
297
297
298
298
299 test commit message content
299 test commit message content
300
300
301 $ hg init commitmsg
301 $ hg init commitmsg
302 $ cd commitmsg
302 $ cd commitmsg
303 $ echo changed > changed
303 $ echo changed > changed
304 $ echo removed > removed
304 $ echo removed > removed
305 $ hg book currentbookmark
305 $ hg book currentbookmark
306 $ hg ci -qAm init
306 $ hg ci -qAm init
307
307
308 $ hg rm removed
308 $ hg rm removed
309 $ echo changed >> changed
309 $ echo changed >> changed
310 $ echo added > added
310 $ echo added > added
311 $ hg add added
311 $ hg add added
312 $ HGEDITOR=cat hg ci -A
312 $ HGEDITOR=cat hg ci -A
313
313
314
314
315 HG: Enter commit message. Lines beginning with 'HG:' are removed.
315 HG: Enter commit message. Lines beginning with 'HG:' are removed.
316 HG: Leave message empty to abort commit.
316 HG: Leave message empty to abort commit.
317 HG: --
317 HG: --
318 HG: user: test
318 HG: user: test
319 HG: branch 'default'
319 HG: branch 'default'
320 HG: bookmark 'currentbookmark'
320 HG: bookmark 'currentbookmark'
321 HG: added added
321 HG: added added
322 HG: changed changed
322 HG: changed changed
323 HG: removed removed
323 HG: removed removed
324 abort: empty commit message
324 abort: empty commit message
325 [255]
325 [255]
326
326
327 test saving last-message.txt
327 test saving last-message.txt
328
328
329 $ hg init sub
329 $ hg init sub
330 $ echo a > sub/a
330 $ echo a > sub/a
331 $ hg -R sub add sub/a
331 $ hg -R sub add sub/a
332 $ cat > sub/.hg/hgrc <<EOF
332 $ cat > sub/.hg/hgrc <<EOF
333 > [hooks]
333 > [hooks]
334 > precommit.test-saving-last-message = false
334 > precommit.test-saving-last-message = false
335 > EOF
335 > EOF
336
336
337 $ echo 'sub = sub' > .hgsub
337 $ echo 'sub = sub' > .hgsub
338 $ hg add .hgsub
338 $ hg add .hgsub
339
339
340 $ cat > $TESTTMP/editor.sh <<EOF
340 $ cat > $TESTTMP/editor.sh <<EOF
341 > echo "==== before editing:"
341 > echo "==== before editing:"
342 > cat \$1
342 > cat \$1
343 > echo "===="
343 > echo "===="
344 > echo "test saving last-message.txt" >> \$1
344 > echo "test saving last-message.txt" >> \$1
345 > EOF
345 > EOF
346
346
347 $ rm -f .hg/last-message.txt
347 $ rm -f .hg/last-message.txt
348 $ HGEDITOR="sh $TESTTMP/editor.sh" hg commit -S -q
348 $ HGEDITOR="sh $TESTTMP/editor.sh" hg commit -S -q
349 ==== before editing:
349 ==== before editing:
350
350
351
351
352 HG: Enter commit message. Lines beginning with 'HG:' are removed.
352 HG: Enter commit message. Lines beginning with 'HG:' are removed.
353 HG: Leave message empty to abort commit.
353 HG: Leave message empty to abort commit.
354 HG: --
354 HG: --
355 HG: user: test
355 HG: user: test
356 HG: branch 'default'
356 HG: branch 'default'
357 HG: bookmark 'currentbookmark'
357 HG: bookmark 'currentbookmark'
358 HG: subrepo sub
358 HG: subrepo sub
359 HG: added .hgsub
359 HG: added .hgsub
360 HG: added added
360 HG: added added
361 HG: changed .hgsubstate
361 HG: changed .hgsubstate
362 HG: changed changed
362 HG: changed changed
363 HG: removed removed
363 HG: removed removed
364 ====
364 ====
365 abort: precommit.test-saving-last-message hook exited with status 1 (in subrepo sub)
365 abort: precommit.test-saving-last-message hook exited with status 1 (in subrepo sub)
366 [255]
366 [255]
367 $ cat .hg/last-message.txt
367 $ cat .hg/last-message.txt
368
368
369
369
370 test saving last-message.txt
370 test saving last-message.txt
371
371
372 test that '[committemplate] changeset' definition and commit log
372 test that '[committemplate] changeset' definition and commit log
373 specific template keywords work well
373 specific template keywords work well
374
374
375 $ cat >> .hg/hgrc <<EOF
375 $ cat >> .hg/hgrc <<EOF
376 > [committemplate]
376 > [committemplate]
377 > changeset.commit.normal = HG: this is "commit.normal" template
377 > changeset.commit.normal = HG: this is "commit.normal" template
378 > HG: {extramsg}
378 > HG: {extramsg}
379 > {if(currentbookmark,
379 > {if(currentbookmark,
380 > "HG: bookmark '{currentbookmark}' is activated\n",
380 > "HG: bookmark '{currentbookmark}' is activated\n",
381 > "HG: no bookmark is activated\n")}{subrepos %
381 > "HG: no bookmark is activated\n")}{subrepos %
382 > "HG: subrepo '{subrepo}' is changed\n"}
382 > "HG: subrepo '{subrepo}' is changed\n"}
383 >
383 >
384 > changeset.commit = HG: this is "commit" template
384 > changeset.commit = HG: this is "commit" template
385 > HG: {extramsg}
385 > HG: {extramsg}
386 > {if(currentbookmark,
386 > {if(currentbookmark,
387 > "HG: bookmark '{currentbookmark}' is activated\n",
387 > "HG: bookmark '{currentbookmark}' is activated\n",
388 > "HG: no bookmark is activated\n")}{subrepos %
388 > "HG: no bookmark is activated\n")}{subrepos %
389 > "HG: subrepo '{subrepo}' is changed\n"}
389 > "HG: subrepo '{subrepo}' is changed\n"}
390 >
390 >
391 > changeset = HG: this is customized commit template
391 > changeset = HG: this is customized commit template
392 > HG: {extramsg}
392 > HG: {extramsg}
393 > {if(currentbookmark,
393 > {if(currentbookmark,
394 > "HG: bookmark '{currentbookmark}' is activated\n",
394 > "HG: bookmark '{currentbookmark}' is activated\n",
395 > "HG: no bookmark is activated\n")}{subrepos %
395 > "HG: no bookmark is activated\n")}{subrepos %
396 > "HG: subrepo '{subrepo}' is changed\n"}
396 > "HG: subrepo '{subrepo}' is changed\n"}
397 > EOF
397 > EOF
398
398
399 $ hg init sub2
399 $ hg init sub2
400 $ echo a > sub2/a
400 $ echo a > sub2/a
401 $ hg -R sub2 add sub2/a
401 $ hg -R sub2 add sub2/a
402 $ echo 'sub2 = sub2' >> .hgsub
402 $ echo 'sub2 = sub2' >> .hgsub
403
403
404 $ HGEDITOR=cat hg commit -S -q
404 $ HGEDITOR=cat hg commit -S -q
405 HG: this is "commit.normal" template
405 HG: this is "commit.normal" template
406 HG: Leave message empty to abort commit.
406 HG: Leave message empty to abort commit.
407 HG: bookmark 'currentbookmark' is activated
407 HG: bookmark 'currentbookmark' is activated
408 HG: subrepo 'sub' is changed
408 HG: subrepo 'sub' is changed
409 HG: subrepo 'sub2' is changed
409 HG: subrepo 'sub2' is changed
410 abort: empty commit message
410 abort: empty commit message
411 [255]
411 [255]
412
412
413 $ cat >> .hg/hgrc <<EOF
413 $ cat >> .hg/hgrc <<EOF
414 > [committemplate]
414 > [committemplate]
415 > changeset.commit.normal =
415 > changeset.commit.normal =
416 > # now, "changeset.commit" should be chosen for "hg commit"
416 > # now, "changeset.commit" should be chosen for "hg commit"
417 > EOF
417 > EOF
418
418
419 $ hg bookmark --inactive currentbookmark
419 $ hg bookmark --inactive currentbookmark
420 $ hg forget .hgsub
420 $ hg forget .hgsub
421 $ HGEDITOR=cat hg commit -q
421 $ HGEDITOR=cat hg commit -q
422 HG: this is "commit" template
422 HG: this is "commit" template
423 HG: Leave message empty to abort commit.
423 HG: Leave message empty to abort commit.
424 HG: no bookmark is activated
424 HG: no bookmark is activated
425 abort: empty commit message
425 abort: empty commit message
426 [255]
426 [255]
427
427
428 $ cat >> .hg/hgrc <<EOF
428 $ cat >> .hg/hgrc <<EOF
429 > [committemplate]
429 > [committemplate]
430 > changeset.commit =
430 > changeset.commit =
431 > # now, "changeset" should be chosen for "hg commit"
431 > # now, "changeset" should be chosen for "hg commit"
432 > EOF
432 > EOF
433
433
434 $ HGEDITOR=cat hg commit -q
434 $ HGEDITOR=cat hg commit -q
435 HG: this is customized commit template
435 HG: this is customized commit template
436 HG: Leave message empty to abort commit.
436 HG: Leave message empty to abort commit.
437 HG: no bookmark is activated
437 HG: no bookmark is activated
438 abort: empty commit message
438 abort: empty commit message
439 [255]
439 [255]
440
440
441 $ cat >> .hg/hgrc <<EOF
441 $ cat >> .hg/hgrc <<EOF
442 > [committemplate]
442 > [committemplate]
443 > changeset = {desc}
443 > changeset = {desc}
444 > HG: mods={file_mods}
445 > HG: adds={file_adds}
446 > HG: dels={file_dels}
444 > HG: files={files}
447 > HG: files={files}
445 > HG:
448 > HG:
446 > {splitlines(diff()) % 'HG: {line}\n'
449 > {splitlines(diff()) % 'HG: {line}\n'
447 > }HG:
450 > }HG:
451 > HG: mods={file_mods}
452 > HG: adds={file_adds}
453 > HG: dels={file_dels}
448 > HG: files={files}\n
454 > HG: files={files}\n
449 > EOF
455 > EOF
450 $ hg status -amr
456 $ hg status -amr
451 M changed
457 M changed
452 A added
458 A added
453 R removed
459 R removed
454 $ HGEDITOR=cat hg commit -q -e -m "foo bar" changed
460 $ HGEDITOR=cat hg commit -q -e -m "foo bar" changed
455 foo bar
461 foo bar
462 HG: mods=changed
463 HG: adds=
464 HG: dels=
456 HG: files=changed
465 HG: files=changed
457 HG:
466 HG:
458 HG: --- a/changed Thu Jan 01 00:00:00 1970 +0000
467 HG: --- a/changed Thu Jan 01 00:00:00 1970 +0000
459 HG: +++ b/changed Thu Jan 01 00:00:00 1970 +0000
468 HG: +++ b/changed Thu Jan 01 00:00:00 1970 +0000
460 HG: @@ -1,1 +1,2 @@
469 HG: @@ -1,1 +1,2 @@
461 HG: changed
470 HG: changed
462 HG: +changed
471 HG: +changed
463 HG:
472 HG:
473 HG: mods=changed
474 HG: adds=
475 HG: dels=
464 HG: files=changed
476 HG: files=changed
465 $ hg status -amr
477 $ hg status -amr
466 A added
478 A added
467 R removed
479 R removed
468 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
480 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
469 M changed
481 M changed
470 A
482 A
471 R
483 R
472 $ hg rollback -q
484 $ hg rollback -q
473
485
474 $ cat >> .hg/hgrc <<EOF
486 $ cat >> .hg/hgrc <<EOF
475 > [committemplate]
487 > [committemplate]
476 > changeset = {desc}
488 > changeset = {desc}
489 > HG: mods={file_mods}
490 > HG: adds={file_adds}
491 > HG: dels={file_dels}
477 > HG: files={files}
492 > HG: files={files}
478 > HG:
493 > HG:
479 > {splitlines(diff("changed")) % 'HG: {line}\n'
494 > {splitlines(diff("changed")) % 'HG: {line}\n'
480 > }HG:
495 > }HG:
496 > HG: mods={file_mods}
497 > HG: adds={file_adds}
498 > HG: dels={file_dels}
481 > HG: files={files}
499 > HG: files={files}
482 > HG:
500 > HG:
483 > {splitlines(diff("added")) % 'HG: {line}\n'
501 > {splitlines(diff("added")) % 'HG: {line}\n'
484 > }HG:
502 > }HG:
503 > HG: mods={file_mods}
504 > HG: adds={file_adds}
505 > HG: dels={file_dels}
485 > HG: files={files}
506 > HG: files={files}
486 > HG:
507 > HG:
487 > {splitlines(diff("removed")) % 'HG: {line}\n'
508 > {splitlines(diff("removed")) % 'HG: {line}\n'
488 > }HG:
509 > }HG:
510 > HG: mods={file_mods}
511 > HG: adds={file_adds}
512 > HG: dels={file_dels}
489 > HG: files={files}\n
513 > HG: files={files}\n
490 > EOF
514 > EOF
491 $ HGEDITOR=cat hg commit -q -e -m "foo bar" added removed
515 $ HGEDITOR=cat hg commit -q -e -m "foo bar" added removed
492 foo bar
516 foo bar
517 HG: mods=
518 HG: adds=added
519 HG: dels=removed
493 HG: files=added removed
520 HG: files=added removed
494 HG:
521 HG:
495 HG:
522 HG:
523 HG: mods=
524 HG: adds=added
525 HG: dels=removed
496 HG: files=added removed
526 HG: files=added removed
497 HG:
527 HG:
498 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
528 HG: --- /dev/null Thu Jan 01 00:00:00 1970 +0000
499 HG: +++ b/added Thu Jan 01 00:00:00 1970 +0000
529 HG: +++ b/added Thu Jan 01 00:00:00 1970 +0000
500 HG: @@ -0,0 +1,1 @@
530 HG: @@ -0,0 +1,1 @@
501 HG: +added
531 HG: +added
502 HG:
532 HG:
533 HG: mods=
534 HG: adds=added
535 HG: dels=removed
503 HG: files=added removed
536 HG: files=added removed
504 HG:
537 HG:
505 HG: --- a/removed Thu Jan 01 00:00:00 1970 +0000
538 HG: --- a/removed Thu Jan 01 00:00:00 1970 +0000
506 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
539 HG: +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
507 HG: @@ -1,1 +0,0 @@
540 HG: @@ -1,1 +0,0 @@
508 HG: -removed
541 HG: -removed
509 HG:
542 HG:
543 HG: mods=
544 HG: adds=added
545 HG: dels=removed
510 HG: files=added removed
546 HG: files=added removed
511 $ hg status -amr
547 $ hg status -amr
512 M changed
548 M changed
513 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
549 $ hg parents --template "M {file_mods}\nA {file_adds}\nR {file_dels}\n"
514 M
550 M
515 A added
551 A added
516 R removed
552 R removed
517 $ hg rollback -q
553 $ hg rollback -q
518
554
519 $ cat >> .hg/hgrc <<EOF
555 $ cat >> .hg/hgrc <<EOF
520 > # disable customizing for subsequent tests
556 > # disable customizing for subsequent tests
521 > [committemplate]
557 > [committemplate]
522 > changeset =
558 > changeset =
523 > EOF
559 > EOF
524
560
525 $ cd ..
561 $ cd ..
526
562
527
563
528 commit copy
564 commit copy
529
565
530 $ hg init dir2
566 $ hg init dir2
531 $ cd dir2
567 $ cd dir2
532 $ echo bleh > bar
568 $ echo bleh > bar
533 $ hg add bar
569 $ hg add bar
534 $ hg ci -m 'add bar'
570 $ hg ci -m 'add bar'
535
571
536 $ hg cp bar foo
572 $ hg cp bar foo
537 $ echo >> bar
573 $ echo >> bar
538 $ hg ci -m 'cp bar foo; change bar'
574 $ hg ci -m 'cp bar foo; change bar'
539
575
540 $ hg debugrename foo
576 $ hg debugrename foo
541 foo renamed from bar:26d3ca0dfd18e44d796b564e38dd173c9668d3a9
577 foo renamed from bar:26d3ca0dfd18e44d796b564e38dd173c9668d3a9
542 $ hg debugindex bar
578 $ hg debugindex bar
543 rev offset length ..... linkrev nodeid p1 p2 (re)
579 rev offset length ..... linkrev nodeid p1 p2 (re)
544 0 0 6 ..... 0 26d3ca0dfd18 000000000000 000000000000 (re)
580 0 0 6 ..... 0 26d3ca0dfd18 000000000000 000000000000 (re)
545 1 6 7 ..... 1 d267bddd54f7 26d3ca0dfd18 000000000000 (re)
581 1 6 7 ..... 1 d267bddd54f7 26d3ca0dfd18 000000000000 (re)
546
582
547 verify pathauditor blocks evil filepaths
583 verify pathauditor blocks evil filepaths
548 $ cat > evil-commit.py <<EOF
584 $ cat > evil-commit.py <<EOF
549 > from mercurial import ui, hg, context, node
585 > from mercurial import ui, hg, context, node
550 > notrc = u".h\u200cg".encode('utf-8') + '/hgrc'
586 > notrc = u".h\u200cg".encode('utf-8') + '/hgrc'
551 > u = ui.ui()
587 > u = ui.ui()
552 > r = hg.repository(u, '.')
588 > r = hg.repository(u, '.')
553 > def filectxfn(repo, memctx, path):
589 > def filectxfn(repo, memctx, path):
554 > return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
590 > return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
555 > c = context.memctx(r, [r['tip'].node(), node.nullid],
591 > c = context.memctx(r, [r['tip'].node(), node.nullid],
556 > 'evil', [notrc], filectxfn, 0)
592 > 'evil', [notrc], filectxfn, 0)
557 > r.commitctx(c)
593 > r.commitctx(c)
558 > EOF
594 > EOF
559 $ $PYTHON evil-commit.py
595 $ $PYTHON evil-commit.py
560 #if windows
596 #if windows
561 $ hg co --clean tip
597 $ hg co --clean tip
562 abort: path contains illegal component: .h\xe2\x80\x8cg\\hgrc (esc)
598 abort: path contains illegal component: .h\xe2\x80\x8cg\\hgrc (esc)
563 [255]
599 [255]
564 #else
600 #else
565 $ hg co --clean tip
601 $ hg co --clean tip
566 abort: path contains illegal component: .h\xe2\x80\x8cg/hgrc (esc)
602 abort: path contains illegal component: .h\xe2\x80\x8cg/hgrc (esc)
567 [255]
603 [255]
568 #endif
604 #endif
569
605
570 $ hg rollback -f
606 $ hg rollback -f
571 repository tip rolled back to revision 1 (undo commit)
607 repository tip rolled back to revision 1 (undo commit)
572 $ cat > evil-commit.py <<EOF
608 $ cat > evil-commit.py <<EOF
573 > from mercurial import ui, hg, context, node
609 > from mercurial import ui, hg, context, node
574 > notrc = "HG~1/hgrc"
610 > notrc = "HG~1/hgrc"
575 > u = ui.ui()
611 > u = ui.ui()
576 > r = hg.repository(u, '.')
612 > r = hg.repository(u, '.')
577 > def filectxfn(repo, memctx, path):
613 > def filectxfn(repo, memctx, path):
578 > return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
614 > return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
579 > c = context.memctx(r, [r['tip'].node(), node.nullid],
615 > c = context.memctx(r, [r['tip'].node(), node.nullid],
580 > 'evil', [notrc], filectxfn, 0)
616 > 'evil', [notrc], filectxfn, 0)
581 > r.commitctx(c)
617 > r.commitctx(c)
582 > EOF
618 > EOF
583 $ $PYTHON evil-commit.py
619 $ $PYTHON evil-commit.py
584 $ hg co --clean tip
620 $ hg co --clean tip
585 abort: path contains illegal component: HG~1/hgrc (glob)
621 abort: path contains illegal component: HG~1/hgrc (glob)
586 [255]
622 [255]
587
623
588 $ hg rollback -f
624 $ hg rollback -f
589 repository tip rolled back to revision 1 (undo commit)
625 repository tip rolled back to revision 1 (undo commit)
590 $ cat > evil-commit.py <<EOF
626 $ cat > evil-commit.py <<EOF
591 > from mercurial import ui, hg, context, node
627 > from mercurial import ui, hg, context, node
592 > notrc = "HG8B6C~2/hgrc"
628 > notrc = "HG8B6C~2/hgrc"
593 > u = ui.ui()
629 > u = ui.ui()
594 > r = hg.repository(u, '.')
630 > r = hg.repository(u, '.')
595 > def filectxfn(repo, memctx, path):
631 > def filectxfn(repo, memctx, path):
596 > return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
632 > return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
597 > c = context.memctx(r, [r['tip'].node(), node.nullid],
633 > c = context.memctx(r, [r['tip'].node(), node.nullid],
598 > 'evil', [notrc], filectxfn, 0)
634 > 'evil', [notrc], filectxfn, 0)
599 > r.commitctx(c)
635 > r.commitctx(c)
600 > EOF
636 > EOF
601 $ $PYTHON evil-commit.py
637 $ $PYTHON evil-commit.py
602 $ hg co --clean tip
638 $ hg co --clean tip
603 abort: path contains illegal component: HG8B6C~2/hgrc (glob)
639 abort: path contains illegal component: HG8B6C~2/hgrc (glob)
604 [255]
640 [255]
General Comments 0
You need to be logged in to leave comments. Login now