##// END OF EJS Templates
commit: pass mergestate into _filecommit() instead of re-reading it...
Pulkit Goyal -
r46014:037e88d4 default
parent child Browse files
Show More
@@ -1,438 +1,442
1 # commit.py - fonction to perform commit
1 # commit.py - fonction to perform commit
2 #
2 #
3 # This software may be used and distributed according to the terms of the
3 # This software may be used and distributed according to the terms of the
4 # GNU General Public License version 2 or any later version.
4 # GNU General Public License version 2 or any later version.
5
5
6 from __future__ import absolute_import
6 from __future__ import absolute_import
7
7
8 import errno
8 import errno
9
9
10 from .i18n import _
10 from .i18n import _
11 from .node import (
11 from .node import (
12 hex,
12 hex,
13 nullid,
13 nullid,
14 nullrev,
14 nullrev,
15 )
15 )
16
16
17 from . import (
17 from . import (
18 context,
18 context,
19 mergestate,
19 mergestate,
20 metadata,
20 metadata,
21 phases,
21 phases,
22 scmutil,
22 scmutil,
23 subrepoutil,
23 subrepoutil,
24 )
24 )
25
25
26
26
27 def _write_copy_meta(repo):
27 def _write_copy_meta(repo):
28 """return a (changelog, filelog) boolean tuple
28 """return a (changelog, filelog) boolean tuple
29
29
30 changelog: copy related information should be stored in the changeset
30 changelog: copy related information should be stored in the changeset
31 filelof: copy related information should be written in the file revision
31 filelof: copy related information should be written in the file revision
32 """
32 """
33 if repo.filecopiesmode == b'changeset-sidedata':
33 if repo.filecopiesmode == b'changeset-sidedata':
34 writechangesetcopy = True
34 writechangesetcopy = True
35 writefilecopymeta = True
35 writefilecopymeta = True
36 else:
36 else:
37 writecopiesto = repo.ui.config(b'experimental', b'copies.write-to')
37 writecopiesto = repo.ui.config(b'experimental', b'copies.write-to')
38 writefilecopymeta = writecopiesto != b'changeset-only'
38 writefilecopymeta = writecopiesto != b'changeset-only'
39 writechangesetcopy = writecopiesto in (
39 writechangesetcopy = writecopiesto in (
40 b'changeset-only',
40 b'changeset-only',
41 b'compatibility',
41 b'compatibility',
42 )
42 )
43 return writechangesetcopy, writefilecopymeta
43 return writechangesetcopy, writefilecopymeta
44
44
45
45
46 def commitctx(repo, ctx, error=False, origctx=None):
46 def commitctx(repo, ctx, error=False, origctx=None):
47 """Add a new revision to the target repository.
47 """Add a new revision to the target repository.
48 Revision information is passed via the context argument.
48 Revision information is passed via the context argument.
49
49
50 ctx.files() should list all files involved in this commit, i.e.
50 ctx.files() should list all files involved in this commit, i.e.
51 modified/added/removed files. On merge, it may be wider than the
51 modified/added/removed files. On merge, it may be wider than the
52 ctx.files() to be committed, since any file nodes derived directly
52 ctx.files() to be committed, since any file nodes derived directly
53 from p1 or p2 are excluded from the committed ctx.files().
53 from p1 or p2 are excluded from the committed ctx.files().
54
54
55 origctx is for convert to work around the problem that bug
55 origctx is for convert to work around the problem that bug
56 fixes to the files list in changesets change hashes. For
56 fixes to the files list in changesets change hashes. For
57 convert to be the identity, it can pass an origctx and this
57 convert to be the identity, it can pass an origctx and this
58 function will use the same files list when it makes sense to
58 function will use the same files list when it makes sense to
59 do so.
59 do so.
60 """
60 """
61 repo = repo.unfiltered()
61 repo = repo.unfiltered()
62
62
63 p1, p2 = ctx.p1(), ctx.p2()
63 p1, p2 = ctx.p1(), ctx.p2()
64 user = ctx.user()
64 user = ctx.user()
65
65
66 with repo.lock(), repo.transaction(b"commit") as tr:
66 with repo.lock(), repo.transaction(b"commit") as tr:
67 mn, files = _prepare_files(tr, ctx, error=error, origctx=origctx)
67 mn, files = _prepare_files(tr, ctx, error=error, origctx=origctx)
68
68
69 extra = ctx.extra().copy()
69 extra = ctx.extra().copy()
70
70
71 if extra is not None:
71 if extra is not None:
72 for name in (
72 for name in (
73 b'p1copies',
73 b'p1copies',
74 b'p2copies',
74 b'p2copies',
75 b'filesadded',
75 b'filesadded',
76 b'filesremoved',
76 b'filesremoved',
77 ):
77 ):
78 extra.pop(name, None)
78 extra.pop(name, None)
79 if repo.changelog._copiesstorage == b'extra':
79 if repo.changelog._copiesstorage == b'extra':
80 extra = _extra_with_copies(repo, extra, files)
80 extra = _extra_with_copies(repo, extra, files)
81
81
82 # update changelog
82 # update changelog
83 repo.ui.note(_(b"committing changelog\n"))
83 repo.ui.note(_(b"committing changelog\n"))
84 repo.changelog.delayupdate(tr)
84 repo.changelog.delayupdate(tr)
85 n = repo.changelog.add(
85 n = repo.changelog.add(
86 mn,
86 mn,
87 files,
87 files,
88 ctx.description(),
88 ctx.description(),
89 tr,
89 tr,
90 p1.node(),
90 p1.node(),
91 p2.node(),
91 p2.node(),
92 user,
92 user,
93 ctx.date(),
93 ctx.date(),
94 extra,
94 extra,
95 )
95 )
96 xp1, xp2 = p1.hex(), p2 and p2.hex() or b''
96 xp1, xp2 = p1.hex(), p2 and p2.hex() or b''
97 repo.hook(
97 repo.hook(
98 b'pretxncommit', throw=True, node=hex(n), parent1=xp1, parent2=xp2,
98 b'pretxncommit', throw=True, node=hex(n), parent1=xp1, parent2=xp2,
99 )
99 )
100 # set the new commit is proper phase
100 # set the new commit is proper phase
101 targetphase = subrepoutil.newcommitphase(repo.ui, ctx)
101 targetphase = subrepoutil.newcommitphase(repo.ui, ctx)
102 if targetphase:
102 if targetphase:
103 # retract boundary do not alter parent changeset.
103 # retract boundary do not alter parent changeset.
104 # if a parent have higher the resulting phase will
104 # if a parent have higher the resulting phase will
105 # be compliant anyway
105 # be compliant anyway
106 #
106 #
107 # if minimal phase was 0 we don't need to retract anything
107 # if minimal phase was 0 we don't need to retract anything
108 phases.registernew(repo, tr, targetphase, [n])
108 phases.registernew(repo, tr, targetphase, [n])
109 return n
109 return n
110
110
111
111
112 def _prepare_files(tr, ctx, error=False, origctx=None):
112 def _prepare_files(tr, ctx, error=False, origctx=None):
113 repo = ctx.repo()
113 repo = ctx.repo()
114 p1 = ctx.p1()
114 p1 = ctx.p1()
115
115
116 writechangesetcopy, writefilecopymeta = _write_copy_meta(repo)
116 writechangesetcopy, writefilecopymeta = _write_copy_meta(repo)
117
117
118 if ctx.manifestnode():
118 if ctx.manifestnode():
119 # reuse an existing manifest revision
119 # reuse an existing manifest revision
120 repo.ui.debug(b'reusing known manifest\n')
120 repo.ui.debug(b'reusing known manifest\n')
121 mn = ctx.manifestnode()
121 mn = ctx.manifestnode()
122 files = metadata.ChangingFiles()
122 files = metadata.ChangingFiles()
123 files.update_touched(ctx.files())
123 files.update_touched(ctx.files())
124 if writechangesetcopy:
124 if writechangesetcopy:
125 files.update_added(ctx.filesadded())
125 files.update_added(ctx.filesadded())
126 files.update_removed(ctx.filesremoved())
126 files.update_removed(ctx.filesremoved())
127 elif not ctx.files():
127 elif not ctx.files():
128 repo.ui.debug(b'reusing manifest from p1 (no file change)\n')
128 repo.ui.debug(b'reusing manifest from p1 (no file change)\n')
129 mn = p1.manifestnode()
129 mn = p1.manifestnode()
130 files = metadata.ChangingFiles()
130 files = metadata.ChangingFiles()
131 else:
131 else:
132 mn, files = _process_files(tr, ctx, error=error)
132 mn, files = _process_files(tr, ctx, error=error)
133
133
134 if origctx and origctx.manifestnode() == mn:
134 if origctx and origctx.manifestnode() == mn:
135 origfiles = origctx.files()
135 origfiles = origctx.files()
136 assert files.touched.issubset(origfiles)
136 assert files.touched.issubset(origfiles)
137 files.update_touched(origfiles)
137 files.update_touched(origfiles)
138
138
139 if writechangesetcopy:
139 if writechangesetcopy:
140 files.update_copies_from_p1(ctx.p1copies())
140 files.update_copies_from_p1(ctx.p1copies())
141 files.update_copies_from_p2(ctx.p2copies())
141 files.update_copies_from_p2(ctx.p2copies())
142
142
143 return mn, files
143 return mn, files
144
144
145
145
146 def _process_files(tr, ctx, error=False):
146 def _process_files(tr, ctx, error=False):
147 repo = ctx.repo()
147 repo = ctx.repo()
148 p1 = ctx.p1()
148 p1 = ctx.p1()
149 p2 = ctx.p2()
149 p2 = ctx.p2()
150
150
151 writechangesetcopy, writefilecopymeta = _write_copy_meta(repo)
151 writechangesetcopy, writefilecopymeta = _write_copy_meta(repo)
152
152
153 m1ctx = p1.manifestctx()
153 m1ctx = p1.manifestctx()
154 m2ctx = p2.manifestctx()
154 m2ctx = p2.manifestctx()
155 mctx = m1ctx.copy()
155 mctx = m1ctx.copy()
156
156
157 m = mctx.read()
157 m = mctx.read()
158 m1 = m1ctx.read()
158 m1 = m1ctx.read()
159 m2 = m2ctx.read()
159 m2 = m2ctx.read()
160 ms = mergestate.mergestate.read(repo)
160
161
161 files = metadata.ChangingFiles()
162 files = metadata.ChangingFiles()
162
163
163 # check in files
164 # check in files
164 added = []
165 added = []
165 removed = list(ctx.removed())
166 removed = list(ctx.removed())
166 linkrev = len(repo)
167 linkrev = len(repo)
167 repo.ui.note(_(b"committing files:\n"))
168 repo.ui.note(_(b"committing files:\n"))
168 uipathfn = scmutil.getuipathfn(repo)
169 uipathfn = scmutil.getuipathfn(repo)
169 for f in sorted(ctx.modified() + ctx.added()):
170 for f in sorted(ctx.modified() + ctx.added()):
170 repo.ui.note(uipathfn(f) + b"\n")
171 repo.ui.note(uipathfn(f) + b"\n")
171 try:
172 try:
172 fctx = ctx[f]
173 fctx = ctx[f]
173 if fctx is None:
174 if fctx is None:
174 removed.append(f)
175 removed.append(f)
175 else:
176 else:
176 added.append(f)
177 added.append(f)
177 m[f], is_touched = _filecommit(
178 m[f], is_touched = _filecommit(
178 repo, fctx, m1, m2, linkrev, tr, writefilecopymeta,
179 repo, fctx, m1, m2, linkrev, tr, writefilecopymeta, ms
179 )
180 )
180 if is_touched:
181 if is_touched:
181 if is_touched == 'added':
182 if is_touched == 'added':
182 files.mark_added(f)
183 files.mark_added(f)
183 else:
184 else:
184 files.mark_touched(f)
185 files.mark_touched(f)
185 m.setflag(f, fctx.flags())
186 m.setflag(f, fctx.flags())
186 except OSError:
187 except OSError:
187 repo.ui.warn(_(b"trouble committing %s!\n") % uipathfn(f))
188 repo.ui.warn(_(b"trouble committing %s!\n") % uipathfn(f))
188 raise
189 raise
189 except IOError as inst:
190 except IOError as inst:
190 errcode = getattr(inst, 'errno', errno.ENOENT)
191 errcode = getattr(inst, 'errno', errno.ENOENT)
191 if error or errcode and errcode != errno.ENOENT:
192 if error or errcode and errcode != errno.ENOENT:
192 repo.ui.warn(_(b"trouble committing %s!\n") % uipathfn(f))
193 repo.ui.warn(_(b"trouble committing %s!\n") % uipathfn(f))
193 raise
194 raise
194
195
195 # update manifest
196 # update manifest
196 removed = [f for f in removed if f in m1 or f in m2]
197 removed = [f for f in removed if f in m1 or f in m2]
197 drop = sorted([f for f in removed if f in m])
198 drop = sorted([f for f in removed if f in m])
198 for f in drop:
199 for f in drop:
199 del m[f]
200 del m[f]
200 if p2.rev() == nullrev:
201 if p2.rev() == nullrev:
201 files.update_removed(removed)
202 files.update_removed(removed)
202 else:
203 else:
203 rf = metadata.get_removal_filter(ctx, (p1, p2, m1, m2))
204 rf = metadata.get_removal_filter(ctx, (p1, p2, m1, m2))
204 for f in removed:
205 for f in removed:
205 if not rf(f):
206 if not rf(f):
206 files.mark_removed(f)
207 files.mark_removed(f)
207
208
208 mn = _commit_manifest(tr, linkrev, ctx, mctx, m, files.touched, added, drop)
209 mn = _commit_manifest(tr, linkrev, ctx, mctx, m, files.touched, added, drop)
209
210
210 return mn, files
211 return mn, files
211
212
212
213
213 def _filecommit(
214 def _filecommit(
214 repo, fctx, manifest1, manifest2, linkrev, tr, includecopymeta,
215 repo, fctx, manifest1, manifest2, linkrev, tr, includecopymeta, ms,
215 ):
216 ):
216 """
217 """
217 commit an individual file as part of a larger transaction
218 commit an individual file as part of a larger transaction
218
219
219 input:
220 input:
220
221
221 fctx: a file context with the content we are trying to commit
222 fctx: a file context with the content we are trying to commit
222 manifest1: manifest of changeset first parent
223 manifest1: manifest of changeset first parent
223 manifest2: manifest of changeset second parent
224 manifest2: manifest of changeset second parent
224 linkrev: revision number of the changeset being created
225 linkrev: revision number of the changeset being created
225 tr: current transation
226 tr: current transation
226 includecopymeta: boolean, set to False to skip storing the copy data
227 includecopymeta: boolean, set to False to skip storing the copy data
227 (only used by the Google specific feature of using
228 (only used by the Google specific feature of using
228 changeset extra as copy source of truth).
229 changeset extra as copy source of truth).
230 ms: mergestate object
229
231
230 output: (filenode, touched)
232 output: (filenode, touched)
231
233
232 filenode: the filenode that should be used by this changeset
234 filenode: the filenode that should be used by this changeset
233 touched: one of: None (mean untouched), 'added' or 'modified'
235 touched: one of: None (mean untouched), 'added' or 'modified'
234 """
236 """
235
237
236 fname = fctx.path()
238 fname = fctx.path()
237 fparent1 = manifest1.get(fname, nullid)
239 fparent1 = manifest1.get(fname, nullid)
238 fparent2 = manifest2.get(fname, nullid)
240 fparent2 = manifest2.get(fname, nullid)
239 touched = None
241 touched = None
240 if fparent1 == fparent2 == nullid:
242 if fparent1 == fparent2 == nullid:
241 touched = 'added'
243 touched = 'added'
242
244
243 if isinstance(fctx, context.filectx):
245 if isinstance(fctx, context.filectx):
244 # This block fast path most comparisons which are usually done. It
246 # This block fast path most comparisons which are usually done. It
245 # assumes that bare filectx is used and no merge happened, hence no
247 # assumes that bare filectx is used and no merge happened, hence no
246 # need to create a new file revision in this case.
248 # need to create a new file revision in this case.
247 node = fctx.filenode()
249 node = fctx.filenode()
248 if node in [fparent1, fparent2]:
250 if node in [fparent1, fparent2]:
249 repo.ui.debug(b'reusing %s filelog entry\n' % fname)
251 repo.ui.debug(b'reusing %s filelog entry\n' % fname)
250 if (
252 if (
251 fparent1 != nullid and manifest1.flags(fname) != fctx.flags()
253 fparent1 != nullid and manifest1.flags(fname) != fctx.flags()
252 ) or (
254 ) or (
253 fparent2 != nullid and manifest2.flags(fname) != fctx.flags()
255 fparent2 != nullid and manifest2.flags(fname) != fctx.flags()
254 ):
256 ):
255 touched = 'modified'
257 touched = 'modified'
256 return node, touched
258 return node, touched
257
259
258 flog = repo.file(fname)
260 flog = repo.file(fname)
259 meta = {}
261 meta = {}
260 cfname = fctx.copysource()
262 cfname = fctx.copysource()
261 fnode = None
263 fnode = None
262
264
263 if cfname and cfname != fname:
265 if cfname and cfname != fname:
264 # Mark the new revision of this file as a copy of another
266 # Mark the new revision of this file as a copy of another
265 # file. This copy data will effectively act as a parent
267 # file. This copy data will effectively act as a parent
266 # of this new revision. If this is a merge, the first
268 # of this new revision. If this is a merge, the first
267 # parent will be the nullid (meaning "look up the copy data")
269 # parent will be the nullid (meaning "look up the copy data")
268 # and the second one will be the other parent. For example:
270 # and the second one will be the other parent. For example:
269 #
271 #
270 # 0 --- 1 --- 3 rev1 changes file foo
272 # 0 --- 1 --- 3 rev1 changes file foo
271 # \ / rev2 renames foo to bar and changes it
273 # \ / rev2 renames foo to bar and changes it
272 # \- 2 -/ rev3 should have bar with all changes and
274 # \- 2 -/ rev3 should have bar with all changes and
273 # should record that bar descends from
275 # should record that bar descends from
274 # bar in rev2 and foo in rev1
276 # bar in rev2 and foo in rev1
275 #
277 #
276 # this allows this merge to succeed:
278 # this allows this merge to succeed:
277 #
279 #
278 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
280 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
279 # \ / merging rev3 and rev4 should use bar@rev2
281 # \ / merging rev3 and rev4 should use bar@rev2
280 # \- 2 --- 4 as the merge base
282 # \- 2 --- 4 as the merge base
281 #
283 #
282
284
283 cnode = manifest1.get(cfname)
285 cnode = manifest1.get(cfname)
284 newfparent = fparent2
286 newfparent = fparent2
285
287
286 if manifest2: # branch merge
288 if manifest2: # branch merge
287 if fparent2 == nullid or cnode is None: # copied on remote side
289 if fparent2 == nullid or cnode is None: # copied on remote side
288 if cfname in manifest2:
290 if cfname in manifest2:
289 cnode = manifest2[cfname]
291 cnode = manifest2[cfname]
290 newfparent = fparent1
292 newfparent = fparent1
291
293
292 # Here, we used to search backwards through history to try to find
294 # Here, we used to search backwards through history to try to find
293 # where the file copy came from if the source of a copy was not in
295 # where the file copy came from if the source of a copy was not in
294 # the parent directory. However, this doesn't actually make sense to
296 # the parent directory. However, this doesn't actually make sense to
295 # do (what does a copy from something not in your working copy even
297 # do (what does a copy from something not in your working copy even
296 # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
298 # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
297 # the user that copy information was dropped, so if they didn't
299 # the user that copy information was dropped, so if they didn't
298 # expect this outcome it can be fixed, but this is the correct
300 # expect this outcome it can be fixed, but this is the correct
299 # behavior in this circumstance.
301 # behavior in this circumstance.
300
302
301 if cnode:
303 if cnode:
302 repo.ui.debug(b" %s: copy %s:%s\n" % (fname, cfname, hex(cnode)))
304 repo.ui.debug(b" %s: copy %s:%s\n" % (fname, cfname, hex(cnode)))
303 if includecopymeta:
305 if includecopymeta:
304 meta[b"copy"] = cfname
306 meta[b"copy"] = cfname
305 meta[b"copyrev"] = hex(cnode)
307 meta[b"copyrev"] = hex(cnode)
306 fparent1, fparent2 = nullid, newfparent
308 fparent1, fparent2 = nullid, newfparent
307 else:
309 else:
308 repo.ui.warn(
310 repo.ui.warn(
309 _(
311 _(
310 b"warning: can't find ancestor for '%s' "
312 b"warning: can't find ancestor for '%s' "
311 b"copied from '%s'!\n"
313 b"copied from '%s'!\n"
312 )
314 )
313 % (fname, cfname)
315 % (fname, cfname)
314 )
316 )
315
317
316 elif fparent1 == nullid:
318 elif fparent1 == nullid:
317 fparent1, fparent2 = fparent2, nullid
319 fparent1, fparent2 = fparent2, nullid
318 elif fparent2 != nullid:
320 elif fparent2 != nullid:
319 # is one parent an ancestor of the other?
321 # is one parent an ancestor of the other?
320 fparentancestors = flog.commonancestorsheads(fparent1, fparent2)
322 fparentancestors = flog.commonancestorsheads(fparent1, fparent2)
321 if fparent1 in fparentancestors:
323 if fparent1 in fparentancestors:
322 fparent1, fparent2 = fparent2, nullid
324 fparent1, fparent2 = fparent2, nullid
323 elif fparent2 in fparentancestors:
325 elif fparent2 in fparentancestors:
324 fparent2 = nullid
326 fparent2 = nullid
325 elif not fparentancestors:
327 elif not fparentancestors:
326 # TODO: this whole if-else might be simplified much more
328 # TODO: this whole if-else might be simplified much more
327 ms = mergestate.mergestate.read(repo)
329 if (
328 if ms.extras(fname).get(b'filenode-source') == b'other':
330 ms.active()
331 and ms.extras(fname).get(b'filenode-source') == b'other'
332 ):
329 fparent1, fparent2 = fparent2, nullid
333 fparent1, fparent2 = fparent2, nullid
330
334
331 # is the file changed?
335 # is the file changed?
332 text = fctx.data()
336 text = fctx.data()
333 if fparent2 != nullid or meta or flog.cmp(fparent1, text):
337 if fparent2 != nullid or meta or flog.cmp(fparent1, text):
334 if touched is None: # do not overwrite added
338 if touched is None: # do not overwrite added
335 touched = 'modified'
339 touched = 'modified'
336 fnode = flog.add(text, meta, tr, linkrev, fparent1, fparent2)
340 fnode = flog.add(text, meta, tr, linkrev, fparent1, fparent2)
337 # are just the flags changed during merge?
341 # are just the flags changed during merge?
338 elif fname in manifest1 and manifest1.flags(fname) != fctx.flags():
342 elif fname in manifest1 and manifest1.flags(fname) != fctx.flags():
339 touched = 'modified'
343 touched = 'modified'
340 fnode = fparent1
344 fnode = fparent1
341 else:
345 else:
342 fnode = fparent1
346 fnode = fparent1
343 return fnode, touched
347 return fnode, touched
344
348
345
349
346 def _commit_manifest(tr, linkrev, ctx, mctx, manifest, files, added, drop):
350 def _commit_manifest(tr, linkrev, ctx, mctx, manifest, files, added, drop):
347 """make a new manifest entry (or reuse a new one)
351 """make a new manifest entry (or reuse a new one)
348
352
349 given an initialised manifest context and precomputed list of
353 given an initialised manifest context and precomputed list of
350 - files: files affected by the commit
354 - files: files affected by the commit
351 - added: new entries in the manifest
355 - added: new entries in the manifest
352 - drop: entries present in parents but absent of this one
356 - drop: entries present in parents but absent of this one
353
357
354 Create a new manifest revision, reuse existing ones if possible.
358 Create a new manifest revision, reuse existing ones if possible.
355
359
356 Return the nodeid of the manifest revision.
360 Return the nodeid of the manifest revision.
357 """
361 """
358 repo = ctx.repo()
362 repo = ctx.repo()
359
363
360 md = None
364 md = None
361
365
362 # all this is cached, so it is find to get them all from the ctx.
366 # all this is cached, so it is find to get them all from the ctx.
363 p1 = ctx.p1()
367 p1 = ctx.p1()
364 p2 = ctx.p2()
368 p2 = ctx.p2()
365 m1ctx = p1.manifestctx()
369 m1ctx = p1.manifestctx()
366
370
367 m1 = m1ctx.read()
371 m1 = m1ctx.read()
368
372
369 if not files:
373 if not files:
370 # if no "files" actually changed in terms of the changelog,
374 # if no "files" actually changed in terms of the changelog,
371 # try hard to detect unmodified manifest entry so that the
375 # try hard to detect unmodified manifest entry so that the
372 # exact same commit can be reproduced later on convert.
376 # exact same commit can be reproduced later on convert.
373 md = m1.diff(manifest, scmutil.matchfiles(repo, ctx.files()))
377 md = m1.diff(manifest, scmutil.matchfiles(repo, ctx.files()))
374 if not files and md:
378 if not files and md:
375 repo.ui.debug(
379 repo.ui.debug(
376 b'not reusing manifest (no file change in '
380 b'not reusing manifest (no file change in '
377 b'changelog, but manifest differs)\n'
381 b'changelog, but manifest differs)\n'
378 )
382 )
379 if files or md:
383 if files or md:
380 repo.ui.note(_(b"committing manifest\n"))
384 repo.ui.note(_(b"committing manifest\n"))
381 # we're using narrowmatch here since it's already applied at
385 # we're using narrowmatch here since it's already applied at
382 # other stages (such as dirstate.walk), so we're already
386 # other stages (such as dirstate.walk), so we're already
383 # ignoring things outside of narrowspec in most cases. The
387 # ignoring things outside of narrowspec in most cases. The
384 # one case where we might have files outside the narrowspec
388 # one case where we might have files outside the narrowspec
385 # at this point is merges, and we already error out in the
389 # at this point is merges, and we already error out in the
386 # case where the merge has files outside of the narrowspec,
390 # case where the merge has files outside of the narrowspec,
387 # so this is safe.
391 # so this is safe.
388 mn = mctx.write(
392 mn = mctx.write(
389 tr,
393 tr,
390 linkrev,
394 linkrev,
391 p1.manifestnode(),
395 p1.manifestnode(),
392 p2.manifestnode(),
396 p2.manifestnode(),
393 added,
397 added,
394 drop,
398 drop,
395 match=repo.narrowmatch(),
399 match=repo.narrowmatch(),
396 )
400 )
397 else:
401 else:
398 repo.ui.debug(
402 repo.ui.debug(
399 b'reusing manifest from p1 (listed files ' b'actually unchanged)\n'
403 b'reusing manifest from p1 (listed files ' b'actually unchanged)\n'
400 )
404 )
401 mn = p1.manifestnode()
405 mn = p1.manifestnode()
402
406
403 return mn
407 return mn
404
408
405
409
406 def _extra_with_copies(repo, extra, files):
410 def _extra_with_copies(repo, extra, files):
407 """encode copy information into a `extra` dictionnary"""
411 """encode copy information into a `extra` dictionnary"""
408 p1copies = files.copied_from_p1
412 p1copies = files.copied_from_p1
409 p2copies = files.copied_from_p2
413 p2copies = files.copied_from_p2
410 filesadded = files.added
414 filesadded = files.added
411 filesremoved = files.removed
415 filesremoved = files.removed
412 files = sorted(files.touched)
416 files = sorted(files.touched)
413 if not _write_copy_meta(repo)[1]:
417 if not _write_copy_meta(repo)[1]:
414 # If writing only to changeset extras, use None to indicate that
418 # If writing only to changeset extras, use None to indicate that
415 # no entry should be written. If writing to both, write an empty
419 # no entry should be written. If writing to both, write an empty
416 # entry to prevent the reader from falling back to reading
420 # entry to prevent the reader from falling back to reading
417 # filelogs.
421 # filelogs.
418 p1copies = p1copies or None
422 p1copies = p1copies or None
419 p2copies = p2copies or None
423 p2copies = p2copies or None
420 filesadded = filesadded or None
424 filesadded = filesadded or None
421 filesremoved = filesremoved or None
425 filesremoved = filesremoved or None
422
426
423 extrasentries = p1copies, p2copies, filesadded, filesremoved
427 extrasentries = p1copies, p2copies, filesadded, filesremoved
424 if extra is None and any(x is not None for x in extrasentries):
428 if extra is None and any(x is not None for x in extrasentries):
425 extra = {}
429 extra = {}
426 if p1copies is not None:
430 if p1copies is not None:
427 p1copies = metadata.encodecopies(files, p1copies)
431 p1copies = metadata.encodecopies(files, p1copies)
428 extra[b'p1copies'] = p1copies
432 extra[b'p1copies'] = p1copies
429 if p2copies is not None:
433 if p2copies is not None:
430 p2copies = metadata.encodecopies(files, p2copies)
434 p2copies = metadata.encodecopies(files, p2copies)
431 extra[b'p2copies'] = p2copies
435 extra[b'p2copies'] = p2copies
432 if filesadded is not None:
436 if filesadded is not None:
433 filesadded = metadata.encodefileindices(files, filesadded)
437 filesadded = metadata.encodefileindices(files, filesadded)
434 extra[b'filesadded'] = filesadded
438 extra[b'filesadded'] = filesadded
435 if filesremoved is not None:
439 if filesremoved is not None:
436 filesremoved = metadata.encodefileindices(files, filesremoved)
440 filesremoved = metadata.encodefileindices(files, filesremoved)
437 extra[b'filesremoved'] = filesremoved
441 extra[b'filesremoved'] = filesremoved
438 return extra
442 return extra
@@ -1,1202 +1,1202
1 $ cat >> "$HGRCPATH" << EOF
1 $ cat >> "$HGRCPATH" << EOF
2 > [ui]
2 > [ui]
3 > merge = :merge3
3 > merge = :merge3
4 > EOF
4 > EOF
5
5
6 init
6 init
7
7
8 $ hg init repo
8 $ hg init repo
9 $ cd repo
9 $ cd repo
10
10
11 commit
11 commit
12
12
13 $ echo 'a' > a
13 $ echo 'a' > a
14 $ hg ci -A -m test -u nobody -d '1 0'
14 $ hg ci -A -m test -u nobody -d '1 0'
15 adding a
15 adding a
16
16
17 annotate -c
17 annotate -c
18
18
19 $ hg annotate -c a
19 $ hg annotate -c a
20 8435f90966e4: a
20 8435f90966e4: a
21
21
22 annotate -cl
22 annotate -cl
23
23
24 $ hg annotate -cl a
24 $ hg annotate -cl a
25 8435f90966e4:1: a
25 8435f90966e4:1: a
26
26
27 annotate -d
27 annotate -d
28
28
29 $ hg annotate -d a
29 $ hg annotate -d a
30 Thu Jan 01 00:00:01 1970 +0000: a
30 Thu Jan 01 00:00:01 1970 +0000: a
31
31
32 annotate -n
32 annotate -n
33
33
34 $ hg annotate -n a
34 $ hg annotate -n a
35 0: a
35 0: a
36
36
37 annotate -nl
37 annotate -nl
38
38
39 $ hg annotate -nl a
39 $ hg annotate -nl a
40 0:1: a
40 0:1: a
41
41
42 annotate -u
42 annotate -u
43
43
44 $ hg annotate -u a
44 $ hg annotate -u a
45 nobody: a
45 nobody: a
46
46
47 annotate -cdnu
47 annotate -cdnu
48
48
49 $ hg annotate -cdnu a
49 $ hg annotate -cdnu a
50 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a
50 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a
51
51
52 annotate -cdnul
52 annotate -cdnul
53
53
54 $ hg annotate -cdnul a
54 $ hg annotate -cdnul a
55 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000:1: a
55 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000:1: a
56
56
57 annotate (JSON)
57 annotate (JSON)
58
58
59 $ hg annotate -Tjson a
59 $ hg annotate -Tjson a
60 [
60 [
61 {
61 {
62 "lines": [{"line": "a\n", "rev": 0}],
62 "lines": [{"line": "a\n", "rev": 0}],
63 "path": "a"
63 "path": "a"
64 }
64 }
65 ]
65 ]
66
66
67 $ hg annotate -Tjson -cdfnul a
67 $ hg annotate -Tjson -cdfnul a
68 [
68 [
69 {
69 {
70 "lines": [{"date": [1.0, 0], "line": "a\n", "lineno": 1, "node": "8435f90966e442695d2ded29fdade2bac5ad8065", "path": "a", "rev": 0, "user": "nobody"}],
70 "lines": [{"date": [1.0, 0], "line": "a\n", "lineno": 1, "node": "8435f90966e442695d2ded29fdade2bac5ad8065", "path": "a", "rev": 0, "user": "nobody"}],
71 "path": "a"
71 "path": "a"
72 }
72 }
73 ]
73 ]
74
74
75 log-like templating
75 log-like templating
76
76
77 $ hg annotate -T'{lines % "{rev} {node|shortest}: {line}"}' a
77 $ hg annotate -T'{lines % "{rev} {node|shortest}: {line}"}' a
78 0 8435: a
78 0 8435: a
79
79
80 '{lineno}' field should be populated as necessary
80 '{lineno}' field should be populated as necessary
81
81
82 $ hg annotate -T'{lines % "{rev}:{lineno}: {line}"}' a
82 $ hg annotate -T'{lines % "{rev}:{lineno}: {line}"}' a
83 0:1: a
83 0:1: a
84 $ hg annotate -Ta a \
84 $ hg annotate -Ta a \
85 > --config templates.a='"{lines % "{rev}:{lineno}: {line}"}"'
85 > --config templates.a='"{lines % "{rev}:{lineno}: {line}"}"'
86 0:1: a
86 0:1: a
87
87
88 $ cat <<EOF >>a
88 $ cat <<EOF >>a
89 > a
89 > a
90 > a
90 > a
91 > EOF
91 > EOF
92 $ hg ci -ma1 -d '1 0'
92 $ hg ci -ma1 -d '1 0'
93 $ hg cp a b
93 $ hg cp a b
94 $ hg ci -mb -d '1 0'
94 $ hg ci -mb -d '1 0'
95 $ cat <<EOF >> b
95 $ cat <<EOF >> b
96 > b4
96 > b4
97 > b5
97 > b5
98 > b6
98 > b6
99 > EOF
99 > EOF
100 $ hg ci -mb2 -d '2 0'
100 $ hg ci -mb2 -d '2 0'
101
101
102 default output of '{lines}' should be readable
102 default output of '{lines}' should be readable
103
103
104 $ hg annotate -T'{lines}' a
104 $ hg annotate -T'{lines}' a
105 0: a
105 0: a
106 1: a
106 1: a
107 1: a
107 1: a
108 $ hg annotate -T'{join(lines, "\n")}' a
108 $ hg annotate -T'{join(lines, "\n")}' a
109 0: a
109 0: a
110
110
111 1: a
111 1: a
112
112
113 1: a
113 1: a
114
114
115 several filters can be applied to '{lines}'
115 several filters can be applied to '{lines}'
116
116
117 $ hg annotate -T'{lines|json}\n' a
117 $ hg annotate -T'{lines|json}\n' a
118 [{"line": "a\n", "rev": 0}, {"line": "a\n", "rev": 1}, {"line": "a\n", "rev": 1}]
118 [{"line": "a\n", "rev": 0}, {"line": "a\n", "rev": 1}, {"line": "a\n", "rev": 1}]
119 $ hg annotate -T'{lines|stringify}' a
119 $ hg annotate -T'{lines|stringify}' a
120 0: a
120 0: a
121 1: a
121 1: a
122 1: a
122 1: a
123 $ hg annotate -T'{lines|count}\n' a
123 $ hg annotate -T'{lines|count}\n' a
124 3
124 3
125
125
126 annotate multiple files (JSON)
126 annotate multiple files (JSON)
127
127
128 $ hg annotate -Tjson a b
128 $ hg annotate -Tjson a b
129 [
129 [
130 {
130 {
131 "lines": [{"line": "a\n", "rev": 0}, {"line": "a\n", "rev": 1}, {"line": "a\n", "rev": 1}],
131 "lines": [{"line": "a\n", "rev": 0}, {"line": "a\n", "rev": 1}, {"line": "a\n", "rev": 1}],
132 "path": "a"
132 "path": "a"
133 },
133 },
134 {
134 {
135 "lines": [{"line": "a\n", "rev": 0}, {"line": "a\n", "rev": 1}, {"line": "a\n", "rev": 1}, {"line": "b4\n", "rev": 3}, {"line": "b5\n", "rev": 3}, {"line": "b6\n", "rev": 3}],
135 "lines": [{"line": "a\n", "rev": 0}, {"line": "a\n", "rev": 1}, {"line": "a\n", "rev": 1}, {"line": "b4\n", "rev": 3}, {"line": "b5\n", "rev": 3}, {"line": "b6\n", "rev": 3}],
136 "path": "b"
136 "path": "b"
137 }
137 }
138 ]
138 ]
139
139
140 annotate multiple files (template)
140 annotate multiple files (template)
141
141
142 $ hg annotate -T'== {path} ==\n{lines % "{rev}: {line}"}' a b
142 $ hg annotate -T'== {path} ==\n{lines % "{rev}: {line}"}' a b
143 == a ==
143 == a ==
144 0: a
144 0: a
145 1: a
145 1: a
146 1: a
146 1: a
147 == b ==
147 == b ==
148 0: a
148 0: a
149 1: a
149 1: a
150 1: a
150 1: a
151 3: b4
151 3: b4
152 3: b5
152 3: b5
153 3: b6
153 3: b6
154
154
155 annotate -n b
155 annotate -n b
156
156
157 $ hg annotate -n b
157 $ hg annotate -n b
158 0: a
158 0: a
159 1: a
159 1: a
160 1: a
160 1: a
161 3: b4
161 3: b4
162 3: b5
162 3: b5
163 3: b6
163 3: b6
164
164
165 annotate --no-follow b
165 annotate --no-follow b
166
166
167 $ hg annotate --no-follow b
167 $ hg annotate --no-follow b
168 2: a
168 2: a
169 2: a
169 2: a
170 2: a
170 2: a
171 3: b4
171 3: b4
172 3: b5
172 3: b5
173 3: b6
173 3: b6
174
174
175 annotate -nl b
175 annotate -nl b
176
176
177 $ hg annotate -nl b
177 $ hg annotate -nl b
178 0:1: a
178 0:1: a
179 1:2: a
179 1:2: a
180 1:3: a
180 1:3: a
181 3:4: b4
181 3:4: b4
182 3:5: b5
182 3:5: b5
183 3:6: b6
183 3:6: b6
184
184
185 annotate -nf b
185 annotate -nf b
186
186
187 $ hg annotate -nf b
187 $ hg annotate -nf b
188 0 a: a
188 0 a: a
189 1 a: a
189 1 a: a
190 1 a: a
190 1 a: a
191 3 b: b4
191 3 b: b4
192 3 b: b5
192 3 b: b5
193 3 b: b6
193 3 b: b6
194
194
195 annotate -nlf b
195 annotate -nlf b
196
196
197 $ hg annotate -nlf b
197 $ hg annotate -nlf b
198 0 a:1: a
198 0 a:1: a
199 1 a:2: a
199 1 a:2: a
200 1 a:3: a
200 1 a:3: a
201 3 b:4: b4
201 3 b:4: b4
202 3 b:5: b5
202 3 b:5: b5
203 3 b:6: b6
203 3 b:6: b6
204
204
205 $ hg up -C 2
205 $ hg up -C 2
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 $ cat <<EOF >> b
207 $ cat <<EOF >> b
208 > b4
208 > b4
209 > c
209 > c
210 > b5
210 > b5
211 > EOF
211 > EOF
212 $ hg ci -mb2.1 -d '2 0'
212 $ hg ci -mb2.1 -d '2 0'
213 created new head
213 created new head
214 $ hg merge
214 $ hg merge
215 merging b
215 merging b
216 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
216 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
217 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
217 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
218 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
218 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
219 [1]
219 [1]
220 $ cat b
220 $ cat b
221 a
221 a
222 a
222 a
223 a
223 a
224 <<<<<<< working copy: 5fbdc1152d97 - test: b2.1
224 <<<<<<< working copy: 5fbdc1152d97 - test: b2.1
225 b4
225 b4
226 c
226 c
227 b5
227 b5
228 ||||||| base
228 ||||||| base
229 =======
229 =======
230 b4
230 b4
231 b5
231 b5
232 b6
232 b6
233 >>>>>>> merge rev: 37ec9f5c3d1f - test: b2
233 >>>>>>> merge rev: 37ec9f5c3d1f - test: b2
234 $ cat <<EOF > b
234 $ cat <<EOF > b
235 > a
235 > a
236 > a
236 > a
237 > a
237 > a
238 > b4
238 > b4
239 > c
239 > c
240 > b5
240 > b5
241 > EOF
241 > EOF
242 $ hg resolve --mark -q
242 $ hg resolve --mark -q
243 $ rm b.orig
243 $ rm b.orig
244 $ hg ci -mmergeb -d '3 0'
244 $ hg ci -mmergeb -d '3 0'
245
245
246 annotate after merge
246 annotate after merge
247
247
248 $ hg annotate -nf b
248 $ hg annotate -nf b
249 0 a: a
249 0 a: a
250 1 a: a
250 1 a: a
251 1 a: a
251 1 a: a
252 3 b: b4
252 3 b: b4
253 4 b: c
253 4 b: c
254 3 b: b5
254 3 b: b5
255
255
256 annotate after merge with -l
256 annotate after merge with -l
257
257
258 $ hg annotate -nlf b
258 $ hg annotate -nlf b
259 0 a:1: a
259 0 a:1: a
260 1 a:2: a
260 1 a:2: a
261 1 a:3: a
261 1 a:3: a
262 3 b:4: b4
262 3 b:4: b4
263 4 b:5: c
263 4 b:5: c
264 3 b:5: b5
264 3 b:5: b5
265
265
266 $ hg up -C 1
266 $ hg up -C 1
267 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
267 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
268 $ hg cp a b
268 $ hg cp a b
269 $ cat <<EOF > b
269 $ cat <<EOF > b
270 > a
270 > a
271 > z
271 > z
272 > a
272 > a
273 > EOF
273 > EOF
274 $ hg ci -mc -d '3 0'
274 $ hg ci -mc -d '3 0'
275 created new head
275 created new head
276 Work around the pure version not resolving the conflict like native code
276 Work around the pure version not resolving the conflict like native code
277 #if pure
277 #if pure
278 $ hg merge
278 $ hg merge
279 merging b
279 merging b
280 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
280 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
281 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
281 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
282 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
282 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
283 [1]
283 [1]
284 $ cat <<EOF > b
284 $ cat <<EOF > b
285 > a
285 > a
286 > z
286 > z
287 > a
287 > a
288 > b4
288 > b4
289 > c
289 > c
290 > b5
290 > b5
291 > EOF
291 > EOF
292 $ hg resolve -m b
292 $ hg resolve -m b
293 (no more unresolved files)
293 (no more unresolved files)
294 $ rm b.orig
294 $ rm b.orig
295 #else
295 #else
296 $ hg merge
296 $ hg merge
297 merging b
297 merging b
298 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
298 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
299 (branch merge, don't forget to commit)
299 (branch merge, don't forget to commit)
300 #endif
300 #endif
301 $ echo d >> b
301 $ echo d >> b
302 $ hg ci -mmerge2 -d '4 0'
302 $ hg ci -mmerge2 -d '4 0'
303
303
304 annotate after rename merge
304 annotate after rename merge
305
305
306 $ hg annotate -nf b
306 $ hg annotate -nf b
307 0 a: a
307 0 a: a
308 6 b: z
308 6 b: z
309 1 a: a
309 1 a: a
310 3 b: b4
310 3 b: b4
311 4 b: c
311 4 b: c
312 3 b: b5
312 3 b: b5
313 7 b: d
313 7 b: d
314
314
315 annotate after rename merge with -l
315 annotate after rename merge with -l
316
316
317 $ hg annotate -nlf b
317 $ hg annotate -nlf b
318 0 a:1: a
318 0 a:1: a
319 6 b:2: z
319 6 b:2: z
320 1 a:3: a
320 1 a:3: a
321 3 b:4: b4
321 3 b:4: b4
322 4 b:5: c
322 4 b:5: c
323 3 b:5: b5
323 3 b:5: b5
324 7 b:7: d
324 7 b:7: d
325
325
326 --skip nothing (should be the same as no --skip at all)
326 --skip nothing (should be the same as no --skip at all)
327
327
328 $ hg annotate -nlf b --skip '1::0'
328 $ hg annotate -nlf b --skip '1::0'
329 0 a:1: a
329 0 a:1: a
330 6 b:2: z
330 6 b:2: z
331 1 a:3: a
331 1 a:3: a
332 3 b:4: b4
332 3 b:4: b4
333 4 b:5: c
333 4 b:5: c
334 3 b:5: b5
334 3 b:5: b5
335 7 b:7: d
335 7 b:7: d
336
336
337 --skip a modified line. Note a slight behavior difference in pure - this is
337 --skip a modified line. Note a slight behavior difference in pure - this is
338 because the pure code comes up with slightly different deltas internally.
338 because the pure code comes up with slightly different deltas internally.
339
339
340 $ hg annotate -nlf b --skip 6
340 $ hg annotate -nlf b --skip 6
341 0 a:1: a
341 0 a:1: a
342 1 a:2* z (no-pure !)
342 1 a:2* z (no-pure !)
343 0 a:1* z (pure !)
343 0 a:1* z (pure !)
344 1 a:3: a
344 1 a:3: a
345 3 b:4: b4
345 3 b:4: b4
346 4 b:5: c
346 4 b:5: c
347 3 b:5: b5
347 3 b:5: b5
348 7 b:7: d
348 7 b:7: d
349
349
350 --skip added lines (and test multiple skip)
350 --skip added lines (and test multiple skip)
351
351
352 $ hg annotate -nlf b --skip 3
352 $ hg annotate -nlf b --skip 3
353 0 a:1: a
353 0 a:1: a
354 6 b:2: z
354 6 b:2: z
355 1 a:3: a
355 1 a:3: a
356 1 a:3* b4
356 1 a:3* b4
357 4 b:5: c
357 4 b:5: c
358 1 a:3* b5
358 1 a:3* b5
359 7 b:7: d
359 7 b:7: d
360
360
361 $ hg annotate -nlf b --skip 4
361 $ hg annotate -nlf b --skip 4
362 0 a:1: a
362 0 a:1: a
363 6 b:2: z
363 6 b:2: z
364 1 a:3: a
364 1 a:3: a
365 3 b:4: b4
365 3 b:4: b4
366 1 a:3* c
366 1 a:3* c
367 3 b:5: b5
367 3 b:5: b5
368 7 b:7: d
368 7 b:7: d
369
369
370 $ hg annotate -nlf b --skip 3 --skip 4
370 $ hg annotate -nlf b --skip 3 --skip 4
371 0 a:1: a
371 0 a:1: a
372 6 b:2: z
372 6 b:2: z
373 1 a:3: a
373 1 a:3: a
374 1 a:3* b4
374 1 a:3* b4
375 1 a:3* c
375 1 a:3* c
376 1 a:3* b5
376 1 a:3* b5
377 7 b:7: d
377 7 b:7: d
378
378
379 $ hg annotate -nlf b --skip 'merge()'
379 $ hg annotate -nlf b --skip 'merge()'
380 0 a:1: a
380 0 a:1: a
381 6 b:2: z
381 6 b:2: z
382 1 a:3: a
382 1 a:3: a
383 3 b:4: b4
383 3 b:4: b4
384 4 b:5: c
384 4 b:5: c
385 3 b:5: b5
385 3 b:5: b5
386 3 b:5* d
386 3 b:5* d
387
387
388 --skip everything -- use the revision the file was introduced in
388 --skip everything -- use the revision the file was introduced in
389
389
390 $ hg annotate -nlf b --skip 'all()'
390 $ hg annotate -nlf b --skip 'all()'
391 0 a:1: a
391 0 a:1: a
392 0 a:1* z
392 0 a:1* z
393 0 a:1* a
393 0 a:1* a
394 0 a:1* b4
394 0 a:1* b4
395 0 a:1* c
395 0 a:1* c
396 0 a:1* b5
396 0 a:1* b5
397 0 a:1* d
397 0 a:1* d
398
398
399 Issue2807: alignment of line numbers with -l
399 Issue2807: alignment of line numbers with -l
400
400
401 $ echo more >> b
401 $ echo more >> b
402 $ hg ci -mmore -d '5 0'
402 $ hg ci -mmore -d '5 0'
403 $ echo more >> b
403 $ echo more >> b
404 $ hg ci -mmore -d '6 0'
404 $ hg ci -mmore -d '6 0'
405 $ echo more >> b
405 $ echo more >> b
406 $ hg ci -mmore -d '7 0'
406 $ hg ci -mmore -d '7 0'
407 $ hg annotate -nlf b
407 $ hg annotate -nlf b
408 0 a: 1: a
408 0 a: 1: a
409 6 b: 2: z
409 6 b: 2: z
410 1 a: 3: a
410 1 a: 3: a
411 3 b: 4: b4
411 3 b: 4: b4
412 4 b: 5: c
412 4 b: 5: c
413 3 b: 5: b5
413 3 b: 5: b5
414 7 b: 7: d
414 7 b: 7: d
415 8 b: 8: more
415 8 b: 8: more
416 9 b: 9: more
416 9 b: 9: more
417 10 b:10: more
417 10 b:10: more
418
418
419 linkrev vs rev
419 linkrev vs rev
420
420
421 $ hg annotate -r tip -n a
421 $ hg annotate -r tip -n a
422 0: a
422 0: a
423 1: a
423 1: a
424 1: a
424 1: a
425
425
426 linkrev vs rev with -l
426 linkrev vs rev with -l
427
427
428 $ hg annotate -r tip -nl a
428 $ hg annotate -r tip -nl a
429 0:1: a
429 0:1: a
430 1:2: a
430 1:2: a
431 1:3: a
431 1:3: a
432
432
433 Issue589: "undelete" sequence leads to crash
433 Issue589: "undelete" sequence leads to crash
434
434
435 annotate was crashing when trying to --follow something
435 annotate was crashing when trying to --follow something
436
436
437 like A -> B -> A
437 like A -> B -> A
438
438
439 generate ABA rename configuration
439 generate ABA rename configuration
440
440
441 $ echo foo > foo
441 $ echo foo > foo
442 $ hg add foo
442 $ hg add foo
443 $ hg ci -m addfoo
443 $ hg ci -m addfoo
444 $ hg rename foo bar
444 $ hg rename foo bar
445 $ hg ci -m renamefoo
445 $ hg ci -m renamefoo
446 $ hg rename bar foo
446 $ hg rename bar foo
447 $ hg ci -m renamebar
447 $ hg ci -m renamebar
448
448
449 annotate after ABA with follow
449 annotate after ABA with follow
450
450
451 $ hg annotate --follow foo
451 $ hg annotate --follow foo
452 foo: foo
452 foo: foo
453
453
454 missing file
454 missing file
455
455
456 $ hg ann nosuchfile
456 $ hg ann nosuchfile
457 abort: nosuchfile: no such file in rev e9e6b4fa872f
457 abort: nosuchfile: no such file in rev e9e6b4fa872f
458 [255]
458 [255]
459
459
460 annotate file without '\n' on last line
460 annotate file without '\n' on last line
461
461
462 $ printf "" > c
462 $ printf "" > c
463 $ hg ci -A -m test -u nobody -d '1 0'
463 $ hg ci -A -m test -u nobody -d '1 0'
464 adding c
464 adding c
465 $ hg annotate c
465 $ hg annotate c
466 $ printf "a\nb" > c
466 $ printf "a\nb" > c
467 $ hg ci -m test
467 $ hg ci -m test
468 $ hg annotate c
468 $ hg annotate c
469 [0-9]+: a (re)
469 [0-9]+: a (re)
470 [0-9]+: b (re)
470 [0-9]+: b (re)
471
471
472 Issue3841: check annotation of the file of which filelog includes
472 Issue3841: check annotation of the file of which filelog includes
473 merging between the revision and its ancestor
473 merging between the revision and its ancestor
474
474
475 to reproduce the situation with recent Mercurial, this script uses (1)
475 to reproduce the situation with recent Mercurial, this script uses (1)
476 "hg debugsetparents" to merge without ancestor check by "hg merge",
476 "hg debugsetparents" to merge without ancestor check by "hg merge",
477 and (2) the extension to allow filelog merging between the revision
477 and (2) the extension to allow filelog merging between the revision
478 and its ancestor by overriding "repo._filecommit".
478 and its ancestor by overriding "repo._filecommit".
479
479
480 $ cat > ../legacyrepo.py <<EOF
480 $ cat > ../legacyrepo.py <<EOF
481 > from __future__ import absolute_import
481 > from __future__ import absolute_import
482 > from mercurial import commit, error, extensions, node
482 > from mercurial import commit, error, extensions, node
483 > def _filecommit(orig, repo, fctx, manifest1, manifest2,
483 > def _filecommit(orig, repo, fctx, manifest1, manifest2,
484 > linkrev, tr, includecopymeta):
484 > linkrev, tr, includecopymeta, ms):
485 > fname = fctx.path()
485 > fname = fctx.path()
486 > text = fctx.data()
486 > text = fctx.data()
487 > flog = repo.file(fname)
487 > flog = repo.file(fname)
488 > fparent1 = manifest1.get(fname, node.nullid)
488 > fparent1 = manifest1.get(fname, node.nullid)
489 > fparent2 = manifest2.get(fname, node.nullid)
489 > fparent2 = manifest2.get(fname, node.nullid)
490 > meta = {}
490 > meta = {}
491 > copy = fctx.copysource()
491 > copy = fctx.copysource()
492 > if copy and copy != fname:
492 > if copy and copy != fname:
493 > raise error.Abort('copying is not supported')
493 > raise error.Abort('copying is not supported')
494 > if fparent2 != node.nullid:
494 > if fparent2 != node.nullid:
495 > return flog.add(text, meta, tr, linkrev,
495 > return flog.add(text, meta, tr, linkrev,
496 > fparent1, fparent2), 'modified'
496 > fparent1, fparent2), 'modified'
497 > raise error.Abort('only merging is supported')
497 > raise error.Abort('only merging is supported')
498 > def uisetup(ui):
498 > def uisetup(ui):
499 > extensions.wrapfunction(commit, '_filecommit', _filecommit)
499 > extensions.wrapfunction(commit, '_filecommit', _filecommit)
500 > EOF
500 > EOF
501
501
502 $ cat > baz <<EOF
502 $ cat > baz <<EOF
503 > 1
503 > 1
504 > 2
504 > 2
505 > 3
505 > 3
506 > 4
506 > 4
507 > 5
507 > 5
508 > EOF
508 > EOF
509 $ hg add baz
509 $ hg add baz
510 $ hg commit -m "baz:0"
510 $ hg commit -m "baz:0"
511
511
512 $ cat > baz <<EOF
512 $ cat > baz <<EOF
513 > 1 baz:1
513 > 1 baz:1
514 > 2
514 > 2
515 > 3
515 > 3
516 > 4
516 > 4
517 > 5
517 > 5
518 > EOF
518 > EOF
519 $ hg commit -m "baz:1"
519 $ hg commit -m "baz:1"
520
520
521 $ cat > baz <<EOF
521 $ cat > baz <<EOF
522 > 1 baz:1
522 > 1 baz:1
523 > 2 baz:2
523 > 2 baz:2
524 > 3
524 > 3
525 > 4
525 > 4
526 > 5
526 > 5
527 > EOF
527 > EOF
528 $ hg debugsetparents 17 17
528 $ hg debugsetparents 17 17
529 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:2"
529 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:2"
530 $ hg debugindexdot baz
530 $ hg debugindexdot baz
531 digraph G {
531 digraph G {
532 -1 -> 0
532 -1 -> 0
533 0 -> 1
533 0 -> 1
534 1 -> 2
534 1 -> 2
535 1 -> 2
535 1 -> 2
536 }
536 }
537 $ hg annotate baz
537 $ hg annotate baz
538 17: 1 baz:1
538 17: 1 baz:1
539 18: 2 baz:2
539 18: 2 baz:2
540 16: 3
540 16: 3
541 16: 4
541 16: 4
542 16: 5
542 16: 5
543
543
544 $ cat > baz <<EOF
544 $ cat > baz <<EOF
545 > 1 baz:1
545 > 1 baz:1
546 > 2 baz:2
546 > 2 baz:2
547 > 3 baz:3
547 > 3 baz:3
548 > 4
548 > 4
549 > 5
549 > 5
550 > EOF
550 > EOF
551 $ hg commit -m "baz:3"
551 $ hg commit -m "baz:3"
552
552
553 $ cat > baz <<EOF
553 $ cat > baz <<EOF
554 > 1 baz:1
554 > 1 baz:1
555 > 2 baz:2
555 > 2 baz:2
556 > 3 baz:3
556 > 3 baz:3
557 > 4 baz:4
557 > 4 baz:4
558 > 5
558 > 5
559 > EOF
559 > EOF
560 $ hg debugsetparents 19 18
560 $ hg debugsetparents 19 18
561 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:4"
561 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:4"
562 $ hg debugindexdot baz
562 $ hg debugindexdot baz
563 digraph G {
563 digraph G {
564 -1 -> 0
564 -1 -> 0
565 0 -> 1
565 0 -> 1
566 1 -> 2
566 1 -> 2
567 1 -> 2
567 1 -> 2
568 2 -> 3
568 2 -> 3
569 3 -> 4
569 3 -> 4
570 2 -> 4
570 2 -> 4
571 }
571 }
572 $ hg annotate baz
572 $ hg annotate baz
573 17: 1 baz:1
573 17: 1 baz:1
574 18: 2 baz:2
574 18: 2 baz:2
575 19: 3 baz:3
575 19: 3 baz:3
576 20: 4 baz:4
576 20: 4 baz:4
577 16: 5
577 16: 5
578
578
579 annotate clean file
579 annotate clean file
580
580
581 $ hg annotate -ncr "wdir()" foo
581 $ hg annotate -ncr "wdir()" foo
582 11 472b18db256d : foo
582 11 472b18db256d : foo
583
583
584 annotate modified file
584 annotate modified file
585
585
586 $ echo foofoo >> foo
586 $ echo foofoo >> foo
587 $ hg annotate -r "wdir()" foo
587 $ hg annotate -r "wdir()" foo
588 11 : foo
588 11 : foo
589 20+: foofoo
589 20+: foofoo
590
590
591 $ hg annotate -cr "wdir()" foo
591 $ hg annotate -cr "wdir()" foo
592 472b18db256d : foo
592 472b18db256d : foo
593 b6bedd5477e7+: foofoo
593 b6bedd5477e7+: foofoo
594
594
595 $ hg annotate -ncr "wdir()" foo
595 $ hg annotate -ncr "wdir()" foo
596 11 472b18db256d : foo
596 11 472b18db256d : foo
597 20 b6bedd5477e7+: foofoo
597 20 b6bedd5477e7+: foofoo
598
598
599 $ hg annotate --debug -ncr "wdir()" foo
599 $ hg annotate --debug -ncr "wdir()" foo
600 11 472b18db256d1e8282064eab4bfdaf48cbfe83cd : foo
600 11 472b18db256d1e8282064eab4bfdaf48cbfe83cd : foo
601 20 b6bedd5477e797f25e568a6402d4697f3f895a72+: foofoo
601 20 b6bedd5477e797f25e568a6402d4697f3f895a72+: foofoo
602
602
603 $ hg annotate -udr "wdir()" foo
603 $ hg annotate -udr "wdir()" foo
604 test Thu Jan 01 00:00:00 1970 +0000: foo
604 test Thu Jan 01 00:00:00 1970 +0000: foo
605 test [A-Za-z0-9:+ ]+: foofoo (re)
605 test [A-Za-z0-9:+ ]+: foofoo (re)
606
606
607 $ hg annotate -ncr "wdir()" -Tjson foo
607 $ hg annotate -ncr "wdir()" -Tjson foo
608 [
608 [
609 {
609 {
610 "lines": [{"line": "foo\n", "node": "472b18db256d1e8282064eab4bfdaf48cbfe83cd", "rev": 11}, {"line": "foofoo\n", "node": "ffffffffffffffffffffffffffffffffffffffff", "rev": 2147483647}],
610 "lines": [{"line": "foo\n", "node": "472b18db256d1e8282064eab4bfdaf48cbfe83cd", "rev": 11}, {"line": "foofoo\n", "node": "ffffffffffffffffffffffffffffffffffffffff", "rev": 2147483647}],
611 "path": "foo"
611 "path": "foo"
612 }
612 }
613 ]
613 ]
614
614
615 annotate added file
615 annotate added file
616
616
617 $ echo bar > bar
617 $ echo bar > bar
618 $ hg add bar
618 $ hg add bar
619 $ hg annotate -ncr "wdir()" bar
619 $ hg annotate -ncr "wdir()" bar
620 20 b6bedd5477e7+: bar
620 20 b6bedd5477e7+: bar
621
621
622 annotate renamed file
622 annotate renamed file
623
623
624 $ hg rename foo renamefoo2
624 $ hg rename foo renamefoo2
625 $ hg annotate -ncr "wdir()" renamefoo2
625 $ hg annotate -ncr "wdir()" renamefoo2
626 11 472b18db256d : foo
626 11 472b18db256d : foo
627 20 b6bedd5477e7+: foofoo
627 20 b6bedd5477e7+: foofoo
628
628
629 annotate missing file
629 annotate missing file
630
630
631 $ rm baz
631 $ rm baz
632
632
633 $ hg annotate -ncr "wdir()" baz
633 $ hg annotate -ncr "wdir()" baz
634 abort: $TESTTMP\repo\baz: $ENOENT$ (windows !)
634 abort: $TESTTMP\repo\baz: $ENOENT$ (windows !)
635 abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !)
635 abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !)
636 [255]
636 [255]
637
637
638 annotate removed file
638 annotate removed file
639
639
640 $ hg rm baz
640 $ hg rm baz
641
641
642 $ hg annotate -ncr "wdir()" baz
642 $ hg annotate -ncr "wdir()" baz
643 abort: $TESTTMP\repo\baz: $ENOENT$ (windows !)
643 abort: $TESTTMP\repo\baz: $ENOENT$ (windows !)
644 abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !)
644 abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !)
645 [255]
645 [255]
646
646
647 $ hg revert --all --no-backup --quiet
647 $ hg revert --all --no-backup --quiet
648 $ hg id -n
648 $ hg id -n
649 20
649 20
650
650
651 Test followlines() revset; we usually check both followlines(pat, range) and
651 Test followlines() revset; we usually check both followlines(pat, range) and
652 followlines(pat, range, descend=True) to make sure both give the same result
652 followlines(pat, range, descend=True) to make sure both give the same result
653 when they should.
653 when they should.
654
654
655 $ echo a >> foo
655 $ echo a >> foo
656 $ hg ci -m 'foo: add a'
656 $ hg ci -m 'foo: add a'
657 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5)'
657 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5)'
658 16: baz:0
658 16: baz:0
659 19: baz:3
659 19: baz:3
660 20: baz:4
660 20: baz:4
661 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=20)'
661 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=20)'
662 16: baz:0
662 16: baz:0
663 19: baz:3
663 19: baz:3
664 20: baz:4
664 20: baz:4
665 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=19)'
665 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=19)'
666 16: baz:0
666 16: baz:0
667 19: baz:3
667 19: baz:3
668 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=19, descend=True)'
668 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=19, descend=True)'
669 19: baz:3
669 19: baz:3
670 20: baz:4
670 20: baz:4
671 $ printf "0\n0\n" | cat - baz > baz1
671 $ printf "0\n0\n" | cat - baz > baz1
672 $ mv baz1 baz
672 $ mv baz1 baz
673 $ hg ci -m 'added two lines with 0'
673 $ hg ci -m 'added two lines with 0'
674 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
674 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
675 16: baz:0
675 16: baz:0
676 19: baz:3
676 19: baz:3
677 20: baz:4
677 20: baz:4
678 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, descend=true, startrev=19)'
678 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, descend=true, startrev=19)'
679 19: baz:3
679 19: baz:3
680 20: baz:4
680 20: baz:4
681 $ echo 6 >> baz
681 $ echo 6 >> baz
682 $ hg ci -m 'added line 8'
682 $ hg ci -m 'added line 8'
683 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
683 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
684 16: baz:0
684 16: baz:0
685 19: baz:3
685 19: baz:3
686 20: baz:4
686 20: baz:4
687 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=19, descend=1)'
687 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=19, descend=1)'
688 19: baz:3
688 19: baz:3
689 20: baz:4
689 20: baz:4
690 $ sed 's/3/3+/' baz > baz.new
690 $ sed 's/3/3+/' baz > baz.new
691 $ mv baz.new baz
691 $ mv baz.new baz
692 $ hg ci -m 'baz:3->3+'
692 $ hg ci -m 'baz:3->3+'
693 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7, descend=0)'
693 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7, descend=0)'
694 16: baz:0
694 16: baz:0
695 19: baz:3
695 19: baz:3
696 20: baz:4
696 20: baz:4
697 24: baz:3->3+
697 24: baz:3->3+
698 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=17, descend=True)'
698 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=17, descend=True)'
699 19: baz:3
699 19: baz:3
700 20: baz:4
700 20: baz:4
701 24: baz:3->3+
701 24: baz:3->3+
702 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 1:2, descend=false)'
702 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 1:2, descend=false)'
703 22: added two lines with 0
703 22: added two lines with 0
704
704
705 file patterns are okay
705 file patterns are okay
706 $ hg log -T '{rev}: {desc}\n' -r 'followlines("path:baz", 1:2)'
706 $ hg log -T '{rev}: {desc}\n' -r 'followlines("path:baz", 1:2)'
707 22: added two lines with 0
707 22: added two lines with 0
708
708
709 renames are followed
709 renames are followed
710 $ hg mv baz qux
710 $ hg mv baz qux
711 $ sed 's/4/4+/' qux > qux.new
711 $ sed 's/4/4+/' qux > qux.new
712 $ mv qux.new qux
712 $ mv qux.new qux
713 $ hg ci -m 'qux:4->4+'
713 $ hg ci -m 'qux:4->4+'
714 $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)'
714 $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)'
715 16: baz:0
715 16: baz:0
716 19: baz:3
716 19: baz:3
717 20: baz:4
717 20: baz:4
718 24: baz:3->3+
718 24: baz:3->3+
719 25: qux:4->4+
719 25: qux:4->4+
720
720
721 but are missed when following children
721 but are missed when following children
722 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7, startrev=22, descend=True)'
722 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7, startrev=22, descend=True)'
723 24: baz:3->3+
723 24: baz:3->3+
724
724
725 merge
725 merge
726 $ hg up 24 --quiet
726 $ hg up 24 --quiet
727 $ echo 7 >> baz
727 $ echo 7 >> baz
728 $ hg ci -m 'one more line, out of line range'
728 $ hg ci -m 'one more line, out of line range'
729 created new head
729 created new head
730 $ sed 's/3+/3-/' baz > baz.new
730 $ sed 's/3+/3-/' baz > baz.new
731 $ mv baz.new baz
731 $ mv baz.new baz
732 $ hg ci -m 'baz:3+->3-'
732 $ hg ci -m 'baz:3+->3-'
733 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
733 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)'
734 16: baz:0
734 16: baz:0
735 19: baz:3
735 19: baz:3
736 20: baz:4
736 20: baz:4
737 24: baz:3->3+
737 24: baz:3->3+
738 27: baz:3+->3-
738 27: baz:3+->3-
739 $ hg merge 25
739 $ hg merge 25
740 merging baz and qux to qux
740 merging baz and qux to qux
741 warning: conflicts while merging qux! (edit, then use 'hg resolve --mark')
741 warning: conflicts while merging qux! (edit, then use 'hg resolve --mark')
742 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
742 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
743 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
743 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
744 [1]
744 [1]
745 $ cat qux
745 $ cat qux
746 0
746 0
747 0
747 0
748 1 baz:1
748 1 baz:1
749 2 baz:2
749 2 baz:2
750 <<<<<<< working copy: 863de62655ef - test: baz:3+->3-
750 <<<<<<< working copy: 863de62655ef - test: baz:3+->3-
751 3- baz:3
751 3- baz:3
752 4 baz:4
752 4 baz:4
753 ||||||| base
753 ||||||| base
754 3+ baz:3
754 3+ baz:3
755 4 baz:4
755 4 baz:4
756 =======
756 =======
757 3+ baz:3
757 3+ baz:3
758 4+ baz:4
758 4+ baz:4
759 >>>>>>> merge rev: cb8df70ae185 - test: qux:4->4+
759 >>>>>>> merge rev: cb8df70ae185 - test: qux:4->4+
760 5
760 5
761 6
761 6
762 7
762 7
763 $ cat > qux <<EOF
763 $ cat > qux <<EOF
764 > 0
764 > 0
765 > 0
765 > 0
766 > 1 baz:1
766 > 1 baz:1
767 > 2 baz:2
767 > 2 baz:2
768 > 3- baz:3
768 > 3- baz:3
769 > 4 baz:4
769 > 4 baz:4
770 > 5
770 > 5
771 > 6
771 > 6
772 > 7
772 > 7
773 > EOF
773 > EOF
774 $ hg resolve --mark -q
774 $ hg resolve --mark -q
775 $ rm qux.orig
775 $ rm qux.orig
776 $ hg ci -m merge
776 $ hg ci -m merge
777 $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)'
777 $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)'
778 16: baz:0
778 16: baz:0
779 19: baz:3
779 19: baz:3
780 20: baz:4
780 20: baz:4
781 24: baz:3->3+
781 24: baz:3->3+
782 25: qux:4->4+
782 25: qux:4->4+
783 27: baz:3+->3-
783 27: baz:3+->3-
784 28: merge
784 28: merge
785 $ hg up 25 --quiet
785 $ hg up 25 --quiet
786 $ hg merge 27
786 $ hg merge 27
787 merging qux and baz to qux
787 merging qux and baz to qux
788 warning: conflicts while merging qux! (edit, then use 'hg resolve --mark')
788 warning: conflicts while merging qux! (edit, then use 'hg resolve --mark')
789 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
789 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
790 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
790 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
791 [1]
791 [1]
792 $ cat qux
792 $ cat qux
793 0
793 0
794 0
794 0
795 1 baz:1
795 1 baz:1
796 2 baz:2
796 2 baz:2
797 <<<<<<< working copy: cb8df70ae185 - test: qux:4->4+
797 <<<<<<< working copy: cb8df70ae185 - test: qux:4->4+
798 3+ baz:3
798 3+ baz:3
799 4+ baz:4
799 4+ baz:4
800 ||||||| base
800 ||||||| base
801 3+ baz:3
801 3+ baz:3
802 4 baz:4
802 4 baz:4
803 =======
803 =======
804 3- baz:3
804 3- baz:3
805 4 baz:4
805 4 baz:4
806 >>>>>>> merge rev: 863de62655ef - test: baz:3+->3-
806 >>>>>>> merge rev: 863de62655ef - test: baz:3+->3-
807 5
807 5
808 6
808 6
809 7
809 7
810 $ cat > qux <<EOF
810 $ cat > qux <<EOF
811 > 0
811 > 0
812 > 0
812 > 0
813 > 1 baz:1
813 > 1 baz:1
814 > 2 baz:2
814 > 2 baz:2
815 > 3+ baz:3
815 > 3+ baz:3
816 > 4+ baz:4
816 > 4+ baz:4
817 > 5
817 > 5
818 > 6
818 > 6
819 > EOF
819 > EOF
820 $ hg resolve --mark -q
820 $ hg resolve --mark -q
821 $ rm qux.orig
821 $ rm qux.orig
822 $ hg ci -m 'merge from other side'
822 $ hg ci -m 'merge from other side'
823 created new head
823 created new head
824 $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)'
824 $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)'
825 16: baz:0
825 16: baz:0
826 19: baz:3
826 19: baz:3
827 20: baz:4
827 20: baz:4
828 24: baz:3->3+
828 24: baz:3->3+
829 25: qux:4->4+
829 25: qux:4->4+
830 27: baz:3+->3-
830 27: baz:3+->3-
831 29: merge from other side
831 29: merge from other side
832 $ hg up 24 --quiet
832 $ hg up 24 --quiet
833
833
834 we are missing the branch with rename when following children
834 we are missing the branch with rename when following children
835 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7, startrev=26, descend=True)'
835 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7, startrev=26, descend=True)'
836 27: baz:3+->3-
836 27: baz:3+->3-
837
837
838 we follow all branches in descending direction
838 we follow all branches in descending direction
839 $ hg up 23 --quiet
839 $ hg up 23 --quiet
840 $ sed 's/3/+3/' baz > baz.new
840 $ sed 's/3/+3/' baz > baz.new
841 $ mv baz.new baz
841 $ mv baz.new baz
842 $ hg ci -m 'baz:3->+3'
842 $ hg ci -m 'baz:3->+3'
843 created new head
843 created new head
844 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 2:5, startrev=16, descend=True)' --graph
844 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 2:5, startrev=16, descend=True)' --graph
845 @ 30: baz:3->+3
845 @ 30: baz:3->+3
846 :
846 :
847 : o 27: baz:3+->3-
847 : o 27: baz:3+->3-
848 : :
848 : :
849 : o 24: baz:3->3+
849 : o 24: baz:3->3+
850 :/
850 :/
851 o 20: baz:4
851 o 20: baz:4
852 |\
852 |\
853 | o 19: baz:3
853 | o 19: baz:3
854 |/
854 |/
855 o 18: baz:2
855 o 18: baz:2
856 :
856 :
857 o 16: baz:0
857 o 16: baz:0
858 |
858 |
859 ~
859 ~
860
860
861 Issue5595: on a merge changeset with different line ranges depending on
861 Issue5595: on a merge changeset with different line ranges depending on
862 parent, be conservative and use the surrounding interval to avoid loosing
862 parent, be conservative and use the surrounding interval to avoid loosing
863 track of possible further descendants in specified range.
863 track of possible further descendants in specified range.
864
864
865 $ hg up 23 --quiet
865 $ hg up 23 --quiet
866 $ hg cat baz -r 24
866 $ hg cat baz -r 24
867 0
867 0
868 0
868 0
869 1 baz:1
869 1 baz:1
870 2 baz:2
870 2 baz:2
871 3+ baz:3
871 3+ baz:3
872 4 baz:4
872 4 baz:4
873 5
873 5
874 6
874 6
875 $ cat > baz << EOF
875 $ cat > baz << EOF
876 > 0
876 > 0
877 > 0
877 > 0
878 > a
878 > a
879 > b
879 > b
880 > 3+ baz:3
880 > 3+ baz:3
881 > 4 baz:4
881 > 4 baz:4
882 > y
882 > y
883 > z
883 > z
884 > EOF
884 > EOF
885 $ hg ci -m 'baz: mostly rewrite with some content from 24'
885 $ hg ci -m 'baz: mostly rewrite with some content from 24'
886 created new head
886 created new head
887 $ hg merge --tool :merge-other 24
887 $ hg merge --tool :merge-other 24
888 merging baz
888 merging baz
889 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
889 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
890 (branch merge, don't forget to commit)
890 (branch merge, don't forget to commit)
891 $ hg ci -m 'merge forgetting about baz rewrite'
891 $ hg ci -m 'merge forgetting about baz rewrite'
892 $ cat > baz << EOF
892 $ cat > baz << EOF
893 > 0
893 > 0
894 > 0
894 > 0
895 > 1 baz:1
895 > 1 baz:1
896 > 2+ baz:2
896 > 2+ baz:2
897 > 3+ baz:3
897 > 3+ baz:3
898 > 4 baz:4
898 > 4 baz:4
899 > 5
899 > 5
900 > 6
900 > 6
901 > EOF
901 > EOF
902 $ hg ci -m 'baz: narrow change (2->2+)'
902 $ hg ci -m 'baz: narrow change (2->2+)'
903 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:4, startrev=20, descend=True)' --graph
903 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:4, startrev=20, descend=True)' --graph
904 @ 33: baz: narrow change (2->2+)
904 @ 33: baz: narrow change (2->2+)
905 |
905 |
906 o 32: merge forgetting about baz rewrite
906 o 32: merge forgetting about baz rewrite
907 |\
907 |\
908 | o 31: baz: mostly rewrite with some content from 24
908 | o 31: baz: mostly rewrite with some content from 24
909 | :
909 | :
910 | : o 30: baz:3->+3
910 | : o 30: baz:3->+3
911 | :/
911 | :/
912 +---o 27: baz:3+->3-
912 +---o 27: baz:3+->3-
913 | :
913 | :
914 o : 24: baz:3->3+
914 o : 24: baz:3->3+
915 :/
915 :/
916 o 20: baz:4
916 o 20: baz:4
917 |\
917 |\
918 ~ ~
918 ~ ~
919
919
920 An integer as a line range, which is parsed as '1:1'
920 An integer as a line range, which is parsed as '1:1'
921
921
922 $ hg log -r 'followlines(baz, 1)'
922 $ hg log -r 'followlines(baz, 1)'
923 changeset: 22:2174d0bf352a
923 changeset: 22:2174d0bf352a
924 user: test
924 user: test
925 date: Thu Jan 01 00:00:00 1970 +0000
925 date: Thu Jan 01 00:00:00 1970 +0000
926 summary: added two lines with 0
926 summary: added two lines with 0
927
927
928
928
929 check error cases
929 check error cases
930 $ hg up 24 --quiet
930 $ hg up 24 --quiet
931 $ hg log -r 'followlines()'
931 $ hg log -r 'followlines()'
932 hg: parse error: followlines takes at least 1 positional arguments
932 hg: parse error: followlines takes at least 1 positional arguments
933 [255]
933 [255]
934 $ hg log -r 'followlines(baz)'
934 $ hg log -r 'followlines(baz)'
935 hg: parse error: followlines requires a line range
935 hg: parse error: followlines requires a line range
936 [255]
936 [255]
937 $ hg log -r 'followlines(baz, x)'
937 $ hg log -r 'followlines(baz, x)'
938 hg: parse error: followlines expects a line number or a range
938 hg: parse error: followlines expects a line number or a range
939 [255]
939 [255]
940 $ hg log -r 'followlines(baz, 1:2, startrev=desc("b"))'
940 $ hg log -r 'followlines(baz, 1:2, startrev=desc("b"))'
941 hg: parse error: followlines expects exactly one revision
941 hg: parse error: followlines expects exactly one revision
942 [255]
942 [255]
943 $ hg log -r 'followlines("glob:*", 1:2)'
943 $ hg log -r 'followlines("glob:*", 1:2)'
944 hg: parse error: followlines expects exactly one file
944 hg: parse error: followlines expects exactly one file
945 [255]
945 [255]
946 $ hg log -r 'followlines(baz, 1:)'
946 $ hg log -r 'followlines(baz, 1:)'
947 hg: parse error: line range bounds must be integers
947 hg: parse error: line range bounds must be integers
948 [255]
948 [255]
949 $ hg log -r 'followlines(baz, :1)'
949 $ hg log -r 'followlines(baz, :1)'
950 hg: parse error: line range bounds must be integers
950 hg: parse error: line range bounds must be integers
951 [255]
951 [255]
952 $ hg log -r 'followlines(baz, x:4)'
952 $ hg log -r 'followlines(baz, x:4)'
953 hg: parse error: line range bounds must be integers
953 hg: parse error: line range bounds must be integers
954 [255]
954 [255]
955 $ hg log -r 'followlines(baz, 5:4)'
955 $ hg log -r 'followlines(baz, 5:4)'
956 hg: parse error: line range must be positive
956 hg: parse error: line range must be positive
957 [255]
957 [255]
958 $ hg log -r 'followlines(baz, 0:4)'
958 $ hg log -r 'followlines(baz, 0:4)'
959 hg: parse error: fromline must be strictly positive
959 hg: parse error: fromline must be strictly positive
960 [255]
960 [255]
961 $ hg log -r 'followlines(baz, 2:40)'
961 $ hg log -r 'followlines(baz, 2:40)'
962 abort: line range exceeds file size
962 abort: line range exceeds file size
963 [255]
963 [255]
964 $ hg log -r 'followlines(baz, 2:4, startrev=20, descend=[1])'
964 $ hg log -r 'followlines(baz, 2:4, startrev=20, descend=[1])'
965 hg: parse error at 43: not a prefix: [
965 hg: parse error at 43: not a prefix: [
966 (followlines(baz, 2:4, startrev=20, descend=[1])
966 (followlines(baz, 2:4, startrev=20, descend=[1])
967 ^ here)
967 ^ here)
968 [255]
968 [255]
969 $ hg log -r 'followlines(baz, 2:4, startrev=20, descend=a)'
969 $ hg log -r 'followlines(baz, 2:4, startrev=20, descend=a)'
970 hg: parse error: descend argument must be a boolean
970 hg: parse error: descend argument must be a boolean
971 [255]
971 [255]
972
972
973 Test empty annotate output
973 Test empty annotate output
974
974
975 $ printf '\0' > binary
975 $ printf '\0' > binary
976 $ touch empty
976 $ touch empty
977 $ hg ci -qAm 'add binary and empty files'
977 $ hg ci -qAm 'add binary and empty files'
978
978
979 $ hg annotate binary empty
979 $ hg annotate binary empty
980 binary: binary file
980 binary: binary file
981
981
982 $ hg annotate -Tjson binary empty
982 $ hg annotate -Tjson binary empty
983 [
983 [
984 {
984 {
985 "path": "binary"
985 "path": "binary"
986 },
986 },
987 {
987 {
988 "lines": [],
988 "lines": [],
989 "path": "empty"
989 "path": "empty"
990 }
990 }
991 ]
991 ]
992
992
993 Test annotate with whitespace options
993 Test annotate with whitespace options
994
994
995 $ cd ..
995 $ cd ..
996 $ hg init repo-ws
996 $ hg init repo-ws
997 $ cd repo-ws
997 $ cd repo-ws
998 $ cat > a <<EOF
998 $ cat > a <<EOF
999 > aa
999 > aa
1000 >
1000 >
1001 > b b
1001 > b b
1002 > EOF
1002 > EOF
1003 $ hg ci -Am "adda"
1003 $ hg ci -Am "adda"
1004 adding a
1004 adding a
1005 $ sed 's/EOL$//g' > a <<EOF
1005 $ sed 's/EOL$//g' > a <<EOF
1006 > a a
1006 > a a
1007 >
1007 >
1008 > EOL
1008 > EOL
1009 > b b
1009 > b b
1010 > EOF
1010 > EOF
1011 $ hg ci -m "changea"
1011 $ hg ci -m "changea"
1012
1012
1013 Annotate with no option
1013 Annotate with no option
1014
1014
1015 $ hg annotate a
1015 $ hg annotate a
1016 1: a a
1016 1: a a
1017 0:
1017 0:
1018 1:
1018 1:
1019 1: b b
1019 1: b b
1020
1020
1021 Annotate with --ignore-space-change
1021 Annotate with --ignore-space-change
1022
1022
1023 $ hg annotate --ignore-space-change a
1023 $ hg annotate --ignore-space-change a
1024 1: a a
1024 1: a a
1025 1:
1025 1:
1026 0:
1026 0:
1027 0: b b
1027 0: b b
1028
1028
1029 Annotate with --ignore-all-space
1029 Annotate with --ignore-all-space
1030
1030
1031 $ hg annotate --ignore-all-space a
1031 $ hg annotate --ignore-all-space a
1032 0: a a
1032 0: a a
1033 0:
1033 0:
1034 1:
1034 1:
1035 0: b b
1035 0: b b
1036
1036
1037 Annotate with --ignore-blank-lines (similar to no options case)
1037 Annotate with --ignore-blank-lines (similar to no options case)
1038
1038
1039 $ hg annotate --ignore-blank-lines a
1039 $ hg annotate --ignore-blank-lines a
1040 1: a a
1040 1: a a
1041 0:
1041 0:
1042 1:
1042 1:
1043 1: b b
1043 1: b b
1044
1044
1045 $ cd ..
1045 $ cd ..
1046
1046
1047 Annotate with orphaned CR (issue5798)
1047 Annotate with orphaned CR (issue5798)
1048 -------------------------------------
1048 -------------------------------------
1049
1049
1050 $ hg init repo-cr
1050 $ hg init repo-cr
1051 $ cd repo-cr
1051 $ cd repo-cr
1052
1052
1053 $ cat <<'EOF' >> "$TESTTMP/substcr.py"
1053 $ cat <<'EOF' >> "$TESTTMP/substcr.py"
1054 > import sys
1054 > import sys
1055 > from mercurial.utils import procutil
1055 > from mercurial.utils import procutil
1056 > procutil.setbinary(sys.stdin)
1056 > procutil.setbinary(sys.stdin)
1057 > procutil.setbinary(sys.stdout)
1057 > procutil.setbinary(sys.stdout)
1058 > stdin = getattr(sys.stdin, 'buffer', sys.stdin)
1058 > stdin = getattr(sys.stdin, 'buffer', sys.stdin)
1059 > stdout = getattr(sys.stdout, 'buffer', sys.stdout)
1059 > stdout = getattr(sys.stdout, 'buffer', sys.stdout)
1060 > stdout.write(stdin.read().replace(b'\r', b'[CR]'))
1060 > stdout.write(stdin.read().replace(b'\r', b'[CR]'))
1061 > EOF
1061 > EOF
1062
1062
1063 >>> with open('a', 'wb') as f:
1063 >>> with open('a', 'wb') as f:
1064 ... f.write(b'0a\r0b\r\n0c\r0d\r\n0e\n0f\n0g') and None
1064 ... f.write(b'0a\r0b\r\n0c\r0d\r\n0e\n0f\n0g') and None
1065 $ hg ci -qAm0
1065 $ hg ci -qAm0
1066 >>> with open('a', 'wb') as f:
1066 >>> with open('a', 'wb') as f:
1067 ... f.write(b'0a\r0b\r\n1c\r1d\r\n0e\n1f\n0g') and None
1067 ... f.write(b'0a\r0b\r\n1c\r1d\r\n0e\n1f\n0g') and None
1068 $ hg ci -m1
1068 $ hg ci -m1
1069
1069
1070 $ hg annotate -r0 a | "$PYTHON" "$TESTTMP/substcr.py"
1070 $ hg annotate -r0 a | "$PYTHON" "$TESTTMP/substcr.py"
1071 0: 0a[CR]0b[CR]
1071 0: 0a[CR]0b[CR]
1072 0: 0c[CR]0d[CR]
1072 0: 0c[CR]0d[CR]
1073 0: 0e
1073 0: 0e
1074 0: 0f
1074 0: 0f
1075 0: 0g
1075 0: 0g
1076 $ hg annotate -r1 a | "$PYTHON" "$TESTTMP/substcr.py"
1076 $ hg annotate -r1 a | "$PYTHON" "$TESTTMP/substcr.py"
1077 0: 0a[CR]0b[CR]
1077 0: 0a[CR]0b[CR]
1078 1: 1c[CR]1d[CR]
1078 1: 1c[CR]1d[CR]
1079 0: 0e
1079 0: 0e
1080 1: 1f
1080 1: 1f
1081 0: 0g
1081 0: 0g
1082
1082
1083 $ cd ..
1083 $ cd ..
1084
1084
1085 Annotate with linkrev pointing to another branch
1085 Annotate with linkrev pointing to another branch
1086 ------------------------------------------------
1086 ------------------------------------------------
1087
1087
1088 create history with a filerev whose linkrev points to another branch
1088 create history with a filerev whose linkrev points to another branch
1089
1089
1090 $ hg init branchedlinkrev
1090 $ hg init branchedlinkrev
1091 $ cd branchedlinkrev
1091 $ cd branchedlinkrev
1092 $ echo A > a
1092 $ echo A > a
1093 $ hg commit -Am 'contentA'
1093 $ hg commit -Am 'contentA'
1094 adding a
1094 adding a
1095 $ echo B >> a
1095 $ echo B >> a
1096 $ hg commit -m 'contentB'
1096 $ hg commit -m 'contentB'
1097 $ hg up --rev 'desc(contentA)'
1097 $ hg up --rev 'desc(contentA)'
1098 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1098 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1099 $ echo unrelated > unrelated
1099 $ echo unrelated > unrelated
1100 $ hg commit -Am 'unrelated'
1100 $ hg commit -Am 'unrelated'
1101 adding unrelated
1101 adding unrelated
1102 created new head
1102 created new head
1103 $ hg graft -r 'desc(contentB)'
1103 $ hg graft -r 'desc(contentB)'
1104 grafting 1:fd27c222e3e6 "contentB"
1104 grafting 1:fd27c222e3e6 "contentB"
1105 $ echo C >> a
1105 $ echo C >> a
1106 $ hg commit -m 'contentC'
1106 $ hg commit -m 'contentC'
1107 $ echo W >> a
1107 $ echo W >> a
1108 $ hg log -G
1108 $ hg log -G
1109 @ changeset: 4:072f1e8df249
1109 @ changeset: 4:072f1e8df249
1110 | tag: tip
1110 | tag: tip
1111 | user: test
1111 | user: test
1112 | date: Thu Jan 01 00:00:00 1970 +0000
1112 | date: Thu Jan 01 00:00:00 1970 +0000
1113 | summary: contentC
1113 | summary: contentC
1114 |
1114 |
1115 o changeset: 3:ff38df03cc4b
1115 o changeset: 3:ff38df03cc4b
1116 | user: test
1116 | user: test
1117 | date: Thu Jan 01 00:00:00 1970 +0000
1117 | date: Thu Jan 01 00:00:00 1970 +0000
1118 | summary: contentB
1118 | summary: contentB
1119 |
1119 |
1120 o changeset: 2:62aaf3f6fc06
1120 o changeset: 2:62aaf3f6fc06
1121 | parent: 0:f0932f74827e
1121 | parent: 0:f0932f74827e
1122 | user: test
1122 | user: test
1123 | date: Thu Jan 01 00:00:00 1970 +0000
1123 | date: Thu Jan 01 00:00:00 1970 +0000
1124 | summary: unrelated
1124 | summary: unrelated
1125 |
1125 |
1126 | o changeset: 1:fd27c222e3e6
1126 | o changeset: 1:fd27c222e3e6
1127 |/ user: test
1127 |/ user: test
1128 | date: Thu Jan 01 00:00:00 1970 +0000
1128 | date: Thu Jan 01 00:00:00 1970 +0000
1129 | summary: contentB
1129 | summary: contentB
1130 |
1130 |
1131 o changeset: 0:f0932f74827e
1131 o changeset: 0:f0932f74827e
1132 user: test
1132 user: test
1133 date: Thu Jan 01 00:00:00 1970 +0000
1133 date: Thu Jan 01 00:00:00 1970 +0000
1134 summary: contentA
1134 summary: contentA
1135
1135
1136
1136
1137 Annotate should list ancestor of starting revision only
1137 Annotate should list ancestor of starting revision only
1138
1138
1139 $ hg annotate a
1139 $ hg annotate a
1140 0: A
1140 0: A
1141 3: B
1141 3: B
1142 4: C
1142 4: C
1143
1143
1144 $ hg annotate a -r 'wdir()'
1144 $ hg annotate a -r 'wdir()'
1145 0 : A
1145 0 : A
1146 3 : B
1146 3 : B
1147 4 : C
1147 4 : C
1148 4+: W
1148 4+: W
1149
1149
1150 Even when the starting revision is the linkrev-shadowed one:
1150 Even when the starting revision is the linkrev-shadowed one:
1151
1151
1152 $ hg annotate a -r 3
1152 $ hg annotate a -r 3
1153 0: A
1153 0: A
1154 3: B
1154 3: B
1155
1155
1156 $ cd ..
1156 $ cd ..
1157
1157
1158 Issue5360: Deleted chunk in p1 of a merge changeset
1158 Issue5360: Deleted chunk in p1 of a merge changeset
1159
1159
1160 $ hg init repo-5360
1160 $ hg init repo-5360
1161 $ cd repo-5360
1161 $ cd repo-5360
1162 $ echo 1 > a
1162 $ echo 1 > a
1163 $ hg commit -A a -m 1
1163 $ hg commit -A a -m 1
1164 $ echo 2 >> a
1164 $ echo 2 >> a
1165 $ hg commit -m 2
1165 $ hg commit -m 2
1166 $ echo a > a
1166 $ echo a > a
1167 $ hg commit -m a
1167 $ hg commit -m a
1168 $ hg update '.^' -q
1168 $ hg update '.^' -q
1169 $ echo 3 >> a
1169 $ echo 3 >> a
1170 $ hg commit -m 3 -q
1170 $ hg commit -m 3 -q
1171 $ hg merge 2 -q
1171 $ hg merge 2 -q
1172 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1172 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1173 [1]
1173 [1]
1174 $ cat a
1174 $ cat a
1175 <<<<<<< working copy: 0a068f0261cf - test: 3
1175 <<<<<<< working copy: 0a068f0261cf - test: 3
1176 1
1176 1
1177 2
1177 2
1178 3
1178 3
1179 ||||||| base
1179 ||||||| base
1180 1
1180 1
1181 2
1181 2
1182 =======
1182 =======
1183 a
1183 a
1184 >>>>>>> merge rev: 9409851bc20a - test: a
1184 >>>>>>> merge rev: 9409851bc20a - test: a
1185 $ cat > a << EOF
1185 $ cat > a << EOF
1186 > b
1186 > b
1187 > 1
1187 > 1
1188 > 2
1188 > 2
1189 > 3
1189 > 3
1190 > a
1190 > a
1191 > EOF
1191 > EOF
1192 $ hg resolve --mark -q
1192 $ hg resolve --mark -q
1193 $ rm a.orig
1193 $ rm a.orig
1194 $ hg commit -m m
1194 $ hg commit -m m
1195 $ hg annotate a
1195 $ hg annotate a
1196 4: b
1196 4: b
1197 0: 1
1197 0: 1
1198 1: 2
1198 1: 2
1199 3: 3
1199 3: 3
1200 2: a
1200 2: a
1201
1201
1202 $ cd ..
1202 $ cd ..
@@ -1,819 +1,819
1 (this file is backported from core hg tests/test-annotate.t)
1 (this file is backported from core hg tests/test-annotate.t)
2
2
3 $ cat >> $HGRCPATH << EOF
3 $ cat >> $HGRCPATH << EOF
4 > [ui]
4 > [ui]
5 > merge = :merge3
5 > merge = :merge3
6 > [diff]
6 > [diff]
7 > git=1
7 > git=1
8 > [extensions]
8 > [extensions]
9 > fastannotate=
9 > fastannotate=
10 > [fastannotate]
10 > [fastannotate]
11 > modes=fctx
11 > modes=fctx
12 > forcefollow=False
12 > forcefollow=False
13 > mainbranch=.
13 > mainbranch=.
14 > EOF
14 > EOF
15
15
16 init
16 init
17
17
18 $ hg init repo
18 $ hg init repo
19 $ cd repo
19 $ cd repo
20
20
21 commit
21 commit
22
22
23 $ echo 'a' > a
23 $ echo 'a' > a
24 $ hg ci -A -m test -u nobody -d '1 0'
24 $ hg ci -A -m test -u nobody -d '1 0'
25 adding a
25 adding a
26
26
27 annotate -c
27 annotate -c
28
28
29 $ hg annotate -c a
29 $ hg annotate -c a
30 8435f90966e4: a
30 8435f90966e4: a
31
31
32 annotate -cl
32 annotate -cl
33
33
34 $ hg annotate -cl a
34 $ hg annotate -cl a
35 8435f90966e4:1: a
35 8435f90966e4:1: a
36
36
37 annotate -d
37 annotate -d
38
38
39 $ hg annotate -d a
39 $ hg annotate -d a
40 Thu Jan 01 00:00:01 1970 +0000: a
40 Thu Jan 01 00:00:01 1970 +0000: a
41
41
42 annotate -n
42 annotate -n
43
43
44 $ hg annotate -n a
44 $ hg annotate -n a
45 0: a
45 0: a
46
46
47 annotate -nl
47 annotate -nl
48
48
49 $ hg annotate -nl a
49 $ hg annotate -nl a
50 0:1: a
50 0:1: a
51
51
52 annotate -u
52 annotate -u
53
53
54 $ hg annotate -u a
54 $ hg annotate -u a
55 nobody: a
55 nobody: a
56
56
57 annotate -cdnu
57 annotate -cdnu
58
58
59 $ hg annotate -cdnu a
59 $ hg annotate -cdnu a
60 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a
60 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a
61
61
62 annotate -cdnul
62 annotate -cdnul
63
63
64 $ hg annotate -cdnul a
64 $ hg annotate -cdnul a
65 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000:1: a
65 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000:1: a
66
66
67 annotate (JSON)
67 annotate (JSON)
68
68
69 $ hg annotate -Tjson a
69 $ hg annotate -Tjson a
70 [
70 [
71 {
71 {
72 "lines": [{"line": "a\n", "rev": 0}],
72 "lines": [{"line": "a\n", "rev": 0}],
73 "path": "a"
73 "path": "a"
74 }
74 }
75 ]
75 ]
76
76
77 $ hg annotate -Tjson -cdfnul a
77 $ hg annotate -Tjson -cdfnul a
78 [
78 [
79 {
79 {
80 "lines": [{"date": [1.0, 0], "line": "a\n", "lineno": 1, "node": "8435f90966e442695d2ded29fdade2bac5ad8065", "path": "a", "rev": 0, "user": "nobody"}],
80 "lines": [{"date": [1.0, 0], "line": "a\n", "lineno": 1, "node": "8435f90966e442695d2ded29fdade2bac5ad8065", "path": "a", "rev": 0, "user": "nobody"}],
81 "path": "a"
81 "path": "a"
82 }
82 }
83 ]
83 ]
84
84
85 $ cat <<EOF >>a
85 $ cat <<EOF >>a
86 > a
86 > a
87 > a
87 > a
88 > EOF
88 > EOF
89 $ hg ci -ma1 -d '1 0'
89 $ hg ci -ma1 -d '1 0'
90 $ hg cp a b
90 $ hg cp a b
91 $ hg ci -mb -d '1 0'
91 $ hg ci -mb -d '1 0'
92 $ cat <<EOF >> b
92 $ cat <<EOF >> b
93 > b4
93 > b4
94 > b5
94 > b5
95 > b6
95 > b6
96 > EOF
96 > EOF
97 $ hg ci -mb2 -d '2 0'
97 $ hg ci -mb2 -d '2 0'
98
98
99 annotate -n b
99 annotate -n b
100
100
101 $ hg annotate -n b
101 $ hg annotate -n b
102 0: a
102 0: a
103 1: a
103 1: a
104 1: a
104 1: a
105 3: b4
105 3: b4
106 3: b5
106 3: b5
107 3: b6
107 3: b6
108
108
109 annotate --no-follow b
109 annotate --no-follow b
110
110
111 $ hg annotate --no-follow b
111 $ hg annotate --no-follow b
112 2: a
112 2: a
113 2: a
113 2: a
114 2: a
114 2: a
115 3: b4
115 3: b4
116 3: b5
116 3: b5
117 3: b6
117 3: b6
118
118
119 annotate -nl b
119 annotate -nl b
120
120
121 $ hg annotate -nl b
121 $ hg annotate -nl b
122 0:1: a
122 0:1: a
123 1:2: a
123 1:2: a
124 1:3: a
124 1:3: a
125 3:4: b4
125 3:4: b4
126 3:5: b5
126 3:5: b5
127 3:6: b6
127 3:6: b6
128
128
129 annotate -nf b
129 annotate -nf b
130
130
131 $ hg annotate -nf b
131 $ hg annotate -nf b
132 0 a: a
132 0 a: a
133 1 a: a
133 1 a: a
134 1 a: a
134 1 a: a
135 3 b: b4
135 3 b: b4
136 3 b: b5
136 3 b: b5
137 3 b: b6
137 3 b: b6
138
138
139 annotate -nlf b
139 annotate -nlf b
140
140
141 $ hg annotate -nlf b
141 $ hg annotate -nlf b
142 0 a:1: a
142 0 a:1: a
143 1 a:2: a
143 1 a:2: a
144 1 a:3: a
144 1 a:3: a
145 3 b:4: b4
145 3 b:4: b4
146 3 b:5: b5
146 3 b:5: b5
147 3 b:6: b6
147 3 b:6: b6
148
148
149 $ hg up -C 2
149 $ hg up -C 2
150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 $ cat <<EOF >> b
151 $ cat <<EOF >> b
152 > b4
152 > b4
153 > c
153 > c
154 > b5
154 > b5
155 > EOF
155 > EOF
156 $ hg ci -mb2.1 -d '2 0'
156 $ hg ci -mb2.1 -d '2 0'
157 created new head
157 created new head
158 $ hg merge
158 $ hg merge
159 merging b
159 merging b
160 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
160 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
161 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
161 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
162 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
162 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
163 [1]
163 [1]
164 $ cat b
164 $ cat b
165 a
165 a
166 a
166 a
167 a
167 a
168 <<<<<<< working copy: 5fbdc1152d97 - test: b2.1
168 <<<<<<< working copy: 5fbdc1152d97 - test: b2.1
169 b4
169 b4
170 c
170 c
171 b5
171 b5
172 ||||||| base
172 ||||||| base
173 =======
173 =======
174 b4
174 b4
175 b5
175 b5
176 b6
176 b6
177 >>>>>>> merge rev: 37ec9f5c3d1f - test: b2
177 >>>>>>> merge rev: 37ec9f5c3d1f - test: b2
178 $ cat <<EOF > b
178 $ cat <<EOF > b
179 > a
179 > a
180 > a
180 > a
181 > a
181 > a
182 > b4
182 > b4
183 > c
183 > c
184 > b5
184 > b5
185 > EOF
185 > EOF
186 $ hg resolve --mark -q
186 $ hg resolve --mark -q
187 $ rm b.orig
187 $ rm b.orig
188 $ hg ci -mmergeb -d '3 0'
188 $ hg ci -mmergeb -d '3 0'
189
189
190 annotate after merge
190 annotate after merge
191 (note: the first one falls back to the vanilla annotate which does not use linelog)
191 (note: the first one falls back to the vanilla annotate which does not use linelog)
192
192
193 $ hg annotate -nf b --debug
193 $ hg annotate -nf b --debug
194 fastannotate: b: rebuilding broken cache
194 fastannotate: b: rebuilding broken cache
195 fastannotate: b: 5 new changesets in the main branch
195 fastannotate: b: 5 new changesets in the main branch
196 0 a: a
196 0 a: a
197 1 a: a
197 1 a: a
198 1 a: a
198 1 a: a
199 3 b: b4
199 3 b: b4
200 4 b: c
200 4 b: c
201 3 b: b5
201 3 b: b5
202
202
203 (difference explained below)
203 (difference explained below)
204
204
205 $ hg annotate -nf b --debug
205 $ hg annotate -nf b --debug
206 fastannotate: b: using fast path (resolved fctx: False)
206 fastannotate: b: using fast path (resolved fctx: False)
207 0 a: a
207 0 a: a
208 1 a: a
208 1 a: a
209 1 a: a
209 1 a: a
210 4 b: b4
210 4 b: b4
211 4 b: c
211 4 b: c
212 4 b: b5
212 4 b: b5
213
213
214 annotate after merge with -l
214 annotate after merge with -l
215 (fastannotate differs from annotate)
215 (fastannotate differs from annotate)
216
216
217 $ hg log -Gp -T '{rev}:{node}' -r '2..5'
217 $ hg log -Gp -T '{rev}:{node}' -r '2..5'
218 @ 5:64afcdf8e29e063c635be123d8d2fb160af00f7e
218 @ 5:64afcdf8e29e063c635be123d8d2fb160af00f7e
219 |\
219 |\
220 | o 4:5fbdc1152d97597717021ad9e063061b200f146bdiff --git a/b b/b
220 | o 4:5fbdc1152d97597717021ad9e063061b200f146bdiff --git a/b b/b
221 | | --- a/b
221 | | --- a/b
222 | | +++ b/b
222 | | +++ b/b
223 | | @@ -1,3 +1,6 @@
223 | | @@ -1,3 +1,6 @@
224 | | a
224 | | a
225 | | a
225 | | a
226 | | a
226 | | a
227 | | +b4
227 | | +b4
228 | | +c
228 | | +c
229 | | +b5
229 | | +b5
230 | |
230 | |
231 o | 3:37ec9f5c3d1f99572d7075971cb4876e2139b52fdiff --git a/b b/b
231 o | 3:37ec9f5c3d1f99572d7075971cb4876e2139b52fdiff --git a/b b/b
232 |/ --- a/b
232 |/ --- a/b
233 | +++ b/b
233 | +++ b/b
234 | @@ -1,3 +1,6 @@
234 | @@ -1,3 +1,6 @@
235 | a
235 | a
236 | a
236 | a
237 | a
237 | a
238 | +b4
238 | +b4
239 | +b5
239 | +b5
240 | +b6
240 | +b6
241 |
241 |
242 o 2:3086dbafde1ce745abfc8d2d367847280aabae9ddiff --git a/a b/b
242 o 2:3086dbafde1ce745abfc8d2d367847280aabae9ddiff --git a/a b/b
243 | copy from a
243 | copy from a
244 ~ copy to b
244 ~ copy to b
245
245
246
246
247 (in this case, "b4", "b5" could be considered introduced by either rev 3, or rev 4.
247 (in this case, "b4", "b5" could be considered introduced by either rev 3, or rev 4.
248 and that causes the rev number difference)
248 and that causes the rev number difference)
249
249
250 $ hg annotate -nlf b --config fastannotate.modes=
250 $ hg annotate -nlf b --config fastannotate.modes=
251 0 a:1: a
251 0 a:1: a
252 1 a:2: a
252 1 a:2: a
253 1 a:3: a
253 1 a:3: a
254 3 b:4: b4
254 3 b:4: b4
255 4 b:5: c
255 4 b:5: c
256 3 b:5: b5
256 3 b:5: b5
257
257
258 $ hg annotate -nlf b
258 $ hg annotate -nlf b
259 0 a:1: a
259 0 a:1: a
260 1 a:2: a
260 1 a:2: a
261 1 a:3: a
261 1 a:3: a
262 4 b:4: b4
262 4 b:4: b4
263 4 b:5: c
263 4 b:5: c
264 4 b:6: b5
264 4 b:6: b5
265
265
266 $ hg up -C 1
266 $ hg up -C 1
267 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
267 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
268 $ hg cp a b
268 $ hg cp a b
269 $ cat <<EOF > b
269 $ cat <<EOF > b
270 > a
270 > a
271 > z
271 > z
272 > a
272 > a
273 > EOF
273 > EOF
274 $ hg ci -mc -d '3 0'
274 $ hg ci -mc -d '3 0'
275 created new head
275 created new head
276 Work around the pure version not resolving the conflict like native code
276 Work around the pure version not resolving the conflict like native code
277 #if pure
277 #if pure
278 $ hg merge
278 $ hg merge
279 merging b
279 merging b
280 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
280 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
281 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
281 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
282 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
282 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
283 [1]
283 [1]
284 $ cat <<EOF > b
284 $ cat <<EOF > b
285 > a
285 > a
286 > z
286 > z
287 > a
287 > a
288 > b4
288 > b4
289 > c
289 > c
290 > b5
290 > b5
291 > EOF
291 > EOF
292 $ hg resolve -m b
292 $ hg resolve -m b
293 (no more unresolved files)
293 (no more unresolved files)
294 $ rm b.orig
294 $ rm b.orig
295 #else
295 #else
296 $ hg merge
296 $ hg merge
297 merging b
297 merging b
298 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
298 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
299 (branch merge, don't forget to commit)
299 (branch merge, don't forget to commit)
300 #endif
300 #endif
301 $ echo d >> b
301 $ echo d >> b
302 $ hg ci -mmerge2 -d '4 0'
302 $ hg ci -mmerge2 -d '4 0'
303
303
304 annotate after rename merge
304 annotate after rename merge
305
305
306 $ hg annotate -nf b
306 $ hg annotate -nf b
307 0 a: a
307 0 a: a
308 6 b: z
308 6 b: z
309 1 a: a
309 1 a: a
310 3 b: b4
310 3 b: b4
311 4 b: c
311 4 b: c
312 3 b: b5
312 3 b: b5
313 7 b: d
313 7 b: d
314
314
315 annotate after rename merge with -l
315 annotate after rename merge with -l
316 (fastannotate differs from annotate)
316 (fastannotate differs from annotate)
317
317
318 $ hg log -Gp -T '{rev}:{node}' -r '0+1+6+7'
318 $ hg log -Gp -T '{rev}:{node}' -r '0+1+6+7'
319 @ 7:6284bb6c38fef984a929862a53bbc71ce9eafa81diff --git a/b b/b
319 @ 7:6284bb6c38fef984a929862a53bbc71ce9eafa81diff --git a/b b/b
320 |\ --- a/b
320 |\ --- a/b
321 | : +++ b/b
321 | : +++ b/b
322 | : @@ -1,3 +1,7 @@
322 | : @@ -1,3 +1,7 @@
323 | : a
323 | : a
324 | : z
324 | : z
325 | : a
325 | : a
326 | : +b4
326 | : +b4
327 | : +c
327 | : +c
328 | : +b5
328 | : +b5
329 | : +d
329 | : +d
330 | :
330 | :
331 o : 6:b80e3e32f75a6a67cd4ac85496a11511e9112816diff --git a/a b/b
331 o : 6:b80e3e32f75a6a67cd4ac85496a11511e9112816diff --git a/a b/b
332 :/ copy from a
332 :/ copy from a
333 : copy to b
333 : copy to b
334 : --- a/a
334 : --- a/a
335 : +++ b/b
335 : +++ b/b
336 : @@ -1,3 +1,3 @@
336 : @@ -1,3 +1,3 @@
337 : -a (?)
337 : -a (?)
338 : a
338 : a
339 : +z
339 : +z
340 : a
340 : a
341 : -a (?)
341 : -a (?)
342 :
342 :
343 o 1:762f04898e6684ff713415f7b8a8d53d33f96c92diff --git a/a b/a
343 o 1:762f04898e6684ff713415f7b8a8d53d33f96c92diff --git a/a b/a
344 | --- a/a
344 | --- a/a
345 | +++ b/a
345 | +++ b/a
346 | @@ -1,1 +1,3 @@
346 | @@ -1,1 +1,3 @@
347 | a
347 | a
348 | +a
348 | +a
349 | +a
349 | +a
350 |
350 |
351 o 0:8435f90966e442695d2ded29fdade2bac5ad8065diff --git a/a b/a
351 o 0:8435f90966e442695d2ded29fdade2bac5ad8065diff --git a/a b/a
352 new file mode 100644
352 new file mode 100644
353 --- /dev/null
353 --- /dev/null
354 +++ b/a
354 +++ b/a
355 @@ -0,0 +1,1 @@
355 @@ -0,0 +1,1 @@
356 +a
356 +a
357
357
358
358
359 (note on question marks:
359 (note on question marks:
360 the upstream bdiff change (96f2f50d923f+3633403888ae+8c0c75aa3ff4+5c4e2636c1a9
360 the upstream bdiff change (96f2f50d923f+3633403888ae+8c0c75aa3ff4+5c4e2636c1a9
361 +38ed54888617) alters the output so deletion is not always at the end of the
361 +38ed54888617) alters the output so deletion is not always at the end of the
362 output. for example:
362 output. for example:
363 | a | b | old | new | # old: e1d6aa0e4c3a, new: 8836f13e3c5b
363 | a | b | old | new | # old: e1d6aa0e4c3a, new: 8836f13e3c5b
364 |-------------------|
364 |-------------------|
365 | a | a | a | -a |
365 | a | a | a | -a |
366 | a | z | +z | a |
366 | a | z | +z | a |
367 | a | a | a | +z |
367 | a | a | a | +z |
368 | | | -a | a |
368 | | | -a | a |
369 |-------------------|
369 |-------------------|
370 | a | a | a |
370 | a | a | a |
371 | a | a | a |
371 | a | a | a |
372 | a | | -a |
372 | a | | -a |
373 this leads to more question marks below)
373 this leads to more question marks below)
374
374
375 (rev 1 adds two "a"s and rev 6 deletes one "a".
375 (rev 1 adds two "a"s and rev 6 deletes one "a".
376 the "a" that rev 6 deletes could be either the first or the second "a" of those two "a"s added by rev 1.
376 the "a" that rev 6 deletes could be either the first or the second "a" of those two "a"s added by rev 1.
377 and that causes the line number difference)
377 and that causes the line number difference)
378
378
379 $ hg annotate -nlf b --config fastannotate.modes=
379 $ hg annotate -nlf b --config fastannotate.modes=
380 0 a:1: a
380 0 a:1: a
381 6 b:2: z
381 6 b:2: z
382 1 a:3: a
382 1 a:3: a
383 3 b:4: b4
383 3 b:4: b4
384 4 b:5: c
384 4 b:5: c
385 3 b:5: b5
385 3 b:5: b5
386 7 b:7: d
386 7 b:7: d
387
387
388 $ hg annotate -nlf b
388 $ hg annotate -nlf b
389 0 a:1: a (?)
389 0 a:1: a (?)
390 1 a:2: a (?)
390 1 a:2: a (?)
391 6 b:2: z
391 6 b:2: z
392 1 a:2: a (?)
392 1 a:2: a (?)
393 1 a:3: a (?)
393 1 a:3: a (?)
394 3 b:4: b4
394 3 b:4: b4
395 4 b:5: c
395 4 b:5: c
396 3 b:5: b5
396 3 b:5: b5
397 7 b:7: d
397 7 b:7: d
398
398
399 Issue2807: alignment of line numbers with -l
399 Issue2807: alignment of line numbers with -l
400 (fastannotate differs from annotate, same reason as above)
400 (fastannotate differs from annotate, same reason as above)
401
401
402 $ echo more >> b
402 $ echo more >> b
403 $ hg ci -mmore -d '5 0'
403 $ hg ci -mmore -d '5 0'
404 $ echo more >> b
404 $ echo more >> b
405 $ hg ci -mmore -d '6 0'
405 $ hg ci -mmore -d '6 0'
406 $ echo more >> b
406 $ echo more >> b
407 $ hg ci -mmore -d '7 0'
407 $ hg ci -mmore -d '7 0'
408 $ hg annotate -nlf b
408 $ hg annotate -nlf b
409 0 a: 1: a (?)
409 0 a: 1: a (?)
410 1 a: 2: a (?)
410 1 a: 2: a (?)
411 6 b: 2: z
411 6 b: 2: z
412 1 a: 2: a (?)
412 1 a: 2: a (?)
413 1 a: 3: a (?)
413 1 a: 3: a (?)
414 3 b: 4: b4
414 3 b: 4: b4
415 4 b: 5: c
415 4 b: 5: c
416 3 b: 5: b5
416 3 b: 5: b5
417 7 b: 7: d
417 7 b: 7: d
418 8 b: 8: more
418 8 b: 8: more
419 9 b: 9: more
419 9 b: 9: more
420 10 b:10: more
420 10 b:10: more
421
421
422 linkrev vs rev
422 linkrev vs rev
423
423
424 $ hg annotate -r tip -n a
424 $ hg annotate -r tip -n a
425 0: a
425 0: a
426 1: a
426 1: a
427 1: a
427 1: a
428
428
429 linkrev vs rev with -l
429 linkrev vs rev with -l
430
430
431 $ hg annotate -r tip -nl a
431 $ hg annotate -r tip -nl a
432 0:1: a
432 0:1: a
433 1:2: a
433 1:2: a
434 1:3: a
434 1:3: a
435
435
436 Issue589: "undelete" sequence leads to crash
436 Issue589: "undelete" sequence leads to crash
437
437
438 annotate was crashing when trying to --follow something
438 annotate was crashing when trying to --follow something
439
439
440 like A -> B -> A
440 like A -> B -> A
441
441
442 generate ABA rename configuration
442 generate ABA rename configuration
443
443
444 $ echo foo > foo
444 $ echo foo > foo
445 $ hg add foo
445 $ hg add foo
446 $ hg ci -m addfoo
446 $ hg ci -m addfoo
447 $ hg rename foo bar
447 $ hg rename foo bar
448 $ hg ci -m renamefoo
448 $ hg ci -m renamefoo
449 $ hg rename bar foo
449 $ hg rename bar foo
450 $ hg ci -m renamebar
450 $ hg ci -m renamebar
451
451
452 annotate after ABA with follow
452 annotate after ABA with follow
453
453
454 $ hg annotate --follow foo
454 $ hg annotate --follow foo
455 foo: foo
455 foo: foo
456
456
457 missing file
457 missing file
458
458
459 $ hg ann nosuchfile
459 $ hg ann nosuchfile
460 abort: nosuchfile: no such file in rev e9e6b4fa872f
460 abort: nosuchfile: no such file in rev e9e6b4fa872f
461 [255]
461 [255]
462
462
463 annotate file without '\n' on last line
463 annotate file without '\n' on last line
464
464
465 $ printf "" > c
465 $ printf "" > c
466 $ hg ci -A -m test -u nobody -d '1 0'
466 $ hg ci -A -m test -u nobody -d '1 0'
467 adding c
467 adding c
468 $ hg annotate c
468 $ hg annotate c
469 $ printf "a\nb" > c
469 $ printf "a\nb" > c
470 $ hg ci -m test
470 $ hg ci -m test
471 $ hg annotate c
471 $ hg annotate c
472 [0-9]+: a (re)
472 [0-9]+: a (re)
473 [0-9]+: b (re)
473 [0-9]+: b (re)
474
474
475 Issue3841: check annotation of the file of which filelog includes
475 Issue3841: check annotation of the file of which filelog includes
476 merging between the revision and its ancestor
476 merging between the revision and its ancestor
477
477
478 to reproduce the situation with recent Mercurial, this script uses (1)
478 to reproduce the situation with recent Mercurial, this script uses (1)
479 "hg debugsetparents" to merge without ancestor check by "hg merge",
479 "hg debugsetparents" to merge without ancestor check by "hg merge",
480 and (2) the extension to allow filelog merging between the revision
480 and (2) the extension to allow filelog merging between the revision
481 and its ancestor by overriding "repo._filecommit".
481 and its ancestor by overriding "repo._filecommit".
482
482
483 $ cat > ../legacyrepo.py <<EOF
483 $ cat > ../legacyrepo.py <<EOF
484 > from __future__ import absolute_import
484 > from __future__ import absolute_import
485 > from mercurial import commit, error, extensions, node
485 > from mercurial import commit, error, extensions, node
486 > def _filecommit(orig, repo, fctx, manifest1, manifest2,
486 > def _filecommit(orig, repo, fctx, manifest1, manifest2,
487 > linkrev, tr, includecopymeta):
487 > linkrev, tr, includecopymeta, ms):
488 > fname = fctx.path()
488 > fname = fctx.path()
489 > text = fctx.data()
489 > text = fctx.data()
490 > flog = repo.file(fname)
490 > flog = repo.file(fname)
491 > fparent1 = manifest1.get(fname, node.nullid)
491 > fparent1 = manifest1.get(fname, node.nullid)
492 > fparent2 = manifest2.get(fname, node.nullid)
492 > fparent2 = manifest2.get(fname, node.nullid)
493 > meta = {}
493 > meta = {}
494 > copy = fctx.copysource()
494 > copy = fctx.copysource()
495 > if copy and copy != fname:
495 > if copy and copy != fname:
496 > raise error.Abort('copying is not supported')
496 > raise error.Abort('copying is not supported')
497 > if fparent2 != node.nullid:
497 > if fparent2 != node.nullid:
498 > return flog.add(text, meta, tr, linkrev,
498 > return flog.add(text, meta, tr, linkrev,
499 > fparent1, fparent2), 'modified'
499 > fparent1, fparent2), 'modified'
500 > raise error.Abort('only merging is supported')
500 > raise error.Abort('only merging is supported')
501 > def uisetup(ui):
501 > def uisetup(ui):
502 > extensions.wrapfunction(commit, '_filecommit', _filecommit)
502 > extensions.wrapfunction(commit, '_filecommit', _filecommit)
503 > EOF
503 > EOF
504
504
505 $ cat > baz <<EOF
505 $ cat > baz <<EOF
506 > 1
506 > 1
507 > 2
507 > 2
508 > 3
508 > 3
509 > 4
509 > 4
510 > 5
510 > 5
511 > EOF
511 > EOF
512 $ hg add baz
512 $ hg add baz
513 $ hg commit -m "baz:0"
513 $ hg commit -m "baz:0"
514
514
515 $ cat > baz <<EOF
515 $ cat > baz <<EOF
516 > 1 baz:1
516 > 1 baz:1
517 > 2
517 > 2
518 > 3
518 > 3
519 > 4
519 > 4
520 > 5
520 > 5
521 > EOF
521 > EOF
522 $ hg commit -m "baz:1"
522 $ hg commit -m "baz:1"
523
523
524 $ cat > baz <<EOF
524 $ cat > baz <<EOF
525 > 1 baz:1
525 > 1 baz:1
526 > 2 baz:2
526 > 2 baz:2
527 > 3
527 > 3
528 > 4
528 > 4
529 > 5
529 > 5
530 > EOF
530 > EOF
531 $ hg debugsetparents 17 17
531 $ hg debugsetparents 17 17
532 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:2"
532 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:2"
533 $ hg debugindexdot baz
533 $ hg debugindexdot baz
534 digraph G {
534 digraph G {
535 -1 -> 0
535 -1 -> 0
536 0 -> 1
536 0 -> 1
537 1 -> 2
537 1 -> 2
538 1 -> 2
538 1 -> 2
539 }
539 }
540 $ hg annotate baz
540 $ hg annotate baz
541 17: 1 baz:1
541 17: 1 baz:1
542 18: 2 baz:2
542 18: 2 baz:2
543 16: 3
543 16: 3
544 16: 4
544 16: 4
545 16: 5
545 16: 5
546
546
547 $ cat > baz <<EOF
547 $ cat > baz <<EOF
548 > 1 baz:1
548 > 1 baz:1
549 > 2 baz:2
549 > 2 baz:2
550 > 3 baz:3
550 > 3 baz:3
551 > 4
551 > 4
552 > 5
552 > 5
553 > EOF
553 > EOF
554 $ hg commit -m "baz:3"
554 $ hg commit -m "baz:3"
555
555
556 $ cat > baz <<EOF
556 $ cat > baz <<EOF
557 > 1 baz:1
557 > 1 baz:1
558 > 2 baz:2
558 > 2 baz:2
559 > 3 baz:3
559 > 3 baz:3
560 > 4 baz:4
560 > 4 baz:4
561 > 5
561 > 5
562 > EOF
562 > EOF
563 $ hg debugsetparents 19 18
563 $ hg debugsetparents 19 18
564 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:4"
564 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:4"
565 $ hg debugindexdot baz
565 $ hg debugindexdot baz
566 digraph G {
566 digraph G {
567 -1 -> 0
567 -1 -> 0
568 0 -> 1
568 0 -> 1
569 1 -> 2
569 1 -> 2
570 1 -> 2
570 1 -> 2
571 2 -> 3
571 2 -> 3
572 3 -> 4
572 3 -> 4
573 2 -> 4
573 2 -> 4
574 }
574 }
575 $ hg annotate baz
575 $ hg annotate baz
576 17: 1 baz:1
576 17: 1 baz:1
577 18: 2 baz:2
577 18: 2 baz:2
578 19: 3 baz:3
578 19: 3 baz:3
579 20: 4 baz:4
579 20: 4 baz:4
580 16: 5
580 16: 5
581
581
582 annotate clean file
582 annotate clean file
583
583
584 $ hg annotate -ncr "wdir()" foo
584 $ hg annotate -ncr "wdir()" foo
585 11 472b18db256d : foo
585 11 472b18db256d : foo
586
586
587 annotate modified file
587 annotate modified file
588
588
589 $ echo foofoo >> foo
589 $ echo foofoo >> foo
590 $ hg annotate -r "wdir()" foo
590 $ hg annotate -r "wdir()" foo
591 11 : foo
591 11 : foo
592 20+: foofoo
592 20+: foofoo
593
593
594 $ hg annotate -cr "wdir()" foo
594 $ hg annotate -cr "wdir()" foo
595 472b18db256d : foo
595 472b18db256d : foo
596 b6bedd5477e7+: foofoo
596 b6bedd5477e7+: foofoo
597
597
598 $ hg annotate -ncr "wdir()" foo
598 $ hg annotate -ncr "wdir()" foo
599 11 472b18db256d : foo
599 11 472b18db256d : foo
600 20 b6bedd5477e7+: foofoo
600 20 b6bedd5477e7+: foofoo
601
601
602 $ hg annotate --debug -ncr "wdir()" foo
602 $ hg annotate --debug -ncr "wdir()" foo
603 11 472b18db256d1e8282064eab4bfdaf48cbfe83cd : foo
603 11 472b18db256d1e8282064eab4bfdaf48cbfe83cd : foo
604 20 b6bedd5477e797f25e568a6402d4697f3f895a72+: foofoo
604 20 b6bedd5477e797f25e568a6402d4697f3f895a72+: foofoo
605
605
606 $ hg annotate -udr "wdir()" foo
606 $ hg annotate -udr "wdir()" foo
607 test Thu Jan 01 00:00:00 1970 +0000: foo
607 test Thu Jan 01 00:00:00 1970 +0000: foo
608 test [A-Za-z0-9:+ ]+: foofoo (re)
608 test [A-Za-z0-9:+ ]+: foofoo (re)
609
609
610 $ hg annotate -ncr "wdir()" -Tjson foo
610 $ hg annotate -ncr "wdir()" -Tjson foo
611 [
611 [
612 {
612 {
613 "lines": [{"line": "foo\n", "node": "472b18db256d1e8282064eab4bfdaf48cbfe83cd", "rev": 11}, {"line": "foofoo\n", "node": "ffffffffffffffffffffffffffffffffffffffff", "rev": 2147483647}],
613 "lines": [{"line": "foo\n", "node": "472b18db256d1e8282064eab4bfdaf48cbfe83cd", "rev": 11}, {"line": "foofoo\n", "node": "ffffffffffffffffffffffffffffffffffffffff", "rev": 2147483647}],
614 "path": "foo"
614 "path": "foo"
615 }
615 }
616 ]
616 ]
617
617
618 annotate added file
618 annotate added file
619
619
620 $ echo bar > bar
620 $ echo bar > bar
621 $ hg add bar
621 $ hg add bar
622 $ hg annotate -ncr "wdir()" bar
622 $ hg annotate -ncr "wdir()" bar
623 20 b6bedd5477e7+: bar
623 20 b6bedd5477e7+: bar
624
624
625 annotate renamed file
625 annotate renamed file
626
626
627 $ hg rename foo renamefoo2
627 $ hg rename foo renamefoo2
628 $ hg annotate -ncr "wdir()" renamefoo2
628 $ hg annotate -ncr "wdir()" renamefoo2
629 11 472b18db256d : foo
629 11 472b18db256d : foo
630 20 b6bedd5477e7+: foofoo
630 20 b6bedd5477e7+: foofoo
631
631
632 annotate missing file
632 annotate missing file
633
633
634 $ rm baz
634 $ rm baz
635 $ hg annotate -ncr "wdir()" baz
635 $ hg annotate -ncr "wdir()" baz
636 abort: $TESTTMP/repo/baz: $ENOENT$ (windows !)
636 abort: $TESTTMP/repo/baz: $ENOENT$ (windows !)
637 abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !)
637 abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !)
638 [255]
638 [255]
639
639
640 annotate removed file
640 annotate removed file
641
641
642 $ hg rm baz
642 $ hg rm baz
643 $ hg annotate -ncr "wdir()" baz
643 $ hg annotate -ncr "wdir()" baz
644 abort: $TESTTMP/repo/baz: $ENOENT$ (windows !)
644 abort: $TESTTMP/repo/baz: $ENOENT$ (windows !)
645 abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !)
645 abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !)
646 [255]
646 [255]
647
647
648 Test annotate with whitespace options
648 Test annotate with whitespace options
649
649
650 $ cd ..
650 $ cd ..
651 $ hg init repo-ws
651 $ hg init repo-ws
652 $ cd repo-ws
652 $ cd repo-ws
653 $ cat > a <<EOF
653 $ cat > a <<EOF
654 > aa
654 > aa
655 >
655 >
656 > b b
656 > b b
657 > EOF
657 > EOF
658 $ hg ci -Am "adda"
658 $ hg ci -Am "adda"
659 adding a
659 adding a
660 $ sed 's/EOL$//g' > a <<EOF
660 $ sed 's/EOL$//g' > a <<EOF
661 > a a
661 > a a
662 >
662 >
663 > EOL
663 > EOL
664 > b b
664 > b b
665 > EOF
665 > EOF
666 $ hg ci -m "changea"
666 $ hg ci -m "changea"
667
667
668 Annotate with no option
668 Annotate with no option
669
669
670 $ hg annotate a
670 $ hg annotate a
671 1: a a
671 1: a a
672 0:
672 0:
673 1:
673 1:
674 1: b b
674 1: b b
675
675
676 Annotate with --ignore-space-change
676 Annotate with --ignore-space-change
677
677
678 $ hg annotate --ignore-space-change a
678 $ hg annotate --ignore-space-change a
679 1: a a
679 1: a a
680 1:
680 1:
681 0:
681 0:
682 0: b b
682 0: b b
683
683
684 Annotate with --ignore-all-space
684 Annotate with --ignore-all-space
685
685
686 $ hg annotate --ignore-all-space a
686 $ hg annotate --ignore-all-space a
687 0: a a
687 0: a a
688 0:
688 0:
689 1:
689 1:
690 0: b b
690 0: b b
691
691
692 Annotate with --ignore-blank-lines (similar to no options case)
692 Annotate with --ignore-blank-lines (similar to no options case)
693
693
694 $ hg annotate --ignore-blank-lines a
694 $ hg annotate --ignore-blank-lines a
695 1: a a
695 1: a a
696 0:
696 0:
697 1:
697 1:
698 1: b b
698 1: b b
699
699
700 $ cd ..
700 $ cd ..
701
701
702 Annotate with linkrev pointing to another branch
702 Annotate with linkrev pointing to another branch
703 ------------------------------------------------
703 ------------------------------------------------
704
704
705 create history with a filerev whose linkrev points to another branch
705 create history with a filerev whose linkrev points to another branch
706
706
707 $ hg init branchedlinkrev
707 $ hg init branchedlinkrev
708 $ cd branchedlinkrev
708 $ cd branchedlinkrev
709 $ echo A > a
709 $ echo A > a
710 $ hg commit -Am 'contentA'
710 $ hg commit -Am 'contentA'
711 adding a
711 adding a
712 $ echo B >> a
712 $ echo B >> a
713 $ hg commit -m 'contentB'
713 $ hg commit -m 'contentB'
714 $ hg up --rev 'desc(contentA)'
714 $ hg up --rev 'desc(contentA)'
715 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
715 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
716 $ echo unrelated > unrelated
716 $ echo unrelated > unrelated
717 $ hg commit -Am 'unrelated'
717 $ hg commit -Am 'unrelated'
718 adding unrelated
718 adding unrelated
719 created new head
719 created new head
720 $ hg graft -r 'desc(contentB)'
720 $ hg graft -r 'desc(contentB)'
721 grafting 1:fd27c222e3e6 "contentB"
721 grafting 1:fd27c222e3e6 "contentB"
722 $ echo C >> a
722 $ echo C >> a
723 $ hg commit -m 'contentC'
723 $ hg commit -m 'contentC'
724 $ echo W >> a
724 $ echo W >> a
725 $ hg log -G
725 $ hg log -G
726 @ changeset: 4:072f1e8df249
726 @ changeset: 4:072f1e8df249
727 | tag: tip
727 | tag: tip
728 | user: test
728 | user: test
729 | date: Thu Jan 01 00:00:00 1970 +0000
729 | date: Thu Jan 01 00:00:00 1970 +0000
730 | summary: contentC
730 | summary: contentC
731 |
731 |
732 o changeset: 3:ff38df03cc4b
732 o changeset: 3:ff38df03cc4b
733 | user: test
733 | user: test
734 | date: Thu Jan 01 00:00:00 1970 +0000
734 | date: Thu Jan 01 00:00:00 1970 +0000
735 | summary: contentB
735 | summary: contentB
736 |
736 |
737 o changeset: 2:62aaf3f6fc06
737 o changeset: 2:62aaf3f6fc06
738 | parent: 0:f0932f74827e
738 | parent: 0:f0932f74827e
739 | user: test
739 | user: test
740 | date: Thu Jan 01 00:00:00 1970 +0000
740 | date: Thu Jan 01 00:00:00 1970 +0000
741 | summary: unrelated
741 | summary: unrelated
742 |
742 |
743 | o changeset: 1:fd27c222e3e6
743 | o changeset: 1:fd27c222e3e6
744 |/ user: test
744 |/ user: test
745 | date: Thu Jan 01 00:00:00 1970 +0000
745 | date: Thu Jan 01 00:00:00 1970 +0000
746 | summary: contentB
746 | summary: contentB
747 |
747 |
748 o changeset: 0:f0932f74827e
748 o changeset: 0:f0932f74827e
749 user: test
749 user: test
750 date: Thu Jan 01 00:00:00 1970 +0000
750 date: Thu Jan 01 00:00:00 1970 +0000
751 summary: contentA
751 summary: contentA
752
752
753
753
754 Annotate should list ancestor of starting revision only
754 Annotate should list ancestor of starting revision only
755
755
756 $ hg annotate a
756 $ hg annotate a
757 0: A
757 0: A
758 3: B
758 3: B
759 4: C
759 4: C
760
760
761 $ hg annotate a -r 'wdir()'
761 $ hg annotate a -r 'wdir()'
762 0 : A
762 0 : A
763 3 : B
763 3 : B
764 4 : C
764 4 : C
765 4+: W
765 4+: W
766
766
767 Even when the starting revision is the linkrev-shadowed one:
767 Even when the starting revision is the linkrev-shadowed one:
768
768
769 $ hg annotate a -r 3
769 $ hg annotate a -r 3
770 0: A
770 0: A
771 3: B
771 3: B
772
772
773 $ cd ..
773 $ cd ..
774
774
775 Issue5360: Deleted chunk in p1 of a merge changeset
775 Issue5360: Deleted chunk in p1 of a merge changeset
776
776
777 $ hg init repo-5360
777 $ hg init repo-5360
778 $ cd repo-5360
778 $ cd repo-5360
779 $ echo 1 > a
779 $ echo 1 > a
780 $ hg commit -A a -m 1
780 $ hg commit -A a -m 1
781 $ echo 2 >> a
781 $ echo 2 >> a
782 $ hg commit -m 2
782 $ hg commit -m 2
783 $ echo a > a
783 $ echo a > a
784 $ hg commit -m a
784 $ hg commit -m a
785 $ hg update '.^' -q
785 $ hg update '.^' -q
786 $ echo 3 >> a
786 $ echo 3 >> a
787 $ hg commit -m 3 -q
787 $ hg commit -m 3 -q
788 $ hg merge 2 -q
788 $ hg merge 2 -q
789 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
789 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
790 [1]
790 [1]
791 $ cat a
791 $ cat a
792 <<<<<<< working copy: 0a068f0261cf - test: 3
792 <<<<<<< working copy: 0a068f0261cf - test: 3
793 1
793 1
794 2
794 2
795 3
795 3
796 ||||||| base
796 ||||||| base
797 1
797 1
798 2
798 2
799 =======
799 =======
800 a
800 a
801 >>>>>>> merge rev: 9409851bc20a - test: a
801 >>>>>>> merge rev: 9409851bc20a - test: a
802 $ cat > a << EOF
802 $ cat > a << EOF
803 > b
803 > b
804 > 1
804 > 1
805 > 2
805 > 2
806 > 3
806 > 3
807 > a
807 > a
808 > EOF
808 > EOF
809 $ hg resolve --mark -q
809 $ hg resolve --mark -q
810 $ rm a.orig
810 $ rm a.orig
811 $ hg commit -m m
811 $ hg commit -m m
812 $ hg annotate a
812 $ hg annotate a
813 4: b
813 4: b
814 0: 1
814 0: 1
815 1: 2
815 1: 2
816 3: 3
816 3: 3
817 2: a
817 2: a
818
818
819 $ cd ..
819 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now