##// END OF EJS Templates
rev-branch-cache: stop pretending we will overwrite data when we don't...
marmoute -
r52867:4c885d5f default
parent child Browse files
Show More
@@ -1,427 +1,434
1 # rev_cache.py - caching branch information per revision
1 # rev_cache.py - caching branch information per revision
2 #
2 #
3 # This software may be used and distributed according to the terms of the
3 # This software may be used and distributed according to the terms of the
4 # GNU General Public License version 2 or any later version.
4 # GNU General Public License version 2 or any later version.
5 from __future__ import annotations
5 from __future__ import annotations
6
6
7 import os
7 import os
8 import struct
8 import struct
9
9
10 from ..node import (
10 from ..node import (
11 nullrev,
11 nullrev,
12 )
12 )
13
13
14 from .. import (
14 from .. import (
15 encoding,
15 encoding,
16 error,
16 error,
17 util,
17 util,
18 )
18 )
19
19
20 from ..utils import (
20 from ..utils import (
21 stringutil,
21 stringutil,
22 )
22 )
23
23
24 calcsize = struct.calcsize
24 calcsize = struct.calcsize
25 pack_into = struct.pack_into
25 pack_into = struct.pack_into
26 unpack_from = struct.unpack_from
26 unpack_from = struct.unpack_from
27
27
28
28
29 # Revision branch info cache
29 # Revision branch info cache
30
30
31 # The "V2" version use the same format as the "V1" but garantee it won't be
31 # The "V2" version use the same format as the "V1" but garantee it won't be
32 # truncated, preventing SIGBUS when it is mmap-ed
32 # truncated, preventing SIGBUS when it is mmap-ed
33 _rbcversion = b'-v2'
33 _rbcversion = b'-v2'
34 _rbcnames = b'rbc-names' + _rbcversion
34 _rbcnames = b'rbc-names' + _rbcversion
35 _rbcrevs = b'rbc-revs' + _rbcversion
35 _rbcrevs = b'rbc-revs' + _rbcversion
36 _rbc_legacy_version = b'-v1'
36 _rbc_legacy_version = b'-v1'
37 _rbc_legacy_names = b'rbc-names' + _rbc_legacy_version
37 _rbc_legacy_names = b'rbc-names' + _rbc_legacy_version
38 _rbc_legacy_revs = b'rbc-revs' + _rbc_legacy_version
38 _rbc_legacy_revs = b'rbc-revs' + _rbc_legacy_version
39 # [4 byte hash prefix][4 byte branch name number with sign bit indicating open]
39 # [4 byte hash prefix][4 byte branch name number with sign bit indicating open]
40 _rbcrecfmt = b'>4sI'
40 _rbcrecfmt = b'>4sI'
41 _rbcrecsize = calcsize(_rbcrecfmt)
41 _rbcrecsize = calcsize(_rbcrecfmt)
42 _rbcmininc = 64 * _rbcrecsize
42 _rbcmininc = 64 * _rbcrecsize
43 _rbcnodelen = 4
43 _rbcnodelen = 4
44 _rbcbranchidxmask = 0x7FFFFFFF
44 _rbcbranchidxmask = 0x7FFFFFFF
45 _rbccloseflag = 0x80000000
45 _rbccloseflag = 0x80000000
46
46
47
47
48 # with atomic replacement.
48 # with atomic replacement.
49 REWRITE_RATIO = 0.2
49 REWRITE_RATIO = 0.2
50
50
51
51
52 class rbcrevs:
52 class rbcrevs:
53 """a byte string consisting of an immutable prefix followed by a mutable suffix"""
53 """a byte string consisting of an immutable prefix followed by a mutable suffix"""
54
54
55 def __init__(self, revs):
55 def __init__(self, revs):
56 self._prefix = revs
56 self._prefix = revs
57 self._rest = bytearray()
57 self._rest = bytearray()
58
58
59 def __len__(self):
59 def __len__(self):
60 return len(self._prefix) + len(self._rest)
60 return len(self._prefix) + len(self._rest)
61
61
62 def unpack_record(self, rbcrevidx):
62 def unpack_record(self, rbcrevidx):
63 if rbcrevidx < len(self._prefix):
63 if rbcrevidx < len(self._prefix):
64 return unpack_from(_rbcrecfmt, util.buffer(self._prefix), rbcrevidx)
64 return unpack_from(_rbcrecfmt, util.buffer(self._prefix), rbcrevidx)
65 else:
65 else:
66 return unpack_from(
66 return unpack_from(
67 _rbcrecfmt,
67 _rbcrecfmt,
68 util.buffer(self._rest),
68 util.buffer(self._rest),
69 rbcrevidx - len(self._prefix),
69 rbcrevidx - len(self._prefix),
70 )
70 )
71
71
72 def make_mutable(self):
72 def make_mutable(self):
73 if len(self._prefix) > 0:
73 if len(self._prefix) > 0:
74 entirety = bytearray()
74 entirety = bytearray()
75 entirety[:] = self._prefix
75 entirety[:] = self._prefix
76 entirety.extend(self._rest)
76 entirety.extend(self._rest)
77 self._rest = entirety
77 self._rest = entirety
78 self._prefix = bytearray()
78 self._prefix = bytearray()
79
79
80 def truncate(self, pos):
80 def truncate(self, pos):
81 self.make_mutable()
81 self.make_mutable()
82 del self._rest[pos:]
82 del self._rest[pos:]
83
83
84 def pack_into(self, rbcrevidx, node, branchidx):
84 def pack_into(self, rbcrevidx, node, branchidx):
85 if rbcrevidx < len(self._prefix):
85 if rbcrevidx < len(self._prefix):
86 self.make_mutable()
86 self.make_mutable()
87 buf = self._rest
87 buf = self._rest
88 start_offset = rbcrevidx - len(self._prefix)
88 start_offset = rbcrevidx - len(self._prefix)
89 end_offset = start_offset + _rbcrecsize
89 end_offset = start_offset + _rbcrecsize
90
90
91 if len(self._rest) < end_offset:
91 if len(self._rest) < end_offset:
92 # bytearray doesn't allocate extra space at least in Python 3.7.
92 # bytearray doesn't allocate extra space at least in Python 3.7.
93 # When multiple changesets are added in a row, precise resize would
93 # When multiple changesets are added in a row, precise resize would
94 # result in quadratic complexity. Overallocate to compensate by
94 # result in quadratic complexity. Overallocate to compensate by
95 # using the classic doubling technique for dynamic arrays instead.
95 # using the classic doubling technique for dynamic arrays instead.
96 # If there was a gap in the map before, less space will be reserved.
96 # If there was a gap in the map before, less space will be reserved.
97 self._rest.extend(b'\0' * end_offset)
97 self._rest.extend(b'\0' * end_offset)
98 return pack_into(
98 return pack_into(
99 _rbcrecfmt,
99 _rbcrecfmt,
100 buf,
100 buf,
101 start_offset,
101 start_offset,
102 node,
102 node,
103 branchidx,
103 branchidx,
104 )
104 )
105
105
106 def extend(self, extension):
106 def extend(self, extension):
107 return self._rest.extend(extension)
107 return self._rest.extend(extension)
108
108
109 def slice(self, begin, end):
109 def slice(self, begin, end):
110 if begin < len(self._prefix):
110 if begin < len(self._prefix):
111 acc = bytearray()
111 acc = bytearray()
112 acc[:] = self._prefix[begin:end]
112 acc[:] = self._prefix[begin:end]
113 acc.extend(
113 acc.extend(
114 self._rest[begin - len(self._prefix) : end - len(self._prefix)]
114 self._rest[begin - len(self._prefix) : end - len(self._prefix)]
115 )
115 )
116 return acc
116 return acc
117 return self._rest[begin - len(self._prefix) : end - len(self._prefix)]
117 return self._rest[begin - len(self._prefix) : end - len(self._prefix)]
118
118
119
119
120 class revbranchcache:
120 class revbranchcache:
121 """Persistent cache, mapping from revision number to branch name and close.
121 """Persistent cache, mapping from revision number to branch name and close.
122 This is a low level cache, independent of filtering.
122 This is a low level cache, independent of filtering.
123
123
124 Branch names are stored in rbc-names in internal encoding separated by 0.
124 Branch names are stored in rbc-names in internal encoding separated by 0.
125 rbc-names is append-only, and each branch name is only stored once and will
125 rbc-names is append-only, and each branch name is only stored once and will
126 thus have a unique index.
126 thus have a unique index.
127
127
128 The branch info for each revision is stored in rbc-revs as constant size
128 The branch info for each revision is stored in rbc-revs as constant size
129 records. The whole file is read into memory, but it is only 'parsed' on
129 records. The whole file is read into memory, but it is only 'parsed' on
130 demand. The file is usually append-only but will be truncated if repo
130 demand. The file is usually append-only but will be truncated if repo
131 modification is detected.
131 modification is detected.
132 The record for each revision contains the first 4 bytes of the
132 The record for each revision contains the first 4 bytes of the
133 corresponding node hash, and the record is only used if it still matches.
133 corresponding node hash, and the record is only used if it still matches.
134 Even a completely trashed rbc-revs fill thus still give the right result
134 Even a completely trashed rbc-revs fill thus still give the right result
135 while converging towards full recovery ... assuming no incorrectly matching
135 while converging towards full recovery ... assuming no incorrectly matching
136 node hashes.
136 node hashes.
137 The record also contains 4 bytes where 31 bits contains the index of the
137 The record also contains 4 bytes where 31 bits contains the index of the
138 branch and the last bit indicate that it is a branch close commit.
138 branch and the last bit indicate that it is a branch close commit.
139 The usage pattern for rbc-revs is thus somewhat similar to 00changelog.i
139 The usage pattern for rbc-revs is thus somewhat similar to 00changelog.i
140 and will grow with it but be 1/8th of its size.
140 and will grow with it but be 1/8th of its size.
141 """
141 """
142
142
143 def __init__(self, repo, readonly=True):
143 def __init__(self, repo, readonly=True):
144 assert repo.filtername is None
144 assert repo.filtername is None
145 self._repo = repo
145 self._repo = repo
146 self._names = [] # branch names in local encoding with static index
146 self._names = [] # branch names in local encoding with static index
147 self._rbcrevs = rbcrevs(bytearray())
147 self._rbcrevs = rbcrevs(bytearray())
148 self._rbcsnameslen = 0 # length of names read at _rbcsnameslen
148 self._rbcsnameslen = 0 # length of names read at _rbcsnameslen
149 self._force_overwrite = False
149 self._force_overwrite = False
150 v1_fallback = False
150 v1_fallback = False
151 try:
151 try:
152 try:
152 try:
153 bndata = repo.cachevfs.read(_rbcnames)
153 bndata = repo.cachevfs.read(_rbcnames)
154 except (IOError, OSError):
154 except (IOError, OSError):
155 # If we don't have "v2" data, we might have "v1" data worth
155 # If we don't have "v2" data, we might have "v1" data worth
156 # using.
156 # using.
157 #
157 #
158 # consider stop doing this many version after hg-6.9 release
158 # consider stop doing this many version after hg-6.9 release
159 bndata = repo.cachevfs.read(_rbc_legacy_names)
159 bndata = repo.cachevfs.read(_rbc_legacy_names)
160 v1_fallback = True
160 v1_fallback = True
161 self._force_overwrite = True
161 self._force_overwrite = True
162 self._rbcsnameslen = len(bndata) # for verification before writing
162 self._rbcsnameslen = len(bndata) # for verification before writing
163 if bndata:
163 if bndata:
164 self._names = [
164 self._names = [
165 encoding.tolocal(bn) for bn in bndata.split(b'\0')
165 encoding.tolocal(bn) for bn in bndata.split(b'\0')
166 ]
166 ]
167 except (IOError, OSError):
167 except (IOError, OSError):
168 if readonly:
168 if readonly:
169 # don't try to use cache - fall back to the slow path
169 # don't try to use cache - fall back to the slow path
170 self.branchinfo = self._branchinfo
170 self.branchinfo = self._branchinfo
171
171
172 if self._names:
172 if self._names:
173 try:
173 try:
174 usemmap = repo.ui.configbool(b'storage', b'revbranchcache.mmap')
174 usemmap = repo.ui.configbool(b'storage', b'revbranchcache.mmap')
175 if not v1_fallback:
175 if not v1_fallback:
176 with repo.cachevfs(_rbcrevs) as fp:
176 with repo.cachevfs(_rbcrevs) as fp:
177 if usemmap and repo.cachevfs.is_mmap_safe(_rbcrevs):
177 if usemmap and repo.cachevfs.is_mmap_safe(_rbcrevs):
178 data = util.buffer(util.mmapread(fp))
178 data = util.buffer(util.mmapread(fp))
179 else:
179 else:
180 data = fp.read()
180 data = fp.read()
181 else:
181 else:
182 # If we don't have "v2" data, we might have "v1" data worth
182 # If we don't have "v2" data, we might have "v1" data worth
183 # using.
183 # using.
184 #
184 #
185 # Consider stop doing this many version after hg-6.9
185 # Consider stop doing this many version after hg-6.9
186 # release.
186 # release.
187 with repo.cachevfs(_rbc_legacy_revs) as fp:
187 with repo.cachevfs(_rbc_legacy_revs) as fp:
188 data = fp.read()
188 data = fp.read()
189 self._rbcrevs = rbcrevs(data)
189 self._rbcrevs = rbcrevs(data)
190 except (IOError, OSError) as inst:
190 except (IOError, OSError) as inst:
191 repo.ui.debug(
191 repo.ui.debug(
192 b"couldn't read revision branch cache: %s\n"
192 b"couldn't read revision branch cache: %s\n"
193 % stringutil.forcebytestr(inst)
193 % stringutil.forcebytestr(inst)
194 )
194 )
195 # remember number of good records on disk
195 # remember number of good records on disk
196 self._rbcrevslen = min(
196 self._rbcrevslen = min(
197 len(self._rbcrevs) // _rbcrecsize, len(repo.changelog)
197 len(self._rbcrevs) // _rbcrecsize, len(repo.changelog)
198 )
198 )
199 if self._rbcrevslen == 0:
199 if self._rbcrevslen == 0:
200 self._names = []
200 self._names = []
201 self._rbcnamescount = len(self._names) # number of names read at
201 self._rbcnamescount = len(self._names) # number of names read at
202 # _rbcsnameslen
202 # _rbcsnameslen
203
203
204 def _clear(self):
204 def _clear(self):
205 self._rbcsnameslen = 0
205 self._rbcsnameslen = 0
206 del self._names[:]
206 del self._names[:]
207 self._rbcnamescount = 0
207 self._rbcnamescount = 0
208 self._rbcrevslen = len(self._repo.changelog)
208 self._rbcrevslen = len(self._repo.changelog)
209 self._rbcrevs = rbcrevs(bytearray(self._rbcrevslen * _rbcrecsize))
209 self._rbcrevs = rbcrevs(bytearray(self._rbcrevslen * _rbcrecsize))
210 util.clearcachedproperty(self, b'_namesreverse')
210 util.clearcachedproperty(self, b'_namesreverse')
211 self._force_overwrite = True
211 self._force_overwrite = True
212
212
213 def invalidate(self, rev=0):
213 def invalidate(self, rev=0):
214 self._rbcrevslen = rev
214 self._rbcrevslen = rev
215 self._rbcrevs.truncate(rev)
215 self._rbcrevs.truncate(rev)
216 self._force_overwrite = True
216 self._force_overwrite = True
217
217
218 @util.propertycache
218 @util.propertycache
219 def _namesreverse(self):
219 def _namesreverse(self):
220 return {b: r for r, b in enumerate(self._names)}
220 return {b: r for r, b in enumerate(self._names)}
221
221
222 def branchinfo(self, rev):
222 def branchinfo(self, rev):
223 """Return branch name and close flag for rev, using and updating
223 """Return branch name and close flag for rev, using and updating
224 persistent cache."""
224 persistent cache."""
225 changelog = self._repo.changelog
225 changelog = self._repo.changelog
226 rbcrevidx = rev * _rbcrecsize
226 rbcrevidx = rev * _rbcrecsize
227
227
228 # avoid negative index, changelog.read(nullrev) is fast without cache
228 # avoid negative index, changelog.read(nullrev) is fast without cache
229 if rev == nullrev:
229 if rev == nullrev:
230 return changelog.branchinfo(rev)
230 return changelog.branchinfo(rev)
231
231
232 # if requested rev isn't allocated, grow and cache the rev info
232 # if requested rev isn't allocated, grow and cache the rev info
233 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
233 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
234 return self._branchinfo(rev)
234 return self._branchinfo(rev)
235
235
236 # fast path: extract data from cache, use it if node is matching
236 # fast path: extract data from cache, use it if node is matching
237 reponode = changelog.node(rev)[:_rbcnodelen]
237 reponode = changelog.node(rev)[:_rbcnodelen]
238 cachenode, branchidx = self._rbcrevs.unpack_record(rbcrevidx)
238 cachenode, branchidx = self._rbcrevs.unpack_record(rbcrevidx)
239 close = bool(branchidx & _rbccloseflag)
239 close = bool(branchidx & _rbccloseflag)
240 if close:
240 if close:
241 branchidx &= _rbcbranchidxmask
241 branchidx &= _rbcbranchidxmask
242 if cachenode == b'\0\0\0\0':
242 if cachenode == b'\0\0\0\0':
243 pass
243 pass
244 elif cachenode == reponode:
244 elif cachenode == reponode:
245 try:
245 try:
246 return self._names[branchidx], close
246 return self._names[branchidx], close
247 except IndexError:
247 except IndexError:
248 # recover from invalid reference to unknown branch
248 # recover from invalid reference to unknown branch
249 self._repo.ui.debug(
249 self._repo.ui.debug(
250 b"referenced branch names not found"
250 b"referenced branch names not found"
251 b" - rebuilding revision branch cache from scratch\n"
251 b" - rebuilding revision branch cache from scratch\n"
252 )
252 )
253 self._clear()
253 self._clear()
254 else:
254 else:
255 # rev/node map has changed, invalidate the cache from here up
255 # rev/node map has changed, invalidate the cache from here up
256 self._repo.ui.debug(
256 self._repo.ui.debug(
257 b"history modification detected - truncating "
257 b"history modification detected - truncating "
258 b"revision branch cache to revision %d\n" % rev
258 b"revision branch cache to revision %d\n" % rev
259 )
259 )
260 truncate = rbcrevidx + _rbcrecsize
260 truncate = rbcrevidx + _rbcrecsize
261 self._rbcrevs.truncate(truncate)
261 self._rbcrevs.truncate(truncate)
262 self._rbcrevslen = min(self._rbcrevslen, truncate)
262 self._rbcrevslen = min(self._rbcrevslen, truncate)
263
263
264 # fall back to slow path and make sure it will be written to disk
264 # fall back to slow path and make sure it will be written to disk
265 return self._branchinfo(rev)
265 return self._branchinfo(rev)
266
266
267 def _branchinfo(self, rev):
267 def _branchinfo(self, rev):
268 """Retrieve branch info from changelog and update _rbcrevs"""
268 """Retrieve branch info from changelog and update _rbcrevs"""
269 changelog = self._repo.changelog
269 changelog = self._repo.changelog
270 b, close = changelog.branchinfo(rev)
270 b, close = changelog.branchinfo(rev)
271 if b in self._namesreverse:
271 if b in self._namesreverse:
272 branchidx = self._namesreverse[b]
272 branchidx = self._namesreverse[b]
273 else:
273 else:
274 branchidx = len(self._names)
274 branchidx = len(self._names)
275 self._names.append(b)
275 self._names.append(b)
276 self._namesreverse[b] = branchidx
276 self._namesreverse[b] = branchidx
277 reponode = changelog.node(rev)
277 reponode = changelog.node(rev)
278 if close:
278 if close:
279 branchidx |= _rbccloseflag
279 branchidx |= _rbccloseflag
280 self._setcachedata(rev, reponode, branchidx)
280 self._setcachedata(rev, reponode, branchidx)
281 return b, close
281 return b, close
282
282
283 def setdata(self, rev, changelogrevision):
283 def setdata(self, rev, changelogrevision):
284 """add new data information to the cache"""
284 """add new data information to the cache"""
285 branch, close = changelogrevision.branchinfo
285 branch, close = changelogrevision.branchinfo
286
286
287 if branch in self._namesreverse:
287 if branch in self._namesreverse:
288 branchidx = self._namesreverse[branch]
288 branchidx = self._namesreverse[branch]
289 else:
289 else:
290 branchidx = len(self._names)
290 branchidx = len(self._names)
291 self._names.append(branch)
291 self._names.append(branch)
292 self._namesreverse[branch] = branchidx
292 self._namesreverse[branch] = branchidx
293 if close:
293 if close:
294 branchidx |= _rbccloseflag
294 branchidx |= _rbccloseflag
295 self._setcachedata(rev, self._repo.changelog.node(rev), branchidx)
295 self._setcachedata(rev, self._repo.changelog.node(rev), branchidx)
296 # If no cache data were readable (non exists, bad permission, etc)
296 # If no cache data were readable (non exists, bad permission, etc)
297 # the cache was bypassing itself by setting:
297 # the cache was bypassing itself by setting:
298 #
298 #
299 # self.branchinfo = self._branchinfo
299 # self.branchinfo = self._branchinfo
300 #
300 #
301 # Since we now have data in the cache, we need to drop this bypassing.
301 # Since we now have data in the cache, we need to drop this bypassing.
302 if 'branchinfo' in vars(self):
302 if 'branchinfo' in vars(self):
303 del self.branchinfo
303 del self.branchinfo
304
304
305 def _setcachedata(self, rev, node, branchidx):
305 def _setcachedata(self, rev, node, branchidx):
306 """Writes the node's branch data to the in-memory cache data."""
306 """Writes the node's branch data to the in-memory cache data."""
307 if rev == nullrev:
307 if rev == nullrev:
308 return
308 return
309 rbcrevidx = rev * _rbcrecsize
309 rbcrevidx = rev * _rbcrecsize
310 self._rbcrevs.pack_into(rbcrevidx, node, branchidx)
310 self._rbcrevs.pack_into(rbcrevidx, node, branchidx)
311 self._rbcrevslen = min(self._rbcrevslen, rev)
311 self._rbcrevslen = min(self._rbcrevslen, rev)
312
312
313 tr = self._repo.currenttransaction()
313 tr = self._repo.currenttransaction()
314 if tr:
314 if tr:
315 tr.addfinalize(b'write-revbranchcache', self.write)
315 tr.addfinalize(b'write-revbranchcache', self.write)
316
316
317 def write(self, tr=None):
317 def write(self, tr=None):
318 """Save branch cache if it is dirty."""
318 """Save branch cache if it is dirty."""
319 repo = self._repo
319 repo = self._repo
320 wlock = None
320 wlock = None
321 step = b''
321 step = b''
322 try:
322 try:
323 # write the new names
323 # write the new names
324 if self._force_overwrite or self._rbcnamescount < len(self._names):
324 if self._force_overwrite or self._rbcnamescount < len(self._names):
325 wlock = repo.wlock(wait=False)
325 wlock = repo.wlock(wait=False)
326 step = b' names'
326 step = b' names'
327 self._writenames(repo)
327 self._writenames(repo)
328
328
329 # write the new revs
329 # write the new revs
330 start = self._rbcrevslen * _rbcrecsize
330 start = self._rbcrevslen * _rbcrecsize
331 if self._force_overwrite or start != len(self._rbcrevs):
331 if self._force_overwrite or start != len(self._rbcrevs):
332 step = b''
332 step = b''
333 if wlock is None:
333 if wlock is None:
334 wlock = repo.wlock(wait=False)
334 wlock = repo.wlock(wait=False)
335 self._writerevs(repo, start)
335 self._writerevs(repo, start)
336
336
337 except (IOError, OSError, error.Abort, error.LockError) as inst:
337 except (IOError, OSError, error.Abort, error.LockError) as inst:
338 repo.ui.debug(
338 repo.ui.debug(
339 b"couldn't write revision branch cache%s: %s\n"
339 b"couldn't write revision branch cache%s: %s\n"
340 % (step, stringutil.forcebytestr(inst))
340 % (step, stringutil.forcebytestr(inst))
341 )
341 )
342 finally:
342 finally:
343 if wlock is not None:
343 if wlock is not None:
344 wlock.release()
344 wlock.release()
345
345
346 def _writenames(self, repo):
346 def _writenames(self, repo):
347 """write the new branch names to revbranchcache"""
347 """write the new branch names to revbranchcache"""
348 f = None
348 f = None
349 if self._force_overwrite:
349 if self._force_overwrite:
350 self._rbcsnameslen = 0
350 self._rbcsnameslen = 0
351 self._rbcnamescount = 0
351 self._rbcnamescount = 0
352 try:
352 try:
353 if self._force_overwrite or self._rbcnamescount != 0:
353 if self._force_overwrite or self._rbcnamescount != 0:
354 f = repo.cachevfs.open(_rbcnames, b'ab')
354 f = repo.cachevfs.open(_rbcnames, b'ab')
355 current_size = f.tell()
355 current_size = f.tell()
356 if current_size == self._rbcsnameslen:
356 if current_size == self._rbcsnameslen:
357 f.write(b'\0')
357 f.write(b'\0')
358 else:
358 else:
359 f.close()
359 f.close()
360 if self._force_overwrite:
360 if self._force_overwrite:
361 dbg = b"resetting content of %s\n"
361 dbg = b"resetting content of %s\n"
362 elif current_size > 0:
362 elif current_size > 0:
363 dbg = b"%s changed - rewriting it\n"
363 dbg = b"%s changed - rewriting it\n"
364 else:
364 else:
365 dbg = b"%s is missing - rewriting it\n"
365 dbg = b"%s is missing - rewriting it\n"
366 repo.ui.debug(dbg % _rbcnames)
366 repo.ui.debug(dbg % _rbcnames)
367 self._rbcnamescount = 0
367 self._rbcnamescount = 0
368 self._rbcrevslen = 0
368 self._rbcrevslen = 0
369 if self._rbcnamescount == 0:
369 if self._rbcnamescount == 0:
370 # before rewriting names, make sure references are removed
370 # before rewriting names, make sure references are removed
371 repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
371 repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
372 f = repo.cachevfs.open(_rbcnames, b'wb')
372 f = repo.cachevfs.open(_rbcnames, b'wb')
373 names = self._names[self._rbcnamescount :]
373 names = self._names[self._rbcnamescount :]
374 from_local = encoding.fromlocal
374 from_local = encoding.fromlocal
375 data = b'\0'.join(from_local(b) for b in names)
375 data = b'\0'.join(from_local(b) for b in names)
376 f.write(data)
376 f.write(data)
377 self._rbcsnameslen = f.tell()
377 self._rbcsnameslen = f.tell()
378 finally:
378 finally:
379 if f is not None:
379 if f is not None:
380 f.close()
380 f.close()
381 self._rbcnamescount = len(self._names)
381 self._rbcnamescount = len(self._names)
382
382
383 def _writerevs(self, repo, start):
383 def _writerevs(self, repo, start):
384 """write the new revs to revbranchcache"""
384 """write the new revs to revbranchcache"""
385 revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize)
385 revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize)
386
386
387 end = revs * _rbcrecsize
387 end = revs * _rbcrecsize
388 if self._force_overwrite:
388 if self._force_overwrite:
389 start = 0
389 start = 0
390
390
391 with repo.cachevfs.open(_rbcrevs, b'a+b') as f:
391 with repo.cachevfs.open(_rbcrevs, b'a+b') as f:
392 pass # this make sure the file exist…
392 pass # this make sure the file exist…
393 with repo.cachevfs.open(_rbcrevs, b'r+b') as f:
393 with repo.cachevfs.open(_rbcrevs, b'r+b') as f:
394 f.seek(0, os.SEEK_END)
394 f.seek(0, os.SEEK_END)
395 current_size = f.tell()
395 current_size = f.tell()
396 if current_size < start:
396 if current_size < start:
397 start = 0
397 start = 0
398 if current_size != start:
398 if current_size != start:
399 threshold = current_size * REWRITE_RATIO
399 threshold = current_size * REWRITE_RATIO
400 if (max(end, current_size) - start) < threshold:
400 overwritten = min(end, current_size) - start
401 # end affected, let overwrite the bad value
401 if (max(end, current_size) - start) >= threshold:
402 overwritten = min(end, current_size) - start
402 start = 0
403 dbg = b"resetting content of cache/%s\n" % _rbcrevs
404 repo.ui.debug(dbg)
405 elif overwritten > 0:
406 # end affected, let us overwrite the bad value
403 dbg = b"overwriting %d bytes from %d in cache/%s"
407 dbg = b"overwriting %d bytes from %d in cache/%s"
404 dbg %= (overwritten, start, _rbcrevs)
408 dbg %= (current_size - start, start, _rbcrevs)
405 if end < current_size:
409 if end < current_size:
406 extra = b" leaving (%d trailing bytes)"
410 extra = b" leaving (%d trailing bytes)"
407 extra %= current_size - end
411 extra %= current_size - end
408 dbg += extra
412 dbg += extra
409 dbg += b'\n'
413 dbg += b'\n'
410 repo.ui.debug(dbg)
414 repo.ui.debug(dbg)
411 else:
415 else:
412 start = 0
416 # extra untouched data at the end, lets warn about them
413 dbg = b"resetting content of cache/%s\n" % _rbcrevs
417 assert start == end # since don't write anything
418 dbg = b"cache/%s contains %d unknown trailing bytes\n"
419 dbg %= (_rbcrevs, current_size - start)
414 repo.ui.debug(dbg)
420 repo.ui.debug(dbg)
421
415 if start > 0:
422 if start > 0:
416 f.seek(start)
423 f.seek(start)
417 f.write(self._rbcrevs.slice(start, end))
424 f.write(self._rbcrevs.slice(start, end))
418 else:
425 else:
419 f.close()
426 f.close()
420 with repo.cachevfs.open(
427 with repo.cachevfs.open(
421 _rbcrevs,
428 _rbcrevs,
422 b'wb',
429 b'wb',
423 atomictemp=True,
430 atomictemp=True,
424 ) as rev_file:
431 ) as rev_file:
425 rev_file.write(self._rbcrevs.slice(start, end))
432 rev_file.write(self._rbcrevs.slice(start, end))
426 self._rbcrevslen = revs
433 self._rbcrevslen = revs
427 self._force_overwrite = False
434 self._force_overwrite = False
@@ -1,1466 +1,1466
1 #testcases mmap nommap
1 #testcases mmap nommap
2 #testcases v2 v3
2 #testcases v2 v3
3
3
4 #if mmap
4 #if mmap
5 $ cat <<EOF >> $HGRCPATH
5 $ cat <<EOF >> $HGRCPATH
6 > [storage]
6 > [storage]
7 > revbranchcache.mmap=true
7 > revbranchcache.mmap=true
8 > EOF
8 > EOF
9 #endif
9 #endif
10
10
11 #if v3
11 #if v3
12 $ cat <<EOF >> $HGRCPATH
12 $ cat <<EOF >> $HGRCPATH
13 > [experimental]
13 > [experimental]
14 > branch-cache-v3=yes
14 > branch-cache-v3=yes
15 > EOF
15 > EOF
16 #else
16 #else
17 $ cat <<EOF >> $HGRCPATH
17 $ cat <<EOF >> $HGRCPATH
18 > [experimental]
18 > [experimental]
19 > branch-cache-v3=no
19 > branch-cache-v3=no
20 > EOF
20 > EOF
21 #endif
21 #endif
22
22
23 $ hg init a
23 $ hg init a
24 $ cd a
24 $ cd a
25
25
26 Verify checking branch of nullrev before the cache is created doesnt crash
26 Verify checking branch of nullrev before the cache is created doesnt crash
27 $ hg log -r 'branch(.)' -T '{branch}\n'
27 $ hg log -r 'branch(.)' -T '{branch}\n'
28
28
29 Basic test
29 Basic test
30 $ echo 'root' >root
30 $ echo 'root' >root
31 $ hg add root
31 $ hg add root
32 $ hg commit -d '0 0' -m "Adding root node"
32 $ hg commit -d '0 0' -m "Adding root node"
33
33
34 $ echo 'a' >a
34 $ echo 'a' >a
35 $ hg add a
35 $ hg add a
36 $ hg branch a
36 $ hg branch a
37 marked working directory as branch a
37 marked working directory as branch a
38 (branches are permanent and global, did you want a bookmark?)
38 (branches are permanent and global, did you want a bookmark?)
39 $ hg commit -d '1 0' -m "Adding a branch"
39 $ hg commit -d '1 0' -m "Adding a branch"
40
40
41 $ hg branch q
41 $ hg branch q
42 marked working directory as branch q
42 marked working directory as branch q
43 $ echo 'aa' >a
43 $ echo 'aa' >a
44 $ hg branch -C
44 $ hg branch -C
45 reset working directory to branch a
45 reset working directory to branch a
46 $ hg commit -d '2 0' -m "Adding to a branch"
46 $ hg commit -d '2 0' -m "Adding to a branch"
47
47
48 $ hg update -C 0
48 $ hg update -C 0
49 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
49 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
50 $ echo 'b' >b
50 $ echo 'b' >b
51 $ hg add b
51 $ hg add b
52 $ hg branch b
52 $ hg branch b
53 marked working directory as branch b
53 marked working directory as branch b
54 $ hg commit -d '2 0' -m "Adding b branch"
54 $ hg commit -d '2 0' -m "Adding b branch"
55
55
56 $ echo 'bh1' >bh1
56 $ echo 'bh1' >bh1
57 $ hg add bh1
57 $ hg add bh1
58 $ hg commit -d '3 0' -m "Adding b branch head 1"
58 $ hg commit -d '3 0' -m "Adding b branch head 1"
59
59
60 $ hg update -C 2
60 $ hg update -C 2
61 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
61 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
62 $ echo 'bh2' >bh2
62 $ echo 'bh2' >bh2
63 $ hg add bh2
63 $ hg add bh2
64 $ hg commit -d '4 0' -m "Adding b branch head 2"
64 $ hg commit -d '4 0' -m "Adding b branch head 2"
65
65
66 $ echo 'c' >c
66 $ echo 'c' >c
67 $ hg add c
67 $ hg add c
68 $ hg branch c
68 $ hg branch c
69 marked working directory as branch c
69 marked working directory as branch c
70 $ hg commit -d '5 0' -m "Adding c branch"
70 $ hg commit -d '5 0' -m "Adding c branch"
71
71
72 reserved names
72 reserved names
73
73
74 $ hg branch tip
74 $ hg branch tip
75 abort: the name 'tip' is reserved
75 abort: the name 'tip' is reserved
76 [10]
76 [10]
77 $ hg branch null
77 $ hg branch null
78 abort: the name 'null' is reserved
78 abort: the name 'null' is reserved
79 [10]
79 [10]
80 $ hg branch .
80 $ hg branch .
81 abort: the name '.' is reserved
81 abort: the name '.' is reserved
82 [10]
82 [10]
83
83
84 invalid characters
84 invalid characters
85
85
86 $ hg branch 'foo:bar'
86 $ hg branch 'foo:bar'
87 abort: ':' cannot be used in a name
87 abort: ':' cannot be used in a name
88 [10]
88 [10]
89
89
90 $ hg branch 'foo
90 $ hg branch 'foo
91 > bar'
91 > bar'
92 abort: '\n' cannot be used in a name
92 abort: '\n' cannot be used in a name
93 [10]
93 [10]
94
94
95 trailing or leading spaces should be stripped before testing duplicates
95 trailing or leading spaces should be stripped before testing duplicates
96
96
97 $ hg branch 'b '
97 $ hg branch 'b '
98 abort: a branch of the same name already exists
98 abort: a branch of the same name already exists
99 (use 'hg update' to switch to it)
99 (use 'hg update' to switch to it)
100 [10]
100 [10]
101
101
102 $ hg branch ' b'
102 $ hg branch ' b'
103 abort: a branch of the same name already exists
103 abort: a branch of the same name already exists
104 (use 'hg update' to switch to it)
104 (use 'hg update' to switch to it)
105 [10]
105 [10]
106
106
107 underscores in numeric branch names (issue6737)
107 underscores in numeric branch names (issue6737)
108
108
109 $ hg branch 2700_210
109 $ hg branch 2700_210
110 marked working directory as branch 2700_210
110 marked working directory as branch 2700_210
111
111
112 verify update will accept invalid legacy branch names
112 verify update will accept invalid legacy branch names
113
113
114 $ hg init test-invalid-branch-name
114 $ hg init test-invalid-branch-name
115 $ cd test-invalid-branch-name
115 $ cd test-invalid-branch-name
116 $ hg unbundle -u "$TESTDIR"/bundles/test-invalid-branch-name.hg
116 $ hg unbundle -u "$TESTDIR"/bundles/test-invalid-branch-name.hg
117 adding changesets
117 adding changesets
118 adding manifests
118 adding manifests
119 adding file changes
119 adding file changes
120 added 3 changesets with 3 changes to 2 files
120 added 3 changesets with 3 changes to 2 files
121 new changesets f0e4c7f04036:33c2ceb9310b (3 drafts)
121 new changesets f0e4c7f04036:33c2ceb9310b (3 drafts)
122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123
123
124 $ hg update '"colon:test"'
124 $ hg update '"colon:test"'
125 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
125 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 $ cd ..
126 $ cd ..
127
127
128 $ echo 'd' >d
128 $ echo 'd' >d
129 $ hg add d
129 $ hg add d
130 $ hg branch 'a branch name much longer than the default justification used by branches'
130 $ hg branch 'a branch name much longer than the default justification used by branches'
131 marked working directory as branch a branch name much longer than the default justification used by branches
131 marked working directory as branch a branch name much longer than the default justification used by branches
132 $ hg commit -d '6 0' -m "Adding d branch"
132 $ hg commit -d '6 0' -m "Adding d branch"
133
133
134 $ hg branches
134 $ hg branches
135 a branch name much longer than the default justification used by branches 7:10ff5895aa57
135 a branch name much longer than the default justification used by branches 7:10ff5895aa57
136 b 4:aee39cd168d0
136 b 4:aee39cd168d0
137 c 6:589736a22561 (inactive)
137 c 6:589736a22561 (inactive)
138 a 5:d8cbc61dbaa6 (inactive)
138 a 5:d8cbc61dbaa6 (inactive)
139 default 0:19709c5a4e75 (inactive)
139 default 0:19709c5a4e75 (inactive)
140
140
141 -------
141 -------
142
142
143 $ hg branches -a
143 $ hg branches -a
144 a branch name much longer than the default justification used by branches 7:10ff5895aa57
144 a branch name much longer than the default justification used by branches 7:10ff5895aa57
145 b 4:aee39cd168d0
145 b 4:aee39cd168d0
146
146
147 --- Branch a
147 --- Branch a
148
148
149 $ hg log -b a
149 $ hg log -b a
150 changeset: 5:d8cbc61dbaa6
150 changeset: 5:d8cbc61dbaa6
151 branch: a
151 branch: a
152 parent: 2:881fe2b92ad0
152 parent: 2:881fe2b92ad0
153 user: test
153 user: test
154 date: Thu Jan 01 00:00:04 1970 +0000
154 date: Thu Jan 01 00:00:04 1970 +0000
155 summary: Adding b branch head 2
155 summary: Adding b branch head 2
156
156
157 changeset: 2:881fe2b92ad0
157 changeset: 2:881fe2b92ad0
158 branch: a
158 branch: a
159 user: test
159 user: test
160 date: Thu Jan 01 00:00:02 1970 +0000
160 date: Thu Jan 01 00:00:02 1970 +0000
161 summary: Adding to a branch
161 summary: Adding to a branch
162
162
163 changeset: 1:dd6b440dd85a
163 changeset: 1:dd6b440dd85a
164 branch: a
164 branch: a
165 user: test
165 user: test
166 date: Thu Jan 01 00:00:01 1970 +0000
166 date: Thu Jan 01 00:00:01 1970 +0000
167 summary: Adding a branch
167 summary: Adding a branch
168
168
169
169
170 ---- Branch b
170 ---- Branch b
171
171
172 $ hg log -b b
172 $ hg log -b b
173 changeset: 4:aee39cd168d0
173 changeset: 4:aee39cd168d0
174 branch: b
174 branch: b
175 user: test
175 user: test
176 date: Thu Jan 01 00:00:03 1970 +0000
176 date: Thu Jan 01 00:00:03 1970 +0000
177 summary: Adding b branch head 1
177 summary: Adding b branch head 1
178
178
179 changeset: 3:ac22033332d1
179 changeset: 3:ac22033332d1
180 branch: b
180 branch: b
181 parent: 0:19709c5a4e75
181 parent: 0:19709c5a4e75
182 user: test
182 user: test
183 date: Thu Jan 01 00:00:02 1970 +0000
183 date: Thu Jan 01 00:00:02 1970 +0000
184 summary: Adding b branch
184 summary: Adding b branch
185
185
186
186
187 ---- going to test branch listing by rev
187 ---- going to test branch listing by rev
188 $ hg branches -r0
188 $ hg branches -r0
189 default 0:19709c5a4e75 (inactive)
189 default 0:19709c5a4e75 (inactive)
190 $ hg branches -qr0
190 $ hg branches -qr0
191 default
191 default
192 --- now more than one rev
192 --- now more than one rev
193 $ hg branches -r2:5
193 $ hg branches -r2:5
194 b 4:aee39cd168d0
194 b 4:aee39cd168d0
195 a 5:d8cbc61dbaa6 (inactive)
195 a 5:d8cbc61dbaa6 (inactive)
196 $ hg branches -qr2:5
196 $ hg branches -qr2:5
197 b
197 b
198 a
198 a
199 ---- going to test branch closing
199 ---- going to test branch closing
200
200
201 $ hg branches
201 $ hg branches
202 a branch name much longer than the default justification used by branches 7:10ff5895aa57
202 a branch name much longer than the default justification used by branches 7:10ff5895aa57
203 b 4:aee39cd168d0
203 b 4:aee39cd168d0
204 c 6:589736a22561 (inactive)
204 c 6:589736a22561 (inactive)
205 a 5:d8cbc61dbaa6 (inactive)
205 a 5:d8cbc61dbaa6 (inactive)
206 default 0:19709c5a4e75 (inactive)
206 default 0:19709c5a4e75 (inactive)
207 $ hg up -C b
207 $ hg up -C b
208 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
208 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
209 $ echo 'xxx1' >> b
209 $ echo 'xxx1' >> b
210 $ hg commit -d '7 0' -m 'adding cset to branch b'
210 $ hg commit -d '7 0' -m 'adding cset to branch b'
211 $ hg up -C aee39cd168d0
211 $ hg up -C aee39cd168d0
212 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
212 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
213 $ echo 'xxx2' >> b
213 $ echo 'xxx2' >> b
214 $ hg commit -d '8 0' -m 'adding head to branch b'
214 $ hg commit -d '8 0' -m 'adding head to branch b'
215 created new head
215 created new head
216 $ echo 'xxx3' >> b
216 $ echo 'xxx3' >> b
217 $ hg commit -d '9 0' -m 'adding another cset to branch b'
217 $ hg commit -d '9 0' -m 'adding another cset to branch b'
218 $ hg branches
218 $ hg branches
219 b 10:bfbe841b666e
219 b 10:bfbe841b666e
220 a branch name much longer than the default justification used by branches 7:10ff5895aa57
220 a branch name much longer than the default justification used by branches 7:10ff5895aa57
221 c 6:589736a22561 (inactive)
221 c 6:589736a22561 (inactive)
222 a 5:d8cbc61dbaa6 (inactive)
222 a 5:d8cbc61dbaa6 (inactive)
223 default 0:19709c5a4e75 (inactive)
223 default 0:19709c5a4e75 (inactive)
224 $ hg heads --closed
224 $ hg heads --closed
225 changeset: 10:bfbe841b666e
225 changeset: 10:bfbe841b666e
226 branch: b
226 branch: b
227 tag: tip
227 tag: tip
228 user: test
228 user: test
229 date: Thu Jan 01 00:00:09 1970 +0000
229 date: Thu Jan 01 00:00:09 1970 +0000
230 summary: adding another cset to branch b
230 summary: adding another cset to branch b
231
231
232 changeset: 8:eebb944467c9
232 changeset: 8:eebb944467c9
233 branch: b
233 branch: b
234 parent: 4:aee39cd168d0
234 parent: 4:aee39cd168d0
235 user: test
235 user: test
236 date: Thu Jan 01 00:00:07 1970 +0000
236 date: Thu Jan 01 00:00:07 1970 +0000
237 summary: adding cset to branch b
237 summary: adding cset to branch b
238
238
239 changeset: 7:10ff5895aa57
239 changeset: 7:10ff5895aa57
240 branch: a branch name much longer than the default justification used by branches
240 branch: a branch name much longer than the default justification used by branches
241 user: test
241 user: test
242 date: Thu Jan 01 00:00:06 1970 +0000
242 date: Thu Jan 01 00:00:06 1970 +0000
243 summary: Adding d branch
243 summary: Adding d branch
244
244
245 changeset: 6:589736a22561
245 changeset: 6:589736a22561
246 branch: c
246 branch: c
247 user: test
247 user: test
248 date: Thu Jan 01 00:00:05 1970 +0000
248 date: Thu Jan 01 00:00:05 1970 +0000
249 summary: Adding c branch
249 summary: Adding c branch
250
250
251 changeset: 5:d8cbc61dbaa6
251 changeset: 5:d8cbc61dbaa6
252 branch: a
252 branch: a
253 parent: 2:881fe2b92ad0
253 parent: 2:881fe2b92ad0
254 user: test
254 user: test
255 date: Thu Jan 01 00:00:04 1970 +0000
255 date: Thu Jan 01 00:00:04 1970 +0000
256 summary: Adding b branch head 2
256 summary: Adding b branch head 2
257
257
258 changeset: 0:19709c5a4e75
258 changeset: 0:19709c5a4e75
259 user: test
259 user: test
260 date: Thu Jan 01 00:00:00 1970 +0000
260 date: Thu Jan 01 00:00:00 1970 +0000
261 summary: Adding root node
261 summary: Adding root node
262
262
263 $ hg heads
263 $ hg heads
264 changeset: 10:bfbe841b666e
264 changeset: 10:bfbe841b666e
265 branch: b
265 branch: b
266 tag: tip
266 tag: tip
267 user: test
267 user: test
268 date: Thu Jan 01 00:00:09 1970 +0000
268 date: Thu Jan 01 00:00:09 1970 +0000
269 summary: adding another cset to branch b
269 summary: adding another cset to branch b
270
270
271 changeset: 8:eebb944467c9
271 changeset: 8:eebb944467c9
272 branch: b
272 branch: b
273 parent: 4:aee39cd168d0
273 parent: 4:aee39cd168d0
274 user: test
274 user: test
275 date: Thu Jan 01 00:00:07 1970 +0000
275 date: Thu Jan 01 00:00:07 1970 +0000
276 summary: adding cset to branch b
276 summary: adding cset to branch b
277
277
278 changeset: 7:10ff5895aa57
278 changeset: 7:10ff5895aa57
279 branch: a branch name much longer than the default justification used by branches
279 branch: a branch name much longer than the default justification used by branches
280 user: test
280 user: test
281 date: Thu Jan 01 00:00:06 1970 +0000
281 date: Thu Jan 01 00:00:06 1970 +0000
282 summary: Adding d branch
282 summary: Adding d branch
283
283
284 changeset: 6:589736a22561
284 changeset: 6:589736a22561
285 branch: c
285 branch: c
286 user: test
286 user: test
287 date: Thu Jan 01 00:00:05 1970 +0000
287 date: Thu Jan 01 00:00:05 1970 +0000
288 summary: Adding c branch
288 summary: Adding c branch
289
289
290 changeset: 5:d8cbc61dbaa6
290 changeset: 5:d8cbc61dbaa6
291 branch: a
291 branch: a
292 parent: 2:881fe2b92ad0
292 parent: 2:881fe2b92ad0
293 user: test
293 user: test
294 date: Thu Jan 01 00:00:04 1970 +0000
294 date: Thu Jan 01 00:00:04 1970 +0000
295 summary: Adding b branch head 2
295 summary: Adding b branch head 2
296
296
297 changeset: 0:19709c5a4e75
297 changeset: 0:19709c5a4e75
298 user: test
298 user: test
299 date: Thu Jan 01 00:00:00 1970 +0000
299 date: Thu Jan 01 00:00:00 1970 +0000
300 summary: Adding root node
300 summary: Adding root node
301
301
302 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
302 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
303 $ hg branches -a
303 $ hg branches -a
304 b 8:eebb944467c9
304 b 8:eebb944467c9
305 a branch name much longer than the default justification used by branches 7:10ff5895aa57
305 a branch name much longer than the default justification used by branches 7:10ff5895aa57
306 $ hg up -C b
306 $ hg up -C b
307 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
307 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
308 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
308 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
309 $ hg commit -d '9 0' --close-branch -m 're-closing this branch'
309 $ hg commit -d '9 0' --close-branch -m 're-closing this branch'
310 abort: current revision is already a branch closing head
310 abort: current revision is already a branch closing head
311 [10]
311 [10]
312
312
313 $ echo foo > b
313 $ echo foo > b
314 $ hg commit -d '9 0' --close-branch -m 're-closing this branch'
314 $ hg commit -d '9 0' --close-branch -m 're-closing this branch'
315
315
316 $ echo bar > b
316 $ echo bar > b
317 $ hg commit -d '9 0' --close-branch -m 're-closing this branch' bh1
317 $ hg commit -d '9 0' --close-branch -m 're-closing this branch' bh1
318 abort: current revision is already a branch closing head
318 abort: current revision is already a branch closing head
319 [10]
319 [10]
320 $ hg commit -d '9 0' --close-branch -m 're-closing this branch' b
320 $ hg commit -d '9 0' --close-branch -m 're-closing this branch' b
321
321
322 $ echo baz > b
322 $ echo baz > b
323 $ hg commit -d '9 0' --close-branch -m 'empty re-closing this branch' -X b
323 $ hg commit -d '9 0' --close-branch -m 'empty re-closing this branch' -X b
324 abort: current revision is already a branch closing head
324 abort: current revision is already a branch closing head
325 [10]
325 [10]
326 $ hg revert b
326 $ hg revert b
327
327
328 $ hg debugstrip --rev 13: --no-backup
328 $ hg debugstrip --rev 13: --no-backup
329 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
329 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
330 $ hg revert --all --no-backup
330 $ hg revert --all --no-backup
331
331
332 $ hg log -r tip --debug
332 $ hg log -r tip --debug
333 changeset: 12:e3d49c0575d8fc2cb1cd6859c747c14f5f6d499f
333 changeset: 12:e3d49c0575d8fc2cb1cd6859c747c14f5f6d499f
334 branch: b
334 branch: b
335 tag: tip
335 tag: tip
336 phase: draft
336 phase: draft
337 parent: 8:eebb944467c9fb9651ed232aeaf31b3c0a7fc6c1
337 parent: 8:eebb944467c9fb9651ed232aeaf31b3c0a7fc6c1
338 parent: -1:0000000000000000000000000000000000000000
338 parent: -1:0000000000000000000000000000000000000000
339 manifest: 8:6f9ed32d2b310e391a4f107d5f0f071df785bfee
339 manifest: 8:6f9ed32d2b310e391a4f107d5f0f071df785bfee
340 user: test
340 user: test
341 date: Thu Jan 01 00:00:09 1970 +0000
341 date: Thu Jan 01 00:00:09 1970 +0000
342 extra: branch=b
342 extra: branch=b
343 extra: close=1
343 extra: close=1
344 description:
344 description:
345 close this part branch too
345 close this part branch too
346
346
347
347
348 --- b branch should be inactive
348 --- b branch should be inactive
349
349
350 $ hg branches
350 $ hg branches
351 a branch name much longer than the default justification used by branches 7:10ff5895aa57
351 a branch name much longer than the default justification used by branches 7:10ff5895aa57
352 c 6:589736a22561 (inactive)
352 c 6:589736a22561 (inactive)
353 a 5:d8cbc61dbaa6 (inactive)
353 a 5:d8cbc61dbaa6 (inactive)
354 default 0:19709c5a4e75 (inactive)
354 default 0:19709c5a4e75 (inactive)
355 $ hg branches -c
355 $ hg branches -c
356 a branch name much longer than the default justification used by branches 7:10ff5895aa57
356 a branch name much longer than the default justification used by branches 7:10ff5895aa57
357 b 12:e3d49c0575d8 (closed)
357 b 12:e3d49c0575d8 (closed)
358 c 6:589736a22561 (inactive)
358 c 6:589736a22561 (inactive)
359 a 5:d8cbc61dbaa6 (inactive)
359 a 5:d8cbc61dbaa6 (inactive)
360 default 0:19709c5a4e75 (inactive)
360 default 0:19709c5a4e75 (inactive)
361 $ hg branches -a
361 $ hg branches -a
362 a branch name much longer than the default justification used by branches 7:10ff5895aa57
362 a branch name much longer than the default justification used by branches 7:10ff5895aa57
363 $ hg branches -q
363 $ hg branches -q
364 a branch name much longer than the default justification used by branches
364 a branch name much longer than the default justification used by branches
365 c
365 c
366 a
366 a
367 default
367 default
368 $ hg heads b
368 $ hg heads b
369 no open branch heads found on branches b
369 no open branch heads found on branches b
370 [1]
370 [1]
371 $ hg heads --closed b
371 $ hg heads --closed b
372 changeset: 12:e3d49c0575d8
372 changeset: 12:e3d49c0575d8
373 branch: b
373 branch: b
374 tag: tip
374 tag: tip
375 parent: 8:eebb944467c9
375 parent: 8:eebb944467c9
376 user: test
376 user: test
377 date: Thu Jan 01 00:00:09 1970 +0000
377 date: Thu Jan 01 00:00:09 1970 +0000
378 summary: close this part branch too
378 summary: close this part branch too
379
379
380 changeset: 11:d3f163457ebf
380 changeset: 11:d3f163457ebf
381 branch: b
381 branch: b
382 user: test
382 user: test
383 date: Thu Jan 01 00:00:09 1970 +0000
383 date: Thu Jan 01 00:00:09 1970 +0000
384 summary: prune bad branch
384 summary: prune bad branch
385
385
386 $ echo 'xxx4' >> b
386 $ echo 'xxx4' >> b
387 $ hg commit -d '9 0' -m 'reopen branch with a change'
387 $ hg commit -d '9 0' -m 'reopen branch with a change'
388 reopening closed branch head 12
388 reopening closed branch head 12
389
389
390 --- branch b is back in action
390 --- branch b is back in action
391
391
392 $ hg branches -a
392 $ hg branches -a
393 b 13:e23b5505d1ad
393 b 13:e23b5505d1ad
394 a branch name much longer than the default justification used by branches 7:10ff5895aa57
394 a branch name much longer than the default justification used by branches 7:10ff5895aa57
395
395
396 ---- test heads listings
396 ---- test heads listings
397
397
398 $ hg heads
398 $ hg heads
399 changeset: 13:e23b5505d1ad
399 changeset: 13:e23b5505d1ad
400 branch: b
400 branch: b
401 tag: tip
401 tag: tip
402 user: test
402 user: test
403 date: Thu Jan 01 00:00:09 1970 +0000
403 date: Thu Jan 01 00:00:09 1970 +0000
404 summary: reopen branch with a change
404 summary: reopen branch with a change
405
405
406 changeset: 7:10ff5895aa57
406 changeset: 7:10ff5895aa57
407 branch: a branch name much longer than the default justification used by branches
407 branch: a branch name much longer than the default justification used by branches
408 user: test
408 user: test
409 date: Thu Jan 01 00:00:06 1970 +0000
409 date: Thu Jan 01 00:00:06 1970 +0000
410 summary: Adding d branch
410 summary: Adding d branch
411
411
412 changeset: 6:589736a22561
412 changeset: 6:589736a22561
413 branch: c
413 branch: c
414 user: test
414 user: test
415 date: Thu Jan 01 00:00:05 1970 +0000
415 date: Thu Jan 01 00:00:05 1970 +0000
416 summary: Adding c branch
416 summary: Adding c branch
417
417
418 changeset: 5:d8cbc61dbaa6
418 changeset: 5:d8cbc61dbaa6
419 branch: a
419 branch: a
420 parent: 2:881fe2b92ad0
420 parent: 2:881fe2b92ad0
421 user: test
421 user: test
422 date: Thu Jan 01 00:00:04 1970 +0000
422 date: Thu Jan 01 00:00:04 1970 +0000
423 summary: Adding b branch head 2
423 summary: Adding b branch head 2
424
424
425 changeset: 0:19709c5a4e75
425 changeset: 0:19709c5a4e75
426 user: test
426 user: test
427 date: Thu Jan 01 00:00:00 1970 +0000
427 date: Thu Jan 01 00:00:00 1970 +0000
428 summary: Adding root node
428 summary: Adding root node
429
429
430
430
431 branch default
431 branch default
432
432
433 $ hg heads default
433 $ hg heads default
434 changeset: 0:19709c5a4e75
434 changeset: 0:19709c5a4e75
435 user: test
435 user: test
436 date: Thu Jan 01 00:00:00 1970 +0000
436 date: Thu Jan 01 00:00:00 1970 +0000
437 summary: Adding root node
437 summary: Adding root node
438
438
439
439
440 branch a
440 branch a
441
441
442 $ hg heads a
442 $ hg heads a
443 changeset: 5:d8cbc61dbaa6
443 changeset: 5:d8cbc61dbaa6
444 branch: a
444 branch: a
445 parent: 2:881fe2b92ad0
445 parent: 2:881fe2b92ad0
446 user: test
446 user: test
447 date: Thu Jan 01 00:00:04 1970 +0000
447 date: Thu Jan 01 00:00:04 1970 +0000
448 summary: Adding b branch head 2
448 summary: Adding b branch head 2
449
449
450 $ hg heads --active a
450 $ hg heads --active a
451 no open branch heads found on branches a
451 no open branch heads found on branches a
452 [1]
452 [1]
453
453
454 branch b
454 branch b
455
455
456 $ hg heads b
456 $ hg heads b
457 changeset: 13:e23b5505d1ad
457 changeset: 13:e23b5505d1ad
458 branch: b
458 branch: b
459 tag: tip
459 tag: tip
460 user: test
460 user: test
461 date: Thu Jan 01 00:00:09 1970 +0000
461 date: Thu Jan 01 00:00:09 1970 +0000
462 summary: reopen branch with a change
462 summary: reopen branch with a change
463
463
464 $ hg heads --closed b
464 $ hg heads --closed b
465 changeset: 13:e23b5505d1ad
465 changeset: 13:e23b5505d1ad
466 branch: b
466 branch: b
467 tag: tip
467 tag: tip
468 user: test
468 user: test
469 date: Thu Jan 01 00:00:09 1970 +0000
469 date: Thu Jan 01 00:00:09 1970 +0000
470 summary: reopen branch with a change
470 summary: reopen branch with a change
471
471
472 changeset: 11:d3f163457ebf
472 changeset: 11:d3f163457ebf
473 branch: b
473 branch: b
474 user: test
474 user: test
475 date: Thu Jan 01 00:00:09 1970 +0000
475 date: Thu Jan 01 00:00:09 1970 +0000
476 summary: prune bad branch
476 summary: prune bad branch
477
477
478
478
479 reclose branch
479 reclose branch
480
480
481 $ hg up -C c
481 $ hg up -C c
482 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
482 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
483 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
483 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
484 $ hg branches
484 $ hg branches
485 b 13:e23b5505d1ad
485 b 13:e23b5505d1ad
486 a branch name much longer than the default justification used by branches 7:10ff5895aa57
486 a branch name much longer than the default justification used by branches 7:10ff5895aa57
487 a 5:d8cbc61dbaa6 (inactive)
487 a 5:d8cbc61dbaa6 (inactive)
488 default 0:19709c5a4e75 (inactive)
488 default 0:19709c5a4e75 (inactive)
489 $ hg branches --closed
489 $ hg branches --closed
490 b 13:e23b5505d1ad
490 b 13:e23b5505d1ad
491 a branch name much longer than the default justification used by branches 7:10ff5895aa57
491 a branch name much longer than the default justification used by branches 7:10ff5895aa57
492 c 14:f894c25619d3 (closed)
492 c 14:f894c25619d3 (closed)
493 a 5:d8cbc61dbaa6 (inactive)
493 a 5:d8cbc61dbaa6 (inactive)
494 default 0:19709c5a4e75 (inactive)
494 default 0:19709c5a4e75 (inactive)
495
495
496 multihead branch
496 multihead branch
497
497
498 $ hg up -C default
498 $ hg up -C default
499 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
499 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
500 $ hg branch m
500 $ hg branch m
501 marked working directory as branch m
501 marked working directory as branch m
502 $ touch m
502 $ touch m
503 $ hg add m
503 $ hg add m
504 $ hg commit -d '10 0' -m 'multihead base'
504 $ hg commit -d '10 0' -m 'multihead base'
505 $ echo "m1" >m
505 $ echo "m1" >m
506 $ hg commit -d '10 0' -m 'head 1'
506 $ hg commit -d '10 0' -m 'head 1'
507 $ hg up -C '.^'
507 $ hg up -C '.^'
508 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
508 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
509 $ echo "m2" >m
509 $ echo "m2" >m
510 $ hg commit -d '10 0' -m 'head 2'
510 $ hg commit -d '10 0' -m 'head 2'
511 created new head
511 created new head
512 $ hg log -b m
512 $ hg log -b m
513 changeset: 17:df343b0df04f
513 changeset: 17:df343b0df04f
514 branch: m
514 branch: m
515 tag: tip
515 tag: tip
516 parent: 15:f3447637f53e
516 parent: 15:f3447637f53e
517 user: test
517 user: test
518 date: Thu Jan 01 00:00:10 1970 +0000
518 date: Thu Jan 01 00:00:10 1970 +0000
519 summary: head 2
519 summary: head 2
520
520
521 changeset: 16:a58ca5d3bdf3
521 changeset: 16:a58ca5d3bdf3
522 branch: m
522 branch: m
523 user: test
523 user: test
524 date: Thu Jan 01 00:00:10 1970 +0000
524 date: Thu Jan 01 00:00:10 1970 +0000
525 summary: head 1
525 summary: head 1
526
526
527 changeset: 15:f3447637f53e
527 changeset: 15:f3447637f53e
528 branch: m
528 branch: m
529 parent: 0:19709c5a4e75
529 parent: 0:19709c5a4e75
530 user: test
530 user: test
531 date: Thu Jan 01 00:00:10 1970 +0000
531 date: Thu Jan 01 00:00:10 1970 +0000
532 summary: multihead base
532 summary: multihead base
533
533
534 $ hg heads --topo m
534 $ hg heads --topo m
535 changeset: 17:df343b0df04f
535 changeset: 17:df343b0df04f
536 branch: m
536 branch: m
537 tag: tip
537 tag: tip
538 parent: 15:f3447637f53e
538 parent: 15:f3447637f53e
539 user: test
539 user: test
540 date: Thu Jan 01 00:00:10 1970 +0000
540 date: Thu Jan 01 00:00:10 1970 +0000
541 summary: head 2
541 summary: head 2
542
542
543 changeset: 16:a58ca5d3bdf3
543 changeset: 16:a58ca5d3bdf3
544 branch: m
544 branch: m
545 user: test
545 user: test
546 date: Thu Jan 01 00:00:10 1970 +0000
546 date: Thu Jan 01 00:00:10 1970 +0000
547 summary: head 1
547 summary: head 1
548
548
549 $ hg branches
549 $ hg branches
550 m 17:df343b0df04f
550 m 17:df343b0df04f
551 b 13:e23b5505d1ad
551 b 13:e23b5505d1ad
552 a branch name much longer than the default justification used by branches 7:10ff5895aa57
552 a branch name much longer than the default justification used by branches 7:10ff5895aa57
553 a 5:d8cbc61dbaa6 (inactive)
553 a 5:d8cbc61dbaa6 (inactive)
554 default 0:19709c5a4e75 (inactive)
554 default 0:19709c5a4e75 (inactive)
555
555
556 partially merge multihead branch
556 partially merge multihead branch
557
557
558 $ hg up -C default
558 $ hg up -C default
559 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
559 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
560 $ hg branch md
560 $ hg branch md
561 marked working directory as branch md
561 marked working directory as branch md
562 $ hg merge m
562 $ hg merge m
563 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
563 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
564 (branch merge, don't forget to commit)
564 (branch merge, don't forget to commit)
565 $ hg commit -d '11 0' -m 'merge head 2'
565 $ hg commit -d '11 0' -m 'merge head 2'
566 $ hg heads --topo m
566 $ hg heads --topo m
567 changeset: 16:a58ca5d3bdf3
567 changeset: 16:a58ca5d3bdf3
568 branch: m
568 branch: m
569 user: test
569 user: test
570 date: Thu Jan 01 00:00:10 1970 +0000
570 date: Thu Jan 01 00:00:10 1970 +0000
571 summary: head 1
571 summary: head 1
572
572
573 $ hg branches
573 $ hg branches
574 md 18:c914c99f1fbb
574 md 18:c914c99f1fbb
575 m 17:df343b0df04f
575 m 17:df343b0df04f
576 b 13:e23b5505d1ad
576 b 13:e23b5505d1ad
577 a branch name much longer than the default justification used by branches 7:10ff5895aa57
577 a branch name much longer than the default justification used by branches 7:10ff5895aa57
578 a 5:d8cbc61dbaa6 (inactive)
578 a 5:d8cbc61dbaa6 (inactive)
579 default 0:19709c5a4e75 (inactive)
579 default 0:19709c5a4e75 (inactive)
580
580
581 partially close multihead branch
581 partially close multihead branch
582
582
583 $ hg up -C a58ca5d3bdf3
583 $ hg up -C a58ca5d3bdf3
584 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
585 $ hg commit -d '12 0' -m 'close head 1' --close-branch
585 $ hg commit -d '12 0' -m 'close head 1' --close-branch
586 $ hg heads --topo m
586 $ hg heads --topo m
587 changeset: 19:cd21a80baa3d
587 changeset: 19:cd21a80baa3d
588 branch: m
588 branch: m
589 tag: tip
589 tag: tip
590 parent: 16:a58ca5d3bdf3
590 parent: 16:a58ca5d3bdf3
591 user: test
591 user: test
592 date: Thu Jan 01 00:00:12 1970 +0000
592 date: Thu Jan 01 00:00:12 1970 +0000
593 summary: close head 1
593 summary: close head 1
594
594
595 $ hg branches
595 $ hg branches
596 md 18:c914c99f1fbb
596 md 18:c914c99f1fbb
597 b 13:e23b5505d1ad
597 b 13:e23b5505d1ad
598 a branch name much longer than the default justification used by branches 7:10ff5895aa57
598 a branch name much longer than the default justification used by branches 7:10ff5895aa57
599 m 17:df343b0df04f (inactive)
599 m 17:df343b0df04f (inactive)
600 a 5:d8cbc61dbaa6 (inactive)
600 a 5:d8cbc61dbaa6 (inactive)
601 default 0:19709c5a4e75 (inactive)
601 default 0:19709c5a4e75 (inactive)
602
602
603 default branch colors:
603 default branch colors:
604
604
605 $ cat <<EOF >> $HGRCPATH
605 $ cat <<EOF >> $HGRCPATH
606 > [extensions]
606 > [extensions]
607 > color =
607 > color =
608 > [color]
608 > [color]
609 > mode = ansi
609 > mode = ansi
610 > EOF
610 > EOF
611
611
612 $ hg up -C b
612 $ hg up -C b
613 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
613 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
614 $ hg branches --color=always
614 $ hg branches --color=always
615 \x1b[0;0mmd\x1b[0m\x1b[0;33m 18:c914c99f1fbb\x1b[0m (esc)
615 \x1b[0;0mmd\x1b[0m\x1b[0;33m 18:c914c99f1fbb\x1b[0m (esc)
616 \x1b[0;32mb\x1b[0m\x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
616 \x1b[0;32mb\x1b[0m\x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
617 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;33m 7:10ff5895aa57\x1b[0m (esc)
617 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;33m 7:10ff5895aa57\x1b[0m (esc)
618 \x1b[0;0mm\x1b[0m\x1b[0;33m 17:df343b0df04f\x1b[0m (inactive) (esc)
618 \x1b[0;0mm\x1b[0m\x1b[0;33m 17:df343b0df04f\x1b[0m (inactive) (esc)
619 \x1b[0;0ma\x1b[0m\x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
619 \x1b[0;0ma\x1b[0m\x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
620 \x1b[0;0mdefault\x1b[0m\x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
620 \x1b[0;0mdefault\x1b[0m\x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
621
621
622 default closed branch color:
622 default closed branch color:
623
623
624 $ hg branches --color=always --closed
624 $ hg branches --color=always --closed
625 \x1b[0;0mmd\x1b[0m\x1b[0;33m 18:c914c99f1fbb\x1b[0m (esc)
625 \x1b[0;0mmd\x1b[0m\x1b[0;33m 18:c914c99f1fbb\x1b[0m (esc)
626 \x1b[0;32mb\x1b[0m\x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
626 \x1b[0;32mb\x1b[0m\x1b[0;33m 13:e23b5505d1ad\x1b[0m (esc)
627 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;33m 7:10ff5895aa57\x1b[0m (esc)
627 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;33m 7:10ff5895aa57\x1b[0m (esc)
628 \x1b[0;0mm\x1b[0m\x1b[0;33m 17:df343b0df04f\x1b[0m (inactive) (esc)
628 \x1b[0;0mm\x1b[0m\x1b[0;33m 17:df343b0df04f\x1b[0m (inactive) (esc)
629 \x1b[0;30;1mc\x1b[0m\x1b[0;33m 14:f894c25619d3\x1b[0m (closed) (esc)
629 \x1b[0;30;1mc\x1b[0m\x1b[0;33m 14:f894c25619d3\x1b[0m (closed) (esc)
630 \x1b[0;0ma\x1b[0m\x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
630 \x1b[0;0ma\x1b[0m\x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
631 \x1b[0;0mdefault\x1b[0m\x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
631 \x1b[0;0mdefault\x1b[0m\x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
632
632
633 $ cat <<EOF >> $HGRCPATH
633 $ cat <<EOF >> $HGRCPATH
634 > [extensions]
634 > [extensions]
635 > color =
635 > color =
636 > [color]
636 > [color]
637 > branches.active = green
637 > branches.active = green
638 > branches.closed = blue
638 > branches.closed = blue
639 > branches.current = red
639 > branches.current = red
640 > branches.inactive = magenta
640 > branches.inactive = magenta
641 > log.changeset = cyan
641 > log.changeset = cyan
642 > EOF
642 > EOF
643
643
644 custom branch colors:
644 custom branch colors:
645
645
646 $ hg branches --color=always
646 $ hg branches --color=always
647 \x1b[0;32mmd\x1b[0m\x1b[0;36m 18:c914c99f1fbb\x1b[0m (esc)
647 \x1b[0;32mmd\x1b[0m\x1b[0;36m 18:c914c99f1fbb\x1b[0m (esc)
648 \x1b[0;31mb\x1b[0m\x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
648 \x1b[0;31mb\x1b[0m\x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
649 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;36m 7:10ff5895aa57\x1b[0m (esc)
649 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;36m 7:10ff5895aa57\x1b[0m (esc)
650 \x1b[0;35mm\x1b[0m\x1b[0;36m 17:df343b0df04f\x1b[0m (inactive) (esc)
650 \x1b[0;35mm\x1b[0m\x1b[0;36m 17:df343b0df04f\x1b[0m (inactive) (esc)
651 \x1b[0;35ma\x1b[0m\x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
651 \x1b[0;35ma\x1b[0m\x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
652 \x1b[0;35mdefault\x1b[0m\x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
652 \x1b[0;35mdefault\x1b[0m\x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
653
653
654 custom closed branch color:
654 custom closed branch color:
655
655
656 $ hg branches --color=always --closed
656 $ hg branches --color=always --closed
657 \x1b[0;32mmd\x1b[0m\x1b[0;36m 18:c914c99f1fbb\x1b[0m (esc)
657 \x1b[0;32mmd\x1b[0m\x1b[0;36m 18:c914c99f1fbb\x1b[0m (esc)
658 \x1b[0;31mb\x1b[0m\x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
658 \x1b[0;31mb\x1b[0m\x1b[0;36m 13:e23b5505d1ad\x1b[0m (esc)
659 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;36m 7:10ff5895aa57\x1b[0m (esc)
659 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m\x1b[0;36m 7:10ff5895aa57\x1b[0m (esc)
660 \x1b[0;35mm\x1b[0m\x1b[0;36m 17:df343b0df04f\x1b[0m (inactive) (esc)
660 \x1b[0;35mm\x1b[0m\x1b[0;36m 17:df343b0df04f\x1b[0m (inactive) (esc)
661 \x1b[0;34mc\x1b[0m\x1b[0;36m 14:f894c25619d3\x1b[0m (closed) (esc)
661 \x1b[0;34mc\x1b[0m\x1b[0;36m 14:f894c25619d3\x1b[0m (closed) (esc)
662 \x1b[0;35ma\x1b[0m\x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
662 \x1b[0;35ma\x1b[0m\x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
663 \x1b[0;35mdefault\x1b[0m\x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
663 \x1b[0;35mdefault\x1b[0m\x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
664
664
665 template output:
665 template output:
666
666
667 $ hg branches -Tjson --closed
667 $ hg branches -Tjson --closed
668 [
668 [
669 {
669 {
670 "active": true,
670 "active": true,
671 "branch": "md",
671 "branch": "md",
672 "closed": false,
672 "closed": false,
673 "current": false,
673 "current": false,
674 "node": "c914c99f1fbb2b1d785a0a939ed3f67275df18e9",
674 "node": "c914c99f1fbb2b1d785a0a939ed3f67275df18e9",
675 "rev": 18
675 "rev": 18
676 },
676 },
677 {
677 {
678 "active": true,
678 "active": true,
679 "branch": "b",
679 "branch": "b",
680 "closed": false,
680 "closed": false,
681 "current": true,
681 "current": true,
682 "node": "e23b5505d1ad24aab6f84fd8c7cb8cd8e5e93be0",
682 "node": "e23b5505d1ad24aab6f84fd8c7cb8cd8e5e93be0",
683 "rev": 13
683 "rev": 13
684 },
684 },
685 {
685 {
686 "active": true,
686 "active": true,
687 "branch": "a branch name much longer than the default justification used by branches",
687 "branch": "a branch name much longer than the default justification used by branches",
688 "closed": false,
688 "closed": false,
689 "current": false,
689 "current": false,
690 "node": "10ff5895aa5793bd378da574af8cec8ea408d831",
690 "node": "10ff5895aa5793bd378da574af8cec8ea408d831",
691 "rev": 7
691 "rev": 7
692 },
692 },
693 {
693 {
694 "active": false,
694 "active": false,
695 "branch": "m",
695 "branch": "m",
696 "closed": false,
696 "closed": false,
697 "current": false,
697 "current": false,
698 "node": "df343b0df04feb2a946cd4b6e9520e552fef14ee",
698 "node": "df343b0df04feb2a946cd4b6e9520e552fef14ee",
699 "rev": 17
699 "rev": 17
700 },
700 },
701 {
701 {
702 "active": false,
702 "active": false,
703 "branch": "c",
703 "branch": "c",
704 "closed": true,
704 "closed": true,
705 "current": false,
705 "current": false,
706 "node": "f894c25619d3f1484639d81be950e0a07bc6f1f6",
706 "node": "f894c25619d3f1484639d81be950e0a07bc6f1f6",
707 "rev": 14
707 "rev": 14
708 },
708 },
709 {
709 {
710 "active": false,
710 "active": false,
711 "branch": "a",
711 "branch": "a",
712 "closed": false,
712 "closed": false,
713 "current": false,
713 "current": false,
714 "node": "d8cbc61dbaa6dc817175d1e301eecb863f280832",
714 "node": "d8cbc61dbaa6dc817175d1e301eecb863f280832",
715 "rev": 5
715 "rev": 5
716 },
716 },
717 {
717 {
718 "active": false,
718 "active": false,
719 "branch": "default",
719 "branch": "default",
720 "closed": false,
720 "closed": false,
721 "current": false,
721 "current": false,
722 "node": "19709c5a4e75bf938f8e349aff97438539bb729e",
722 "node": "19709c5a4e75bf938f8e349aff97438539bb729e",
723 "rev": 0
723 "rev": 0
724 }
724 }
725 ]
725 ]
726
726
727 $ hg branches --closed -T '{if(closed, "{branch}\n")}'
727 $ hg branches --closed -T '{if(closed, "{branch}\n")}'
728 c
728 c
729
729
730 $ hg branches -T '{word(0, branch)}: {desc|firstline}\n'
730 $ hg branches -T '{word(0, branch)}: {desc|firstline}\n'
731 md: merge head 2
731 md: merge head 2
732 b: reopen branch with a change
732 b: reopen branch with a change
733 a: Adding d branch
733 a: Adding d branch
734 m: head 2
734 m: head 2
735 a: Adding b branch head 2
735 a: Adding b branch head 2
736 default: Adding root node
736 default: Adding root node
737
737
738 $ cat <<'EOF' > "$TESTTMP/map-myjson"
738 $ cat <<'EOF' > "$TESTTMP/map-myjson"
739 > docheader = '\{\n'
739 > docheader = '\{\n'
740 > docfooter = '\n}\n'
740 > docfooter = '\n}\n'
741 > separator = ',\n'
741 > separator = ',\n'
742 > branches = ' {dict(branch, node|short)|json}'
742 > branches = ' {dict(branch, node|short)|json}'
743 > EOF
743 > EOF
744 $ hg branches -T "$TESTTMP/map-myjson"
744 $ hg branches -T "$TESTTMP/map-myjson"
745 {
745 {
746 {"branch": "md", "node": "c914c99f1fbb"},
746 {"branch": "md", "node": "c914c99f1fbb"},
747 {"branch": "b", "node": "e23b5505d1ad"},
747 {"branch": "b", "node": "e23b5505d1ad"},
748 {"branch": "a branch *", "node": "10ff5895aa57"}, (glob)
748 {"branch": "a branch *", "node": "10ff5895aa57"}, (glob)
749 {"branch": "m", "node": "df343b0df04f"},
749 {"branch": "m", "node": "df343b0df04f"},
750 {"branch": "a", "node": "d8cbc61dbaa6"},
750 {"branch": "a", "node": "d8cbc61dbaa6"},
751 {"branch": "default", "node": "19709c5a4e75"}
751 {"branch": "default", "node": "19709c5a4e75"}
752 }
752 }
753
753
754 $ cat <<'EOF' >> .hg/hgrc
754 $ cat <<'EOF' >> .hg/hgrc
755 > [templates]
755 > [templates]
756 > myjson = ' {dict(branch, node|short)|json}'
756 > myjson = ' {dict(branch, node|short)|json}'
757 > myjson:docheader = '\{\n'
757 > myjson:docheader = '\{\n'
758 > myjson:docfooter = '\n}\n'
758 > myjson:docfooter = '\n}\n'
759 > myjson:separator = ',\n'
759 > myjson:separator = ',\n'
760 > EOF
760 > EOF
761 $ hg branches -T myjson
761 $ hg branches -T myjson
762 {
762 {
763 {"branch": "md", "node": "c914c99f1fbb"},
763 {"branch": "md", "node": "c914c99f1fbb"},
764 {"branch": "b", "node": "e23b5505d1ad"},
764 {"branch": "b", "node": "e23b5505d1ad"},
765 {"branch": "a branch *", "node": "10ff5895aa57"}, (glob)
765 {"branch": "a branch *", "node": "10ff5895aa57"}, (glob)
766 {"branch": "m", "node": "df343b0df04f"},
766 {"branch": "m", "node": "df343b0df04f"},
767 {"branch": "a", "node": "d8cbc61dbaa6"},
767 {"branch": "a", "node": "d8cbc61dbaa6"},
768 {"branch": "default", "node": "19709c5a4e75"}
768 {"branch": "default", "node": "19709c5a4e75"}
769 }
769 }
770
770
771 $ cat <<'EOF' >> .hg/hgrc
771 $ cat <<'EOF' >> .hg/hgrc
772 > [templates]
772 > [templates]
773 > :docheader = 'should not be selected as a docheader for literal templates\n'
773 > :docheader = 'should not be selected as a docheader for literal templates\n'
774 > EOF
774 > EOF
775 $ hg branches -T '{branch}\n'
775 $ hg branches -T '{branch}\n'
776 md
776 md
777 b
777 b
778 a branch name much longer than the default justification used by branches
778 a branch name much longer than the default justification used by branches
779 m
779 m
780 a
780 a
781 default
781 default
782
782
783 Tests of revision branch name caching
783 Tests of revision branch name caching
784
784
785 We rev branch cache is updated automatically. In these tests we use a trick to
785 We rev branch cache is updated automatically. In these tests we use a trick to
786 trigger rebuilds. We remove the branch head cache and run 'hg head' to cause a
786 trigger rebuilds. We remove the branch head cache and run 'hg head' to cause a
787 rebuild that also will populate the rev branch cache.
787 rebuild that also will populate the rev branch cache.
788
788
789 revision branch cache is created when building the branch head cache
789 revision branch cache is created when building the branch head cache
790 $ rm -rf .hg/cache; hg head a -T '{rev}\n'
790 $ rm -rf .hg/cache; hg head a -T '{rev}\n'
791 5
791 5
792 $ f --hexdump --size .hg/cache/rbc-*
792 $ f --hexdump --size .hg/cache/rbc-*
793 .hg/cache/rbc-names-v2: size=92
793 .hg/cache/rbc-names-v2: size=92
794 0000: 64 65 66 61 75 6c 74 00 61 00 62 00 63 00 61 20 |default.a.b.c.a |
794 0000: 64 65 66 61 75 6c 74 00 61 00 62 00 63 00 61 20 |default.a.b.c.a |
795 0010: 62 72 61 6e 63 68 20 6e 61 6d 65 20 6d 75 63 68 |branch name much|
795 0010: 62 72 61 6e 63 68 20 6e 61 6d 65 20 6d 75 63 68 |branch name much|
796 0020: 20 6c 6f 6e 67 65 72 20 74 68 61 6e 20 74 68 65 | longer than the|
796 0020: 20 6c 6f 6e 67 65 72 20 74 68 61 6e 20 74 68 65 | longer than the|
797 0030: 20 64 65 66 61 75 6c 74 20 6a 75 73 74 69 66 69 | default justifi|
797 0030: 20 64 65 66 61 75 6c 74 20 6a 75 73 74 69 66 69 | default justifi|
798 0040: 63 61 74 69 6f 6e 20 75 73 65 64 20 62 79 20 62 |cation used by b|
798 0040: 63 61 74 69 6f 6e 20 75 73 65 64 20 62 79 20 62 |cation used by b|
799 0050: 72 61 6e 63 68 65 73 00 6d 00 6d 64 |ranches.m.md|
799 0050: 72 61 6e 63 68 65 73 00 6d 00 6d 64 |ranches.m.md|
800 .hg/cache/rbc-revs-v2: size=160
800 .hg/cache/rbc-revs-v2: size=160
801 0000: 19 70 9c 5a 00 00 00 00 dd 6b 44 0d 00 00 00 01 |.p.Z.....kD.....|
801 0000: 19 70 9c 5a 00 00 00 00 dd 6b 44 0d 00 00 00 01 |.p.Z.....kD.....|
802 0010: 88 1f e2 b9 00 00 00 01 ac 22 03 33 00 00 00 02 |.........".3....|
802 0010: 88 1f e2 b9 00 00 00 01 ac 22 03 33 00 00 00 02 |.........".3....|
803 0020: ae e3 9c d1 00 00 00 02 d8 cb c6 1d 00 00 00 01 |................|
803 0020: ae e3 9c d1 00 00 00 02 d8 cb c6 1d 00 00 00 01 |................|
804 0030: 58 97 36 a2 00 00 00 03 10 ff 58 95 00 00 00 04 |X.6.......X.....|
804 0030: 58 97 36 a2 00 00 00 03 10 ff 58 95 00 00 00 04 |X.6.......X.....|
805 0040: ee bb 94 44 00 00 00 02 5f 40 61 bb 00 00 00 02 |...D...._@a.....|
805 0040: ee bb 94 44 00 00 00 02 5f 40 61 bb 00 00 00 02 |...D...._@a.....|
806 0050: bf be 84 1b 00 00 00 02 d3 f1 63 45 80 00 00 02 |..........cE....|
806 0050: bf be 84 1b 00 00 00 02 d3 f1 63 45 80 00 00 02 |..........cE....|
807 0060: e3 d4 9c 05 80 00 00 02 e2 3b 55 05 00 00 00 02 |.........;U.....|
807 0060: e3 d4 9c 05 80 00 00 02 e2 3b 55 05 00 00 00 02 |.........;U.....|
808 0070: f8 94 c2 56 80 00 00 03 f3 44 76 37 00 00 00 05 |...V.....Dv7....|
808 0070: f8 94 c2 56 80 00 00 03 f3 44 76 37 00 00 00 05 |...V.....Dv7....|
809 0080: a5 8c a5 d3 00 00 00 05 df 34 3b 0d 00 00 00 05 |.........4;.....|
809 0080: a5 8c a5 d3 00 00 00 05 df 34 3b 0d 00 00 00 05 |.........4;.....|
810 0090: c9 14 c9 9f 00 00 00 06 cd 21 a8 0b 80 00 00 05 |.........!......|
810 0090: c9 14 c9 9f 00 00 00 06 cd 21 a8 0b 80 00 00 05 |.........!......|
811
811
812 no errors when revbranchcache is not writable
812 no errors when revbranchcache is not writable
813
813
814 $ echo >> .hg/cache/rbc-revs-v2
814 $ echo >> .hg/cache/rbc-revs-v2
815 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v2_
815 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v2_
816 $ mkdir .hg/cache/rbc-revs-v2
816 $ mkdir .hg/cache/rbc-revs-v2
817 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n'
817 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n'
818 5
818 5
819 $ rmdir .hg/cache/rbc-revs-v2
819 $ rmdir .hg/cache/rbc-revs-v2
820 $ mv .hg/cache/rbc-revs-v2_ .hg/cache/rbc-revs-v2
820 $ mv .hg/cache/rbc-revs-v2_ .hg/cache/rbc-revs-v2
821
821
822 no errors when wlock cannot be acquired
822 no errors when wlock cannot be acquired
823
823
824 #if unix-permissions
824 #if unix-permissions
825 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v2_
825 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v2_
826 $ rm -f .hg/cache/branch*
826 $ rm -f .hg/cache/branch*
827 $ chmod 555 .hg
827 $ chmod 555 .hg
828 $ hg head a -T '{rev}\n'
828 $ hg head a -T '{rev}\n'
829 5
829 5
830 $ chmod 755 .hg
830 $ chmod 755 .hg
831 $ mv .hg/cache/rbc-revs-v2_ .hg/cache/rbc-revs-v2
831 $ mv .hg/cache/rbc-revs-v2_ .hg/cache/rbc-revs-v2
832 #endif
832 #endif
833
833
834 recovery from invalid cache revs file with trailing data
834 recovery from invalid cache revs file with trailing data
835 $ echo >> .hg/cache/rbc-revs-v2
835 $ echo >> .hg/cache/rbc-revs-v2
836 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
836 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
837 5
837 5
838 overwriting 0 bytes from 160 in cache/rbc-revs-v2 leaving (2 trailing bytes)
838 cache/rbc-revs-v2 contains 2 unknown trailing bytes
839 $ f --size .hg/cache/rbc-revs*
839 $ f --size .hg/cache/rbc-revs*
840 .hg/cache/rbc-revs-v2: size=162
840 .hg/cache/rbc-revs-v2: size=162
841
841
842 recovery from invalid cache file with partial last record
842 recovery from invalid cache file with partial last record
843 $ mv .hg/cache/rbc-revs-v2 .
843 $ mv .hg/cache/rbc-revs-v2 .
844 $ f -qDB 119 rbc-revs-v2 > .hg/cache/rbc-revs-v2
844 $ f -qDB 119 rbc-revs-v2 > .hg/cache/rbc-revs-v2
845 $ f --size .hg/cache/rbc-revs*
845 $ f --size .hg/cache/rbc-revs*
846 .hg/cache/rbc-revs-v2: size=119
846 .hg/cache/rbc-revs-v2: size=119
847 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
847 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
848 5
848 5
849 resetting content of cache/rbc-revs-v2
849 resetting content of cache/rbc-revs-v2
850 $ f --size .hg/cache/rbc-revs*
850 $ f --size .hg/cache/rbc-revs*
851 .hg/cache/rbc-revs-v2: size=160
851 .hg/cache/rbc-revs-v2: size=160
852
852
853 recovery from invalid cache file with missing record - no truncation
853 recovery from invalid cache file with missing record - no truncation
854 $ mv .hg/cache/rbc-revs-v2 .
854 $ mv .hg/cache/rbc-revs-v2 .
855 $ f -qDB 112 rbc-revs-v2 > .hg/cache/rbc-revs-v2
855 $ f -qDB 112 rbc-revs-v2 > .hg/cache/rbc-revs-v2
856 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
856 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
857 5
857 5
858 $ f --size .hg/cache/rbc-revs*
858 $ f --size .hg/cache/rbc-revs*
859 .hg/cache/rbc-revs-v2: size=160
859 .hg/cache/rbc-revs-v2: size=160
860
860
861 recovery from invalid cache file with some bad records
861 recovery from invalid cache file with some bad records
862 $ mv .hg/cache/rbc-revs-v2 .
862 $ mv .hg/cache/rbc-revs-v2 .
863 $ f -qDB 8 rbc-revs-v2 > .hg/cache/rbc-revs-v2
863 $ f -qDB 8 rbc-revs-v2 > .hg/cache/rbc-revs-v2
864 $ f --size .hg/cache/rbc-revs*
864 $ f --size .hg/cache/rbc-revs*
865 .hg/cache/rbc-revs-v2: size=8
865 .hg/cache/rbc-revs-v2: size=8
866 $ f -qDB 112 rbc-revs-v2 >> .hg/cache/rbc-revs-v2
866 $ f -qDB 112 rbc-revs-v2 >> .hg/cache/rbc-revs-v2
867 $ f --size .hg/cache/rbc-revs*
867 $ f --size .hg/cache/rbc-revs*
868 .hg/cache/rbc-revs-v2: size=120
868 .hg/cache/rbc-revs-v2: size=120
869 $ hg log -r 'branch(.)' -T '{rev} ' --debug
869 $ hg log -r 'branch(.)' -T '{rev} ' --debug
870 history modification detected - truncating revision branch cache to revision * (glob)
870 history modification detected - truncating revision branch cache to revision * (glob)
871 history modification detected - truncating revision branch cache to revision 1
871 history modification detected - truncating revision branch cache to revision 1
872 3 4 8 9 10 11 12 13 resetting content of cache/rbc-revs-v2
872 3 4 8 9 10 11 12 13 resetting content of cache/rbc-revs-v2
873 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
873 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
874 5
874 5
875 resetting content of cache/rbc-revs-v2
875 resetting content of cache/rbc-revs-v2
876 $ f --size --hexdump --bytes=16 .hg/cache/rbc-revs*
876 $ f --size --hexdump --bytes=16 .hg/cache/rbc-revs*
877 .hg/cache/rbc-revs-v2: size=160
877 .hg/cache/rbc-revs-v2: size=160
878 0000: 19 70 9c 5a 00 00 00 00 dd 6b 44 0d 00 00 00 01 |.p.Z.....kD.....|
878 0000: 19 70 9c 5a 00 00 00 00 dd 6b 44 0d 00 00 00 01 |.p.Z.....kD.....|
879
879
880 Smoothly reuse "v1" format if no v2 exists
880 Smoothly reuse "v1" format if no v2 exists
881 ------------------------------------------
881 ------------------------------------------
882
882
883 read only operation with valid data
883 read only operation with valid data
884 (actively rewrite data)
884 (actively rewrite data)
885
885
886 $ rm .hg/cache/rbc-names-v2
886 $ rm .hg/cache/rbc-names-v2
887 $ rm .hg/cache/rbc-revs-v2
887 $ rm .hg/cache/rbc-revs-v2
888 $ rm .hg/cache/branch*
888 $ rm .hg/cache/branch*
889 $ hg head a -T '{rev}\n' --debug
889 $ hg head a -T '{rev}\n' --debug
890 5
890 5
891 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
891 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
892 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
892 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
893 $ rm .hg/cache/branch*
893 $ rm .hg/cache/branch*
894 $ hg head a -T '{rev}\n' --debug
894 $ hg head a -T '{rev}\n' --debug
895 5
895 5
896 $ f --size .hg/cache/rbc-*-*
896 $ f --size .hg/cache/rbc-*-*
897 .hg/cache/rbc-names-v1: size=92
897 .hg/cache/rbc-names-v1: size=92
898 .hg/cache/rbc-names-v2: size=92
898 .hg/cache/rbc-names-v2: size=92
899 .hg/cache/rbc-revs-v1: size=160
899 .hg/cache/rbc-revs-v1: size=160
900 .hg/cache/rbc-revs-v2: size=160
900 .hg/cache/rbc-revs-v2: size=160
901
901
902
902
903 Write operation write a full v2 files
903 Write operation write a full v2 files
904
904
905 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
905 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
906 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
906 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
907 $ f --size .hg/cache/rbc-*
907 $ f --size .hg/cache/rbc-*
908 .hg/cache/rbc-names-v1: size=92
908 .hg/cache/rbc-names-v1: size=92
909 .hg/cache/rbc-revs-v1: size=160
909 .hg/cache/rbc-revs-v1: size=160
910 $ hg branch not-here-for-long
910 $ hg branch not-here-for-long
911 marked working directory as branch not-here-for-long
911 marked working directory as branch not-here-for-long
912 $ hg ci -m not-long --debug
912 $ hg ci -m not-long --debug
913 reusing manifest from p1 (no file change)
913 reusing manifest from p1 (no file change)
914 committing changelog
914 committing changelog
915 updating the branch cache
915 updating the branch cache
916 committed changeset * (glob)
916 committed changeset * (glob)
917 $ f --size .hg/cache/rbc-*
917 $ f --size .hg/cache/rbc-*
918 .hg/cache/rbc-names-v1: size=92
918 .hg/cache/rbc-names-v1: size=92
919 .hg/cache/rbc-names-v2: size=110
919 .hg/cache/rbc-names-v2: size=110
920 .hg/cache/rbc-revs-v1: size=160
920 .hg/cache/rbc-revs-v1: size=160
921 .hg/cache/rbc-revs-v2: size=168
921 .hg/cache/rbc-revs-v2: size=168
922
922
923 So does explicit cache upgrade
923 So does explicit cache upgrade
924 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
924 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
925 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
925 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
926 $ f --size .hg/cache/rbc-*
926 $ f --size .hg/cache/rbc-*
927 .hg/cache/rbc-names-v1: size=110
927 .hg/cache/rbc-names-v1: size=110
928 .hg/cache/rbc-revs-v1: size=168
928 .hg/cache/rbc-revs-v1: size=168
929 $ hg debugupdatecache
929 $ hg debugupdatecache
930 $ f --size .hg/cache/rbc-*
930 $ f --size .hg/cache/rbc-*
931 .hg/cache/rbc-names-v1: size=110
931 .hg/cache/rbc-names-v1: size=110
932 .hg/cache/rbc-names-v2: size=110
932 .hg/cache/rbc-names-v2: size=110
933 .hg/cache/rbc-revs-v1: size=168
933 .hg/cache/rbc-revs-v1: size=168
934 .hg/cache/rbc-revs-v2: size=168
934 .hg/cache/rbc-revs-v2: size=168
935
935
936 With invalid v1 data, we rewrite it too (as v2)
936 With invalid v1 data, we rewrite it too (as v2)
937
937
938 $ cp .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
938 $ cp .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
939 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-revs-v1
939 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-revs-v1
940 $ rm .hg/cache/rbc-revs-v2
940 $ rm .hg/cache/rbc-revs-v2
941 $ rm .hg/cache/branch*
941 $ rm .hg/cache/branch*
942 $
942 $
943 $ hg head a -T '{rev}\n' --debug
943 $ hg head a -T '{rev}\n' --debug
944 history modification detected - truncating revision branch cache to revision 0
944 history modification detected - truncating revision branch cache to revision 0
945 5
945 5
946 $ f --size .hg/cache/rbc-*-*
946 $ f --size .hg/cache/rbc-*-*
947 .hg/cache/rbc-names-v1: size=110
947 .hg/cache/rbc-names-v1: size=110
948 .hg/cache/rbc-names-v2: size=110
948 .hg/cache/rbc-names-v2: size=110
949 .hg/cache/rbc-revs-v1: size=110
949 .hg/cache/rbc-revs-v1: size=110
950 .hg/cache/rbc-revs-v2: size=168
950 .hg/cache/rbc-revs-v2: size=168
951
951
952 cleanup
952 cleanup
953
953
954 $ hg up -qr '.^'
954 $ hg up -qr '.^'
955 $ hg rollback -qf
955 $ hg rollback -qf
956 $ rm .hg/cache/*
956 $ rm .hg/cache/*
957 $ hg debugupdatecache
957 $ hg debugupdatecache
958 $ f --size .hg/cache/rbc-*
958 $ f --size .hg/cache/rbc-*
959 .hg/cache/rbc-names-v2: size=92
959 .hg/cache/rbc-names-v2: size=92
960 .hg/cache/rbc-revs-v2: size=160
960 .hg/cache/rbc-revs-v2: size=160
961
961
962 cache is updated when committing
962 cache is updated when committing
963 $ hg branch i-will-regret-this
963 $ hg branch i-will-regret-this
964 marked working directory as branch i-will-regret-this
964 marked working directory as branch i-will-regret-this
965 $ hg ci -m regrets
965 $ hg ci -m regrets
966 $ f --size .hg/cache/rbc-*
966 $ f --size .hg/cache/rbc-*
967 .hg/cache/rbc-names-v2: size=111
967 .hg/cache/rbc-names-v2: size=111
968 .hg/cache/rbc-revs-v2: size=168
968 .hg/cache/rbc-revs-v2: size=168
969
969
970 update after rollback - the cache will be correct but rbc-names will will still
970 update after rollback - the cache will be correct but rbc-names will will still
971 contain the branch name even though it no longer is used
971 contain the branch name even though it no longer is used
972 $ hg up -qr '.^'
972 $ hg up -qr '.^'
973 $ hg rollback -qf
973 $ hg rollback -qf
974 $ f --size .hg/cache/rbc-names-*
974 $ f --size .hg/cache/rbc-names-*
975 .hg/cache/rbc-names-v2: size=111
975 .hg/cache/rbc-names-v2: size=111
976 $ grep "i-will-regret-this" .hg/cache/rbc-names-* > /dev/null
976 $ grep "i-will-regret-this" .hg/cache/rbc-names-* > /dev/null
977 $ f --size .hg/cache/rbc-revs-*
977 $ f --size .hg/cache/rbc-revs-*
978 .hg/cache/rbc-revs-v2: size=168
978 .hg/cache/rbc-revs-v2: size=168
979
979
980 cache is updated/truncated when stripping - it is thus very hard to get in a
980 cache is updated/truncated when stripping - it is thus very hard to get in a
981 situation where the cache is out of sync and the hash check detects it
981 situation where the cache is out of sync and the hash check detects it
982 $ hg --config extensions.strip= strip -r tip --nob
982 $ hg --config extensions.strip= strip -r tip --nob
983 $ f --size .hg/cache/rbc-revs*
983 $ f --size .hg/cache/rbc-revs*
984 .hg/cache/rbc-revs-v2: size=152
984 .hg/cache/rbc-revs-v2: size=152
985
985
986 cache is rebuilt when corruption is detected
986 cache is rebuilt when corruption is detected
987 $ echo > .hg/cache/rbc-names-v2
987 $ echo > .hg/cache/rbc-names-v2
988 $ hg log -r '5:&branch(.)' -T '{rev} ' --debug
988 $ hg log -r '5:&branch(.)' -T '{rev} ' --debug
989 referenced branch names not found - rebuilding revision branch cache from scratch
989 referenced branch names not found - rebuilding revision branch cache from scratch
990 8 9 10 11 12 13 resetting content of rbc-names-v2
990 8 9 10 11 12 13 resetting content of rbc-names-v2
991 $ f --size .hg/cache/rbc-names-*
991 $ f --size .hg/cache/rbc-names-*
992 .hg/cache/rbc-names-v2: size=84
992 .hg/cache/rbc-names-v2: size=84
993 $ grep "i-will-regret-this" .hg/cache/rbc-names-* > /dev/null
993 $ grep "i-will-regret-this" .hg/cache/rbc-names-* > /dev/null
994 [1]
994 [1]
995 $ f --size .hg/cache/rbc-revs-*
995 $ f --size .hg/cache/rbc-revs-*
996 .hg/cache/rbc-revs-v2: size=152
996 .hg/cache/rbc-revs-v2: size=152
997
997
998 Test that cache files are created and grows correctly:
998 Test that cache files are created and grows correctly:
999
999
1000 $ rm .hg/cache/rbc*
1000 $ rm .hg/cache/rbc*
1001 $ hg log -r "5 & branch(5)" -T "{rev}\n"
1001 $ hg log -r "5 & branch(5)" -T "{rev}\n"
1002 5
1002 5
1003
1003
1004 (here v3 is querying branch info for heads so it warm much more of the cache)
1004 (here v3 is querying branch info for heads so it warm much more of the cache)
1005
1005
1006 #if v2
1006 #if v2
1007 $ f --size .hg/cache/rbc-*
1007 $ f --size .hg/cache/rbc-*
1008 .hg/cache/rbc-names-v2: size=1
1008 .hg/cache/rbc-names-v2: size=1
1009 .hg/cache/rbc-revs-v2: size=48
1009 .hg/cache/rbc-revs-v2: size=48
1010 #else
1010 #else
1011 $ f --size .hg/cache/rbc-*
1011 $ f --size .hg/cache/rbc-*
1012 .hg/cache/rbc-names-v2: size=84
1012 .hg/cache/rbc-names-v2: size=84
1013 .hg/cache/rbc-revs-v2: size=152
1013 .hg/cache/rbc-revs-v2: size=152
1014 #endif
1014 #endif
1015
1015
1016 $ cd ..
1016 $ cd ..
1017
1017
1018 Test for multiple incorrect branch cache entries:
1018 Test for multiple incorrect branch cache entries:
1019
1019
1020 $ hg init b
1020 $ hg init b
1021 $ cd b
1021 $ cd b
1022 $ touch f
1022 $ touch f
1023 $ hg ci -Aqmf
1023 $ hg ci -Aqmf
1024 $ echo >> f
1024 $ echo >> f
1025 $ hg ci -Amf
1025 $ hg ci -Amf
1026 $ hg branch -q branch
1026 $ hg branch -q branch
1027 $ hg ci -Amf
1027 $ hg ci -Amf
1028
1028
1029 #if v2
1029 #if v2
1030
1030
1031 $ f --size --sha256 .hg/cache/rbc-*
1031 $ f --size --sha256 .hg/cache/rbc-*
1032 .hg/cache/rbc-names-v2: size=14, sha256=d376f7eea9a7e28fac6470e78dae753c81a5543c9ad436e96999590e004a281c
1032 .hg/cache/rbc-names-v2: size=14, sha256=d376f7eea9a7e28fac6470e78dae753c81a5543c9ad436e96999590e004a281c
1033 .hg/cache/rbc-revs-v2: size=24, sha256=ec89032fd4e66e7282cb6e403848c681a855a9c36c6b44d19179218553b78779
1033 .hg/cache/rbc-revs-v2: size=24, sha256=ec89032fd4e66e7282cb6e403848c681a855a9c36c6b44d19179218553b78779
1034
1034
1035 $ : > .hg/cache/rbc-revs-v2
1035 $ : > .hg/cache/rbc-revs-v2
1036
1036
1037 No superfluous rebuilding of cache:
1037 No superfluous rebuilding of cache:
1038 $ hg log -r "branch(null)&branch(branch)" --debug
1038 $ hg log -r "branch(null)&branch(branch)" --debug
1039 $ f --size --sha256 .hg/cache/rbc-*
1039 $ f --size --sha256 .hg/cache/rbc-*
1040 .hg/cache/rbc-names-v2: size=14, sha256=d376f7eea9a7e28fac6470e78dae753c81a5543c9ad436e96999590e004a281c
1040 .hg/cache/rbc-names-v2: size=14, sha256=d376f7eea9a7e28fac6470e78dae753c81a5543c9ad436e96999590e004a281c
1041 .hg/cache/rbc-revs-v2: size=24, sha256=ec89032fd4e66e7282cb6e403848c681a855a9c36c6b44d19179218553b78779
1041 .hg/cache/rbc-revs-v2: size=24, sha256=ec89032fd4e66e7282cb6e403848c681a855a9c36c6b44d19179218553b78779
1042 #endif
1042 #endif
1043
1043
1044 $ cd ..
1044 $ cd ..
1045
1045
1046 Test to make sure that `--close-branch` only works on a branch head:
1046 Test to make sure that `--close-branch` only works on a branch head:
1047 --------------------------------------------------------------------
1047 --------------------------------------------------------------------
1048 $ hg init closebranch
1048 $ hg init closebranch
1049 $ cd closebranch
1049 $ cd closebranch
1050 $ for ch in a b c; do
1050 $ for ch in a b c; do
1051 > echo $ch > $ch
1051 > echo $ch > $ch
1052 > hg add $ch
1052 > hg add $ch
1053 > hg ci -m "added "$ch
1053 > hg ci -m "added "$ch
1054 > done;
1054 > done;
1055
1055
1056 $ hg up -r "desc('added b')"
1056 $ hg up -r "desc('added b')"
1057 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1057 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1058
1058
1059 trying to close branch from a cset which is not a branch head
1059 trying to close branch from a cset which is not a branch head
1060 it should abort:
1060 it should abort:
1061 $ hg ci -m "closing branch" --close-branch
1061 $ hg ci -m "closing branch" --close-branch
1062 abort: can only close branch heads
1062 abort: can only close branch heads
1063 (use --force-close-branch to close branch from a non-head changeset)
1063 (use --force-close-branch to close branch from a non-head changeset)
1064 [10]
1064 [10]
1065
1065
1066 $ hg up 0
1066 $ hg up 0
1067 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1067 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1068 $ hg log -GT "{rev}: {node|short} {desc|firstline}\n\t{branch}\n\n"
1068 $ hg log -GT "{rev}: {node|short} {desc|firstline}\n\t{branch}\n\n"
1069 o 2: 155349b645be added c
1069 o 2: 155349b645be added c
1070 | default
1070 | default
1071 |
1071 |
1072 o 1: 5f6d8a4bf34a added b
1072 o 1: 5f6d8a4bf34a added b
1073 | default
1073 | default
1074 |
1074 |
1075 @ 0: 9092f1db7931 added a
1075 @ 0: 9092f1db7931 added a
1076 default
1076 default
1077
1077
1078 Test --force-close-branch to close a branch from a non-head changeset:
1078 Test --force-close-branch to close a branch from a non-head changeset:
1079 ---------------------------------------------------------------------
1079 ---------------------------------------------------------------------
1080
1080
1081 $ hg show stack --config extensions.show=
1081 $ hg show stack --config extensions.show=
1082 o 1553 added c
1082 o 1553 added c
1083 o 5f6d added b
1083 o 5f6d added b
1084 @ 9092 added a
1084 @ 9092 added a
1085
1085
1086 $ hg ci -m "branch closed" --close-branch
1086 $ hg ci -m "branch closed" --close-branch
1087 abort: can only close branch heads
1087 abort: can only close branch heads
1088 (use --force-close-branch to close branch from a non-head changeset)
1088 (use --force-close-branch to close branch from a non-head changeset)
1089 [10]
1089 [10]
1090
1090
1091 $ hg ci -m "branch closed" --force-close-branch
1091 $ hg ci -m "branch closed" --force-close-branch
1092 created new head
1092 created new head
1093 $ cd ..
1093 $ cd ..
1094
1094
1095 Test various special cases for the branchmap
1095 Test various special cases for the branchmap
1096 --------------------------------------------
1096 --------------------------------------------
1097
1097
1098 Basic fork of the same branch
1098 Basic fork of the same branch
1099
1099
1100 $ hg init branchmap-testing1
1100 $ hg init branchmap-testing1
1101 $ cd branchmap-testing1
1101 $ cd branchmap-testing1
1102 $ hg debugbuild '@A . :base . :p1 *base /p1'
1102 $ hg debugbuild '@A . :base . :p1 *base /p1'
1103 $ hg log -G
1103 $ hg log -G
1104 o changeset: 3:71ca9a6d524e
1104 o changeset: 3:71ca9a6d524e
1105 |\ branch: A
1105 |\ branch: A
1106 | | tag: tip
1106 | | tag: tip
1107 | | parent: 2:a3b807b3ff0b
1107 | | parent: 2:a3b807b3ff0b
1108 | | parent: 1:99ba08759bc7
1108 | | parent: 1:99ba08759bc7
1109 | | user: debugbuilddag
1109 | | user: debugbuilddag
1110 | | date: Thu Jan 01 00:00:03 1970 +0000
1110 | | date: Thu Jan 01 00:00:03 1970 +0000
1111 | | summary: r3
1111 | | summary: r3
1112 | |
1112 | |
1113 | o changeset: 2:a3b807b3ff0b
1113 | o changeset: 2:a3b807b3ff0b
1114 | | branch: A
1114 | | branch: A
1115 | | parent: 0:2ab8003a1750
1115 | | parent: 0:2ab8003a1750
1116 | | user: debugbuilddag
1116 | | user: debugbuilddag
1117 | | date: Thu Jan 01 00:00:02 1970 +0000
1117 | | date: Thu Jan 01 00:00:02 1970 +0000
1118 | | summary: r2
1118 | | summary: r2
1119 | |
1119 | |
1120 o | changeset: 1:99ba08759bc7
1120 o | changeset: 1:99ba08759bc7
1121 |/ branch: A
1121 |/ branch: A
1122 | tag: p1
1122 | tag: p1
1123 | user: debugbuilddag
1123 | user: debugbuilddag
1124 | date: Thu Jan 01 00:00:01 1970 +0000
1124 | date: Thu Jan 01 00:00:01 1970 +0000
1125 | summary: r1
1125 | summary: r1
1126 |
1126 |
1127 o changeset: 0:2ab8003a1750
1127 o changeset: 0:2ab8003a1750
1128 branch: A
1128 branch: A
1129 tag: base
1129 tag: base
1130 user: debugbuilddag
1130 user: debugbuilddag
1131 date: Thu Jan 01 00:00:00 1970 +0000
1131 date: Thu Jan 01 00:00:00 1970 +0000
1132 summary: r0
1132 summary: r0
1133
1133
1134 $ hg branches
1134 $ hg branches
1135 A 3:71ca9a6d524e
1135 A 3:71ca9a6d524e
1136 $ hg clone -r 1 -r 2 . ../branchmap-testing1-clone
1136 $ hg clone -r 1 -r 2 . ../branchmap-testing1-clone
1137 adding changesets
1137 adding changesets
1138 adding manifests
1138 adding manifests
1139 adding file changes
1139 adding file changes
1140 added 3 changesets with 0 changes to 0 files (+1 heads)
1140 added 3 changesets with 0 changes to 0 files (+1 heads)
1141 new changesets 2ab8003a1750:a3b807b3ff0b
1141 new changesets 2ab8003a1750:a3b807b3ff0b
1142 updating to branch A
1142 updating to branch A
1143 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1143 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1144 $ cd ../branchmap-testing1-clone
1144 $ cd ../branchmap-testing1-clone
1145 $ hg pull ../branchmap-testing1
1145 $ hg pull ../branchmap-testing1
1146 pulling from ../branchmap-testing1
1146 pulling from ../branchmap-testing1
1147 searching for changes
1147 searching for changes
1148 adding changesets
1148 adding changesets
1149 adding manifests
1149 adding manifests
1150 adding file changes
1150 adding file changes
1151 added 1 changesets with 0 changes to 0 files (-1 heads)
1151 added 1 changesets with 0 changes to 0 files (-1 heads)
1152 new changesets 71ca9a6d524e
1152 new changesets 71ca9a6d524e
1153 (run 'hg update' to get a working copy)
1153 (run 'hg update' to get a working copy)
1154 $ hg branches
1154 $ hg branches
1155 A 3:71ca9a6d524e
1155 A 3:71ca9a6d524e
1156 $ cd ..
1156 $ cd ..
1157
1157
1158 Switching to a different branch and back
1158 Switching to a different branch and back
1159
1159
1160 $ hg init branchmap-testing2
1160 $ hg init branchmap-testing2
1161 $ cd branchmap-testing2
1161 $ cd branchmap-testing2
1162 $ hg debugbuild '@A . @B . @A .'
1162 $ hg debugbuild '@A . @B . @A .'
1163 $ hg log -G
1163 $ hg log -G
1164 o changeset: 2:9699e9f260b5
1164 o changeset: 2:9699e9f260b5
1165 | branch: A
1165 | branch: A
1166 | tag: tip
1166 | tag: tip
1167 | user: debugbuilddag
1167 | user: debugbuilddag
1168 | date: Thu Jan 01 00:00:02 1970 +0000
1168 | date: Thu Jan 01 00:00:02 1970 +0000
1169 | summary: r2
1169 | summary: r2
1170 |
1170 |
1171 o changeset: 1:0bc7d348d965
1171 o changeset: 1:0bc7d348d965
1172 | branch: B
1172 | branch: B
1173 | user: debugbuilddag
1173 | user: debugbuilddag
1174 | date: Thu Jan 01 00:00:01 1970 +0000
1174 | date: Thu Jan 01 00:00:01 1970 +0000
1175 | summary: r1
1175 | summary: r1
1176 |
1176 |
1177 o changeset: 0:2ab8003a1750
1177 o changeset: 0:2ab8003a1750
1178 branch: A
1178 branch: A
1179 user: debugbuilddag
1179 user: debugbuilddag
1180 date: Thu Jan 01 00:00:00 1970 +0000
1180 date: Thu Jan 01 00:00:00 1970 +0000
1181 summary: r0
1181 summary: r0
1182
1182
1183 $ hg branches
1183 $ hg branches
1184 A 2:9699e9f260b5
1184 A 2:9699e9f260b5
1185 B 1:0bc7d348d965 (inactive)
1185 B 1:0bc7d348d965 (inactive)
1186 $ hg clone -r 1 . ../branchmap-testing2-clone
1186 $ hg clone -r 1 . ../branchmap-testing2-clone
1187 adding changesets
1187 adding changesets
1188 adding manifests
1188 adding manifests
1189 adding file changes
1189 adding file changes
1190 added 2 changesets with 0 changes to 0 files
1190 added 2 changesets with 0 changes to 0 files
1191 new changesets 2ab8003a1750:0bc7d348d965
1191 new changesets 2ab8003a1750:0bc7d348d965
1192 updating to branch B
1192 updating to branch B
1193 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1193 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1194 $ cd ../branchmap-testing2-clone
1194 $ cd ../branchmap-testing2-clone
1195 $ hg pull ../branchmap-testing2
1195 $ hg pull ../branchmap-testing2
1196 pulling from ../branchmap-testing2
1196 pulling from ../branchmap-testing2
1197 searching for changes
1197 searching for changes
1198 adding changesets
1198 adding changesets
1199 adding manifests
1199 adding manifests
1200 adding file changes
1200 adding file changes
1201 added 1 changesets with 0 changes to 0 files
1201 added 1 changesets with 0 changes to 0 files
1202 new changesets 9699e9f260b5
1202 new changesets 9699e9f260b5
1203 (run 'hg update' to get a working copy)
1203 (run 'hg update' to get a working copy)
1204 $ hg branches
1204 $ hg branches
1205 A 2:9699e9f260b5
1205 A 2:9699e9f260b5
1206 B 1:0bc7d348d965 (inactive)
1206 B 1:0bc7d348d965 (inactive)
1207 $ cd ..
1207 $ cd ..
1208
1208
1209 A fork on a branch switching to a different branch and back
1209 A fork on a branch switching to a different branch and back
1210 is still collecting the fork.
1210 is still collecting the fork.
1211
1211
1212 $ hg init branchmap-testing3
1212 $ hg init branchmap-testing3
1213 $ cd branchmap-testing3
1213 $ cd branchmap-testing3
1214 $ hg debugbuild '@A . :base . :p1 *base @B . @A /p1'
1214 $ hg debugbuild '@A . :base . :p1 *base @B . @A /p1'
1215 $ hg log -G
1215 $ hg log -G
1216 o changeset: 4:3614a1711d23
1216 o changeset: 4:3614a1711d23
1217 |\ branch: A
1217 |\ branch: A
1218 | | tag: tip
1218 | | tag: tip
1219 | | parent: 3:e9c8abcf65aa
1219 | | parent: 3:e9c8abcf65aa
1220 | | parent: 1:99ba08759bc7
1220 | | parent: 1:99ba08759bc7
1221 | | user: debugbuilddag
1221 | | user: debugbuilddag
1222 | | date: Thu Jan 01 00:00:04 1970 +0000
1222 | | date: Thu Jan 01 00:00:04 1970 +0000
1223 | | summary: r4
1223 | | summary: r4
1224 | |
1224 | |
1225 | o changeset: 3:e9c8abcf65aa
1225 | o changeset: 3:e9c8abcf65aa
1226 | | branch: B
1226 | | branch: B
1227 | | user: debugbuilddag
1227 | | user: debugbuilddag
1228 | | date: Thu Jan 01 00:00:03 1970 +0000
1228 | | date: Thu Jan 01 00:00:03 1970 +0000
1229 | | summary: r3
1229 | | summary: r3
1230 | |
1230 | |
1231 | o changeset: 2:a3b807b3ff0b
1231 | o changeset: 2:a3b807b3ff0b
1232 | | branch: A
1232 | | branch: A
1233 | | parent: 0:2ab8003a1750
1233 | | parent: 0:2ab8003a1750
1234 | | user: debugbuilddag
1234 | | user: debugbuilddag
1235 | | date: Thu Jan 01 00:00:02 1970 +0000
1235 | | date: Thu Jan 01 00:00:02 1970 +0000
1236 | | summary: r2
1236 | | summary: r2
1237 | |
1237 | |
1238 o | changeset: 1:99ba08759bc7
1238 o | changeset: 1:99ba08759bc7
1239 |/ branch: A
1239 |/ branch: A
1240 | tag: p1
1240 | tag: p1
1241 | user: debugbuilddag
1241 | user: debugbuilddag
1242 | date: Thu Jan 01 00:00:01 1970 +0000
1242 | date: Thu Jan 01 00:00:01 1970 +0000
1243 | summary: r1
1243 | summary: r1
1244 |
1244 |
1245 o changeset: 0:2ab8003a1750
1245 o changeset: 0:2ab8003a1750
1246 branch: A
1246 branch: A
1247 tag: base
1247 tag: base
1248 user: debugbuilddag
1248 user: debugbuilddag
1249 date: Thu Jan 01 00:00:00 1970 +0000
1249 date: Thu Jan 01 00:00:00 1970 +0000
1250 summary: r0
1250 summary: r0
1251
1251
1252 $ hg branches
1252 $ hg branches
1253 A 4:3614a1711d23
1253 A 4:3614a1711d23
1254 B 3:e9c8abcf65aa (inactive)
1254 B 3:e9c8abcf65aa (inactive)
1255 $ hg clone -r 1 -r 3 . ../branchmap-testing3-clone
1255 $ hg clone -r 1 -r 3 . ../branchmap-testing3-clone
1256 adding changesets
1256 adding changesets
1257 adding manifests
1257 adding manifests
1258 adding file changes
1258 adding file changes
1259 added 4 changesets with 0 changes to 0 files (+1 heads)
1259 added 4 changesets with 0 changes to 0 files (+1 heads)
1260 new changesets 2ab8003a1750:e9c8abcf65aa
1260 new changesets 2ab8003a1750:e9c8abcf65aa
1261 updating to branch A
1261 updating to branch A
1262 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1262 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1263 $ cd ../branchmap-testing3-clone
1263 $ cd ../branchmap-testing3-clone
1264 $ hg pull ../branchmap-testing3
1264 $ hg pull ../branchmap-testing3
1265 pulling from ../branchmap-testing3
1265 pulling from ../branchmap-testing3
1266 searching for changes
1266 searching for changes
1267 adding changesets
1267 adding changesets
1268 adding manifests
1268 adding manifests
1269 adding file changes
1269 adding file changes
1270 added 1 changesets with 0 changes to 0 files (-1 heads)
1270 added 1 changesets with 0 changes to 0 files (-1 heads)
1271 new changesets 3614a1711d23
1271 new changesets 3614a1711d23
1272 (run 'hg update' to get a working copy)
1272 (run 'hg update' to get a working copy)
1273 $ hg branches
1273 $ hg branches
1274 A 4:3614a1711d23
1274 A 4:3614a1711d23
1275 B 3:e9c8abcf65aa (inactive)
1275 B 3:e9c8abcf65aa (inactive)
1276 $ cd ..
1276 $ cd ..
1277
1277
1278 Intermediary parents are on different branches.
1278 Intermediary parents are on different branches.
1279
1279
1280 $ hg init branchmap-testing4
1280 $ hg init branchmap-testing4
1281 $ cd branchmap-testing4
1281 $ cd branchmap-testing4
1282 $ hg debugbuild '@A . @B :base . @A :p1 *base @C . @A /p1'
1282 $ hg debugbuild '@A . @B :base . @A :p1 *base @C . @A /p1'
1283 $ hg log -G
1283 $ hg log -G
1284 o changeset: 4:4bf67499b70a
1284 o changeset: 4:4bf67499b70a
1285 |\ branch: A
1285 |\ branch: A
1286 | | tag: tip
1286 | | tag: tip
1287 | | parent: 3:4a546028fa8f
1287 | | parent: 3:4a546028fa8f
1288 | | parent: 1:0bc7d348d965
1288 | | parent: 1:0bc7d348d965
1289 | | user: debugbuilddag
1289 | | user: debugbuilddag
1290 | | date: Thu Jan 01 00:00:04 1970 +0000
1290 | | date: Thu Jan 01 00:00:04 1970 +0000
1291 | | summary: r4
1291 | | summary: r4
1292 | |
1292 | |
1293 | o changeset: 3:4a546028fa8f
1293 | o changeset: 3:4a546028fa8f
1294 | | branch: C
1294 | | branch: C
1295 | | user: debugbuilddag
1295 | | user: debugbuilddag
1296 | | date: Thu Jan 01 00:00:03 1970 +0000
1296 | | date: Thu Jan 01 00:00:03 1970 +0000
1297 | | summary: r3
1297 | | summary: r3
1298 | |
1298 | |
1299 | o changeset: 2:a3b807b3ff0b
1299 | o changeset: 2:a3b807b3ff0b
1300 | | branch: A
1300 | | branch: A
1301 | | parent: 0:2ab8003a1750
1301 | | parent: 0:2ab8003a1750
1302 | | user: debugbuilddag
1302 | | user: debugbuilddag
1303 | | date: Thu Jan 01 00:00:02 1970 +0000
1303 | | date: Thu Jan 01 00:00:02 1970 +0000
1304 | | summary: r2
1304 | | summary: r2
1305 | |
1305 | |
1306 o | changeset: 1:0bc7d348d965
1306 o | changeset: 1:0bc7d348d965
1307 |/ branch: B
1307 |/ branch: B
1308 | tag: p1
1308 | tag: p1
1309 | user: debugbuilddag
1309 | user: debugbuilddag
1310 | date: Thu Jan 01 00:00:01 1970 +0000
1310 | date: Thu Jan 01 00:00:01 1970 +0000
1311 | summary: r1
1311 | summary: r1
1312 |
1312 |
1313 o changeset: 0:2ab8003a1750
1313 o changeset: 0:2ab8003a1750
1314 branch: A
1314 branch: A
1315 tag: base
1315 tag: base
1316 user: debugbuilddag
1316 user: debugbuilddag
1317 date: Thu Jan 01 00:00:00 1970 +0000
1317 date: Thu Jan 01 00:00:00 1970 +0000
1318 summary: r0
1318 summary: r0
1319
1319
1320 $ hg branches
1320 $ hg branches
1321 A 4:4bf67499b70a
1321 A 4:4bf67499b70a
1322 C 3:4a546028fa8f (inactive)
1322 C 3:4a546028fa8f (inactive)
1323 B 1:0bc7d348d965 (inactive)
1323 B 1:0bc7d348d965 (inactive)
1324 $ hg clone -r 1 -r 3 . ../branchmap-testing4-clone
1324 $ hg clone -r 1 -r 3 . ../branchmap-testing4-clone
1325 adding changesets
1325 adding changesets
1326 adding manifests
1326 adding manifests
1327 adding file changes
1327 adding file changes
1328 added 4 changesets with 0 changes to 0 files (+1 heads)
1328 added 4 changesets with 0 changes to 0 files (+1 heads)
1329 new changesets 2ab8003a1750:4a546028fa8f
1329 new changesets 2ab8003a1750:4a546028fa8f
1330 updating to branch B
1330 updating to branch B
1331 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1331 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1332 $ cd ../branchmap-testing4-clone
1332 $ cd ../branchmap-testing4-clone
1333 $ hg pull ../branchmap-testing4
1333 $ hg pull ../branchmap-testing4
1334 pulling from ../branchmap-testing4
1334 pulling from ../branchmap-testing4
1335 searching for changes
1335 searching for changes
1336 adding changesets
1336 adding changesets
1337 adding manifests
1337 adding manifests
1338 adding file changes
1338 adding file changes
1339 added 1 changesets with 0 changes to 0 files (-1 heads)
1339 added 1 changesets with 0 changes to 0 files (-1 heads)
1340 new changesets 4bf67499b70a
1340 new changesets 4bf67499b70a
1341 (run 'hg update' to get a working copy)
1341 (run 'hg update' to get a working copy)
1342 $ hg branches
1342 $ hg branches
1343 A 4:4bf67499b70a
1343 A 4:4bf67499b70a
1344 C 3:4a546028fa8f (inactive)
1344 C 3:4a546028fa8f (inactive)
1345 B 1:0bc7d348d965 (inactive)
1345 B 1:0bc7d348d965 (inactive)
1346 $ cd ..
1346 $ cd ..
1347
1347
1348 Check that the cache are not written too early
1348 Check that the cache are not written too early
1349 ----------------------------------------------
1349 ----------------------------------------------
1350
1350
1351 $ hg log -R branchmap-testing1 -G
1351 $ hg log -R branchmap-testing1 -G
1352 o changeset: 3:71ca9a6d524e
1352 o changeset: 3:71ca9a6d524e
1353 |\ branch: A
1353 |\ branch: A
1354 | | tag: tip
1354 | | tag: tip
1355 | | parent: 2:a3b807b3ff0b
1355 | | parent: 2:a3b807b3ff0b
1356 | | parent: 1:99ba08759bc7
1356 | | parent: 1:99ba08759bc7
1357 | | user: debugbuilddag
1357 | | user: debugbuilddag
1358 | | date: Thu Jan 01 00:00:03 1970 +0000
1358 | | date: Thu Jan 01 00:00:03 1970 +0000
1359 | | summary: r3
1359 | | summary: r3
1360 | |
1360 | |
1361 | o changeset: 2:a3b807b3ff0b
1361 | o changeset: 2:a3b807b3ff0b
1362 | | branch: A
1362 | | branch: A
1363 | | parent: 0:2ab8003a1750
1363 | | parent: 0:2ab8003a1750
1364 | | user: debugbuilddag
1364 | | user: debugbuilddag
1365 | | date: Thu Jan 01 00:00:02 1970 +0000
1365 | | date: Thu Jan 01 00:00:02 1970 +0000
1366 | | summary: r2
1366 | | summary: r2
1367 | |
1367 | |
1368 o | changeset: 1:99ba08759bc7
1368 o | changeset: 1:99ba08759bc7
1369 |/ branch: A
1369 |/ branch: A
1370 | tag: p1
1370 | tag: p1
1371 | user: debugbuilddag
1371 | user: debugbuilddag
1372 | date: Thu Jan 01 00:00:01 1970 +0000
1372 | date: Thu Jan 01 00:00:01 1970 +0000
1373 | summary: r1
1373 | summary: r1
1374 |
1374 |
1375 o changeset: 0:2ab8003a1750
1375 o changeset: 0:2ab8003a1750
1376 branch: A
1376 branch: A
1377 tag: base
1377 tag: base
1378 user: debugbuilddag
1378 user: debugbuilddag
1379 date: Thu Jan 01 00:00:00 1970 +0000
1379 date: Thu Jan 01 00:00:00 1970 +0000
1380 summary: r0
1380 summary: r0
1381
1381
1382 $ hg bundle -R branchmap-testing1 --base 1 bundle.hg --rev 'head()'
1382 $ hg bundle -R branchmap-testing1 --base 1 bundle.hg --rev 'head()'
1383 2 changesets found
1383 2 changesets found
1384
1384
1385 Unbundling revision should warm the served cache
1385 Unbundling revision should warm the served cache
1386
1386
1387 $ hg clone branchmap-testing1 --rev 1 branchmap-update-01
1387 $ hg clone branchmap-testing1 --rev 1 branchmap-update-01
1388 adding changesets
1388 adding changesets
1389 adding manifests
1389 adding manifests
1390 adding file changes
1390 adding file changes
1391 added 2 changesets with 0 changes to 0 files
1391 added 2 changesets with 0 changes to 0 files
1392 new changesets 2ab8003a1750:99ba08759bc7
1392 new changesets 2ab8003a1750:99ba08759bc7
1393 updating to branch A
1393 updating to branch A
1394 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1394 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1395 #if v3
1395 #if v3
1396 $ cat branchmap-update-01/.hg/cache/branch3-exp-base
1396 $ cat branchmap-update-01/.hg/cache/branch3-exp-base
1397 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1397 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1398 A
1398 A
1399 #else
1399 #else
1400 $ cat branchmap-update-01/.hg/cache/branch2-base
1400 $ cat branchmap-update-01/.hg/cache/branch2-base
1401 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1401 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1402 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1402 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1403 #endif
1403 #endif
1404 $ hg -R branchmap-update-01 unbundle bundle.hg
1404 $ hg -R branchmap-update-01 unbundle bundle.hg
1405 adding changesets
1405 adding changesets
1406 adding manifests
1406 adding manifests
1407 adding file changes
1407 adding file changes
1408 added 2 changesets with 0 changes to 0 files
1408 added 2 changesets with 0 changes to 0 files
1409 new changesets a3b807b3ff0b:71ca9a6d524e (2 drafts)
1409 new changesets a3b807b3ff0b:71ca9a6d524e (2 drafts)
1410 (run 'hg update' to get a working copy)
1410 (run 'hg update' to get a working copy)
1411 #if v3
1411 #if v3
1412 $ cat branchmap-update-01/.hg/cache/branch3-exp-served
1412 $ cat branchmap-update-01/.hg/cache/branch3-exp-served
1413 tip-node=71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 tip-rev=3 topo-mode=pure
1413 tip-node=71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 tip-rev=3 topo-mode=pure
1414 A
1414 A
1415 #else
1415 #else
1416 $ cat branchmap-update-01/.hg/cache/branch2-served
1416 $ cat branchmap-update-01/.hg/cache/branch2-served
1417 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 3
1417 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 3
1418 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 o A
1418 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 o A
1419 #endif
1419 #endif
1420
1420
1421 aborted Unbundle should not update the on disk cache
1421 aborted Unbundle should not update the on disk cache
1422
1422
1423 $ cat >> simplehook.py << EOF
1423 $ cat >> simplehook.py << EOF
1424 > import sys
1424 > import sys
1425 > from mercurial import node
1425 > from mercurial import node
1426 > from mercurial import branchmap
1426 > from mercurial import branchmap
1427 > def hook(ui, repo, *args, **kwargs):
1427 > def hook(ui, repo, *args, **kwargs):
1428 > s = repo.filtered(b"served")
1428 > s = repo.filtered(b"served")
1429 > s.branchmap()
1429 > s.branchmap()
1430 > return 1
1430 > return 1
1431 > EOF
1431 > EOF
1432 $ hg clone branchmap-testing1 --rev 1 branchmap-update-02
1432 $ hg clone branchmap-testing1 --rev 1 branchmap-update-02
1433 adding changesets
1433 adding changesets
1434 adding manifests
1434 adding manifests
1435 adding file changes
1435 adding file changes
1436 added 2 changesets with 0 changes to 0 files
1436 added 2 changesets with 0 changes to 0 files
1437 new changesets 2ab8003a1750:99ba08759bc7
1437 new changesets 2ab8003a1750:99ba08759bc7
1438 updating to branch A
1438 updating to branch A
1439 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1439 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1440
1440
1441 #if v3
1441 #if v3
1442 $ cat branchmap-update-02/.hg/cache/branch3-exp-base
1442 $ cat branchmap-update-02/.hg/cache/branch3-exp-base
1443 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1443 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1444 A
1444 A
1445 #else
1445 #else
1446 $ cat branchmap-update-02/.hg/cache/branch2-base
1446 $ cat branchmap-update-02/.hg/cache/branch2-base
1447 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1447 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1448 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1448 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1449 #endif
1449 #endif
1450 $ hg -R branchmap-update-02 unbundle bundle.hg --config "hooks.pretxnclose=python:$TESTTMP/simplehook.py:hook"
1450 $ hg -R branchmap-update-02 unbundle bundle.hg --config "hooks.pretxnclose=python:$TESTTMP/simplehook.py:hook"
1451 adding changesets
1451 adding changesets
1452 adding manifests
1452 adding manifests
1453 adding file changes
1453 adding file changes
1454 transaction abort!
1454 transaction abort!
1455 rollback completed
1455 rollback completed
1456 abort: pretxnclose hook failed
1456 abort: pretxnclose hook failed
1457 [40]
1457 [40]
1458 #if v3
1458 #if v3
1459 $ cat branchmap-update-02/.hg/cache/branch3-exp-base
1459 $ cat branchmap-update-02/.hg/cache/branch3-exp-base
1460 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1460 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1461 A
1461 A
1462 #else
1462 #else
1463 $ cat branchmap-update-02/.hg/cache/branch2-base
1463 $ cat branchmap-update-02/.hg/cache/branch2-base
1464 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1464 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1465 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1465 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1466 #endif
1466 #endif
General Comments 0
You need to be logged in to leave comments. Login now