##// END OF EJS Templates
filectx.parents: enforce changeid of parent to be in own changectx ancestors...
Pierre-Yves David -
r23702:c4892478 default
parent child Browse files
Show More
@@ -1,1726 +1,1772 b''
1 # context.py - changeset and file context objects for mercurial
1 # context.py - changeset and file context objects for mercurial
2 #
2 #
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import nullid, nullrev, short, hex, bin
8 from node import nullid, nullrev, short, hex, bin
9 from i18n import _
9 from i18n import _
10 import mdiff, error, util, scmutil, subrepo, patch, encoding, phases
10 import mdiff, error, util, scmutil, subrepo, patch, encoding, phases
11 import match as matchmod
11 import match as matchmod
12 import os, errno, stat
12 import os, errno, stat
13 import obsolete as obsmod
13 import obsolete as obsmod
14 import repoview
14 import repoview
15 import fileset
15 import fileset
16 import revlog
16 import revlog
17
17
18 propertycache = util.propertycache
18 propertycache = util.propertycache
19
19
20 # Phony node value to stand-in for new files in some uses of
20 # Phony node value to stand-in for new files in some uses of
21 # manifests. Manifests support 21-byte hashes for nodes which are
21 # manifests. Manifests support 21-byte hashes for nodes which are
22 # dirty in the working copy.
22 # dirty in the working copy.
23 _newnode = '!' * 21
23 _newnode = '!' * 21
24
24
25 def _adjustlinkrev(repo, path, filelog, fnode, srcrev):
26 """return the first ancestor of <srcrev> introducting <fnode>
27
28 If the linkrev of the file revision does not point to an ancestor of
29 srcrev, we'll walk down the ancestors until we find one introducing this
30 file revision.
31
32 :repo: a localrepository object (used to access changelog and manifest)
33 :path: the file path
34 :fnode: the nodeid of the file revision
35 :filelog: the filelog of this path
36 :srcrev: the changeset revision we search ancestors from
37 """
38 cl = repo.unfiltered().changelog
39 ma = repo.manifest
40 # fetch the linkrev
41 fr = filelog.rev(fnode)
42 lkr = filelog.linkrev(fr)
43 # check if this linkrev is an ancestor of srcrev
44 anc = cl.ancestors([srcrev], lkr)
45 if lkr not in anc:
46 for a in anc:
47 ac = cl.read(a) # get changeset data (we avoid object creation).
48 if path in ac[3]: # checking the 'files' field.
49 # The file has been touched, check if the content is similar
50 # to the one we search for.
51 if fnode == ma.readdelta(ac[0]).get(path):
52 return a
53 # In theory, we should never get out of that loop without a result. But
54 # if manifest uses a buggy file revision (not children of the one it
55 # replaces) we could. Such a buggy situation will likely result is crash
56 # somewhere else at to some point.
57 return lkr
58
25 class basectx(object):
59 class basectx(object):
26 """A basectx object represents the common logic for its children:
60 """A basectx object represents the common logic for its children:
27 changectx: read-only context that is already present in the repo,
61 changectx: read-only context that is already present in the repo,
28 workingctx: a context that represents the working directory and can
62 workingctx: a context that represents the working directory and can
29 be committed,
63 be committed,
30 memctx: a context that represents changes in-memory and can also
64 memctx: a context that represents changes in-memory and can also
31 be committed."""
65 be committed."""
32 def __new__(cls, repo, changeid='', *args, **kwargs):
66 def __new__(cls, repo, changeid='', *args, **kwargs):
33 if isinstance(changeid, basectx):
67 if isinstance(changeid, basectx):
34 return changeid
68 return changeid
35
69
36 o = super(basectx, cls).__new__(cls)
70 o = super(basectx, cls).__new__(cls)
37
71
38 o._repo = repo
72 o._repo = repo
39 o._rev = nullrev
73 o._rev = nullrev
40 o._node = nullid
74 o._node = nullid
41
75
42 return o
76 return o
43
77
44 def __str__(self):
78 def __str__(self):
45 return short(self.node())
79 return short(self.node())
46
80
47 def __int__(self):
81 def __int__(self):
48 return self.rev()
82 return self.rev()
49
83
50 def __repr__(self):
84 def __repr__(self):
51 return "<%s %s>" % (type(self).__name__, str(self))
85 return "<%s %s>" % (type(self).__name__, str(self))
52
86
53 def __eq__(self, other):
87 def __eq__(self, other):
54 try:
88 try:
55 return type(self) == type(other) and self._rev == other._rev
89 return type(self) == type(other) and self._rev == other._rev
56 except AttributeError:
90 except AttributeError:
57 return False
91 return False
58
92
59 def __ne__(self, other):
93 def __ne__(self, other):
60 return not (self == other)
94 return not (self == other)
61
95
62 def __contains__(self, key):
96 def __contains__(self, key):
63 return key in self._manifest
97 return key in self._manifest
64
98
65 def __getitem__(self, key):
99 def __getitem__(self, key):
66 return self.filectx(key)
100 return self.filectx(key)
67
101
68 def __iter__(self):
102 def __iter__(self):
69 for f in sorted(self._manifest):
103 for f in sorted(self._manifest):
70 yield f
104 yield f
71
105
72 def _manifestmatches(self, match, s):
106 def _manifestmatches(self, match, s):
73 """generate a new manifest filtered by the match argument
107 """generate a new manifest filtered by the match argument
74
108
75 This method is for internal use only and mainly exists to provide an
109 This method is for internal use only and mainly exists to provide an
76 object oriented way for other contexts to customize the manifest
110 object oriented way for other contexts to customize the manifest
77 generation.
111 generation.
78 """
112 """
79 return self.manifest().matches(match)
113 return self.manifest().matches(match)
80
114
81 def _matchstatus(self, other, match):
115 def _matchstatus(self, other, match):
82 """return match.always if match is none
116 """return match.always if match is none
83
117
84 This internal method provides a way for child objects to override the
118 This internal method provides a way for child objects to override the
85 match operator.
119 match operator.
86 """
120 """
87 return match or matchmod.always(self._repo.root, self._repo.getcwd())
121 return match or matchmod.always(self._repo.root, self._repo.getcwd())
88
122
89 def _buildstatus(self, other, s, match, listignored, listclean,
123 def _buildstatus(self, other, s, match, listignored, listclean,
90 listunknown):
124 listunknown):
91 """build a status with respect to another context"""
125 """build a status with respect to another context"""
92 # Load earliest manifest first for caching reasons. More specifically,
126 # Load earliest manifest first for caching reasons. More specifically,
93 # if you have revisions 1000 and 1001, 1001 is probably stored as a
127 # if you have revisions 1000 and 1001, 1001 is probably stored as a
94 # delta against 1000. Thus, if you read 1000 first, we'll reconstruct
128 # delta against 1000. Thus, if you read 1000 first, we'll reconstruct
95 # 1000 and cache it so that when you read 1001, we just need to apply a
129 # 1000 and cache it so that when you read 1001, we just need to apply a
96 # delta to what's in the cache. So that's one full reconstruction + one
130 # delta to what's in the cache. So that's one full reconstruction + one
97 # delta application.
131 # delta application.
98 if self.rev() is not None and self.rev() < other.rev():
132 if self.rev() is not None and self.rev() < other.rev():
99 self.manifest()
133 self.manifest()
100 mf1 = other._manifestmatches(match, s)
134 mf1 = other._manifestmatches(match, s)
101 mf2 = self._manifestmatches(match, s)
135 mf2 = self._manifestmatches(match, s)
102
136
103 modified, added, clean = [], [], []
137 modified, added, clean = [], [], []
104 deleted, unknown, ignored = s.deleted, s.unknown, s.ignored
138 deleted, unknown, ignored = s.deleted, s.unknown, s.ignored
105 deletedset = set(deleted)
139 deletedset = set(deleted)
106 withflags = mf1.withflags() | mf2.withflags()
140 withflags = mf1.withflags() | mf2.withflags()
107 for fn, mf2node in mf2.iteritems():
141 for fn, mf2node in mf2.iteritems():
108 if fn in mf1:
142 if fn in mf1:
109 if (fn not in deletedset and
143 if (fn not in deletedset and
110 ((fn in withflags and mf1.flags(fn) != mf2.flags(fn)) or
144 ((fn in withflags and mf1.flags(fn) != mf2.flags(fn)) or
111 (mf1[fn] != mf2node and
145 (mf1[fn] != mf2node and
112 (mf2node != _newnode or self[fn].cmp(other[fn]))))):
146 (mf2node != _newnode or self[fn].cmp(other[fn]))))):
113 modified.append(fn)
147 modified.append(fn)
114 elif listclean:
148 elif listclean:
115 clean.append(fn)
149 clean.append(fn)
116 del mf1[fn]
150 del mf1[fn]
117 elif fn not in deletedset:
151 elif fn not in deletedset:
118 added.append(fn)
152 added.append(fn)
119 removed = mf1.keys()
153 removed = mf1.keys()
120 if removed:
154 if removed:
121 # need to filter files if they are already reported as removed
155 # need to filter files if they are already reported as removed
122 unknown = [fn for fn in unknown if fn not in mf1]
156 unknown = [fn for fn in unknown if fn not in mf1]
123 ignored = [fn for fn in ignored if fn not in mf1]
157 ignored = [fn for fn in ignored if fn not in mf1]
124
158
125 return scmutil.status(modified, added, removed, deleted, unknown,
159 return scmutil.status(modified, added, removed, deleted, unknown,
126 ignored, clean)
160 ignored, clean)
127
161
128 @propertycache
162 @propertycache
129 def substate(self):
163 def substate(self):
130 return subrepo.state(self, self._repo.ui)
164 return subrepo.state(self, self._repo.ui)
131
165
132 def subrev(self, subpath):
166 def subrev(self, subpath):
133 return self.substate[subpath][1]
167 return self.substate[subpath][1]
134
168
135 def rev(self):
169 def rev(self):
136 return self._rev
170 return self._rev
137 def node(self):
171 def node(self):
138 return self._node
172 return self._node
139 def hex(self):
173 def hex(self):
140 return hex(self.node())
174 return hex(self.node())
141 def manifest(self):
175 def manifest(self):
142 return self._manifest
176 return self._manifest
143 def phasestr(self):
177 def phasestr(self):
144 return phases.phasenames[self.phase()]
178 return phases.phasenames[self.phase()]
145 def mutable(self):
179 def mutable(self):
146 return self.phase() > phases.public
180 return self.phase() > phases.public
147
181
148 def getfileset(self, expr):
182 def getfileset(self, expr):
149 return fileset.getfileset(self, expr)
183 return fileset.getfileset(self, expr)
150
184
151 def obsolete(self):
185 def obsolete(self):
152 """True if the changeset is obsolete"""
186 """True if the changeset is obsolete"""
153 return self.rev() in obsmod.getrevs(self._repo, 'obsolete')
187 return self.rev() in obsmod.getrevs(self._repo, 'obsolete')
154
188
155 def extinct(self):
189 def extinct(self):
156 """True if the changeset is extinct"""
190 """True if the changeset is extinct"""
157 return self.rev() in obsmod.getrevs(self._repo, 'extinct')
191 return self.rev() in obsmod.getrevs(self._repo, 'extinct')
158
192
159 def unstable(self):
193 def unstable(self):
160 """True if the changeset is not obsolete but it's ancestor are"""
194 """True if the changeset is not obsolete but it's ancestor are"""
161 return self.rev() in obsmod.getrevs(self._repo, 'unstable')
195 return self.rev() in obsmod.getrevs(self._repo, 'unstable')
162
196
163 def bumped(self):
197 def bumped(self):
164 """True if the changeset try to be a successor of a public changeset
198 """True if the changeset try to be a successor of a public changeset
165
199
166 Only non-public and non-obsolete changesets may be bumped.
200 Only non-public and non-obsolete changesets may be bumped.
167 """
201 """
168 return self.rev() in obsmod.getrevs(self._repo, 'bumped')
202 return self.rev() in obsmod.getrevs(self._repo, 'bumped')
169
203
170 def divergent(self):
204 def divergent(self):
171 """Is a successors of a changeset with multiple possible successors set
205 """Is a successors of a changeset with multiple possible successors set
172
206
173 Only non-public and non-obsolete changesets may be divergent.
207 Only non-public and non-obsolete changesets may be divergent.
174 """
208 """
175 return self.rev() in obsmod.getrevs(self._repo, 'divergent')
209 return self.rev() in obsmod.getrevs(self._repo, 'divergent')
176
210
177 def troubled(self):
211 def troubled(self):
178 """True if the changeset is either unstable, bumped or divergent"""
212 """True if the changeset is either unstable, bumped or divergent"""
179 return self.unstable() or self.bumped() or self.divergent()
213 return self.unstable() or self.bumped() or self.divergent()
180
214
181 def troubles(self):
215 def troubles(self):
182 """return the list of troubles affecting this changesets.
216 """return the list of troubles affecting this changesets.
183
217
184 Troubles are returned as strings. possible values are:
218 Troubles are returned as strings. possible values are:
185 - unstable,
219 - unstable,
186 - bumped,
220 - bumped,
187 - divergent.
221 - divergent.
188 """
222 """
189 troubles = []
223 troubles = []
190 if self.unstable():
224 if self.unstable():
191 troubles.append('unstable')
225 troubles.append('unstable')
192 if self.bumped():
226 if self.bumped():
193 troubles.append('bumped')
227 troubles.append('bumped')
194 if self.divergent():
228 if self.divergent():
195 troubles.append('divergent')
229 troubles.append('divergent')
196 return troubles
230 return troubles
197
231
198 def parents(self):
232 def parents(self):
199 """return contexts for each parent changeset"""
233 """return contexts for each parent changeset"""
200 return self._parents
234 return self._parents
201
235
202 def p1(self):
236 def p1(self):
203 return self._parents[0]
237 return self._parents[0]
204
238
205 def p2(self):
239 def p2(self):
206 if len(self._parents) == 2:
240 if len(self._parents) == 2:
207 return self._parents[1]
241 return self._parents[1]
208 return changectx(self._repo, -1)
242 return changectx(self._repo, -1)
209
243
210 def _fileinfo(self, path):
244 def _fileinfo(self, path):
211 if '_manifest' in self.__dict__:
245 if '_manifest' in self.__dict__:
212 try:
246 try:
213 return self._manifest[path], self._manifest.flags(path)
247 return self._manifest[path], self._manifest.flags(path)
214 except KeyError:
248 except KeyError:
215 raise error.ManifestLookupError(self._node, path,
249 raise error.ManifestLookupError(self._node, path,
216 _('not found in manifest'))
250 _('not found in manifest'))
217 if '_manifestdelta' in self.__dict__ or path in self.files():
251 if '_manifestdelta' in self.__dict__ or path in self.files():
218 if path in self._manifestdelta:
252 if path in self._manifestdelta:
219 return (self._manifestdelta[path],
253 return (self._manifestdelta[path],
220 self._manifestdelta.flags(path))
254 self._manifestdelta.flags(path))
221 node, flag = self._repo.manifest.find(self._changeset[0], path)
255 node, flag = self._repo.manifest.find(self._changeset[0], path)
222 if not node:
256 if not node:
223 raise error.ManifestLookupError(self._node, path,
257 raise error.ManifestLookupError(self._node, path,
224 _('not found in manifest'))
258 _('not found in manifest'))
225
259
226 return node, flag
260 return node, flag
227
261
228 def filenode(self, path):
262 def filenode(self, path):
229 return self._fileinfo(path)[0]
263 return self._fileinfo(path)[0]
230
264
231 def flags(self, path):
265 def flags(self, path):
232 try:
266 try:
233 return self._fileinfo(path)[1]
267 return self._fileinfo(path)[1]
234 except error.LookupError:
268 except error.LookupError:
235 return ''
269 return ''
236
270
237 def sub(self, path):
271 def sub(self, path):
238 return subrepo.subrepo(self, path)
272 return subrepo.subrepo(self, path)
239
273
240 def match(self, pats=[], include=None, exclude=None, default='glob'):
274 def match(self, pats=[], include=None, exclude=None, default='glob'):
241 r = self._repo
275 r = self._repo
242 return matchmod.match(r.root, r.getcwd(), pats,
276 return matchmod.match(r.root, r.getcwd(), pats,
243 include, exclude, default,
277 include, exclude, default,
244 auditor=r.auditor, ctx=self)
278 auditor=r.auditor, ctx=self)
245
279
246 def diff(self, ctx2=None, match=None, **opts):
280 def diff(self, ctx2=None, match=None, **opts):
247 """Returns a diff generator for the given contexts and matcher"""
281 """Returns a diff generator for the given contexts and matcher"""
248 if ctx2 is None:
282 if ctx2 is None:
249 ctx2 = self.p1()
283 ctx2 = self.p1()
250 if ctx2 is not None:
284 if ctx2 is not None:
251 ctx2 = self._repo[ctx2]
285 ctx2 = self._repo[ctx2]
252 diffopts = patch.diffopts(self._repo.ui, opts)
286 diffopts = patch.diffopts(self._repo.ui, opts)
253 return patch.diff(self._repo, ctx2, self, match=match, opts=diffopts)
287 return patch.diff(self._repo, ctx2, self, match=match, opts=diffopts)
254
288
255 @propertycache
289 @propertycache
256 def _dirs(self):
290 def _dirs(self):
257 return scmutil.dirs(self._manifest)
291 return scmutil.dirs(self._manifest)
258
292
259 def dirs(self):
293 def dirs(self):
260 return self._dirs
294 return self._dirs
261
295
262 def dirty(self, missing=False, merge=True, branch=True):
296 def dirty(self, missing=False, merge=True, branch=True):
263 return False
297 return False
264
298
265 def status(self, other=None, match=None, listignored=False,
299 def status(self, other=None, match=None, listignored=False,
266 listclean=False, listunknown=False, listsubrepos=False):
300 listclean=False, listunknown=False, listsubrepos=False):
267 """return status of files between two nodes or node and working
301 """return status of files between two nodes or node and working
268 directory.
302 directory.
269
303
270 If other is None, compare this node with working directory.
304 If other is None, compare this node with working directory.
271
305
272 returns (modified, added, removed, deleted, unknown, ignored, clean)
306 returns (modified, added, removed, deleted, unknown, ignored, clean)
273 """
307 """
274
308
275 ctx1 = self
309 ctx1 = self
276 ctx2 = self._repo[other]
310 ctx2 = self._repo[other]
277
311
278 # This next code block is, admittedly, fragile logic that tests for
312 # This next code block is, admittedly, fragile logic that tests for
279 # reversing the contexts and wouldn't need to exist if it weren't for
313 # reversing the contexts and wouldn't need to exist if it weren't for
280 # the fast (and common) code path of comparing the working directory
314 # the fast (and common) code path of comparing the working directory
281 # with its first parent.
315 # with its first parent.
282 #
316 #
283 # What we're aiming for here is the ability to call:
317 # What we're aiming for here is the ability to call:
284 #
318 #
285 # workingctx.status(parentctx)
319 # workingctx.status(parentctx)
286 #
320 #
287 # If we always built the manifest for each context and compared those,
321 # If we always built the manifest for each context and compared those,
288 # then we'd be done. But the special case of the above call means we
322 # then we'd be done. But the special case of the above call means we
289 # just copy the manifest of the parent.
323 # just copy the manifest of the parent.
290 reversed = False
324 reversed = False
291 if (not isinstance(ctx1, changectx)
325 if (not isinstance(ctx1, changectx)
292 and isinstance(ctx2, changectx)):
326 and isinstance(ctx2, changectx)):
293 reversed = True
327 reversed = True
294 ctx1, ctx2 = ctx2, ctx1
328 ctx1, ctx2 = ctx2, ctx1
295
329
296 match = ctx2._matchstatus(ctx1, match)
330 match = ctx2._matchstatus(ctx1, match)
297 r = scmutil.status([], [], [], [], [], [], [])
331 r = scmutil.status([], [], [], [], [], [], [])
298 r = ctx2._buildstatus(ctx1, r, match, listignored, listclean,
332 r = ctx2._buildstatus(ctx1, r, match, listignored, listclean,
299 listunknown)
333 listunknown)
300
334
301 if reversed:
335 if reversed:
302 # Reverse added and removed. Clear deleted, unknown and ignored as
336 # Reverse added and removed. Clear deleted, unknown and ignored as
303 # these make no sense to reverse.
337 # these make no sense to reverse.
304 r = scmutil.status(r.modified, r.removed, r.added, [], [], [],
338 r = scmutil.status(r.modified, r.removed, r.added, [], [], [],
305 r.clean)
339 r.clean)
306
340
307 if listsubrepos:
341 if listsubrepos:
308 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
342 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
309 rev2 = ctx2.subrev(subpath)
343 rev2 = ctx2.subrev(subpath)
310 try:
344 try:
311 submatch = matchmod.narrowmatcher(subpath, match)
345 submatch = matchmod.narrowmatcher(subpath, match)
312 s = sub.status(rev2, match=submatch, ignored=listignored,
346 s = sub.status(rev2, match=submatch, ignored=listignored,
313 clean=listclean, unknown=listunknown,
347 clean=listclean, unknown=listunknown,
314 listsubrepos=True)
348 listsubrepos=True)
315 for rfiles, sfiles in zip(r, s):
349 for rfiles, sfiles in zip(r, s):
316 rfiles.extend("%s/%s" % (subpath, f) for f in sfiles)
350 rfiles.extend("%s/%s" % (subpath, f) for f in sfiles)
317 except error.LookupError:
351 except error.LookupError:
318 self._repo.ui.status(_("skipping missing "
352 self._repo.ui.status(_("skipping missing "
319 "subrepository: %s\n") % subpath)
353 "subrepository: %s\n") % subpath)
320
354
321 for l in r:
355 for l in r:
322 l.sort()
356 l.sort()
323
357
324 return r
358 return r
325
359
326
360
327 def makememctx(repo, parents, text, user, date, branch, files, store,
361 def makememctx(repo, parents, text, user, date, branch, files, store,
328 editor=None):
362 editor=None):
329 def getfilectx(repo, memctx, path):
363 def getfilectx(repo, memctx, path):
330 data, mode, copied = store.getfile(path)
364 data, mode, copied = store.getfile(path)
331 if data is None:
365 if data is None:
332 return None
366 return None
333 islink, isexec = mode
367 islink, isexec = mode
334 return memfilectx(repo, path, data, islink=islink, isexec=isexec,
368 return memfilectx(repo, path, data, islink=islink, isexec=isexec,
335 copied=copied, memctx=memctx)
369 copied=copied, memctx=memctx)
336 extra = {}
370 extra = {}
337 if branch:
371 if branch:
338 extra['branch'] = encoding.fromlocal(branch)
372 extra['branch'] = encoding.fromlocal(branch)
339 ctx = memctx(repo, parents, text, files, getfilectx, user,
373 ctx = memctx(repo, parents, text, files, getfilectx, user,
340 date, extra, editor)
374 date, extra, editor)
341 return ctx
375 return ctx
342
376
343 class changectx(basectx):
377 class changectx(basectx):
344 """A changecontext object makes access to data related to a particular
378 """A changecontext object makes access to data related to a particular
345 changeset convenient. It represents a read-only context already present in
379 changeset convenient. It represents a read-only context already present in
346 the repo."""
380 the repo."""
347 def __init__(self, repo, changeid=''):
381 def __init__(self, repo, changeid=''):
348 """changeid is a revision number, node, or tag"""
382 """changeid is a revision number, node, or tag"""
349
383
350 # since basectx.__new__ already took care of copying the object, we
384 # since basectx.__new__ already took care of copying the object, we
351 # don't need to do anything in __init__, so we just exit here
385 # don't need to do anything in __init__, so we just exit here
352 if isinstance(changeid, basectx):
386 if isinstance(changeid, basectx):
353 return
387 return
354
388
355 if changeid == '':
389 if changeid == '':
356 changeid = '.'
390 changeid = '.'
357 self._repo = repo
391 self._repo = repo
358
392
359 try:
393 try:
360 if isinstance(changeid, int):
394 if isinstance(changeid, int):
361 self._node = repo.changelog.node(changeid)
395 self._node = repo.changelog.node(changeid)
362 self._rev = changeid
396 self._rev = changeid
363 return
397 return
364 if isinstance(changeid, long):
398 if isinstance(changeid, long):
365 changeid = str(changeid)
399 changeid = str(changeid)
366 if changeid == '.':
400 if changeid == '.':
367 self._node = repo.dirstate.p1()
401 self._node = repo.dirstate.p1()
368 self._rev = repo.changelog.rev(self._node)
402 self._rev = repo.changelog.rev(self._node)
369 return
403 return
370 if changeid == 'null':
404 if changeid == 'null':
371 self._node = nullid
405 self._node = nullid
372 self._rev = nullrev
406 self._rev = nullrev
373 return
407 return
374 if changeid == 'tip':
408 if changeid == 'tip':
375 self._node = repo.changelog.tip()
409 self._node = repo.changelog.tip()
376 self._rev = repo.changelog.rev(self._node)
410 self._rev = repo.changelog.rev(self._node)
377 return
411 return
378 if len(changeid) == 20:
412 if len(changeid) == 20:
379 try:
413 try:
380 self._node = changeid
414 self._node = changeid
381 self._rev = repo.changelog.rev(changeid)
415 self._rev = repo.changelog.rev(changeid)
382 return
416 return
383 except error.FilteredRepoLookupError:
417 except error.FilteredRepoLookupError:
384 raise
418 raise
385 except LookupError:
419 except LookupError:
386 pass
420 pass
387
421
388 try:
422 try:
389 r = int(changeid)
423 r = int(changeid)
390 if str(r) != changeid:
424 if str(r) != changeid:
391 raise ValueError
425 raise ValueError
392 l = len(repo.changelog)
426 l = len(repo.changelog)
393 if r < 0:
427 if r < 0:
394 r += l
428 r += l
395 if r < 0 or r >= l:
429 if r < 0 or r >= l:
396 raise ValueError
430 raise ValueError
397 self._rev = r
431 self._rev = r
398 self._node = repo.changelog.node(r)
432 self._node = repo.changelog.node(r)
399 return
433 return
400 except error.FilteredIndexError:
434 except error.FilteredIndexError:
401 raise
435 raise
402 except (ValueError, OverflowError, IndexError):
436 except (ValueError, OverflowError, IndexError):
403 pass
437 pass
404
438
405 if len(changeid) == 40:
439 if len(changeid) == 40:
406 try:
440 try:
407 self._node = bin(changeid)
441 self._node = bin(changeid)
408 self._rev = repo.changelog.rev(self._node)
442 self._rev = repo.changelog.rev(self._node)
409 return
443 return
410 except error.FilteredLookupError:
444 except error.FilteredLookupError:
411 raise
445 raise
412 except (TypeError, LookupError):
446 except (TypeError, LookupError):
413 pass
447 pass
414
448
415 # lookup bookmarks through the name interface
449 # lookup bookmarks through the name interface
416 try:
450 try:
417 self._node = repo.names.singlenode(repo, changeid)
451 self._node = repo.names.singlenode(repo, changeid)
418 self._rev = repo.changelog.rev(self._node)
452 self._rev = repo.changelog.rev(self._node)
419 return
453 return
420 except KeyError:
454 except KeyError:
421 pass
455 pass
422 except error.FilteredRepoLookupError:
456 except error.FilteredRepoLookupError:
423 raise
457 raise
424 except error.RepoLookupError:
458 except error.RepoLookupError:
425 pass
459 pass
426
460
427 self._node = repo.unfiltered().changelog._partialmatch(changeid)
461 self._node = repo.unfiltered().changelog._partialmatch(changeid)
428 if self._node is not None:
462 if self._node is not None:
429 self._rev = repo.changelog.rev(self._node)
463 self._rev = repo.changelog.rev(self._node)
430 return
464 return
431
465
432 # lookup failed
466 # lookup failed
433 # check if it might have come from damaged dirstate
467 # check if it might have come from damaged dirstate
434 #
468 #
435 # XXX we could avoid the unfiltered if we had a recognizable
469 # XXX we could avoid the unfiltered if we had a recognizable
436 # exception for filtered changeset access
470 # exception for filtered changeset access
437 if changeid in repo.unfiltered().dirstate.parents():
471 if changeid in repo.unfiltered().dirstate.parents():
438 msg = _("working directory has unknown parent '%s'!")
472 msg = _("working directory has unknown parent '%s'!")
439 raise error.Abort(msg % short(changeid))
473 raise error.Abort(msg % short(changeid))
440 try:
474 try:
441 if len(changeid) == 20:
475 if len(changeid) == 20:
442 changeid = hex(changeid)
476 changeid = hex(changeid)
443 except TypeError:
477 except TypeError:
444 pass
478 pass
445 except (error.FilteredIndexError, error.FilteredLookupError,
479 except (error.FilteredIndexError, error.FilteredLookupError,
446 error.FilteredRepoLookupError):
480 error.FilteredRepoLookupError):
447 if repo.filtername == 'visible':
481 if repo.filtername == 'visible':
448 msg = _("hidden revision '%s'") % changeid
482 msg = _("hidden revision '%s'") % changeid
449 hint = _('use --hidden to access hidden revisions')
483 hint = _('use --hidden to access hidden revisions')
450 raise error.FilteredRepoLookupError(msg, hint=hint)
484 raise error.FilteredRepoLookupError(msg, hint=hint)
451 msg = _("filtered revision '%s' (not in '%s' subset)")
485 msg = _("filtered revision '%s' (not in '%s' subset)")
452 msg %= (changeid, repo.filtername)
486 msg %= (changeid, repo.filtername)
453 raise error.FilteredRepoLookupError(msg)
487 raise error.FilteredRepoLookupError(msg)
454 except IndexError:
488 except IndexError:
455 pass
489 pass
456 raise error.RepoLookupError(
490 raise error.RepoLookupError(
457 _("unknown revision '%s'") % changeid)
491 _("unknown revision '%s'") % changeid)
458
492
459 def __hash__(self):
493 def __hash__(self):
460 try:
494 try:
461 return hash(self._rev)
495 return hash(self._rev)
462 except AttributeError:
496 except AttributeError:
463 return id(self)
497 return id(self)
464
498
465 def __nonzero__(self):
499 def __nonzero__(self):
466 return self._rev != nullrev
500 return self._rev != nullrev
467
501
468 @propertycache
502 @propertycache
469 def _changeset(self):
503 def _changeset(self):
470 return self._repo.changelog.read(self.rev())
504 return self._repo.changelog.read(self.rev())
471
505
472 @propertycache
506 @propertycache
473 def _manifest(self):
507 def _manifest(self):
474 return self._repo.manifest.read(self._changeset[0])
508 return self._repo.manifest.read(self._changeset[0])
475
509
476 @propertycache
510 @propertycache
477 def _manifestdelta(self):
511 def _manifestdelta(self):
478 return self._repo.manifest.readdelta(self._changeset[0])
512 return self._repo.manifest.readdelta(self._changeset[0])
479
513
480 @propertycache
514 @propertycache
481 def _parents(self):
515 def _parents(self):
482 p = self._repo.changelog.parentrevs(self._rev)
516 p = self._repo.changelog.parentrevs(self._rev)
483 if p[1] == nullrev:
517 if p[1] == nullrev:
484 p = p[:-1]
518 p = p[:-1]
485 return [changectx(self._repo, x) for x in p]
519 return [changectx(self._repo, x) for x in p]
486
520
487 def changeset(self):
521 def changeset(self):
488 return self._changeset
522 return self._changeset
489 def manifestnode(self):
523 def manifestnode(self):
490 return self._changeset[0]
524 return self._changeset[0]
491
525
492 def user(self):
526 def user(self):
493 return self._changeset[1]
527 return self._changeset[1]
494 def date(self):
528 def date(self):
495 return self._changeset[2]
529 return self._changeset[2]
496 def files(self):
530 def files(self):
497 return self._changeset[3]
531 return self._changeset[3]
498 def description(self):
532 def description(self):
499 return self._changeset[4]
533 return self._changeset[4]
500 def branch(self):
534 def branch(self):
501 return encoding.tolocal(self._changeset[5].get("branch"))
535 return encoding.tolocal(self._changeset[5].get("branch"))
502 def closesbranch(self):
536 def closesbranch(self):
503 return 'close' in self._changeset[5]
537 return 'close' in self._changeset[5]
504 def extra(self):
538 def extra(self):
505 return self._changeset[5]
539 return self._changeset[5]
506 def tags(self):
540 def tags(self):
507 return self._repo.nodetags(self._node)
541 return self._repo.nodetags(self._node)
508 def bookmarks(self):
542 def bookmarks(self):
509 return self._repo.nodebookmarks(self._node)
543 return self._repo.nodebookmarks(self._node)
510 def phase(self):
544 def phase(self):
511 return self._repo._phasecache.phase(self._repo, self._rev)
545 return self._repo._phasecache.phase(self._repo, self._rev)
512 def hidden(self):
546 def hidden(self):
513 return self._rev in repoview.filterrevs(self._repo, 'visible')
547 return self._rev in repoview.filterrevs(self._repo, 'visible')
514
548
515 def children(self):
549 def children(self):
516 """return contexts for each child changeset"""
550 """return contexts for each child changeset"""
517 c = self._repo.changelog.children(self._node)
551 c = self._repo.changelog.children(self._node)
518 return [changectx(self._repo, x) for x in c]
552 return [changectx(self._repo, x) for x in c]
519
553
520 def ancestors(self):
554 def ancestors(self):
521 for a in self._repo.changelog.ancestors([self._rev]):
555 for a in self._repo.changelog.ancestors([self._rev]):
522 yield changectx(self._repo, a)
556 yield changectx(self._repo, a)
523
557
524 def descendants(self):
558 def descendants(self):
525 for d in self._repo.changelog.descendants([self._rev]):
559 for d in self._repo.changelog.descendants([self._rev]):
526 yield changectx(self._repo, d)
560 yield changectx(self._repo, d)
527
561
528 def filectx(self, path, fileid=None, filelog=None):
562 def filectx(self, path, fileid=None, filelog=None):
529 """get a file context from this changeset"""
563 """get a file context from this changeset"""
530 if fileid is None:
564 if fileid is None:
531 fileid = self.filenode(path)
565 fileid = self.filenode(path)
532 return filectx(self._repo, path, fileid=fileid,
566 return filectx(self._repo, path, fileid=fileid,
533 changectx=self, filelog=filelog)
567 changectx=self, filelog=filelog)
534
568
535 def ancestor(self, c2, warn=False):
569 def ancestor(self, c2, warn=False):
536 """return the "best" ancestor context of self and c2
570 """return the "best" ancestor context of self and c2
537
571
538 If there are multiple candidates, it will show a message and check
572 If there are multiple candidates, it will show a message and check
539 merge.preferancestor configuration before falling back to the
573 merge.preferancestor configuration before falling back to the
540 revlog ancestor."""
574 revlog ancestor."""
541 # deal with workingctxs
575 # deal with workingctxs
542 n2 = c2._node
576 n2 = c2._node
543 if n2 is None:
577 if n2 is None:
544 n2 = c2._parents[0]._node
578 n2 = c2._parents[0]._node
545 cahs = self._repo.changelog.commonancestorsheads(self._node, n2)
579 cahs = self._repo.changelog.commonancestorsheads(self._node, n2)
546 if not cahs:
580 if not cahs:
547 anc = nullid
581 anc = nullid
548 elif len(cahs) == 1:
582 elif len(cahs) == 1:
549 anc = cahs[0]
583 anc = cahs[0]
550 else:
584 else:
551 for r in self._repo.ui.configlist('merge', 'preferancestor'):
585 for r in self._repo.ui.configlist('merge', 'preferancestor'):
552 try:
586 try:
553 ctx = changectx(self._repo, r)
587 ctx = changectx(self._repo, r)
554 except error.RepoLookupError:
588 except error.RepoLookupError:
555 continue
589 continue
556 anc = ctx.node()
590 anc = ctx.node()
557 if anc in cahs:
591 if anc in cahs:
558 break
592 break
559 else:
593 else:
560 anc = self._repo.changelog.ancestor(self._node, n2)
594 anc = self._repo.changelog.ancestor(self._node, n2)
561 if warn:
595 if warn:
562 self._repo.ui.status(
596 self._repo.ui.status(
563 (_("note: using %s as ancestor of %s and %s\n") %
597 (_("note: using %s as ancestor of %s and %s\n") %
564 (short(anc), short(self._node), short(n2))) +
598 (short(anc), short(self._node), short(n2))) +
565 ''.join(_(" alternatively, use --config "
599 ''.join(_(" alternatively, use --config "
566 "merge.preferancestor=%s\n") %
600 "merge.preferancestor=%s\n") %
567 short(n) for n in sorted(cahs) if n != anc))
601 short(n) for n in sorted(cahs) if n != anc))
568 return changectx(self._repo, anc)
602 return changectx(self._repo, anc)
569
603
570 def descendant(self, other):
604 def descendant(self, other):
571 """True if other is descendant of this changeset"""
605 """True if other is descendant of this changeset"""
572 return self._repo.changelog.descendant(self._rev, other._rev)
606 return self._repo.changelog.descendant(self._rev, other._rev)
573
607
574 def walk(self, match):
608 def walk(self, match):
575 fset = set(match.files())
609 fset = set(match.files())
576 # for dirstate.walk, files=['.'] means "walk the whole tree".
610 # for dirstate.walk, files=['.'] means "walk the whole tree".
577 # follow that here, too
611 # follow that here, too
578 fset.discard('.')
612 fset.discard('.')
579
613
580 # avoid the entire walk if we're only looking for specific files
614 # avoid the entire walk if we're only looking for specific files
581 if fset and not match.anypats():
615 if fset and not match.anypats():
582 if util.all([fn in self for fn in fset]):
616 if util.all([fn in self for fn in fset]):
583 for fn in sorted(fset):
617 for fn in sorted(fset):
584 if match(fn):
618 if match(fn):
585 yield fn
619 yield fn
586 raise StopIteration
620 raise StopIteration
587
621
588 for fn in self:
622 for fn in self:
589 if fn in fset:
623 if fn in fset:
590 # specified pattern is the exact name
624 # specified pattern is the exact name
591 fset.remove(fn)
625 fset.remove(fn)
592 if match(fn):
626 if match(fn):
593 yield fn
627 yield fn
594 for fn in sorted(fset):
628 for fn in sorted(fset):
595 if fn in self._dirs:
629 if fn in self._dirs:
596 # specified pattern is a directory
630 # specified pattern is a directory
597 continue
631 continue
598 match.bad(fn, _('no such file in rev %s') % self)
632 match.bad(fn, _('no such file in rev %s') % self)
599
633
600 def matches(self, match):
634 def matches(self, match):
601 return self.walk(match)
635 return self.walk(match)
602
636
603 class basefilectx(object):
637 class basefilectx(object):
604 """A filecontext object represents the common logic for its children:
638 """A filecontext object represents the common logic for its children:
605 filectx: read-only access to a filerevision that is already present
639 filectx: read-only access to a filerevision that is already present
606 in the repo,
640 in the repo,
607 workingfilectx: a filecontext that represents files from the working
641 workingfilectx: a filecontext that represents files from the working
608 directory,
642 directory,
609 memfilectx: a filecontext that represents files in-memory."""
643 memfilectx: a filecontext that represents files in-memory."""
610 def __new__(cls, repo, path, *args, **kwargs):
644 def __new__(cls, repo, path, *args, **kwargs):
611 return super(basefilectx, cls).__new__(cls)
645 return super(basefilectx, cls).__new__(cls)
612
646
613 @propertycache
647 @propertycache
614 def _filelog(self):
648 def _filelog(self):
615 return self._repo.file(self._path)
649 return self._repo.file(self._path)
616
650
617 @propertycache
651 @propertycache
618 def _changeid(self):
652 def _changeid(self):
619 if '_changeid' in self.__dict__:
653 if '_changeid' in self.__dict__:
620 return self._changeid
654 return self._changeid
621 elif '_changectx' in self.__dict__:
655 elif '_changectx' in self.__dict__:
622 return self._changectx.rev()
656 return self._changectx.rev()
623 else:
657 else:
624 return self._filelog.linkrev(self._filerev)
658 return self._filelog.linkrev(self._filerev)
625
659
626 @propertycache
660 @propertycache
627 def _filenode(self):
661 def _filenode(self):
628 if '_fileid' in self.__dict__:
662 if '_fileid' in self.__dict__:
629 return self._filelog.lookup(self._fileid)
663 return self._filelog.lookup(self._fileid)
630 else:
664 else:
631 return self._changectx.filenode(self._path)
665 return self._changectx.filenode(self._path)
632
666
633 @propertycache
667 @propertycache
634 def _filerev(self):
668 def _filerev(self):
635 return self._filelog.rev(self._filenode)
669 return self._filelog.rev(self._filenode)
636
670
637 @propertycache
671 @propertycache
638 def _repopath(self):
672 def _repopath(self):
639 return self._path
673 return self._path
640
674
641 def __nonzero__(self):
675 def __nonzero__(self):
642 try:
676 try:
643 self._filenode
677 self._filenode
644 return True
678 return True
645 except error.LookupError:
679 except error.LookupError:
646 # file is missing
680 # file is missing
647 return False
681 return False
648
682
649 def __str__(self):
683 def __str__(self):
650 return "%s@%s" % (self.path(), self._changectx)
684 return "%s@%s" % (self.path(), self._changectx)
651
685
652 def __repr__(self):
686 def __repr__(self):
653 return "<%s %s>" % (type(self).__name__, str(self))
687 return "<%s %s>" % (type(self).__name__, str(self))
654
688
655 def __hash__(self):
689 def __hash__(self):
656 try:
690 try:
657 return hash((self._path, self._filenode))
691 return hash((self._path, self._filenode))
658 except AttributeError:
692 except AttributeError:
659 return id(self)
693 return id(self)
660
694
661 def __eq__(self, other):
695 def __eq__(self, other):
662 try:
696 try:
663 return (type(self) == type(other) and self._path == other._path
697 return (type(self) == type(other) and self._path == other._path
664 and self._filenode == other._filenode)
698 and self._filenode == other._filenode)
665 except AttributeError:
699 except AttributeError:
666 return False
700 return False
667
701
668 def __ne__(self, other):
702 def __ne__(self, other):
669 return not (self == other)
703 return not (self == other)
670
704
671 def filerev(self):
705 def filerev(self):
672 return self._filerev
706 return self._filerev
673 def filenode(self):
707 def filenode(self):
674 return self._filenode
708 return self._filenode
675 def flags(self):
709 def flags(self):
676 return self._changectx.flags(self._path)
710 return self._changectx.flags(self._path)
677 def filelog(self):
711 def filelog(self):
678 return self._filelog
712 return self._filelog
679 def rev(self):
713 def rev(self):
680 return self._changeid
714 return self._changeid
681 def linkrev(self):
715 def linkrev(self):
682 return self._filelog.linkrev(self._filerev)
716 return self._filelog.linkrev(self._filerev)
683 def node(self):
717 def node(self):
684 return self._changectx.node()
718 return self._changectx.node()
685 def hex(self):
719 def hex(self):
686 return self._changectx.hex()
720 return self._changectx.hex()
687 def user(self):
721 def user(self):
688 return self._changectx.user()
722 return self._changectx.user()
689 def date(self):
723 def date(self):
690 return self._changectx.date()
724 return self._changectx.date()
691 def files(self):
725 def files(self):
692 return self._changectx.files()
726 return self._changectx.files()
693 def description(self):
727 def description(self):
694 return self._changectx.description()
728 return self._changectx.description()
695 def branch(self):
729 def branch(self):
696 return self._changectx.branch()
730 return self._changectx.branch()
697 def extra(self):
731 def extra(self):
698 return self._changectx.extra()
732 return self._changectx.extra()
699 def phase(self):
733 def phase(self):
700 return self._changectx.phase()
734 return self._changectx.phase()
701 def phasestr(self):
735 def phasestr(self):
702 return self._changectx.phasestr()
736 return self._changectx.phasestr()
703 def manifest(self):
737 def manifest(self):
704 return self._changectx.manifest()
738 return self._changectx.manifest()
705 def changectx(self):
739 def changectx(self):
706 return self._changectx
740 return self._changectx
707
741
708 def path(self):
742 def path(self):
709 return self._path
743 return self._path
710
744
711 def isbinary(self):
745 def isbinary(self):
712 try:
746 try:
713 return util.binary(self.data())
747 return util.binary(self.data())
714 except IOError:
748 except IOError:
715 return False
749 return False
716 def isexec(self):
750 def isexec(self):
717 return 'x' in self.flags()
751 return 'x' in self.flags()
718 def islink(self):
752 def islink(self):
719 return 'l' in self.flags()
753 return 'l' in self.flags()
720
754
721 def cmp(self, fctx):
755 def cmp(self, fctx):
722 """compare with other file context
756 """compare with other file context
723
757
724 returns True if different than fctx.
758 returns True if different than fctx.
725 """
759 """
726 if (fctx._filerev is None
760 if (fctx._filerev is None
727 and (self._repo._encodefilterpats
761 and (self._repo._encodefilterpats
728 # if file data starts with '\1\n', empty metadata block is
762 # if file data starts with '\1\n', empty metadata block is
729 # prepended, which adds 4 bytes to filelog.size().
763 # prepended, which adds 4 bytes to filelog.size().
730 or self.size() - 4 == fctx.size())
764 or self.size() - 4 == fctx.size())
731 or self.size() == fctx.size()):
765 or self.size() == fctx.size()):
732 return self._filelog.cmp(self._filenode, fctx.data())
766 return self._filelog.cmp(self._filenode, fctx.data())
733
767
734 return True
768 return True
735
769
736 def parents(self):
770 def parents(self):
737 _path = self._path
771 _path = self._path
738 fl = self._filelog
772 fl = self._filelog
739 parents = self._filelog.parents(self._filenode)
773 parents = self._filelog.parents(self._filenode)
740 pl = [(_path, node, fl) for node in parents if node != nullid]
774 pl = [(_path, node, fl) for node in parents if node != nullid]
741
775
742 r = self._filelog.renamed(self._filenode)
776 r = fl.renamed(self._filenode)
743 if r:
777 if r:
744 # - In the simple rename case, both parent are nullid, pl is empty.
778 # - In the simple rename case, both parent are nullid, pl is empty.
745 # - In case of merge, only one of the parent is null id and should
779 # - In case of merge, only one of the parent is null id and should
746 # be replaced with the rename information. This parent is -always-
780 # be replaced with the rename information. This parent is -always-
747 # the first one.
781 # the first one.
748 #
782 #
749 # As null id have alway been filtered out in the previous list
783 # As null id have alway been filtered out in the previous list
750 # comprehension, inserting to 0 will always result in "replacing
784 # comprehension, inserting to 0 will always result in "replacing
751 # first nullid parent with rename information.
785 # first nullid parent with rename information.
752 pl.insert(0, (r[0], r[1], self._repo.file(r[0])))
786 pl.insert(0, (r[0], r[1], self._repo.file(r[0])))
753
787
754 return [filectx(self._repo, p, fileid=n, filelog=l) for p, n, l in pl]
788 ret = []
789 for path, fnode, l in pl:
790 if '_changeid' in vars(self) or '_changectx' in vars(self):
791 # If self is associated with a changeset (probably explicitly
792 # fed), ensure the created filectx is associated with a
793 # changeset that is an ancestor of self.changectx.
794 rev = _adjustlinkrev(self._repo, path, l, fnode, self.rev())
795 fctx = filectx(self._repo, path, fileid=fnode, filelog=l,
796 changeid=rev)
797 else:
798 fctx = filectx(self._repo, path, fileid=fnode, filelog=l)
799 ret.append(fctx)
800 return ret
755
801
756 def p1(self):
802 def p1(self):
757 return self.parents()[0]
803 return self.parents()[0]
758
804
759 def p2(self):
805 def p2(self):
760 p = self.parents()
806 p = self.parents()
761 if len(p) == 2:
807 if len(p) == 2:
762 return p[1]
808 return p[1]
763 return filectx(self._repo, self._path, fileid=-1, filelog=self._filelog)
809 return filectx(self._repo, self._path, fileid=-1, filelog=self._filelog)
764
810
765 def annotate(self, follow=False, linenumber=None, diffopts=None):
811 def annotate(self, follow=False, linenumber=None, diffopts=None):
766 '''returns a list of tuples of (ctx, line) for each line
812 '''returns a list of tuples of (ctx, line) for each line
767 in the file, where ctx is the filectx of the node where
813 in the file, where ctx is the filectx of the node where
768 that line was last changed.
814 that line was last changed.
769 This returns tuples of ((ctx, linenumber), line) for each line,
815 This returns tuples of ((ctx, linenumber), line) for each line,
770 if "linenumber" parameter is NOT "None".
816 if "linenumber" parameter is NOT "None".
771 In such tuples, linenumber means one at the first appearance
817 In such tuples, linenumber means one at the first appearance
772 in the managed file.
818 in the managed file.
773 To reduce annotation cost,
819 To reduce annotation cost,
774 this returns fixed value(False is used) as linenumber,
820 this returns fixed value(False is used) as linenumber,
775 if "linenumber" parameter is "False".'''
821 if "linenumber" parameter is "False".'''
776
822
777 if linenumber is None:
823 if linenumber is None:
778 def decorate(text, rev):
824 def decorate(text, rev):
779 return ([rev] * len(text.splitlines()), text)
825 return ([rev] * len(text.splitlines()), text)
780 elif linenumber:
826 elif linenumber:
781 def decorate(text, rev):
827 def decorate(text, rev):
782 size = len(text.splitlines())
828 size = len(text.splitlines())
783 return ([(rev, i) for i in xrange(1, size + 1)], text)
829 return ([(rev, i) for i in xrange(1, size + 1)], text)
784 else:
830 else:
785 def decorate(text, rev):
831 def decorate(text, rev):
786 return ([(rev, False)] * len(text.splitlines()), text)
832 return ([(rev, False)] * len(text.splitlines()), text)
787
833
788 def pair(parent, child):
834 def pair(parent, child):
789 blocks = mdiff.allblocks(parent[1], child[1], opts=diffopts,
835 blocks = mdiff.allblocks(parent[1], child[1], opts=diffopts,
790 refine=True)
836 refine=True)
791 for (a1, a2, b1, b2), t in blocks:
837 for (a1, a2, b1, b2), t in blocks:
792 # Changed blocks ('!') or blocks made only of blank lines ('~')
838 # Changed blocks ('!') or blocks made only of blank lines ('~')
793 # belong to the child.
839 # belong to the child.
794 if t == '=':
840 if t == '=':
795 child[0][b1:b2] = parent[0][a1:a2]
841 child[0][b1:b2] = parent[0][a1:a2]
796 return child
842 return child
797
843
798 getlog = util.lrucachefunc(lambda x: self._repo.file(x))
844 getlog = util.lrucachefunc(lambda x: self._repo.file(x))
799
845
800 def parents(f):
846 def parents(f):
801 pl = f.parents()
847 pl = f.parents()
802
848
803 # Don't return renamed parents if we aren't following.
849 # Don't return renamed parents if we aren't following.
804 if not follow:
850 if not follow:
805 pl = [p for p in pl if p.path() == f.path()]
851 pl = [p for p in pl if p.path() == f.path()]
806
852
807 # renamed filectx won't have a filelog yet, so set it
853 # renamed filectx won't have a filelog yet, so set it
808 # from the cache to save time
854 # from the cache to save time
809 for p in pl:
855 for p in pl:
810 if not '_filelog' in p.__dict__:
856 if not '_filelog' in p.__dict__:
811 p._filelog = getlog(p.path())
857 p._filelog = getlog(p.path())
812
858
813 return pl
859 return pl
814
860
815 # use linkrev to find the first changeset where self appeared
861 # use linkrev to find the first changeset where self appeared
816 if self.rev() != self.linkrev():
862 if self.rev() != self.linkrev():
817 base = self.filectx(self.filenode())
863 base = self.filectx(self.filenode())
818 else:
864 else:
819 base = self
865 base = self
820
866
821 # This algorithm would prefer to be recursive, but Python is a
867 # This algorithm would prefer to be recursive, but Python is a
822 # bit recursion-hostile. Instead we do an iterative
868 # bit recursion-hostile. Instead we do an iterative
823 # depth-first search.
869 # depth-first search.
824
870
825 visit = [base]
871 visit = [base]
826 hist = {}
872 hist = {}
827 pcache = {}
873 pcache = {}
828 needed = {base: 1}
874 needed = {base: 1}
829 while visit:
875 while visit:
830 f = visit[-1]
876 f = visit[-1]
831 pcached = f in pcache
877 pcached = f in pcache
832 if not pcached:
878 if not pcached:
833 pcache[f] = parents(f)
879 pcache[f] = parents(f)
834
880
835 ready = True
881 ready = True
836 pl = pcache[f]
882 pl = pcache[f]
837 for p in pl:
883 for p in pl:
838 if p not in hist:
884 if p not in hist:
839 ready = False
885 ready = False
840 visit.append(p)
886 visit.append(p)
841 if not pcached:
887 if not pcached:
842 needed[p] = needed.get(p, 0) + 1
888 needed[p] = needed.get(p, 0) + 1
843 if ready:
889 if ready:
844 visit.pop()
890 visit.pop()
845 reusable = f in hist
891 reusable = f in hist
846 if reusable:
892 if reusable:
847 curr = hist[f]
893 curr = hist[f]
848 else:
894 else:
849 curr = decorate(f.data(), f)
895 curr = decorate(f.data(), f)
850 for p in pl:
896 for p in pl:
851 if not reusable:
897 if not reusable:
852 curr = pair(hist[p], curr)
898 curr = pair(hist[p], curr)
853 if needed[p] == 1:
899 if needed[p] == 1:
854 del hist[p]
900 del hist[p]
855 del needed[p]
901 del needed[p]
856 else:
902 else:
857 needed[p] -= 1
903 needed[p] -= 1
858
904
859 hist[f] = curr
905 hist[f] = curr
860 pcache[f] = []
906 pcache[f] = []
861
907
862 return zip(hist[base][0], hist[base][1].splitlines(True))
908 return zip(hist[base][0], hist[base][1].splitlines(True))
863
909
864 def ancestors(self, followfirst=False):
910 def ancestors(self, followfirst=False):
865 visit = {}
911 visit = {}
866 c = self
912 c = self
867 cut = followfirst and 1 or None
913 cut = followfirst and 1 or None
868 while True:
914 while True:
869 for parent in c.parents()[:cut]:
915 for parent in c.parents()[:cut]:
870 visit[(parent.rev(), parent.node())] = parent
916 visit[(parent.rev(), parent.node())] = parent
871 if not visit:
917 if not visit:
872 break
918 break
873 c = visit.pop(max(visit))
919 c = visit.pop(max(visit))
874 yield c
920 yield c
875
921
876 class filectx(basefilectx):
922 class filectx(basefilectx):
877 """A filecontext object makes access to data related to a particular
923 """A filecontext object makes access to data related to a particular
878 filerevision convenient."""
924 filerevision convenient."""
879 def __init__(self, repo, path, changeid=None, fileid=None,
925 def __init__(self, repo, path, changeid=None, fileid=None,
880 filelog=None, changectx=None):
926 filelog=None, changectx=None):
881 """changeid can be a changeset revision, node, or tag.
927 """changeid can be a changeset revision, node, or tag.
882 fileid can be a file revision or node."""
928 fileid can be a file revision or node."""
883 self._repo = repo
929 self._repo = repo
884 self._path = path
930 self._path = path
885
931
886 assert (changeid is not None
932 assert (changeid is not None
887 or fileid is not None
933 or fileid is not None
888 or changectx is not None), \
934 or changectx is not None), \
889 ("bad args: changeid=%r, fileid=%r, changectx=%r"
935 ("bad args: changeid=%r, fileid=%r, changectx=%r"
890 % (changeid, fileid, changectx))
936 % (changeid, fileid, changectx))
891
937
892 if filelog is not None:
938 if filelog is not None:
893 self._filelog = filelog
939 self._filelog = filelog
894
940
895 if changeid is not None:
941 if changeid is not None:
896 self._changeid = changeid
942 self._changeid = changeid
897 if changectx is not None:
943 if changectx is not None:
898 self._changectx = changectx
944 self._changectx = changectx
899 if fileid is not None:
945 if fileid is not None:
900 self._fileid = fileid
946 self._fileid = fileid
901
947
902 @propertycache
948 @propertycache
903 def _changectx(self):
949 def _changectx(self):
904 try:
950 try:
905 return changectx(self._repo, self._changeid)
951 return changectx(self._repo, self._changeid)
906 except error.FilteredRepoLookupError:
952 except error.FilteredRepoLookupError:
907 # Linkrev may point to any revision in the repository. When the
953 # Linkrev may point to any revision in the repository. When the
908 # repository is filtered this may lead to `filectx` trying to build
954 # repository is filtered this may lead to `filectx` trying to build
909 # `changectx` for filtered revision. In such case we fallback to
955 # `changectx` for filtered revision. In such case we fallback to
910 # creating `changectx` on the unfiltered version of the reposition.
956 # creating `changectx` on the unfiltered version of the reposition.
911 # This fallback should not be an issue because `changectx` from
957 # This fallback should not be an issue because `changectx` from
912 # `filectx` are not used in complex operations that care about
958 # `filectx` are not used in complex operations that care about
913 # filtering.
959 # filtering.
914 #
960 #
915 # This fallback is a cheap and dirty fix that prevent several
961 # This fallback is a cheap and dirty fix that prevent several
916 # crashes. It does not ensure the behavior is correct. However the
962 # crashes. It does not ensure the behavior is correct. However the
917 # behavior was not correct before filtering either and "incorrect
963 # behavior was not correct before filtering either and "incorrect
918 # behavior" is seen as better as "crash"
964 # behavior" is seen as better as "crash"
919 #
965 #
920 # Linkrevs have several serious troubles with filtering that are
966 # Linkrevs have several serious troubles with filtering that are
921 # complicated to solve. Proper handling of the issue here should be
967 # complicated to solve. Proper handling of the issue here should be
922 # considered when solving linkrev issue are on the table.
968 # considered when solving linkrev issue are on the table.
923 return changectx(self._repo.unfiltered(), self._changeid)
969 return changectx(self._repo.unfiltered(), self._changeid)
924
970
925 def filectx(self, fileid):
971 def filectx(self, fileid):
926 '''opens an arbitrary revision of the file without
972 '''opens an arbitrary revision of the file without
927 opening a new filelog'''
973 opening a new filelog'''
928 return filectx(self._repo, self._path, fileid=fileid,
974 return filectx(self._repo, self._path, fileid=fileid,
929 filelog=self._filelog)
975 filelog=self._filelog)
930
976
931 def data(self):
977 def data(self):
932 try:
978 try:
933 return self._filelog.read(self._filenode)
979 return self._filelog.read(self._filenode)
934 except error.CensoredNodeError:
980 except error.CensoredNodeError:
935 if self._repo.ui.config("censor", "policy", "abort") == "ignore":
981 if self._repo.ui.config("censor", "policy", "abort") == "ignore":
936 return ""
982 return ""
937 raise util.Abort(_("censored node: %s") % short(self._filenode),
983 raise util.Abort(_("censored node: %s") % short(self._filenode),
938 hint=_("set censor.policy to ignore errors"))
984 hint=_("set censor.policy to ignore errors"))
939
985
940 def size(self):
986 def size(self):
941 return self._filelog.size(self._filerev)
987 return self._filelog.size(self._filerev)
942
988
943 def renamed(self):
989 def renamed(self):
944 """check if file was actually renamed in this changeset revision
990 """check if file was actually renamed in this changeset revision
945
991
946 If rename logged in file revision, we report copy for changeset only
992 If rename logged in file revision, we report copy for changeset only
947 if file revisions linkrev points back to the changeset in question
993 if file revisions linkrev points back to the changeset in question
948 or both changeset parents contain different file revisions.
994 or both changeset parents contain different file revisions.
949 """
995 """
950
996
951 renamed = self._filelog.renamed(self._filenode)
997 renamed = self._filelog.renamed(self._filenode)
952 if not renamed:
998 if not renamed:
953 return renamed
999 return renamed
954
1000
955 if self.rev() == self.linkrev():
1001 if self.rev() == self.linkrev():
956 return renamed
1002 return renamed
957
1003
958 name = self.path()
1004 name = self.path()
959 fnode = self._filenode
1005 fnode = self._filenode
960 for p in self._changectx.parents():
1006 for p in self._changectx.parents():
961 try:
1007 try:
962 if fnode == p.filenode(name):
1008 if fnode == p.filenode(name):
963 return None
1009 return None
964 except error.LookupError:
1010 except error.LookupError:
965 pass
1011 pass
966 return renamed
1012 return renamed
967
1013
968 def children(self):
1014 def children(self):
969 # hard for renames
1015 # hard for renames
970 c = self._filelog.children(self._filenode)
1016 c = self._filelog.children(self._filenode)
971 return [filectx(self._repo, self._path, fileid=x,
1017 return [filectx(self._repo, self._path, fileid=x,
972 filelog=self._filelog) for x in c]
1018 filelog=self._filelog) for x in c]
973
1019
974 class committablectx(basectx):
1020 class committablectx(basectx):
975 """A committablectx object provides common functionality for a context that
1021 """A committablectx object provides common functionality for a context that
976 wants the ability to commit, e.g. workingctx or memctx."""
1022 wants the ability to commit, e.g. workingctx or memctx."""
977 def __init__(self, repo, text="", user=None, date=None, extra=None,
1023 def __init__(self, repo, text="", user=None, date=None, extra=None,
978 changes=None):
1024 changes=None):
979 self._repo = repo
1025 self._repo = repo
980 self._rev = None
1026 self._rev = None
981 self._node = None
1027 self._node = None
982 self._text = text
1028 self._text = text
983 if date:
1029 if date:
984 self._date = util.parsedate(date)
1030 self._date = util.parsedate(date)
985 if user:
1031 if user:
986 self._user = user
1032 self._user = user
987 if changes:
1033 if changes:
988 self._status = changes
1034 self._status = changes
989
1035
990 self._extra = {}
1036 self._extra = {}
991 if extra:
1037 if extra:
992 self._extra = extra.copy()
1038 self._extra = extra.copy()
993 if 'branch' not in self._extra:
1039 if 'branch' not in self._extra:
994 try:
1040 try:
995 branch = encoding.fromlocal(self._repo.dirstate.branch())
1041 branch = encoding.fromlocal(self._repo.dirstate.branch())
996 except UnicodeDecodeError:
1042 except UnicodeDecodeError:
997 raise util.Abort(_('branch name not in UTF-8!'))
1043 raise util.Abort(_('branch name not in UTF-8!'))
998 self._extra['branch'] = branch
1044 self._extra['branch'] = branch
999 if self._extra['branch'] == '':
1045 if self._extra['branch'] == '':
1000 self._extra['branch'] = 'default'
1046 self._extra['branch'] = 'default'
1001
1047
1002 def __str__(self):
1048 def __str__(self):
1003 return str(self._parents[0]) + "+"
1049 return str(self._parents[0]) + "+"
1004
1050
1005 def __nonzero__(self):
1051 def __nonzero__(self):
1006 return True
1052 return True
1007
1053
1008 def _buildflagfunc(self):
1054 def _buildflagfunc(self):
1009 # Create a fallback function for getting file flags when the
1055 # Create a fallback function for getting file flags when the
1010 # filesystem doesn't support them
1056 # filesystem doesn't support them
1011
1057
1012 copiesget = self._repo.dirstate.copies().get
1058 copiesget = self._repo.dirstate.copies().get
1013
1059
1014 if len(self._parents) < 2:
1060 if len(self._parents) < 2:
1015 # when we have one parent, it's easy: copy from parent
1061 # when we have one parent, it's easy: copy from parent
1016 man = self._parents[0].manifest()
1062 man = self._parents[0].manifest()
1017 def func(f):
1063 def func(f):
1018 f = copiesget(f, f)
1064 f = copiesget(f, f)
1019 return man.flags(f)
1065 return man.flags(f)
1020 else:
1066 else:
1021 # merges are tricky: we try to reconstruct the unstored
1067 # merges are tricky: we try to reconstruct the unstored
1022 # result from the merge (issue1802)
1068 # result from the merge (issue1802)
1023 p1, p2 = self._parents
1069 p1, p2 = self._parents
1024 pa = p1.ancestor(p2)
1070 pa = p1.ancestor(p2)
1025 m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest()
1071 m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest()
1026
1072
1027 def func(f):
1073 def func(f):
1028 f = copiesget(f, f) # may be wrong for merges with copies
1074 f = copiesget(f, f) # may be wrong for merges with copies
1029 fl1, fl2, fla = m1.flags(f), m2.flags(f), ma.flags(f)
1075 fl1, fl2, fla = m1.flags(f), m2.flags(f), ma.flags(f)
1030 if fl1 == fl2:
1076 if fl1 == fl2:
1031 return fl1
1077 return fl1
1032 if fl1 == fla:
1078 if fl1 == fla:
1033 return fl2
1079 return fl2
1034 if fl2 == fla:
1080 if fl2 == fla:
1035 return fl1
1081 return fl1
1036 return '' # punt for conflicts
1082 return '' # punt for conflicts
1037
1083
1038 return func
1084 return func
1039
1085
1040 @propertycache
1086 @propertycache
1041 def _flagfunc(self):
1087 def _flagfunc(self):
1042 return self._repo.dirstate.flagfunc(self._buildflagfunc)
1088 return self._repo.dirstate.flagfunc(self._buildflagfunc)
1043
1089
1044 @propertycache
1090 @propertycache
1045 def _manifest(self):
1091 def _manifest(self):
1046 """generate a manifest corresponding to the values in self._status
1092 """generate a manifest corresponding to the values in self._status
1047
1093
1048 This reuse the file nodeid from parent, but we append an extra letter
1094 This reuse the file nodeid from parent, but we append an extra letter
1049 when modified. Modified files get an extra 'm' while added files get
1095 when modified. Modified files get an extra 'm' while added files get
1050 an extra 'a'. This is used by manifests merge to see that files
1096 an extra 'a'. This is used by manifests merge to see that files
1051 are different and by update logic to avoid deleting newly added files.
1097 are different and by update logic to avoid deleting newly added files.
1052 """
1098 """
1053
1099
1054 man1 = self._parents[0].manifest()
1100 man1 = self._parents[0].manifest()
1055 man = man1.copy()
1101 man = man1.copy()
1056 if len(self._parents) > 1:
1102 if len(self._parents) > 1:
1057 man2 = self.p2().manifest()
1103 man2 = self.p2().manifest()
1058 def getman(f):
1104 def getman(f):
1059 if f in man1:
1105 if f in man1:
1060 return man1
1106 return man1
1061 return man2
1107 return man2
1062 else:
1108 else:
1063 getman = lambda f: man1
1109 getman = lambda f: man1
1064
1110
1065 copied = self._repo.dirstate.copies()
1111 copied = self._repo.dirstate.copies()
1066 ff = self._flagfunc
1112 ff = self._flagfunc
1067 for i, l in (("a", self._status.added), ("m", self._status.modified)):
1113 for i, l in (("a", self._status.added), ("m", self._status.modified)):
1068 for f in l:
1114 for f in l:
1069 orig = copied.get(f, f)
1115 orig = copied.get(f, f)
1070 man[f] = getman(orig).get(orig, nullid) + i
1116 man[f] = getman(orig).get(orig, nullid) + i
1071 try:
1117 try:
1072 man.setflag(f, ff(f))
1118 man.setflag(f, ff(f))
1073 except OSError:
1119 except OSError:
1074 pass
1120 pass
1075
1121
1076 for f in self._status.deleted + self._status.removed:
1122 for f in self._status.deleted + self._status.removed:
1077 if f in man:
1123 if f in man:
1078 del man[f]
1124 del man[f]
1079
1125
1080 return man
1126 return man
1081
1127
1082 @propertycache
1128 @propertycache
1083 def _status(self):
1129 def _status(self):
1084 return self._repo.status()
1130 return self._repo.status()
1085
1131
1086 @propertycache
1132 @propertycache
1087 def _user(self):
1133 def _user(self):
1088 return self._repo.ui.username()
1134 return self._repo.ui.username()
1089
1135
1090 @propertycache
1136 @propertycache
1091 def _date(self):
1137 def _date(self):
1092 return util.makedate()
1138 return util.makedate()
1093
1139
1094 def subrev(self, subpath):
1140 def subrev(self, subpath):
1095 return None
1141 return None
1096
1142
1097 def user(self):
1143 def user(self):
1098 return self._user or self._repo.ui.username()
1144 return self._user or self._repo.ui.username()
1099 def date(self):
1145 def date(self):
1100 return self._date
1146 return self._date
1101 def description(self):
1147 def description(self):
1102 return self._text
1148 return self._text
1103 def files(self):
1149 def files(self):
1104 return sorted(self._status.modified + self._status.added +
1150 return sorted(self._status.modified + self._status.added +
1105 self._status.removed)
1151 self._status.removed)
1106
1152
1107 def modified(self):
1153 def modified(self):
1108 return self._status.modified
1154 return self._status.modified
1109 def added(self):
1155 def added(self):
1110 return self._status.added
1156 return self._status.added
1111 def removed(self):
1157 def removed(self):
1112 return self._status.removed
1158 return self._status.removed
1113 def deleted(self):
1159 def deleted(self):
1114 return self._status.deleted
1160 return self._status.deleted
1115 def branch(self):
1161 def branch(self):
1116 return encoding.tolocal(self._extra['branch'])
1162 return encoding.tolocal(self._extra['branch'])
1117 def closesbranch(self):
1163 def closesbranch(self):
1118 return 'close' in self._extra
1164 return 'close' in self._extra
1119 def extra(self):
1165 def extra(self):
1120 return self._extra
1166 return self._extra
1121
1167
1122 def tags(self):
1168 def tags(self):
1123 t = []
1169 t = []
1124 for p in self.parents():
1170 for p in self.parents():
1125 t.extend(p.tags())
1171 t.extend(p.tags())
1126 return t
1172 return t
1127
1173
1128 def bookmarks(self):
1174 def bookmarks(self):
1129 b = []
1175 b = []
1130 for p in self.parents():
1176 for p in self.parents():
1131 b.extend(p.bookmarks())
1177 b.extend(p.bookmarks())
1132 return b
1178 return b
1133
1179
1134 def phase(self):
1180 def phase(self):
1135 phase = phases.draft # default phase to draft
1181 phase = phases.draft # default phase to draft
1136 for p in self.parents():
1182 for p in self.parents():
1137 phase = max(phase, p.phase())
1183 phase = max(phase, p.phase())
1138 return phase
1184 return phase
1139
1185
1140 def hidden(self):
1186 def hidden(self):
1141 return False
1187 return False
1142
1188
1143 def children(self):
1189 def children(self):
1144 return []
1190 return []
1145
1191
1146 def flags(self, path):
1192 def flags(self, path):
1147 if '_manifest' in self.__dict__:
1193 if '_manifest' in self.__dict__:
1148 try:
1194 try:
1149 return self._manifest.flags(path)
1195 return self._manifest.flags(path)
1150 except KeyError:
1196 except KeyError:
1151 return ''
1197 return ''
1152
1198
1153 try:
1199 try:
1154 return self._flagfunc(path)
1200 return self._flagfunc(path)
1155 except OSError:
1201 except OSError:
1156 return ''
1202 return ''
1157
1203
1158 def ancestor(self, c2):
1204 def ancestor(self, c2):
1159 """return the "best" ancestor context of self and c2"""
1205 """return the "best" ancestor context of self and c2"""
1160 return self._parents[0].ancestor(c2) # punt on two parents for now
1206 return self._parents[0].ancestor(c2) # punt on two parents for now
1161
1207
1162 def walk(self, match):
1208 def walk(self, match):
1163 return sorted(self._repo.dirstate.walk(match, sorted(self.substate),
1209 return sorted(self._repo.dirstate.walk(match, sorted(self.substate),
1164 True, False))
1210 True, False))
1165
1211
1166 def matches(self, match):
1212 def matches(self, match):
1167 return sorted(self._repo.dirstate.matches(match))
1213 return sorted(self._repo.dirstate.matches(match))
1168
1214
1169 def ancestors(self):
1215 def ancestors(self):
1170 for p in self._parents:
1216 for p in self._parents:
1171 yield p
1217 yield p
1172 for a in self._repo.changelog.ancestors(
1218 for a in self._repo.changelog.ancestors(
1173 [p.rev() for p in self._parents]):
1219 [p.rev() for p in self._parents]):
1174 yield changectx(self._repo, a)
1220 yield changectx(self._repo, a)
1175
1221
1176 def markcommitted(self, node):
1222 def markcommitted(self, node):
1177 """Perform post-commit cleanup necessary after committing this ctx
1223 """Perform post-commit cleanup necessary after committing this ctx
1178
1224
1179 Specifically, this updates backing stores this working context
1225 Specifically, this updates backing stores this working context
1180 wraps to reflect the fact that the changes reflected by this
1226 wraps to reflect the fact that the changes reflected by this
1181 workingctx have been committed. For example, it marks
1227 workingctx have been committed. For example, it marks
1182 modified and added files as normal in the dirstate.
1228 modified and added files as normal in the dirstate.
1183
1229
1184 """
1230 """
1185
1231
1186 self._repo.dirstate.beginparentchange()
1232 self._repo.dirstate.beginparentchange()
1187 for f in self.modified() + self.added():
1233 for f in self.modified() + self.added():
1188 self._repo.dirstate.normal(f)
1234 self._repo.dirstate.normal(f)
1189 for f in self.removed():
1235 for f in self.removed():
1190 self._repo.dirstate.drop(f)
1236 self._repo.dirstate.drop(f)
1191 self._repo.dirstate.setparents(node)
1237 self._repo.dirstate.setparents(node)
1192 self._repo.dirstate.endparentchange()
1238 self._repo.dirstate.endparentchange()
1193
1239
1194 def dirs(self):
1240 def dirs(self):
1195 return self._repo.dirstate.dirs()
1241 return self._repo.dirstate.dirs()
1196
1242
1197 class workingctx(committablectx):
1243 class workingctx(committablectx):
1198 """A workingctx object makes access to data related to
1244 """A workingctx object makes access to data related to
1199 the current working directory convenient.
1245 the current working directory convenient.
1200 date - any valid date string or (unixtime, offset), or None.
1246 date - any valid date string or (unixtime, offset), or None.
1201 user - username string, or None.
1247 user - username string, or None.
1202 extra - a dictionary of extra values, or None.
1248 extra - a dictionary of extra values, or None.
1203 changes - a list of file lists as returned by localrepo.status()
1249 changes - a list of file lists as returned by localrepo.status()
1204 or None to use the repository status.
1250 or None to use the repository status.
1205 """
1251 """
1206 def __init__(self, repo, text="", user=None, date=None, extra=None,
1252 def __init__(self, repo, text="", user=None, date=None, extra=None,
1207 changes=None):
1253 changes=None):
1208 super(workingctx, self).__init__(repo, text, user, date, extra, changes)
1254 super(workingctx, self).__init__(repo, text, user, date, extra, changes)
1209
1255
1210 def __iter__(self):
1256 def __iter__(self):
1211 d = self._repo.dirstate
1257 d = self._repo.dirstate
1212 for f in d:
1258 for f in d:
1213 if d[f] != 'r':
1259 if d[f] != 'r':
1214 yield f
1260 yield f
1215
1261
1216 def __contains__(self, key):
1262 def __contains__(self, key):
1217 return self._repo.dirstate[key] not in "?r"
1263 return self._repo.dirstate[key] not in "?r"
1218
1264
1219 @propertycache
1265 @propertycache
1220 def _parents(self):
1266 def _parents(self):
1221 p = self._repo.dirstate.parents()
1267 p = self._repo.dirstate.parents()
1222 if p[1] == nullid:
1268 if p[1] == nullid:
1223 p = p[:-1]
1269 p = p[:-1]
1224 return [changectx(self._repo, x) for x in p]
1270 return [changectx(self._repo, x) for x in p]
1225
1271
1226 def filectx(self, path, filelog=None):
1272 def filectx(self, path, filelog=None):
1227 """get a file context from the working directory"""
1273 """get a file context from the working directory"""
1228 return workingfilectx(self._repo, path, workingctx=self,
1274 return workingfilectx(self._repo, path, workingctx=self,
1229 filelog=filelog)
1275 filelog=filelog)
1230
1276
1231 def dirty(self, missing=False, merge=True, branch=True):
1277 def dirty(self, missing=False, merge=True, branch=True):
1232 "check whether a working directory is modified"
1278 "check whether a working directory is modified"
1233 # check subrepos first
1279 # check subrepos first
1234 for s in sorted(self.substate):
1280 for s in sorted(self.substate):
1235 if self.sub(s).dirty():
1281 if self.sub(s).dirty():
1236 return True
1282 return True
1237 # check current working dir
1283 # check current working dir
1238 return ((merge and self.p2()) or
1284 return ((merge and self.p2()) or
1239 (branch and self.branch() != self.p1().branch()) or
1285 (branch and self.branch() != self.p1().branch()) or
1240 self.modified() or self.added() or self.removed() or
1286 self.modified() or self.added() or self.removed() or
1241 (missing and self.deleted()))
1287 (missing and self.deleted()))
1242
1288
1243 def add(self, list, prefix=""):
1289 def add(self, list, prefix=""):
1244 join = lambda f: os.path.join(prefix, f)
1290 join = lambda f: os.path.join(prefix, f)
1245 wlock = self._repo.wlock()
1291 wlock = self._repo.wlock()
1246 ui, ds = self._repo.ui, self._repo.dirstate
1292 ui, ds = self._repo.ui, self._repo.dirstate
1247 try:
1293 try:
1248 rejected = []
1294 rejected = []
1249 lstat = self._repo.wvfs.lstat
1295 lstat = self._repo.wvfs.lstat
1250 for f in list:
1296 for f in list:
1251 scmutil.checkportable(ui, join(f))
1297 scmutil.checkportable(ui, join(f))
1252 try:
1298 try:
1253 st = lstat(f)
1299 st = lstat(f)
1254 except OSError:
1300 except OSError:
1255 ui.warn(_("%s does not exist!\n") % join(f))
1301 ui.warn(_("%s does not exist!\n") % join(f))
1256 rejected.append(f)
1302 rejected.append(f)
1257 continue
1303 continue
1258 if st.st_size > 10000000:
1304 if st.st_size > 10000000:
1259 ui.warn(_("%s: up to %d MB of RAM may be required "
1305 ui.warn(_("%s: up to %d MB of RAM may be required "
1260 "to manage this file\n"
1306 "to manage this file\n"
1261 "(use 'hg revert %s' to cancel the "
1307 "(use 'hg revert %s' to cancel the "
1262 "pending addition)\n")
1308 "pending addition)\n")
1263 % (f, 3 * st.st_size // 1000000, join(f)))
1309 % (f, 3 * st.st_size // 1000000, join(f)))
1264 if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
1310 if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
1265 ui.warn(_("%s not added: only files and symlinks "
1311 ui.warn(_("%s not added: only files and symlinks "
1266 "supported currently\n") % join(f))
1312 "supported currently\n") % join(f))
1267 rejected.append(f)
1313 rejected.append(f)
1268 elif ds[f] in 'amn':
1314 elif ds[f] in 'amn':
1269 ui.warn(_("%s already tracked!\n") % join(f))
1315 ui.warn(_("%s already tracked!\n") % join(f))
1270 elif ds[f] == 'r':
1316 elif ds[f] == 'r':
1271 ds.normallookup(f)
1317 ds.normallookup(f)
1272 else:
1318 else:
1273 ds.add(f)
1319 ds.add(f)
1274 return rejected
1320 return rejected
1275 finally:
1321 finally:
1276 wlock.release()
1322 wlock.release()
1277
1323
1278 def forget(self, files, prefix=""):
1324 def forget(self, files, prefix=""):
1279 join = lambda f: os.path.join(prefix, f)
1325 join = lambda f: os.path.join(prefix, f)
1280 wlock = self._repo.wlock()
1326 wlock = self._repo.wlock()
1281 try:
1327 try:
1282 rejected = []
1328 rejected = []
1283 for f in files:
1329 for f in files:
1284 if f not in self._repo.dirstate:
1330 if f not in self._repo.dirstate:
1285 self._repo.ui.warn(_("%s not tracked!\n") % join(f))
1331 self._repo.ui.warn(_("%s not tracked!\n") % join(f))
1286 rejected.append(f)
1332 rejected.append(f)
1287 elif self._repo.dirstate[f] != 'a':
1333 elif self._repo.dirstate[f] != 'a':
1288 self._repo.dirstate.remove(f)
1334 self._repo.dirstate.remove(f)
1289 else:
1335 else:
1290 self._repo.dirstate.drop(f)
1336 self._repo.dirstate.drop(f)
1291 return rejected
1337 return rejected
1292 finally:
1338 finally:
1293 wlock.release()
1339 wlock.release()
1294
1340
1295 def undelete(self, list):
1341 def undelete(self, list):
1296 pctxs = self.parents()
1342 pctxs = self.parents()
1297 wlock = self._repo.wlock()
1343 wlock = self._repo.wlock()
1298 try:
1344 try:
1299 for f in list:
1345 for f in list:
1300 if self._repo.dirstate[f] != 'r':
1346 if self._repo.dirstate[f] != 'r':
1301 self._repo.ui.warn(_("%s not removed!\n") % f)
1347 self._repo.ui.warn(_("%s not removed!\n") % f)
1302 else:
1348 else:
1303 fctx = f in pctxs[0] and pctxs[0][f] or pctxs[1][f]
1349 fctx = f in pctxs[0] and pctxs[0][f] or pctxs[1][f]
1304 t = fctx.data()
1350 t = fctx.data()
1305 self._repo.wwrite(f, t, fctx.flags())
1351 self._repo.wwrite(f, t, fctx.flags())
1306 self._repo.dirstate.normal(f)
1352 self._repo.dirstate.normal(f)
1307 finally:
1353 finally:
1308 wlock.release()
1354 wlock.release()
1309
1355
1310 def copy(self, source, dest):
1356 def copy(self, source, dest):
1311 try:
1357 try:
1312 st = self._repo.wvfs.lstat(dest)
1358 st = self._repo.wvfs.lstat(dest)
1313 except OSError, err:
1359 except OSError, err:
1314 if err.errno != errno.ENOENT:
1360 if err.errno != errno.ENOENT:
1315 raise
1361 raise
1316 self._repo.ui.warn(_("%s does not exist!\n") % dest)
1362 self._repo.ui.warn(_("%s does not exist!\n") % dest)
1317 return
1363 return
1318 if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
1364 if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
1319 self._repo.ui.warn(_("copy failed: %s is not a file or a "
1365 self._repo.ui.warn(_("copy failed: %s is not a file or a "
1320 "symbolic link\n") % dest)
1366 "symbolic link\n") % dest)
1321 else:
1367 else:
1322 wlock = self._repo.wlock()
1368 wlock = self._repo.wlock()
1323 try:
1369 try:
1324 if self._repo.dirstate[dest] in '?':
1370 if self._repo.dirstate[dest] in '?':
1325 self._repo.dirstate.add(dest)
1371 self._repo.dirstate.add(dest)
1326 elif self._repo.dirstate[dest] in 'r':
1372 elif self._repo.dirstate[dest] in 'r':
1327 self._repo.dirstate.normallookup(dest)
1373 self._repo.dirstate.normallookup(dest)
1328 self._repo.dirstate.copy(source, dest)
1374 self._repo.dirstate.copy(source, dest)
1329 finally:
1375 finally:
1330 wlock.release()
1376 wlock.release()
1331
1377
1332 def _filtersuspectsymlink(self, files):
1378 def _filtersuspectsymlink(self, files):
1333 if not files or self._repo.dirstate._checklink:
1379 if not files or self._repo.dirstate._checklink:
1334 return files
1380 return files
1335
1381
1336 # Symlink placeholders may get non-symlink-like contents
1382 # Symlink placeholders may get non-symlink-like contents
1337 # via user error or dereferencing by NFS or Samba servers,
1383 # via user error or dereferencing by NFS or Samba servers,
1338 # so we filter out any placeholders that don't look like a
1384 # so we filter out any placeholders that don't look like a
1339 # symlink
1385 # symlink
1340 sane = []
1386 sane = []
1341 for f in files:
1387 for f in files:
1342 if self.flags(f) == 'l':
1388 if self.flags(f) == 'l':
1343 d = self[f].data()
1389 d = self[f].data()
1344 if d == '' or len(d) >= 1024 or '\n' in d or util.binary(d):
1390 if d == '' or len(d) >= 1024 or '\n' in d or util.binary(d):
1345 self._repo.ui.debug('ignoring suspect symlink placeholder'
1391 self._repo.ui.debug('ignoring suspect symlink placeholder'
1346 ' "%s"\n' % f)
1392 ' "%s"\n' % f)
1347 continue
1393 continue
1348 sane.append(f)
1394 sane.append(f)
1349 return sane
1395 return sane
1350
1396
1351 def _checklookup(self, files):
1397 def _checklookup(self, files):
1352 # check for any possibly clean files
1398 # check for any possibly clean files
1353 if not files:
1399 if not files:
1354 return [], []
1400 return [], []
1355
1401
1356 modified = []
1402 modified = []
1357 fixup = []
1403 fixup = []
1358 pctx = self._parents[0]
1404 pctx = self._parents[0]
1359 # do a full compare of any files that might have changed
1405 # do a full compare of any files that might have changed
1360 for f in sorted(files):
1406 for f in sorted(files):
1361 if (f not in pctx or self.flags(f) != pctx.flags(f)
1407 if (f not in pctx or self.flags(f) != pctx.flags(f)
1362 or pctx[f].cmp(self[f])):
1408 or pctx[f].cmp(self[f])):
1363 modified.append(f)
1409 modified.append(f)
1364 else:
1410 else:
1365 fixup.append(f)
1411 fixup.append(f)
1366
1412
1367 # update dirstate for files that are actually clean
1413 # update dirstate for files that are actually clean
1368 if fixup:
1414 if fixup:
1369 try:
1415 try:
1370 # updating the dirstate is optional
1416 # updating the dirstate is optional
1371 # so we don't wait on the lock
1417 # so we don't wait on the lock
1372 # wlock can invalidate the dirstate, so cache normal _after_
1418 # wlock can invalidate the dirstate, so cache normal _after_
1373 # taking the lock
1419 # taking the lock
1374 wlock = self._repo.wlock(False)
1420 wlock = self._repo.wlock(False)
1375 normal = self._repo.dirstate.normal
1421 normal = self._repo.dirstate.normal
1376 try:
1422 try:
1377 for f in fixup:
1423 for f in fixup:
1378 normal(f)
1424 normal(f)
1379 finally:
1425 finally:
1380 wlock.release()
1426 wlock.release()
1381 except error.LockError:
1427 except error.LockError:
1382 pass
1428 pass
1383 return modified, fixup
1429 return modified, fixup
1384
1430
1385 def _manifestmatches(self, match, s):
1431 def _manifestmatches(self, match, s):
1386 """Slow path for workingctx
1432 """Slow path for workingctx
1387
1433
1388 The fast path is when we compare the working directory to its parent
1434 The fast path is when we compare the working directory to its parent
1389 which means this function is comparing with a non-parent; therefore we
1435 which means this function is comparing with a non-parent; therefore we
1390 need to build a manifest and return what matches.
1436 need to build a manifest and return what matches.
1391 """
1437 """
1392 mf = self._repo['.']._manifestmatches(match, s)
1438 mf = self._repo['.']._manifestmatches(match, s)
1393 for f in s.modified + s.added:
1439 for f in s.modified + s.added:
1394 mf[f] = _newnode
1440 mf[f] = _newnode
1395 mf.setflag(f, self.flags(f))
1441 mf.setflag(f, self.flags(f))
1396 for f in s.removed:
1442 for f in s.removed:
1397 if f in mf:
1443 if f in mf:
1398 del mf[f]
1444 del mf[f]
1399 return mf
1445 return mf
1400
1446
1401 def _dirstatestatus(self, match=None, ignored=False, clean=False,
1447 def _dirstatestatus(self, match=None, ignored=False, clean=False,
1402 unknown=False):
1448 unknown=False):
1403 '''Gets the status from the dirstate -- internal use only.'''
1449 '''Gets the status from the dirstate -- internal use only.'''
1404 listignored, listclean, listunknown = ignored, clean, unknown
1450 listignored, listclean, listunknown = ignored, clean, unknown
1405 match = match or matchmod.always(self._repo.root, self._repo.getcwd())
1451 match = match or matchmod.always(self._repo.root, self._repo.getcwd())
1406 subrepos = []
1452 subrepos = []
1407 if '.hgsub' in self:
1453 if '.hgsub' in self:
1408 subrepos = sorted(self.substate)
1454 subrepos = sorted(self.substate)
1409 cmp, s = self._repo.dirstate.status(match, subrepos, listignored,
1455 cmp, s = self._repo.dirstate.status(match, subrepos, listignored,
1410 listclean, listunknown)
1456 listclean, listunknown)
1411
1457
1412 # check for any possibly clean files
1458 # check for any possibly clean files
1413 if cmp:
1459 if cmp:
1414 modified2, fixup = self._checklookup(cmp)
1460 modified2, fixup = self._checklookup(cmp)
1415 s.modified.extend(modified2)
1461 s.modified.extend(modified2)
1416
1462
1417 # update dirstate for files that are actually clean
1463 # update dirstate for files that are actually clean
1418 if fixup and listclean:
1464 if fixup and listclean:
1419 s.clean.extend(fixup)
1465 s.clean.extend(fixup)
1420
1466
1421 return s
1467 return s
1422
1468
1423 def _buildstatus(self, other, s, match, listignored, listclean,
1469 def _buildstatus(self, other, s, match, listignored, listclean,
1424 listunknown):
1470 listunknown):
1425 """build a status with respect to another context
1471 """build a status with respect to another context
1426
1472
1427 This includes logic for maintaining the fast path of status when
1473 This includes logic for maintaining the fast path of status when
1428 comparing the working directory against its parent, which is to skip
1474 comparing the working directory against its parent, which is to skip
1429 building a new manifest if self (working directory) is not comparing
1475 building a new manifest if self (working directory) is not comparing
1430 against its parent (repo['.']).
1476 against its parent (repo['.']).
1431 """
1477 """
1432 s = self._dirstatestatus(match, listignored, listclean, listunknown)
1478 s = self._dirstatestatus(match, listignored, listclean, listunknown)
1433 # Filter out symlinks that, in the case of FAT32 and NTFS filesystems,
1479 # Filter out symlinks that, in the case of FAT32 and NTFS filesystems,
1434 # might have accidentally ended up with the entire contents of the file
1480 # might have accidentally ended up with the entire contents of the file
1435 # they are supposed to be linking to.
1481 # they are supposed to be linking to.
1436 s.modified[:] = self._filtersuspectsymlink(s.modified)
1482 s.modified[:] = self._filtersuspectsymlink(s.modified)
1437 if other != self._repo['.']:
1483 if other != self._repo['.']:
1438 s = super(workingctx, self)._buildstatus(other, s, match,
1484 s = super(workingctx, self)._buildstatus(other, s, match,
1439 listignored, listclean,
1485 listignored, listclean,
1440 listunknown)
1486 listunknown)
1441 elif match.always():
1487 elif match.always():
1442 # cache for performance
1488 # cache for performance
1443 self._status = s
1489 self._status = s
1444 return s
1490 return s
1445
1491
1446 def _matchstatus(self, other, match):
1492 def _matchstatus(self, other, match):
1447 """override the match method with a filter for directory patterns
1493 """override the match method with a filter for directory patterns
1448
1494
1449 We use inheritance to customize the match.bad method only in cases of
1495 We use inheritance to customize the match.bad method only in cases of
1450 workingctx since it belongs only to the working directory when
1496 workingctx since it belongs only to the working directory when
1451 comparing against the parent changeset.
1497 comparing against the parent changeset.
1452
1498
1453 If we aren't comparing against the working directory's parent, then we
1499 If we aren't comparing against the working directory's parent, then we
1454 just use the default match object sent to us.
1500 just use the default match object sent to us.
1455 """
1501 """
1456 superself = super(workingctx, self)
1502 superself = super(workingctx, self)
1457 match = superself._matchstatus(other, match)
1503 match = superself._matchstatus(other, match)
1458 if other != self._repo['.']:
1504 if other != self._repo['.']:
1459 def bad(f, msg):
1505 def bad(f, msg):
1460 # 'f' may be a directory pattern from 'match.files()',
1506 # 'f' may be a directory pattern from 'match.files()',
1461 # so 'f not in ctx1' is not enough
1507 # so 'f not in ctx1' is not enough
1462 if f not in other and f not in other.dirs():
1508 if f not in other and f not in other.dirs():
1463 self._repo.ui.warn('%s: %s\n' %
1509 self._repo.ui.warn('%s: %s\n' %
1464 (self._repo.dirstate.pathto(f), msg))
1510 (self._repo.dirstate.pathto(f), msg))
1465 match.bad = bad
1511 match.bad = bad
1466 return match
1512 return match
1467
1513
1468 class committablefilectx(basefilectx):
1514 class committablefilectx(basefilectx):
1469 """A committablefilectx provides common functionality for a file context
1515 """A committablefilectx provides common functionality for a file context
1470 that wants the ability to commit, e.g. workingfilectx or memfilectx."""
1516 that wants the ability to commit, e.g. workingfilectx or memfilectx."""
1471 def __init__(self, repo, path, filelog=None, ctx=None):
1517 def __init__(self, repo, path, filelog=None, ctx=None):
1472 self._repo = repo
1518 self._repo = repo
1473 self._path = path
1519 self._path = path
1474 self._changeid = None
1520 self._changeid = None
1475 self._filerev = self._filenode = None
1521 self._filerev = self._filenode = None
1476
1522
1477 if filelog is not None:
1523 if filelog is not None:
1478 self._filelog = filelog
1524 self._filelog = filelog
1479 if ctx:
1525 if ctx:
1480 self._changectx = ctx
1526 self._changectx = ctx
1481
1527
1482 def __nonzero__(self):
1528 def __nonzero__(self):
1483 return True
1529 return True
1484
1530
1485 def parents(self):
1531 def parents(self):
1486 '''return parent filectxs, following copies if necessary'''
1532 '''return parent filectxs, following copies if necessary'''
1487 def filenode(ctx, path):
1533 def filenode(ctx, path):
1488 return ctx._manifest.get(path, nullid)
1534 return ctx._manifest.get(path, nullid)
1489
1535
1490 path = self._path
1536 path = self._path
1491 fl = self._filelog
1537 fl = self._filelog
1492 pcl = self._changectx._parents
1538 pcl = self._changectx._parents
1493 renamed = self.renamed()
1539 renamed = self.renamed()
1494
1540
1495 if renamed:
1541 if renamed:
1496 pl = [renamed + (None,)]
1542 pl = [renamed + (None,)]
1497 else:
1543 else:
1498 pl = [(path, filenode(pcl[0], path), fl)]
1544 pl = [(path, filenode(pcl[0], path), fl)]
1499
1545
1500 for pc in pcl[1:]:
1546 for pc in pcl[1:]:
1501 pl.append((path, filenode(pc, path), fl))
1547 pl.append((path, filenode(pc, path), fl))
1502
1548
1503 return [filectx(self._repo, p, fileid=n, filelog=l)
1549 return [filectx(self._repo, p, fileid=n, filelog=l)
1504 for p, n, l in pl if n != nullid]
1550 for p, n, l in pl if n != nullid]
1505
1551
1506 def children(self):
1552 def children(self):
1507 return []
1553 return []
1508
1554
1509 class workingfilectx(committablefilectx):
1555 class workingfilectx(committablefilectx):
1510 """A workingfilectx object makes access to data related to a particular
1556 """A workingfilectx object makes access to data related to a particular
1511 file in the working directory convenient."""
1557 file in the working directory convenient."""
1512 def __init__(self, repo, path, filelog=None, workingctx=None):
1558 def __init__(self, repo, path, filelog=None, workingctx=None):
1513 super(workingfilectx, self).__init__(repo, path, filelog, workingctx)
1559 super(workingfilectx, self).__init__(repo, path, filelog, workingctx)
1514
1560
1515 @propertycache
1561 @propertycache
1516 def _changectx(self):
1562 def _changectx(self):
1517 return workingctx(self._repo)
1563 return workingctx(self._repo)
1518
1564
1519 def data(self):
1565 def data(self):
1520 return self._repo.wread(self._path)
1566 return self._repo.wread(self._path)
1521 def renamed(self):
1567 def renamed(self):
1522 rp = self._repo.dirstate.copied(self._path)
1568 rp = self._repo.dirstate.copied(self._path)
1523 if not rp:
1569 if not rp:
1524 return None
1570 return None
1525 return rp, self._changectx._parents[0]._manifest.get(rp, nullid)
1571 return rp, self._changectx._parents[0]._manifest.get(rp, nullid)
1526
1572
1527 def size(self):
1573 def size(self):
1528 return self._repo.wvfs.lstat(self._path).st_size
1574 return self._repo.wvfs.lstat(self._path).st_size
1529 def date(self):
1575 def date(self):
1530 t, tz = self._changectx.date()
1576 t, tz = self._changectx.date()
1531 try:
1577 try:
1532 return (int(self._repo.wvfs.lstat(self._path).st_mtime), tz)
1578 return (int(self._repo.wvfs.lstat(self._path).st_mtime), tz)
1533 except OSError, err:
1579 except OSError, err:
1534 if err.errno != errno.ENOENT:
1580 if err.errno != errno.ENOENT:
1535 raise
1581 raise
1536 return (t, tz)
1582 return (t, tz)
1537
1583
1538 def cmp(self, fctx):
1584 def cmp(self, fctx):
1539 """compare with other file context
1585 """compare with other file context
1540
1586
1541 returns True if different than fctx.
1587 returns True if different than fctx.
1542 """
1588 """
1543 # fctx should be a filectx (not a workingfilectx)
1589 # fctx should be a filectx (not a workingfilectx)
1544 # invert comparison to reuse the same code path
1590 # invert comparison to reuse the same code path
1545 return fctx.cmp(self)
1591 return fctx.cmp(self)
1546
1592
1547 def remove(self, ignoremissing=False):
1593 def remove(self, ignoremissing=False):
1548 """wraps unlink for a repo's working directory"""
1594 """wraps unlink for a repo's working directory"""
1549 util.unlinkpath(self._repo.wjoin(self._path), ignoremissing)
1595 util.unlinkpath(self._repo.wjoin(self._path), ignoremissing)
1550
1596
1551 def write(self, data, flags):
1597 def write(self, data, flags):
1552 """wraps repo.wwrite"""
1598 """wraps repo.wwrite"""
1553 self._repo.wwrite(self._path, data, flags)
1599 self._repo.wwrite(self._path, data, flags)
1554
1600
1555 class memctx(committablectx):
1601 class memctx(committablectx):
1556 """Use memctx to perform in-memory commits via localrepo.commitctx().
1602 """Use memctx to perform in-memory commits via localrepo.commitctx().
1557
1603
1558 Revision information is supplied at initialization time while
1604 Revision information is supplied at initialization time while
1559 related files data and is made available through a callback
1605 related files data and is made available through a callback
1560 mechanism. 'repo' is the current localrepo, 'parents' is a
1606 mechanism. 'repo' is the current localrepo, 'parents' is a
1561 sequence of two parent revisions identifiers (pass None for every
1607 sequence of two parent revisions identifiers (pass None for every
1562 missing parent), 'text' is the commit message and 'files' lists
1608 missing parent), 'text' is the commit message and 'files' lists
1563 names of files touched by the revision (normalized and relative to
1609 names of files touched by the revision (normalized and relative to
1564 repository root).
1610 repository root).
1565
1611
1566 filectxfn(repo, memctx, path) is a callable receiving the
1612 filectxfn(repo, memctx, path) is a callable receiving the
1567 repository, the current memctx object and the normalized path of
1613 repository, the current memctx object and the normalized path of
1568 requested file, relative to repository root. It is fired by the
1614 requested file, relative to repository root. It is fired by the
1569 commit function for every file in 'files', but calls order is
1615 commit function for every file in 'files', but calls order is
1570 undefined. If the file is available in the revision being
1616 undefined. If the file is available in the revision being
1571 committed (updated or added), filectxfn returns a memfilectx
1617 committed (updated or added), filectxfn returns a memfilectx
1572 object. If the file was removed, filectxfn raises an
1618 object. If the file was removed, filectxfn raises an
1573 IOError. Moved files are represented by marking the source file
1619 IOError. Moved files are represented by marking the source file
1574 removed and the new file added with copy information (see
1620 removed and the new file added with copy information (see
1575 memfilectx).
1621 memfilectx).
1576
1622
1577 user receives the committer name and defaults to current
1623 user receives the committer name and defaults to current
1578 repository username, date is the commit date in any format
1624 repository username, date is the commit date in any format
1579 supported by util.parsedate() and defaults to current date, extra
1625 supported by util.parsedate() and defaults to current date, extra
1580 is a dictionary of metadata or is left empty.
1626 is a dictionary of metadata or is left empty.
1581 """
1627 """
1582
1628
1583 # Mercurial <= 3.1 expects the filectxfn to raise IOError for missing files.
1629 # Mercurial <= 3.1 expects the filectxfn to raise IOError for missing files.
1584 # Extensions that need to retain compatibility across Mercurial 3.1 can use
1630 # Extensions that need to retain compatibility across Mercurial 3.1 can use
1585 # this field to determine what to do in filectxfn.
1631 # this field to determine what to do in filectxfn.
1586 _returnnoneformissingfiles = True
1632 _returnnoneformissingfiles = True
1587
1633
1588 def __init__(self, repo, parents, text, files, filectxfn, user=None,
1634 def __init__(self, repo, parents, text, files, filectxfn, user=None,
1589 date=None, extra=None, editor=False):
1635 date=None, extra=None, editor=False):
1590 super(memctx, self).__init__(repo, text, user, date, extra)
1636 super(memctx, self).__init__(repo, text, user, date, extra)
1591 self._rev = None
1637 self._rev = None
1592 self._node = None
1638 self._node = None
1593 parents = [(p or nullid) for p in parents]
1639 parents = [(p or nullid) for p in parents]
1594 p1, p2 = parents
1640 p1, p2 = parents
1595 self._parents = [changectx(self._repo, p) for p in (p1, p2)]
1641 self._parents = [changectx(self._repo, p) for p in (p1, p2)]
1596 files = sorted(set(files))
1642 files = sorted(set(files))
1597 self._files = files
1643 self._files = files
1598 self.substate = {}
1644 self.substate = {}
1599
1645
1600 # if store is not callable, wrap it in a function
1646 # if store is not callable, wrap it in a function
1601 if not callable(filectxfn):
1647 if not callable(filectxfn):
1602 def getfilectx(repo, memctx, path):
1648 def getfilectx(repo, memctx, path):
1603 fctx = filectxfn[path]
1649 fctx = filectxfn[path]
1604 # this is weird but apparently we only keep track of one parent
1650 # this is weird but apparently we only keep track of one parent
1605 # (why not only store that instead of a tuple?)
1651 # (why not only store that instead of a tuple?)
1606 copied = fctx.renamed()
1652 copied = fctx.renamed()
1607 if copied:
1653 if copied:
1608 copied = copied[0]
1654 copied = copied[0]
1609 return memfilectx(repo, path, fctx.data(),
1655 return memfilectx(repo, path, fctx.data(),
1610 islink=fctx.islink(), isexec=fctx.isexec(),
1656 islink=fctx.islink(), isexec=fctx.isexec(),
1611 copied=copied, memctx=memctx)
1657 copied=copied, memctx=memctx)
1612 self._filectxfn = getfilectx
1658 self._filectxfn = getfilectx
1613 else:
1659 else:
1614 # "util.cachefunc" reduces invocation of possibly expensive
1660 # "util.cachefunc" reduces invocation of possibly expensive
1615 # "filectxfn" for performance (e.g. converting from another VCS)
1661 # "filectxfn" for performance (e.g. converting from another VCS)
1616 self._filectxfn = util.cachefunc(filectxfn)
1662 self._filectxfn = util.cachefunc(filectxfn)
1617
1663
1618 self._extra = extra and extra.copy() or {}
1664 self._extra = extra and extra.copy() or {}
1619 if self._extra.get('branch', '') == '':
1665 if self._extra.get('branch', '') == '':
1620 self._extra['branch'] = 'default'
1666 self._extra['branch'] = 'default'
1621
1667
1622 if editor:
1668 if editor:
1623 self._text = editor(self._repo, self, [])
1669 self._text = editor(self._repo, self, [])
1624 self._repo.savecommitmessage(self._text)
1670 self._repo.savecommitmessage(self._text)
1625
1671
1626 def filectx(self, path, filelog=None):
1672 def filectx(self, path, filelog=None):
1627 """get a file context from the working directory
1673 """get a file context from the working directory
1628
1674
1629 Returns None if file doesn't exist and should be removed."""
1675 Returns None if file doesn't exist and should be removed."""
1630 return self._filectxfn(self._repo, self, path)
1676 return self._filectxfn(self._repo, self, path)
1631
1677
1632 def commit(self):
1678 def commit(self):
1633 """commit context to the repo"""
1679 """commit context to the repo"""
1634 return self._repo.commitctx(self)
1680 return self._repo.commitctx(self)
1635
1681
1636 @propertycache
1682 @propertycache
1637 def _manifest(self):
1683 def _manifest(self):
1638 """generate a manifest based on the return values of filectxfn"""
1684 """generate a manifest based on the return values of filectxfn"""
1639
1685
1640 # keep this simple for now; just worry about p1
1686 # keep this simple for now; just worry about p1
1641 pctx = self._parents[0]
1687 pctx = self._parents[0]
1642 man = pctx.manifest().copy()
1688 man = pctx.manifest().copy()
1643
1689
1644 for f in self._status.modified:
1690 for f in self._status.modified:
1645 p1node = nullid
1691 p1node = nullid
1646 p2node = nullid
1692 p2node = nullid
1647 p = pctx[f].parents() # if file isn't in pctx, check p2?
1693 p = pctx[f].parents() # if file isn't in pctx, check p2?
1648 if len(p) > 0:
1694 if len(p) > 0:
1649 p1node = p[0].node()
1695 p1node = p[0].node()
1650 if len(p) > 1:
1696 if len(p) > 1:
1651 p2node = p[1].node()
1697 p2node = p[1].node()
1652 man[f] = revlog.hash(self[f].data(), p1node, p2node)
1698 man[f] = revlog.hash(self[f].data(), p1node, p2node)
1653
1699
1654 for f in self._status.added:
1700 for f in self._status.added:
1655 man[f] = revlog.hash(self[f].data(), nullid, nullid)
1701 man[f] = revlog.hash(self[f].data(), nullid, nullid)
1656
1702
1657 for f in self._status.removed:
1703 for f in self._status.removed:
1658 if f in man:
1704 if f in man:
1659 del man[f]
1705 del man[f]
1660
1706
1661 return man
1707 return man
1662
1708
1663 @propertycache
1709 @propertycache
1664 def _status(self):
1710 def _status(self):
1665 """Calculate exact status from ``files`` specified at construction
1711 """Calculate exact status from ``files`` specified at construction
1666 """
1712 """
1667 man1 = self.p1().manifest()
1713 man1 = self.p1().manifest()
1668 p2 = self._parents[1]
1714 p2 = self._parents[1]
1669 # "1 < len(self._parents)" can't be used for checking
1715 # "1 < len(self._parents)" can't be used for checking
1670 # existence of the 2nd parent, because "memctx._parents" is
1716 # existence of the 2nd parent, because "memctx._parents" is
1671 # explicitly initialized by the list, of which length is 2.
1717 # explicitly initialized by the list, of which length is 2.
1672 if p2.node() != nullid:
1718 if p2.node() != nullid:
1673 man2 = p2.manifest()
1719 man2 = p2.manifest()
1674 managing = lambda f: f in man1 or f in man2
1720 managing = lambda f: f in man1 or f in man2
1675 else:
1721 else:
1676 managing = lambda f: f in man1
1722 managing = lambda f: f in man1
1677
1723
1678 modified, added, removed = [], [], []
1724 modified, added, removed = [], [], []
1679 for f in self._files:
1725 for f in self._files:
1680 if not managing(f):
1726 if not managing(f):
1681 added.append(f)
1727 added.append(f)
1682 elif self[f]:
1728 elif self[f]:
1683 modified.append(f)
1729 modified.append(f)
1684 else:
1730 else:
1685 removed.append(f)
1731 removed.append(f)
1686
1732
1687 return scmutil.status(modified, added, removed, [], [], [], [])
1733 return scmutil.status(modified, added, removed, [], [], [], [])
1688
1734
1689 class memfilectx(committablefilectx):
1735 class memfilectx(committablefilectx):
1690 """memfilectx represents an in-memory file to commit.
1736 """memfilectx represents an in-memory file to commit.
1691
1737
1692 See memctx and committablefilectx for more details.
1738 See memctx and committablefilectx for more details.
1693 """
1739 """
1694 def __init__(self, repo, path, data, islink=False,
1740 def __init__(self, repo, path, data, islink=False,
1695 isexec=False, copied=None, memctx=None):
1741 isexec=False, copied=None, memctx=None):
1696 """
1742 """
1697 path is the normalized file path relative to repository root.
1743 path is the normalized file path relative to repository root.
1698 data is the file content as a string.
1744 data is the file content as a string.
1699 islink is True if the file is a symbolic link.
1745 islink is True if the file is a symbolic link.
1700 isexec is True if the file is executable.
1746 isexec is True if the file is executable.
1701 copied is the source file path if current file was copied in the
1747 copied is the source file path if current file was copied in the
1702 revision being committed, or None."""
1748 revision being committed, or None."""
1703 super(memfilectx, self).__init__(repo, path, None, memctx)
1749 super(memfilectx, self).__init__(repo, path, None, memctx)
1704 self._data = data
1750 self._data = data
1705 self._flags = (islink and 'l' or '') + (isexec and 'x' or '')
1751 self._flags = (islink and 'l' or '') + (isexec and 'x' or '')
1706 self._copied = None
1752 self._copied = None
1707 if copied:
1753 if copied:
1708 self._copied = (copied, nullid)
1754 self._copied = (copied, nullid)
1709
1755
1710 def data(self):
1756 def data(self):
1711 return self._data
1757 return self._data
1712 def size(self):
1758 def size(self):
1713 return len(self.data())
1759 return len(self.data())
1714 def flags(self):
1760 def flags(self):
1715 return self._flags
1761 return self._flags
1716 def renamed(self):
1762 def renamed(self):
1717 return self._copied
1763 return self._copied
1718
1764
1719 def remove(self, ignoremissing=False):
1765 def remove(self, ignoremissing=False):
1720 """wraps unlink for a repo's working directory"""
1766 """wraps unlink for a repo's working directory"""
1721 # need to figure out what to do here
1767 # need to figure out what to do here
1722 del self._changectx[self._path]
1768 del self._changectx[self._path]
1723
1769
1724 def write(self, data, flags):
1770 def write(self, data, flags):
1725 """wraps repo.wwrite"""
1771 """wraps repo.wwrite"""
1726 self._data = data
1772 self._data = data
@@ -1,453 +1,513 b''
1 $ HGMERGE=true; export HGMERGE
1 $ HGMERGE=true; export HGMERGE
2
2
3 init
3 init
4
4
5 $ hg init repo
5 $ hg init repo
6 $ cd repo
6 $ cd repo
7
7
8 commit
8 commit
9
9
10 $ echo 'a' > a
10 $ echo 'a' > a
11 $ hg ci -A -m test -u nobody -d '1 0'
11 $ hg ci -A -m test -u nobody -d '1 0'
12 adding a
12 adding a
13
13
14 annotate -c
14 annotate -c
15
15
16 $ hg annotate -c a
16 $ hg annotate -c a
17 8435f90966e4: a
17 8435f90966e4: a
18
18
19 annotate -cl
19 annotate -cl
20
20
21 $ hg annotate -cl a
21 $ hg annotate -cl a
22 8435f90966e4:1: a
22 8435f90966e4:1: a
23
23
24 annotate -d
24 annotate -d
25
25
26 $ hg annotate -d a
26 $ hg annotate -d a
27 Thu Jan 01 00:00:01 1970 +0000: a
27 Thu Jan 01 00:00:01 1970 +0000: a
28
28
29 annotate -n
29 annotate -n
30
30
31 $ hg annotate -n a
31 $ hg annotate -n a
32 0: a
32 0: a
33
33
34 annotate -nl
34 annotate -nl
35
35
36 $ hg annotate -nl a
36 $ hg annotate -nl a
37 0:1: a
37 0:1: a
38
38
39 annotate -u
39 annotate -u
40
40
41 $ hg annotate -u a
41 $ hg annotate -u a
42 nobody: a
42 nobody: a
43
43
44 annotate -cdnu
44 annotate -cdnu
45
45
46 $ hg annotate -cdnu a
46 $ hg annotate -cdnu a
47 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a
47 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a
48
48
49 annotate -cdnul
49 annotate -cdnul
50
50
51 $ hg annotate -cdnul a
51 $ hg annotate -cdnul a
52 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000:1: a
52 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000:1: a
53
53
54 annotate (JSON)
54 annotate (JSON)
55
55
56 $ hg annotate -Tjson a
56 $ hg annotate -Tjson a
57 [
57 [
58 {
58 {
59 "line": "a\n",
59 "line": "a\n",
60 "rev": 0
60 "rev": 0
61 }
61 }
62 ]
62 ]
63
63
64 $ hg annotate -Tjson -cdfnul a
64 $ hg annotate -Tjson -cdfnul a
65 [
65 [
66 {
66 {
67 "date": [1.0, 0],
67 "date": [1.0, 0],
68 "file": "a",
68 "file": "a",
69 "line": "a\n",
69 "line": "a\n",
70 "line_number": 1,
70 "line_number": 1,
71 "node": "8435f90966e442695d2ded29fdade2bac5ad8065",
71 "node": "8435f90966e442695d2ded29fdade2bac5ad8065",
72 "rev": 0,
72 "rev": 0,
73 "user": "nobody"
73 "user": "nobody"
74 }
74 }
75 ]
75 ]
76
76
77 $ cat <<EOF >>a
77 $ cat <<EOF >>a
78 > a
78 > a
79 > a
79 > a
80 > EOF
80 > EOF
81 $ hg ci -ma1 -d '1 0'
81 $ hg ci -ma1 -d '1 0'
82 $ hg cp a b
82 $ hg cp a b
83 $ hg ci -mb -d '1 0'
83 $ hg ci -mb -d '1 0'
84 $ cat <<EOF >> b
84 $ cat <<EOF >> b
85 > b4
85 > b4
86 > b5
86 > b5
87 > b6
87 > b6
88 > EOF
88 > EOF
89 $ hg ci -mb2 -d '2 0'
89 $ hg ci -mb2 -d '2 0'
90
90
91 annotate -n b
91 annotate -n b
92
92
93 $ hg annotate -n b
93 $ hg annotate -n b
94 0: a
94 0: a
95 1: a
95 1: a
96 1: a
96 1: a
97 3: b4
97 3: b4
98 3: b5
98 3: b5
99 3: b6
99 3: b6
100
100
101 annotate --no-follow b
101 annotate --no-follow b
102
102
103 $ hg annotate --no-follow b
103 $ hg annotate --no-follow b
104 2: a
104 2: a
105 2: a
105 2: a
106 2: a
106 2: a
107 3: b4
107 3: b4
108 3: b5
108 3: b5
109 3: b6
109 3: b6
110
110
111 annotate -nl b
111 annotate -nl b
112
112
113 $ hg annotate -nl b
113 $ hg annotate -nl b
114 0:1: a
114 0:1: a
115 1:2: a
115 1:2: a
116 1:3: a
116 1:3: a
117 3:4: b4
117 3:4: b4
118 3:5: b5
118 3:5: b5
119 3:6: b6
119 3:6: b6
120
120
121 annotate -nf b
121 annotate -nf b
122
122
123 $ hg annotate -nf b
123 $ hg annotate -nf b
124 0 a: a
124 0 a: a
125 1 a: a
125 1 a: a
126 1 a: a
126 1 a: a
127 3 b: b4
127 3 b: b4
128 3 b: b5
128 3 b: b5
129 3 b: b6
129 3 b: b6
130
130
131 annotate -nlf b
131 annotate -nlf b
132
132
133 $ hg annotate -nlf b
133 $ hg annotate -nlf b
134 0 a:1: a
134 0 a:1: a
135 1 a:2: a
135 1 a:2: a
136 1 a:3: a
136 1 a:3: a
137 3 b:4: b4
137 3 b:4: b4
138 3 b:5: b5
138 3 b:5: b5
139 3 b:6: b6
139 3 b:6: b6
140
140
141 $ hg up -C 2
141 $ hg up -C 2
142 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
143 $ cat <<EOF >> b
143 $ cat <<EOF >> b
144 > b4
144 > b4
145 > c
145 > c
146 > b5
146 > b5
147 > EOF
147 > EOF
148 $ hg ci -mb2.1 -d '2 0'
148 $ hg ci -mb2.1 -d '2 0'
149 created new head
149 created new head
150 $ hg merge
150 $ hg merge
151 merging b
151 merging b
152 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
152 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
153 (branch merge, don't forget to commit)
153 (branch merge, don't forget to commit)
154 $ hg ci -mmergeb -d '3 0'
154 $ hg ci -mmergeb -d '3 0'
155
155
156 annotate after merge
156 annotate after merge
157
157
158 $ hg annotate -nf b
158 $ hg annotate -nf b
159 0 a: a
159 0 a: a
160 1 a: a
160 1 a: a
161 1 a: a
161 1 a: a
162 3 b: b4
162 3 b: b4
163 4 b: c
163 4 b: c
164 3 b: b5
164 3 b: b5
165
165
166 annotate after merge with -l
166 annotate after merge with -l
167
167
168 $ hg annotate -nlf b
168 $ hg annotate -nlf b
169 0 a:1: a
169 0 a:1: a
170 1 a:2: a
170 1 a:2: a
171 1 a:3: a
171 1 a:3: a
172 3 b:4: b4
172 3 b:4: b4
173 4 b:5: c
173 4 b:5: c
174 3 b:5: b5
174 3 b:5: b5
175
175
176 $ hg up -C 1
176 $ hg up -C 1
177 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
177 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
178 $ hg cp a b
178 $ hg cp a b
179 $ cat <<EOF > b
179 $ cat <<EOF > b
180 > a
180 > a
181 > z
181 > z
182 > a
182 > a
183 > EOF
183 > EOF
184 $ hg ci -mc -d '3 0'
184 $ hg ci -mc -d '3 0'
185 created new head
185 created new head
186 $ hg merge
186 $ hg merge
187 merging b
187 merging b
188 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
188 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
189 (branch merge, don't forget to commit)
189 (branch merge, don't forget to commit)
190 $ cat <<EOF >> b
190 $ cat <<EOF >> b
191 > b4
191 > b4
192 > c
192 > c
193 > b5
193 > b5
194 > EOF
194 > EOF
195 $ echo d >> b
195 $ echo d >> b
196 $ hg ci -mmerge2 -d '4 0'
196 $ hg ci -mmerge2 -d '4 0'
197
197
198 annotate after rename merge
198 annotate after rename merge
199
199
200 $ hg annotate -nf b
200 $ hg annotate -nf b
201 0 a: a
201 0 a: a
202 6 b: z
202 6 b: z
203 1 a: a
203 1 a: a
204 3 b: b4
204 3 b: b4
205 4 b: c
205 4 b: c
206 3 b: b5
206 3 b: b5
207 7 b: d
207 7 b: d
208
208
209 annotate after rename merge with -l
209 annotate after rename merge with -l
210
210
211 $ hg annotate -nlf b
211 $ hg annotate -nlf b
212 0 a:1: a
212 0 a:1: a
213 6 b:2: z
213 6 b:2: z
214 1 a:3: a
214 1 a:3: a
215 3 b:4: b4
215 3 b:4: b4
216 4 b:5: c
216 4 b:5: c
217 3 b:5: b5
217 3 b:5: b5
218 7 b:7: d
218 7 b:7: d
219
219
220 Issue2807: alignment of line numbers with -l
220 Issue2807: alignment of line numbers with -l
221
221
222 $ echo more >> b
222 $ echo more >> b
223 $ hg ci -mmore -d '5 0'
223 $ hg ci -mmore -d '5 0'
224 $ echo more >> b
224 $ echo more >> b
225 $ hg ci -mmore -d '6 0'
225 $ hg ci -mmore -d '6 0'
226 $ echo more >> b
226 $ echo more >> b
227 $ hg ci -mmore -d '7 0'
227 $ hg ci -mmore -d '7 0'
228 $ hg annotate -nlf b
228 $ hg annotate -nlf b
229 0 a: 1: a
229 0 a: 1: a
230 6 b: 2: z
230 6 b: 2: z
231 1 a: 3: a
231 1 a: 3: a
232 3 b: 4: b4
232 3 b: 4: b4
233 4 b: 5: c
233 4 b: 5: c
234 3 b: 5: b5
234 3 b: 5: b5
235 7 b: 7: d
235 7 b: 7: d
236 8 b: 8: more
236 8 b: 8: more
237 9 b: 9: more
237 9 b: 9: more
238 10 b:10: more
238 10 b:10: more
239
239
240 linkrev vs rev
240 linkrev vs rev
241
241
242 $ hg annotate -r tip -n a
242 $ hg annotate -r tip -n a
243 0: a
243 0: a
244 1: a
244 1: a
245 1: a
245 1: a
246
246
247 linkrev vs rev with -l
247 linkrev vs rev with -l
248
248
249 $ hg annotate -r tip -nl a
249 $ hg annotate -r tip -nl a
250 0:1: a
250 0:1: a
251 1:2: a
251 1:2: a
252 1:3: a
252 1:3: a
253
253
254 Issue589: "undelete" sequence leads to crash
254 Issue589: "undelete" sequence leads to crash
255
255
256 annotate was crashing when trying to --follow something
256 annotate was crashing when trying to --follow something
257
257
258 like A -> B -> A
258 like A -> B -> A
259
259
260 generate ABA rename configuration
260 generate ABA rename configuration
261
261
262 $ echo foo > foo
262 $ echo foo > foo
263 $ hg add foo
263 $ hg add foo
264 $ hg ci -m addfoo
264 $ hg ci -m addfoo
265 $ hg rename foo bar
265 $ hg rename foo bar
266 $ hg ci -m renamefoo
266 $ hg ci -m renamefoo
267 $ hg rename bar foo
267 $ hg rename bar foo
268 $ hg ci -m renamebar
268 $ hg ci -m renamebar
269
269
270 annotate after ABA with follow
270 annotate after ABA with follow
271
271
272 $ hg annotate --follow foo
272 $ hg annotate --follow foo
273 foo: foo
273 foo: foo
274
274
275 missing file
275 missing file
276
276
277 $ hg ann nosuchfile
277 $ hg ann nosuchfile
278 abort: nosuchfile: no such file in rev e9e6b4fa872f
278 abort: nosuchfile: no such file in rev e9e6b4fa872f
279 [255]
279 [255]
280
280
281 annotate file without '\n' on last line
281 annotate file without '\n' on last line
282
282
283 $ printf "" > c
283 $ printf "" > c
284 $ hg ci -A -m test -u nobody -d '1 0'
284 $ hg ci -A -m test -u nobody -d '1 0'
285 adding c
285 adding c
286 $ hg annotate c
286 $ hg annotate c
287 $ printf "a\nb" > c
287 $ printf "a\nb" > c
288 $ hg ci -m test
288 $ hg ci -m test
289 $ hg annotate c
289 $ hg annotate c
290 [0-9]+: a (re)
290 [0-9]+: a (re)
291 [0-9]+: b (re)
291 [0-9]+: b (re)
292
292
293 Issue3841: check annotation of the file of which filelog includes
293 Issue3841: check annotation of the file of which filelog includes
294 merging between the revision and its ancestor
294 merging between the revision and its ancestor
295
295
296 to reproduce the situation with recent Mercurial, this script uses (1)
296 to reproduce the situation with recent Mercurial, this script uses (1)
297 "hg debugsetparents" to merge without ancestor check by "hg merge",
297 "hg debugsetparents" to merge without ancestor check by "hg merge",
298 and (2) the extension to allow filelog merging between the revision
298 and (2) the extension to allow filelog merging between the revision
299 and its ancestor by overriding "repo._filecommit".
299 and its ancestor by overriding "repo._filecommit".
300
300
301 $ cat > ../legacyrepo.py <<EOF
301 $ cat > ../legacyrepo.py <<EOF
302 > from mercurial import node, util
302 > from mercurial import node, util
303 > def reposetup(ui, repo):
303 > def reposetup(ui, repo):
304 > class legacyrepo(repo.__class__):
304 > class legacyrepo(repo.__class__):
305 > def _filecommit(self, fctx, manifest1, manifest2,
305 > def _filecommit(self, fctx, manifest1, manifest2,
306 > linkrev, tr, changelist):
306 > linkrev, tr, changelist):
307 > fname = fctx.path()
307 > fname = fctx.path()
308 > text = fctx.data()
308 > text = fctx.data()
309 > flog = self.file(fname)
309 > flog = self.file(fname)
310 > fparent1 = manifest1.get(fname, node.nullid)
310 > fparent1 = manifest1.get(fname, node.nullid)
311 > fparent2 = manifest2.get(fname, node.nullid)
311 > fparent2 = manifest2.get(fname, node.nullid)
312 > meta = {}
312 > meta = {}
313 > copy = fctx.renamed()
313 > copy = fctx.renamed()
314 > if copy and copy[0] != fname:
314 > if copy and copy[0] != fname:
315 > raise util.Abort('copying is not supported')
315 > raise util.Abort('copying is not supported')
316 > if fparent2 != node.nullid:
316 > if fparent2 != node.nullid:
317 > changelist.append(fname)
317 > changelist.append(fname)
318 > return flog.add(text, meta, tr, linkrev,
318 > return flog.add(text, meta, tr, linkrev,
319 > fparent1, fparent2)
319 > fparent1, fparent2)
320 > raise util.Abort('only merging is supported')
320 > raise util.Abort('only merging is supported')
321 > repo.__class__ = legacyrepo
321 > repo.__class__ = legacyrepo
322 > EOF
322 > EOF
323
323
324 $ cat > baz <<EOF
324 $ cat > baz <<EOF
325 > 1
325 > 1
326 > 2
326 > 2
327 > 3
327 > 3
328 > 4
328 > 4
329 > 5
329 > 5
330 > EOF
330 > EOF
331 $ hg add baz
331 $ hg add baz
332 $ hg commit -m "baz:0"
332 $ hg commit -m "baz:0"
333
333
334 $ cat > baz <<EOF
334 $ cat > baz <<EOF
335 > 1 baz:1
335 > 1 baz:1
336 > 2
336 > 2
337 > 3
337 > 3
338 > 4
338 > 4
339 > 5
339 > 5
340 > EOF
340 > EOF
341 $ hg commit -m "baz:1"
341 $ hg commit -m "baz:1"
342
342
343 $ cat > baz <<EOF
343 $ cat > baz <<EOF
344 > 1 baz:1
344 > 1 baz:1
345 > 2 baz:2
345 > 2 baz:2
346 > 3
346 > 3
347 > 4
347 > 4
348 > 5
348 > 5
349 > EOF
349 > EOF
350 $ hg debugsetparents 17 17
350 $ hg debugsetparents 17 17
351 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:2"
351 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:2"
352 $ hg debugindexdot .hg/store/data/baz.i
352 $ hg debugindexdot .hg/store/data/baz.i
353 digraph G {
353 digraph G {
354 -1 -> 0
354 -1 -> 0
355 0 -> 1
355 0 -> 1
356 1 -> 2
356 1 -> 2
357 1 -> 2
357 1 -> 2
358 }
358 }
359 $ hg annotate baz
359 $ hg annotate baz
360 17: 1 baz:1
360 17: 1 baz:1
361 18: 2 baz:2
361 18: 2 baz:2
362 16: 3
362 16: 3
363 16: 4
363 16: 4
364 16: 5
364 16: 5
365
365
366 $ cat > baz <<EOF
366 $ cat > baz <<EOF
367 > 1 baz:1
367 > 1 baz:1
368 > 2 baz:2
368 > 2 baz:2
369 > 3 baz:3
369 > 3 baz:3
370 > 4
370 > 4
371 > 5
371 > 5
372 > EOF
372 > EOF
373 $ hg commit -m "baz:3"
373 $ hg commit -m "baz:3"
374
374
375 $ cat > baz <<EOF
375 $ cat > baz <<EOF
376 > 1 baz:1
376 > 1 baz:1
377 > 2 baz:2
377 > 2 baz:2
378 > 3 baz:3
378 > 3 baz:3
379 > 4 baz:4
379 > 4 baz:4
380 > 5
380 > 5
381 > EOF
381 > EOF
382 $ hg debugsetparents 19 18
382 $ hg debugsetparents 19 18
383 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:4"
383 $ hg --config extensions.legacyrepo=../legacyrepo.py commit -m "baz:4"
384 $ hg debugindexdot .hg/store/data/baz.i
384 $ hg debugindexdot .hg/store/data/baz.i
385 digraph G {
385 digraph G {
386 -1 -> 0
386 -1 -> 0
387 0 -> 1
387 0 -> 1
388 1 -> 2
388 1 -> 2
389 1 -> 2
389 1 -> 2
390 2 -> 3
390 2 -> 3
391 3 -> 4
391 3 -> 4
392 2 -> 4
392 2 -> 4
393 }
393 }
394 $ hg annotate baz
394 $ hg annotate baz
395 17: 1 baz:1
395 17: 1 baz:1
396 18: 2 baz:2
396 18: 2 baz:2
397 19: 3 baz:3
397 19: 3 baz:3
398 20: 4 baz:4
398 20: 4 baz:4
399 16: 5
399 16: 5
400
400
401 Test annotate with whitespace options
401 Test annotate with whitespace options
402
402
403 $ cd ..
403 $ cd ..
404 $ hg init repo-ws
404 $ hg init repo-ws
405 $ cd repo-ws
405 $ cd repo-ws
406 $ cat > a <<EOF
406 $ cat > a <<EOF
407 > aa
407 > aa
408 >
408 >
409 > b b
409 > b b
410 > EOF
410 > EOF
411 $ hg ci -Am "adda"
411 $ hg ci -Am "adda"
412 adding a
412 adding a
413 $ sed 's/EOL$//g' > a <<EOF
413 $ sed 's/EOL$//g' > a <<EOF
414 > a a
414 > a a
415 >
415 >
416 > EOL
416 > EOL
417 > b b
417 > b b
418 > EOF
418 > EOF
419 $ hg ci -m "changea"
419 $ hg ci -m "changea"
420
420
421 Annotate with no option
421 Annotate with no option
422
422
423 $ hg annotate a
423 $ hg annotate a
424 1: a a
424 1: a a
425 0:
425 0:
426 1:
426 1:
427 1: b b
427 1: b b
428
428
429 Annotate with --ignore-space-change
429 Annotate with --ignore-space-change
430
430
431 $ hg annotate --ignore-space-change a
431 $ hg annotate --ignore-space-change a
432 1: a a
432 1: a a
433 1:
433 1:
434 0:
434 0:
435 0: b b
435 0: b b
436
436
437 Annotate with --ignore-all-space
437 Annotate with --ignore-all-space
438
438
439 $ hg annotate --ignore-all-space a
439 $ hg annotate --ignore-all-space a
440 0: a a
440 0: a a
441 0:
441 0:
442 1:
442 1:
443 0: b b
443 0: b b
444
444
445 Annotate with --ignore-blank-lines (similar to no options case)
445 Annotate with --ignore-blank-lines (similar to no options case)
446
446
447 $ hg annotate --ignore-blank-lines a
447 $ hg annotate --ignore-blank-lines a
448 1: a a
448 1: a a
449 0:
449 0:
450 1:
450 1:
451 1: b b
451 1: b b
452
452
453 $ cd ..
453 $ cd ..
454
455 Annotate with linkrev pointing to another branch
456 ------------------------------------------------
457
458 create history with a filerev whose linkrev points to another branch
459
460 $ hg init branchedlinkrev
461 $ cd branchedlinkrev
462 $ echo A > a
463 $ hg commit -Am 'contentA'
464 adding a
465 $ echo B >> a
466 $ hg commit -m 'contentB'
467 $ hg up --rev 'desc(contentA)'
468 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
469 $ echo unrelated > unrelated
470 $ hg commit -Am 'unrelated'
471 adding unrelated
472 created new head
473 $ hg graft -r 'desc(contentB)'
474 grafting 1:fd27c222e3e6 "contentB"
475 $ echo C >> a
476 $ hg commit -m 'contentC'
477 $ hg log -G
478 @ changeset: 4:072f1e8df249
479 | tag: tip
480 | user: test
481 | date: Thu Jan 01 00:00:00 1970 +0000
482 | summary: contentC
483 |
484 o changeset: 3:ff38df03cc4b
485 | user: test
486 | date: Thu Jan 01 00:00:00 1970 +0000
487 | summary: contentB
488 |
489 o changeset: 2:62aaf3f6fc06
490 | parent: 0:f0932f74827e
491 | user: test
492 | date: Thu Jan 01 00:00:00 1970 +0000
493 | summary: unrelated
494 |
495 | o changeset: 1:fd27c222e3e6
496 |/ user: test
497 | date: Thu Jan 01 00:00:00 1970 +0000
498 | summary: contentB
499 |
500 o changeset: 0:f0932f74827e
501 user: test
502 date: Thu Jan 01 00:00:00 1970 +0000
503 summary: contentA
504
505
506 Annotate should list ancestor of starting revision only
507
508 $ hg annotate a
509 0: A
510 3: B
511 4: C
512
513 $ cd ..
@@ -1,1566 +1,1659 b''
1 Log on empty repository: checking consistency
1 Log on empty repository: checking consistency
2
2
3 $ hg init empty
3 $ hg init empty
4 $ cd empty
4 $ cd empty
5 $ hg log
5 $ hg log
6 $ hg log -r 1
6 $ hg log -r 1
7 abort: unknown revision '1'!
7 abort: unknown revision '1'!
8 [255]
8 [255]
9 $ hg log -r -1:0
9 $ hg log -r -1:0
10 abort: unknown revision '-1'!
10 abort: unknown revision '-1'!
11 [255]
11 [255]
12 $ hg log -r 'branch(name)'
12 $ hg log -r 'branch(name)'
13 abort: unknown revision 'name'!
13 abort: unknown revision 'name'!
14 [255]
14 [255]
15 $ hg log -r null -q
15 $ hg log -r null -q
16 -1:000000000000
16 -1:000000000000
17
17
18 The g is crafted to have 2 filelog topological heads in a linear
18 The g is crafted to have 2 filelog topological heads in a linear
19 changeset graph
19 changeset graph
20
20
21 $ hg init a
21 $ hg init a
22 $ cd a
22 $ cd a
23 $ echo a > a
23 $ echo a > a
24 $ echo f > f
24 $ echo f > f
25 $ hg ci -Ama -d '1 0'
25 $ hg ci -Ama -d '1 0'
26 adding a
26 adding a
27 adding f
27 adding f
28
28
29 $ hg cp a b
29 $ hg cp a b
30 $ hg cp f g
30 $ hg cp f g
31 $ hg ci -mb -d '2 0'
31 $ hg ci -mb -d '2 0'
32
32
33 $ mkdir dir
33 $ mkdir dir
34 $ hg mv b dir
34 $ hg mv b dir
35 $ echo g >> g
35 $ echo g >> g
36 $ echo f >> f
36 $ echo f >> f
37 $ hg ci -mc -d '3 0'
37 $ hg ci -mc -d '3 0'
38
38
39 $ hg mv a b
39 $ hg mv a b
40 $ hg cp -f f g
40 $ hg cp -f f g
41 $ echo a > d
41 $ echo a > d
42 $ hg add d
42 $ hg add d
43 $ hg ci -md -d '4 0'
43 $ hg ci -md -d '4 0'
44
44
45 $ hg mv dir/b e
45 $ hg mv dir/b e
46 $ hg ci -me -d '5 0'
46 $ hg ci -me -d '5 0'
47
47
48 $ hg log a
48 $ hg log a
49 changeset: 0:9161b9aeaf16
49 changeset: 0:9161b9aeaf16
50 user: test
50 user: test
51 date: Thu Jan 01 00:00:01 1970 +0000
51 date: Thu Jan 01 00:00:01 1970 +0000
52 summary: a
52 summary: a
53
53
54 log on directory
54 log on directory
55
55
56 $ hg log dir
56 $ hg log dir
57 changeset: 4:7e4639b4691b
57 changeset: 4:7e4639b4691b
58 tag: tip
58 tag: tip
59 user: test
59 user: test
60 date: Thu Jan 01 00:00:05 1970 +0000
60 date: Thu Jan 01 00:00:05 1970 +0000
61 summary: e
61 summary: e
62
62
63 changeset: 2:f8954cd4dc1f
63 changeset: 2:f8954cd4dc1f
64 user: test
64 user: test
65 date: Thu Jan 01 00:00:03 1970 +0000
65 date: Thu Jan 01 00:00:03 1970 +0000
66 summary: c
66 summary: c
67
67
68 $ hg log somethingthatdoesntexist dir
68 $ hg log somethingthatdoesntexist dir
69 changeset: 4:7e4639b4691b
69 changeset: 4:7e4639b4691b
70 tag: tip
70 tag: tip
71 user: test
71 user: test
72 date: Thu Jan 01 00:00:05 1970 +0000
72 date: Thu Jan 01 00:00:05 1970 +0000
73 summary: e
73 summary: e
74
74
75 changeset: 2:f8954cd4dc1f
75 changeset: 2:f8954cd4dc1f
76 user: test
76 user: test
77 date: Thu Jan 01 00:00:03 1970 +0000
77 date: Thu Jan 01 00:00:03 1970 +0000
78 summary: c
78 summary: c
79
79
80
80
81 -f, non-existent directory
81 -f, non-existent directory
82
82
83 $ hg log -f dir
83 $ hg log -f dir
84 abort: cannot follow file not in parent revision: "dir"
84 abort: cannot follow file not in parent revision: "dir"
85 [255]
85 [255]
86
86
87 -f, directory
87 -f, directory
88
88
89 $ hg up -q 3
89 $ hg up -q 3
90 $ hg log -f dir
90 $ hg log -f dir
91 changeset: 2:f8954cd4dc1f
91 changeset: 2:f8954cd4dc1f
92 user: test
92 user: test
93 date: Thu Jan 01 00:00:03 1970 +0000
93 date: Thu Jan 01 00:00:03 1970 +0000
94 summary: c
94 summary: c
95
95
96 -f, directory with --patch
96 -f, directory with --patch
97
97
98 $ hg log -f dir -p
98 $ hg log -f dir -p
99 changeset: 2:f8954cd4dc1f
99 changeset: 2:f8954cd4dc1f
100 user: test
100 user: test
101 date: Thu Jan 01 00:00:03 1970 +0000
101 date: Thu Jan 01 00:00:03 1970 +0000
102 summary: c
102 summary: c
103
103
104 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
104 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
105 --- /dev/null* (glob)
105 --- /dev/null* (glob)
106 +++ b/dir/b* (glob)
106 +++ b/dir/b* (glob)
107 @@ -0,0 +1,1 @@
107 @@ -0,0 +1,1 @@
108 +a
108 +a
109
109
110
110
111 -f, pattern
111 -f, pattern
112
112
113 $ hg log -f -I 'dir**' -p
113 $ hg log -f -I 'dir**' -p
114 changeset: 2:f8954cd4dc1f
114 changeset: 2:f8954cd4dc1f
115 user: test
115 user: test
116 date: Thu Jan 01 00:00:03 1970 +0000
116 date: Thu Jan 01 00:00:03 1970 +0000
117 summary: c
117 summary: c
118
118
119 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
119 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
120 --- /dev/null* (glob)
120 --- /dev/null* (glob)
121 +++ b/dir/b* (glob)
121 +++ b/dir/b* (glob)
122 @@ -0,0 +1,1 @@
122 @@ -0,0 +1,1 @@
123 +a
123 +a
124
124
125 $ hg up -q 4
125 $ hg up -q 4
126
126
127 -f, a wrong style
127 -f, a wrong style
128
128
129 $ hg log -f -l1 --style something
129 $ hg log -f -l1 --style something
130 abort: style 'something' not found
130 abort: style 'something' not found
131 (available styles: bisect, changelog, compact, default, phases, xml)
131 (available styles: bisect, changelog, compact, default, phases, xml)
132 [255]
132 [255]
133
133
134 -f, phases style
134 -f, phases style
135
135
136
136
137 $ hg log -f -l1 --style phases
137 $ hg log -f -l1 --style phases
138 changeset: 4:7e4639b4691b
138 changeset: 4:7e4639b4691b
139 tag: tip
139 tag: tip
140 phase: draft
140 phase: draft
141 user: test
141 user: test
142 date: Thu Jan 01 00:00:05 1970 +0000
142 date: Thu Jan 01 00:00:05 1970 +0000
143 summary: e
143 summary: e
144
144
145
145
146 -f, but no args
146 -f, but no args
147
147
148 $ hg log -f
148 $ hg log -f
149 changeset: 4:7e4639b4691b
149 changeset: 4:7e4639b4691b
150 tag: tip
150 tag: tip
151 user: test
151 user: test
152 date: Thu Jan 01 00:00:05 1970 +0000
152 date: Thu Jan 01 00:00:05 1970 +0000
153 summary: e
153 summary: e
154
154
155 changeset: 3:2ca5ba701980
155 changeset: 3:2ca5ba701980
156 user: test
156 user: test
157 date: Thu Jan 01 00:00:04 1970 +0000
157 date: Thu Jan 01 00:00:04 1970 +0000
158 summary: d
158 summary: d
159
159
160 changeset: 2:f8954cd4dc1f
160 changeset: 2:f8954cd4dc1f
161 user: test
161 user: test
162 date: Thu Jan 01 00:00:03 1970 +0000
162 date: Thu Jan 01 00:00:03 1970 +0000
163 summary: c
163 summary: c
164
164
165 changeset: 1:d89b0a12d229
165 changeset: 1:d89b0a12d229
166 user: test
166 user: test
167 date: Thu Jan 01 00:00:02 1970 +0000
167 date: Thu Jan 01 00:00:02 1970 +0000
168 summary: b
168 summary: b
169
169
170 changeset: 0:9161b9aeaf16
170 changeset: 0:9161b9aeaf16
171 user: test
171 user: test
172 date: Thu Jan 01 00:00:01 1970 +0000
172 date: Thu Jan 01 00:00:01 1970 +0000
173 summary: a
173 summary: a
174
174
175
175
176 one rename
176 one rename
177
177
178 $ hg up -q 2
178 $ hg up -q 2
179 $ hg log -vf a
179 $ hg log -vf a
180 changeset: 0:9161b9aeaf16
180 changeset: 0:9161b9aeaf16
181 user: test
181 user: test
182 date: Thu Jan 01 00:00:01 1970 +0000
182 date: Thu Jan 01 00:00:01 1970 +0000
183 files: a f
183 files: a f
184 description:
184 description:
185 a
185 a
186
186
187
187
188
188
189 many renames
189 many renames
190
190
191 $ hg up -q tip
191 $ hg up -q tip
192 $ hg log -vf e
192 $ hg log -vf e
193 changeset: 4:7e4639b4691b
193 changeset: 4:7e4639b4691b
194 tag: tip
194 tag: tip
195 user: test
195 user: test
196 date: Thu Jan 01 00:00:05 1970 +0000
196 date: Thu Jan 01 00:00:05 1970 +0000
197 files: dir/b e
197 files: dir/b e
198 description:
198 description:
199 e
199 e
200
200
201
201
202 changeset: 2:f8954cd4dc1f
202 changeset: 2:f8954cd4dc1f
203 user: test
203 user: test
204 date: Thu Jan 01 00:00:03 1970 +0000
204 date: Thu Jan 01 00:00:03 1970 +0000
205 files: b dir/b f g
205 files: b dir/b f g
206 description:
206 description:
207 c
207 c
208
208
209
209
210 changeset: 1:d89b0a12d229
210 changeset: 1:d89b0a12d229
211 user: test
211 user: test
212 date: Thu Jan 01 00:00:02 1970 +0000
212 date: Thu Jan 01 00:00:02 1970 +0000
213 files: b g
213 files: b g
214 description:
214 description:
215 b
215 b
216
216
217
217
218 changeset: 0:9161b9aeaf16
218 changeset: 0:9161b9aeaf16
219 user: test
219 user: test
220 date: Thu Jan 01 00:00:01 1970 +0000
220 date: Thu Jan 01 00:00:01 1970 +0000
221 files: a f
221 files: a f
222 description:
222 description:
223 a
223 a
224
224
225
225
226
226
227
227
228 log -pf dir/b
228 log -pf dir/b
229
229
230 $ hg up -q 3
230 $ hg up -q 3
231 $ hg log -pf dir/b
231 $ hg log -pf dir/b
232 changeset: 2:f8954cd4dc1f
232 changeset: 2:f8954cd4dc1f
233 user: test
233 user: test
234 date: Thu Jan 01 00:00:03 1970 +0000
234 date: Thu Jan 01 00:00:03 1970 +0000
235 summary: c
235 summary: c
236
236
237 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
237 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
238 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
238 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
239 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
239 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
240 @@ -0,0 +1,1 @@
240 @@ -0,0 +1,1 @@
241 +a
241 +a
242
242
243 changeset: 1:d89b0a12d229
243 changeset: 1:d89b0a12d229
244 user: test
244 user: test
245 date: Thu Jan 01 00:00:02 1970 +0000
245 date: Thu Jan 01 00:00:02 1970 +0000
246 summary: b
246 summary: b
247
247
248 diff -r 9161b9aeaf16 -r d89b0a12d229 b
248 diff -r 9161b9aeaf16 -r d89b0a12d229 b
249 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
249 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
250 +++ b/b Thu Jan 01 00:00:02 1970 +0000
250 +++ b/b Thu Jan 01 00:00:02 1970 +0000
251 @@ -0,0 +1,1 @@
251 @@ -0,0 +1,1 @@
252 +a
252 +a
253
253
254 changeset: 0:9161b9aeaf16
254 changeset: 0:9161b9aeaf16
255 user: test
255 user: test
256 date: Thu Jan 01 00:00:01 1970 +0000
256 date: Thu Jan 01 00:00:01 1970 +0000
257 summary: a
257 summary: a
258
258
259 diff -r 000000000000 -r 9161b9aeaf16 a
259 diff -r 000000000000 -r 9161b9aeaf16 a
260 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
260 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
261 +++ b/a Thu Jan 01 00:00:01 1970 +0000
261 +++ b/a Thu Jan 01 00:00:01 1970 +0000
262 @@ -0,0 +1,1 @@
262 @@ -0,0 +1,1 @@
263 +a
263 +a
264
264
265
265
266 log -pf b inside dir
266 log -pf b inside dir
267
267
268 $ hg --cwd=dir log -pf b
268 $ hg --cwd=dir log -pf b
269 changeset: 2:f8954cd4dc1f
269 changeset: 2:f8954cd4dc1f
270 user: test
270 user: test
271 date: Thu Jan 01 00:00:03 1970 +0000
271 date: Thu Jan 01 00:00:03 1970 +0000
272 summary: c
272 summary: c
273
273
274 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
274 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
275 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
275 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
276 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
276 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
277 @@ -0,0 +1,1 @@
277 @@ -0,0 +1,1 @@
278 +a
278 +a
279
279
280 changeset: 1:d89b0a12d229
280 changeset: 1:d89b0a12d229
281 user: test
281 user: test
282 date: Thu Jan 01 00:00:02 1970 +0000
282 date: Thu Jan 01 00:00:02 1970 +0000
283 summary: b
283 summary: b
284
284
285 diff -r 9161b9aeaf16 -r d89b0a12d229 b
285 diff -r 9161b9aeaf16 -r d89b0a12d229 b
286 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
286 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
287 +++ b/b Thu Jan 01 00:00:02 1970 +0000
287 +++ b/b Thu Jan 01 00:00:02 1970 +0000
288 @@ -0,0 +1,1 @@
288 @@ -0,0 +1,1 @@
289 +a
289 +a
290
290
291 changeset: 0:9161b9aeaf16
291 changeset: 0:9161b9aeaf16
292 user: test
292 user: test
293 date: Thu Jan 01 00:00:01 1970 +0000
293 date: Thu Jan 01 00:00:01 1970 +0000
294 summary: a
294 summary: a
295
295
296 diff -r 000000000000 -r 9161b9aeaf16 a
296 diff -r 000000000000 -r 9161b9aeaf16 a
297 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
297 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
298 +++ b/a Thu Jan 01 00:00:01 1970 +0000
298 +++ b/a Thu Jan 01 00:00:01 1970 +0000
299 @@ -0,0 +1,1 @@
299 @@ -0,0 +1,1 @@
300 +a
300 +a
301
301
302
302
303 log -pf, but no args
303 log -pf, but no args
304
304
305 $ hg log -pf
305 $ hg log -pf
306 changeset: 3:2ca5ba701980
306 changeset: 3:2ca5ba701980
307 user: test
307 user: test
308 date: Thu Jan 01 00:00:04 1970 +0000
308 date: Thu Jan 01 00:00:04 1970 +0000
309 summary: d
309 summary: d
310
310
311 diff -r f8954cd4dc1f -r 2ca5ba701980 a
311 diff -r f8954cd4dc1f -r 2ca5ba701980 a
312 --- a/a Thu Jan 01 00:00:03 1970 +0000
312 --- a/a Thu Jan 01 00:00:03 1970 +0000
313 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
313 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
314 @@ -1,1 +0,0 @@
314 @@ -1,1 +0,0 @@
315 -a
315 -a
316 diff -r f8954cd4dc1f -r 2ca5ba701980 b
316 diff -r f8954cd4dc1f -r 2ca5ba701980 b
317 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
317 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
318 +++ b/b Thu Jan 01 00:00:04 1970 +0000
318 +++ b/b Thu Jan 01 00:00:04 1970 +0000
319 @@ -0,0 +1,1 @@
319 @@ -0,0 +1,1 @@
320 +a
320 +a
321 diff -r f8954cd4dc1f -r 2ca5ba701980 d
321 diff -r f8954cd4dc1f -r 2ca5ba701980 d
322 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
322 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
323 +++ b/d Thu Jan 01 00:00:04 1970 +0000
323 +++ b/d Thu Jan 01 00:00:04 1970 +0000
324 @@ -0,0 +1,1 @@
324 @@ -0,0 +1,1 @@
325 +a
325 +a
326 diff -r f8954cd4dc1f -r 2ca5ba701980 g
326 diff -r f8954cd4dc1f -r 2ca5ba701980 g
327 --- a/g Thu Jan 01 00:00:03 1970 +0000
327 --- a/g Thu Jan 01 00:00:03 1970 +0000
328 +++ b/g Thu Jan 01 00:00:04 1970 +0000
328 +++ b/g Thu Jan 01 00:00:04 1970 +0000
329 @@ -1,2 +1,2 @@
329 @@ -1,2 +1,2 @@
330 f
330 f
331 -g
331 -g
332 +f
332 +f
333
333
334 changeset: 2:f8954cd4dc1f
334 changeset: 2:f8954cd4dc1f
335 user: test
335 user: test
336 date: Thu Jan 01 00:00:03 1970 +0000
336 date: Thu Jan 01 00:00:03 1970 +0000
337 summary: c
337 summary: c
338
338
339 diff -r d89b0a12d229 -r f8954cd4dc1f b
339 diff -r d89b0a12d229 -r f8954cd4dc1f b
340 --- a/b Thu Jan 01 00:00:02 1970 +0000
340 --- a/b Thu Jan 01 00:00:02 1970 +0000
341 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
341 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
342 @@ -1,1 +0,0 @@
342 @@ -1,1 +0,0 @@
343 -a
343 -a
344 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
344 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
345 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
345 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
346 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
346 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
347 @@ -0,0 +1,1 @@
347 @@ -0,0 +1,1 @@
348 +a
348 +a
349 diff -r d89b0a12d229 -r f8954cd4dc1f f
349 diff -r d89b0a12d229 -r f8954cd4dc1f f
350 --- a/f Thu Jan 01 00:00:02 1970 +0000
350 --- a/f Thu Jan 01 00:00:02 1970 +0000
351 +++ b/f Thu Jan 01 00:00:03 1970 +0000
351 +++ b/f Thu Jan 01 00:00:03 1970 +0000
352 @@ -1,1 +1,2 @@
352 @@ -1,1 +1,2 @@
353 f
353 f
354 +f
354 +f
355 diff -r d89b0a12d229 -r f8954cd4dc1f g
355 diff -r d89b0a12d229 -r f8954cd4dc1f g
356 --- a/g Thu Jan 01 00:00:02 1970 +0000
356 --- a/g Thu Jan 01 00:00:02 1970 +0000
357 +++ b/g Thu Jan 01 00:00:03 1970 +0000
357 +++ b/g Thu Jan 01 00:00:03 1970 +0000
358 @@ -1,1 +1,2 @@
358 @@ -1,1 +1,2 @@
359 f
359 f
360 +g
360 +g
361
361
362 changeset: 1:d89b0a12d229
362 changeset: 1:d89b0a12d229
363 user: test
363 user: test
364 date: Thu Jan 01 00:00:02 1970 +0000
364 date: Thu Jan 01 00:00:02 1970 +0000
365 summary: b
365 summary: b
366
366
367 diff -r 9161b9aeaf16 -r d89b0a12d229 b
367 diff -r 9161b9aeaf16 -r d89b0a12d229 b
368 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
368 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
369 +++ b/b Thu Jan 01 00:00:02 1970 +0000
369 +++ b/b Thu Jan 01 00:00:02 1970 +0000
370 @@ -0,0 +1,1 @@
370 @@ -0,0 +1,1 @@
371 +a
371 +a
372 diff -r 9161b9aeaf16 -r d89b0a12d229 g
372 diff -r 9161b9aeaf16 -r d89b0a12d229 g
373 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
373 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
374 +++ b/g Thu Jan 01 00:00:02 1970 +0000
374 +++ b/g Thu Jan 01 00:00:02 1970 +0000
375 @@ -0,0 +1,1 @@
375 @@ -0,0 +1,1 @@
376 +f
376 +f
377
377
378 changeset: 0:9161b9aeaf16
378 changeset: 0:9161b9aeaf16
379 user: test
379 user: test
380 date: Thu Jan 01 00:00:01 1970 +0000
380 date: Thu Jan 01 00:00:01 1970 +0000
381 summary: a
381 summary: a
382
382
383 diff -r 000000000000 -r 9161b9aeaf16 a
383 diff -r 000000000000 -r 9161b9aeaf16 a
384 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
384 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
385 +++ b/a Thu Jan 01 00:00:01 1970 +0000
385 +++ b/a Thu Jan 01 00:00:01 1970 +0000
386 @@ -0,0 +1,1 @@
386 @@ -0,0 +1,1 @@
387 +a
387 +a
388 diff -r 000000000000 -r 9161b9aeaf16 f
388 diff -r 000000000000 -r 9161b9aeaf16 f
389 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
389 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
390 +++ b/f Thu Jan 01 00:00:01 1970 +0000
390 +++ b/f Thu Jan 01 00:00:01 1970 +0000
391 @@ -0,0 +1,1 @@
391 @@ -0,0 +1,1 @@
392 +f
392 +f
393
393
394
394
395 log -vf dir/b
395 log -vf dir/b
396
396
397 $ hg log -vf dir/b
397 $ hg log -vf dir/b
398 changeset: 2:f8954cd4dc1f
398 changeset: 2:f8954cd4dc1f
399 user: test
399 user: test
400 date: Thu Jan 01 00:00:03 1970 +0000
400 date: Thu Jan 01 00:00:03 1970 +0000
401 files: b dir/b f g
401 files: b dir/b f g
402 description:
402 description:
403 c
403 c
404
404
405
405
406 changeset: 1:d89b0a12d229
406 changeset: 1:d89b0a12d229
407 user: test
407 user: test
408 date: Thu Jan 01 00:00:02 1970 +0000
408 date: Thu Jan 01 00:00:02 1970 +0000
409 files: b g
409 files: b g
410 description:
410 description:
411 b
411 b
412
412
413
413
414 changeset: 0:9161b9aeaf16
414 changeset: 0:9161b9aeaf16
415 user: test
415 user: test
416 date: Thu Jan 01 00:00:01 1970 +0000
416 date: Thu Jan 01 00:00:01 1970 +0000
417 files: a f
417 files: a f
418 description:
418 description:
419 a
419 a
420
420
421
421
422
422
423
423
424 -f and multiple filelog heads
424 -f and multiple filelog heads
425
425
426 $ hg up -q 2
426 $ hg up -q 2
427 $ hg log -f g --template '{rev}\n'
427 $ hg log -f g --template '{rev}\n'
428 2
428 2
429 1
429 1
430 0
430 0
431 $ hg up -q tip
431 $ hg up -q tip
432 $ hg log -f g --template '{rev}\n'
432 $ hg log -f g --template '{rev}\n'
433 3
433 3
434 2
434 2
435 0
435 0
436
436
437
437
438 log copies with --copies
438 log copies with --copies
439
439
440 $ hg log -vC --template '{rev} {file_copies}\n'
440 $ hg log -vC --template '{rev} {file_copies}\n'
441 4 e (dir/b)
441 4 e (dir/b)
442 3 b (a)g (f)
442 3 b (a)g (f)
443 2 dir/b (b)
443 2 dir/b (b)
444 1 b (a)g (f)
444 1 b (a)g (f)
445 0
445 0
446
446
447 log copies switch without --copies, with old filecopy template
447 log copies switch without --copies, with old filecopy template
448
448
449 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
449 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
450 4
450 4
451 3
451 3
452 2
452 2
453 1
453 1
454 0
454 0
455
455
456 log copies switch with --copies
456 log copies switch with --copies
457
457
458 $ hg log -vC --template '{rev} {file_copies_switch}\n'
458 $ hg log -vC --template '{rev} {file_copies_switch}\n'
459 4 e (dir/b)
459 4 e (dir/b)
460 3 b (a)g (f)
460 3 b (a)g (f)
461 2 dir/b (b)
461 2 dir/b (b)
462 1 b (a)g (f)
462 1 b (a)g (f)
463 0
463 0
464
464
465
465
466 log copies with hardcoded style and with --style=default
466 log copies with hardcoded style and with --style=default
467
467
468 $ hg log -vC -r4
468 $ hg log -vC -r4
469 changeset: 4:7e4639b4691b
469 changeset: 4:7e4639b4691b
470 tag: tip
470 tag: tip
471 user: test
471 user: test
472 date: Thu Jan 01 00:00:05 1970 +0000
472 date: Thu Jan 01 00:00:05 1970 +0000
473 files: dir/b e
473 files: dir/b e
474 copies: e (dir/b)
474 copies: e (dir/b)
475 description:
475 description:
476 e
476 e
477
477
478
478
479 $ hg log -vC -r4 --style=default
479 $ hg log -vC -r4 --style=default
480 changeset: 4:7e4639b4691b
480 changeset: 4:7e4639b4691b
481 tag: tip
481 tag: tip
482 user: test
482 user: test
483 date: Thu Jan 01 00:00:05 1970 +0000
483 date: Thu Jan 01 00:00:05 1970 +0000
484 files: dir/b e
484 files: dir/b e
485 copies: e (dir/b)
485 copies: e (dir/b)
486 description:
486 description:
487 e
487 e
488
488
489
489
490
490
491
491
492 log copies, non-linear manifest
492 log copies, non-linear manifest
493
493
494 $ hg up -C 3
494 $ hg up -C 3
495 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
495 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
496 $ hg mv dir/b e
496 $ hg mv dir/b e
497 $ echo foo > foo
497 $ echo foo > foo
498 $ hg ci -Ame2 -d '6 0'
498 $ hg ci -Ame2 -d '6 0'
499 adding foo
499 adding foo
500 created new head
500 created new head
501 $ hg log -v --template '{rev} {file_copies}\n' -r 5
501 $ hg log -v --template '{rev} {file_copies}\n' -r 5
502 5 e (dir/b)
502 5 e (dir/b)
503
503
504
504
505 log copies, execute bit set
505 log copies, execute bit set
506
506
507 #if execbit
507 #if execbit
508 $ chmod +x e
508 $ chmod +x e
509 $ hg ci -me3 -d '7 0'
509 $ hg ci -me3 -d '7 0'
510 $ hg log -v --template '{rev} {file_copies}\n' -r 6
510 $ hg log -v --template '{rev} {file_copies}\n' -r 6
511 6
511 6
512 #endif
512 #endif
513
513
514
514
515 log -p d
515 log -p d
516
516
517 $ hg log -pv d
517 $ hg log -pv d
518 changeset: 3:2ca5ba701980
518 changeset: 3:2ca5ba701980
519 user: test
519 user: test
520 date: Thu Jan 01 00:00:04 1970 +0000
520 date: Thu Jan 01 00:00:04 1970 +0000
521 files: a b d g
521 files: a b d g
522 description:
522 description:
523 d
523 d
524
524
525
525
526 diff -r f8954cd4dc1f -r 2ca5ba701980 d
526 diff -r f8954cd4dc1f -r 2ca5ba701980 d
527 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
527 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
528 +++ b/d Thu Jan 01 00:00:04 1970 +0000
528 +++ b/d Thu Jan 01 00:00:04 1970 +0000
529 @@ -0,0 +1,1 @@
529 @@ -0,0 +1,1 @@
530 +a
530 +a
531
531
532
532
533
533
534 log --removed file
534 log --removed file
535
535
536 $ hg log --removed -v a
536 $ hg log --removed -v a
537 changeset: 3:2ca5ba701980
537 changeset: 3:2ca5ba701980
538 user: test
538 user: test
539 date: Thu Jan 01 00:00:04 1970 +0000
539 date: Thu Jan 01 00:00:04 1970 +0000
540 files: a b d g
540 files: a b d g
541 description:
541 description:
542 d
542 d
543
543
544
544
545 changeset: 0:9161b9aeaf16
545 changeset: 0:9161b9aeaf16
546 user: test
546 user: test
547 date: Thu Jan 01 00:00:01 1970 +0000
547 date: Thu Jan 01 00:00:01 1970 +0000
548 files: a f
548 files: a f
549 description:
549 description:
550 a
550 a
551
551
552
552
553
553
554 log --removed revrange file
554 log --removed revrange file
555
555
556 $ hg log --removed -v -r0:2 a
556 $ hg log --removed -v -r0:2 a
557 changeset: 0:9161b9aeaf16
557 changeset: 0:9161b9aeaf16
558 user: test
558 user: test
559 date: Thu Jan 01 00:00:01 1970 +0000
559 date: Thu Jan 01 00:00:01 1970 +0000
560 files: a f
560 files: a f
561 description:
561 description:
562 a
562 a
563
563
564
564
565 $ cd ..
565 $ cd ..
566
566
567 log --follow tests
567 log --follow tests
568
568
569 $ hg init follow
569 $ hg init follow
570 $ cd follow
570 $ cd follow
571
571
572 $ echo base > base
572 $ echo base > base
573 $ hg ci -Ambase -d '1 0'
573 $ hg ci -Ambase -d '1 0'
574 adding base
574 adding base
575
575
576 $ echo r1 >> base
576 $ echo r1 >> base
577 $ hg ci -Amr1 -d '1 0'
577 $ hg ci -Amr1 -d '1 0'
578 $ echo r2 >> base
578 $ echo r2 >> base
579 $ hg ci -Amr2 -d '1 0'
579 $ hg ci -Amr2 -d '1 0'
580
580
581 $ hg up -C 1
581 $ hg up -C 1
582 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
582 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
583 $ echo b1 > b1
583 $ echo b1 > b1
584 $ hg ci -Amb1 -d '1 0'
584 $ hg ci -Amb1 -d '1 0'
585 adding b1
585 adding b1
586 created new head
586 created new head
587
587
588
588
589 log -f
589 log -f
590
590
591 $ hg log -f
591 $ hg log -f
592 changeset: 3:e62f78d544b4
592 changeset: 3:e62f78d544b4
593 tag: tip
593 tag: tip
594 parent: 1:3d5bf5654eda
594 parent: 1:3d5bf5654eda
595 user: test
595 user: test
596 date: Thu Jan 01 00:00:01 1970 +0000
596 date: Thu Jan 01 00:00:01 1970 +0000
597 summary: b1
597 summary: b1
598
598
599 changeset: 1:3d5bf5654eda
599 changeset: 1:3d5bf5654eda
600 user: test
600 user: test
601 date: Thu Jan 01 00:00:01 1970 +0000
601 date: Thu Jan 01 00:00:01 1970 +0000
602 summary: r1
602 summary: r1
603
603
604 changeset: 0:67e992f2c4f3
604 changeset: 0:67e992f2c4f3
605 user: test
605 user: test
606 date: Thu Jan 01 00:00:01 1970 +0000
606 date: Thu Jan 01 00:00:01 1970 +0000
607 summary: base
607 summary: base
608
608
609
609
610
610
611 log -f -r 1:tip
611 log -f -r 1:tip
612
612
613 $ hg up -C 0
613 $ hg up -C 0
614 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
614 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
615 $ echo b2 > b2
615 $ echo b2 > b2
616 $ hg ci -Amb2 -d '1 0'
616 $ hg ci -Amb2 -d '1 0'
617 adding b2
617 adding b2
618 created new head
618 created new head
619 $ hg log -f -r 1:tip
619 $ hg log -f -r 1:tip
620 changeset: 1:3d5bf5654eda
620 changeset: 1:3d5bf5654eda
621 user: test
621 user: test
622 date: Thu Jan 01 00:00:01 1970 +0000
622 date: Thu Jan 01 00:00:01 1970 +0000
623 summary: r1
623 summary: r1
624
624
625 changeset: 2:60c670bf5b30
625 changeset: 2:60c670bf5b30
626 user: test
626 user: test
627 date: Thu Jan 01 00:00:01 1970 +0000
627 date: Thu Jan 01 00:00:01 1970 +0000
628 summary: r2
628 summary: r2
629
629
630 changeset: 3:e62f78d544b4
630 changeset: 3:e62f78d544b4
631 parent: 1:3d5bf5654eda
631 parent: 1:3d5bf5654eda
632 user: test
632 user: test
633 date: Thu Jan 01 00:00:01 1970 +0000
633 date: Thu Jan 01 00:00:01 1970 +0000
634 summary: b1
634 summary: b1
635
635
636
636
637
637
638 log -r . with two parents
638 log -r . with two parents
639
639
640 $ hg up -C 3
640 $ hg up -C 3
641 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
641 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
642 $ hg merge tip
642 $ hg merge tip
643 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
643 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
644 (branch merge, don't forget to commit)
644 (branch merge, don't forget to commit)
645 $ hg log -r .
645 $ hg log -r .
646 changeset: 3:e62f78d544b4
646 changeset: 3:e62f78d544b4
647 parent: 1:3d5bf5654eda
647 parent: 1:3d5bf5654eda
648 user: test
648 user: test
649 date: Thu Jan 01 00:00:01 1970 +0000
649 date: Thu Jan 01 00:00:01 1970 +0000
650 summary: b1
650 summary: b1
651
651
652
652
653
653
654 log -r . with one parent
654 log -r . with one parent
655
655
656 $ hg ci -mm12 -d '1 0'
656 $ hg ci -mm12 -d '1 0'
657 $ hg log -r .
657 $ hg log -r .
658 changeset: 5:302e9dd6890d
658 changeset: 5:302e9dd6890d
659 tag: tip
659 tag: tip
660 parent: 3:e62f78d544b4
660 parent: 3:e62f78d544b4
661 parent: 4:ddb82e70d1a1
661 parent: 4:ddb82e70d1a1
662 user: test
662 user: test
663 date: Thu Jan 01 00:00:01 1970 +0000
663 date: Thu Jan 01 00:00:01 1970 +0000
664 summary: m12
664 summary: m12
665
665
666
666
667 $ echo postm >> b1
667 $ echo postm >> b1
668 $ hg ci -Amb1.1 -d'1 0'
668 $ hg ci -Amb1.1 -d'1 0'
669
669
670
670
671 log --follow-first
671 log --follow-first
672
672
673 $ hg log --follow-first
673 $ hg log --follow-first
674 changeset: 6:2404bbcab562
674 changeset: 6:2404bbcab562
675 tag: tip
675 tag: tip
676 user: test
676 user: test
677 date: Thu Jan 01 00:00:01 1970 +0000
677 date: Thu Jan 01 00:00:01 1970 +0000
678 summary: b1.1
678 summary: b1.1
679
679
680 changeset: 5:302e9dd6890d
680 changeset: 5:302e9dd6890d
681 parent: 3:e62f78d544b4
681 parent: 3:e62f78d544b4
682 parent: 4:ddb82e70d1a1
682 parent: 4:ddb82e70d1a1
683 user: test
683 user: test
684 date: Thu Jan 01 00:00:01 1970 +0000
684 date: Thu Jan 01 00:00:01 1970 +0000
685 summary: m12
685 summary: m12
686
686
687 changeset: 3:e62f78d544b4
687 changeset: 3:e62f78d544b4
688 parent: 1:3d5bf5654eda
688 parent: 1:3d5bf5654eda
689 user: test
689 user: test
690 date: Thu Jan 01 00:00:01 1970 +0000
690 date: Thu Jan 01 00:00:01 1970 +0000
691 summary: b1
691 summary: b1
692
692
693 changeset: 1:3d5bf5654eda
693 changeset: 1:3d5bf5654eda
694 user: test
694 user: test
695 date: Thu Jan 01 00:00:01 1970 +0000
695 date: Thu Jan 01 00:00:01 1970 +0000
696 summary: r1
696 summary: r1
697
697
698 changeset: 0:67e992f2c4f3
698 changeset: 0:67e992f2c4f3
699 user: test
699 user: test
700 date: Thu Jan 01 00:00:01 1970 +0000
700 date: Thu Jan 01 00:00:01 1970 +0000
701 summary: base
701 summary: base
702
702
703
703
704
704
705 log -P 2
705 log -P 2
706
706
707 $ hg log -P 2
707 $ hg log -P 2
708 changeset: 6:2404bbcab562
708 changeset: 6:2404bbcab562
709 tag: tip
709 tag: tip
710 user: test
710 user: test
711 date: Thu Jan 01 00:00:01 1970 +0000
711 date: Thu Jan 01 00:00:01 1970 +0000
712 summary: b1.1
712 summary: b1.1
713
713
714 changeset: 5:302e9dd6890d
714 changeset: 5:302e9dd6890d
715 parent: 3:e62f78d544b4
715 parent: 3:e62f78d544b4
716 parent: 4:ddb82e70d1a1
716 parent: 4:ddb82e70d1a1
717 user: test
717 user: test
718 date: Thu Jan 01 00:00:01 1970 +0000
718 date: Thu Jan 01 00:00:01 1970 +0000
719 summary: m12
719 summary: m12
720
720
721 changeset: 4:ddb82e70d1a1
721 changeset: 4:ddb82e70d1a1
722 parent: 0:67e992f2c4f3
722 parent: 0:67e992f2c4f3
723 user: test
723 user: test
724 date: Thu Jan 01 00:00:01 1970 +0000
724 date: Thu Jan 01 00:00:01 1970 +0000
725 summary: b2
725 summary: b2
726
726
727 changeset: 3:e62f78d544b4
727 changeset: 3:e62f78d544b4
728 parent: 1:3d5bf5654eda
728 parent: 1:3d5bf5654eda
729 user: test
729 user: test
730 date: Thu Jan 01 00:00:01 1970 +0000
730 date: Thu Jan 01 00:00:01 1970 +0000
731 summary: b1
731 summary: b1
732
732
733
733
734
734
735 log -r tip -p --git
735 log -r tip -p --git
736
736
737 $ hg log -r tip -p --git
737 $ hg log -r tip -p --git
738 changeset: 6:2404bbcab562
738 changeset: 6:2404bbcab562
739 tag: tip
739 tag: tip
740 user: test
740 user: test
741 date: Thu Jan 01 00:00:01 1970 +0000
741 date: Thu Jan 01 00:00:01 1970 +0000
742 summary: b1.1
742 summary: b1.1
743
743
744 diff --git a/b1 b/b1
744 diff --git a/b1 b/b1
745 --- a/b1
745 --- a/b1
746 +++ b/b1
746 +++ b/b1
747 @@ -1,1 +1,2 @@
747 @@ -1,1 +1,2 @@
748 b1
748 b1
749 +postm
749 +postm
750
750
751
751
752
752
753 log -r ""
753 log -r ""
754
754
755 $ hg log -r ''
755 $ hg log -r ''
756 hg: parse error: empty query
756 hg: parse error: empty query
757 [255]
757 [255]
758
758
759 log -r <some unknown node id>
759 log -r <some unknown node id>
760
760
761 $ hg log -r 1000000000000000000000000000000000000000
761 $ hg log -r 1000000000000000000000000000000000000000
762 abort: unknown revision '1000000000000000000000000000000000000000'!
762 abort: unknown revision '1000000000000000000000000000000000000000'!
763 [255]
763 [255]
764
764
765 log -k r1
765 log -k r1
766
766
767 $ hg log -k r1
767 $ hg log -k r1
768 changeset: 1:3d5bf5654eda
768 changeset: 1:3d5bf5654eda
769 user: test
769 user: test
770 date: Thu Jan 01 00:00:01 1970 +0000
770 date: Thu Jan 01 00:00:01 1970 +0000
771 summary: r1
771 summary: r1
772
772
773 log -p -l2 --color=always
773 log -p -l2 --color=always
774
774
775 $ hg --config extensions.color= --config color.mode=ansi \
775 $ hg --config extensions.color= --config color.mode=ansi \
776 > log -p -l2 --color=always
776 > log -p -l2 --color=always
777 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
777 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
778 tag: tip
778 tag: tip
779 user: test
779 user: test
780 date: Thu Jan 01 00:00:01 1970 +0000
780 date: Thu Jan 01 00:00:01 1970 +0000
781 summary: b1.1
781 summary: b1.1
782
782
783 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
783 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
784 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
784 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
785 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
785 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
786 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
786 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
787 b1
787 b1
788 \x1b[0;32m+postm\x1b[0m (esc)
788 \x1b[0;32m+postm\x1b[0m (esc)
789
789
790 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
790 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
791 parent: 3:e62f78d544b4
791 parent: 3:e62f78d544b4
792 parent: 4:ddb82e70d1a1
792 parent: 4:ddb82e70d1a1
793 user: test
793 user: test
794 date: Thu Jan 01 00:00:01 1970 +0000
794 date: Thu Jan 01 00:00:01 1970 +0000
795 summary: m12
795 summary: m12
796
796
797 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
797 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
798 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
798 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
799 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
799 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
800 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
800 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
801 \x1b[0;32m+b2\x1b[0m (esc)
801 \x1b[0;32m+b2\x1b[0m (esc)
802
802
803
803
804
804
805 log -r tip --stat
805 log -r tip --stat
806
806
807 $ hg log -r tip --stat
807 $ hg log -r tip --stat
808 changeset: 6:2404bbcab562
808 changeset: 6:2404bbcab562
809 tag: tip
809 tag: tip
810 user: test
810 user: test
811 date: Thu Jan 01 00:00:01 1970 +0000
811 date: Thu Jan 01 00:00:01 1970 +0000
812 summary: b1.1
812 summary: b1.1
813
813
814 b1 | 1 +
814 b1 | 1 +
815 1 files changed, 1 insertions(+), 0 deletions(-)
815 1 files changed, 1 insertions(+), 0 deletions(-)
816
816
817
817
818 $ cd ..
818 $ cd ..
819
819
820
820
821 User
821 User
822
822
823 $ hg init usertest
823 $ hg init usertest
824 $ cd usertest
824 $ cd usertest
825
825
826 $ echo a > a
826 $ echo a > a
827 $ hg ci -A -m "a" -u "User One <user1@example.org>"
827 $ hg ci -A -m "a" -u "User One <user1@example.org>"
828 adding a
828 adding a
829 $ echo b > b
829 $ echo b > b
830 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
830 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
831 adding b
831 adding b
832
832
833 $ hg log -u "User One <user1@example.org>"
833 $ hg log -u "User One <user1@example.org>"
834 changeset: 0:29a4c94f1924
834 changeset: 0:29a4c94f1924
835 user: User One <user1@example.org>
835 user: User One <user1@example.org>
836 date: Thu Jan 01 00:00:00 1970 +0000
836 date: Thu Jan 01 00:00:00 1970 +0000
837 summary: a
837 summary: a
838
838
839 $ hg log -u "user1" -u "user2"
839 $ hg log -u "user1" -u "user2"
840 changeset: 1:e834b5e69c0e
840 changeset: 1:e834b5e69c0e
841 tag: tip
841 tag: tip
842 user: User Two <user2@example.org>
842 user: User Two <user2@example.org>
843 date: Thu Jan 01 00:00:00 1970 +0000
843 date: Thu Jan 01 00:00:00 1970 +0000
844 summary: b
844 summary: b
845
845
846 changeset: 0:29a4c94f1924
846 changeset: 0:29a4c94f1924
847 user: User One <user1@example.org>
847 user: User One <user1@example.org>
848 date: Thu Jan 01 00:00:00 1970 +0000
848 date: Thu Jan 01 00:00:00 1970 +0000
849 summary: a
849 summary: a
850
850
851 $ hg log -u "user3"
851 $ hg log -u "user3"
852
852
853 $ cd ..
853 $ cd ..
854
854
855 $ hg init branches
855 $ hg init branches
856 $ cd branches
856 $ cd branches
857
857
858 $ echo a > a
858 $ echo a > a
859 $ hg ci -A -m "commit on default"
859 $ hg ci -A -m "commit on default"
860 adding a
860 adding a
861 $ hg branch test
861 $ hg branch test
862 marked working directory as branch test
862 marked working directory as branch test
863 (branches are permanent and global, did you want a bookmark?)
863 (branches are permanent and global, did you want a bookmark?)
864 $ echo b > b
864 $ echo b > b
865 $ hg ci -A -m "commit on test"
865 $ hg ci -A -m "commit on test"
866 adding b
866 adding b
867
867
868 $ hg up default
868 $ hg up default
869 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
869 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
870 $ echo c > c
870 $ echo c > c
871 $ hg ci -A -m "commit on default"
871 $ hg ci -A -m "commit on default"
872 adding c
872 adding c
873 $ hg up test
873 $ hg up test
874 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
874 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
875 $ echo c > c
875 $ echo c > c
876 $ hg ci -A -m "commit on test"
876 $ hg ci -A -m "commit on test"
877 adding c
877 adding c
878
878
879
879
880 log -b default
880 log -b default
881
881
882 $ hg log -b default
882 $ hg log -b default
883 changeset: 2:c3a4f03cc9a7
883 changeset: 2:c3a4f03cc9a7
884 parent: 0:24427303d56f
884 parent: 0:24427303d56f
885 user: test
885 user: test
886 date: Thu Jan 01 00:00:00 1970 +0000
886 date: Thu Jan 01 00:00:00 1970 +0000
887 summary: commit on default
887 summary: commit on default
888
888
889 changeset: 0:24427303d56f
889 changeset: 0:24427303d56f
890 user: test
890 user: test
891 date: Thu Jan 01 00:00:00 1970 +0000
891 date: Thu Jan 01 00:00:00 1970 +0000
892 summary: commit on default
892 summary: commit on default
893
893
894
894
895
895
896 log -b test
896 log -b test
897
897
898 $ hg log -b test
898 $ hg log -b test
899 changeset: 3:f5d8de11c2e2
899 changeset: 3:f5d8de11c2e2
900 branch: test
900 branch: test
901 tag: tip
901 tag: tip
902 parent: 1:d32277701ccb
902 parent: 1:d32277701ccb
903 user: test
903 user: test
904 date: Thu Jan 01 00:00:00 1970 +0000
904 date: Thu Jan 01 00:00:00 1970 +0000
905 summary: commit on test
905 summary: commit on test
906
906
907 changeset: 1:d32277701ccb
907 changeset: 1:d32277701ccb
908 branch: test
908 branch: test
909 user: test
909 user: test
910 date: Thu Jan 01 00:00:00 1970 +0000
910 date: Thu Jan 01 00:00:00 1970 +0000
911 summary: commit on test
911 summary: commit on test
912
912
913
913
914
914
915 log -b dummy
915 log -b dummy
916
916
917 $ hg log -b dummy
917 $ hg log -b dummy
918 abort: unknown revision 'dummy'!
918 abort: unknown revision 'dummy'!
919 [255]
919 [255]
920
920
921
921
922 log -b .
922 log -b .
923
923
924 $ hg log -b .
924 $ hg log -b .
925 changeset: 3:f5d8de11c2e2
925 changeset: 3:f5d8de11c2e2
926 branch: test
926 branch: test
927 tag: tip
927 tag: tip
928 parent: 1:d32277701ccb
928 parent: 1:d32277701ccb
929 user: test
929 user: test
930 date: Thu Jan 01 00:00:00 1970 +0000
930 date: Thu Jan 01 00:00:00 1970 +0000
931 summary: commit on test
931 summary: commit on test
932
932
933 changeset: 1:d32277701ccb
933 changeset: 1:d32277701ccb
934 branch: test
934 branch: test
935 user: test
935 user: test
936 date: Thu Jan 01 00:00:00 1970 +0000
936 date: Thu Jan 01 00:00:00 1970 +0000
937 summary: commit on test
937 summary: commit on test
938
938
939
939
940
940
941 log -b default -b test
941 log -b default -b test
942
942
943 $ hg log -b default -b test
943 $ hg log -b default -b test
944 changeset: 3:f5d8de11c2e2
944 changeset: 3:f5d8de11c2e2
945 branch: test
945 branch: test
946 tag: tip
946 tag: tip
947 parent: 1:d32277701ccb
947 parent: 1:d32277701ccb
948 user: test
948 user: test
949 date: Thu Jan 01 00:00:00 1970 +0000
949 date: Thu Jan 01 00:00:00 1970 +0000
950 summary: commit on test
950 summary: commit on test
951
951
952 changeset: 2:c3a4f03cc9a7
952 changeset: 2:c3a4f03cc9a7
953 parent: 0:24427303d56f
953 parent: 0:24427303d56f
954 user: test
954 user: test
955 date: Thu Jan 01 00:00:00 1970 +0000
955 date: Thu Jan 01 00:00:00 1970 +0000
956 summary: commit on default
956 summary: commit on default
957
957
958 changeset: 1:d32277701ccb
958 changeset: 1:d32277701ccb
959 branch: test
959 branch: test
960 user: test
960 user: test
961 date: Thu Jan 01 00:00:00 1970 +0000
961 date: Thu Jan 01 00:00:00 1970 +0000
962 summary: commit on test
962 summary: commit on test
963
963
964 changeset: 0:24427303d56f
964 changeset: 0:24427303d56f
965 user: test
965 user: test
966 date: Thu Jan 01 00:00:00 1970 +0000
966 date: Thu Jan 01 00:00:00 1970 +0000
967 summary: commit on default
967 summary: commit on default
968
968
969
969
970
970
971 log -b default -b .
971 log -b default -b .
972
972
973 $ hg log -b default -b .
973 $ hg log -b default -b .
974 changeset: 3:f5d8de11c2e2
974 changeset: 3:f5d8de11c2e2
975 branch: test
975 branch: test
976 tag: tip
976 tag: tip
977 parent: 1:d32277701ccb
977 parent: 1:d32277701ccb
978 user: test
978 user: test
979 date: Thu Jan 01 00:00:00 1970 +0000
979 date: Thu Jan 01 00:00:00 1970 +0000
980 summary: commit on test
980 summary: commit on test
981
981
982 changeset: 2:c3a4f03cc9a7
982 changeset: 2:c3a4f03cc9a7
983 parent: 0:24427303d56f
983 parent: 0:24427303d56f
984 user: test
984 user: test
985 date: Thu Jan 01 00:00:00 1970 +0000
985 date: Thu Jan 01 00:00:00 1970 +0000
986 summary: commit on default
986 summary: commit on default
987
987
988 changeset: 1:d32277701ccb
988 changeset: 1:d32277701ccb
989 branch: test
989 branch: test
990 user: test
990 user: test
991 date: Thu Jan 01 00:00:00 1970 +0000
991 date: Thu Jan 01 00:00:00 1970 +0000
992 summary: commit on test
992 summary: commit on test
993
993
994 changeset: 0:24427303d56f
994 changeset: 0:24427303d56f
995 user: test
995 user: test
996 date: Thu Jan 01 00:00:00 1970 +0000
996 date: Thu Jan 01 00:00:00 1970 +0000
997 summary: commit on default
997 summary: commit on default
998
998
999
999
1000
1000
1001 log -b . -b test
1001 log -b . -b test
1002
1002
1003 $ hg log -b . -b test
1003 $ hg log -b . -b test
1004 changeset: 3:f5d8de11c2e2
1004 changeset: 3:f5d8de11c2e2
1005 branch: test
1005 branch: test
1006 tag: tip
1006 tag: tip
1007 parent: 1:d32277701ccb
1007 parent: 1:d32277701ccb
1008 user: test
1008 user: test
1009 date: Thu Jan 01 00:00:00 1970 +0000
1009 date: Thu Jan 01 00:00:00 1970 +0000
1010 summary: commit on test
1010 summary: commit on test
1011
1011
1012 changeset: 1:d32277701ccb
1012 changeset: 1:d32277701ccb
1013 branch: test
1013 branch: test
1014 user: test
1014 user: test
1015 date: Thu Jan 01 00:00:00 1970 +0000
1015 date: Thu Jan 01 00:00:00 1970 +0000
1016 summary: commit on test
1016 summary: commit on test
1017
1017
1018
1018
1019
1019
1020 log -b 2
1020 log -b 2
1021
1021
1022 $ hg log -b 2
1022 $ hg log -b 2
1023 changeset: 2:c3a4f03cc9a7
1023 changeset: 2:c3a4f03cc9a7
1024 parent: 0:24427303d56f
1024 parent: 0:24427303d56f
1025 user: test
1025 user: test
1026 date: Thu Jan 01 00:00:00 1970 +0000
1026 date: Thu Jan 01 00:00:00 1970 +0000
1027 summary: commit on default
1027 summary: commit on default
1028
1028
1029 changeset: 0:24427303d56f
1029 changeset: 0:24427303d56f
1030 user: test
1030 user: test
1031 date: Thu Jan 01 00:00:00 1970 +0000
1031 date: Thu Jan 01 00:00:00 1970 +0000
1032 summary: commit on default
1032 summary: commit on default
1033
1033
1034
1034
1035
1035
1036 log -p --cwd dir (in subdir)
1036 log -p --cwd dir (in subdir)
1037
1037
1038 $ mkdir dir
1038 $ mkdir dir
1039 $ hg log -p --cwd dir
1039 $ hg log -p --cwd dir
1040 changeset: 3:f5d8de11c2e2
1040 changeset: 3:f5d8de11c2e2
1041 branch: test
1041 branch: test
1042 tag: tip
1042 tag: tip
1043 parent: 1:d32277701ccb
1043 parent: 1:d32277701ccb
1044 user: test
1044 user: test
1045 date: Thu Jan 01 00:00:00 1970 +0000
1045 date: Thu Jan 01 00:00:00 1970 +0000
1046 summary: commit on test
1046 summary: commit on test
1047
1047
1048 diff -r d32277701ccb -r f5d8de11c2e2 c
1048 diff -r d32277701ccb -r f5d8de11c2e2 c
1049 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1049 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1050 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1050 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1051 @@ -0,0 +1,1 @@
1051 @@ -0,0 +1,1 @@
1052 +c
1052 +c
1053
1053
1054 changeset: 2:c3a4f03cc9a7
1054 changeset: 2:c3a4f03cc9a7
1055 parent: 0:24427303d56f
1055 parent: 0:24427303d56f
1056 user: test
1056 user: test
1057 date: Thu Jan 01 00:00:00 1970 +0000
1057 date: Thu Jan 01 00:00:00 1970 +0000
1058 summary: commit on default
1058 summary: commit on default
1059
1059
1060 diff -r 24427303d56f -r c3a4f03cc9a7 c
1060 diff -r 24427303d56f -r c3a4f03cc9a7 c
1061 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1061 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1062 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1062 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1063 @@ -0,0 +1,1 @@
1063 @@ -0,0 +1,1 @@
1064 +c
1064 +c
1065
1065
1066 changeset: 1:d32277701ccb
1066 changeset: 1:d32277701ccb
1067 branch: test
1067 branch: test
1068 user: test
1068 user: test
1069 date: Thu Jan 01 00:00:00 1970 +0000
1069 date: Thu Jan 01 00:00:00 1970 +0000
1070 summary: commit on test
1070 summary: commit on test
1071
1071
1072 diff -r 24427303d56f -r d32277701ccb b
1072 diff -r 24427303d56f -r d32277701ccb b
1073 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1073 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1074 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1074 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1075 @@ -0,0 +1,1 @@
1075 @@ -0,0 +1,1 @@
1076 +b
1076 +b
1077
1077
1078 changeset: 0:24427303d56f
1078 changeset: 0:24427303d56f
1079 user: test
1079 user: test
1080 date: Thu Jan 01 00:00:00 1970 +0000
1080 date: Thu Jan 01 00:00:00 1970 +0000
1081 summary: commit on default
1081 summary: commit on default
1082
1082
1083 diff -r 000000000000 -r 24427303d56f a
1083 diff -r 000000000000 -r 24427303d56f a
1084 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1084 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1085 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1085 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1086 @@ -0,0 +1,1 @@
1086 @@ -0,0 +1,1 @@
1087 +a
1087 +a
1088
1088
1089
1089
1090
1090
1091 log -p -R repo
1091 log -p -R repo
1092
1092
1093 $ cd dir
1093 $ cd dir
1094 $ hg log -p -R .. ../a
1094 $ hg log -p -R .. ../a
1095 changeset: 0:24427303d56f
1095 changeset: 0:24427303d56f
1096 user: test
1096 user: test
1097 date: Thu Jan 01 00:00:00 1970 +0000
1097 date: Thu Jan 01 00:00:00 1970 +0000
1098 summary: commit on default
1098 summary: commit on default
1099
1099
1100 diff -r 000000000000 -r 24427303d56f a
1100 diff -r 000000000000 -r 24427303d56f a
1101 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1101 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1102 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1102 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1103 @@ -0,0 +1,1 @@
1103 @@ -0,0 +1,1 @@
1104 +a
1104 +a
1105
1105
1106
1106
1107 $ cd ../..
1107 $ cd ../..
1108
1108
1109 $ hg init follow2
1109 $ hg init follow2
1110 $ cd follow2
1110 $ cd follow2
1111
1111
1112 # Build the following history:
1112 # Build the following history:
1113 # tip - o - x - o - x - x
1113 # tip - o - x - o - x - x
1114 # \ /
1114 # \ /
1115 # o - o - o - x
1115 # o - o - o - x
1116 # \ /
1116 # \ /
1117 # o
1117 # o
1118 #
1118 #
1119 # Where "o" is a revision containing "foo" and
1119 # Where "o" is a revision containing "foo" and
1120 # "x" is a revision without "foo"
1120 # "x" is a revision without "foo"
1121
1121
1122 $ touch init
1122 $ touch init
1123 $ hg ci -A -m "init, unrelated"
1123 $ hg ci -A -m "init, unrelated"
1124 adding init
1124 adding init
1125 $ echo 'foo' > init
1125 $ echo 'foo' > init
1126 $ hg ci -m "change, unrelated"
1126 $ hg ci -m "change, unrelated"
1127 $ echo 'foo' > foo
1127 $ echo 'foo' > foo
1128 $ hg ci -A -m "add unrelated old foo"
1128 $ hg ci -A -m "add unrelated old foo"
1129 adding foo
1129 adding foo
1130 $ hg rm foo
1130 $ hg rm foo
1131 $ hg ci -m "delete foo, unrelated"
1131 $ hg ci -m "delete foo, unrelated"
1132 $ echo 'related' > foo
1132 $ echo 'related' > foo
1133 $ hg ci -A -m "add foo, related"
1133 $ hg ci -A -m "add foo, related"
1134 adding foo
1134 adding foo
1135
1135
1136 $ hg up 0
1136 $ hg up 0
1137 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1137 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1138 $ touch branch
1138 $ touch branch
1139 $ hg ci -A -m "first branch, unrelated"
1139 $ hg ci -A -m "first branch, unrelated"
1140 adding branch
1140 adding branch
1141 created new head
1141 created new head
1142 $ touch foo
1142 $ touch foo
1143 $ hg ci -A -m "create foo, related"
1143 $ hg ci -A -m "create foo, related"
1144 adding foo
1144 adding foo
1145 $ echo 'change' > foo
1145 $ echo 'change' > foo
1146 $ hg ci -m "change foo, related"
1146 $ hg ci -m "change foo, related"
1147
1147
1148 $ hg up 6
1148 $ hg up 6
1149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1150 $ echo 'change foo in branch' > foo
1150 $ echo 'change foo in branch' > foo
1151 $ hg ci -m "change foo in branch, related"
1151 $ hg ci -m "change foo in branch, related"
1152 created new head
1152 created new head
1153 $ hg merge 7
1153 $ hg merge 7
1154 merging foo
1154 merging foo
1155 warning: conflicts during merge.
1155 warning: conflicts during merge.
1156 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1156 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1157 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1157 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1158 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1158 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1159 [1]
1159 [1]
1160 $ echo 'merge 1' > foo
1160 $ echo 'merge 1' > foo
1161 $ hg resolve -m foo
1161 $ hg resolve -m foo
1162 (no more unresolved files)
1162 (no more unresolved files)
1163 $ hg ci -m "First merge, related"
1163 $ hg ci -m "First merge, related"
1164
1164
1165 $ hg merge 4
1165 $ hg merge 4
1166 merging foo
1166 merging foo
1167 warning: conflicts during merge.
1167 warning: conflicts during merge.
1168 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1168 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
1169 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1169 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1170 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1170 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1171 [1]
1171 [1]
1172 $ echo 'merge 2' > foo
1172 $ echo 'merge 2' > foo
1173 $ hg resolve -m foo
1173 $ hg resolve -m foo
1174 (no more unresolved files)
1174 (no more unresolved files)
1175 $ hg ci -m "Last merge, related"
1175 $ hg ci -m "Last merge, related"
1176
1176
1177 $ hg log --graph
1177 $ hg log --graph
1178 @ changeset: 10:4dae8563d2c5
1178 @ changeset: 10:4dae8563d2c5
1179 |\ tag: tip
1179 |\ tag: tip
1180 | | parent: 9:7b35701b003e
1180 | | parent: 9:7b35701b003e
1181 | | parent: 4:88176d361b69
1181 | | parent: 4:88176d361b69
1182 | | user: test
1182 | | user: test
1183 | | date: Thu Jan 01 00:00:00 1970 +0000
1183 | | date: Thu Jan 01 00:00:00 1970 +0000
1184 | | summary: Last merge, related
1184 | | summary: Last merge, related
1185 | |
1185 | |
1186 | o changeset: 9:7b35701b003e
1186 | o changeset: 9:7b35701b003e
1187 | |\ parent: 8:e5416ad8a855
1187 | |\ parent: 8:e5416ad8a855
1188 | | | parent: 7:87fe3144dcfa
1188 | | | parent: 7:87fe3144dcfa
1189 | | | user: test
1189 | | | user: test
1190 | | | date: Thu Jan 01 00:00:00 1970 +0000
1190 | | | date: Thu Jan 01 00:00:00 1970 +0000
1191 | | | summary: First merge, related
1191 | | | summary: First merge, related
1192 | | |
1192 | | |
1193 | | o changeset: 8:e5416ad8a855
1193 | | o changeset: 8:e5416ad8a855
1194 | | | parent: 6:dc6c325fe5ee
1194 | | | parent: 6:dc6c325fe5ee
1195 | | | user: test
1195 | | | user: test
1196 | | | date: Thu Jan 01 00:00:00 1970 +0000
1196 | | | date: Thu Jan 01 00:00:00 1970 +0000
1197 | | | summary: change foo in branch, related
1197 | | | summary: change foo in branch, related
1198 | | |
1198 | | |
1199 | o | changeset: 7:87fe3144dcfa
1199 | o | changeset: 7:87fe3144dcfa
1200 | |/ user: test
1200 | |/ user: test
1201 | | date: Thu Jan 01 00:00:00 1970 +0000
1201 | | date: Thu Jan 01 00:00:00 1970 +0000
1202 | | summary: change foo, related
1202 | | summary: change foo, related
1203 | |
1203 | |
1204 | o changeset: 6:dc6c325fe5ee
1204 | o changeset: 6:dc6c325fe5ee
1205 | | user: test
1205 | | user: test
1206 | | date: Thu Jan 01 00:00:00 1970 +0000
1206 | | date: Thu Jan 01 00:00:00 1970 +0000
1207 | | summary: create foo, related
1207 | | summary: create foo, related
1208 | |
1208 | |
1209 | o changeset: 5:73db34516eb9
1209 | o changeset: 5:73db34516eb9
1210 | | parent: 0:e87515fd044a
1210 | | parent: 0:e87515fd044a
1211 | | user: test
1211 | | user: test
1212 | | date: Thu Jan 01 00:00:00 1970 +0000
1212 | | date: Thu Jan 01 00:00:00 1970 +0000
1213 | | summary: first branch, unrelated
1213 | | summary: first branch, unrelated
1214 | |
1214 | |
1215 o | changeset: 4:88176d361b69
1215 o | changeset: 4:88176d361b69
1216 | | user: test
1216 | | user: test
1217 | | date: Thu Jan 01 00:00:00 1970 +0000
1217 | | date: Thu Jan 01 00:00:00 1970 +0000
1218 | | summary: add foo, related
1218 | | summary: add foo, related
1219 | |
1219 | |
1220 o | changeset: 3:dd78ae4afb56
1220 o | changeset: 3:dd78ae4afb56
1221 | | user: test
1221 | | user: test
1222 | | date: Thu Jan 01 00:00:00 1970 +0000
1222 | | date: Thu Jan 01 00:00:00 1970 +0000
1223 | | summary: delete foo, unrelated
1223 | | summary: delete foo, unrelated
1224 | |
1224 | |
1225 o | changeset: 2:c4c64aedf0f7
1225 o | changeset: 2:c4c64aedf0f7
1226 | | user: test
1226 | | user: test
1227 | | date: Thu Jan 01 00:00:00 1970 +0000
1227 | | date: Thu Jan 01 00:00:00 1970 +0000
1228 | | summary: add unrelated old foo
1228 | | summary: add unrelated old foo
1229 | |
1229 | |
1230 o | changeset: 1:e5faa7440653
1230 o | changeset: 1:e5faa7440653
1231 |/ user: test
1231 |/ user: test
1232 | date: Thu Jan 01 00:00:00 1970 +0000
1232 | date: Thu Jan 01 00:00:00 1970 +0000
1233 | summary: change, unrelated
1233 | summary: change, unrelated
1234 |
1234 |
1235 o changeset: 0:e87515fd044a
1235 o changeset: 0:e87515fd044a
1236 user: test
1236 user: test
1237 date: Thu Jan 01 00:00:00 1970 +0000
1237 date: Thu Jan 01 00:00:00 1970 +0000
1238 summary: init, unrelated
1238 summary: init, unrelated
1239
1239
1240
1240
1241 $ hg --traceback log -f foo
1241 $ hg --traceback log -f foo
1242 changeset: 10:4dae8563d2c5
1242 changeset: 10:4dae8563d2c5
1243 tag: tip
1243 tag: tip
1244 parent: 9:7b35701b003e
1244 parent: 9:7b35701b003e
1245 parent: 4:88176d361b69
1245 parent: 4:88176d361b69
1246 user: test
1246 user: test
1247 date: Thu Jan 01 00:00:00 1970 +0000
1247 date: Thu Jan 01 00:00:00 1970 +0000
1248 summary: Last merge, related
1248 summary: Last merge, related
1249
1249
1250 changeset: 9:7b35701b003e
1250 changeset: 9:7b35701b003e
1251 parent: 8:e5416ad8a855
1251 parent: 8:e5416ad8a855
1252 parent: 7:87fe3144dcfa
1252 parent: 7:87fe3144dcfa
1253 user: test
1253 user: test
1254 date: Thu Jan 01 00:00:00 1970 +0000
1254 date: Thu Jan 01 00:00:00 1970 +0000
1255 summary: First merge, related
1255 summary: First merge, related
1256
1256
1257 changeset: 8:e5416ad8a855
1257 changeset: 8:e5416ad8a855
1258 parent: 6:dc6c325fe5ee
1258 parent: 6:dc6c325fe5ee
1259 user: test
1259 user: test
1260 date: Thu Jan 01 00:00:00 1970 +0000
1260 date: Thu Jan 01 00:00:00 1970 +0000
1261 summary: change foo in branch, related
1261 summary: change foo in branch, related
1262
1262
1263 changeset: 7:87fe3144dcfa
1263 changeset: 7:87fe3144dcfa
1264 user: test
1264 user: test
1265 date: Thu Jan 01 00:00:00 1970 +0000
1265 date: Thu Jan 01 00:00:00 1970 +0000
1266 summary: change foo, related
1266 summary: change foo, related
1267
1267
1268 changeset: 6:dc6c325fe5ee
1268 changeset: 6:dc6c325fe5ee
1269 user: test
1269 user: test
1270 date: Thu Jan 01 00:00:00 1970 +0000
1270 date: Thu Jan 01 00:00:00 1970 +0000
1271 summary: create foo, related
1271 summary: create foo, related
1272
1272
1273 changeset: 4:88176d361b69
1273 changeset: 4:88176d361b69
1274 user: test
1274 user: test
1275 date: Thu Jan 01 00:00:00 1970 +0000
1275 date: Thu Jan 01 00:00:00 1970 +0000
1276 summary: add foo, related
1276 summary: add foo, related
1277
1277
1278
1278
1279 Also check when maxrev < lastrevfilelog
1279 Also check when maxrev < lastrevfilelog
1280
1280
1281 $ hg --traceback log -f -r4 foo
1281 $ hg --traceback log -f -r4 foo
1282 changeset: 4:88176d361b69
1282 changeset: 4:88176d361b69
1283 user: test
1283 user: test
1284 date: Thu Jan 01 00:00:00 1970 +0000
1284 date: Thu Jan 01 00:00:00 1970 +0000
1285 summary: add foo, related
1285 summary: add foo, related
1286
1286
1287 $ cd ..
1287 $ cd ..
1288
1288
1289 Issue2383: hg log showing _less_ differences than hg diff
1289 Issue2383: hg log showing _less_ differences than hg diff
1290
1290
1291 $ hg init issue2383
1291 $ hg init issue2383
1292 $ cd issue2383
1292 $ cd issue2383
1293
1293
1294 Create a test repo:
1294 Create a test repo:
1295
1295
1296 $ echo a > a
1296 $ echo a > a
1297 $ hg ci -Am0
1297 $ hg ci -Am0
1298 adding a
1298 adding a
1299 $ echo b > b
1299 $ echo b > b
1300 $ hg ci -Am1
1300 $ hg ci -Am1
1301 adding b
1301 adding b
1302 $ hg co 0
1302 $ hg co 0
1303 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1303 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1304 $ echo b > a
1304 $ echo b > a
1305 $ hg ci -m2
1305 $ hg ci -m2
1306 created new head
1306 created new head
1307
1307
1308 Merge:
1308 Merge:
1309
1309
1310 $ hg merge
1310 $ hg merge
1311 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1311 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1312 (branch merge, don't forget to commit)
1312 (branch merge, don't forget to commit)
1313
1313
1314 Make sure there's a file listed in the merge to trigger the bug:
1314 Make sure there's a file listed in the merge to trigger the bug:
1315
1315
1316 $ echo c > a
1316 $ echo c > a
1317 $ hg ci -m3
1317 $ hg ci -m3
1318
1318
1319 Two files shown here in diff:
1319 Two files shown here in diff:
1320
1320
1321 $ hg diff --rev 2:3
1321 $ hg diff --rev 2:3
1322 diff -r b09be438c43a -r 8e07aafe1edc a
1322 diff -r b09be438c43a -r 8e07aafe1edc a
1323 --- a/a Thu Jan 01 00:00:00 1970 +0000
1323 --- a/a Thu Jan 01 00:00:00 1970 +0000
1324 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1324 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1325 @@ -1,1 +1,1 @@
1325 @@ -1,1 +1,1 @@
1326 -b
1326 -b
1327 +c
1327 +c
1328 diff -r b09be438c43a -r 8e07aafe1edc b
1328 diff -r b09be438c43a -r 8e07aafe1edc b
1329 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1329 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1330 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1330 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1331 @@ -0,0 +1,1 @@
1331 @@ -0,0 +1,1 @@
1332 +b
1332 +b
1333
1333
1334 Diff here should be the same:
1334 Diff here should be the same:
1335
1335
1336 $ hg log -vpr 3
1336 $ hg log -vpr 3
1337 changeset: 3:8e07aafe1edc
1337 changeset: 3:8e07aafe1edc
1338 tag: tip
1338 tag: tip
1339 parent: 2:b09be438c43a
1339 parent: 2:b09be438c43a
1340 parent: 1:925d80f479bb
1340 parent: 1:925d80f479bb
1341 user: test
1341 user: test
1342 date: Thu Jan 01 00:00:00 1970 +0000
1342 date: Thu Jan 01 00:00:00 1970 +0000
1343 files: a
1343 files: a
1344 description:
1344 description:
1345 3
1345 3
1346
1346
1347
1347
1348 diff -r b09be438c43a -r 8e07aafe1edc a
1348 diff -r b09be438c43a -r 8e07aafe1edc a
1349 --- a/a Thu Jan 01 00:00:00 1970 +0000
1349 --- a/a Thu Jan 01 00:00:00 1970 +0000
1350 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1350 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1351 @@ -1,1 +1,1 @@
1351 @@ -1,1 +1,1 @@
1352 -b
1352 -b
1353 +c
1353 +c
1354 diff -r b09be438c43a -r 8e07aafe1edc b
1354 diff -r b09be438c43a -r 8e07aafe1edc b
1355 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1355 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1356 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1356 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1357 @@ -0,0 +1,1 @@
1357 @@ -0,0 +1,1 @@
1358 +b
1358 +b
1359
1359
1360 $ cd ..
1360 $ cd ..
1361
1361
1362 'hg log -r rev fn' when last(filelog(fn)) != rev
1362 'hg log -r rev fn' when last(filelog(fn)) != rev
1363
1363
1364 $ hg init simplelog
1364 $ hg init simplelog
1365 $ cd simplelog
1365 $ cd simplelog
1366 $ echo f > a
1366 $ echo f > a
1367 $ hg ci -Am'a' -d '0 0'
1367 $ hg ci -Am'a' -d '0 0'
1368 adding a
1368 adding a
1369 $ echo f >> a
1369 $ echo f >> a
1370 $ hg ci -Am'a bis' -d '1 0'
1370 $ hg ci -Am'a bis' -d '1 0'
1371
1371
1372 $ hg log -r0 a
1372 $ hg log -r0 a
1373 changeset: 0:9f758d63dcde
1373 changeset: 0:9f758d63dcde
1374 user: test
1374 user: test
1375 date: Thu Jan 01 00:00:00 1970 +0000
1375 date: Thu Jan 01 00:00:00 1970 +0000
1376 summary: a
1376 summary: a
1377
1377
1378 enable obsolete to test hidden feature
1378 enable obsolete to test hidden feature
1379
1379
1380 $ cat >> $HGRCPATH << EOF
1380 $ cat >> $HGRCPATH << EOF
1381 > [experimental]
1381 > [experimental]
1382 > evolution=createmarkers
1382 > evolution=createmarkers
1383 > EOF
1383 > EOF
1384
1384
1385 $ hg log --template='{rev}:{node}\n'
1385 $ hg log --template='{rev}:{node}\n'
1386 1:a765632148dc55d38c35c4f247c618701886cb2f
1386 1:a765632148dc55d38c35c4f247c618701886cb2f
1387 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1387 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1388 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1388 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1389 $ hg up null -q
1389 $ hg up null -q
1390 $ hg log --template='{rev}:{node}\n'
1390 $ hg log --template='{rev}:{node}\n'
1391 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1391 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1392 $ hg log --template='{rev}:{node}\n' --hidden
1392 $ hg log --template='{rev}:{node}\n' --hidden
1393 1:a765632148dc55d38c35c4f247c618701886cb2f
1393 1:a765632148dc55d38c35c4f247c618701886cb2f
1394 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1394 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1395 $ hg log -r a
1395 $ hg log -r a
1396 abort: hidden revision 'a'!
1396 abort: hidden revision 'a'!
1397 (use --hidden to access hidden revisions)
1397 (use --hidden to access hidden revisions)
1398 [255]
1398 [255]
1399
1399
1400 test that parent prevent a changeset to be hidden
1400 test that parent prevent a changeset to be hidden
1401
1401
1402 $ hg up 1 -q --hidden
1402 $ hg up 1 -q --hidden
1403 $ hg log --template='{rev}:{node}\n'
1403 $ hg log --template='{rev}:{node}\n'
1404 1:a765632148dc55d38c35c4f247c618701886cb2f
1404 1:a765632148dc55d38c35c4f247c618701886cb2f
1405 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1405 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1406
1406
1407 test that second parent prevent a changeset to be hidden too
1407 test that second parent prevent a changeset to be hidden too
1408
1408
1409 $ hg debugsetparents 0 1 # nothing suitable to merge here
1409 $ hg debugsetparents 0 1 # nothing suitable to merge here
1410 $ hg log --template='{rev}:{node}\n'
1410 $ hg log --template='{rev}:{node}\n'
1411 1:a765632148dc55d38c35c4f247c618701886cb2f
1411 1:a765632148dc55d38c35c4f247c618701886cb2f
1412 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1412 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1413 $ hg debugsetparents 1
1413 $ hg debugsetparents 1
1414 $ hg up -q null
1414 $ hg up -q null
1415
1415
1416 bookmarks prevent a changeset being hidden
1416 bookmarks prevent a changeset being hidden
1417
1417
1418 $ hg bookmark --hidden -r 1 X
1418 $ hg bookmark --hidden -r 1 X
1419 $ hg log --template '{rev}:{node}\n'
1419 $ hg log --template '{rev}:{node}\n'
1420 1:a765632148dc55d38c35c4f247c618701886cb2f
1420 1:a765632148dc55d38c35c4f247c618701886cb2f
1421 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1421 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1422 $ hg bookmark -d X
1422 $ hg bookmark -d X
1423
1423
1424 divergent bookmarks are not hidden
1424 divergent bookmarks are not hidden
1425
1425
1426 $ hg bookmark --hidden -r 1 X@foo
1426 $ hg bookmark --hidden -r 1 X@foo
1427 $ hg log --template '{rev}:{node}\n'
1427 $ hg log --template '{rev}:{node}\n'
1428 1:a765632148dc55d38c35c4f247c618701886cb2f
1428 1:a765632148dc55d38c35c4f247c618701886cb2f
1429 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1429 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1430
1430
1431 clear extensions configuration
1431 clear extensions configuration
1432 $ echo '[extensions]' >> $HGRCPATH
1432 $ echo '[extensions]' >> $HGRCPATH
1433 $ echo "obs=!" >> $HGRCPATH
1433 $ echo "obs=!" >> $HGRCPATH
1434 $ cd ..
1434 $ cd ..
1435
1435
1436 test -u/-k for problematic encoding
1436 test -u/-k for problematic encoding
1437 # unicode: cp932:
1437 # unicode: cp932:
1438 # u30A2 0x83 0x41(= 'A')
1438 # u30A2 0x83 0x41(= 'A')
1439 # u30C2 0x83 0x61(= 'a')
1439 # u30C2 0x83 0x61(= 'a')
1440
1440
1441 $ hg init problematicencoding
1441 $ hg init problematicencoding
1442 $ cd problematicencoding
1442 $ cd problematicencoding
1443
1443
1444 $ python > setup.sh <<EOF
1444 $ python > setup.sh <<EOF
1445 > print u'''
1445 > print u'''
1446 > echo a > text
1446 > echo a > text
1447 > hg add text
1447 > hg add text
1448 > hg --encoding utf-8 commit -u '\u30A2' -m none
1448 > hg --encoding utf-8 commit -u '\u30A2' -m none
1449 > echo b > text
1449 > echo b > text
1450 > hg --encoding utf-8 commit -u '\u30C2' -m none
1450 > hg --encoding utf-8 commit -u '\u30C2' -m none
1451 > echo c > text
1451 > echo c > text
1452 > hg --encoding utf-8 commit -u none -m '\u30A2'
1452 > hg --encoding utf-8 commit -u none -m '\u30A2'
1453 > echo d > text
1453 > echo d > text
1454 > hg --encoding utf-8 commit -u none -m '\u30C2'
1454 > hg --encoding utf-8 commit -u none -m '\u30C2'
1455 > '''.encode('utf-8')
1455 > '''.encode('utf-8')
1456 > EOF
1456 > EOF
1457 $ sh < setup.sh
1457 $ sh < setup.sh
1458
1458
1459 test in problematic encoding
1459 test in problematic encoding
1460 $ python > test.sh <<EOF
1460 $ python > test.sh <<EOF
1461 > print u'''
1461 > print u'''
1462 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
1462 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
1463 > echo ====
1463 > echo ====
1464 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
1464 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
1465 > echo ====
1465 > echo ====
1466 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
1466 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
1467 > echo ====
1467 > echo ====
1468 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
1468 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
1469 > '''.encode('cp932')
1469 > '''.encode('cp932')
1470 > EOF
1470 > EOF
1471 $ sh < test.sh
1471 $ sh < test.sh
1472 0
1472 0
1473 ====
1473 ====
1474 1
1474 1
1475 ====
1475 ====
1476 2
1476 2
1477 0
1477 0
1478 ====
1478 ====
1479 3
1479 3
1480 1
1480 1
1481
1481
1482 $ cd ..
1482 $ cd ..
1483
1483
1484 test hg log on non-existent files and on directories
1484 test hg log on non-existent files and on directories
1485 $ hg init issue1340
1485 $ hg init issue1340
1486 $ cd issue1340
1486 $ cd issue1340
1487 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
1487 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
1488 $ echo 1 > d1/f1
1488 $ echo 1 > d1/f1
1489 $ echo 1 > D2/f1
1489 $ echo 1 > D2/f1
1490 $ echo 1 > D3.i/f1
1490 $ echo 1 > D3.i/f1
1491 $ echo 1 > d4.hg/f1
1491 $ echo 1 > d4.hg/f1
1492 $ echo 1 > d5.d/f1
1492 $ echo 1 > d5.d/f1
1493 $ echo 1 > .d6/f1
1493 $ echo 1 > .d6/f1
1494 $ hg -q add .
1494 $ hg -q add .
1495 $ hg commit -m "a bunch of weird directories"
1495 $ hg commit -m "a bunch of weird directories"
1496 $ hg log -l1 d1/f1 | grep changeset
1496 $ hg log -l1 d1/f1 | grep changeset
1497 changeset: 0:65624cd9070a
1497 changeset: 0:65624cd9070a
1498 $ hg log -l1 f1
1498 $ hg log -l1 f1
1499 $ hg log -l1 . | grep changeset
1499 $ hg log -l1 . | grep changeset
1500 changeset: 0:65624cd9070a
1500 changeset: 0:65624cd9070a
1501 $ hg log -l1 ./ | grep changeset
1501 $ hg log -l1 ./ | grep changeset
1502 changeset: 0:65624cd9070a
1502 changeset: 0:65624cd9070a
1503 $ hg log -l1 d1 | grep changeset
1503 $ hg log -l1 d1 | grep changeset
1504 changeset: 0:65624cd9070a
1504 changeset: 0:65624cd9070a
1505 $ hg log -l1 D2 | grep changeset
1505 $ hg log -l1 D2 | grep changeset
1506 changeset: 0:65624cd9070a
1506 changeset: 0:65624cd9070a
1507 $ hg log -l1 D2/f1 | grep changeset
1507 $ hg log -l1 D2/f1 | grep changeset
1508 changeset: 0:65624cd9070a
1508 changeset: 0:65624cd9070a
1509 $ hg log -l1 D3.i | grep changeset
1509 $ hg log -l1 D3.i | grep changeset
1510 changeset: 0:65624cd9070a
1510 changeset: 0:65624cd9070a
1511 $ hg log -l1 D3.i/f1 | grep changeset
1511 $ hg log -l1 D3.i/f1 | grep changeset
1512 changeset: 0:65624cd9070a
1512 changeset: 0:65624cd9070a
1513 $ hg log -l1 d4.hg | grep changeset
1513 $ hg log -l1 d4.hg | grep changeset
1514 changeset: 0:65624cd9070a
1514 changeset: 0:65624cd9070a
1515 $ hg log -l1 d4.hg/f1 | grep changeset
1515 $ hg log -l1 d4.hg/f1 | grep changeset
1516 changeset: 0:65624cd9070a
1516 changeset: 0:65624cd9070a
1517 $ hg log -l1 d5.d | grep changeset
1517 $ hg log -l1 d5.d | grep changeset
1518 changeset: 0:65624cd9070a
1518 changeset: 0:65624cd9070a
1519 $ hg log -l1 d5.d/f1 | grep changeset
1519 $ hg log -l1 d5.d/f1 | grep changeset
1520 changeset: 0:65624cd9070a
1520 changeset: 0:65624cd9070a
1521 $ hg log -l1 .d6 | grep changeset
1521 $ hg log -l1 .d6 | grep changeset
1522 changeset: 0:65624cd9070a
1522 changeset: 0:65624cd9070a
1523 $ hg log -l1 .d6/f1 | grep changeset
1523 $ hg log -l1 .d6/f1 | grep changeset
1524 changeset: 0:65624cd9070a
1524 changeset: 0:65624cd9070a
1525
1525
1526 issue3772: hg log -r :null showing revision 0 as well
1526 issue3772: hg log -r :null showing revision 0 as well
1527
1527
1528 $ hg log -r :null
1528 $ hg log -r :null
1529 changeset: 0:65624cd9070a
1529 changeset: 0:65624cd9070a
1530 tag: tip
1530 tag: tip
1531 user: test
1531 user: test
1532 date: Thu Jan 01 00:00:00 1970 +0000
1532 date: Thu Jan 01 00:00:00 1970 +0000
1533 summary: a bunch of weird directories
1533 summary: a bunch of weird directories
1534
1534
1535 changeset: -1:000000000000
1535 changeset: -1:000000000000
1536 user:
1536 user:
1537 date: Thu Jan 01 00:00:00 1970 +0000
1537 date: Thu Jan 01 00:00:00 1970 +0000
1538
1538
1539 $ hg log -r null:null
1539 $ hg log -r null:null
1540 changeset: -1:000000000000
1540 changeset: -1:000000000000
1541 user:
1541 user:
1542 date: Thu Jan 01 00:00:00 1970 +0000
1542 date: Thu Jan 01 00:00:00 1970 +0000
1543
1543
1544
1544
1545 $ cd ..
1545 $ cd ..
1546
1546
1547 hg log -f dir across branches
1547 hg log -f dir across branches
1548
1548
1549 $ hg init acrossbranches
1549 $ hg init acrossbranches
1550 $ cd acrossbranches
1550 $ cd acrossbranches
1551 $ mkdir d
1551 $ mkdir d
1552 $ echo a > d/a && hg ci -Aqm a
1552 $ echo a > d/a && hg ci -Aqm a
1553 $ echo b > d/a && hg ci -Aqm b
1553 $ echo b > d/a && hg ci -Aqm b
1554 $ hg up -q 0
1554 $ hg up -q 0
1555 $ echo b > d/a && hg ci -Aqm c
1555 $ echo b > d/a && hg ci -Aqm c
1556 $ hg log -f d -T '{desc}' -G
1556 $ hg log -f d -T '{desc}' -G
1557 @ c
1557 @ c
1558 |
1558 |
1559 o a
1559 o a
1560
1560
1561 $ hg log -f d/a -T '{desc}' -G
1561 $ hg log -f d/a -T '{desc}' -G
1562 o b
1562 o b
1563 |
1563 |
1564 o a
1564 o a
1565
1565
1566 $ cd ..
1566 $ cd ..
1567
1568 hg log -f with linkrev pointing to another branch
1569 -------------------------------------------------
1570
1571 create history with a filerev whose linkrev points to another branch
1572
1573 $ hg init branchedlinkrev
1574 $ cd branchedlinkrev
1575 $ echo 1 > a
1576 $ hg commit -Am 'content1'
1577 adding a
1578 $ echo 2 > a
1579 $ hg commit -m 'content2'
1580 $ hg up --rev 'desc(content1)'
1581 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1582 $ echo unrelated > unrelated
1583 $ hg commit -Am 'unrelated'
1584 adding unrelated
1585 created new head
1586 $ hg graft -r 'desc(content2)'
1587 grafting 1:2294ae80ad84 "content2"
1588 $ echo 3 > a
1589 $ hg commit -m 'content3'
1590 $ hg log -G
1591 @ changeset: 4:50b9b36e9c5d
1592 | tag: tip
1593 | user: test
1594 | date: Thu Jan 01 00:00:00 1970 +0000
1595 | summary: content3
1596 |
1597 o changeset: 3:15b2327059e5
1598 | user: test
1599 | date: Thu Jan 01 00:00:00 1970 +0000
1600 | summary: content2
1601 |
1602 o changeset: 2:2029acd1168c
1603 | parent: 0:ae0a3c9f9e95
1604 | user: test
1605 | date: Thu Jan 01 00:00:00 1970 +0000
1606 | summary: unrelated
1607 |
1608 | o changeset: 1:2294ae80ad84
1609 |/ user: test
1610 | date: Thu Jan 01 00:00:00 1970 +0000
1611 | summary: content2
1612 |
1613 o changeset: 0:ae0a3c9f9e95
1614 user: test
1615 date: Thu Jan 01 00:00:00 1970 +0000
1616 summary: content1
1617
1618
1619 log -f on the file should list the graft result.
1620
1621 $ hg log -Gf a
1622 @ changeset: 4:50b9b36e9c5d
1623 | tag: tip
1624 | user: test
1625 | date: Thu Jan 01 00:00:00 1970 +0000
1626 | summary: content3
1627 |
1628 o changeset: 3:15b2327059e5
1629 | user: test
1630 | date: Thu Jan 01 00:00:00 1970 +0000
1631 | summary: content2
1632 |
1633 o changeset: 0:ae0a3c9f9e95
1634 user: test
1635 date: Thu Jan 01 00:00:00 1970 +0000
1636 summary: content1
1637
1638
1639 plain log lists the original version
1640 (XXX we should probably list both)
1641
1642 $ hg log -G a
1643 @ changeset: 4:50b9b36e9c5d
1644 | tag: tip
1645 | user: test
1646 | date: Thu Jan 01 00:00:00 1970 +0000
1647 | summary: content3
1648 |
1649 | o changeset: 1:2294ae80ad84
1650 |/ user: test
1651 | date: Thu Jan 01 00:00:00 1970 +0000
1652 | summary: content2
1653 |
1654 o changeset: 0:ae0a3c9f9e95
1655 user: test
1656 date: Thu Jan 01 00:00:00 1970 +0000
1657 summary: content1
1658
1659 $ cd ..
@@ -1,1607 +1,1669 b''
1
1
2 $ add()
2 $ add()
3 > {
3 > {
4 > echo $2 >> $1
4 > echo $2 >> $1
5 > }
5 > }
6 $ hg init t
6 $ hg init t
7 $ cd t
7 $ cd t
8
8
9 set up a boring main branch
9 set up a boring main branch
10
10
11 $ add a a
11 $ add a a
12 $ hg add a
12 $ hg add a
13 $ mkdir x
13 $ mkdir x
14 $ add x/x x
14 $ add x/x x
15 $ hg add x/x
15 $ hg add x/x
16 $ hg ci -m0
16 $ hg ci -m0
17 $ add a m1
17 $ add a m1
18 $ hg ci -m1
18 $ hg ci -m1
19 $ add a m2
19 $ add a m2
20 $ add x/y y1
20 $ add x/y y1
21 $ hg add x/y
21 $ hg add x/y
22 $ hg ci -m2
22 $ hg ci -m2
23 $ cd ..
23 $ cd ..
24
24
25 $ show()
25 $ show()
26 > {
26 > {
27 > echo "# $2:"
27 > echo "# $2:"
28 > echo
28 > echo
29 > echo "% hg st -C $1"
29 > echo "% hg st -C $1"
30 > hg st -C $1
30 > hg st -C $1
31 > echo
31 > echo
32 > echo "% hg diff --git $1"
32 > echo "% hg diff --git $1"
33 > hg diff --git $1
33 > hg diff --git $1
34 > echo
34 > echo
35 > }
35 > }
36 $ count=0
36 $ count=0
37
37
38 make a new branch and get diff/status output
38 make a new branch and get diff/status output
39 $1 - first commit
39 $1 - first commit
40 $2 - second commit
40 $2 - second commit
41 $3 - working dir action
41 $3 - working dir action
42
42
43 $ tb()
43 $ tb()
44 > {
44 > {
45 > hg clone -q t t2 ; cd t2
45 > hg clone -q t t2 ; cd t2
46 > hg co -q -C 0
46 > hg co -q -C 0
47 >
47 >
48 > echo % add a $count
48 > echo % add a $count
49 > add a $count
49 > add a $count
50 > count=`expr $count + 1`
50 > count=`expr $count + 1`
51 > echo % hg ci -m "t0"
51 > echo % hg ci -m "t0"
52 > hg ci -m "t0"
52 > hg ci -m "t0"
53 > echo % $1
53 > echo % $1
54 > $1
54 > $1
55 > echo % hg ci -m "t1"
55 > echo % hg ci -m "t1"
56 > hg ci -m "t1"
56 > hg ci -m "t1"
57 > echo % $2
57 > echo % $2
58 > $2
58 > $2
59 > echo % hg ci -m "t2"
59 > echo % hg ci -m "t2"
60 > hg ci -m "t2"
60 > hg ci -m "t2"
61 > echo % $3
61 > echo % $3
62 > $3
62 > $3
63 > echo
63 > echo
64 > show "" "working to parent"
64 > show "" "working to parent"
65 > show "--rev 0" "working to root"
65 > show "--rev 0" "working to root"
66 > show "--rev 2" "working to branch"
66 > show "--rev 2" "working to branch"
67 > show "--rev 0 --rev ." "root to parent"
67 > show "--rev 0 --rev ." "root to parent"
68 > show "--rev . --rev 0" "parent to root"
68 > show "--rev . --rev 0" "parent to root"
69 > show "--rev 2 --rev ." "branch to parent"
69 > show "--rev 2 --rev ." "branch to parent"
70 > show "--rev . --rev 2" "parent to branch"
70 > show "--rev . --rev 2" "parent to branch"
71 > echo
71 > echo
72 > cd ..
72 > cd ..
73 > rm -rf t2
73 > rm -rf t2
74 > }
74 > }
75
75
76 rename in working dir
76 rename in working dir
77
77
78 $ tb "add a a1" "add a a2" "hg mv a b"
78 $ tb "add a a1" "add a a2" "hg mv a b"
79 % add a 0
79 % add a 0
80 % hg ci -m t0
80 % hg ci -m t0
81 created new head
81 created new head
82 % add a a1
82 % add a a1
83 % hg ci -m t1
83 % hg ci -m t1
84 % add a a2
84 % add a a2
85 % hg ci -m t2
85 % hg ci -m t2
86 % hg mv a b
86 % hg mv a b
87
87
88 # working to parent:
88 # working to parent:
89
89
90 % hg st -C
90 % hg st -C
91 A b
91 A b
92 a
92 a
93 R a
93 R a
94
94
95 % hg diff --git
95 % hg diff --git
96 diff --git a/a b/b
96 diff --git a/a b/b
97 rename from a
97 rename from a
98 rename to b
98 rename to b
99
99
100 # working to root:
100 # working to root:
101
101
102 % hg st -C --rev 0
102 % hg st -C --rev 0
103 A b
103 A b
104 a
104 a
105 R a
105 R a
106
106
107 % hg diff --git --rev 0
107 % hg diff --git --rev 0
108 diff --git a/a b/b
108 diff --git a/a b/b
109 rename from a
109 rename from a
110 rename to b
110 rename to b
111 --- a/a
111 --- a/a
112 +++ b/b
112 +++ b/b
113 @@ -1,1 +1,4 @@
113 @@ -1,1 +1,4 @@
114 a
114 a
115 +0
115 +0
116 +a1
116 +a1
117 +a2
117 +a2
118
118
119 # working to branch:
119 # working to branch:
120
120
121 % hg st -C --rev 2
121 % hg st -C --rev 2
122 A b
122 A b
123 a
123 a
124 R a
124 R a
125 R x/y
125 R x/y
126
126
127 % hg diff --git --rev 2
127 % hg diff --git --rev 2
128 diff --git a/a b/b
128 diff --git a/a b/b
129 rename from a
129 rename from a
130 rename to b
130 rename to b
131 --- a/a
131 --- a/a
132 +++ b/b
132 +++ b/b
133 @@ -1,3 +1,4 @@
133 @@ -1,3 +1,4 @@
134 a
134 a
135 -m1
135 -m1
136 -m2
136 -m2
137 +0
137 +0
138 +a1
138 +a1
139 +a2
139 +a2
140 diff --git a/x/y b/x/y
140 diff --git a/x/y b/x/y
141 deleted file mode 100644
141 deleted file mode 100644
142 --- a/x/y
142 --- a/x/y
143 +++ /dev/null
143 +++ /dev/null
144 @@ -1,1 +0,0 @@
144 @@ -1,1 +0,0 @@
145 -y1
145 -y1
146
146
147 # root to parent:
147 # root to parent:
148
148
149 % hg st -C --rev 0 --rev .
149 % hg st -C --rev 0 --rev .
150 M a
150 M a
151
151
152 % hg diff --git --rev 0 --rev .
152 % hg diff --git --rev 0 --rev .
153 diff --git a/a b/a
153 diff --git a/a b/a
154 --- a/a
154 --- a/a
155 +++ b/a
155 +++ b/a
156 @@ -1,1 +1,4 @@
156 @@ -1,1 +1,4 @@
157 a
157 a
158 +0
158 +0
159 +a1
159 +a1
160 +a2
160 +a2
161
161
162 # parent to root:
162 # parent to root:
163
163
164 % hg st -C --rev . --rev 0
164 % hg st -C --rev . --rev 0
165 M a
165 M a
166
166
167 % hg diff --git --rev . --rev 0
167 % hg diff --git --rev . --rev 0
168 diff --git a/a b/a
168 diff --git a/a b/a
169 --- a/a
169 --- a/a
170 +++ b/a
170 +++ b/a
171 @@ -1,4 +1,1 @@
171 @@ -1,4 +1,1 @@
172 a
172 a
173 -0
173 -0
174 -a1
174 -a1
175 -a2
175 -a2
176
176
177 # branch to parent:
177 # branch to parent:
178
178
179 % hg st -C --rev 2 --rev .
179 % hg st -C --rev 2 --rev .
180 M a
180 M a
181 R x/y
181 R x/y
182
182
183 % hg diff --git --rev 2 --rev .
183 % hg diff --git --rev 2 --rev .
184 diff --git a/a b/a
184 diff --git a/a b/a
185 --- a/a
185 --- a/a
186 +++ b/a
186 +++ b/a
187 @@ -1,3 +1,4 @@
187 @@ -1,3 +1,4 @@
188 a
188 a
189 -m1
189 -m1
190 -m2
190 -m2
191 +0
191 +0
192 +a1
192 +a1
193 +a2
193 +a2
194 diff --git a/x/y b/x/y
194 diff --git a/x/y b/x/y
195 deleted file mode 100644
195 deleted file mode 100644
196 --- a/x/y
196 --- a/x/y
197 +++ /dev/null
197 +++ /dev/null
198 @@ -1,1 +0,0 @@
198 @@ -1,1 +0,0 @@
199 -y1
199 -y1
200
200
201 # parent to branch:
201 # parent to branch:
202
202
203 % hg st -C --rev . --rev 2
203 % hg st -C --rev . --rev 2
204 M a
204 M a
205 A x/y
205 A x/y
206
206
207 % hg diff --git --rev . --rev 2
207 % hg diff --git --rev . --rev 2
208 diff --git a/a b/a
208 diff --git a/a b/a
209 --- a/a
209 --- a/a
210 +++ b/a
210 +++ b/a
211 @@ -1,4 +1,3 @@
211 @@ -1,4 +1,3 @@
212 a
212 a
213 -0
213 -0
214 -a1
214 -a1
215 -a2
215 -a2
216 +m1
216 +m1
217 +m2
217 +m2
218 diff --git a/x/y b/x/y
218 diff --git a/x/y b/x/y
219 new file mode 100644
219 new file mode 100644
220 --- /dev/null
220 --- /dev/null
221 +++ b/x/y
221 +++ b/x/y
222 @@ -0,0 +1,1 @@
222 @@ -0,0 +1,1 @@
223 +y1
223 +y1
224
224
225
225
226 copy in working dir
226 copy in working dir
227
227
228 $ tb "add a a1" "add a a2" "hg cp a b"
228 $ tb "add a a1" "add a a2" "hg cp a b"
229 % add a 1
229 % add a 1
230 % hg ci -m t0
230 % hg ci -m t0
231 created new head
231 created new head
232 % add a a1
232 % add a a1
233 % hg ci -m t1
233 % hg ci -m t1
234 % add a a2
234 % add a a2
235 % hg ci -m t2
235 % hg ci -m t2
236 % hg cp a b
236 % hg cp a b
237
237
238 # working to parent:
238 # working to parent:
239
239
240 % hg st -C
240 % hg st -C
241 A b
241 A b
242 a
242 a
243
243
244 % hg diff --git
244 % hg diff --git
245 diff --git a/a b/b
245 diff --git a/a b/b
246 copy from a
246 copy from a
247 copy to b
247 copy to b
248
248
249 # working to root:
249 # working to root:
250
250
251 % hg st -C --rev 0
251 % hg st -C --rev 0
252 M a
252 M a
253 A b
253 A b
254 a
254 a
255
255
256 % hg diff --git --rev 0
256 % hg diff --git --rev 0
257 diff --git a/a b/a
257 diff --git a/a b/a
258 --- a/a
258 --- a/a
259 +++ b/a
259 +++ b/a
260 @@ -1,1 +1,4 @@
260 @@ -1,1 +1,4 @@
261 a
261 a
262 +1
262 +1
263 +a1
263 +a1
264 +a2
264 +a2
265 diff --git a/a b/b
265 diff --git a/a b/b
266 copy from a
266 copy from a
267 copy to b
267 copy to b
268 --- a/a
268 --- a/a
269 +++ b/b
269 +++ b/b
270 @@ -1,1 +1,4 @@
270 @@ -1,1 +1,4 @@
271 a
271 a
272 +1
272 +1
273 +a1
273 +a1
274 +a2
274 +a2
275
275
276 # working to branch:
276 # working to branch:
277
277
278 % hg st -C --rev 2
278 % hg st -C --rev 2
279 M a
279 M a
280 A b
280 A b
281 a
281 a
282 R x/y
282 R x/y
283
283
284 % hg diff --git --rev 2
284 % hg diff --git --rev 2
285 diff --git a/a b/a
285 diff --git a/a b/a
286 --- a/a
286 --- a/a
287 +++ b/a
287 +++ b/a
288 @@ -1,3 +1,4 @@
288 @@ -1,3 +1,4 @@
289 a
289 a
290 -m1
290 -m1
291 -m2
291 -m2
292 +1
292 +1
293 +a1
293 +a1
294 +a2
294 +a2
295 diff --git a/a b/b
295 diff --git a/a b/b
296 copy from a
296 copy from a
297 copy to b
297 copy to b
298 --- a/a
298 --- a/a
299 +++ b/b
299 +++ b/b
300 @@ -1,3 +1,4 @@
300 @@ -1,3 +1,4 @@
301 a
301 a
302 -m1
302 -m1
303 -m2
303 -m2
304 +1
304 +1
305 +a1
305 +a1
306 +a2
306 +a2
307 diff --git a/x/y b/x/y
307 diff --git a/x/y b/x/y
308 deleted file mode 100644
308 deleted file mode 100644
309 --- a/x/y
309 --- a/x/y
310 +++ /dev/null
310 +++ /dev/null
311 @@ -1,1 +0,0 @@
311 @@ -1,1 +0,0 @@
312 -y1
312 -y1
313
313
314 # root to parent:
314 # root to parent:
315
315
316 % hg st -C --rev 0 --rev .
316 % hg st -C --rev 0 --rev .
317 M a
317 M a
318
318
319 % hg diff --git --rev 0 --rev .
319 % hg diff --git --rev 0 --rev .
320 diff --git a/a b/a
320 diff --git a/a b/a
321 --- a/a
321 --- a/a
322 +++ b/a
322 +++ b/a
323 @@ -1,1 +1,4 @@
323 @@ -1,1 +1,4 @@
324 a
324 a
325 +1
325 +1
326 +a1
326 +a1
327 +a2
327 +a2
328
328
329 # parent to root:
329 # parent to root:
330
330
331 % hg st -C --rev . --rev 0
331 % hg st -C --rev . --rev 0
332 M a
332 M a
333
333
334 % hg diff --git --rev . --rev 0
334 % hg diff --git --rev . --rev 0
335 diff --git a/a b/a
335 diff --git a/a b/a
336 --- a/a
336 --- a/a
337 +++ b/a
337 +++ b/a
338 @@ -1,4 +1,1 @@
338 @@ -1,4 +1,1 @@
339 a
339 a
340 -1
340 -1
341 -a1
341 -a1
342 -a2
342 -a2
343
343
344 # branch to parent:
344 # branch to parent:
345
345
346 % hg st -C --rev 2 --rev .
346 % hg st -C --rev 2 --rev .
347 M a
347 M a
348 R x/y
348 R x/y
349
349
350 % hg diff --git --rev 2 --rev .
350 % hg diff --git --rev 2 --rev .
351 diff --git a/a b/a
351 diff --git a/a b/a
352 --- a/a
352 --- a/a
353 +++ b/a
353 +++ b/a
354 @@ -1,3 +1,4 @@
354 @@ -1,3 +1,4 @@
355 a
355 a
356 -m1
356 -m1
357 -m2
357 -m2
358 +1
358 +1
359 +a1
359 +a1
360 +a2
360 +a2
361 diff --git a/x/y b/x/y
361 diff --git a/x/y b/x/y
362 deleted file mode 100644
362 deleted file mode 100644
363 --- a/x/y
363 --- a/x/y
364 +++ /dev/null
364 +++ /dev/null
365 @@ -1,1 +0,0 @@
365 @@ -1,1 +0,0 @@
366 -y1
366 -y1
367
367
368 # parent to branch:
368 # parent to branch:
369
369
370 % hg st -C --rev . --rev 2
370 % hg st -C --rev . --rev 2
371 M a
371 M a
372 A x/y
372 A x/y
373
373
374 % hg diff --git --rev . --rev 2
374 % hg diff --git --rev . --rev 2
375 diff --git a/a b/a
375 diff --git a/a b/a
376 --- a/a
376 --- a/a
377 +++ b/a
377 +++ b/a
378 @@ -1,4 +1,3 @@
378 @@ -1,4 +1,3 @@
379 a
379 a
380 -1
380 -1
381 -a1
381 -a1
382 -a2
382 -a2
383 +m1
383 +m1
384 +m2
384 +m2
385 diff --git a/x/y b/x/y
385 diff --git a/x/y b/x/y
386 new file mode 100644
386 new file mode 100644
387 --- /dev/null
387 --- /dev/null
388 +++ b/x/y
388 +++ b/x/y
389 @@ -0,0 +1,1 @@
389 @@ -0,0 +1,1 @@
390 +y1
390 +y1
391
391
392
392
393 single rename
393 single rename
394
394
395 $ tb "hg mv a b" "add b b1" "add b w"
395 $ tb "hg mv a b" "add b b1" "add b w"
396 % add a 2
396 % add a 2
397 % hg ci -m t0
397 % hg ci -m t0
398 created new head
398 created new head
399 % hg mv a b
399 % hg mv a b
400 % hg ci -m t1
400 % hg ci -m t1
401 % add b b1
401 % add b b1
402 % hg ci -m t2
402 % hg ci -m t2
403 % add b w
403 % add b w
404
404
405 # working to parent:
405 # working to parent:
406
406
407 % hg st -C
407 % hg st -C
408 M b
408 M b
409
409
410 % hg diff --git
410 % hg diff --git
411 diff --git a/b b/b
411 diff --git a/b b/b
412 --- a/b
412 --- a/b
413 +++ b/b
413 +++ b/b
414 @@ -1,3 +1,4 @@
414 @@ -1,3 +1,4 @@
415 a
415 a
416 2
416 2
417 b1
417 b1
418 +w
418 +w
419
419
420 # working to root:
420 # working to root:
421
421
422 % hg st -C --rev 0
422 % hg st -C --rev 0
423 A b
423 A b
424 a
424 a
425 R a
425 R a
426
426
427 % hg diff --git --rev 0
427 % hg diff --git --rev 0
428 diff --git a/a b/b
428 diff --git a/a b/b
429 rename from a
429 rename from a
430 rename to b
430 rename to b
431 --- a/a
431 --- a/a
432 +++ b/b
432 +++ b/b
433 @@ -1,1 +1,4 @@
433 @@ -1,1 +1,4 @@
434 a
434 a
435 +2
435 +2
436 +b1
436 +b1
437 +w
437 +w
438
438
439 # working to branch:
439 # working to branch:
440
440
441 % hg st -C --rev 2
441 % hg st -C --rev 2
442 A b
442 A b
443 a
443 a
444 R a
444 R a
445 R x/y
445 R x/y
446
446
447 % hg diff --git --rev 2
447 % hg diff --git --rev 2
448 diff --git a/a b/b
448 diff --git a/a b/b
449 rename from a
449 rename from a
450 rename to b
450 rename to b
451 --- a/a
451 --- a/a
452 +++ b/b
452 +++ b/b
453 @@ -1,3 +1,4 @@
453 @@ -1,3 +1,4 @@
454 a
454 a
455 -m1
455 -m1
456 -m2
456 -m2
457 +2
457 +2
458 +b1
458 +b1
459 +w
459 +w
460 diff --git a/x/y b/x/y
460 diff --git a/x/y b/x/y
461 deleted file mode 100644
461 deleted file mode 100644
462 --- a/x/y
462 --- a/x/y
463 +++ /dev/null
463 +++ /dev/null
464 @@ -1,1 +0,0 @@
464 @@ -1,1 +0,0 @@
465 -y1
465 -y1
466
466
467 # root to parent:
467 # root to parent:
468
468
469 % hg st -C --rev 0 --rev .
469 % hg st -C --rev 0 --rev .
470 A b
470 A b
471 a
471 a
472 R a
472 R a
473
473
474 % hg diff --git --rev 0 --rev .
474 % hg diff --git --rev 0 --rev .
475 diff --git a/a b/b
475 diff --git a/a b/b
476 rename from a
476 rename from a
477 rename to b
477 rename to b
478 --- a/a
478 --- a/a
479 +++ b/b
479 +++ b/b
480 @@ -1,1 +1,3 @@
480 @@ -1,1 +1,3 @@
481 a
481 a
482 +2
482 +2
483 +b1
483 +b1
484
484
485 # parent to root:
485 # parent to root:
486
486
487 % hg st -C --rev . --rev 0
487 % hg st -C --rev . --rev 0
488 A a
488 A a
489 b
489 b
490 R b
490 R b
491
491
492 % hg diff --git --rev . --rev 0
492 % hg diff --git --rev . --rev 0
493 diff --git a/b b/a
493 diff --git a/b b/a
494 rename from b
494 rename from b
495 rename to a
495 rename to a
496 --- a/b
496 --- a/b
497 +++ b/a
497 +++ b/a
498 @@ -1,3 +1,1 @@
498 @@ -1,3 +1,1 @@
499 a
499 a
500 -2
500 -2
501 -b1
501 -b1
502
502
503 # branch to parent:
503 # branch to parent:
504
504
505 % hg st -C --rev 2 --rev .
505 % hg st -C --rev 2 --rev .
506 A b
506 A b
507 a
507 a
508 R a
508 R a
509 R x/y
509 R x/y
510
510
511 % hg diff --git --rev 2 --rev .
511 % hg diff --git --rev 2 --rev .
512 diff --git a/a b/b
512 diff --git a/a b/b
513 rename from a
513 rename from a
514 rename to b
514 rename to b
515 --- a/a
515 --- a/a
516 +++ b/b
516 +++ b/b
517 @@ -1,3 +1,3 @@
517 @@ -1,3 +1,3 @@
518 a
518 a
519 -m1
519 -m1
520 -m2
520 -m2
521 +2
521 +2
522 +b1
522 +b1
523 diff --git a/x/y b/x/y
523 diff --git a/x/y b/x/y
524 deleted file mode 100644
524 deleted file mode 100644
525 --- a/x/y
525 --- a/x/y
526 +++ /dev/null
526 +++ /dev/null
527 @@ -1,1 +0,0 @@
527 @@ -1,1 +0,0 @@
528 -y1
528 -y1
529
529
530 # parent to branch:
530 # parent to branch:
531
531
532 % hg st -C --rev . --rev 2
532 % hg st -C --rev . --rev 2
533 A a
533 A a
534 b
534 b
535 A x/y
535 A x/y
536 R b
536 R b
537
537
538 % hg diff --git --rev . --rev 2
538 % hg diff --git --rev . --rev 2
539 diff --git a/b b/a
539 diff --git a/b b/a
540 rename from b
540 rename from b
541 rename to a
541 rename to a
542 --- a/b
542 --- a/b
543 +++ b/a
543 +++ b/a
544 @@ -1,3 +1,3 @@
544 @@ -1,3 +1,3 @@
545 a
545 a
546 -2
546 -2
547 -b1
547 -b1
548 +m1
548 +m1
549 +m2
549 +m2
550 diff --git a/x/y b/x/y
550 diff --git a/x/y b/x/y
551 new file mode 100644
551 new file mode 100644
552 --- /dev/null
552 --- /dev/null
553 +++ b/x/y
553 +++ b/x/y
554 @@ -0,0 +1,1 @@
554 @@ -0,0 +1,1 @@
555 +y1
555 +y1
556
556
557
557
558 single copy
558 single copy
559
559
560 $ tb "hg cp a b" "add b b1" "add a w"
560 $ tb "hg cp a b" "add b b1" "add a w"
561 % add a 3
561 % add a 3
562 % hg ci -m t0
562 % hg ci -m t0
563 created new head
563 created new head
564 % hg cp a b
564 % hg cp a b
565 % hg ci -m t1
565 % hg ci -m t1
566 % add b b1
566 % add b b1
567 % hg ci -m t2
567 % hg ci -m t2
568 % add a w
568 % add a w
569
569
570 # working to parent:
570 # working to parent:
571
571
572 % hg st -C
572 % hg st -C
573 M a
573 M a
574
574
575 % hg diff --git
575 % hg diff --git
576 diff --git a/a b/a
576 diff --git a/a b/a
577 --- a/a
577 --- a/a
578 +++ b/a
578 +++ b/a
579 @@ -1,2 +1,3 @@
579 @@ -1,2 +1,3 @@
580 a
580 a
581 3
581 3
582 +w
582 +w
583
583
584 # working to root:
584 # working to root:
585
585
586 % hg st -C --rev 0
586 % hg st -C --rev 0
587 M a
587 M a
588 A b
588 A b
589 a
589 a
590
590
591 % hg diff --git --rev 0
591 % hg diff --git --rev 0
592 diff --git a/a b/a
592 diff --git a/a b/a
593 --- a/a
593 --- a/a
594 +++ b/a
594 +++ b/a
595 @@ -1,1 +1,3 @@
595 @@ -1,1 +1,3 @@
596 a
596 a
597 +3
597 +3
598 +w
598 +w
599 diff --git a/a b/b
599 diff --git a/a b/b
600 copy from a
600 copy from a
601 copy to b
601 copy to b
602 --- a/a
602 --- a/a
603 +++ b/b
603 +++ b/b
604 @@ -1,1 +1,3 @@
604 @@ -1,1 +1,3 @@
605 a
605 a
606 +3
606 +3
607 +b1
607 +b1
608
608
609 # working to branch:
609 # working to branch:
610
610
611 % hg st -C --rev 2
611 % hg st -C --rev 2
612 M a
612 M a
613 A b
613 A b
614 a
614 a
615 R x/y
615 R x/y
616
616
617 % hg diff --git --rev 2
617 % hg diff --git --rev 2
618 diff --git a/a b/a
618 diff --git a/a b/a
619 --- a/a
619 --- a/a
620 +++ b/a
620 +++ b/a
621 @@ -1,3 +1,3 @@
621 @@ -1,3 +1,3 @@
622 a
622 a
623 -m1
623 -m1
624 -m2
624 -m2
625 +3
625 +3
626 +w
626 +w
627 diff --git a/a b/b
627 diff --git a/a b/b
628 copy from a
628 copy from a
629 copy to b
629 copy to b
630 --- a/a
630 --- a/a
631 +++ b/b
631 +++ b/b
632 @@ -1,3 +1,3 @@
632 @@ -1,3 +1,3 @@
633 a
633 a
634 -m1
634 -m1
635 -m2
635 -m2
636 +3
636 +3
637 +b1
637 +b1
638 diff --git a/x/y b/x/y
638 diff --git a/x/y b/x/y
639 deleted file mode 100644
639 deleted file mode 100644
640 --- a/x/y
640 --- a/x/y
641 +++ /dev/null
641 +++ /dev/null
642 @@ -1,1 +0,0 @@
642 @@ -1,1 +0,0 @@
643 -y1
643 -y1
644
644
645 # root to parent:
645 # root to parent:
646
646
647 % hg st -C --rev 0 --rev .
647 % hg st -C --rev 0 --rev .
648 M a
648 M a
649 A b
649 A b
650 a
650 a
651
651
652 % hg diff --git --rev 0 --rev .
652 % hg diff --git --rev 0 --rev .
653 diff --git a/a b/a
653 diff --git a/a b/a
654 --- a/a
654 --- a/a
655 +++ b/a
655 +++ b/a
656 @@ -1,1 +1,2 @@
656 @@ -1,1 +1,2 @@
657 a
657 a
658 +3
658 +3
659 diff --git a/a b/b
659 diff --git a/a b/b
660 copy from a
660 copy from a
661 copy to b
661 copy to b
662 --- a/a
662 --- a/a
663 +++ b/b
663 +++ b/b
664 @@ -1,1 +1,3 @@
664 @@ -1,1 +1,3 @@
665 a
665 a
666 +3
666 +3
667 +b1
667 +b1
668
668
669 # parent to root:
669 # parent to root:
670
670
671 % hg st -C --rev . --rev 0
671 % hg st -C --rev . --rev 0
672 M a
672 M a
673 R b
673 R b
674
674
675 % hg diff --git --rev . --rev 0
675 % hg diff --git --rev . --rev 0
676 diff --git a/a b/a
676 diff --git a/a b/a
677 --- a/a
677 --- a/a
678 +++ b/a
678 +++ b/a
679 @@ -1,2 +1,1 @@
679 @@ -1,2 +1,1 @@
680 a
680 a
681 -3
681 -3
682 diff --git a/b b/b
682 diff --git a/b b/b
683 deleted file mode 100644
683 deleted file mode 100644
684 --- a/b
684 --- a/b
685 +++ /dev/null
685 +++ /dev/null
686 @@ -1,3 +0,0 @@
686 @@ -1,3 +0,0 @@
687 -a
687 -a
688 -3
688 -3
689 -b1
689 -b1
690
690
691 # branch to parent:
691 # branch to parent:
692
692
693 % hg st -C --rev 2 --rev .
693 % hg st -C --rev 2 --rev .
694 M a
694 M a
695 A b
695 A b
696 a
696 a
697 R x/y
697 R x/y
698
698
699 % hg diff --git --rev 2 --rev .
699 % hg diff --git --rev 2 --rev .
700 diff --git a/a b/a
700 diff --git a/a b/a
701 --- a/a
701 --- a/a
702 +++ b/a
702 +++ b/a
703 @@ -1,3 +1,2 @@
703 @@ -1,3 +1,2 @@
704 a
704 a
705 -m1
705 -m1
706 -m2
706 -m2
707 +3
707 +3
708 diff --git a/a b/b
708 diff --git a/a b/b
709 copy from a
709 copy from a
710 copy to b
710 copy to b
711 --- a/a
711 --- a/a
712 +++ b/b
712 +++ b/b
713 @@ -1,3 +1,3 @@
713 @@ -1,3 +1,3 @@
714 a
714 a
715 -m1
715 -m1
716 -m2
716 -m2
717 +3
717 +3
718 +b1
718 +b1
719 diff --git a/x/y b/x/y
719 diff --git a/x/y b/x/y
720 deleted file mode 100644
720 deleted file mode 100644
721 --- a/x/y
721 --- a/x/y
722 +++ /dev/null
722 +++ /dev/null
723 @@ -1,1 +0,0 @@
723 @@ -1,1 +0,0 @@
724 -y1
724 -y1
725
725
726 # parent to branch:
726 # parent to branch:
727
727
728 % hg st -C --rev . --rev 2
728 % hg st -C --rev . --rev 2
729 M a
729 M a
730 A x/y
730 A x/y
731 R b
731 R b
732
732
733 % hg diff --git --rev . --rev 2
733 % hg diff --git --rev . --rev 2
734 diff --git a/a b/a
734 diff --git a/a b/a
735 --- a/a
735 --- a/a
736 +++ b/a
736 +++ b/a
737 @@ -1,2 +1,3 @@
737 @@ -1,2 +1,3 @@
738 a
738 a
739 -3
739 -3
740 +m1
740 +m1
741 +m2
741 +m2
742 diff --git a/b b/b
742 diff --git a/b b/b
743 deleted file mode 100644
743 deleted file mode 100644
744 --- a/b
744 --- a/b
745 +++ /dev/null
745 +++ /dev/null
746 @@ -1,3 +0,0 @@
746 @@ -1,3 +0,0 @@
747 -a
747 -a
748 -3
748 -3
749 -b1
749 -b1
750 diff --git a/x/y b/x/y
750 diff --git a/x/y b/x/y
751 new file mode 100644
751 new file mode 100644
752 --- /dev/null
752 --- /dev/null
753 +++ b/x/y
753 +++ b/x/y
754 @@ -0,0 +1,1 @@
754 @@ -0,0 +1,1 @@
755 +y1
755 +y1
756
756
757
757
758 rename chain
758 rename chain
759
759
760 $ tb "hg mv a b" "hg mv b c" "hg mv c d"
760 $ tb "hg mv a b" "hg mv b c" "hg mv c d"
761 % add a 4
761 % add a 4
762 % hg ci -m t0
762 % hg ci -m t0
763 created new head
763 created new head
764 % hg mv a b
764 % hg mv a b
765 % hg ci -m t1
765 % hg ci -m t1
766 % hg mv b c
766 % hg mv b c
767 % hg ci -m t2
767 % hg ci -m t2
768 % hg mv c d
768 % hg mv c d
769
769
770 # working to parent:
770 # working to parent:
771
771
772 % hg st -C
772 % hg st -C
773 A d
773 A d
774 c
774 c
775 R c
775 R c
776
776
777 % hg diff --git
777 % hg diff --git
778 diff --git a/c b/d
778 diff --git a/c b/d
779 rename from c
779 rename from c
780 rename to d
780 rename to d
781
781
782 # working to root:
782 # working to root:
783
783
784 % hg st -C --rev 0
784 % hg st -C --rev 0
785 A d
785 A d
786 a
786 a
787 R a
787 R a
788
788
789 % hg diff --git --rev 0
789 % hg diff --git --rev 0
790 diff --git a/a b/d
790 diff --git a/a b/d
791 rename from a
791 rename from a
792 rename to d
792 rename to d
793 --- a/a
793 --- a/a
794 +++ b/d
794 +++ b/d
795 @@ -1,1 +1,2 @@
795 @@ -1,1 +1,2 @@
796 a
796 a
797 +4
797 +4
798
798
799 # working to branch:
799 # working to branch:
800
800
801 % hg st -C --rev 2
801 % hg st -C --rev 2
802 A d
802 A d
803 a
803 a
804 R a
804 R a
805 R x/y
805 R x/y
806
806
807 % hg diff --git --rev 2
807 % hg diff --git --rev 2
808 diff --git a/a b/d
808 diff --git a/a b/d
809 rename from a
809 rename from a
810 rename to d
810 rename to d
811 --- a/a
811 --- a/a
812 +++ b/d
812 +++ b/d
813 @@ -1,3 +1,2 @@
813 @@ -1,3 +1,2 @@
814 a
814 a
815 -m1
815 -m1
816 -m2
816 -m2
817 +4
817 +4
818 diff --git a/x/y b/x/y
818 diff --git a/x/y b/x/y
819 deleted file mode 100644
819 deleted file mode 100644
820 --- a/x/y
820 --- a/x/y
821 +++ /dev/null
821 +++ /dev/null
822 @@ -1,1 +0,0 @@
822 @@ -1,1 +0,0 @@
823 -y1
823 -y1
824
824
825 # root to parent:
825 # root to parent:
826
826
827 % hg st -C --rev 0 --rev .
827 % hg st -C --rev 0 --rev .
828 A c
828 A c
829 a
829 a
830 R a
830 R a
831
831
832 % hg diff --git --rev 0 --rev .
832 % hg diff --git --rev 0 --rev .
833 diff --git a/a b/c
833 diff --git a/a b/c
834 rename from a
834 rename from a
835 rename to c
835 rename to c
836 --- a/a
836 --- a/a
837 +++ b/c
837 +++ b/c
838 @@ -1,1 +1,2 @@
838 @@ -1,1 +1,2 @@
839 a
839 a
840 +4
840 +4
841
841
842 # parent to root:
842 # parent to root:
843
843
844 % hg st -C --rev . --rev 0
844 % hg st -C --rev . --rev 0
845 A a
845 A a
846 c
846 c
847 R c
847 R c
848
848
849 % hg diff --git --rev . --rev 0
849 % hg diff --git --rev . --rev 0
850 diff --git a/c b/a
850 diff --git a/c b/a
851 rename from c
851 rename from c
852 rename to a
852 rename to a
853 --- a/c
853 --- a/c
854 +++ b/a
854 +++ b/a
855 @@ -1,2 +1,1 @@
855 @@ -1,2 +1,1 @@
856 a
856 a
857 -4
857 -4
858
858
859 # branch to parent:
859 # branch to parent:
860
860
861 % hg st -C --rev 2 --rev .
861 % hg st -C --rev 2 --rev .
862 A c
862 A c
863 a
863 a
864 R a
864 R a
865 R x/y
865 R x/y
866
866
867 % hg diff --git --rev 2 --rev .
867 % hg diff --git --rev 2 --rev .
868 diff --git a/a b/c
868 diff --git a/a b/c
869 rename from a
869 rename from a
870 rename to c
870 rename to c
871 --- a/a
871 --- a/a
872 +++ b/c
872 +++ b/c
873 @@ -1,3 +1,2 @@
873 @@ -1,3 +1,2 @@
874 a
874 a
875 -m1
875 -m1
876 -m2
876 -m2
877 +4
877 +4
878 diff --git a/x/y b/x/y
878 diff --git a/x/y b/x/y
879 deleted file mode 100644
879 deleted file mode 100644
880 --- a/x/y
880 --- a/x/y
881 +++ /dev/null
881 +++ /dev/null
882 @@ -1,1 +0,0 @@
882 @@ -1,1 +0,0 @@
883 -y1
883 -y1
884
884
885 # parent to branch:
885 # parent to branch:
886
886
887 % hg st -C --rev . --rev 2
887 % hg st -C --rev . --rev 2
888 A a
888 A a
889 c
889 c
890 A x/y
890 A x/y
891 R c
891 R c
892
892
893 % hg diff --git --rev . --rev 2
893 % hg diff --git --rev . --rev 2
894 diff --git a/c b/a
894 diff --git a/c b/a
895 rename from c
895 rename from c
896 rename to a
896 rename to a
897 --- a/c
897 --- a/c
898 +++ b/a
898 +++ b/a
899 @@ -1,2 +1,3 @@
899 @@ -1,2 +1,3 @@
900 a
900 a
901 -4
901 -4
902 +m1
902 +m1
903 +m2
903 +m2
904 diff --git a/x/y b/x/y
904 diff --git a/x/y b/x/y
905 new file mode 100644
905 new file mode 100644
906 --- /dev/null
906 --- /dev/null
907 +++ b/x/y
907 +++ b/x/y
908 @@ -0,0 +1,1 @@
908 @@ -0,0 +1,1 @@
909 +y1
909 +y1
910
910
911
911
912 copy chain
912 copy chain
913
913
914 $ tb "hg cp a b" "hg cp b c" "hg cp c d"
914 $ tb "hg cp a b" "hg cp b c" "hg cp c d"
915 % add a 5
915 % add a 5
916 % hg ci -m t0
916 % hg ci -m t0
917 created new head
917 created new head
918 % hg cp a b
918 % hg cp a b
919 % hg ci -m t1
919 % hg ci -m t1
920 % hg cp b c
920 % hg cp b c
921 % hg ci -m t2
921 % hg ci -m t2
922 % hg cp c d
922 % hg cp c d
923
923
924 # working to parent:
924 # working to parent:
925
925
926 % hg st -C
926 % hg st -C
927 A d
927 A d
928 c
928 c
929
929
930 % hg diff --git
930 % hg diff --git
931 diff --git a/c b/d
931 diff --git a/c b/d
932 copy from c
932 copy from c
933 copy to d
933 copy to d
934
934
935 # working to root:
935 # working to root:
936
936
937 % hg st -C --rev 0
937 % hg st -C --rev 0
938 M a
938 M a
939 A b
939 A b
940 a
940 a
941 A c
941 A c
942 a
942 a
943 A d
943 A d
944 a
944 a
945
945
946 % hg diff --git --rev 0
946 % hg diff --git --rev 0
947 diff --git a/a b/a
947 diff --git a/a b/a
948 --- a/a
948 --- a/a
949 +++ b/a
949 +++ b/a
950 @@ -1,1 +1,2 @@
950 @@ -1,1 +1,2 @@
951 a
951 a
952 +5
952 +5
953 diff --git a/a b/b
953 diff --git a/a b/b
954 copy from a
954 copy from a
955 copy to b
955 copy to b
956 --- a/a
956 --- a/a
957 +++ b/b
957 +++ b/b
958 @@ -1,1 +1,2 @@
958 @@ -1,1 +1,2 @@
959 a
959 a
960 +5
960 +5
961 diff --git a/a b/c
961 diff --git a/a b/c
962 copy from a
962 copy from a
963 copy to c
963 copy to c
964 --- a/a
964 --- a/a
965 +++ b/c
965 +++ b/c
966 @@ -1,1 +1,2 @@
966 @@ -1,1 +1,2 @@
967 a
967 a
968 +5
968 +5
969 diff --git a/a b/d
969 diff --git a/a b/d
970 copy from a
970 copy from a
971 copy to d
971 copy to d
972 --- a/a
972 --- a/a
973 +++ b/d
973 +++ b/d
974 @@ -1,1 +1,2 @@
974 @@ -1,1 +1,2 @@
975 a
975 a
976 +5
976 +5
977
977
978 # working to branch:
978 # working to branch:
979
979
980 % hg st -C --rev 2
980 % hg st -C --rev 2
981 M a
981 M a
982 A b
982 A b
983 a
983 a
984 A c
984 A c
985 a
985 a
986 A d
986 A d
987 a
987 a
988 R x/y
988 R x/y
989
989
990 % hg diff --git --rev 2
990 % hg diff --git --rev 2
991 diff --git a/a b/a
991 diff --git a/a b/a
992 --- a/a
992 --- a/a
993 +++ b/a
993 +++ b/a
994 @@ -1,3 +1,2 @@
994 @@ -1,3 +1,2 @@
995 a
995 a
996 -m1
996 -m1
997 -m2
997 -m2
998 +5
998 +5
999 diff --git a/a b/b
999 diff --git a/a b/b
1000 copy from a
1000 copy from a
1001 copy to b
1001 copy to b
1002 --- a/a
1002 --- a/a
1003 +++ b/b
1003 +++ b/b
1004 @@ -1,3 +1,2 @@
1004 @@ -1,3 +1,2 @@
1005 a
1005 a
1006 -m1
1006 -m1
1007 -m2
1007 -m2
1008 +5
1008 +5
1009 diff --git a/a b/c
1009 diff --git a/a b/c
1010 copy from a
1010 copy from a
1011 copy to c
1011 copy to c
1012 --- a/a
1012 --- a/a
1013 +++ b/c
1013 +++ b/c
1014 @@ -1,3 +1,2 @@
1014 @@ -1,3 +1,2 @@
1015 a
1015 a
1016 -m1
1016 -m1
1017 -m2
1017 -m2
1018 +5
1018 +5
1019 diff --git a/a b/d
1019 diff --git a/a b/d
1020 copy from a
1020 copy from a
1021 copy to d
1021 copy to d
1022 --- a/a
1022 --- a/a
1023 +++ b/d
1023 +++ b/d
1024 @@ -1,3 +1,2 @@
1024 @@ -1,3 +1,2 @@
1025 a
1025 a
1026 -m1
1026 -m1
1027 -m2
1027 -m2
1028 +5
1028 +5
1029 diff --git a/x/y b/x/y
1029 diff --git a/x/y b/x/y
1030 deleted file mode 100644
1030 deleted file mode 100644
1031 --- a/x/y
1031 --- a/x/y
1032 +++ /dev/null
1032 +++ /dev/null
1033 @@ -1,1 +0,0 @@
1033 @@ -1,1 +0,0 @@
1034 -y1
1034 -y1
1035
1035
1036 # root to parent:
1036 # root to parent:
1037
1037
1038 % hg st -C --rev 0 --rev .
1038 % hg st -C --rev 0 --rev .
1039 M a
1039 M a
1040 A b
1040 A b
1041 a
1041 a
1042 A c
1042 A c
1043 a
1043 a
1044
1044
1045 % hg diff --git --rev 0 --rev .
1045 % hg diff --git --rev 0 --rev .
1046 diff --git a/a b/a
1046 diff --git a/a b/a
1047 --- a/a
1047 --- a/a
1048 +++ b/a
1048 +++ b/a
1049 @@ -1,1 +1,2 @@
1049 @@ -1,1 +1,2 @@
1050 a
1050 a
1051 +5
1051 +5
1052 diff --git a/a b/b
1052 diff --git a/a b/b
1053 copy from a
1053 copy from a
1054 copy to b
1054 copy to b
1055 --- a/a
1055 --- a/a
1056 +++ b/b
1056 +++ b/b
1057 @@ -1,1 +1,2 @@
1057 @@ -1,1 +1,2 @@
1058 a
1058 a
1059 +5
1059 +5
1060 diff --git a/a b/c
1060 diff --git a/a b/c
1061 copy from a
1061 copy from a
1062 copy to c
1062 copy to c
1063 --- a/a
1063 --- a/a
1064 +++ b/c
1064 +++ b/c
1065 @@ -1,1 +1,2 @@
1065 @@ -1,1 +1,2 @@
1066 a
1066 a
1067 +5
1067 +5
1068
1068
1069 # parent to root:
1069 # parent to root:
1070
1070
1071 % hg st -C --rev . --rev 0
1071 % hg st -C --rev . --rev 0
1072 M a
1072 M a
1073 R b
1073 R b
1074 R c
1074 R c
1075
1075
1076 % hg diff --git --rev . --rev 0
1076 % hg diff --git --rev . --rev 0
1077 diff --git a/a b/a
1077 diff --git a/a b/a
1078 --- a/a
1078 --- a/a
1079 +++ b/a
1079 +++ b/a
1080 @@ -1,2 +1,1 @@
1080 @@ -1,2 +1,1 @@
1081 a
1081 a
1082 -5
1082 -5
1083 diff --git a/b b/b
1083 diff --git a/b b/b
1084 deleted file mode 100644
1084 deleted file mode 100644
1085 --- a/b
1085 --- a/b
1086 +++ /dev/null
1086 +++ /dev/null
1087 @@ -1,2 +0,0 @@
1087 @@ -1,2 +0,0 @@
1088 -a
1088 -a
1089 -5
1089 -5
1090 diff --git a/c b/c
1090 diff --git a/c b/c
1091 deleted file mode 100644
1091 deleted file mode 100644
1092 --- a/c
1092 --- a/c
1093 +++ /dev/null
1093 +++ /dev/null
1094 @@ -1,2 +0,0 @@
1094 @@ -1,2 +0,0 @@
1095 -a
1095 -a
1096 -5
1096 -5
1097
1097
1098 # branch to parent:
1098 # branch to parent:
1099
1099
1100 % hg st -C --rev 2 --rev .
1100 % hg st -C --rev 2 --rev .
1101 M a
1101 M a
1102 A b
1102 A b
1103 a
1103 a
1104 A c
1104 A c
1105 a
1105 a
1106 R x/y
1106 R x/y
1107
1107
1108 % hg diff --git --rev 2 --rev .
1108 % hg diff --git --rev 2 --rev .
1109 diff --git a/a b/a
1109 diff --git a/a b/a
1110 --- a/a
1110 --- a/a
1111 +++ b/a
1111 +++ b/a
1112 @@ -1,3 +1,2 @@
1112 @@ -1,3 +1,2 @@
1113 a
1113 a
1114 -m1
1114 -m1
1115 -m2
1115 -m2
1116 +5
1116 +5
1117 diff --git a/a b/b
1117 diff --git a/a b/b
1118 copy from a
1118 copy from a
1119 copy to b
1119 copy to b
1120 --- a/a
1120 --- a/a
1121 +++ b/b
1121 +++ b/b
1122 @@ -1,3 +1,2 @@
1122 @@ -1,3 +1,2 @@
1123 a
1123 a
1124 -m1
1124 -m1
1125 -m2
1125 -m2
1126 +5
1126 +5
1127 diff --git a/a b/c
1127 diff --git a/a b/c
1128 copy from a
1128 copy from a
1129 copy to c
1129 copy to c
1130 --- a/a
1130 --- a/a
1131 +++ b/c
1131 +++ b/c
1132 @@ -1,3 +1,2 @@
1132 @@ -1,3 +1,2 @@
1133 a
1133 a
1134 -m1
1134 -m1
1135 -m2
1135 -m2
1136 +5
1136 +5
1137 diff --git a/x/y b/x/y
1137 diff --git a/x/y b/x/y
1138 deleted file mode 100644
1138 deleted file mode 100644
1139 --- a/x/y
1139 --- a/x/y
1140 +++ /dev/null
1140 +++ /dev/null
1141 @@ -1,1 +0,0 @@
1141 @@ -1,1 +0,0 @@
1142 -y1
1142 -y1
1143
1143
1144 # parent to branch:
1144 # parent to branch:
1145
1145
1146 % hg st -C --rev . --rev 2
1146 % hg st -C --rev . --rev 2
1147 M a
1147 M a
1148 A x/y
1148 A x/y
1149 R b
1149 R b
1150 R c
1150 R c
1151
1151
1152 % hg diff --git --rev . --rev 2
1152 % hg diff --git --rev . --rev 2
1153 diff --git a/a b/a
1153 diff --git a/a b/a
1154 --- a/a
1154 --- a/a
1155 +++ b/a
1155 +++ b/a
1156 @@ -1,2 +1,3 @@
1156 @@ -1,2 +1,3 @@
1157 a
1157 a
1158 -5
1158 -5
1159 +m1
1159 +m1
1160 +m2
1160 +m2
1161 diff --git a/b b/b
1161 diff --git a/b b/b
1162 deleted file mode 100644
1162 deleted file mode 100644
1163 --- a/b
1163 --- a/b
1164 +++ /dev/null
1164 +++ /dev/null
1165 @@ -1,2 +0,0 @@
1165 @@ -1,2 +0,0 @@
1166 -a
1166 -a
1167 -5
1167 -5
1168 diff --git a/c b/c
1168 diff --git a/c b/c
1169 deleted file mode 100644
1169 deleted file mode 100644
1170 --- a/c
1170 --- a/c
1171 +++ /dev/null
1171 +++ /dev/null
1172 @@ -1,2 +0,0 @@
1172 @@ -1,2 +0,0 @@
1173 -a
1173 -a
1174 -5
1174 -5
1175 diff --git a/x/y b/x/y
1175 diff --git a/x/y b/x/y
1176 new file mode 100644
1176 new file mode 100644
1177 --- /dev/null
1177 --- /dev/null
1178 +++ b/x/y
1178 +++ b/x/y
1179 @@ -0,0 +1,1 @@
1179 @@ -0,0 +1,1 @@
1180 +y1
1180 +y1
1181
1181
1182
1182
1183 circular rename
1183 circular rename
1184
1184
1185 $ tb "add a a1" "hg mv a b" "hg mv b a"
1185 $ tb "add a a1" "hg mv a b" "hg mv b a"
1186 % add a 6
1186 % add a 6
1187 % hg ci -m t0
1187 % hg ci -m t0
1188 created new head
1188 created new head
1189 % add a a1
1189 % add a a1
1190 % hg ci -m t1
1190 % hg ci -m t1
1191 % hg mv a b
1191 % hg mv a b
1192 % hg ci -m t2
1192 % hg ci -m t2
1193 % hg mv b a
1193 % hg mv b a
1194
1194
1195 # working to parent:
1195 # working to parent:
1196
1196
1197 % hg st -C
1197 % hg st -C
1198 A a
1198 A a
1199 b
1199 b
1200 R b
1200 R b
1201
1201
1202 % hg diff --git
1202 % hg diff --git
1203 diff --git a/b b/a
1203 diff --git a/b b/a
1204 rename from b
1204 rename from b
1205 rename to a
1205 rename to a
1206
1206
1207 # working to root:
1207 # working to root:
1208
1208
1209 % hg st -C --rev 0
1209 % hg st -C --rev 0
1210 M a
1210 M a
1211
1211
1212 % hg diff --git --rev 0
1212 % hg diff --git --rev 0
1213 diff --git a/a b/a
1213 diff --git a/a b/a
1214 --- a/a
1214 --- a/a
1215 +++ b/a
1215 +++ b/a
1216 @@ -1,1 +1,3 @@
1216 @@ -1,1 +1,3 @@
1217 a
1217 a
1218 +6
1218 +6
1219 +a1
1219 +a1
1220
1220
1221 # working to branch:
1221 # working to branch:
1222
1222
1223 % hg st -C --rev 2
1223 % hg st -C --rev 2
1224 M a
1224 M a
1225 R x/y
1225 R x/y
1226
1226
1227 % hg diff --git --rev 2
1227 % hg diff --git --rev 2
1228 diff --git a/a b/a
1228 diff --git a/a b/a
1229 --- a/a
1229 --- a/a
1230 +++ b/a
1230 +++ b/a
1231 @@ -1,3 +1,3 @@
1231 @@ -1,3 +1,3 @@
1232 a
1232 a
1233 -m1
1233 -m1
1234 -m2
1234 -m2
1235 +6
1235 +6
1236 +a1
1236 +a1
1237 diff --git a/x/y b/x/y
1237 diff --git a/x/y b/x/y
1238 deleted file mode 100644
1238 deleted file mode 100644
1239 --- a/x/y
1239 --- a/x/y
1240 +++ /dev/null
1240 +++ /dev/null
1241 @@ -1,1 +0,0 @@
1241 @@ -1,1 +0,0 @@
1242 -y1
1242 -y1
1243
1243
1244 # root to parent:
1244 # root to parent:
1245
1245
1246 % hg st -C --rev 0 --rev .
1246 % hg st -C --rev 0 --rev .
1247 A b
1247 A b
1248 a
1248 a
1249 R a
1249 R a
1250
1250
1251 % hg diff --git --rev 0 --rev .
1251 % hg diff --git --rev 0 --rev .
1252 diff --git a/a b/b
1252 diff --git a/a b/b
1253 rename from a
1253 rename from a
1254 rename to b
1254 rename to b
1255 --- a/a
1255 --- a/a
1256 +++ b/b
1256 +++ b/b
1257 @@ -1,1 +1,3 @@
1257 @@ -1,1 +1,3 @@
1258 a
1258 a
1259 +6
1259 +6
1260 +a1
1260 +a1
1261
1261
1262 # parent to root:
1262 # parent to root:
1263
1263
1264 % hg st -C --rev . --rev 0
1264 % hg st -C --rev . --rev 0
1265 A a
1265 A a
1266 b
1266 b
1267 R b
1267 R b
1268
1268
1269 % hg diff --git --rev . --rev 0
1269 % hg diff --git --rev . --rev 0
1270 diff --git a/b b/a
1270 diff --git a/b b/a
1271 rename from b
1271 rename from b
1272 rename to a
1272 rename to a
1273 --- a/b
1273 --- a/b
1274 +++ b/a
1274 +++ b/a
1275 @@ -1,3 +1,1 @@
1275 @@ -1,3 +1,1 @@
1276 a
1276 a
1277 -6
1277 -6
1278 -a1
1278 -a1
1279
1279
1280 # branch to parent:
1280 # branch to parent:
1281
1281
1282 % hg st -C --rev 2 --rev .
1282 % hg st -C --rev 2 --rev .
1283 A b
1283 A b
1284 a
1284 a
1285 R a
1285 R a
1286 R x/y
1286 R x/y
1287
1287
1288 % hg diff --git --rev 2 --rev .
1288 % hg diff --git --rev 2 --rev .
1289 diff --git a/a b/b
1289 diff --git a/a b/b
1290 rename from a
1290 rename from a
1291 rename to b
1291 rename to b
1292 --- a/a
1292 --- a/a
1293 +++ b/b
1293 +++ b/b
1294 @@ -1,3 +1,3 @@
1294 @@ -1,3 +1,3 @@
1295 a
1295 a
1296 -m1
1296 -m1
1297 -m2
1297 -m2
1298 +6
1298 +6
1299 +a1
1299 +a1
1300 diff --git a/x/y b/x/y
1300 diff --git a/x/y b/x/y
1301 deleted file mode 100644
1301 deleted file mode 100644
1302 --- a/x/y
1302 --- a/x/y
1303 +++ /dev/null
1303 +++ /dev/null
1304 @@ -1,1 +0,0 @@
1304 @@ -1,1 +0,0 @@
1305 -y1
1305 -y1
1306
1306
1307 # parent to branch:
1307 # parent to branch:
1308
1308
1309 % hg st -C --rev . --rev 2
1309 % hg st -C --rev . --rev 2
1310 A a
1310 A a
1311 b
1311 b
1312 A x/y
1312 A x/y
1313 R b
1313 R b
1314
1314
1315 % hg diff --git --rev . --rev 2
1315 % hg diff --git --rev . --rev 2
1316 diff --git a/b b/a
1316 diff --git a/b b/a
1317 rename from b
1317 rename from b
1318 rename to a
1318 rename to a
1319 --- a/b
1319 --- a/b
1320 +++ b/a
1320 +++ b/a
1321 @@ -1,3 +1,3 @@
1321 @@ -1,3 +1,3 @@
1322 a
1322 a
1323 -6
1323 -6
1324 -a1
1324 -a1
1325 +m1
1325 +m1
1326 +m2
1326 +m2
1327 diff --git a/x/y b/x/y
1327 diff --git a/x/y b/x/y
1328 new file mode 100644
1328 new file mode 100644
1329 --- /dev/null
1329 --- /dev/null
1330 +++ b/x/y
1330 +++ b/x/y
1331 @@ -0,0 +1,1 @@
1331 @@ -0,0 +1,1 @@
1332 +y1
1332 +y1
1333
1333
1334
1334
1335 directory move
1335 directory move
1336
1336
1337 $ tb "hg mv x y" "add y/x x1" "add y/x x2"
1337 $ tb "hg mv x y" "add y/x x1" "add y/x x2"
1338 % add a 7
1338 % add a 7
1339 % hg ci -m t0
1339 % hg ci -m t0
1340 created new head
1340 created new head
1341 % hg mv x y
1341 % hg mv x y
1342 moving x/x to y/x (glob)
1342 moving x/x to y/x (glob)
1343 % hg ci -m t1
1343 % hg ci -m t1
1344 % add y/x x1
1344 % add y/x x1
1345 % hg ci -m t2
1345 % hg ci -m t2
1346 % add y/x x2
1346 % add y/x x2
1347
1347
1348 # working to parent:
1348 # working to parent:
1349
1349
1350 % hg st -C
1350 % hg st -C
1351 M y/x
1351 M y/x
1352
1352
1353 % hg diff --git
1353 % hg diff --git
1354 diff --git a/y/x b/y/x
1354 diff --git a/y/x b/y/x
1355 --- a/y/x
1355 --- a/y/x
1356 +++ b/y/x
1356 +++ b/y/x
1357 @@ -1,2 +1,3 @@
1357 @@ -1,2 +1,3 @@
1358 x
1358 x
1359 x1
1359 x1
1360 +x2
1360 +x2
1361
1361
1362 # working to root:
1362 # working to root:
1363
1363
1364 % hg st -C --rev 0
1364 % hg st -C --rev 0
1365 M a
1365 M a
1366 A y/x
1366 A y/x
1367 x/x
1367 x/x
1368 R x/x
1368 R x/x
1369
1369
1370 % hg diff --git --rev 0
1370 % hg diff --git --rev 0
1371 diff --git a/a b/a
1371 diff --git a/a b/a
1372 --- a/a
1372 --- a/a
1373 +++ b/a
1373 +++ b/a
1374 @@ -1,1 +1,2 @@
1374 @@ -1,1 +1,2 @@
1375 a
1375 a
1376 +7
1376 +7
1377 diff --git a/x/x b/y/x
1377 diff --git a/x/x b/y/x
1378 rename from x/x
1378 rename from x/x
1379 rename to y/x
1379 rename to y/x
1380 --- a/x/x
1380 --- a/x/x
1381 +++ b/y/x
1381 +++ b/y/x
1382 @@ -1,1 +1,3 @@
1382 @@ -1,1 +1,3 @@
1383 x
1383 x
1384 +x1
1384 +x1
1385 +x2
1385 +x2
1386
1386
1387 # working to branch:
1387 # working to branch:
1388
1388
1389 % hg st -C --rev 2
1389 % hg st -C --rev 2
1390 M a
1390 M a
1391 A y/x
1391 A y/x
1392 x/x
1392 x/x
1393 R x/x
1393 R x/x
1394 R x/y
1394 R x/y
1395
1395
1396 % hg diff --git --rev 2
1396 % hg diff --git --rev 2
1397 diff --git a/a b/a
1397 diff --git a/a b/a
1398 --- a/a
1398 --- a/a
1399 +++ b/a
1399 +++ b/a
1400 @@ -1,3 +1,2 @@
1400 @@ -1,3 +1,2 @@
1401 a
1401 a
1402 -m1
1402 -m1
1403 -m2
1403 -m2
1404 +7
1404 +7
1405 diff --git a/x/y b/x/y
1405 diff --git a/x/y b/x/y
1406 deleted file mode 100644
1406 deleted file mode 100644
1407 --- a/x/y
1407 --- a/x/y
1408 +++ /dev/null
1408 +++ /dev/null
1409 @@ -1,1 +0,0 @@
1409 @@ -1,1 +0,0 @@
1410 -y1
1410 -y1
1411 diff --git a/x/x b/y/x
1411 diff --git a/x/x b/y/x
1412 rename from x/x
1412 rename from x/x
1413 rename to y/x
1413 rename to y/x
1414 --- a/x/x
1414 --- a/x/x
1415 +++ b/y/x
1415 +++ b/y/x
1416 @@ -1,1 +1,3 @@
1416 @@ -1,1 +1,3 @@
1417 x
1417 x
1418 +x1
1418 +x1
1419 +x2
1419 +x2
1420
1420
1421 # root to parent:
1421 # root to parent:
1422
1422
1423 % hg st -C --rev 0 --rev .
1423 % hg st -C --rev 0 --rev .
1424 M a
1424 M a
1425 A y/x
1425 A y/x
1426 x/x
1426 x/x
1427 R x/x
1427 R x/x
1428
1428
1429 % hg diff --git --rev 0 --rev .
1429 % hg diff --git --rev 0 --rev .
1430 diff --git a/a b/a
1430 diff --git a/a b/a
1431 --- a/a
1431 --- a/a
1432 +++ b/a
1432 +++ b/a
1433 @@ -1,1 +1,2 @@
1433 @@ -1,1 +1,2 @@
1434 a
1434 a
1435 +7
1435 +7
1436 diff --git a/x/x b/y/x
1436 diff --git a/x/x b/y/x
1437 rename from x/x
1437 rename from x/x
1438 rename to y/x
1438 rename to y/x
1439 --- a/x/x
1439 --- a/x/x
1440 +++ b/y/x
1440 +++ b/y/x
1441 @@ -1,1 +1,2 @@
1441 @@ -1,1 +1,2 @@
1442 x
1442 x
1443 +x1
1443 +x1
1444
1444
1445 # parent to root:
1445 # parent to root:
1446
1446
1447 % hg st -C --rev . --rev 0
1447 % hg st -C --rev . --rev 0
1448 M a
1448 M a
1449 A x/x
1449 A x/x
1450 y/x
1450 y/x
1451 R y/x
1451 R y/x
1452
1452
1453 % hg diff --git --rev . --rev 0
1453 % hg diff --git --rev . --rev 0
1454 diff --git a/a b/a
1454 diff --git a/a b/a
1455 --- a/a
1455 --- a/a
1456 +++ b/a
1456 +++ b/a
1457 @@ -1,2 +1,1 @@
1457 @@ -1,2 +1,1 @@
1458 a
1458 a
1459 -7
1459 -7
1460 diff --git a/y/x b/x/x
1460 diff --git a/y/x b/x/x
1461 rename from y/x
1461 rename from y/x
1462 rename to x/x
1462 rename to x/x
1463 --- a/y/x
1463 --- a/y/x
1464 +++ b/x/x
1464 +++ b/x/x
1465 @@ -1,2 +1,1 @@
1465 @@ -1,2 +1,1 @@
1466 x
1466 x
1467 -x1
1467 -x1
1468
1468
1469 # branch to parent:
1469 # branch to parent:
1470
1470
1471 % hg st -C --rev 2 --rev .
1471 % hg st -C --rev 2 --rev .
1472 M a
1472 M a
1473 A y/x
1473 A y/x
1474 x/x
1474 x/x
1475 R x/x
1475 R x/x
1476 R x/y
1476 R x/y
1477
1477
1478 % hg diff --git --rev 2 --rev .
1478 % hg diff --git --rev 2 --rev .
1479 diff --git a/a b/a
1479 diff --git a/a b/a
1480 --- a/a
1480 --- a/a
1481 +++ b/a
1481 +++ b/a
1482 @@ -1,3 +1,2 @@
1482 @@ -1,3 +1,2 @@
1483 a
1483 a
1484 -m1
1484 -m1
1485 -m2
1485 -m2
1486 +7
1486 +7
1487 diff --git a/x/y b/x/y
1487 diff --git a/x/y b/x/y
1488 deleted file mode 100644
1488 deleted file mode 100644
1489 --- a/x/y
1489 --- a/x/y
1490 +++ /dev/null
1490 +++ /dev/null
1491 @@ -1,1 +0,0 @@
1491 @@ -1,1 +0,0 @@
1492 -y1
1492 -y1
1493 diff --git a/x/x b/y/x
1493 diff --git a/x/x b/y/x
1494 rename from x/x
1494 rename from x/x
1495 rename to y/x
1495 rename to y/x
1496 --- a/x/x
1496 --- a/x/x
1497 +++ b/y/x
1497 +++ b/y/x
1498 @@ -1,1 +1,2 @@
1498 @@ -1,1 +1,2 @@
1499 x
1499 x
1500 +x1
1500 +x1
1501
1501
1502 # parent to branch:
1502 # parent to branch:
1503
1503
1504 % hg st -C --rev . --rev 2
1504 % hg st -C --rev . --rev 2
1505 M a
1505 M a
1506 A x/x
1506 A x/x
1507 y/x
1507 y/x
1508 A x/y
1508 A x/y
1509 R y/x
1509 R y/x
1510
1510
1511 % hg diff --git --rev . --rev 2
1511 % hg diff --git --rev . --rev 2
1512 diff --git a/a b/a
1512 diff --git a/a b/a
1513 --- a/a
1513 --- a/a
1514 +++ b/a
1514 +++ b/a
1515 @@ -1,2 +1,3 @@
1515 @@ -1,2 +1,3 @@
1516 a
1516 a
1517 -7
1517 -7
1518 +m1
1518 +m1
1519 +m2
1519 +m2
1520 diff --git a/y/x b/x/x
1520 diff --git a/y/x b/x/x
1521 rename from y/x
1521 rename from y/x
1522 rename to x/x
1522 rename to x/x
1523 --- a/y/x
1523 --- a/y/x
1524 +++ b/x/x
1524 +++ b/x/x
1525 @@ -1,2 +1,1 @@
1525 @@ -1,2 +1,1 @@
1526 x
1526 x
1527 -x1
1527 -x1
1528 diff --git a/x/y b/x/y
1528 diff --git a/x/y b/x/y
1529 new file mode 100644
1529 new file mode 100644
1530 --- /dev/null
1530 --- /dev/null
1531 +++ b/x/y
1531 +++ b/x/y
1532 @@ -0,0 +1,1 @@
1532 @@ -0,0 +1,1 @@
1533 +y1
1533 +y1
1534
1534
1535
1535
1536
1536
1537 Cannot implement unrelated branch with tb
1537 Cannot implement unrelated branch with tb
1538 testing copies with unrelated branch
1538 testing copies with unrelated branch
1539
1539
1540 $ hg init unrelated
1540 $ hg init unrelated
1541 $ cd unrelated
1541 $ cd unrelated
1542 $ echo a >> a
1542 $ echo a >> a
1543 $ hg ci -Am adda
1543 $ hg ci -Am adda
1544 adding a
1544 adding a
1545 $ hg mv a b
1545 $ hg mv a b
1546 $ hg ci -m movea
1546 $ hg ci -m movea
1547 $ hg up -C null
1547 $ hg up -C null
1548 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1548 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1549 $ echo a >> a
1549 $ echo a >> a
1550 $ hg ci -Am addunrelateda
1550 $ hg ci -Am addunrelateda
1551 adding a
1551 adding a
1552 created new head
1552 created new head
1553
1553
1554 unrelated branch diff
1554 unrelated branch diff
1555
1555
1556 $ hg diff --git -r 2 -r 1
1556 $ hg diff --git -r 2 -r 1
1557 diff --git a/a b/a
1557 diff --git a/a b/a
1558 deleted file mode 100644
1558 deleted file mode 100644
1559 --- a/a
1559 --- a/a
1560 +++ /dev/null
1560 +++ /dev/null
1561 @@ -1,1 +0,0 @@
1561 @@ -1,1 +0,0 @@
1562 -a
1562 -a
1563 diff --git a/b b/b
1563 diff --git a/b b/b
1564 new file mode 100644
1564 new file mode 100644
1565 --- /dev/null
1565 --- /dev/null
1566 +++ b/b
1566 +++ b/b
1567 @@ -0,0 +1,1 @@
1567 @@ -0,0 +1,1 @@
1568 +a
1568 +a
1569 $ cd ..
1569 $ cd ..
1570
1570
1571
1571
1572 test for case where we didn't look sufficiently far back to find rename ancestor
1572 test for case where we didn't look sufficiently far back to find rename ancestor
1573
1573
1574 $ hg init diffstop
1574 $ hg init diffstop
1575 $ cd diffstop
1575 $ cd diffstop
1576 $ echo > f
1576 $ echo > f
1577 $ hg ci -qAmf
1577 $ hg ci -qAmf
1578 $ hg mv f g
1578 $ hg mv f g
1579 $ hg ci -m'f->g'
1579 $ hg ci -m'f->g'
1580 $ hg up -qr0
1580 $ hg up -qr0
1581 $ touch x
1581 $ touch x
1582 $ hg ci -qAmx
1582 $ hg ci -qAmx
1583 $ echo f > f
1583 $ echo f > f
1584 $ hg ci -qmf=f
1584 $ hg ci -qmf=f
1585 $ hg merge -q
1585 $ hg merge -q
1586 $ hg ci -mmerge
1586 $ hg ci -mmerge
1587 $ hg log -G --template '{rev} {desc}'
1587 $ hg log -G --template '{rev} {desc}'
1588 @ 4 merge
1588 @ 4 merge
1589 |\
1589 |\
1590 | o 3 f=f
1590 | o 3 f=f
1591 | |
1591 | |
1592 | o 2 x
1592 | o 2 x
1593 | |
1593 | |
1594 o | 1 f->g
1594 o | 1 f->g
1595 |/
1595 |/
1596 o 0 f
1596 o 0 f
1597
1597
1598 $ hg diff --git -r 2
1598 $ hg diff --git -r 2
1599 diff --git a/f b/g
1599 diff --git a/f b/g
1600 rename from f
1600 rename from f
1601 rename to g
1601 rename to g
1602 --- a/f
1602 --- a/f
1603 +++ b/g
1603 +++ b/g
1604 @@ -1,1 +1,1 @@
1604 @@ -1,1 +1,1 @@
1605 -
1605 -
1606 +f
1606 +f
1607 $ cd ..
1607 $ cd ..
1608
1609 Additional tricky linkrev case
1610 ------------------------------
1611
1612 If the first file revision after the diff base has a linkrev pointing to a
1613 changeset on another branch with a revision lower that the diff base, we can
1614 jump past the copy detection limit and fail to detect the rename.
1615
1616 $ hg init diffstoplinkrev
1617 $ cd diffstoplinkrev
1618
1619 $ touch f
1620 $ hg ci -Aqm 'empty f'
1621
1622 Make a simple change
1623
1624 $ echo change > f
1625 $ hg ci -m 'change f'
1626
1627 Make a second branch, we use a named branch to create a simple commit
1628 that does not touch f.
1629
1630 $ hg up -qr 'desc(empty)'
1631 $ hg branch -q dev
1632 $ hg ci -Aqm dev
1633
1634 Graft the initial change, as f was untouched, we reuse the same entry and the
1635 linkrev point to the older branch.
1636
1637 $ hg graft -q 'desc(change)'
1638
1639 Make a rename because we want to track renames. It is also important that the
1640 faulty linkrev is not the "start" commit to ensure the linkrev will be used.
1641
1642 $ hg mv f renamed
1643 $ hg ci -m renamed
1644
1645 $ hg log -G -T '{rev} {desc}'
1646 @ 4 renamed
1647 |
1648 o 3 change f
1649 |
1650 o 2 dev
1651 |
1652 | o 1 change f
1653 |/
1654 o 0 empty f
1655
1656
1657 The copy tracking should still reach rev 2 (branch creation).
1658 accessing the parent of 4 (renamed) should not jump use to revision 1.
1659
1660 $ hg diff --git -r 'desc(dev)' -r .
1661 diff --git a/f b/renamed
1662 rename from f
1663 rename to renamed
1664 --- a/f
1665 +++ b/renamed
1666 @@ -0,0 +1,1 @@
1667 +change
1668
1669 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now