##// END OF EJS Templates
rev-branch-cache: properly ignores unaligned trailing data...
marmoute -
r52868:76416b6e default
parent child Browse files
Show More
@@ -1,434 +1,442
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 @property
60 def len_prefix(self):
61 size = len(self._prefix)
62 return size - (size % _rbcrecsize)
63
59 def __len__(self):
64 def __len__(self):
60 return len(self._prefix) + len(self._rest)
65 return self.len_prefix + len(self._rest)
61
66
62 def unpack_record(self, rbcrevidx):
67 def unpack_record(self, rbcrevidx):
63 if rbcrevidx < len(self._prefix):
68 if rbcrevidx < self.len_prefix:
64 return unpack_from(_rbcrecfmt, util.buffer(self._prefix), rbcrevidx)
69 return unpack_from(_rbcrecfmt, util.buffer(self._prefix), rbcrevidx)
65 else:
70 else:
66 return unpack_from(
71 return unpack_from(
67 _rbcrecfmt,
72 _rbcrecfmt,
68 util.buffer(self._rest),
73 util.buffer(self._rest),
69 rbcrevidx - len(self._prefix),
74 rbcrevidx - self.len_prefix,
70 )
75 )
71
76
72 def make_mutable(self):
77 def make_mutable(self):
73 if len(self._prefix) > 0:
78 if self.len_prefix > 0:
74 entirety = bytearray()
79 entirety = bytearray()
75 entirety[:] = self._prefix
80 entirety[:] = self._prefix[: self.len_prefix]
76 entirety.extend(self._rest)
81 entirety.extend(self._rest)
77 self._rest = entirety
82 self._rest = entirety
78 self._prefix = bytearray()
83 self._prefix = bytearray()
79
84
80 def truncate(self, pos):
85 def truncate(self, pos):
81 self.make_mutable()
86 self.make_mutable()
82 del self._rest[pos:]
87 del self._rest[pos:]
83
88
84 def pack_into(self, rbcrevidx, node, branchidx):
89 def pack_into(self, rbcrevidx, node, branchidx):
85 if rbcrevidx < len(self._prefix):
90 if rbcrevidx < self.len_prefix:
86 self.make_mutable()
91 self.make_mutable()
87 buf = self._rest
92 buf = self._rest
88 start_offset = rbcrevidx - len(self._prefix)
93 start_offset = rbcrevidx - self.len_prefix
89 end_offset = start_offset + _rbcrecsize
94 end_offset = start_offset + _rbcrecsize
90
95
91 if len(self._rest) < end_offset:
96 if len(self._rest) < end_offset:
92 # bytearray doesn't allocate extra space at least in Python 3.7.
97 # bytearray doesn't allocate extra space at least in Python 3.7.
93 # When multiple changesets are added in a row, precise resize would
98 # When multiple changesets are added in a row, precise resize would
94 # result in quadratic complexity. Overallocate to compensate by
99 # result in quadratic complexity. Overallocate to compensate by
95 # using the classic doubling technique for dynamic arrays instead.
100 # using the classic doubling technique for dynamic arrays instead.
96 # If there was a gap in the map before, less space will be reserved.
101 # If there was a gap in the map before, less space will be reserved.
97 self._rest.extend(b'\0' * end_offset)
102 self._rest.extend(b'\0' * end_offset)
98 return pack_into(
103 return pack_into(
99 _rbcrecfmt,
104 _rbcrecfmt,
100 buf,
105 buf,
101 start_offset,
106 start_offset,
102 node,
107 node,
103 branchidx,
108 branchidx,
104 )
109 )
105
110
106 def extend(self, extension):
111 def extend(self, extension):
107 return self._rest.extend(extension)
112 return self._rest.extend(extension)
108
113
109 def slice(self, begin, end):
114 def slice(self, begin, end):
110 if begin < len(self._prefix):
115 if begin < self.len_prefix:
111 acc = bytearray()
116 acc = bytearray()
112 acc[:] = self._prefix[begin:end]
117 acc[:] = self._prefix[begin : min(end, self.len_prefix)]
113 acc.extend(
118 acc.extend(
114 self._rest[begin - len(self._prefix) : end - len(self._prefix)]
119 self._rest[begin - self.len_prefix : end - self.len_prefix]
115 )
120 )
116 return acc
121 return acc
117 return self._rest[begin - len(self._prefix) : end - len(self._prefix)]
122 return self._rest[begin - self.len_prefix : end - self.len_prefix]
118
123
119
124
120 class revbranchcache:
125 class revbranchcache:
121 """Persistent cache, mapping from revision number to branch name and close.
126 """Persistent cache, mapping from revision number to branch name and close.
122 This is a low level cache, independent of filtering.
127 This is a low level cache, independent of filtering.
123
128
124 Branch names are stored in rbc-names in internal encoding separated by 0.
129 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
130 rbc-names is append-only, and each branch name is only stored once and will
126 thus have a unique index.
131 thus have a unique index.
127
132
128 The branch info for each revision is stored in rbc-revs as constant size
133 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
134 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
135 demand. The file is usually append-only but will be truncated if repo
131 modification is detected.
136 modification is detected.
132 The record for each revision contains the first 4 bytes of the
137 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.
138 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
139 Even a completely trashed rbc-revs fill thus still give the right result
135 while converging towards full recovery ... assuming no incorrectly matching
140 while converging towards full recovery ... assuming no incorrectly matching
136 node hashes.
141 node hashes.
137 The record also contains 4 bytes where 31 bits contains the index of the
142 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.
143 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
144 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.
145 and will grow with it but be 1/8th of its size.
141 """
146 """
142
147
143 def __init__(self, repo, readonly=True):
148 def __init__(self, repo, readonly=True):
144 assert repo.filtername is None
149 assert repo.filtername is None
145 self._repo = repo
150 self._repo = repo
146 self._names = [] # branch names in local encoding with static index
151 self._names = [] # branch names in local encoding with static index
147 self._rbcrevs = rbcrevs(bytearray())
152 self._rbcrevs = rbcrevs(bytearray())
148 self._rbcsnameslen = 0 # length of names read at _rbcsnameslen
153 self._rbcsnameslen = 0 # length of names read at _rbcsnameslen
149 self._force_overwrite = False
154 self._force_overwrite = False
150 v1_fallback = False
155 v1_fallback = False
151 try:
156 try:
152 try:
157 try:
153 bndata = repo.cachevfs.read(_rbcnames)
158 bndata = repo.cachevfs.read(_rbcnames)
154 except (IOError, OSError):
159 except (IOError, OSError):
155 # If we don't have "v2" data, we might have "v1" data worth
160 # If we don't have "v2" data, we might have "v1" data worth
156 # using.
161 # using.
157 #
162 #
158 # consider stop doing this many version after hg-6.9 release
163 # consider stop doing this many version after hg-6.9 release
159 bndata = repo.cachevfs.read(_rbc_legacy_names)
164 bndata = repo.cachevfs.read(_rbc_legacy_names)
160 v1_fallback = True
165 v1_fallback = True
161 self._force_overwrite = True
166 self._force_overwrite = True
162 self._rbcsnameslen = len(bndata) # for verification before writing
167 self._rbcsnameslen = len(bndata) # for verification before writing
163 if bndata:
168 if bndata:
164 self._names = [
169 self._names = [
165 encoding.tolocal(bn) for bn in bndata.split(b'\0')
170 encoding.tolocal(bn) for bn in bndata.split(b'\0')
166 ]
171 ]
167 except (IOError, OSError):
172 except (IOError, OSError):
168 if readonly:
173 if readonly:
169 # don't try to use cache - fall back to the slow path
174 # don't try to use cache - fall back to the slow path
170 self.branchinfo = self._branchinfo
175 self.branchinfo = self._branchinfo
171
176
172 if self._names:
177 if self._names:
173 try:
178 try:
174 usemmap = repo.ui.configbool(b'storage', b'revbranchcache.mmap')
179 usemmap = repo.ui.configbool(b'storage', b'revbranchcache.mmap')
175 if not v1_fallback:
180 if not v1_fallback:
176 with repo.cachevfs(_rbcrevs) as fp:
181 with repo.cachevfs(_rbcrevs) as fp:
177 if usemmap and repo.cachevfs.is_mmap_safe(_rbcrevs):
182 if usemmap and repo.cachevfs.is_mmap_safe(_rbcrevs):
178 data = util.buffer(util.mmapread(fp))
183 data = util.buffer(util.mmapread(fp))
179 else:
184 else:
180 data = fp.read()
185 data = fp.read()
181 else:
186 else:
182 # If we don't have "v2" data, we might have "v1" data worth
187 # If we don't have "v2" data, we might have "v1" data worth
183 # using.
188 # using.
184 #
189 #
185 # Consider stop doing this many version after hg-6.9
190 # Consider stop doing this many version after hg-6.9
186 # release.
191 # release.
187 with repo.cachevfs(_rbc_legacy_revs) as fp:
192 with repo.cachevfs(_rbc_legacy_revs) as fp:
188 data = fp.read()
193 data = fp.read()
189 self._rbcrevs = rbcrevs(data)
194 self._rbcrevs = rbcrevs(data)
190 except (IOError, OSError) as inst:
195 except (IOError, OSError) as inst:
191 repo.ui.debug(
196 repo.ui.debug(
192 b"couldn't read revision branch cache: %s\n"
197 b"couldn't read revision branch cache: %s\n"
193 % stringutil.forcebytestr(inst)
198 % stringutil.forcebytestr(inst)
194 )
199 )
195 # remember number of good records on disk
200 # remember number of good records on disk
196 self._rbcrevslen = min(
201 self._rbcrevslen = min(
197 len(self._rbcrevs) // _rbcrecsize, len(repo.changelog)
202 len(self._rbcrevs) // _rbcrecsize, len(repo.changelog)
198 )
203 )
199 if self._rbcrevslen == 0:
204 if self._rbcrevslen == 0:
200 self._names = []
205 self._names = []
201 self._rbcnamescount = len(self._names) # number of names read at
206 self._rbcnamescount = len(self._names) # number of names read at
202 # _rbcsnameslen
207 # _rbcsnameslen
203
208
204 def _clear(self):
209 def _clear(self):
205 self._rbcsnameslen = 0
210 self._rbcsnameslen = 0
206 del self._names[:]
211 del self._names[:]
207 self._rbcnamescount = 0
212 self._rbcnamescount = 0
208 self._rbcrevslen = len(self._repo.changelog)
213 self._rbcrevslen = len(self._repo.changelog)
209 self._rbcrevs = rbcrevs(bytearray(self._rbcrevslen * _rbcrecsize))
214 self._rbcrevs = rbcrevs(bytearray(self._rbcrevslen * _rbcrecsize))
210 util.clearcachedproperty(self, b'_namesreverse')
215 util.clearcachedproperty(self, b'_namesreverse')
211 self._force_overwrite = True
216 self._force_overwrite = True
212
217
213 def invalidate(self, rev=0):
218 def invalidate(self, rev=0):
214 self._rbcrevslen = rev
219 self._rbcrevslen = rev
215 self._rbcrevs.truncate(rev)
220 self._rbcrevs.truncate(rev)
216 self._force_overwrite = True
221 self._force_overwrite = True
217
222
218 @util.propertycache
223 @util.propertycache
219 def _namesreverse(self):
224 def _namesreverse(self):
220 return {b: r for r, b in enumerate(self._names)}
225 return {b: r for r, b in enumerate(self._names)}
221
226
222 def branchinfo(self, rev):
227 def branchinfo(self, rev):
223 """Return branch name and close flag for rev, using and updating
228 """Return branch name and close flag for rev, using and updating
224 persistent cache."""
229 persistent cache."""
225 changelog = self._repo.changelog
230 changelog = self._repo.changelog
226 rbcrevidx = rev * _rbcrecsize
231 rbcrevidx = rev * _rbcrecsize
227
232
228 # avoid negative index, changelog.read(nullrev) is fast without cache
233 # avoid negative index, changelog.read(nullrev) is fast without cache
229 if rev == nullrev:
234 if rev == nullrev:
230 return changelog.branchinfo(rev)
235 return changelog.branchinfo(rev)
231
236
232 # if requested rev isn't allocated, grow and cache the rev info
237 # if requested rev isn't allocated, grow and cache the rev info
233 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
238 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
234 return self._branchinfo(rev)
239 return self._branchinfo(rev)
235
240
236 # fast path: extract data from cache, use it if node is matching
241 # fast path: extract data from cache, use it if node is matching
237 reponode = changelog.node(rev)[:_rbcnodelen]
242 reponode = changelog.node(rev)[:_rbcnodelen]
238 cachenode, branchidx = self._rbcrevs.unpack_record(rbcrevidx)
243 cachenode, branchidx = self._rbcrevs.unpack_record(rbcrevidx)
239 close = bool(branchidx & _rbccloseflag)
244 close = bool(branchidx & _rbccloseflag)
240 if close:
245 if close:
241 branchidx &= _rbcbranchidxmask
246 branchidx &= _rbcbranchidxmask
242 if cachenode == b'\0\0\0\0':
247 if cachenode == b'\0\0\0\0':
243 pass
248 pass
244 elif cachenode == reponode:
249 elif cachenode == reponode:
245 try:
250 try:
246 return self._names[branchidx], close
251 return self._names[branchidx], close
247 except IndexError:
252 except IndexError:
248 # recover from invalid reference to unknown branch
253 # recover from invalid reference to unknown branch
249 self._repo.ui.debug(
254 self._repo.ui.debug(
250 b"referenced branch names not found"
255 b"referenced branch names not found"
251 b" - rebuilding revision branch cache from scratch\n"
256 b" - rebuilding revision branch cache from scratch\n"
252 )
257 )
253 self._clear()
258 self._clear()
254 else:
259 else:
255 # rev/node map has changed, invalidate the cache from here up
260 # rev/node map has changed, invalidate the cache from here up
256 self._repo.ui.debug(
261 self._repo.ui.debug(
257 b"history modification detected - truncating "
262 b"history modification detected - truncating "
258 b"revision branch cache to revision %d\n" % rev
263 b"revision branch cache to revision %d\n" % rev
259 )
264 )
260 truncate = rbcrevidx + _rbcrecsize
265 truncate = rbcrevidx + _rbcrecsize
261 self._rbcrevs.truncate(truncate)
266 self._rbcrevs.truncate(truncate)
262 self._rbcrevslen = min(self._rbcrevslen, truncate)
267 self._rbcrevslen = min(self._rbcrevslen, truncate)
263
268
264 # fall back to slow path and make sure it will be written to disk
269 # fall back to slow path and make sure it will be written to disk
265 return self._branchinfo(rev)
270 return self._branchinfo(rev)
266
271
267 def _branchinfo(self, rev):
272 def _branchinfo(self, rev):
268 """Retrieve branch info from changelog and update _rbcrevs"""
273 """Retrieve branch info from changelog and update _rbcrevs"""
269 changelog = self._repo.changelog
274 changelog = self._repo.changelog
270 b, close = changelog.branchinfo(rev)
275 b, close = changelog.branchinfo(rev)
271 if b in self._namesreverse:
276 if b in self._namesreverse:
272 branchidx = self._namesreverse[b]
277 branchidx = self._namesreverse[b]
273 else:
278 else:
274 branchidx = len(self._names)
279 branchidx = len(self._names)
275 self._names.append(b)
280 self._names.append(b)
276 self._namesreverse[b] = branchidx
281 self._namesreverse[b] = branchidx
277 reponode = changelog.node(rev)
282 reponode = changelog.node(rev)
278 if close:
283 if close:
279 branchidx |= _rbccloseflag
284 branchidx |= _rbccloseflag
280 self._setcachedata(rev, reponode, branchidx)
285 self._setcachedata(rev, reponode, branchidx)
281 return b, close
286 return b, close
282
287
283 def setdata(self, rev, changelogrevision):
288 def setdata(self, rev, changelogrevision):
284 """add new data information to the cache"""
289 """add new data information to the cache"""
285 branch, close = changelogrevision.branchinfo
290 branch, close = changelogrevision.branchinfo
286
291
287 if branch in self._namesreverse:
292 if branch in self._namesreverse:
288 branchidx = self._namesreverse[branch]
293 branchidx = self._namesreverse[branch]
289 else:
294 else:
290 branchidx = len(self._names)
295 branchidx = len(self._names)
291 self._names.append(branch)
296 self._names.append(branch)
292 self._namesreverse[branch] = branchidx
297 self._namesreverse[branch] = branchidx
293 if close:
298 if close:
294 branchidx |= _rbccloseflag
299 branchidx |= _rbccloseflag
295 self._setcachedata(rev, self._repo.changelog.node(rev), branchidx)
300 self._setcachedata(rev, self._repo.changelog.node(rev), branchidx)
296 # If no cache data were readable (non exists, bad permission, etc)
301 # If no cache data were readable (non exists, bad permission, etc)
297 # the cache was bypassing itself by setting:
302 # the cache was bypassing itself by setting:
298 #
303 #
299 # self.branchinfo = self._branchinfo
304 # self.branchinfo = self._branchinfo
300 #
305 #
301 # Since we now have data in the cache, we need to drop this bypassing.
306 # Since we now have data in the cache, we need to drop this bypassing.
302 if 'branchinfo' in vars(self):
307 if 'branchinfo' in vars(self):
303 del self.branchinfo
308 del self.branchinfo
304
309
305 def _setcachedata(self, rev, node, branchidx):
310 def _setcachedata(self, rev, node, branchidx):
306 """Writes the node's branch data to the in-memory cache data."""
311 """Writes the node's branch data to the in-memory cache data."""
307 if rev == nullrev:
312 if rev == nullrev:
308 return
313 return
309 rbcrevidx = rev * _rbcrecsize
314 rbcrevidx = rev * _rbcrecsize
310 self._rbcrevs.pack_into(rbcrevidx, node, branchidx)
315 self._rbcrevs.pack_into(rbcrevidx, node, branchidx)
311 self._rbcrevslen = min(self._rbcrevslen, rev)
316 self._rbcrevslen = min(self._rbcrevslen, rev)
312
317
313 tr = self._repo.currenttransaction()
318 tr = self._repo.currenttransaction()
314 if tr:
319 if tr:
315 tr.addfinalize(b'write-revbranchcache', self.write)
320 tr.addfinalize(b'write-revbranchcache', self.write)
316
321
317 def write(self, tr=None):
322 def write(self, tr=None):
318 """Save branch cache if it is dirty."""
323 """Save branch cache if it is dirty."""
319 repo = self._repo
324 repo = self._repo
320 wlock = None
325 wlock = None
321 step = b''
326 step = b''
322 try:
327 try:
323 # write the new names
328 # write the new names
324 if self._force_overwrite or self._rbcnamescount < len(self._names):
329 if self._force_overwrite or self._rbcnamescount < len(self._names):
325 wlock = repo.wlock(wait=False)
330 wlock = repo.wlock(wait=False)
326 step = b' names'
331 step = b' names'
327 self._writenames(repo)
332 self._writenames(repo)
328
333
329 # write the new revs
334 # write the new revs
330 start = self._rbcrevslen * _rbcrecsize
335 start = self._rbcrevslen * _rbcrecsize
331 if self._force_overwrite or start != len(self._rbcrevs):
336 if self._force_overwrite or start != len(self._rbcrevs):
332 step = b''
337 step = b''
333 if wlock is None:
338 if wlock is None:
334 wlock = repo.wlock(wait=False)
339 wlock = repo.wlock(wait=False)
335 self._writerevs(repo, start)
340 self._writerevs(repo, start)
336
341
337 except (IOError, OSError, error.Abort, error.LockError) as inst:
342 except (IOError, OSError, error.Abort, error.LockError) as inst:
338 repo.ui.debug(
343 repo.ui.debug(
339 b"couldn't write revision branch cache%s: %s\n"
344 b"couldn't write revision branch cache%s: %s\n"
340 % (step, stringutil.forcebytestr(inst))
345 % (step, stringutil.forcebytestr(inst))
341 )
346 )
342 finally:
347 finally:
343 if wlock is not None:
348 if wlock is not None:
344 wlock.release()
349 wlock.release()
345
350
346 def _writenames(self, repo):
351 def _writenames(self, repo):
347 """write the new branch names to revbranchcache"""
352 """write the new branch names to revbranchcache"""
348 f = None
353 f = None
349 if self._force_overwrite:
354 if self._force_overwrite:
350 self._rbcsnameslen = 0
355 self._rbcsnameslen = 0
351 self._rbcnamescount = 0
356 self._rbcnamescount = 0
352 try:
357 try:
353 if self._force_overwrite or self._rbcnamescount != 0:
358 if self._force_overwrite or self._rbcnamescount != 0:
354 f = repo.cachevfs.open(_rbcnames, b'ab')
359 f = repo.cachevfs.open(_rbcnames, b'ab')
355 current_size = f.tell()
360 current_size = f.tell()
356 if current_size == self._rbcsnameslen:
361 if current_size == self._rbcsnameslen:
357 f.write(b'\0')
362 f.write(b'\0')
358 else:
363 else:
359 f.close()
364 f.close()
360 if self._force_overwrite:
365 if self._force_overwrite:
361 dbg = b"resetting content of %s\n"
366 dbg = b"resetting content of %s\n"
362 elif current_size > 0:
367 elif current_size > 0:
363 dbg = b"%s changed - rewriting it\n"
368 dbg = b"%s changed - rewriting it\n"
364 else:
369 else:
365 dbg = b"%s is missing - rewriting it\n"
370 dbg = b"%s is missing - rewriting it\n"
366 repo.ui.debug(dbg % _rbcnames)
371 repo.ui.debug(dbg % _rbcnames)
367 self._rbcnamescount = 0
372 self._rbcnamescount = 0
368 self._rbcrevslen = 0
373 self._rbcrevslen = 0
369 if self._rbcnamescount == 0:
374 if self._rbcnamescount == 0:
370 # before rewriting names, make sure references are removed
375 # before rewriting names, make sure references are removed
371 repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
376 repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
372 f = repo.cachevfs.open(_rbcnames, b'wb')
377 f = repo.cachevfs.open(_rbcnames, b'wb')
373 names = self._names[self._rbcnamescount :]
378 names = self._names[self._rbcnamescount :]
374 from_local = encoding.fromlocal
379 from_local = encoding.fromlocal
375 data = b'\0'.join(from_local(b) for b in names)
380 data = b'\0'.join(from_local(b) for b in names)
376 f.write(data)
381 f.write(data)
377 self._rbcsnameslen = f.tell()
382 self._rbcsnameslen = f.tell()
378 finally:
383 finally:
379 if f is not None:
384 if f is not None:
380 f.close()
385 f.close()
381 self._rbcnamescount = len(self._names)
386 self._rbcnamescount = len(self._names)
382
387
383 def _writerevs(self, repo, start):
388 def _writerevs(self, repo, start):
384 """write the new revs to revbranchcache"""
389 """write the new revs to revbranchcache"""
385 revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize)
390 revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize)
386
391
387 end = revs * _rbcrecsize
392 end = revs * _rbcrecsize
388 if self._force_overwrite:
393 if self._force_overwrite:
389 start = 0
394 start = 0
390
395
396 # align start on entry boundary
397 start = _rbcrecsize * (start // _rbcrecsize)
398
391 with repo.cachevfs.open(_rbcrevs, b'a+b') as f:
399 with repo.cachevfs.open(_rbcrevs, b'a+b') as f:
392 pass # this make sure the file exist…
400 pass # this make sure the file exist…
393 with repo.cachevfs.open(_rbcrevs, b'r+b') as f:
401 with repo.cachevfs.open(_rbcrevs, b'r+b') as f:
394 f.seek(0, os.SEEK_END)
402 f.seek(0, os.SEEK_END)
395 current_size = f.tell()
403 current_size = f.tell()
396 if current_size < start:
404 if current_size < start:
397 start = 0
405 start = 0
398 if current_size != start:
406 if current_size != start:
399 threshold = current_size * REWRITE_RATIO
407 threshold = current_size * REWRITE_RATIO
400 overwritten = min(end, current_size) - start
408 overwritten = min(end, current_size) - start
401 if (max(end, current_size) - start) >= threshold:
409 if (max(end, current_size) - start) >= threshold:
402 start = 0
410 start = 0
403 dbg = b"resetting content of cache/%s\n" % _rbcrevs
411 dbg = b"resetting content of cache/%s\n" % _rbcrevs
404 repo.ui.debug(dbg)
412 repo.ui.debug(dbg)
405 elif overwritten > 0:
413 elif overwritten > 0:
406 # end affected, let us overwrite the bad value
414 # end affected, let us overwrite the bad value
407 dbg = b"overwriting %d bytes from %d in cache/%s"
415 dbg = b"overwriting %d bytes from %d in cache/%s"
408 dbg %= (current_size - start, start, _rbcrevs)
416 dbg %= (current_size - start, start, _rbcrevs)
409 if end < current_size:
417 if end < current_size:
410 extra = b" leaving (%d trailing bytes)"
418 extra = b" leaving (%d trailing bytes)"
411 extra %= current_size - end
419 extra %= current_size - end
412 dbg += extra
420 dbg += extra
413 dbg += b'\n'
421 dbg += b'\n'
414 repo.ui.debug(dbg)
422 repo.ui.debug(dbg)
415 else:
423 else:
416 # extra untouched data at the end, lets warn about them
424 # extra untouched data at the end, lets warn about them
417 assert start == end # since don't write anything
425 assert start == end # since don't write anything
418 dbg = b"cache/%s contains %d unknown trailing bytes\n"
426 dbg = b"cache/%s contains %d unknown trailing bytes\n"
419 dbg %= (_rbcrevs, current_size - start)
427 dbg %= (_rbcrevs, current_size - start)
420 repo.ui.debug(dbg)
428 repo.ui.debug(dbg)
421
429
422 if start > 0:
430 if start > 0:
423 f.seek(start)
431 f.seek(start)
424 f.write(self._rbcrevs.slice(start, end))
432 f.write(self._rbcrevs.slice(start, end))
425 else:
433 else:
426 f.close()
434 f.close()
427 with repo.cachevfs.open(
435 with repo.cachevfs.open(
428 _rbcrevs,
436 _rbcrevs,
429 b'wb',
437 b'wb',
430 atomictemp=True,
438 atomictemp=True,
431 ) as rev_file:
439 ) as rev_file:
432 rev_file.write(self._rbcrevs.slice(start, end))
440 rev_file.write(self._rbcrevs.slice(start, end))
433 self._rbcrevslen = revs
441 self._rbcrevslen = revs
434 self._force_overwrite = False
442 self._force_overwrite = False
@@ -1,1466 +1,1481
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 dealing with valid cache revs file but for extra trailing data
835 $ echo >> .hg/cache/rbc-revs-v2
835 --------------------------------------------------------------
836
837 When the trailing data are smaller than a record, they are practically
838 invisible to the cache and ignored. No warning is issued about them.
839
840 $ echo '42' >> .hg/cache/rbc-revs-v2
836 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
841 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
837 5
842 5
838 cache/rbc-revs-v2 contains 2 unknown trailing bytes
839 $ f --size .hg/cache/rbc-revs*
843 $ f --size .hg/cache/rbc-revs*
840 .hg/cache/rbc-revs-v2: size=162
844 .hg/cache/rbc-revs-v2: size=164
845
846 When the trailing data are larger than a record, they are seens as extra
847 (probably invalid) data. We warn about them when writing.
848
849 $ echo 'abracadabra!' >> .hg/cache/rbc-revs-v2
850 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
851 5
852 cache/rbc-revs-v2 contains 17 unknown trailing bytes
853 $ f --size .hg/cache/rbc-revs*
854 .hg/cache/rbc-revs-v2: size=177
841
855
842 recovery from invalid cache file with partial last record
856 recovery from invalid cache file with partial last record
857 ---------------------------------------------------------
843 $ mv .hg/cache/rbc-revs-v2 .
858 $ mv .hg/cache/rbc-revs-v2 .
844 $ f -qDB 119 rbc-revs-v2 > .hg/cache/rbc-revs-v2
859 $ f -qDB 119 rbc-revs-v2 > .hg/cache/rbc-revs-v2
845 $ f --size .hg/cache/rbc-revs*
860 $ f --size .hg/cache/rbc-revs*
846 .hg/cache/rbc-revs-v2: size=119
861 .hg/cache/rbc-revs-v2: size=119
847 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
862 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
848 5
863 5
849 resetting content of cache/rbc-revs-v2
864 resetting content of cache/rbc-revs-v2
850 $ f --size .hg/cache/rbc-revs*
865 $ f --size .hg/cache/rbc-revs*
851 .hg/cache/rbc-revs-v2: size=160
866 .hg/cache/rbc-revs-v2: size=160
852
867
853 recovery from invalid cache file with missing record - no truncation
868 recovery from invalid cache file with missing record - no truncation
854 $ mv .hg/cache/rbc-revs-v2 .
869 $ mv .hg/cache/rbc-revs-v2 .
855 $ f -qDB 112 rbc-revs-v2 > .hg/cache/rbc-revs-v2
870 $ f -qDB 112 rbc-revs-v2 > .hg/cache/rbc-revs-v2
856 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
871 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
857 5
872 5
858 $ f --size .hg/cache/rbc-revs*
873 $ f --size .hg/cache/rbc-revs*
859 .hg/cache/rbc-revs-v2: size=160
874 .hg/cache/rbc-revs-v2: size=160
860
875
861 recovery from invalid cache file with some bad records
876 recovery from invalid cache file with some bad records
862 $ mv .hg/cache/rbc-revs-v2 .
877 $ mv .hg/cache/rbc-revs-v2 .
863 $ f -qDB 8 rbc-revs-v2 > .hg/cache/rbc-revs-v2
878 $ f -qDB 8 rbc-revs-v2 > .hg/cache/rbc-revs-v2
864 $ f --size .hg/cache/rbc-revs*
879 $ f --size .hg/cache/rbc-revs*
865 .hg/cache/rbc-revs-v2: size=8
880 .hg/cache/rbc-revs-v2: size=8
866 $ f -qDB 112 rbc-revs-v2 >> .hg/cache/rbc-revs-v2
881 $ f -qDB 112 rbc-revs-v2 >> .hg/cache/rbc-revs-v2
867 $ f --size .hg/cache/rbc-revs*
882 $ f --size .hg/cache/rbc-revs*
868 .hg/cache/rbc-revs-v2: size=120
883 .hg/cache/rbc-revs-v2: size=120
869 $ hg log -r 'branch(.)' -T '{rev} ' --debug
884 $ hg log -r 'branch(.)' -T '{rev} ' --debug
870 history modification detected - truncating revision branch cache to revision * (glob)
885 history modification detected - truncating revision branch cache to revision * (glob)
871 history modification detected - truncating revision branch cache to revision 1
886 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
887 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
888 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug
874 5
889 5
875 resetting content of cache/rbc-revs-v2
890 resetting content of cache/rbc-revs-v2
876 $ f --size --hexdump --bytes=16 .hg/cache/rbc-revs*
891 $ f --size --hexdump --bytes=16 .hg/cache/rbc-revs*
877 .hg/cache/rbc-revs-v2: size=160
892 .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.....|
893 0000: 19 70 9c 5a 00 00 00 00 dd 6b 44 0d 00 00 00 01 |.p.Z.....kD.....|
879
894
880 Smoothly reuse "v1" format if no v2 exists
895 Smoothly reuse "v1" format if no v2 exists
881 ------------------------------------------
896 ------------------------------------------
882
897
883 read only operation with valid data
898 read only operation with valid data
884 (actively rewrite data)
899 (actively rewrite data)
885
900
886 $ rm .hg/cache/rbc-names-v2
901 $ rm .hg/cache/rbc-names-v2
887 $ rm .hg/cache/rbc-revs-v2
902 $ rm .hg/cache/rbc-revs-v2
888 $ rm .hg/cache/branch*
903 $ rm .hg/cache/branch*
889 $ hg head a -T '{rev}\n' --debug
904 $ hg head a -T '{rev}\n' --debug
890 5
905 5
891 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
906 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
892 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
907 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
893 $ rm .hg/cache/branch*
908 $ rm .hg/cache/branch*
894 $ hg head a -T '{rev}\n' --debug
909 $ hg head a -T '{rev}\n' --debug
895 5
910 5
896 $ f --size .hg/cache/rbc-*-*
911 $ f --size .hg/cache/rbc-*-*
897 .hg/cache/rbc-names-v1: size=92
912 .hg/cache/rbc-names-v1: size=92
898 .hg/cache/rbc-names-v2: size=92
913 .hg/cache/rbc-names-v2: size=92
899 .hg/cache/rbc-revs-v1: size=160
914 .hg/cache/rbc-revs-v1: size=160
900 .hg/cache/rbc-revs-v2: size=160
915 .hg/cache/rbc-revs-v2: size=160
901
916
902
917
903 Write operation write a full v2 files
918 Write operation write a full v2 files
904
919
905 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
920 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
906 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
921 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
907 $ f --size .hg/cache/rbc-*
922 $ f --size .hg/cache/rbc-*
908 .hg/cache/rbc-names-v1: size=92
923 .hg/cache/rbc-names-v1: size=92
909 .hg/cache/rbc-revs-v1: size=160
924 .hg/cache/rbc-revs-v1: size=160
910 $ hg branch not-here-for-long
925 $ hg branch not-here-for-long
911 marked working directory as branch not-here-for-long
926 marked working directory as branch not-here-for-long
912 $ hg ci -m not-long --debug
927 $ hg ci -m not-long --debug
913 reusing manifest from p1 (no file change)
928 reusing manifest from p1 (no file change)
914 committing changelog
929 committing changelog
915 updating the branch cache
930 updating the branch cache
916 committed changeset * (glob)
931 committed changeset * (glob)
917 $ f --size .hg/cache/rbc-*
932 $ f --size .hg/cache/rbc-*
918 .hg/cache/rbc-names-v1: size=92
933 .hg/cache/rbc-names-v1: size=92
919 .hg/cache/rbc-names-v2: size=110
934 .hg/cache/rbc-names-v2: size=110
920 .hg/cache/rbc-revs-v1: size=160
935 .hg/cache/rbc-revs-v1: size=160
921 .hg/cache/rbc-revs-v2: size=168
936 .hg/cache/rbc-revs-v2: size=168
922
937
923 So does explicit cache upgrade
938 So does explicit cache upgrade
924 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
939 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
925 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
940 $ mv .hg/cache/rbc-revs-v2 .hg/cache/rbc-revs-v1
926 $ f --size .hg/cache/rbc-*
941 $ f --size .hg/cache/rbc-*
927 .hg/cache/rbc-names-v1: size=110
942 .hg/cache/rbc-names-v1: size=110
928 .hg/cache/rbc-revs-v1: size=168
943 .hg/cache/rbc-revs-v1: size=168
929 $ hg debugupdatecache
944 $ hg debugupdatecache
930 $ f --size .hg/cache/rbc-*
945 $ f --size .hg/cache/rbc-*
931 .hg/cache/rbc-names-v1: size=110
946 .hg/cache/rbc-names-v1: size=110
932 .hg/cache/rbc-names-v2: size=110
947 .hg/cache/rbc-names-v2: size=110
933 .hg/cache/rbc-revs-v1: size=168
948 .hg/cache/rbc-revs-v1: size=168
934 .hg/cache/rbc-revs-v2: size=168
949 .hg/cache/rbc-revs-v2: size=168
935
950
936 With invalid v1 data, we rewrite it too (as v2)
951 With invalid v1 data, we rewrite it too (as v2)
937
952
938 $ cp .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
953 $ cp .hg/cache/rbc-names-v2 .hg/cache/rbc-names-v1
939 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-revs-v1
954 $ mv .hg/cache/rbc-names-v2 .hg/cache/rbc-revs-v1
940 $ rm .hg/cache/rbc-revs-v2
955 $ rm .hg/cache/rbc-revs-v2
941 $ rm .hg/cache/branch*
956 $ rm .hg/cache/branch*
942 $
957 $
943 $ hg head a -T '{rev}\n' --debug
958 $ hg head a -T '{rev}\n' --debug
944 history modification detected - truncating revision branch cache to revision 0
959 history modification detected - truncating revision branch cache to revision 0
945 5
960 5
946 $ f --size .hg/cache/rbc-*-*
961 $ f --size .hg/cache/rbc-*-*
947 .hg/cache/rbc-names-v1: size=110
962 .hg/cache/rbc-names-v1: size=110
948 .hg/cache/rbc-names-v2: size=110
963 .hg/cache/rbc-names-v2: size=110
949 .hg/cache/rbc-revs-v1: size=110
964 .hg/cache/rbc-revs-v1: size=110
950 .hg/cache/rbc-revs-v2: size=168
965 .hg/cache/rbc-revs-v2: size=168
951
966
952 cleanup
967 cleanup
953
968
954 $ hg up -qr '.^'
969 $ hg up -qr '.^'
955 $ hg rollback -qf
970 $ hg rollback -qf
956 $ rm .hg/cache/*
971 $ rm .hg/cache/*
957 $ hg debugupdatecache
972 $ hg debugupdatecache
958 $ f --size .hg/cache/rbc-*
973 $ f --size .hg/cache/rbc-*
959 .hg/cache/rbc-names-v2: size=92
974 .hg/cache/rbc-names-v2: size=92
960 .hg/cache/rbc-revs-v2: size=160
975 .hg/cache/rbc-revs-v2: size=160
961
976
962 cache is updated when committing
977 cache is updated when committing
963 $ hg branch i-will-regret-this
978 $ hg branch i-will-regret-this
964 marked working directory as branch i-will-regret-this
979 marked working directory as branch i-will-regret-this
965 $ hg ci -m regrets
980 $ hg ci -m regrets
966 $ f --size .hg/cache/rbc-*
981 $ f --size .hg/cache/rbc-*
967 .hg/cache/rbc-names-v2: size=111
982 .hg/cache/rbc-names-v2: size=111
968 .hg/cache/rbc-revs-v2: size=168
983 .hg/cache/rbc-revs-v2: size=168
969
984
970 update after rollback - the cache will be correct but rbc-names will will still
985 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
986 contain the branch name even though it no longer is used
972 $ hg up -qr '.^'
987 $ hg up -qr '.^'
973 $ hg rollback -qf
988 $ hg rollback -qf
974 $ f --size .hg/cache/rbc-names-*
989 $ f --size .hg/cache/rbc-names-*
975 .hg/cache/rbc-names-v2: size=111
990 .hg/cache/rbc-names-v2: size=111
976 $ grep "i-will-regret-this" .hg/cache/rbc-names-* > /dev/null
991 $ grep "i-will-regret-this" .hg/cache/rbc-names-* > /dev/null
977 $ f --size .hg/cache/rbc-revs-*
992 $ f --size .hg/cache/rbc-revs-*
978 .hg/cache/rbc-revs-v2: size=168
993 .hg/cache/rbc-revs-v2: size=168
979
994
980 cache is updated/truncated when stripping - it is thus very hard to get in a
995 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
996 situation where the cache is out of sync and the hash check detects it
982 $ hg --config extensions.strip= strip -r tip --nob
997 $ hg --config extensions.strip= strip -r tip --nob
983 $ f --size .hg/cache/rbc-revs*
998 $ f --size .hg/cache/rbc-revs*
984 .hg/cache/rbc-revs-v2: size=152
999 .hg/cache/rbc-revs-v2: size=152
985
1000
986 cache is rebuilt when corruption is detected
1001 cache is rebuilt when corruption is detected
987 $ echo > .hg/cache/rbc-names-v2
1002 $ echo > .hg/cache/rbc-names-v2
988 $ hg log -r '5:&branch(.)' -T '{rev} ' --debug
1003 $ hg log -r '5:&branch(.)' -T '{rev} ' --debug
989 referenced branch names not found - rebuilding revision branch cache from scratch
1004 referenced branch names not found - rebuilding revision branch cache from scratch
990 8 9 10 11 12 13 resetting content of rbc-names-v2
1005 8 9 10 11 12 13 resetting content of rbc-names-v2
991 $ f --size .hg/cache/rbc-names-*
1006 $ f --size .hg/cache/rbc-names-*
992 .hg/cache/rbc-names-v2: size=84
1007 .hg/cache/rbc-names-v2: size=84
993 $ grep "i-will-regret-this" .hg/cache/rbc-names-* > /dev/null
1008 $ grep "i-will-regret-this" .hg/cache/rbc-names-* > /dev/null
994 [1]
1009 [1]
995 $ f --size .hg/cache/rbc-revs-*
1010 $ f --size .hg/cache/rbc-revs-*
996 .hg/cache/rbc-revs-v2: size=152
1011 .hg/cache/rbc-revs-v2: size=152
997
1012
998 Test that cache files are created and grows correctly:
1013 Test that cache files are created and grows correctly:
999
1014
1000 $ rm .hg/cache/rbc*
1015 $ rm .hg/cache/rbc*
1001 $ hg log -r "5 & branch(5)" -T "{rev}\n"
1016 $ hg log -r "5 & branch(5)" -T "{rev}\n"
1002 5
1017 5
1003
1018
1004 (here v3 is querying branch info for heads so it warm much more of the cache)
1019 (here v3 is querying branch info for heads so it warm much more of the cache)
1005
1020
1006 #if v2
1021 #if v2
1007 $ f --size .hg/cache/rbc-*
1022 $ f --size .hg/cache/rbc-*
1008 .hg/cache/rbc-names-v2: size=1
1023 .hg/cache/rbc-names-v2: size=1
1009 .hg/cache/rbc-revs-v2: size=48
1024 .hg/cache/rbc-revs-v2: size=48
1010 #else
1025 #else
1011 $ f --size .hg/cache/rbc-*
1026 $ f --size .hg/cache/rbc-*
1012 .hg/cache/rbc-names-v2: size=84
1027 .hg/cache/rbc-names-v2: size=84
1013 .hg/cache/rbc-revs-v2: size=152
1028 .hg/cache/rbc-revs-v2: size=152
1014 #endif
1029 #endif
1015
1030
1016 $ cd ..
1031 $ cd ..
1017
1032
1018 Test for multiple incorrect branch cache entries:
1033 Test for multiple incorrect branch cache entries:
1019
1034
1020 $ hg init b
1035 $ hg init b
1021 $ cd b
1036 $ cd b
1022 $ touch f
1037 $ touch f
1023 $ hg ci -Aqmf
1038 $ hg ci -Aqmf
1024 $ echo >> f
1039 $ echo >> f
1025 $ hg ci -Amf
1040 $ hg ci -Amf
1026 $ hg branch -q branch
1041 $ hg branch -q branch
1027 $ hg ci -Amf
1042 $ hg ci -Amf
1028
1043
1029 #if v2
1044 #if v2
1030
1045
1031 $ f --size --sha256 .hg/cache/rbc-*
1046 $ f --size --sha256 .hg/cache/rbc-*
1032 .hg/cache/rbc-names-v2: size=14, sha256=d376f7eea9a7e28fac6470e78dae753c81a5543c9ad436e96999590e004a281c
1047 .hg/cache/rbc-names-v2: size=14, sha256=d376f7eea9a7e28fac6470e78dae753c81a5543c9ad436e96999590e004a281c
1033 .hg/cache/rbc-revs-v2: size=24, sha256=ec89032fd4e66e7282cb6e403848c681a855a9c36c6b44d19179218553b78779
1048 .hg/cache/rbc-revs-v2: size=24, sha256=ec89032fd4e66e7282cb6e403848c681a855a9c36c6b44d19179218553b78779
1034
1049
1035 $ : > .hg/cache/rbc-revs-v2
1050 $ : > .hg/cache/rbc-revs-v2
1036
1051
1037 No superfluous rebuilding of cache:
1052 No superfluous rebuilding of cache:
1038 $ hg log -r "branch(null)&branch(branch)" --debug
1053 $ hg log -r "branch(null)&branch(branch)" --debug
1039 $ f --size --sha256 .hg/cache/rbc-*
1054 $ f --size --sha256 .hg/cache/rbc-*
1040 .hg/cache/rbc-names-v2: size=14, sha256=d376f7eea9a7e28fac6470e78dae753c81a5543c9ad436e96999590e004a281c
1055 .hg/cache/rbc-names-v2: size=14, sha256=d376f7eea9a7e28fac6470e78dae753c81a5543c9ad436e96999590e004a281c
1041 .hg/cache/rbc-revs-v2: size=24, sha256=ec89032fd4e66e7282cb6e403848c681a855a9c36c6b44d19179218553b78779
1056 .hg/cache/rbc-revs-v2: size=24, sha256=ec89032fd4e66e7282cb6e403848c681a855a9c36c6b44d19179218553b78779
1042 #endif
1057 #endif
1043
1058
1044 $ cd ..
1059 $ cd ..
1045
1060
1046 Test to make sure that `--close-branch` only works on a branch head:
1061 Test to make sure that `--close-branch` only works on a branch head:
1047 --------------------------------------------------------------------
1062 --------------------------------------------------------------------
1048 $ hg init closebranch
1063 $ hg init closebranch
1049 $ cd closebranch
1064 $ cd closebranch
1050 $ for ch in a b c; do
1065 $ for ch in a b c; do
1051 > echo $ch > $ch
1066 > echo $ch > $ch
1052 > hg add $ch
1067 > hg add $ch
1053 > hg ci -m "added "$ch
1068 > hg ci -m "added "$ch
1054 > done;
1069 > done;
1055
1070
1056 $ hg up -r "desc('added b')"
1071 $ hg up -r "desc('added b')"
1057 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1072 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1058
1073
1059 trying to close branch from a cset which is not a branch head
1074 trying to close branch from a cset which is not a branch head
1060 it should abort:
1075 it should abort:
1061 $ hg ci -m "closing branch" --close-branch
1076 $ hg ci -m "closing branch" --close-branch
1062 abort: can only close branch heads
1077 abort: can only close branch heads
1063 (use --force-close-branch to close branch from a non-head changeset)
1078 (use --force-close-branch to close branch from a non-head changeset)
1064 [10]
1079 [10]
1065
1080
1066 $ hg up 0
1081 $ hg up 0
1067 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1082 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"
1083 $ hg log -GT "{rev}: {node|short} {desc|firstline}\n\t{branch}\n\n"
1069 o 2: 155349b645be added c
1084 o 2: 155349b645be added c
1070 | default
1085 | default
1071 |
1086 |
1072 o 1: 5f6d8a4bf34a added b
1087 o 1: 5f6d8a4bf34a added b
1073 | default
1088 | default
1074 |
1089 |
1075 @ 0: 9092f1db7931 added a
1090 @ 0: 9092f1db7931 added a
1076 default
1091 default
1077
1092
1078 Test --force-close-branch to close a branch from a non-head changeset:
1093 Test --force-close-branch to close a branch from a non-head changeset:
1079 ---------------------------------------------------------------------
1094 ---------------------------------------------------------------------
1080
1095
1081 $ hg show stack --config extensions.show=
1096 $ hg show stack --config extensions.show=
1082 o 1553 added c
1097 o 1553 added c
1083 o 5f6d added b
1098 o 5f6d added b
1084 @ 9092 added a
1099 @ 9092 added a
1085
1100
1086 $ hg ci -m "branch closed" --close-branch
1101 $ hg ci -m "branch closed" --close-branch
1087 abort: can only close branch heads
1102 abort: can only close branch heads
1088 (use --force-close-branch to close branch from a non-head changeset)
1103 (use --force-close-branch to close branch from a non-head changeset)
1089 [10]
1104 [10]
1090
1105
1091 $ hg ci -m "branch closed" --force-close-branch
1106 $ hg ci -m "branch closed" --force-close-branch
1092 created new head
1107 created new head
1093 $ cd ..
1108 $ cd ..
1094
1109
1095 Test various special cases for the branchmap
1110 Test various special cases for the branchmap
1096 --------------------------------------------
1111 --------------------------------------------
1097
1112
1098 Basic fork of the same branch
1113 Basic fork of the same branch
1099
1114
1100 $ hg init branchmap-testing1
1115 $ hg init branchmap-testing1
1101 $ cd branchmap-testing1
1116 $ cd branchmap-testing1
1102 $ hg debugbuild '@A . :base . :p1 *base /p1'
1117 $ hg debugbuild '@A . :base . :p1 *base /p1'
1103 $ hg log -G
1118 $ hg log -G
1104 o changeset: 3:71ca9a6d524e
1119 o changeset: 3:71ca9a6d524e
1105 |\ branch: A
1120 |\ branch: A
1106 | | tag: tip
1121 | | tag: tip
1107 | | parent: 2:a3b807b3ff0b
1122 | | parent: 2:a3b807b3ff0b
1108 | | parent: 1:99ba08759bc7
1123 | | parent: 1:99ba08759bc7
1109 | | user: debugbuilddag
1124 | | user: debugbuilddag
1110 | | date: Thu Jan 01 00:00:03 1970 +0000
1125 | | date: Thu Jan 01 00:00:03 1970 +0000
1111 | | summary: r3
1126 | | summary: r3
1112 | |
1127 | |
1113 | o changeset: 2:a3b807b3ff0b
1128 | o changeset: 2:a3b807b3ff0b
1114 | | branch: A
1129 | | branch: A
1115 | | parent: 0:2ab8003a1750
1130 | | parent: 0:2ab8003a1750
1116 | | user: debugbuilddag
1131 | | user: debugbuilddag
1117 | | date: Thu Jan 01 00:00:02 1970 +0000
1132 | | date: Thu Jan 01 00:00:02 1970 +0000
1118 | | summary: r2
1133 | | summary: r2
1119 | |
1134 | |
1120 o | changeset: 1:99ba08759bc7
1135 o | changeset: 1:99ba08759bc7
1121 |/ branch: A
1136 |/ branch: A
1122 | tag: p1
1137 | tag: p1
1123 | user: debugbuilddag
1138 | user: debugbuilddag
1124 | date: Thu Jan 01 00:00:01 1970 +0000
1139 | date: Thu Jan 01 00:00:01 1970 +0000
1125 | summary: r1
1140 | summary: r1
1126 |
1141 |
1127 o changeset: 0:2ab8003a1750
1142 o changeset: 0:2ab8003a1750
1128 branch: A
1143 branch: A
1129 tag: base
1144 tag: base
1130 user: debugbuilddag
1145 user: debugbuilddag
1131 date: Thu Jan 01 00:00:00 1970 +0000
1146 date: Thu Jan 01 00:00:00 1970 +0000
1132 summary: r0
1147 summary: r0
1133
1148
1134 $ hg branches
1149 $ hg branches
1135 A 3:71ca9a6d524e
1150 A 3:71ca9a6d524e
1136 $ hg clone -r 1 -r 2 . ../branchmap-testing1-clone
1151 $ hg clone -r 1 -r 2 . ../branchmap-testing1-clone
1137 adding changesets
1152 adding changesets
1138 adding manifests
1153 adding manifests
1139 adding file changes
1154 adding file changes
1140 added 3 changesets with 0 changes to 0 files (+1 heads)
1155 added 3 changesets with 0 changes to 0 files (+1 heads)
1141 new changesets 2ab8003a1750:a3b807b3ff0b
1156 new changesets 2ab8003a1750:a3b807b3ff0b
1142 updating to branch A
1157 updating to branch A
1143 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1158 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1144 $ cd ../branchmap-testing1-clone
1159 $ cd ../branchmap-testing1-clone
1145 $ hg pull ../branchmap-testing1
1160 $ hg pull ../branchmap-testing1
1146 pulling from ../branchmap-testing1
1161 pulling from ../branchmap-testing1
1147 searching for changes
1162 searching for changes
1148 adding changesets
1163 adding changesets
1149 adding manifests
1164 adding manifests
1150 adding file changes
1165 adding file changes
1151 added 1 changesets with 0 changes to 0 files (-1 heads)
1166 added 1 changesets with 0 changes to 0 files (-1 heads)
1152 new changesets 71ca9a6d524e
1167 new changesets 71ca9a6d524e
1153 (run 'hg update' to get a working copy)
1168 (run 'hg update' to get a working copy)
1154 $ hg branches
1169 $ hg branches
1155 A 3:71ca9a6d524e
1170 A 3:71ca9a6d524e
1156 $ cd ..
1171 $ cd ..
1157
1172
1158 Switching to a different branch and back
1173 Switching to a different branch and back
1159
1174
1160 $ hg init branchmap-testing2
1175 $ hg init branchmap-testing2
1161 $ cd branchmap-testing2
1176 $ cd branchmap-testing2
1162 $ hg debugbuild '@A . @B . @A .'
1177 $ hg debugbuild '@A . @B . @A .'
1163 $ hg log -G
1178 $ hg log -G
1164 o changeset: 2:9699e9f260b5
1179 o changeset: 2:9699e9f260b5
1165 | branch: A
1180 | branch: A
1166 | tag: tip
1181 | tag: tip
1167 | user: debugbuilddag
1182 | user: debugbuilddag
1168 | date: Thu Jan 01 00:00:02 1970 +0000
1183 | date: Thu Jan 01 00:00:02 1970 +0000
1169 | summary: r2
1184 | summary: r2
1170 |
1185 |
1171 o changeset: 1:0bc7d348d965
1186 o changeset: 1:0bc7d348d965
1172 | branch: B
1187 | branch: B
1173 | user: debugbuilddag
1188 | user: debugbuilddag
1174 | date: Thu Jan 01 00:00:01 1970 +0000
1189 | date: Thu Jan 01 00:00:01 1970 +0000
1175 | summary: r1
1190 | summary: r1
1176 |
1191 |
1177 o changeset: 0:2ab8003a1750
1192 o changeset: 0:2ab8003a1750
1178 branch: A
1193 branch: A
1179 user: debugbuilddag
1194 user: debugbuilddag
1180 date: Thu Jan 01 00:00:00 1970 +0000
1195 date: Thu Jan 01 00:00:00 1970 +0000
1181 summary: r0
1196 summary: r0
1182
1197
1183 $ hg branches
1198 $ hg branches
1184 A 2:9699e9f260b5
1199 A 2:9699e9f260b5
1185 B 1:0bc7d348d965 (inactive)
1200 B 1:0bc7d348d965 (inactive)
1186 $ hg clone -r 1 . ../branchmap-testing2-clone
1201 $ hg clone -r 1 . ../branchmap-testing2-clone
1187 adding changesets
1202 adding changesets
1188 adding manifests
1203 adding manifests
1189 adding file changes
1204 adding file changes
1190 added 2 changesets with 0 changes to 0 files
1205 added 2 changesets with 0 changes to 0 files
1191 new changesets 2ab8003a1750:0bc7d348d965
1206 new changesets 2ab8003a1750:0bc7d348d965
1192 updating to branch B
1207 updating to branch B
1193 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1208 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1194 $ cd ../branchmap-testing2-clone
1209 $ cd ../branchmap-testing2-clone
1195 $ hg pull ../branchmap-testing2
1210 $ hg pull ../branchmap-testing2
1196 pulling from ../branchmap-testing2
1211 pulling from ../branchmap-testing2
1197 searching for changes
1212 searching for changes
1198 adding changesets
1213 adding changesets
1199 adding manifests
1214 adding manifests
1200 adding file changes
1215 adding file changes
1201 added 1 changesets with 0 changes to 0 files
1216 added 1 changesets with 0 changes to 0 files
1202 new changesets 9699e9f260b5
1217 new changesets 9699e9f260b5
1203 (run 'hg update' to get a working copy)
1218 (run 'hg update' to get a working copy)
1204 $ hg branches
1219 $ hg branches
1205 A 2:9699e9f260b5
1220 A 2:9699e9f260b5
1206 B 1:0bc7d348d965 (inactive)
1221 B 1:0bc7d348d965 (inactive)
1207 $ cd ..
1222 $ cd ..
1208
1223
1209 A fork on a branch switching to a different branch and back
1224 A fork on a branch switching to a different branch and back
1210 is still collecting the fork.
1225 is still collecting the fork.
1211
1226
1212 $ hg init branchmap-testing3
1227 $ hg init branchmap-testing3
1213 $ cd branchmap-testing3
1228 $ cd branchmap-testing3
1214 $ hg debugbuild '@A . :base . :p1 *base @B . @A /p1'
1229 $ hg debugbuild '@A . :base . :p1 *base @B . @A /p1'
1215 $ hg log -G
1230 $ hg log -G
1216 o changeset: 4:3614a1711d23
1231 o changeset: 4:3614a1711d23
1217 |\ branch: A
1232 |\ branch: A
1218 | | tag: tip
1233 | | tag: tip
1219 | | parent: 3:e9c8abcf65aa
1234 | | parent: 3:e9c8abcf65aa
1220 | | parent: 1:99ba08759bc7
1235 | | parent: 1:99ba08759bc7
1221 | | user: debugbuilddag
1236 | | user: debugbuilddag
1222 | | date: Thu Jan 01 00:00:04 1970 +0000
1237 | | date: Thu Jan 01 00:00:04 1970 +0000
1223 | | summary: r4
1238 | | summary: r4
1224 | |
1239 | |
1225 | o changeset: 3:e9c8abcf65aa
1240 | o changeset: 3:e9c8abcf65aa
1226 | | branch: B
1241 | | branch: B
1227 | | user: debugbuilddag
1242 | | user: debugbuilddag
1228 | | date: Thu Jan 01 00:00:03 1970 +0000
1243 | | date: Thu Jan 01 00:00:03 1970 +0000
1229 | | summary: r3
1244 | | summary: r3
1230 | |
1245 | |
1231 | o changeset: 2:a3b807b3ff0b
1246 | o changeset: 2:a3b807b3ff0b
1232 | | branch: A
1247 | | branch: A
1233 | | parent: 0:2ab8003a1750
1248 | | parent: 0:2ab8003a1750
1234 | | user: debugbuilddag
1249 | | user: debugbuilddag
1235 | | date: Thu Jan 01 00:00:02 1970 +0000
1250 | | date: Thu Jan 01 00:00:02 1970 +0000
1236 | | summary: r2
1251 | | summary: r2
1237 | |
1252 | |
1238 o | changeset: 1:99ba08759bc7
1253 o | changeset: 1:99ba08759bc7
1239 |/ branch: A
1254 |/ branch: A
1240 | tag: p1
1255 | tag: p1
1241 | user: debugbuilddag
1256 | user: debugbuilddag
1242 | date: Thu Jan 01 00:00:01 1970 +0000
1257 | date: Thu Jan 01 00:00:01 1970 +0000
1243 | summary: r1
1258 | summary: r1
1244 |
1259 |
1245 o changeset: 0:2ab8003a1750
1260 o changeset: 0:2ab8003a1750
1246 branch: A
1261 branch: A
1247 tag: base
1262 tag: base
1248 user: debugbuilddag
1263 user: debugbuilddag
1249 date: Thu Jan 01 00:00:00 1970 +0000
1264 date: Thu Jan 01 00:00:00 1970 +0000
1250 summary: r0
1265 summary: r0
1251
1266
1252 $ hg branches
1267 $ hg branches
1253 A 4:3614a1711d23
1268 A 4:3614a1711d23
1254 B 3:e9c8abcf65aa (inactive)
1269 B 3:e9c8abcf65aa (inactive)
1255 $ hg clone -r 1 -r 3 . ../branchmap-testing3-clone
1270 $ hg clone -r 1 -r 3 . ../branchmap-testing3-clone
1256 adding changesets
1271 adding changesets
1257 adding manifests
1272 adding manifests
1258 adding file changes
1273 adding file changes
1259 added 4 changesets with 0 changes to 0 files (+1 heads)
1274 added 4 changesets with 0 changes to 0 files (+1 heads)
1260 new changesets 2ab8003a1750:e9c8abcf65aa
1275 new changesets 2ab8003a1750:e9c8abcf65aa
1261 updating to branch A
1276 updating to branch A
1262 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1277 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1263 $ cd ../branchmap-testing3-clone
1278 $ cd ../branchmap-testing3-clone
1264 $ hg pull ../branchmap-testing3
1279 $ hg pull ../branchmap-testing3
1265 pulling from ../branchmap-testing3
1280 pulling from ../branchmap-testing3
1266 searching for changes
1281 searching for changes
1267 adding changesets
1282 adding changesets
1268 adding manifests
1283 adding manifests
1269 adding file changes
1284 adding file changes
1270 added 1 changesets with 0 changes to 0 files (-1 heads)
1285 added 1 changesets with 0 changes to 0 files (-1 heads)
1271 new changesets 3614a1711d23
1286 new changesets 3614a1711d23
1272 (run 'hg update' to get a working copy)
1287 (run 'hg update' to get a working copy)
1273 $ hg branches
1288 $ hg branches
1274 A 4:3614a1711d23
1289 A 4:3614a1711d23
1275 B 3:e9c8abcf65aa (inactive)
1290 B 3:e9c8abcf65aa (inactive)
1276 $ cd ..
1291 $ cd ..
1277
1292
1278 Intermediary parents are on different branches.
1293 Intermediary parents are on different branches.
1279
1294
1280 $ hg init branchmap-testing4
1295 $ hg init branchmap-testing4
1281 $ cd branchmap-testing4
1296 $ cd branchmap-testing4
1282 $ hg debugbuild '@A . @B :base . @A :p1 *base @C . @A /p1'
1297 $ hg debugbuild '@A . @B :base . @A :p1 *base @C . @A /p1'
1283 $ hg log -G
1298 $ hg log -G
1284 o changeset: 4:4bf67499b70a
1299 o changeset: 4:4bf67499b70a
1285 |\ branch: A
1300 |\ branch: A
1286 | | tag: tip
1301 | | tag: tip
1287 | | parent: 3:4a546028fa8f
1302 | | parent: 3:4a546028fa8f
1288 | | parent: 1:0bc7d348d965
1303 | | parent: 1:0bc7d348d965
1289 | | user: debugbuilddag
1304 | | user: debugbuilddag
1290 | | date: Thu Jan 01 00:00:04 1970 +0000
1305 | | date: Thu Jan 01 00:00:04 1970 +0000
1291 | | summary: r4
1306 | | summary: r4
1292 | |
1307 | |
1293 | o changeset: 3:4a546028fa8f
1308 | o changeset: 3:4a546028fa8f
1294 | | branch: C
1309 | | branch: C
1295 | | user: debugbuilddag
1310 | | user: debugbuilddag
1296 | | date: Thu Jan 01 00:00:03 1970 +0000
1311 | | date: Thu Jan 01 00:00:03 1970 +0000
1297 | | summary: r3
1312 | | summary: r3
1298 | |
1313 | |
1299 | o changeset: 2:a3b807b3ff0b
1314 | o changeset: 2:a3b807b3ff0b
1300 | | branch: A
1315 | | branch: A
1301 | | parent: 0:2ab8003a1750
1316 | | parent: 0:2ab8003a1750
1302 | | user: debugbuilddag
1317 | | user: debugbuilddag
1303 | | date: Thu Jan 01 00:00:02 1970 +0000
1318 | | date: Thu Jan 01 00:00:02 1970 +0000
1304 | | summary: r2
1319 | | summary: r2
1305 | |
1320 | |
1306 o | changeset: 1:0bc7d348d965
1321 o | changeset: 1:0bc7d348d965
1307 |/ branch: B
1322 |/ branch: B
1308 | tag: p1
1323 | tag: p1
1309 | user: debugbuilddag
1324 | user: debugbuilddag
1310 | date: Thu Jan 01 00:00:01 1970 +0000
1325 | date: Thu Jan 01 00:00:01 1970 +0000
1311 | summary: r1
1326 | summary: r1
1312 |
1327 |
1313 o changeset: 0:2ab8003a1750
1328 o changeset: 0:2ab8003a1750
1314 branch: A
1329 branch: A
1315 tag: base
1330 tag: base
1316 user: debugbuilddag
1331 user: debugbuilddag
1317 date: Thu Jan 01 00:00:00 1970 +0000
1332 date: Thu Jan 01 00:00:00 1970 +0000
1318 summary: r0
1333 summary: r0
1319
1334
1320 $ hg branches
1335 $ hg branches
1321 A 4:4bf67499b70a
1336 A 4:4bf67499b70a
1322 C 3:4a546028fa8f (inactive)
1337 C 3:4a546028fa8f (inactive)
1323 B 1:0bc7d348d965 (inactive)
1338 B 1:0bc7d348d965 (inactive)
1324 $ hg clone -r 1 -r 3 . ../branchmap-testing4-clone
1339 $ hg clone -r 1 -r 3 . ../branchmap-testing4-clone
1325 adding changesets
1340 adding changesets
1326 adding manifests
1341 adding manifests
1327 adding file changes
1342 adding file changes
1328 added 4 changesets with 0 changes to 0 files (+1 heads)
1343 added 4 changesets with 0 changes to 0 files (+1 heads)
1329 new changesets 2ab8003a1750:4a546028fa8f
1344 new changesets 2ab8003a1750:4a546028fa8f
1330 updating to branch B
1345 updating to branch B
1331 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1346 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1332 $ cd ../branchmap-testing4-clone
1347 $ cd ../branchmap-testing4-clone
1333 $ hg pull ../branchmap-testing4
1348 $ hg pull ../branchmap-testing4
1334 pulling from ../branchmap-testing4
1349 pulling from ../branchmap-testing4
1335 searching for changes
1350 searching for changes
1336 adding changesets
1351 adding changesets
1337 adding manifests
1352 adding manifests
1338 adding file changes
1353 adding file changes
1339 added 1 changesets with 0 changes to 0 files (-1 heads)
1354 added 1 changesets with 0 changes to 0 files (-1 heads)
1340 new changesets 4bf67499b70a
1355 new changesets 4bf67499b70a
1341 (run 'hg update' to get a working copy)
1356 (run 'hg update' to get a working copy)
1342 $ hg branches
1357 $ hg branches
1343 A 4:4bf67499b70a
1358 A 4:4bf67499b70a
1344 C 3:4a546028fa8f (inactive)
1359 C 3:4a546028fa8f (inactive)
1345 B 1:0bc7d348d965 (inactive)
1360 B 1:0bc7d348d965 (inactive)
1346 $ cd ..
1361 $ cd ..
1347
1362
1348 Check that the cache are not written too early
1363 Check that the cache are not written too early
1349 ----------------------------------------------
1364 ----------------------------------------------
1350
1365
1351 $ hg log -R branchmap-testing1 -G
1366 $ hg log -R branchmap-testing1 -G
1352 o changeset: 3:71ca9a6d524e
1367 o changeset: 3:71ca9a6d524e
1353 |\ branch: A
1368 |\ branch: A
1354 | | tag: tip
1369 | | tag: tip
1355 | | parent: 2:a3b807b3ff0b
1370 | | parent: 2:a3b807b3ff0b
1356 | | parent: 1:99ba08759bc7
1371 | | parent: 1:99ba08759bc7
1357 | | user: debugbuilddag
1372 | | user: debugbuilddag
1358 | | date: Thu Jan 01 00:00:03 1970 +0000
1373 | | date: Thu Jan 01 00:00:03 1970 +0000
1359 | | summary: r3
1374 | | summary: r3
1360 | |
1375 | |
1361 | o changeset: 2:a3b807b3ff0b
1376 | o changeset: 2:a3b807b3ff0b
1362 | | branch: A
1377 | | branch: A
1363 | | parent: 0:2ab8003a1750
1378 | | parent: 0:2ab8003a1750
1364 | | user: debugbuilddag
1379 | | user: debugbuilddag
1365 | | date: Thu Jan 01 00:00:02 1970 +0000
1380 | | date: Thu Jan 01 00:00:02 1970 +0000
1366 | | summary: r2
1381 | | summary: r2
1367 | |
1382 | |
1368 o | changeset: 1:99ba08759bc7
1383 o | changeset: 1:99ba08759bc7
1369 |/ branch: A
1384 |/ branch: A
1370 | tag: p1
1385 | tag: p1
1371 | user: debugbuilddag
1386 | user: debugbuilddag
1372 | date: Thu Jan 01 00:00:01 1970 +0000
1387 | date: Thu Jan 01 00:00:01 1970 +0000
1373 | summary: r1
1388 | summary: r1
1374 |
1389 |
1375 o changeset: 0:2ab8003a1750
1390 o changeset: 0:2ab8003a1750
1376 branch: A
1391 branch: A
1377 tag: base
1392 tag: base
1378 user: debugbuilddag
1393 user: debugbuilddag
1379 date: Thu Jan 01 00:00:00 1970 +0000
1394 date: Thu Jan 01 00:00:00 1970 +0000
1380 summary: r0
1395 summary: r0
1381
1396
1382 $ hg bundle -R branchmap-testing1 --base 1 bundle.hg --rev 'head()'
1397 $ hg bundle -R branchmap-testing1 --base 1 bundle.hg --rev 'head()'
1383 2 changesets found
1398 2 changesets found
1384
1399
1385 Unbundling revision should warm the served cache
1400 Unbundling revision should warm the served cache
1386
1401
1387 $ hg clone branchmap-testing1 --rev 1 branchmap-update-01
1402 $ hg clone branchmap-testing1 --rev 1 branchmap-update-01
1388 adding changesets
1403 adding changesets
1389 adding manifests
1404 adding manifests
1390 adding file changes
1405 adding file changes
1391 added 2 changesets with 0 changes to 0 files
1406 added 2 changesets with 0 changes to 0 files
1392 new changesets 2ab8003a1750:99ba08759bc7
1407 new changesets 2ab8003a1750:99ba08759bc7
1393 updating to branch A
1408 updating to branch A
1394 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1409 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1395 #if v3
1410 #if v3
1396 $ cat branchmap-update-01/.hg/cache/branch3-exp-base
1411 $ cat branchmap-update-01/.hg/cache/branch3-exp-base
1397 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1412 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1398 A
1413 A
1399 #else
1414 #else
1400 $ cat branchmap-update-01/.hg/cache/branch2-base
1415 $ cat branchmap-update-01/.hg/cache/branch2-base
1401 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1416 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1402 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1417 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1403 #endif
1418 #endif
1404 $ hg -R branchmap-update-01 unbundle bundle.hg
1419 $ hg -R branchmap-update-01 unbundle bundle.hg
1405 adding changesets
1420 adding changesets
1406 adding manifests
1421 adding manifests
1407 adding file changes
1422 adding file changes
1408 added 2 changesets with 0 changes to 0 files
1423 added 2 changesets with 0 changes to 0 files
1409 new changesets a3b807b3ff0b:71ca9a6d524e (2 drafts)
1424 new changesets a3b807b3ff0b:71ca9a6d524e (2 drafts)
1410 (run 'hg update' to get a working copy)
1425 (run 'hg update' to get a working copy)
1411 #if v3
1426 #if v3
1412 $ cat branchmap-update-01/.hg/cache/branch3-exp-served
1427 $ cat branchmap-update-01/.hg/cache/branch3-exp-served
1413 tip-node=71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 tip-rev=3 topo-mode=pure
1428 tip-node=71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 tip-rev=3 topo-mode=pure
1414 A
1429 A
1415 #else
1430 #else
1416 $ cat branchmap-update-01/.hg/cache/branch2-served
1431 $ cat branchmap-update-01/.hg/cache/branch2-served
1417 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 3
1432 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 3
1418 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 o A
1433 71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 o A
1419 #endif
1434 #endif
1420
1435
1421 aborted Unbundle should not update the on disk cache
1436 aborted Unbundle should not update the on disk cache
1422
1437
1423 $ cat >> simplehook.py << EOF
1438 $ cat >> simplehook.py << EOF
1424 > import sys
1439 > import sys
1425 > from mercurial import node
1440 > from mercurial import node
1426 > from mercurial import branchmap
1441 > from mercurial import branchmap
1427 > def hook(ui, repo, *args, **kwargs):
1442 > def hook(ui, repo, *args, **kwargs):
1428 > s = repo.filtered(b"served")
1443 > s = repo.filtered(b"served")
1429 > s.branchmap()
1444 > s.branchmap()
1430 > return 1
1445 > return 1
1431 > EOF
1446 > EOF
1432 $ hg clone branchmap-testing1 --rev 1 branchmap-update-02
1447 $ hg clone branchmap-testing1 --rev 1 branchmap-update-02
1433 adding changesets
1448 adding changesets
1434 adding manifests
1449 adding manifests
1435 adding file changes
1450 adding file changes
1436 added 2 changesets with 0 changes to 0 files
1451 added 2 changesets with 0 changes to 0 files
1437 new changesets 2ab8003a1750:99ba08759bc7
1452 new changesets 2ab8003a1750:99ba08759bc7
1438 updating to branch A
1453 updating to branch A
1439 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1454 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1440
1455
1441 #if v3
1456 #if v3
1442 $ cat branchmap-update-02/.hg/cache/branch3-exp-base
1457 $ cat branchmap-update-02/.hg/cache/branch3-exp-base
1443 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1458 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1444 A
1459 A
1445 #else
1460 #else
1446 $ cat branchmap-update-02/.hg/cache/branch2-base
1461 $ cat branchmap-update-02/.hg/cache/branch2-base
1447 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1462 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1448 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1463 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1449 #endif
1464 #endif
1450 $ hg -R branchmap-update-02 unbundle bundle.hg --config "hooks.pretxnclose=python:$TESTTMP/simplehook.py:hook"
1465 $ hg -R branchmap-update-02 unbundle bundle.hg --config "hooks.pretxnclose=python:$TESTTMP/simplehook.py:hook"
1451 adding changesets
1466 adding changesets
1452 adding manifests
1467 adding manifests
1453 adding file changes
1468 adding file changes
1454 transaction abort!
1469 transaction abort!
1455 rollback completed
1470 rollback completed
1456 abort: pretxnclose hook failed
1471 abort: pretxnclose hook failed
1457 [40]
1472 [40]
1458 #if v3
1473 #if v3
1459 $ cat branchmap-update-02/.hg/cache/branch3-exp-base
1474 $ cat branchmap-update-02/.hg/cache/branch3-exp-base
1460 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1475 tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1 topo-mode=pure
1461 A
1476 A
1462 #else
1477 #else
1463 $ cat branchmap-update-02/.hg/cache/branch2-base
1478 $ cat branchmap-update-02/.hg/cache/branch2-base
1464 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1479 99ba08759bc7f6fdbe5304e83d0387f35c082479 1
1465 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1480 99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
1466 #endif
1481 #endif
General Comments 0
You need to be logged in to leave comments. Login now