##// END OF EJS Templates
manifestcache: use `wcache` directory for manifest cache...
marmoute -
r42131:e4ac7e63 default
parent child Browse files
Show More
@@ -1,2055 +1,2055 b''
1 # manifest.py - manifest revision class for mercurial
1 # manifest.py - manifest revision class for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import heapq
10 import heapq
11 import itertools
11 import itertools
12 import struct
12 import struct
13 import weakref
13 import weakref
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import (
16 from .node import (
17 bin,
17 bin,
18 hex,
18 hex,
19 nullid,
19 nullid,
20 nullrev,
20 nullrev,
21 )
21 )
22 from . import (
22 from . import (
23 error,
23 error,
24 mdiff,
24 mdiff,
25 policy,
25 policy,
26 pycompat,
26 pycompat,
27 repository,
27 repository,
28 revlog,
28 revlog,
29 util,
29 util,
30 )
30 )
31 from .utils import (
31 from .utils import (
32 interfaceutil,
32 interfaceutil,
33 )
33 )
34
34
35 parsers = policy.importmod(r'parsers')
35 parsers = policy.importmod(r'parsers')
36 propertycache = util.propertycache
36 propertycache = util.propertycache
37
37
38 def _parse(data):
38 def _parse(data):
39 # This method does a little bit of excessive-looking
39 # This method does a little bit of excessive-looking
40 # precondition checking. This is so that the behavior of this
40 # precondition checking. This is so that the behavior of this
41 # class exactly matches its C counterpart to try and help
41 # class exactly matches its C counterpart to try and help
42 # prevent surprise breakage for anyone that develops against
42 # prevent surprise breakage for anyone that develops against
43 # the pure version.
43 # the pure version.
44 if data and data[-1:] != '\n':
44 if data and data[-1:] != '\n':
45 raise ValueError('Manifest did not end in a newline.')
45 raise ValueError('Manifest did not end in a newline.')
46 prev = None
46 prev = None
47 for l in data.splitlines():
47 for l in data.splitlines():
48 if prev is not None and prev > l:
48 if prev is not None and prev > l:
49 raise ValueError('Manifest lines not in sorted order.')
49 raise ValueError('Manifest lines not in sorted order.')
50 prev = l
50 prev = l
51 f, n = l.split('\0')
51 f, n = l.split('\0')
52 if len(n) > 40:
52 if len(n) > 40:
53 yield f, bin(n[:40]), n[40:]
53 yield f, bin(n[:40]), n[40:]
54 else:
54 else:
55 yield f, bin(n), ''
55 yield f, bin(n), ''
56
56
57 def _text(it):
57 def _text(it):
58 files = []
58 files = []
59 lines = []
59 lines = []
60 for f, n, fl in it:
60 for f, n, fl in it:
61 files.append(f)
61 files.append(f)
62 # if this is changed to support newlines in filenames,
62 # if this is changed to support newlines in filenames,
63 # be sure to check the templates/ dir again (especially *-raw.tmpl)
63 # be sure to check the templates/ dir again (especially *-raw.tmpl)
64 lines.append("%s\0%s%s\n" % (f, hex(n), fl))
64 lines.append("%s\0%s%s\n" % (f, hex(n), fl))
65
65
66 _checkforbidden(files)
66 _checkforbidden(files)
67 return ''.join(lines)
67 return ''.join(lines)
68
68
69 class lazymanifestiter(object):
69 class lazymanifestiter(object):
70 def __init__(self, lm):
70 def __init__(self, lm):
71 self.pos = 0
71 self.pos = 0
72 self.lm = lm
72 self.lm = lm
73
73
74 def __iter__(self):
74 def __iter__(self):
75 return self
75 return self
76
76
77 def next(self):
77 def next(self):
78 try:
78 try:
79 data, pos = self.lm._get(self.pos)
79 data, pos = self.lm._get(self.pos)
80 except IndexError:
80 except IndexError:
81 raise StopIteration
81 raise StopIteration
82 if pos == -1:
82 if pos == -1:
83 self.pos += 1
83 self.pos += 1
84 return data[0]
84 return data[0]
85 self.pos += 1
85 self.pos += 1
86 zeropos = data.find('\x00', pos)
86 zeropos = data.find('\x00', pos)
87 return data[pos:zeropos]
87 return data[pos:zeropos]
88
88
89 __next__ = next
89 __next__ = next
90
90
91 class lazymanifestiterentries(object):
91 class lazymanifestiterentries(object):
92 def __init__(self, lm):
92 def __init__(self, lm):
93 self.lm = lm
93 self.lm = lm
94 self.pos = 0
94 self.pos = 0
95
95
96 def __iter__(self):
96 def __iter__(self):
97 return self
97 return self
98
98
99 def next(self):
99 def next(self):
100 try:
100 try:
101 data, pos = self.lm._get(self.pos)
101 data, pos = self.lm._get(self.pos)
102 except IndexError:
102 except IndexError:
103 raise StopIteration
103 raise StopIteration
104 if pos == -1:
104 if pos == -1:
105 self.pos += 1
105 self.pos += 1
106 return data
106 return data
107 zeropos = data.find('\x00', pos)
107 zeropos = data.find('\x00', pos)
108 hashval = unhexlify(data, self.lm.extrainfo[self.pos],
108 hashval = unhexlify(data, self.lm.extrainfo[self.pos],
109 zeropos + 1, 40)
109 zeropos + 1, 40)
110 flags = self.lm._getflags(data, self.pos, zeropos)
110 flags = self.lm._getflags(data, self.pos, zeropos)
111 self.pos += 1
111 self.pos += 1
112 return (data[pos:zeropos], hashval, flags)
112 return (data[pos:zeropos], hashval, flags)
113
113
114 __next__ = next
114 __next__ = next
115
115
116 def unhexlify(data, extra, pos, length):
116 def unhexlify(data, extra, pos, length):
117 s = bin(data[pos:pos + length])
117 s = bin(data[pos:pos + length])
118 if extra:
118 if extra:
119 s += chr(extra & 0xff)
119 s += chr(extra & 0xff)
120 return s
120 return s
121
121
122 def _cmp(a, b):
122 def _cmp(a, b):
123 return (a > b) - (a < b)
123 return (a > b) - (a < b)
124
124
125 class _lazymanifest(object):
125 class _lazymanifest(object):
126 def __init__(self, data, positions=None, extrainfo=None, extradata=None):
126 def __init__(self, data, positions=None, extrainfo=None, extradata=None):
127 if positions is None:
127 if positions is None:
128 self.positions = self.findlines(data)
128 self.positions = self.findlines(data)
129 self.extrainfo = [0] * len(self.positions)
129 self.extrainfo = [0] * len(self.positions)
130 self.data = data
130 self.data = data
131 self.extradata = []
131 self.extradata = []
132 else:
132 else:
133 self.positions = positions[:]
133 self.positions = positions[:]
134 self.extrainfo = extrainfo[:]
134 self.extrainfo = extrainfo[:]
135 self.extradata = extradata[:]
135 self.extradata = extradata[:]
136 self.data = data
136 self.data = data
137
137
138 def findlines(self, data):
138 def findlines(self, data):
139 if not data:
139 if not data:
140 return []
140 return []
141 pos = data.find("\n")
141 pos = data.find("\n")
142 if pos == -1 or data[-1:] != '\n':
142 if pos == -1 or data[-1:] != '\n':
143 raise ValueError("Manifest did not end in a newline.")
143 raise ValueError("Manifest did not end in a newline.")
144 positions = [0]
144 positions = [0]
145 prev = data[:data.find('\x00')]
145 prev = data[:data.find('\x00')]
146 while pos < len(data) - 1 and pos != -1:
146 while pos < len(data) - 1 and pos != -1:
147 positions.append(pos + 1)
147 positions.append(pos + 1)
148 nexts = data[pos + 1:data.find('\x00', pos + 1)]
148 nexts = data[pos + 1:data.find('\x00', pos + 1)]
149 if nexts < prev:
149 if nexts < prev:
150 raise ValueError("Manifest lines not in sorted order.")
150 raise ValueError("Manifest lines not in sorted order.")
151 prev = nexts
151 prev = nexts
152 pos = data.find("\n", pos + 1)
152 pos = data.find("\n", pos + 1)
153 return positions
153 return positions
154
154
155 def _get(self, index):
155 def _get(self, index):
156 # get the position encoded in pos:
156 # get the position encoded in pos:
157 # positive number is an index in 'data'
157 # positive number is an index in 'data'
158 # negative number is in extrapieces
158 # negative number is in extrapieces
159 pos = self.positions[index]
159 pos = self.positions[index]
160 if pos >= 0:
160 if pos >= 0:
161 return self.data, pos
161 return self.data, pos
162 return self.extradata[-pos - 1], -1
162 return self.extradata[-pos - 1], -1
163
163
164 def _getkey(self, pos):
164 def _getkey(self, pos):
165 if pos >= 0:
165 if pos >= 0:
166 return self.data[pos:self.data.find('\x00', pos + 1)]
166 return self.data[pos:self.data.find('\x00', pos + 1)]
167 return self.extradata[-pos - 1][0]
167 return self.extradata[-pos - 1][0]
168
168
169 def bsearch(self, key):
169 def bsearch(self, key):
170 first = 0
170 first = 0
171 last = len(self.positions) - 1
171 last = len(self.positions) - 1
172
172
173 while first <= last:
173 while first <= last:
174 midpoint = (first + last)//2
174 midpoint = (first + last)//2
175 nextpos = self.positions[midpoint]
175 nextpos = self.positions[midpoint]
176 candidate = self._getkey(nextpos)
176 candidate = self._getkey(nextpos)
177 r = _cmp(key, candidate)
177 r = _cmp(key, candidate)
178 if r == 0:
178 if r == 0:
179 return midpoint
179 return midpoint
180 else:
180 else:
181 if r < 0:
181 if r < 0:
182 last = midpoint - 1
182 last = midpoint - 1
183 else:
183 else:
184 first = midpoint + 1
184 first = midpoint + 1
185 return -1
185 return -1
186
186
187 def bsearch2(self, key):
187 def bsearch2(self, key):
188 # same as the above, but will always return the position
188 # same as the above, but will always return the position
189 # done for performance reasons
189 # done for performance reasons
190 first = 0
190 first = 0
191 last = len(self.positions) - 1
191 last = len(self.positions) - 1
192
192
193 while first <= last:
193 while first <= last:
194 midpoint = (first + last)//2
194 midpoint = (first + last)//2
195 nextpos = self.positions[midpoint]
195 nextpos = self.positions[midpoint]
196 candidate = self._getkey(nextpos)
196 candidate = self._getkey(nextpos)
197 r = _cmp(key, candidate)
197 r = _cmp(key, candidate)
198 if r == 0:
198 if r == 0:
199 return (midpoint, True)
199 return (midpoint, True)
200 else:
200 else:
201 if r < 0:
201 if r < 0:
202 last = midpoint - 1
202 last = midpoint - 1
203 else:
203 else:
204 first = midpoint + 1
204 first = midpoint + 1
205 return (first, False)
205 return (first, False)
206
206
207 def __contains__(self, key):
207 def __contains__(self, key):
208 return self.bsearch(key) != -1
208 return self.bsearch(key) != -1
209
209
210 def _getflags(self, data, needle, pos):
210 def _getflags(self, data, needle, pos):
211 start = pos + 41
211 start = pos + 41
212 end = data.find("\n", start)
212 end = data.find("\n", start)
213 if end == -1:
213 if end == -1:
214 end = len(data) - 1
214 end = len(data) - 1
215 if start == end:
215 if start == end:
216 return ''
216 return ''
217 return self.data[start:end]
217 return self.data[start:end]
218
218
219 def __getitem__(self, key):
219 def __getitem__(self, key):
220 if not isinstance(key, bytes):
220 if not isinstance(key, bytes):
221 raise TypeError("getitem: manifest keys must be a bytes.")
221 raise TypeError("getitem: manifest keys must be a bytes.")
222 needle = self.bsearch(key)
222 needle = self.bsearch(key)
223 if needle == -1:
223 if needle == -1:
224 raise KeyError
224 raise KeyError
225 data, pos = self._get(needle)
225 data, pos = self._get(needle)
226 if pos == -1:
226 if pos == -1:
227 return (data[1], data[2])
227 return (data[1], data[2])
228 zeropos = data.find('\x00', pos)
228 zeropos = data.find('\x00', pos)
229 assert 0 <= needle <= len(self.positions)
229 assert 0 <= needle <= len(self.positions)
230 assert len(self.extrainfo) == len(self.positions)
230 assert len(self.extrainfo) == len(self.positions)
231 hashval = unhexlify(data, self.extrainfo[needle], zeropos + 1, 40)
231 hashval = unhexlify(data, self.extrainfo[needle], zeropos + 1, 40)
232 flags = self._getflags(data, needle, zeropos)
232 flags = self._getflags(data, needle, zeropos)
233 return (hashval, flags)
233 return (hashval, flags)
234
234
235 def __delitem__(self, key):
235 def __delitem__(self, key):
236 needle, found = self.bsearch2(key)
236 needle, found = self.bsearch2(key)
237 if not found:
237 if not found:
238 raise KeyError
238 raise KeyError
239 cur = self.positions[needle]
239 cur = self.positions[needle]
240 self.positions = self.positions[:needle] + self.positions[needle + 1:]
240 self.positions = self.positions[:needle] + self.positions[needle + 1:]
241 self.extrainfo = self.extrainfo[:needle] + self.extrainfo[needle + 1:]
241 self.extrainfo = self.extrainfo[:needle] + self.extrainfo[needle + 1:]
242 if cur >= 0:
242 if cur >= 0:
243 self.data = self.data[:cur] + '\x00' + self.data[cur + 1:]
243 self.data = self.data[:cur] + '\x00' + self.data[cur + 1:]
244
244
245 def __setitem__(self, key, value):
245 def __setitem__(self, key, value):
246 if not isinstance(key, bytes):
246 if not isinstance(key, bytes):
247 raise TypeError("setitem: manifest keys must be a byte string.")
247 raise TypeError("setitem: manifest keys must be a byte string.")
248 if not isinstance(value, tuple) or len(value) != 2:
248 if not isinstance(value, tuple) or len(value) != 2:
249 raise TypeError("Manifest values must be a tuple of (node, flags).")
249 raise TypeError("Manifest values must be a tuple of (node, flags).")
250 hashval = value[0]
250 hashval = value[0]
251 if not isinstance(hashval, bytes) or not 20 <= len(hashval) <= 22:
251 if not isinstance(hashval, bytes) or not 20 <= len(hashval) <= 22:
252 raise TypeError("node must be a 20-byte byte string")
252 raise TypeError("node must be a 20-byte byte string")
253 flags = value[1]
253 flags = value[1]
254 if len(hashval) == 22:
254 if len(hashval) == 22:
255 hashval = hashval[:-1]
255 hashval = hashval[:-1]
256 if not isinstance(flags, bytes) or len(flags) > 1:
256 if not isinstance(flags, bytes) or len(flags) > 1:
257 raise TypeError("flags must a 0 or 1 byte string, got %r", flags)
257 raise TypeError("flags must a 0 or 1 byte string, got %r", flags)
258 needle, found = self.bsearch2(key)
258 needle, found = self.bsearch2(key)
259 if found:
259 if found:
260 # put the item
260 # put the item
261 pos = self.positions[needle]
261 pos = self.positions[needle]
262 if pos < 0:
262 if pos < 0:
263 self.extradata[-pos - 1] = (key, hashval, value[1])
263 self.extradata[-pos - 1] = (key, hashval, value[1])
264 else:
264 else:
265 # just don't bother
265 # just don't bother
266 self.extradata.append((key, hashval, value[1]))
266 self.extradata.append((key, hashval, value[1]))
267 self.positions[needle] = -len(self.extradata)
267 self.positions[needle] = -len(self.extradata)
268 else:
268 else:
269 # not found, put it in with extra positions
269 # not found, put it in with extra positions
270 self.extradata.append((key, hashval, value[1]))
270 self.extradata.append((key, hashval, value[1]))
271 self.positions = (self.positions[:needle] + [-len(self.extradata)]
271 self.positions = (self.positions[:needle] + [-len(self.extradata)]
272 + self.positions[needle:])
272 + self.positions[needle:])
273 self.extrainfo = (self.extrainfo[:needle] + [0] +
273 self.extrainfo = (self.extrainfo[:needle] + [0] +
274 self.extrainfo[needle:])
274 self.extrainfo[needle:])
275
275
276 def copy(self):
276 def copy(self):
277 # XXX call _compact like in C?
277 # XXX call _compact like in C?
278 return _lazymanifest(self.data, self.positions, self.extrainfo,
278 return _lazymanifest(self.data, self.positions, self.extrainfo,
279 self.extradata)
279 self.extradata)
280
280
281 def _compact(self):
281 def _compact(self):
282 # hopefully not called TOO often
282 # hopefully not called TOO often
283 if len(self.extradata) == 0:
283 if len(self.extradata) == 0:
284 return
284 return
285 l = []
285 l = []
286 i = 0
286 i = 0
287 offset = 0
287 offset = 0
288 self.extrainfo = [0] * len(self.positions)
288 self.extrainfo = [0] * len(self.positions)
289 while i < len(self.positions):
289 while i < len(self.positions):
290 if self.positions[i] >= 0:
290 if self.positions[i] >= 0:
291 cur = self.positions[i]
291 cur = self.positions[i]
292 last_cut = cur
292 last_cut = cur
293 while True:
293 while True:
294 self.positions[i] = offset
294 self.positions[i] = offset
295 i += 1
295 i += 1
296 if i == len(self.positions) or self.positions[i] < 0:
296 if i == len(self.positions) or self.positions[i] < 0:
297 break
297 break
298 offset += self.positions[i] - cur
298 offset += self.positions[i] - cur
299 cur = self.positions[i]
299 cur = self.positions[i]
300 end_cut = self.data.find('\n', cur)
300 end_cut = self.data.find('\n', cur)
301 if end_cut != -1:
301 if end_cut != -1:
302 end_cut += 1
302 end_cut += 1
303 offset += end_cut - cur
303 offset += end_cut - cur
304 l.append(self.data[last_cut:end_cut])
304 l.append(self.data[last_cut:end_cut])
305 else:
305 else:
306 while i < len(self.positions) and self.positions[i] < 0:
306 while i < len(self.positions) and self.positions[i] < 0:
307 cur = self.positions[i]
307 cur = self.positions[i]
308 t = self.extradata[-cur - 1]
308 t = self.extradata[-cur - 1]
309 l.append(self._pack(t))
309 l.append(self._pack(t))
310 self.positions[i] = offset
310 self.positions[i] = offset
311 if len(t[1]) > 20:
311 if len(t[1]) > 20:
312 self.extrainfo[i] = ord(t[1][21])
312 self.extrainfo[i] = ord(t[1][21])
313 offset += len(l[-1])
313 offset += len(l[-1])
314 i += 1
314 i += 1
315 self.data = ''.join(l)
315 self.data = ''.join(l)
316 self.extradata = []
316 self.extradata = []
317
317
318 def _pack(self, d):
318 def _pack(self, d):
319 return d[0] + '\x00' + hex(d[1][:20]) + d[2] + '\n'
319 return d[0] + '\x00' + hex(d[1][:20]) + d[2] + '\n'
320
320
321 def text(self):
321 def text(self):
322 self._compact()
322 self._compact()
323 return self.data
323 return self.data
324
324
325 def diff(self, m2, clean=False):
325 def diff(self, m2, clean=False):
326 '''Finds changes between the current manifest and m2.'''
326 '''Finds changes between the current manifest and m2.'''
327 # XXX think whether efficiency matters here
327 # XXX think whether efficiency matters here
328 diff = {}
328 diff = {}
329
329
330 for fn, e1, flags in self.iterentries():
330 for fn, e1, flags in self.iterentries():
331 if fn not in m2:
331 if fn not in m2:
332 diff[fn] = (e1, flags), (None, '')
332 diff[fn] = (e1, flags), (None, '')
333 else:
333 else:
334 e2 = m2[fn]
334 e2 = m2[fn]
335 if (e1, flags) != e2:
335 if (e1, flags) != e2:
336 diff[fn] = (e1, flags), e2
336 diff[fn] = (e1, flags), e2
337 elif clean:
337 elif clean:
338 diff[fn] = None
338 diff[fn] = None
339
339
340 for fn, e2, flags in m2.iterentries():
340 for fn, e2, flags in m2.iterentries():
341 if fn not in self:
341 if fn not in self:
342 diff[fn] = (None, ''), (e2, flags)
342 diff[fn] = (None, ''), (e2, flags)
343
343
344 return diff
344 return diff
345
345
346 def iterentries(self):
346 def iterentries(self):
347 return lazymanifestiterentries(self)
347 return lazymanifestiterentries(self)
348
348
349 def iterkeys(self):
349 def iterkeys(self):
350 return lazymanifestiter(self)
350 return lazymanifestiter(self)
351
351
352 def __iter__(self):
352 def __iter__(self):
353 return lazymanifestiter(self)
353 return lazymanifestiter(self)
354
354
355 def __len__(self):
355 def __len__(self):
356 return len(self.positions)
356 return len(self.positions)
357
357
358 def filtercopy(self, filterfn):
358 def filtercopy(self, filterfn):
359 # XXX should be optimized
359 # XXX should be optimized
360 c = _lazymanifest('')
360 c = _lazymanifest('')
361 for f, n, fl in self.iterentries():
361 for f, n, fl in self.iterentries():
362 if filterfn(f):
362 if filterfn(f):
363 c[f] = n, fl
363 c[f] = n, fl
364 return c
364 return c
365
365
366 try:
366 try:
367 _lazymanifest = parsers.lazymanifest
367 _lazymanifest = parsers.lazymanifest
368 except AttributeError:
368 except AttributeError:
369 pass
369 pass
370
370
371 @interfaceutil.implementer(repository.imanifestdict)
371 @interfaceutil.implementer(repository.imanifestdict)
372 class manifestdict(object):
372 class manifestdict(object):
373 def __init__(self, data=''):
373 def __init__(self, data=''):
374 self._lm = _lazymanifest(data)
374 self._lm = _lazymanifest(data)
375
375
376 def __getitem__(self, key):
376 def __getitem__(self, key):
377 return self._lm[key][0]
377 return self._lm[key][0]
378
378
379 def find(self, key):
379 def find(self, key):
380 return self._lm[key]
380 return self._lm[key]
381
381
382 def __len__(self):
382 def __len__(self):
383 return len(self._lm)
383 return len(self._lm)
384
384
385 def __nonzero__(self):
385 def __nonzero__(self):
386 # nonzero is covered by the __len__ function, but implementing it here
386 # nonzero is covered by the __len__ function, but implementing it here
387 # makes it easier for extensions to override.
387 # makes it easier for extensions to override.
388 return len(self._lm) != 0
388 return len(self._lm) != 0
389
389
390 __bool__ = __nonzero__
390 __bool__ = __nonzero__
391
391
392 def __setitem__(self, key, node):
392 def __setitem__(self, key, node):
393 self._lm[key] = node, self.flags(key, '')
393 self._lm[key] = node, self.flags(key, '')
394
394
395 def __contains__(self, key):
395 def __contains__(self, key):
396 if key is None:
396 if key is None:
397 return False
397 return False
398 return key in self._lm
398 return key in self._lm
399
399
400 def __delitem__(self, key):
400 def __delitem__(self, key):
401 del self._lm[key]
401 del self._lm[key]
402
402
403 def __iter__(self):
403 def __iter__(self):
404 return self._lm.__iter__()
404 return self._lm.__iter__()
405
405
406 def iterkeys(self):
406 def iterkeys(self):
407 return self._lm.iterkeys()
407 return self._lm.iterkeys()
408
408
409 def keys(self):
409 def keys(self):
410 return list(self.iterkeys())
410 return list(self.iterkeys())
411
411
412 def filesnotin(self, m2, match=None):
412 def filesnotin(self, m2, match=None):
413 '''Set of files in this manifest that are not in the other'''
413 '''Set of files in this manifest that are not in the other'''
414 if match:
414 if match:
415 m1 = self.matches(match)
415 m1 = self.matches(match)
416 m2 = m2.matches(match)
416 m2 = m2.matches(match)
417 return m1.filesnotin(m2)
417 return m1.filesnotin(m2)
418 diff = self.diff(m2)
418 diff = self.diff(m2)
419 files = set(filepath
419 files = set(filepath
420 for filepath, hashflags in diff.iteritems()
420 for filepath, hashflags in diff.iteritems()
421 if hashflags[1][0] is None)
421 if hashflags[1][0] is None)
422 return files
422 return files
423
423
424 @propertycache
424 @propertycache
425 def _dirs(self):
425 def _dirs(self):
426 return util.dirs(self)
426 return util.dirs(self)
427
427
428 def dirs(self):
428 def dirs(self):
429 return self._dirs
429 return self._dirs
430
430
431 def hasdir(self, dir):
431 def hasdir(self, dir):
432 return dir in self._dirs
432 return dir in self._dirs
433
433
434 def _filesfastpath(self, match):
434 def _filesfastpath(self, match):
435 '''Checks whether we can correctly and quickly iterate over matcher
435 '''Checks whether we can correctly and quickly iterate over matcher
436 files instead of over manifest files.'''
436 files instead of over manifest files.'''
437 files = match.files()
437 files = match.files()
438 return (len(files) < 100 and (match.isexact() or
438 return (len(files) < 100 and (match.isexact() or
439 (match.prefix() and all(fn in self for fn in files))))
439 (match.prefix() and all(fn in self for fn in files))))
440
440
441 def walk(self, match):
441 def walk(self, match):
442 '''Generates matching file names.
442 '''Generates matching file names.
443
443
444 Equivalent to manifest.matches(match).iterkeys(), but without creating
444 Equivalent to manifest.matches(match).iterkeys(), but without creating
445 an entirely new manifest.
445 an entirely new manifest.
446
446
447 It also reports nonexistent files by marking them bad with match.bad().
447 It also reports nonexistent files by marking them bad with match.bad().
448 '''
448 '''
449 if match.always():
449 if match.always():
450 for f in iter(self):
450 for f in iter(self):
451 yield f
451 yield f
452 return
452 return
453
453
454 fset = set(match.files())
454 fset = set(match.files())
455
455
456 # avoid the entire walk if we're only looking for specific files
456 # avoid the entire walk if we're only looking for specific files
457 if self._filesfastpath(match):
457 if self._filesfastpath(match):
458 for fn in sorted(fset):
458 for fn in sorted(fset):
459 yield fn
459 yield fn
460 return
460 return
461
461
462 for fn in self:
462 for fn in self:
463 if fn in fset:
463 if fn in fset:
464 # specified pattern is the exact name
464 # specified pattern is the exact name
465 fset.remove(fn)
465 fset.remove(fn)
466 if match(fn):
466 if match(fn):
467 yield fn
467 yield fn
468
468
469 # for dirstate.walk, files=['.'] means "walk the whole tree".
469 # for dirstate.walk, files=['.'] means "walk the whole tree".
470 # follow that here, too
470 # follow that here, too
471 fset.discard('.')
471 fset.discard('.')
472
472
473 for fn in sorted(fset):
473 for fn in sorted(fset):
474 if not self.hasdir(fn):
474 if not self.hasdir(fn):
475 match.bad(fn, None)
475 match.bad(fn, None)
476
476
477 def matches(self, match):
477 def matches(self, match):
478 '''generate a new manifest filtered by the match argument'''
478 '''generate a new manifest filtered by the match argument'''
479 if match.always():
479 if match.always():
480 return self.copy()
480 return self.copy()
481
481
482 if self._filesfastpath(match):
482 if self._filesfastpath(match):
483 m = manifestdict()
483 m = manifestdict()
484 lm = self._lm
484 lm = self._lm
485 for fn in match.files():
485 for fn in match.files():
486 if fn in lm:
486 if fn in lm:
487 m._lm[fn] = lm[fn]
487 m._lm[fn] = lm[fn]
488 return m
488 return m
489
489
490 m = manifestdict()
490 m = manifestdict()
491 m._lm = self._lm.filtercopy(match)
491 m._lm = self._lm.filtercopy(match)
492 return m
492 return m
493
493
494 def diff(self, m2, match=None, clean=False):
494 def diff(self, m2, match=None, clean=False):
495 '''Finds changes between the current manifest and m2.
495 '''Finds changes between the current manifest and m2.
496
496
497 Args:
497 Args:
498 m2: the manifest to which this manifest should be compared.
498 m2: the manifest to which this manifest should be compared.
499 clean: if true, include files unchanged between these manifests
499 clean: if true, include files unchanged between these manifests
500 with a None value in the returned dictionary.
500 with a None value in the returned dictionary.
501
501
502 The result is returned as a dict with filename as key and
502 The result is returned as a dict with filename as key and
503 values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the
503 values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the
504 nodeid in the current/other manifest and fl1/fl2 is the flag
504 nodeid in the current/other manifest and fl1/fl2 is the flag
505 in the current/other manifest. Where the file does not exist,
505 in the current/other manifest. Where the file does not exist,
506 the nodeid will be None and the flags will be the empty
506 the nodeid will be None and the flags will be the empty
507 string.
507 string.
508 '''
508 '''
509 if match:
509 if match:
510 m1 = self.matches(match)
510 m1 = self.matches(match)
511 m2 = m2.matches(match)
511 m2 = m2.matches(match)
512 return m1.diff(m2, clean=clean)
512 return m1.diff(m2, clean=clean)
513 return self._lm.diff(m2._lm, clean)
513 return self._lm.diff(m2._lm, clean)
514
514
515 def setflag(self, key, flag):
515 def setflag(self, key, flag):
516 self._lm[key] = self[key], flag
516 self._lm[key] = self[key], flag
517
517
518 def get(self, key, default=None):
518 def get(self, key, default=None):
519 try:
519 try:
520 return self._lm[key][0]
520 return self._lm[key][0]
521 except KeyError:
521 except KeyError:
522 return default
522 return default
523
523
524 def flags(self, key, default=''):
524 def flags(self, key, default=''):
525 try:
525 try:
526 return self._lm[key][1]
526 return self._lm[key][1]
527 except KeyError:
527 except KeyError:
528 return default
528 return default
529
529
530 def copy(self):
530 def copy(self):
531 c = manifestdict()
531 c = manifestdict()
532 c._lm = self._lm.copy()
532 c._lm = self._lm.copy()
533 return c
533 return c
534
534
535 def items(self):
535 def items(self):
536 return (x[:2] for x in self._lm.iterentries())
536 return (x[:2] for x in self._lm.iterentries())
537
537
538 def iteritems(self):
538 def iteritems(self):
539 return (x[:2] for x in self._lm.iterentries())
539 return (x[:2] for x in self._lm.iterentries())
540
540
541 def iterentries(self):
541 def iterentries(self):
542 return self._lm.iterentries()
542 return self._lm.iterentries()
543
543
544 def text(self):
544 def text(self):
545 # most likely uses native version
545 # most likely uses native version
546 return self._lm.text()
546 return self._lm.text()
547
547
548 def fastdelta(self, base, changes):
548 def fastdelta(self, base, changes):
549 """Given a base manifest text as a bytearray and a list of changes
549 """Given a base manifest text as a bytearray and a list of changes
550 relative to that text, compute a delta that can be used by revlog.
550 relative to that text, compute a delta that can be used by revlog.
551 """
551 """
552 delta = []
552 delta = []
553 dstart = None
553 dstart = None
554 dend = None
554 dend = None
555 dline = [""]
555 dline = [""]
556 start = 0
556 start = 0
557 # zero copy representation of base as a buffer
557 # zero copy representation of base as a buffer
558 addbuf = util.buffer(base)
558 addbuf = util.buffer(base)
559
559
560 changes = list(changes)
560 changes = list(changes)
561 if len(changes) < 1000:
561 if len(changes) < 1000:
562 # start with a readonly loop that finds the offset of
562 # start with a readonly loop that finds the offset of
563 # each line and creates the deltas
563 # each line and creates the deltas
564 for f, todelete in changes:
564 for f, todelete in changes:
565 # bs will either be the index of the item or the insert point
565 # bs will either be the index of the item or the insert point
566 start, end = _msearch(addbuf, f, start)
566 start, end = _msearch(addbuf, f, start)
567 if not todelete:
567 if not todelete:
568 h, fl = self._lm[f]
568 h, fl = self._lm[f]
569 l = "%s\0%s%s\n" % (f, hex(h), fl)
569 l = "%s\0%s%s\n" % (f, hex(h), fl)
570 else:
570 else:
571 if start == end:
571 if start == end:
572 # item we want to delete was not found, error out
572 # item we want to delete was not found, error out
573 raise AssertionError(
573 raise AssertionError(
574 _("failed to remove %s from manifest") % f)
574 _("failed to remove %s from manifest") % f)
575 l = ""
575 l = ""
576 if dstart is not None and dstart <= start and dend >= start:
576 if dstart is not None and dstart <= start and dend >= start:
577 if dend < end:
577 if dend < end:
578 dend = end
578 dend = end
579 if l:
579 if l:
580 dline.append(l)
580 dline.append(l)
581 else:
581 else:
582 if dstart is not None:
582 if dstart is not None:
583 delta.append([dstart, dend, "".join(dline)])
583 delta.append([dstart, dend, "".join(dline)])
584 dstart = start
584 dstart = start
585 dend = end
585 dend = end
586 dline = [l]
586 dline = [l]
587
587
588 if dstart is not None:
588 if dstart is not None:
589 delta.append([dstart, dend, "".join(dline)])
589 delta.append([dstart, dend, "".join(dline)])
590 # apply the delta to the base, and get a delta for addrevision
590 # apply the delta to the base, and get a delta for addrevision
591 deltatext, arraytext = _addlistdelta(base, delta)
591 deltatext, arraytext = _addlistdelta(base, delta)
592 else:
592 else:
593 # For large changes, it's much cheaper to just build the text and
593 # For large changes, it's much cheaper to just build the text and
594 # diff it.
594 # diff it.
595 arraytext = bytearray(self.text())
595 arraytext = bytearray(self.text())
596 deltatext = mdiff.textdiff(
596 deltatext = mdiff.textdiff(
597 util.buffer(base), util.buffer(arraytext))
597 util.buffer(base), util.buffer(arraytext))
598
598
599 return arraytext, deltatext
599 return arraytext, deltatext
600
600
601 def _msearch(m, s, lo=0, hi=None):
601 def _msearch(m, s, lo=0, hi=None):
602 '''return a tuple (start, end) that says where to find s within m.
602 '''return a tuple (start, end) that says where to find s within m.
603
603
604 If the string is found m[start:end] are the line containing
604 If the string is found m[start:end] are the line containing
605 that string. If start == end the string was not found and
605 that string. If start == end the string was not found and
606 they indicate the proper sorted insertion point.
606 they indicate the proper sorted insertion point.
607
607
608 m should be a buffer, a memoryview or a byte string.
608 m should be a buffer, a memoryview or a byte string.
609 s is a byte string'''
609 s is a byte string'''
610 def advance(i, c):
610 def advance(i, c):
611 while i < lenm and m[i:i + 1] != c:
611 while i < lenm and m[i:i + 1] != c:
612 i += 1
612 i += 1
613 return i
613 return i
614 if not s:
614 if not s:
615 return (lo, lo)
615 return (lo, lo)
616 lenm = len(m)
616 lenm = len(m)
617 if not hi:
617 if not hi:
618 hi = lenm
618 hi = lenm
619 while lo < hi:
619 while lo < hi:
620 mid = (lo + hi) // 2
620 mid = (lo + hi) // 2
621 start = mid
621 start = mid
622 while start > 0 and m[start - 1:start] != '\n':
622 while start > 0 and m[start - 1:start] != '\n':
623 start -= 1
623 start -= 1
624 end = advance(start, '\0')
624 end = advance(start, '\0')
625 if bytes(m[start:end]) < s:
625 if bytes(m[start:end]) < s:
626 # we know that after the null there are 40 bytes of sha1
626 # we know that after the null there are 40 bytes of sha1
627 # this translates to the bisect lo = mid + 1
627 # this translates to the bisect lo = mid + 1
628 lo = advance(end + 40, '\n') + 1
628 lo = advance(end + 40, '\n') + 1
629 else:
629 else:
630 # this translates to the bisect hi = mid
630 # this translates to the bisect hi = mid
631 hi = start
631 hi = start
632 end = advance(lo, '\0')
632 end = advance(lo, '\0')
633 found = m[lo:end]
633 found = m[lo:end]
634 if s == found:
634 if s == found:
635 # we know that after the null there are 40 bytes of sha1
635 # we know that after the null there are 40 bytes of sha1
636 end = advance(end + 40, '\n')
636 end = advance(end + 40, '\n')
637 return (lo, end + 1)
637 return (lo, end + 1)
638 else:
638 else:
639 return (lo, lo)
639 return (lo, lo)
640
640
641 def _checkforbidden(l):
641 def _checkforbidden(l):
642 """Check filenames for illegal characters."""
642 """Check filenames for illegal characters."""
643 for f in l:
643 for f in l:
644 if '\n' in f or '\r' in f:
644 if '\n' in f or '\r' in f:
645 raise error.StorageError(
645 raise error.StorageError(
646 _("'\\n' and '\\r' disallowed in filenames: %r")
646 _("'\\n' and '\\r' disallowed in filenames: %r")
647 % pycompat.bytestr(f))
647 % pycompat.bytestr(f))
648
648
649
649
650 # apply the changes collected during the bisect loop to our addlist
650 # apply the changes collected during the bisect loop to our addlist
651 # return a delta suitable for addrevision
651 # return a delta suitable for addrevision
652 def _addlistdelta(addlist, x):
652 def _addlistdelta(addlist, x):
653 # for large addlist arrays, building a new array is cheaper
653 # for large addlist arrays, building a new array is cheaper
654 # than repeatedly modifying the existing one
654 # than repeatedly modifying the existing one
655 currentposition = 0
655 currentposition = 0
656 newaddlist = bytearray()
656 newaddlist = bytearray()
657
657
658 for start, end, content in x:
658 for start, end, content in x:
659 newaddlist += addlist[currentposition:start]
659 newaddlist += addlist[currentposition:start]
660 if content:
660 if content:
661 newaddlist += bytearray(content)
661 newaddlist += bytearray(content)
662
662
663 currentposition = end
663 currentposition = end
664
664
665 newaddlist += addlist[currentposition:]
665 newaddlist += addlist[currentposition:]
666
666
667 deltatext = "".join(struct.pack(">lll", start, end, len(content))
667 deltatext = "".join(struct.pack(">lll", start, end, len(content))
668 + content for start, end, content in x)
668 + content for start, end, content in x)
669 return deltatext, newaddlist
669 return deltatext, newaddlist
670
670
671 def _splittopdir(f):
671 def _splittopdir(f):
672 if '/' in f:
672 if '/' in f:
673 dir, subpath = f.split('/', 1)
673 dir, subpath = f.split('/', 1)
674 return dir + '/', subpath
674 return dir + '/', subpath
675 else:
675 else:
676 return '', f
676 return '', f
677
677
678 _noop = lambda s: None
678 _noop = lambda s: None
679
679
680 class treemanifest(object):
680 class treemanifest(object):
681 def __init__(self, dir='', text=''):
681 def __init__(self, dir='', text=''):
682 self._dir = dir
682 self._dir = dir
683 self._node = nullid
683 self._node = nullid
684 self._loadfunc = _noop
684 self._loadfunc = _noop
685 self._copyfunc = _noop
685 self._copyfunc = _noop
686 self._dirty = False
686 self._dirty = False
687 self._dirs = {}
687 self._dirs = {}
688 self._lazydirs = {}
688 self._lazydirs = {}
689 # Using _lazymanifest here is a little slower than plain old dicts
689 # Using _lazymanifest here is a little slower than plain old dicts
690 self._files = {}
690 self._files = {}
691 self._flags = {}
691 self._flags = {}
692 if text:
692 if text:
693 def readsubtree(subdir, subm):
693 def readsubtree(subdir, subm):
694 raise AssertionError('treemanifest constructor only accepts '
694 raise AssertionError('treemanifest constructor only accepts '
695 'flat manifests')
695 'flat manifests')
696 self.parse(text, readsubtree)
696 self.parse(text, readsubtree)
697 self._dirty = True # Mark flat manifest dirty after parsing
697 self._dirty = True # Mark flat manifest dirty after parsing
698
698
699 def _subpath(self, path):
699 def _subpath(self, path):
700 return self._dir + path
700 return self._dir + path
701
701
702 def _loadalllazy(self):
702 def _loadalllazy(self):
703 selfdirs = self._dirs
703 selfdirs = self._dirs
704 for d, (path, node, readsubtree, docopy) in self._lazydirs.iteritems():
704 for d, (path, node, readsubtree, docopy) in self._lazydirs.iteritems():
705 if docopy:
705 if docopy:
706 selfdirs[d] = readsubtree(path, node).copy()
706 selfdirs[d] = readsubtree(path, node).copy()
707 else:
707 else:
708 selfdirs[d] = readsubtree(path, node)
708 selfdirs[d] = readsubtree(path, node)
709 self._lazydirs = {}
709 self._lazydirs = {}
710
710
711 def _loadlazy(self, d):
711 def _loadlazy(self, d):
712 v = self._lazydirs.get(d)
712 v = self._lazydirs.get(d)
713 if v:
713 if v:
714 path, node, readsubtree, docopy = v
714 path, node, readsubtree, docopy = v
715 if docopy:
715 if docopy:
716 self._dirs[d] = readsubtree(path, node).copy()
716 self._dirs[d] = readsubtree(path, node).copy()
717 else:
717 else:
718 self._dirs[d] = readsubtree(path, node)
718 self._dirs[d] = readsubtree(path, node)
719 del self._lazydirs[d]
719 del self._lazydirs[d]
720
720
721 def _loadchildrensetlazy(self, visit):
721 def _loadchildrensetlazy(self, visit):
722 if not visit:
722 if not visit:
723 return None
723 return None
724 if visit == 'all' or visit == 'this':
724 if visit == 'all' or visit == 'this':
725 self._loadalllazy()
725 self._loadalllazy()
726 return None
726 return None
727
727
728 loadlazy = self._loadlazy
728 loadlazy = self._loadlazy
729 for k in visit:
729 for k in visit:
730 loadlazy(k + '/')
730 loadlazy(k + '/')
731 return visit
731 return visit
732
732
733 def _loaddifflazy(self, t1, t2):
733 def _loaddifflazy(self, t1, t2):
734 """load items in t1 and t2 if they're needed for diffing.
734 """load items in t1 and t2 if they're needed for diffing.
735
735
736 The criteria currently is:
736 The criteria currently is:
737 - if it's not present in _lazydirs in either t1 or t2, load it in the
737 - if it's not present in _lazydirs in either t1 or t2, load it in the
738 other (it may already be loaded or it may not exist, doesn't matter)
738 other (it may already be loaded or it may not exist, doesn't matter)
739 - if it's present in _lazydirs in both, compare the nodeid; if it
739 - if it's present in _lazydirs in both, compare the nodeid; if it
740 differs, load it in both
740 differs, load it in both
741 """
741 """
742 toloadlazy = []
742 toloadlazy = []
743 for d, v1 in t1._lazydirs.iteritems():
743 for d, v1 in t1._lazydirs.iteritems():
744 v2 = t2._lazydirs.get(d)
744 v2 = t2._lazydirs.get(d)
745 if not v2 or v2[1] != v1[1]:
745 if not v2 or v2[1] != v1[1]:
746 toloadlazy.append(d)
746 toloadlazy.append(d)
747 for d, v1 in t2._lazydirs.iteritems():
747 for d, v1 in t2._lazydirs.iteritems():
748 if d not in t1._lazydirs:
748 if d not in t1._lazydirs:
749 toloadlazy.append(d)
749 toloadlazy.append(d)
750
750
751 for d in toloadlazy:
751 for d in toloadlazy:
752 t1._loadlazy(d)
752 t1._loadlazy(d)
753 t2._loadlazy(d)
753 t2._loadlazy(d)
754
754
755 def __len__(self):
755 def __len__(self):
756 self._load()
756 self._load()
757 size = len(self._files)
757 size = len(self._files)
758 self._loadalllazy()
758 self._loadalllazy()
759 for m in self._dirs.values():
759 for m in self._dirs.values():
760 size += m.__len__()
760 size += m.__len__()
761 return size
761 return size
762
762
763 def __nonzero__(self):
763 def __nonzero__(self):
764 # Faster than "__len() != 0" since it avoids loading sub-manifests
764 # Faster than "__len() != 0" since it avoids loading sub-manifests
765 return not self._isempty()
765 return not self._isempty()
766
766
767 __bool__ = __nonzero__
767 __bool__ = __nonzero__
768
768
769 def _isempty(self):
769 def _isempty(self):
770 self._load() # for consistency; already loaded by all callers
770 self._load() # for consistency; already loaded by all callers
771 # See if we can skip loading everything.
771 # See if we can skip loading everything.
772 if self._files or (self._dirs and
772 if self._files or (self._dirs and
773 any(not m._isempty() for m in self._dirs.values())):
773 any(not m._isempty() for m in self._dirs.values())):
774 return False
774 return False
775 self._loadalllazy()
775 self._loadalllazy()
776 return (not self._dirs or
776 return (not self._dirs or
777 all(m._isempty() for m in self._dirs.values()))
777 all(m._isempty() for m in self._dirs.values()))
778
778
779 def __repr__(self):
779 def __repr__(self):
780 return ('<treemanifest dir=%s, node=%s, loaded=%s, dirty=%s at 0x%x>' %
780 return ('<treemanifest dir=%s, node=%s, loaded=%s, dirty=%s at 0x%x>' %
781 (self._dir, hex(self._node),
781 (self._dir, hex(self._node),
782 bool(self._loadfunc is _noop),
782 bool(self._loadfunc is _noop),
783 self._dirty, id(self)))
783 self._dirty, id(self)))
784
784
785 def dir(self):
785 def dir(self):
786 '''The directory that this tree manifest represents, including a
786 '''The directory that this tree manifest represents, including a
787 trailing '/'. Empty string for the repo root directory.'''
787 trailing '/'. Empty string for the repo root directory.'''
788 return self._dir
788 return self._dir
789
789
790 def node(self):
790 def node(self):
791 '''This node of this instance. nullid for unsaved instances. Should
791 '''This node of this instance. nullid for unsaved instances. Should
792 be updated when the instance is read or written from a revlog.
792 be updated when the instance is read or written from a revlog.
793 '''
793 '''
794 assert not self._dirty
794 assert not self._dirty
795 return self._node
795 return self._node
796
796
797 def setnode(self, node):
797 def setnode(self, node):
798 self._node = node
798 self._node = node
799 self._dirty = False
799 self._dirty = False
800
800
801 def iterentries(self):
801 def iterentries(self):
802 self._load()
802 self._load()
803 self._loadalllazy()
803 self._loadalllazy()
804 for p, n in sorted(itertools.chain(self._dirs.items(),
804 for p, n in sorted(itertools.chain(self._dirs.items(),
805 self._files.items())):
805 self._files.items())):
806 if p in self._files:
806 if p in self._files:
807 yield self._subpath(p), n, self._flags.get(p, '')
807 yield self._subpath(p), n, self._flags.get(p, '')
808 else:
808 else:
809 for x in n.iterentries():
809 for x in n.iterentries():
810 yield x
810 yield x
811
811
812 def items(self):
812 def items(self):
813 self._load()
813 self._load()
814 self._loadalllazy()
814 self._loadalllazy()
815 for p, n in sorted(itertools.chain(self._dirs.items(),
815 for p, n in sorted(itertools.chain(self._dirs.items(),
816 self._files.items())):
816 self._files.items())):
817 if p in self._files:
817 if p in self._files:
818 yield self._subpath(p), n
818 yield self._subpath(p), n
819 else:
819 else:
820 for f, sn in n.iteritems():
820 for f, sn in n.iteritems():
821 yield f, sn
821 yield f, sn
822
822
823 iteritems = items
823 iteritems = items
824
824
825 def iterkeys(self):
825 def iterkeys(self):
826 self._load()
826 self._load()
827 self._loadalllazy()
827 self._loadalllazy()
828 for p in sorted(itertools.chain(self._dirs, self._files)):
828 for p in sorted(itertools.chain(self._dirs, self._files)):
829 if p in self._files:
829 if p in self._files:
830 yield self._subpath(p)
830 yield self._subpath(p)
831 else:
831 else:
832 for f in self._dirs[p]:
832 for f in self._dirs[p]:
833 yield f
833 yield f
834
834
835 def keys(self):
835 def keys(self):
836 return list(self.iterkeys())
836 return list(self.iterkeys())
837
837
838 def __iter__(self):
838 def __iter__(self):
839 return self.iterkeys()
839 return self.iterkeys()
840
840
841 def __contains__(self, f):
841 def __contains__(self, f):
842 if f is None:
842 if f is None:
843 return False
843 return False
844 self._load()
844 self._load()
845 dir, subpath = _splittopdir(f)
845 dir, subpath = _splittopdir(f)
846 if dir:
846 if dir:
847 self._loadlazy(dir)
847 self._loadlazy(dir)
848
848
849 if dir not in self._dirs:
849 if dir not in self._dirs:
850 return False
850 return False
851
851
852 return self._dirs[dir].__contains__(subpath)
852 return self._dirs[dir].__contains__(subpath)
853 else:
853 else:
854 return f in self._files
854 return f in self._files
855
855
856 def get(self, f, default=None):
856 def get(self, f, default=None):
857 self._load()
857 self._load()
858 dir, subpath = _splittopdir(f)
858 dir, subpath = _splittopdir(f)
859 if dir:
859 if dir:
860 self._loadlazy(dir)
860 self._loadlazy(dir)
861
861
862 if dir not in self._dirs:
862 if dir not in self._dirs:
863 return default
863 return default
864 return self._dirs[dir].get(subpath, default)
864 return self._dirs[dir].get(subpath, default)
865 else:
865 else:
866 return self._files.get(f, default)
866 return self._files.get(f, default)
867
867
868 def __getitem__(self, f):
868 def __getitem__(self, f):
869 self._load()
869 self._load()
870 dir, subpath = _splittopdir(f)
870 dir, subpath = _splittopdir(f)
871 if dir:
871 if dir:
872 self._loadlazy(dir)
872 self._loadlazy(dir)
873
873
874 return self._dirs[dir].__getitem__(subpath)
874 return self._dirs[dir].__getitem__(subpath)
875 else:
875 else:
876 return self._files[f]
876 return self._files[f]
877
877
878 def flags(self, f):
878 def flags(self, f):
879 self._load()
879 self._load()
880 dir, subpath = _splittopdir(f)
880 dir, subpath = _splittopdir(f)
881 if dir:
881 if dir:
882 self._loadlazy(dir)
882 self._loadlazy(dir)
883
883
884 if dir not in self._dirs:
884 if dir not in self._dirs:
885 return ''
885 return ''
886 return self._dirs[dir].flags(subpath)
886 return self._dirs[dir].flags(subpath)
887 else:
887 else:
888 if f in self._lazydirs or f in self._dirs:
888 if f in self._lazydirs or f in self._dirs:
889 return ''
889 return ''
890 return self._flags.get(f, '')
890 return self._flags.get(f, '')
891
891
892 def find(self, f):
892 def find(self, f):
893 self._load()
893 self._load()
894 dir, subpath = _splittopdir(f)
894 dir, subpath = _splittopdir(f)
895 if dir:
895 if dir:
896 self._loadlazy(dir)
896 self._loadlazy(dir)
897
897
898 return self._dirs[dir].find(subpath)
898 return self._dirs[dir].find(subpath)
899 else:
899 else:
900 return self._files[f], self._flags.get(f, '')
900 return self._files[f], self._flags.get(f, '')
901
901
902 def __delitem__(self, f):
902 def __delitem__(self, f):
903 self._load()
903 self._load()
904 dir, subpath = _splittopdir(f)
904 dir, subpath = _splittopdir(f)
905 if dir:
905 if dir:
906 self._loadlazy(dir)
906 self._loadlazy(dir)
907
907
908 self._dirs[dir].__delitem__(subpath)
908 self._dirs[dir].__delitem__(subpath)
909 # If the directory is now empty, remove it
909 # If the directory is now empty, remove it
910 if self._dirs[dir]._isempty():
910 if self._dirs[dir]._isempty():
911 del self._dirs[dir]
911 del self._dirs[dir]
912 else:
912 else:
913 del self._files[f]
913 del self._files[f]
914 if f in self._flags:
914 if f in self._flags:
915 del self._flags[f]
915 del self._flags[f]
916 self._dirty = True
916 self._dirty = True
917
917
918 def __setitem__(self, f, n):
918 def __setitem__(self, f, n):
919 assert n is not None
919 assert n is not None
920 self._load()
920 self._load()
921 dir, subpath = _splittopdir(f)
921 dir, subpath = _splittopdir(f)
922 if dir:
922 if dir:
923 self._loadlazy(dir)
923 self._loadlazy(dir)
924 if dir not in self._dirs:
924 if dir not in self._dirs:
925 self._dirs[dir] = treemanifest(self._subpath(dir))
925 self._dirs[dir] = treemanifest(self._subpath(dir))
926 self._dirs[dir].__setitem__(subpath, n)
926 self._dirs[dir].__setitem__(subpath, n)
927 else:
927 else:
928 self._files[f] = n[:21] # to match manifestdict's behavior
928 self._files[f] = n[:21] # to match manifestdict's behavior
929 self._dirty = True
929 self._dirty = True
930
930
931 def _load(self):
931 def _load(self):
932 if self._loadfunc is not _noop:
932 if self._loadfunc is not _noop:
933 lf, self._loadfunc = self._loadfunc, _noop
933 lf, self._loadfunc = self._loadfunc, _noop
934 lf(self)
934 lf(self)
935 elif self._copyfunc is not _noop:
935 elif self._copyfunc is not _noop:
936 cf, self._copyfunc = self._copyfunc, _noop
936 cf, self._copyfunc = self._copyfunc, _noop
937 cf(self)
937 cf(self)
938
938
939 def setflag(self, f, flags):
939 def setflag(self, f, flags):
940 """Set the flags (symlink, executable) for path f."""
940 """Set the flags (symlink, executable) for path f."""
941 self._load()
941 self._load()
942 dir, subpath = _splittopdir(f)
942 dir, subpath = _splittopdir(f)
943 if dir:
943 if dir:
944 self._loadlazy(dir)
944 self._loadlazy(dir)
945 if dir not in self._dirs:
945 if dir not in self._dirs:
946 self._dirs[dir] = treemanifest(self._subpath(dir))
946 self._dirs[dir] = treemanifest(self._subpath(dir))
947 self._dirs[dir].setflag(subpath, flags)
947 self._dirs[dir].setflag(subpath, flags)
948 else:
948 else:
949 self._flags[f] = flags
949 self._flags[f] = flags
950 self._dirty = True
950 self._dirty = True
951
951
952 def copy(self):
952 def copy(self):
953 copy = treemanifest(self._dir)
953 copy = treemanifest(self._dir)
954 copy._node = self._node
954 copy._node = self._node
955 copy._dirty = self._dirty
955 copy._dirty = self._dirty
956 if self._copyfunc is _noop:
956 if self._copyfunc is _noop:
957 def _copyfunc(s):
957 def _copyfunc(s):
958 self._load()
958 self._load()
959 s._lazydirs = {d: (p, n, r, True) for
959 s._lazydirs = {d: (p, n, r, True) for
960 d, (p, n, r, c) in self._lazydirs.iteritems()}
960 d, (p, n, r, c) in self._lazydirs.iteritems()}
961 sdirs = s._dirs
961 sdirs = s._dirs
962 for d, v in self._dirs.iteritems():
962 for d, v in self._dirs.iteritems():
963 sdirs[d] = v.copy()
963 sdirs[d] = v.copy()
964 s._files = dict.copy(self._files)
964 s._files = dict.copy(self._files)
965 s._flags = dict.copy(self._flags)
965 s._flags = dict.copy(self._flags)
966 if self._loadfunc is _noop:
966 if self._loadfunc is _noop:
967 _copyfunc(copy)
967 _copyfunc(copy)
968 else:
968 else:
969 copy._copyfunc = _copyfunc
969 copy._copyfunc = _copyfunc
970 else:
970 else:
971 copy._copyfunc = self._copyfunc
971 copy._copyfunc = self._copyfunc
972 return copy
972 return copy
973
973
974 def filesnotin(self, m2, match=None):
974 def filesnotin(self, m2, match=None):
975 '''Set of files in this manifest that are not in the other'''
975 '''Set of files in this manifest that are not in the other'''
976 if match and not match.always():
976 if match and not match.always():
977 m1 = self.matches(match)
977 m1 = self.matches(match)
978 m2 = m2.matches(match)
978 m2 = m2.matches(match)
979 return m1.filesnotin(m2)
979 return m1.filesnotin(m2)
980
980
981 files = set()
981 files = set()
982 def _filesnotin(t1, t2):
982 def _filesnotin(t1, t2):
983 if t1._node == t2._node and not t1._dirty and not t2._dirty:
983 if t1._node == t2._node and not t1._dirty and not t2._dirty:
984 return
984 return
985 t1._load()
985 t1._load()
986 t2._load()
986 t2._load()
987 self._loaddifflazy(t1, t2)
987 self._loaddifflazy(t1, t2)
988 for d, m1 in t1._dirs.iteritems():
988 for d, m1 in t1._dirs.iteritems():
989 if d in t2._dirs:
989 if d in t2._dirs:
990 m2 = t2._dirs[d]
990 m2 = t2._dirs[d]
991 _filesnotin(m1, m2)
991 _filesnotin(m1, m2)
992 else:
992 else:
993 files.update(m1.iterkeys())
993 files.update(m1.iterkeys())
994
994
995 for fn in t1._files:
995 for fn in t1._files:
996 if fn not in t2._files:
996 if fn not in t2._files:
997 files.add(t1._subpath(fn))
997 files.add(t1._subpath(fn))
998
998
999 _filesnotin(self, m2)
999 _filesnotin(self, m2)
1000 return files
1000 return files
1001
1001
1002 @propertycache
1002 @propertycache
1003 def _alldirs(self):
1003 def _alldirs(self):
1004 return util.dirs(self)
1004 return util.dirs(self)
1005
1005
1006 def dirs(self):
1006 def dirs(self):
1007 return self._alldirs
1007 return self._alldirs
1008
1008
1009 def hasdir(self, dir):
1009 def hasdir(self, dir):
1010 self._load()
1010 self._load()
1011 topdir, subdir = _splittopdir(dir)
1011 topdir, subdir = _splittopdir(dir)
1012 if topdir:
1012 if topdir:
1013 self._loadlazy(topdir)
1013 self._loadlazy(topdir)
1014 if topdir in self._dirs:
1014 if topdir in self._dirs:
1015 return self._dirs[topdir].hasdir(subdir)
1015 return self._dirs[topdir].hasdir(subdir)
1016 return False
1016 return False
1017 dirslash = dir + '/'
1017 dirslash = dir + '/'
1018 return dirslash in self._dirs or dirslash in self._lazydirs
1018 return dirslash in self._dirs or dirslash in self._lazydirs
1019
1019
1020 def walk(self, match):
1020 def walk(self, match):
1021 '''Generates matching file names.
1021 '''Generates matching file names.
1022
1022
1023 Equivalent to manifest.matches(match).iterkeys(), but without creating
1023 Equivalent to manifest.matches(match).iterkeys(), but without creating
1024 an entirely new manifest.
1024 an entirely new manifest.
1025
1025
1026 It also reports nonexistent files by marking them bad with match.bad().
1026 It also reports nonexistent files by marking them bad with match.bad().
1027 '''
1027 '''
1028 if match.always():
1028 if match.always():
1029 for f in iter(self):
1029 for f in iter(self):
1030 yield f
1030 yield f
1031 return
1031 return
1032
1032
1033 fset = set(match.files())
1033 fset = set(match.files())
1034
1034
1035 for fn in self._walk(match):
1035 for fn in self._walk(match):
1036 if fn in fset:
1036 if fn in fset:
1037 # specified pattern is the exact name
1037 # specified pattern is the exact name
1038 fset.remove(fn)
1038 fset.remove(fn)
1039 yield fn
1039 yield fn
1040
1040
1041 # for dirstate.walk, files=['.'] means "walk the whole tree".
1041 # for dirstate.walk, files=['.'] means "walk the whole tree".
1042 # follow that here, too
1042 # follow that here, too
1043 fset.discard('.')
1043 fset.discard('.')
1044
1044
1045 for fn in sorted(fset):
1045 for fn in sorted(fset):
1046 if not self.hasdir(fn):
1046 if not self.hasdir(fn):
1047 match.bad(fn, None)
1047 match.bad(fn, None)
1048
1048
1049 def _walk(self, match):
1049 def _walk(self, match):
1050 '''Recursively generates matching file names for walk().'''
1050 '''Recursively generates matching file names for walk().'''
1051 visit = match.visitchildrenset(self._dir[:-1] or '.')
1051 visit = match.visitchildrenset(self._dir[:-1] or '.')
1052 if not visit:
1052 if not visit:
1053 return
1053 return
1054
1054
1055 # yield this dir's files and walk its submanifests
1055 # yield this dir's files and walk its submanifests
1056 self._load()
1056 self._load()
1057 visit = self._loadchildrensetlazy(visit)
1057 visit = self._loadchildrensetlazy(visit)
1058 for p in sorted(list(self._dirs) + list(self._files)):
1058 for p in sorted(list(self._dirs) + list(self._files)):
1059 if p in self._files:
1059 if p in self._files:
1060 fullp = self._subpath(p)
1060 fullp = self._subpath(p)
1061 if match(fullp):
1061 if match(fullp):
1062 yield fullp
1062 yield fullp
1063 else:
1063 else:
1064 if not visit or p[:-1] in visit:
1064 if not visit or p[:-1] in visit:
1065 for f in self._dirs[p]._walk(match):
1065 for f in self._dirs[p]._walk(match):
1066 yield f
1066 yield f
1067
1067
1068 def matches(self, match):
1068 def matches(self, match):
1069 '''generate a new manifest filtered by the match argument'''
1069 '''generate a new manifest filtered by the match argument'''
1070 if match.always():
1070 if match.always():
1071 return self.copy()
1071 return self.copy()
1072
1072
1073 return self._matches(match)
1073 return self._matches(match)
1074
1074
1075 def _matches(self, match):
1075 def _matches(self, match):
1076 '''recursively generate a new manifest filtered by the match argument.
1076 '''recursively generate a new manifest filtered by the match argument.
1077 '''
1077 '''
1078
1078
1079 visit = match.visitchildrenset(self._dir[:-1] or '.')
1079 visit = match.visitchildrenset(self._dir[:-1] or '.')
1080 if visit == 'all':
1080 if visit == 'all':
1081 return self.copy()
1081 return self.copy()
1082 ret = treemanifest(self._dir)
1082 ret = treemanifest(self._dir)
1083 if not visit:
1083 if not visit:
1084 return ret
1084 return ret
1085
1085
1086 self._load()
1086 self._load()
1087 for fn in self._files:
1087 for fn in self._files:
1088 # While visitchildrenset *usually* lists only subdirs, this is
1088 # While visitchildrenset *usually* lists only subdirs, this is
1089 # actually up to the matcher and may have some files in the set().
1089 # actually up to the matcher and may have some files in the set().
1090 # If visit == 'this', we should obviously look at the files in this
1090 # If visit == 'this', we should obviously look at the files in this
1091 # directory; if visit is a set, and fn is in it, we should inspect
1091 # directory; if visit is a set, and fn is in it, we should inspect
1092 # fn (but no need to inspect things not in the set).
1092 # fn (but no need to inspect things not in the set).
1093 if visit != 'this' and fn not in visit:
1093 if visit != 'this' and fn not in visit:
1094 continue
1094 continue
1095 fullp = self._subpath(fn)
1095 fullp = self._subpath(fn)
1096 # visitchildrenset isn't perfect, we still need to call the regular
1096 # visitchildrenset isn't perfect, we still need to call the regular
1097 # matcher code to further filter results.
1097 # matcher code to further filter results.
1098 if not match(fullp):
1098 if not match(fullp):
1099 continue
1099 continue
1100 ret._files[fn] = self._files[fn]
1100 ret._files[fn] = self._files[fn]
1101 if fn in self._flags:
1101 if fn in self._flags:
1102 ret._flags[fn] = self._flags[fn]
1102 ret._flags[fn] = self._flags[fn]
1103
1103
1104 visit = self._loadchildrensetlazy(visit)
1104 visit = self._loadchildrensetlazy(visit)
1105 for dir, subm in self._dirs.iteritems():
1105 for dir, subm in self._dirs.iteritems():
1106 if visit and dir[:-1] not in visit:
1106 if visit and dir[:-1] not in visit:
1107 continue
1107 continue
1108 m = subm._matches(match)
1108 m = subm._matches(match)
1109 if not m._isempty():
1109 if not m._isempty():
1110 ret._dirs[dir] = m
1110 ret._dirs[dir] = m
1111
1111
1112 if not ret._isempty():
1112 if not ret._isempty():
1113 ret._dirty = True
1113 ret._dirty = True
1114 return ret
1114 return ret
1115
1115
1116 def diff(self, m2, match=None, clean=False):
1116 def diff(self, m2, match=None, clean=False):
1117 '''Finds changes between the current manifest and m2.
1117 '''Finds changes between the current manifest and m2.
1118
1118
1119 Args:
1119 Args:
1120 m2: the manifest to which this manifest should be compared.
1120 m2: the manifest to which this manifest should be compared.
1121 clean: if true, include files unchanged between these manifests
1121 clean: if true, include files unchanged between these manifests
1122 with a None value in the returned dictionary.
1122 with a None value in the returned dictionary.
1123
1123
1124 The result is returned as a dict with filename as key and
1124 The result is returned as a dict with filename as key and
1125 values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the
1125 values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the
1126 nodeid in the current/other manifest and fl1/fl2 is the flag
1126 nodeid in the current/other manifest and fl1/fl2 is the flag
1127 in the current/other manifest. Where the file does not exist,
1127 in the current/other manifest. Where the file does not exist,
1128 the nodeid will be None and the flags will be the empty
1128 the nodeid will be None and the flags will be the empty
1129 string.
1129 string.
1130 '''
1130 '''
1131 if match and not match.always():
1131 if match and not match.always():
1132 m1 = self.matches(match)
1132 m1 = self.matches(match)
1133 m2 = m2.matches(match)
1133 m2 = m2.matches(match)
1134 return m1.diff(m2, clean=clean)
1134 return m1.diff(m2, clean=clean)
1135 result = {}
1135 result = {}
1136 emptytree = treemanifest()
1136 emptytree = treemanifest()
1137
1137
1138 def _iterativediff(t1, t2, stack):
1138 def _iterativediff(t1, t2, stack):
1139 """compares two tree manifests and append new tree-manifests which
1139 """compares two tree manifests and append new tree-manifests which
1140 needs to be compared to stack"""
1140 needs to be compared to stack"""
1141 if t1._node == t2._node and not t1._dirty and not t2._dirty:
1141 if t1._node == t2._node and not t1._dirty and not t2._dirty:
1142 return
1142 return
1143 t1._load()
1143 t1._load()
1144 t2._load()
1144 t2._load()
1145 self._loaddifflazy(t1, t2)
1145 self._loaddifflazy(t1, t2)
1146
1146
1147 for d, m1 in t1._dirs.iteritems():
1147 for d, m1 in t1._dirs.iteritems():
1148 m2 = t2._dirs.get(d, emptytree)
1148 m2 = t2._dirs.get(d, emptytree)
1149 stack.append((m1, m2))
1149 stack.append((m1, m2))
1150
1150
1151 for d, m2 in t2._dirs.iteritems():
1151 for d, m2 in t2._dirs.iteritems():
1152 if d not in t1._dirs:
1152 if d not in t1._dirs:
1153 stack.append((emptytree, m2))
1153 stack.append((emptytree, m2))
1154
1154
1155 for fn, n1 in t1._files.iteritems():
1155 for fn, n1 in t1._files.iteritems():
1156 fl1 = t1._flags.get(fn, '')
1156 fl1 = t1._flags.get(fn, '')
1157 n2 = t2._files.get(fn, None)
1157 n2 = t2._files.get(fn, None)
1158 fl2 = t2._flags.get(fn, '')
1158 fl2 = t2._flags.get(fn, '')
1159 if n1 != n2 or fl1 != fl2:
1159 if n1 != n2 or fl1 != fl2:
1160 result[t1._subpath(fn)] = ((n1, fl1), (n2, fl2))
1160 result[t1._subpath(fn)] = ((n1, fl1), (n2, fl2))
1161 elif clean:
1161 elif clean:
1162 result[t1._subpath(fn)] = None
1162 result[t1._subpath(fn)] = None
1163
1163
1164 for fn, n2 in t2._files.iteritems():
1164 for fn, n2 in t2._files.iteritems():
1165 if fn not in t1._files:
1165 if fn not in t1._files:
1166 fl2 = t2._flags.get(fn, '')
1166 fl2 = t2._flags.get(fn, '')
1167 result[t2._subpath(fn)] = ((None, ''), (n2, fl2))
1167 result[t2._subpath(fn)] = ((None, ''), (n2, fl2))
1168
1168
1169 stackls = []
1169 stackls = []
1170 _iterativediff(self, m2, stackls)
1170 _iterativediff(self, m2, stackls)
1171 while stackls:
1171 while stackls:
1172 t1, t2 = stackls.pop()
1172 t1, t2 = stackls.pop()
1173 # stackls is populated in the function call
1173 # stackls is populated in the function call
1174 _iterativediff(t1, t2, stackls)
1174 _iterativediff(t1, t2, stackls)
1175 return result
1175 return result
1176
1176
1177 def unmodifiedsince(self, m2):
1177 def unmodifiedsince(self, m2):
1178 return not self._dirty and not m2._dirty and self._node == m2._node
1178 return not self._dirty and not m2._dirty and self._node == m2._node
1179
1179
1180 def parse(self, text, readsubtree):
1180 def parse(self, text, readsubtree):
1181 selflazy = self._lazydirs
1181 selflazy = self._lazydirs
1182 subpath = self._subpath
1182 subpath = self._subpath
1183 for f, n, fl in _parse(text):
1183 for f, n, fl in _parse(text):
1184 if fl == 't':
1184 if fl == 't':
1185 f = f + '/'
1185 f = f + '/'
1186 # False below means "doesn't need to be copied" and can use the
1186 # False below means "doesn't need to be copied" and can use the
1187 # cached value from readsubtree directly.
1187 # cached value from readsubtree directly.
1188 selflazy[f] = (subpath(f), n, readsubtree, False)
1188 selflazy[f] = (subpath(f), n, readsubtree, False)
1189 elif '/' in f:
1189 elif '/' in f:
1190 # This is a flat manifest, so use __setitem__ and setflag rather
1190 # This is a flat manifest, so use __setitem__ and setflag rather
1191 # than assigning directly to _files and _flags, so we can
1191 # than assigning directly to _files and _flags, so we can
1192 # assign a path in a subdirectory, and to mark dirty (compared
1192 # assign a path in a subdirectory, and to mark dirty (compared
1193 # to nullid).
1193 # to nullid).
1194 self[f] = n
1194 self[f] = n
1195 if fl:
1195 if fl:
1196 self.setflag(f, fl)
1196 self.setflag(f, fl)
1197 else:
1197 else:
1198 # Assigning to _files and _flags avoids marking as dirty,
1198 # Assigning to _files and _flags avoids marking as dirty,
1199 # and should be a little faster.
1199 # and should be a little faster.
1200 self._files[f] = n
1200 self._files[f] = n
1201 if fl:
1201 if fl:
1202 self._flags[f] = fl
1202 self._flags[f] = fl
1203
1203
1204 def text(self):
1204 def text(self):
1205 """Get the full data of this manifest as a bytestring."""
1205 """Get the full data of this manifest as a bytestring."""
1206 self._load()
1206 self._load()
1207 return _text(self.iterentries())
1207 return _text(self.iterentries())
1208
1208
1209 def dirtext(self):
1209 def dirtext(self):
1210 """Get the full data of this directory as a bytestring. Make sure that
1210 """Get the full data of this directory as a bytestring. Make sure that
1211 any submanifests have been written first, so their nodeids are correct.
1211 any submanifests have been written first, so their nodeids are correct.
1212 """
1212 """
1213 self._load()
1213 self._load()
1214 flags = self.flags
1214 flags = self.flags
1215 lazydirs = [(d[:-1], v[1], 't') for d, v in self._lazydirs.iteritems()]
1215 lazydirs = [(d[:-1], v[1], 't') for d, v in self._lazydirs.iteritems()]
1216 dirs = [(d[:-1], self._dirs[d]._node, 't') for d in self._dirs]
1216 dirs = [(d[:-1], self._dirs[d]._node, 't') for d in self._dirs]
1217 files = [(f, self._files[f], flags(f)) for f in self._files]
1217 files = [(f, self._files[f], flags(f)) for f in self._files]
1218 return _text(sorted(dirs + files + lazydirs))
1218 return _text(sorted(dirs + files + lazydirs))
1219
1219
1220 def read(self, gettext, readsubtree):
1220 def read(self, gettext, readsubtree):
1221 def _load_for_read(s):
1221 def _load_for_read(s):
1222 s.parse(gettext(), readsubtree)
1222 s.parse(gettext(), readsubtree)
1223 s._dirty = False
1223 s._dirty = False
1224 self._loadfunc = _load_for_read
1224 self._loadfunc = _load_for_read
1225
1225
1226 def writesubtrees(self, m1, m2, writesubtree, match):
1226 def writesubtrees(self, m1, m2, writesubtree, match):
1227 self._load() # for consistency; should never have any effect here
1227 self._load() # for consistency; should never have any effect here
1228 m1._load()
1228 m1._load()
1229 m2._load()
1229 m2._load()
1230 emptytree = treemanifest()
1230 emptytree = treemanifest()
1231 def getnode(m, d):
1231 def getnode(m, d):
1232 ld = m._lazydirs.get(d)
1232 ld = m._lazydirs.get(d)
1233 if ld:
1233 if ld:
1234 return ld[1]
1234 return ld[1]
1235 return m._dirs.get(d, emptytree)._node
1235 return m._dirs.get(d, emptytree)._node
1236
1236
1237 # let's skip investigating things that `match` says we do not need.
1237 # let's skip investigating things that `match` says we do not need.
1238 visit = match.visitchildrenset(self._dir[:-1] or '.')
1238 visit = match.visitchildrenset(self._dir[:-1] or '.')
1239 visit = self._loadchildrensetlazy(visit)
1239 visit = self._loadchildrensetlazy(visit)
1240 if visit == 'this' or visit == 'all':
1240 if visit == 'this' or visit == 'all':
1241 visit = None
1241 visit = None
1242 for d, subm in self._dirs.iteritems():
1242 for d, subm in self._dirs.iteritems():
1243 if visit and d[:-1] not in visit:
1243 if visit and d[:-1] not in visit:
1244 continue
1244 continue
1245 subp1 = getnode(m1, d)
1245 subp1 = getnode(m1, d)
1246 subp2 = getnode(m2, d)
1246 subp2 = getnode(m2, d)
1247 if subp1 == nullid:
1247 if subp1 == nullid:
1248 subp1, subp2 = subp2, subp1
1248 subp1, subp2 = subp2, subp1
1249 writesubtree(subm, subp1, subp2, match)
1249 writesubtree(subm, subp1, subp2, match)
1250
1250
1251 def walksubtrees(self, matcher=None):
1251 def walksubtrees(self, matcher=None):
1252 """Returns an iterator of the subtrees of this manifest, including this
1252 """Returns an iterator of the subtrees of this manifest, including this
1253 manifest itself.
1253 manifest itself.
1254
1254
1255 If `matcher` is provided, it only returns subtrees that match.
1255 If `matcher` is provided, it only returns subtrees that match.
1256 """
1256 """
1257 if matcher and not matcher.visitdir(self._dir[:-1] or '.'):
1257 if matcher and not matcher.visitdir(self._dir[:-1] or '.'):
1258 return
1258 return
1259 if not matcher or matcher(self._dir[:-1]):
1259 if not matcher or matcher(self._dir[:-1]):
1260 yield self
1260 yield self
1261
1261
1262 self._load()
1262 self._load()
1263 # OPT: use visitchildrenset to avoid loading everything.
1263 # OPT: use visitchildrenset to avoid loading everything.
1264 self._loadalllazy()
1264 self._loadalllazy()
1265 for d, subm in self._dirs.iteritems():
1265 for d, subm in self._dirs.iteritems():
1266 for subtree in subm.walksubtrees(matcher=matcher):
1266 for subtree in subm.walksubtrees(matcher=matcher):
1267 yield subtree
1267 yield subtree
1268
1268
1269 class manifestfulltextcache(util.lrucachedict):
1269 class manifestfulltextcache(util.lrucachedict):
1270 """File-backed LRU cache for the manifest cache
1270 """File-backed LRU cache for the manifest cache
1271
1271
1272 File consists of entries, up to EOF:
1272 File consists of entries, up to EOF:
1273
1273
1274 - 20 bytes node, 4 bytes length, <length> manifest data
1274 - 20 bytes node, 4 bytes length, <length> manifest data
1275
1275
1276 These are written in reverse cache order (oldest to newest).
1276 These are written in reverse cache order (oldest to newest).
1277
1277
1278 """
1278 """
1279
1279
1280 _file = 'manifestfulltextcache'
1280 _file = 'manifestfulltextcache'
1281
1281
1282 def __init__(self, max):
1282 def __init__(self, max):
1283 super(manifestfulltextcache, self).__init__(max)
1283 super(manifestfulltextcache, self).__init__(max)
1284 self._dirty = False
1284 self._dirty = False
1285 self._read = False
1285 self._read = False
1286 self._opener = None
1286 self._opener = None
1287
1287
1288 def read(self):
1288 def read(self):
1289 if self._read or self._opener is None:
1289 if self._read or self._opener is None:
1290 return
1290 return
1291
1291
1292 try:
1292 try:
1293 with self._opener(self._file) as fp:
1293 with self._opener(self._file) as fp:
1294 set = super(manifestfulltextcache, self).__setitem__
1294 set = super(manifestfulltextcache, self).__setitem__
1295 # ignore trailing data, this is a cache, corruption is skipped
1295 # ignore trailing data, this is a cache, corruption is skipped
1296 while True:
1296 while True:
1297 node = fp.read(20)
1297 node = fp.read(20)
1298 if len(node) < 20:
1298 if len(node) < 20:
1299 break
1299 break
1300 try:
1300 try:
1301 size = struct.unpack('>L', fp.read(4))[0]
1301 size = struct.unpack('>L', fp.read(4))[0]
1302 except struct.error:
1302 except struct.error:
1303 break
1303 break
1304 value = bytearray(fp.read(size))
1304 value = bytearray(fp.read(size))
1305 if len(value) != size:
1305 if len(value) != size:
1306 break
1306 break
1307 set(node, value)
1307 set(node, value)
1308 except IOError:
1308 except IOError:
1309 # the file is allowed to be missing
1309 # the file is allowed to be missing
1310 pass
1310 pass
1311
1311
1312 self._read = True
1312 self._read = True
1313 self._dirty = False
1313 self._dirty = False
1314
1314
1315 def write(self):
1315 def write(self):
1316 if not self._dirty or self._opener is None:
1316 if not self._dirty or self._opener is None:
1317 return
1317 return
1318 # rotate backwards to the first used node
1318 # rotate backwards to the first used node
1319 with self._opener(self._file, 'w', atomictemp=True, checkambig=True
1319 with self._opener(self._file, 'w', atomictemp=True, checkambig=True
1320 ) as fp:
1320 ) as fp:
1321 node = self._head.prev
1321 node = self._head.prev
1322 while True:
1322 while True:
1323 if node.key in self._cache:
1323 if node.key in self._cache:
1324 fp.write(node.key)
1324 fp.write(node.key)
1325 fp.write(struct.pack('>L', len(node.value)))
1325 fp.write(struct.pack('>L', len(node.value)))
1326 fp.write(node.value)
1326 fp.write(node.value)
1327 if node is self._head:
1327 if node is self._head:
1328 break
1328 break
1329 node = node.prev
1329 node = node.prev
1330
1330
1331 def __len__(self):
1331 def __len__(self):
1332 if not self._read:
1332 if not self._read:
1333 self.read()
1333 self.read()
1334 return super(manifestfulltextcache, self).__len__()
1334 return super(manifestfulltextcache, self).__len__()
1335
1335
1336 def __contains__(self, k):
1336 def __contains__(self, k):
1337 if not self._read:
1337 if not self._read:
1338 self.read()
1338 self.read()
1339 return super(manifestfulltextcache, self).__contains__(k)
1339 return super(manifestfulltextcache, self).__contains__(k)
1340
1340
1341 def __iter__(self):
1341 def __iter__(self):
1342 if not self._read:
1342 if not self._read:
1343 self.read()
1343 self.read()
1344 return super(manifestfulltextcache, self).__iter__()
1344 return super(manifestfulltextcache, self).__iter__()
1345
1345
1346 def __getitem__(self, k):
1346 def __getitem__(self, k):
1347 if not self._read:
1347 if not self._read:
1348 self.read()
1348 self.read()
1349 # the cache lru order can change on read
1349 # the cache lru order can change on read
1350 setdirty = self._cache.get(k) is not self._head
1350 setdirty = self._cache.get(k) is not self._head
1351 value = super(manifestfulltextcache, self).__getitem__(k)
1351 value = super(manifestfulltextcache, self).__getitem__(k)
1352 if setdirty:
1352 if setdirty:
1353 self._dirty = True
1353 self._dirty = True
1354 return value
1354 return value
1355
1355
1356 def __setitem__(self, k, v):
1356 def __setitem__(self, k, v):
1357 if not self._read:
1357 if not self._read:
1358 self.read()
1358 self.read()
1359 super(manifestfulltextcache, self).__setitem__(k, v)
1359 super(manifestfulltextcache, self).__setitem__(k, v)
1360 self._dirty = True
1360 self._dirty = True
1361
1361
1362 def __delitem__(self, k):
1362 def __delitem__(self, k):
1363 if not self._read:
1363 if not self._read:
1364 self.read()
1364 self.read()
1365 super(manifestfulltextcache, self).__delitem__(k)
1365 super(manifestfulltextcache, self).__delitem__(k)
1366 self._dirty = True
1366 self._dirty = True
1367
1367
1368 def get(self, k, default=None):
1368 def get(self, k, default=None):
1369 if not self._read:
1369 if not self._read:
1370 self.read()
1370 self.read()
1371 return super(manifestfulltextcache, self).get(k, default=default)
1371 return super(manifestfulltextcache, self).get(k, default=default)
1372
1372
1373 def clear(self, clear_persisted_data=False):
1373 def clear(self, clear_persisted_data=False):
1374 super(manifestfulltextcache, self).clear()
1374 super(manifestfulltextcache, self).clear()
1375 if clear_persisted_data:
1375 if clear_persisted_data:
1376 self._dirty = True
1376 self._dirty = True
1377 self.write()
1377 self.write()
1378 self._read = False
1378 self._read = False
1379
1379
1380 @interfaceutil.implementer(repository.imanifeststorage)
1380 @interfaceutil.implementer(repository.imanifeststorage)
1381 class manifestrevlog(object):
1381 class manifestrevlog(object):
1382 '''A revlog that stores manifest texts. This is responsible for caching the
1382 '''A revlog that stores manifest texts. This is responsible for caching the
1383 full-text manifest contents.
1383 full-text manifest contents.
1384 '''
1384 '''
1385 def __init__(self, opener, tree='', dirlogcache=None, indexfile=None,
1385 def __init__(self, opener, tree='', dirlogcache=None, indexfile=None,
1386 treemanifest=False):
1386 treemanifest=False):
1387 """Constructs a new manifest revlog
1387 """Constructs a new manifest revlog
1388
1388
1389 `indexfile` - used by extensions to have two manifests at once, like
1389 `indexfile` - used by extensions to have two manifests at once, like
1390 when transitioning between flatmanifeset and treemanifests.
1390 when transitioning between flatmanifeset and treemanifests.
1391
1391
1392 `treemanifest` - used to indicate this is a tree manifest revlog. Opener
1392 `treemanifest` - used to indicate this is a tree manifest revlog. Opener
1393 options can also be used to make this a tree manifest revlog. The opener
1393 options can also be used to make this a tree manifest revlog. The opener
1394 option takes precedence, so if it is set to True, we ignore whatever
1394 option takes precedence, so if it is set to True, we ignore whatever
1395 value is passed in to the constructor.
1395 value is passed in to the constructor.
1396 """
1396 """
1397 # During normal operations, we expect to deal with not more than four
1397 # During normal operations, we expect to deal with not more than four
1398 # revs at a time (such as during commit --amend). When rebasing large
1398 # revs at a time (such as during commit --amend). When rebasing large
1399 # stacks of commits, the number can go up, hence the config knob below.
1399 # stacks of commits, the number can go up, hence the config knob below.
1400 cachesize = 4
1400 cachesize = 4
1401 optiontreemanifest = False
1401 optiontreemanifest = False
1402 opts = getattr(opener, 'options', None)
1402 opts = getattr(opener, 'options', None)
1403 if opts is not None:
1403 if opts is not None:
1404 cachesize = opts.get('manifestcachesize', cachesize)
1404 cachesize = opts.get('manifestcachesize', cachesize)
1405 optiontreemanifest = opts.get('treemanifest', False)
1405 optiontreemanifest = opts.get('treemanifest', False)
1406
1406
1407 self._treeondisk = optiontreemanifest or treemanifest
1407 self._treeondisk = optiontreemanifest or treemanifest
1408
1408
1409 self._fulltextcache = manifestfulltextcache(cachesize)
1409 self._fulltextcache = manifestfulltextcache(cachesize)
1410
1410
1411 if tree:
1411 if tree:
1412 assert self._treeondisk, 'opts is %r' % opts
1412 assert self._treeondisk, 'opts is %r' % opts
1413
1413
1414 if indexfile is None:
1414 if indexfile is None:
1415 indexfile = '00manifest.i'
1415 indexfile = '00manifest.i'
1416 if tree:
1416 if tree:
1417 indexfile = "meta/" + tree + indexfile
1417 indexfile = "meta/" + tree + indexfile
1418
1418
1419 self.tree = tree
1419 self.tree = tree
1420
1420
1421 # The dirlogcache is kept on the root manifest log
1421 # The dirlogcache is kept on the root manifest log
1422 if tree:
1422 if tree:
1423 self._dirlogcache = dirlogcache
1423 self._dirlogcache = dirlogcache
1424 else:
1424 else:
1425 self._dirlogcache = {'': self}
1425 self._dirlogcache = {'': self}
1426
1426
1427 self._revlog = revlog.revlog(opener, indexfile,
1427 self._revlog = revlog.revlog(opener, indexfile,
1428 # only root indexfile is cached
1428 # only root indexfile is cached
1429 checkambig=not bool(tree),
1429 checkambig=not bool(tree),
1430 mmaplargeindex=True)
1430 mmaplargeindex=True)
1431
1431
1432 self.index = self._revlog.index
1432 self.index = self._revlog.index
1433 self.version = self._revlog.version
1433 self.version = self._revlog.version
1434 self._generaldelta = self._revlog._generaldelta
1434 self._generaldelta = self._revlog._generaldelta
1435
1435
1436 def _setupmanifestcachehooks(self, repo):
1436 def _setupmanifestcachehooks(self, repo):
1437 """Persist the manifestfulltextcache on lock release"""
1437 """Persist the manifestfulltextcache on lock release"""
1438 if not util.safehasattr(repo, '_wlockref'):
1438 if not util.safehasattr(repo, '_wlockref'):
1439 return
1439 return
1440
1440
1441 self._fulltextcache._opener = repo.cachevfs
1441 self._fulltextcache._opener = repo.wcachevfs
1442 if repo._currentlock(repo._wlockref) is None:
1442 if repo._currentlock(repo._wlockref) is None:
1443 return
1443 return
1444
1444
1445 reporef = weakref.ref(repo)
1445 reporef = weakref.ref(repo)
1446 manifestrevlogref = weakref.ref(self)
1446 manifestrevlogref = weakref.ref(self)
1447
1447
1448 def persistmanifestcache():
1448 def persistmanifestcache():
1449 repo = reporef()
1449 repo = reporef()
1450 self = manifestrevlogref()
1450 self = manifestrevlogref()
1451 if repo is None or self is None:
1451 if repo is None or self is None:
1452 return
1452 return
1453 if repo.manifestlog.getstorage(b'') is not self:
1453 if repo.manifestlog.getstorage(b'') is not self:
1454 # there's a different manifest in play now, abort
1454 # there's a different manifest in play now, abort
1455 return
1455 return
1456 self._fulltextcache.write()
1456 self._fulltextcache.write()
1457
1457
1458 repo._afterlock(persistmanifestcache)
1458 repo._afterlock(persistmanifestcache)
1459
1459
1460 @property
1460 @property
1461 def fulltextcache(self):
1461 def fulltextcache(self):
1462 return self._fulltextcache
1462 return self._fulltextcache
1463
1463
1464 def clearcaches(self, clear_persisted_data=False):
1464 def clearcaches(self, clear_persisted_data=False):
1465 self._revlog.clearcaches()
1465 self._revlog.clearcaches()
1466 self._fulltextcache.clear(clear_persisted_data=clear_persisted_data)
1466 self._fulltextcache.clear(clear_persisted_data=clear_persisted_data)
1467 self._dirlogcache = {self.tree: self}
1467 self._dirlogcache = {self.tree: self}
1468
1468
1469 def dirlog(self, d):
1469 def dirlog(self, d):
1470 if d:
1470 if d:
1471 assert self._treeondisk
1471 assert self._treeondisk
1472 if d not in self._dirlogcache:
1472 if d not in self._dirlogcache:
1473 mfrevlog = manifestrevlog(self.opener, d,
1473 mfrevlog = manifestrevlog(self.opener, d,
1474 self._dirlogcache,
1474 self._dirlogcache,
1475 treemanifest=self._treeondisk)
1475 treemanifest=self._treeondisk)
1476 self._dirlogcache[d] = mfrevlog
1476 self._dirlogcache[d] = mfrevlog
1477 return self._dirlogcache[d]
1477 return self._dirlogcache[d]
1478
1478
1479 def add(self, m, transaction, link, p1, p2, added, removed, readtree=None,
1479 def add(self, m, transaction, link, p1, p2, added, removed, readtree=None,
1480 match=None):
1480 match=None):
1481 if p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta'):
1481 if p1 in self.fulltextcache and util.safehasattr(m, 'fastdelta'):
1482 # If our first parent is in the manifest cache, we can
1482 # If our first parent is in the manifest cache, we can
1483 # compute a delta here using properties we know about the
1483 # compute a delta here using properties we know about the
1484 # manifest up-front, which may save time later for the
1484 # manifest up-front, which may save time later for the
1485 # revlog layer.
1485 # revlog layer.
1486
1486
1487 _checkforbidden(added)
1487 _checkforbidden(added)
1488 # combine the changed lists into one sorted iterator
1488 # combine the changed lists into one sorted iterator
1489 work = heapq.merge([(x, False) for x in added],
1489 work = heapq.merge([(x, False) for x in added],
1490 [(x, True) for x in removed])
1490 [(x, True) for x in removed])
1491
1491
1492 arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
1492 arraytext, deltatext = m.fastdelta(self.fulltextcache[p1], work)
1493 cachedelta = self._revlog.rev(p1), deltatext
1493 cachedelta = self._revlog.rev(p1), deltatext
1494 text = util.buffer(arraytext)
1494 text = util.buffer(arraytext)
1495 n = self._revlog.addrevision(text, transaction, link, p1, p2,
1495 n = self._revlog.addrevision(text, transaction, link, p1, p2,
1496 cachedelta)
1496 cachedelta)
1497 else:
1497 else:
1498 # The first parent manifest isn't already loaded, so we'll
1498 # The first parent manifest isn't already loaded, so we'll
1499 # just encode a fulltext of the manifest and pass that
1499 # just encode a fulltext of the manifest and pass that
1500 # through to the revlog layer, and let it handle the delta
1500 # through to the revlog layer, and let it handle the delta
1501 # process.
1501 # process.
1502 if self._treeondisk:
1502 if self._treeondisk:
1503 assert readtree, "readtree must be set for treemanifest writes"
1503 assert readtree, "readtree must be set for treemanifest writes"
1504 assert match, "match must be specified for treemanifest writes"
1504 assert match, "match must be specified for treemanifest writes"
1505 m1 = readtree(self.tree, p1)
1505 m1 = readtree(self.tree, p1)
1506 m2 = readtree(self.tree, p2)
1506 m2 = readtree(self.tree, p2)
1507 n = self._addtree(m, transaction, link, m1, m2, readtree,
1507 n = self._addtree(m, transaction, link, m1, m2, readtree,
1508 match=match)
1508 match=match)
1509 arraytext = None
1509 arraytext = None
1510 else:
1510 else:
1511 text = m.text()
1511 text = m.text()
1512 n = self._revlog.addrevision(text, transaction, link, p1, p2)
1512 n = self._revlog.addrevision(text, transaction, link, p1, p2)
1513 arraytext = bytearray(text)
1513 arraytext = bytearray(text)
1514
1514
1515 if arraytext is not None:
1515 if arraytext is not None:
1516 self.fulltextcache[n] = arraytext
1516 self.fulltextcache[n] = arraytext
1517
1517
1518 return n
1518 return n
1519
1519
1520 def _addtree(self, m, transaction, link, m1, m2, readtree, match):
1520 def _addtree(self, m, transaction, link, m1, m2, readtree, match):
1521 # If the manifest is unchanged compared to one parent,
1521 # If the manifest is unchanged compared to one parent,
1522 # don't write a new revision
1522 # don't write a new revision
1523 if self.tree != '' and (m.unmodifiedsince(m1) or m.unmodifiedsince(
1523 if self.tree != '' and (m.unmodifiedsince(m1) or m.unmodifiedsince(
1524 m2)):
1524 m2)):
1525 return m.node()
1525 return m.node()
1526 def writesubtree(subm, subp1, subp2, match):
1526 def writesubtree(subm, subp1, subp2, match):
1527 sublog = self.dirlog(subm.dir())
1527 sublog = self.dirlog(subm.dir())
1528 sublog.add(subm, transaction, link, subp1, subp2, None, None,
1528 sublog.add(subm, transaction, link, subp1, subp2, None, None,
1529 readtree=readtree, match=match)
1529 readtree=readtree, match=match)
1530 m.writesubtrees(m1, m2, writesubtree, match)
1530 m.writesubtrees(m1, m2, writesubtree, match)
1531 text = m.dirtext()
1531 text = m.dirtext()
1532 n = None
1532 n = None
1533 if self.tree != '':
1533 if self.tree != '':
1534 # Double-check whether contents are unchanged to one parent
1534 # Double-check whether contents are unchanged to one parent
1535 if text == m1.dirtext():
1535 if text == m1.dirtext():
1536 n = m1.node()
1536 n = m1.node()
1537 elif text == m2.dirtext():
1537 elif text == m2.dirtext():
1538 n = m2.node()
1538 n = m2.node()
1539
1539
1540 if not n:
1540 if not n:
1541 n = self._revlog.addrevision(text, transaction, link, m1.node(),
1541 n = self._revlog.addrevision(text, transaction, link, m1.node(),
1542 m2.node())
1542 m2.node())
1543
1543
1544 # Save nodeid so parent manifest can calculate its nodeid
1544 # Save nodeid so parent manifest can calculate its nodeid
1545 m.setnode(n)
1545 m.setnode(n)
1546 return n
1546 return n
1547
1547
1548 def __len__(self):
1548 def __len__(self):
1549 return len(self._revlog)
1549 return len(self._revlog)
1550
1550
1551 def __iter__(self):
1551 def __iter__(self):
1552 return self._revlog.__iter__()
1552 return self._revlog.__iter__()
1553
1553
1554 def rev(self, node):
1554 def rev(self, node):
1555 return self._revlog.rev(node)
1555 return self._revlog.rev(node)
1556
1556
1557 def node(self, rev):
1557 def node(self, rev):
1558 return self._revlog.node(rev)
1558 return self._revlog.node(rev)
1559
1559
1560 def lookup(self, value):
1560 def lookup(self, value):
1561 return self._revlog.lookup(value)
1561 return self._revlog.lookup(value)
1562
1562
1563 def parentrevs(self, rev):
1563 def parentrevs(self, rev):
1564 return self._revlog.parentrevs(rev)
1564 return self._revlog.parentrevs(rev)
1565
1565
1566 def parents(self, node):
1566 def parents(self, node):
1567 return self._revlog.parents(node)
1567 return self._revlog.parents(node)
1568
1568
1569 def linkrev(self, rev):
1569 def linkrev(self, rev):
1570 return self._revlog.linkrev(rev)
1570 return self._revlog.linkrev(rev)
1571
1571
1572 def checksize(self):
1572 def checksize(self):
1573 return self._revlog.checksize()
1573 return self._revlog.checksize()
1574
1574
1575 def revision(self, node, _df=None, raw=False):
1575 def revision(self, node, _df=None, raw=False):
1576 return self._revlog.revision(node, _df=_df, raw=raw)
1576 return self._revlog.revision(node, _df=_df, raw=raw)
1577
1577
1578 def revdiff(self, rev1, rev2):
1578 def revdiff(self, rev1, rev2):
1579 return self._revlog.revdiff(rev1, rev2)
1579 return self._revlog.revdiff(rev1, rev2)
1580
1580
1581 def cmp(self, node, text):
1581 def cmp(self, node, text):
1582 return self._revlog.cmp(node, text)
1582 return self._revlog.cmp(node, text)
1583
1583
1584 def deltaparent(self, rev):
1584 def deltaparent(self, rev):
1585 return self._revlog.deltaparent(rev)
1585 return self._revlog.deltaparent(rev)
1586
1586
1587 def emitrevisions(self, nodes, nodesorder=None,
1587 def emitrevisions(self, nodes, nodesorder=None,
1588 revisiondata=False, assumehaveparentrevisions=False,
1588 revisiondata=False, assumehaveparentrevisions=False,
1589 deltamode=repository.CG_DELTAMODE_STD):
1589 deltamode=repository.CG_DELTAMODE_STD):
1590 return self._revlog.emitrevisions(
1590 return self._revlog.emitrevisions(
1591 nodes, nodesorder=nodesorder, revisiondata=revisiondata,
1591 nodes, nodesorder=nodesorder, revisiondata=revisiondata,
1592 assumehaveparentrevisions=assumehaveparentrevisions,
1592 assumehaveparentrevisions=assumehaveparentrevisions,
1593 deltamode=deltamode)
1593 deltamode=deltamode)
1594
1594
1595 def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None):
1595 def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None):
1596 return self._revlog.addgroup(deltas, linkmapper, transaction,
1596 return self._revlog.addgroup(deltas, linkmapper, transaction,
1597 addrevisioncb=addrevisioncb)
1597 addrevisioncb=addrevisioncb)
1598
1598
1599 def rawsize(self, rev):
1599 def rawsize(self, rev):
1600 return self._revlog.rawsize(rev)
1600 return self._revlog.rawsize(rev)
1601
1601
1602 def getstrippoint(self, minlink):
1602 def getstrippoint(self, minlink):
1603 return self._revlog.getstrippoint(minlink)
1603 return self._revlog.getstrippoint(minlink)
1604
1604
1605 def strip(self, minlink, transaction):
1605 def strip(self, minlink, transaction):
1606 return self._revlog.strip(minlink, transaction)
1606 return self._revlog.strip(minlink, transaction)
1607
1607
1608 def files(self):
1608 def files(self):
1609 return self._revlog.files()
1609 return self._revlog.files()
1610
1610
1611 def clone(self, tr, destrevlog, **kwargs):
1611 def clone(self, tr, destrevlog, **kwargs):
1612 if not isinstance(destrevlog, manifestrevlog):
1612 if not isinstance(destrevlog, manifestrevlog):
1613 raise error.ProgrammingError('expected manifestrevlog to clone()')
1613 raise error.ProgrammingError('expected manifestrevlog to clone()')
1614
1614
1615 return self._revlog.clone(tr, destrevlog._revlog, **kwargs)
1615 return self._revlog.clone(tr, destrevlog._revlog, **kwargs)
1616
1616
1617 def storageinfo(self, exclusivefiles=False, sharedfiles=False,
1617 def storageinfo(self, exclusivefiles=False, sharedfiles=False,
1618 revisionscount=False, trackedsize=False,
1618 revisionscount=False, trackedsize=False,
1619 storedsize=False):
1619 storedsize=False):
1620 return self._revlog.storageinfo(
1620 return self._revlog.storageinfo(
1621 exclusivefiles=exclusivefiles, sharedfiles=sharedfiles,
1621 exclusivefiles=exclusivefiles, sharedfiles=sharedfiles,
1622 revisionscount=revisionscount, trackedsize=trackedsize,
1622 revisionscount=revisionscount, trackedsize=trackedsize,
1623 storedsize=storedsize)
1623 storedsize=storedsize)
1624
1624
1625 @property
1625 @property
1626 def indexfile(self):
1626 def indexfile(self):
1627 return self._revlog.indexfile
1627 return self._revlog.indexfile
1628
1628
1629 @indexfile.setter
1629 @indexfile.setter
1630 def indexfile(self, value):
1630 def indexfile(self, value):
1631 self._revlog.indexfile = value
1631 self._revlog.indexfile = value
1632
1632
1633 @property
1633 @property
1634 def opener(self):
1634 def opener(self):
1635 return self._revlog.opener
1635 return self._revlog.opener
1636
1636
1637 @opener.setter
1637 @opener.setter
1638 def opener(self, value):
1638 def opener(self, value):
1639 self._revlog.opener = value
1639 self._revlog.opener = value
1640
1640
1641 @interfaceutil.implementer(repository.imanifestlog)
1641 @interfaceutil.implementer(repository.imanifestlog)
1642 class manifestlog(object):
1642 class manifestlog(object):
1643 """A collection class representing the collection of manifest snapshots
1643 """A collection class representing the collection of manifest snapshots
1644 referenced by commits in the repository.
1644 referenced by commits in the repository.
1645
1645
1646 In this situation, 'manifest' refers to the abstract concept of a snapshot
1646 In this situation, 'manifest' refers to the abstract concept of a snapshot
1647 of the list of files in the given commit. Consumers of the output of this
1647 of the list of files in the given commit. Consumers of the output of this
1648 class do not care about the implementation details of the actual manifests
1648 class do not care about the implementation details of the actual manifests
1649 they receive (i.e. tree or flat or lazily loaded, etc)."""
1649 they receive (i.e. tree or flat or lazily loaded, etc)."""
1650 def __init__(self, opener, repo, rootstore, narrowmatch):
1650 def __init__(self, opener, repo, rootstore, narrowmatch):
1651 usetreemanifest = False
1651 usetreemanifest = False
1652 cachesize = 4
1652 cachesize = 4
1653
1653
1654 opts = getattr(opener, 'options', None)
1654 opts = getattr(opener, 'options', None)
1655 if opts is not None:
1655 if opts is not None:
1656 usetreemanifest = opts.get('treemanifest', usetreemanifest)
1656 usetreemanifest = opts.get('treemanifest', usetreemanifest)
1657 cachesize = opts.get('manifestcachesize', cachesize)
1657 cachesize = opts.get('manifestcachesize', cachesize)
1658
1658
1659 self._treemanifests = usetreemanifest
1659 self._treemanifests = usetreemanifest
1660
1660
1661 self._rootstore = rootstore
1661 self._rootstore = rootstore
1662 self._rootstore._setupmanifestcachehooks(repo)
1662 self._rootstore._setupmanifestcachehooks(repo)
1663 self._narrowmatch = narrowmatch
1663 self._narrowmatch = narrowmatch
1664
1664
1665 # A cache of the manifestctx or treemanifestctx for each directory
1665 # A cache of the manifestctx or treemanifestctx for each directory
1666 self._dirmancache = {}
1666 self._dirmancache = {}
1667 self._dirmancache[''] = util.lrucachedict(cachesize)
1667 self._dirmancache[''] = util.lrucachedict(cachesize)
1668
1668
1669 self._cachesize = cachesize
1669 self._cachesize = cachesize
1670
1670
1671 def __getitem__(self, node):
1671 def __getitem__(self, node):
1672 """Retrieves the manifest instance for the given node. Throws a
1672 """Retrieves the manifest instance for the given node. Throws a
1673 LookupError if not found.
1673 LookupError if not found.
1674 """
1674 """
1675 return self.get('', node)
1675 return self.get('', node)
1676
1676
1677 def get(self, tree, node, verify=True):
1677 def get(self, tree, node, verify=True):
1678 """Retrieves the manifest instance for the given node. Throws a
1678 """Retrieves the manifest instance for the given node. Throws a
1679 LookupError if not found.
1679 LookupError if not found.
1680
1680
1681 `verify` - if True an exception will be thrown if the node is not in
1681 `verify` - if True an exception will be thrown if the node is not in
1682 the revlog
1682 the revlog
1683 """
1683 """
1684 if node in self._dirmancache.get(tree, ()):
1684 if node in self._dirmancache.get(tree, ()):
1685 return self._dirmancache[tree][node]
1685 return self._dirmancache[tree][node]
1686
1686
1687 if not self._narrowmatch.always():
1687 if not self._narrowmatch.always():
1688 if not self._narrowmatch.visitdir(tree[:-1] or '.'):
1688 if not self._narrowmatch.visitdir(tree[:-1] or '.'):
1689 return excludeddirmanifestctx(tree, node)
1689 return excludeddirmanifestctx(tree, node)
1690 if tree:
1690 if tree:
1691 if self._rootstore._treeondisk:
1691 if self._rootstore._treeondisk:
1692 if verify:
1692 if verify:
1693 # Side-effect is LookupError is raised if node doesn't
1693 # Side-effect is LookupError is raised if node doesn't
1694 # exist.
1694 # exist.
1695 self.getstorage(tree).rev(node)
1695 self.getstorage(tree).rev(node)
1696
1696
1697 m = treemanifestctx(self, tree, node)
1697 m = treemanifestctx(self, tree, node)
1698 else:
1698 else:
1699 raise error.Abort(
1699 raise error.Abort(
1700 _("cannot ask for manifest directory '%s' in a flat "
1700 _("cannot ask for manifest directory '%s' in a flat "
1701 "manifest") % tree)
1701 "manifest") % tree)
1702 else:
1702 else:
1703 if verify:
1703 if verify:
1704 # Side-effect is LookupError is raised if node doesn't exist.
1704 # Side-effect is LookupError is raised if node doesn't exist.
1705 self._rootstore.rev(node)
1705 self._rootstore.rev(node)
1706
1706
1707 if self._treemanifests:
1707 if self._treemanifests:
1708 m = treemanifestctx(self, '', node)
1708 m = treemanifestctx(self, '', node)
1709 else:
1709 else:
1710 m = manifestctx(self, node)
1710 m = manifestctx(self, node)
1711
1711
1712 if node != nullid:
1712 if node != nullid:
1713 mancache = self._dirmancache.get(tree)
1713 mancache = self._dirmancache.get(tree)
1714 if not mancache:
1714 if not mancache:
1715 mancache = util.lrucachedict(self._cachesize)
1715 mancache = util.lrucachedict(self._cachesize)
1716 self._dirmancache[tree] = mancache
1716 self._dirmancache[tree] = mancache
1717 mancache[node] = m
1717 mancache[node] = m
1718 return m
1718 return m
1719
1719
1720 def getstorage(self, tree):
1720 def getstorage(self, tree):
1721 return self._rootstore.dirlog(tree)
1721 return self._rootstore.dirlog(tree)
1722
1722
1723 def clearcaches(self, clear_persisted_data=False):
1723 def clearcaches(self, clear_persisted_data=False):
1724 self._dirmancache.clear()
1724 self._dirmancache.clear()
1725 self._rootstore.clearcaches(clear_persisted_data=clear_persisted_data)
1725 self._rootstore.clearcaches(clear_persisted_data=clear_persisted_data)
1726
1726
1727 def rev(self, node):
1727 def rev(self, node):
1728 return self._rootstore.rev(node)
1728 return self._rootstore.rev(node)
1729
1729
1730 @interfaceutil.implementer(repository.imanifestrevisionwritable)
1730 @interfaceutil.implementer(repository.imanifestrevisionwritable)
1731 class memmanifestctx(object):
1731 class memmanifestctx(object):
1732 def __init__(self, manifestlog):
1732 def __init__(self, manifestlog):
1733 self._manifestlog = manifestlog
1733 self._manifestlog = manifestlog
1734 self._manifestdict = manifestdict()
1734 self._manifestdict = manifestdict()
1735
1735
1736 def _storage(self):
1736 def _storage(self):
1737 return self._manifestlog.getstorage(b'')
1737 return self._manifestlog.getstorage(b'')
1738
1738
1739 def new(self):
1739 def new(self):
1740 return memmanifestctx(self._manifestlog)
1740 return memmanifestctx(self._manifestlog)
1741
1741
1742 def copy(self):
1742 def copy(self):
1743 memmf = memmanifestctx(self._manifestlog)
1743 memmf = memmanifestctx(self._manifestlog)
1744 memmf._manifestdict = self.read().copy()
1744 memmf._manifestdict = self.read().copy()
1745 return memmf
1745 return memmf
1746
1746
1747 def read(self):
1747 def read(self):
1748 return self._manifestdict
1748 return self._manifestdict
1749
1749
1750 def write(self, transaction, link, p1, p2, added, removed, match=None):
1750 def write(self, transaction, link, p1, p2, added, removed, match=None):
1751 return self._storage().add(self._manifestdict, transaction, link,
1751 return self._storage().add(self._manifestdict, transaction, link,
1752 p1, p2, added, removed, match=match)
1752 p1, p2, added, removed, match=match)
1753
1753
1754 @interfaceutil.implementer(repository.imanifestrevisionstored)
1754 @interfaceutil.implementer(repository.imanifestrevisionstored)
1755 class manifestctx(object):
1755 class manifestctx(object):
1756 """A class representing a single revision of a manifest, including its
1756 """A class representing a single revision of a manifest, including its
1757 contents, its parent revs, and its linkrev.
1757 contents, its parent revs, and its linkrev.
1758 """
1758 """
1759 def __init__(self, manifestlog, node):
1759 def __init__(self, manifestlog, node):
1760 self._manifestlog = manifestlog
1760 self._manifestlog = manifestlog
1761 self._data = None
1761 self._data = None
1762
1762
1763 self._node = node
1763 self._node = node
1764
1764
1765 # TODO: We eventually want p1, p2, and linkrev exposed on this class,
1765 # TODO: We eventually want p1, p2, and linkrev exposed on this class,
1766 # but let's add it later when something needs it and we can load it
1766 # but let's add it later when something needs it and we can load it
1767 # lazily.
1767 # lazily.
1768 #self.p1, self.p2 = store.parents(node)
1768 #self.p1, self.p2 = store.parents(node)
1769 #rev = store.rev(node)
1769 #rev = store.rev(node)
1770 #self.linkrev = store.linkrev(rev)
1770 #self.linkrev = store.linkrev(rev)
1771
1771
1772 def _storage(self):
1772 def _storage(self):
1773 return self._manifestlog.getstorage(b'')
1773 return self._manifestlog.getstorage(b'')
1774
1774
1775 def node(self):
1775 def node(self):
1776 return self._node
1776 return self._node
1777
1777
1778 def new(self):
1778 def new(self):
1779 return memmanifestctx(self._manifestlog)
1779 return memmanifestctx(self._manifestlog)
1780
1780
1781 def copy(self):
1781 def copy(self):
1782 memmf = memmanifestctx(self._manifestlog)
1782 memmf = memmanifestctx(self._manifestlog)
1783 memmf._manifestdict = self.read().copy()
1783 memmf._manifestdict = self.read().copy()
1784 return memmf
1784 return memmf
1785
1785
1786 @propertycache
1786 @propertycache
1787 def parents(self):
1787 def parents(self):
1788 return self._storage().parents(self._node)
1788 return self._storage().parents(self._node)
1789
1789
1790 def read(self):
1790 def read(self):
1791 if self._data is None:
1791 if self._data is None:
1792 if self._node == nullid:
1792 if self._node == nullid:
1793 self._data = manifestdict()
1793 self._data = manifestdict()
1794 else:
1794 else:
1795 store = self._storage()
1795 store = self._storage()
1796 if self._node in store.fulltextcache:
1796 if self._node in store.fulltextcache:
1797 text = pycompat.bytestr(store.fulltextcache[self._node])
1797 text = pycompat.bytestr(store.fulltextcache[self._node])
1798 else:
1798 else:
1799 text = store.revision(self._node)
1799 text = store.revision(self._node)
1800 arraytext = bytearray(text)
1800 arraytext = bytearray(text)
1801 store.fulltextcache[self._node] = arraytext
1801 store.fulltextcache[self._node] = arraytext
1802 self._data = manifestdict(text)
1802 self._data = manifestdict(text)
1803 return self._data
1803 return self._data
1804
1804
1805 def readfast(self, shallow=False):
1805 def readfast(self, shallow=False):
1806 '''Calls either readdelta or read, based on which would be less work.
1806 '''Calls either readdelta or read, based on which would be less work.
1807 readdelta is called if the delta is against the p1, and therefore can be
1807 readdelta is called if the delta is against the p1, and therefore can be
1808 read quickly.
1808 read quickly.
1809
1809
1810 If `shallow` is True, nothing changes since this is a flat manifest.
1810 If `shallow` is True, nothing changes since this is a flat manifest.
1811 '''
1811 '''
1812 store = self._storage()
1812 store = self._storage()
1813 r = store.rev(self._node)
1813 r = store.rev(self._node)
1814 deltaparent = store.deltaparent(r)
1814 deltaparent = store.deltaparent(r)
1815 if deltaparent != nullrev and deltaparent in store.parentrevs(r):
1815 if deltaparent != nullrev and deltaparent in store.parentrevs(r):
1816 return self.readdelta()
1816 return self.readdelta()
1817 return self.read()
1817 return self.read()
1818
1818
1819 def readdelta(self, shallow=False):
1819 def readdelta(self, shallow=False):
1820 '''Returns a manifest containing just the entries that are present
1820 '''Returns a manifest containing just the entries that are present
1821 in this manifest, but not in its p1 manifest. This is efficient to read
1821 in this manifest, but not in its p1 manifest. This is efficient to read
1822 if the revlog delta is already p1.
1822 if the revlog delta is already p1.
1823
1823
1824 Changing the value of `shallow` has no effect on flat manifests.
1824 Changing the value of `shallow` has no effect on flat manifests.
1825 '''
1825 '''
1826 store = self._storage()
1826 store = self._storage()
1827 r = store.rev(self._node)
1827 r = store.rev(self._node)
1828 d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r))
1828 d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r))
1829 return manifestdict(d)
1829 return manifestdict(d)
1830
1830
1831 def find(self, key):
1831 def find(self, key):
1832 return self.read().find(key)
1832 return self.read().find(key)
1833
1833
1834 @interfaceutil.implementer(repository.imanifestrevisionwritable)
1834 @interfaceutil.implementer(repository.imanifestrevisionwritable)
1835 class memtreemanifestctx(object):
1835 class memtreemanifestctx(object):
1836 def __init__(self, manifestlog, dir=''):
1836 def __init__(self, manifestlog, dir=''):
1837 self._manifestlog = manifestlog
1837 self._manifestlog = manifestlog
1838 self._dir = dir
1838 self._dir = dir
1839 self._treemanifest = treemanifest()
1839 self._treemanifest = treemanifest()
1840
1840
1841 def _storage(self):
1841 def _storage(self):
1842 return self._manifestlog.getstorage(b'')
1842 return self._manifestlog.getstorage(b'')
1843
1843
1844 def new(self, dir=''):
1844 def new(self, dir=''):
1845 return memtreemanifestctx(self._manifestlog, dir=dir)
1845 return memtreemanifestctx(self._manifestlog, dir=dir)
1846
1846
1847 def copy(self):
1847 def copy(self):
1848 memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
1848 memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
1849 memmf._treemanifest = self._treemanifest.copy()
1849 memmf._treemanifest = self._treemanifest.copy()
1850 return memmf
1850 return memmf
1851
1851
1852 def read(self):
1852 def read(self):
1853 return self._treemanifest
1853 return self._treemanifest
1854
1854
1855 def write(self, transaction, link, p1, p2, added, removed, match=None):
1855 def write(self, transaction, link, p1, p2, added, removed, match=None):
1856 def readtree(dir, node):
1856 def readtree(dir, node):
1857 return self._manifestlog.get(dir, node).read()
1857 return self._manifestlog.get(dir, node).read()
1858 return self._storage().add(self._treemanifest, transaction, link,
1858 return self._storage().add(self._treemanifest, transaction, link,
1859 p1, p2, added, removed, readtree=readtree,
1859 p1, p2, added, removed, readtree=readtree,
1860 match=match)
1860 match=match)
1861
1861
1862 @interfaceutil.implementer(repository.imanifestrevisionstored)
1862 @interfaceutil.implementer(repository.imanifestrevisionstored)
1863 class treemanifestctx(object):
1863 class treemanifestctx(object):
1864 def __init__(self, manifestlog, dir, node):
1864 def __init__(self, manifestlog, dir, node):
1865 self._manifestlog = manifestlog
1865 self._manifestlog = manifestlog
1866 self._dir = dir
1866 self._dir = dir
1867 self._data = None
1867 self._data = None
1868
1868
1869 self._node = node
1869 self._node = node
1870
1870
1871 # TODO: Load p1/p2/linkrev lazily. They need to be lazily loaded so that
1871 # TODO: Load p1/p2/linkrev lazily. They need to be lazily loaded so that
1872 # we can instantiate treemanifestctx objects for directories we don't
1872 # we can instantiate treemanifestctx objects for directories we don't
1873 # have on disk.
1873 # have on disk.
1874 #self.p1, self.p2 = store.parents(node)
1874 #self.p1, self.p2 = store.parents(node)
1875 #rev = store.rev(node)
1875 #rev = store.rev(node)
1876 #self.linkrev = store.linkrev(rev)
1876 #self.linkrev = store.linkrev(rev)
1877
1877
1878 def _storage(self):
1878 def _storage(self):
1879 narrowmatch = self._manifestlog._narrowmatch
1879 narrowmatch = self._manifestlog._narrowmatch
1880 if not narrowmatch.always():
1880 if not narrowmatch.always():
1881 if not narrowmatch.visitdir(self._dir[:-1] or '.'):
1881 if not narrowmatch.visitdir(self._dir[:-1] or '.'):
1882 return excludedmanifestrevlog(self._dir)
1882 return excludedmanifestrevlog(self._dir)
1883 return self._manifestlog.getstorage(self._dir)
1883 return self._manifestlog.getstorage(self._dir)
1884
1884
1885 def read(self):
1885 def read(self):
1886 if self._data is None:
1886 if self._data is None:
1887 store = self._storage()
1887 store = self._storage()
1888 if self._node == nullid:
1888 if self._node == nullid:
1889 self._data = treemanifest()
1889 self._data = treemanifest()
1890 # TODO accessing non-public API
1890 # TODO accessing non-public API
1891 elif store._treeondisk:
1891 elif store._treeondisk:
1892 m = treemanifest(dir=self._dir)
1892 m = treemanifest(dir=self._dir)
1893 def gettext():
1893 def gettext():
1894 return store.revision(self._node)
1894 return store.revision(self._node)
1895 def readsubtree(dir, subm):
1895 def readsubtree(dir, subm):
1896 # Set verify to False since we need to be able to create
1896 # Set verify to False since we need to be able to create
1897 # subtrees for trees that don't exist on disk.
1897 # subtrees for trees that don't exist on disk.
1898 return self._manifestlog.get(dir, subm, verify=False).read()
1898 return self._manifestlog.get(dir, subm, verify=False).read()
1899 m.read(gettext, readsubtree)
1899 m.read(gettext, readsubtree)
1900 m.setnode(self._node)
1900 m.setnode(self._node)
1901 self._data = m
1901 self._data = m
1902 else:
1902 else:
1903 if self._node in store.fulltextcache:
1903 if self._node in store.fulltextcache:
1904 text = pycompat.bytestr(store.fulltextcache[self._node])
1904 text = pycompat.bytestr(store.fulltextcache[self._node])
1905 else:
1905 else:
1906 text = store.revision(self._node)
1906 text = store.revision(self._node)
1907 arraytext = bytearray(text)
1907 arraytext = bytearray(text)
1908 store.fulltextcache[self._node] = arraytext
1908 store.fulltextcache[self._node] = arraytext
1909 self._data = treemanifest(dir=self._dir, text=text)
1909 self._data = treemanifest(dir=self._dir, text=text)
1910
1910
1911 return self._data
1911 return self._data
1912
1912
1913 def node(self):
1913 def node(self):
1914 return self._node
1914 return self._node
1915
1915
1916 def new(self, dir=''):
1916 def new(self, dir=''):
1917 return memtreemanifestctx(self._manifestlog, dir=dir)
1917 return memtreemanifestctx(self._manifestlog, dir=dir)
1918
1918
1919 def copy(self):
1919 def copy(self):
1920 memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
1920 memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
1921 memmf._treemanifest = self.read().copy()
1921 memmf._treemanifest = self.read().copy()
1922 return memmf
1922 return memmf
1923
1923
1924 @propertycache
1924 @propertycache
1925 def parents(self):
1925 def parents(self):
1926 return self._storage().parents(self._node)
1926 return self._storage().parents(self._node)
1927
1927
1928 def readdelta(self, shallow=False):
1928 def readdelta(self, shallow=False):
1929 '''Returns a manifest containing just the entries that are present
1929 '''Returns a manifest containing just the entries that are present
1930 in this manifest, but not in its p1 manifest. This is efficient to read
1930 in this manifest, but not in its p1 manifest. This is efficient to read
1931 if the revlog delta is already p1.
1931 if the revlog delta is already p1.
1932
1932
1933 If `shallow` is True, this will read the delta for this directory,
1933 If `shallow` is True, this will read the delta for this directory,
1934 without recursively reading subdirectory manifests. Instead, any
1934 without recursively reading subdirectory manifests. Instead, any
1935 subdirectory entry will be reported as it appears in the manifest, i.e.
1935 subdirectory entry will be reported as it appears in the manifest, i.e.
1936 the subdirectory will be reported among files and distinguished only by
1936 the subdirectory will be reported among files and distinguished only by
1937 its 't' flag.
1937 its 't' flag.
1938 '''
1938 '''
1939 store = self._storage()
1939 store = self._storage()
1940 if shallow:
1940 if shallow:
1941 r = store.rev(self._node)
1941 r = store.rev(self._node)
1942 d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r))
1942 d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r))
1943 return manifestdict(d)
1943 return manifestdict(d)
1944 else:
1944 else:
1945 # Need to perform a slow delta
1945 # Need to perform a slow delta
1946 r0 = store.deltaparent(store.rev(self._node))
1946 r0 = store.deltaparent(store.rev(self._node))
1947 m0 = self._manifestlog.get(self._dir, store.node(r0)).read()
1947 m0 = self._manifestlog.get(self._dir, store.node(r0)).read()
1948 m1 = self.read()
1948 m1 = self.read()
1949 md = treemanifest(dir=self._dir)
1949 md = treemanifest(dir=self._dir)
1950 for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
1950 for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems():
1951 if n1:
1951 if n1:
1952 md[f] = n1
1952 md[f] = n1
1953 if fl1:
1953 if fl1:
1954 md.setflag(f, fl1)
1954 md.setflag(f, fl1)
1955 return md
1955 return md
1956
1956
1957 def readfast(self, shallow=False):
1957 def readfast(self, shallow=False):
1958 '''Calls either readdelta or read, based on which would be less work.
1958 '''Calls either readdelta or read, based on which would be less work.
1959 readdelta is called if the delta is against the p1, and therefore can be
1959 readdelta is called if the delta is against the p1, and therefore can be
1960 read quickly.
1960 read quickly.
1961
1961
1962 If `shallow` is True, it only returns the entries from this manifest,
1962 If `shallow` is True, it only returns the entries from this manifest,
1963 and not any submanifests.
1963 and not any submanifests.
1964 '''
1964 '''
1965 store = self._storage()
1965 store = self._storage()
1966 r = store.rev(self._node)
1966 r = store.rev(self._node)
1967 deltaparent = store.deltaparent(r)
1967 deltaparent = store.deltaparent(r)
1968 if (deltaparent != nullrev and
1968 if (deltaparent != nullrev and
1969 deltaparent in store.parentrevs(r)):
1969 deltaparent in store.parentrevs(r)):
1970 return self.readdelta(shallow=shallow)
1970 return self.readdelta(shallow=shallow)
1971
1971
1972 if shallow:
1972 if shallow:
1973 return manifestdict(store.revision(self._node))
1973 return manifestdict(store.revision(self._node))
1974 else:
1974 else:
1975 return self.read()
1975 return self.read()
1976
1976
1977 def find(self, key):
1977 def find(self, key):
1978 return self.read().find(key)
1978 return self.read().find(key)
1979
1979
1980 class excludeddir(treemanifest):
1980 class excludeddir(treemanifest):
1981 """Stand-in for a directory that is excluded from the repository.
1981 """Stand-in for a directory that is excluded from the repository.
1982
1982
1983 With narrowing active on a repository that uses treemanifests,
1983 With narrowing active on a repository that uses treemanifests,
1984 some of the directory revlogs will be excluded from the resulting
1984 some of the directory revlogs will be excluded from the resulting
1985 clone. This is a huge storage win for clients, but means we need
1985 clone. This is a huge storage win for clients, but means we need
1986 some sort of pseudo-manifest to surface to internals so we can
1986 some sort of pseudo-manifest to surface to internals so we can
1987 detect a merge conflict outside the narrowspec. That's what this
1987 detect a merge conflict outside the narrowspec. That's what this
1988 class is: it stands in for a directory whose node is known, but
1988 class is: it stands in for a directory whose node is known, but
1989 whose contents are unknown.
1989 whose contents are unknown.
1990 """
1990 """
1991 def __init__(self, dir, node):
1991 def __init__(self, dir, node):
1992 super(excludeddir, self).__init__(dir)
1992 super(excludeddir, self).__init__(dir)
1993 self._node = node
1993 self._node = node
1994 # Add an empty file, which will be included by iterators and such,
1994 # Add an empty file, which will be included by iterators and such,
1995 # appearing as the directory itself (i.e. something like "dir/")
1995 # appearing as the directory itself (i.e. something like "dir/")
1996 self._files[''] = node
1996 self._files[''] = node
1997 self._flags[''] = 't'
1997 self._flags[''] = 't'
1998
1998
1999 # Manifests outside the narrowspec should never be modified, so avoid
1999 # Manifests outside the narrowspec should never be modified, so avoid
2000 # copying. This makes a noticeable difference when there are very many
2000 # copying. This makes a noticeable difference when there are very many
2001 # directories outside the narrowspec. Also, it makes sense for the copy to
2001 # directories outside the narrowspec. Also, it makes sense for the copy to
2002 # be of the same type as the original, which would not happen with the
2002 # be of the same type as the original, which would not happen with the
2003 # super type's copy().
2003 # super type's copy().
2004 def copy(self):
2004 def copy(self):
2005 return self
2005 return self
2006
2006
2007 class excludeddirmanifestctx(treemanifestctx):
2007 class excludeddirmanifestctx(treemanifestctx):
2008 """context wrapper for excludeddir - see that docstring for rationale"""
2008 """context wrapper for excludeddir - see that docstring for rationale"""
2009 def __init__(self, dir, node):
2009 def __init__(self, dir, node):
2010 self._dir = dir
2010 self._dir = dir
2011 self._node = node
2011 self._node = node
2012
2012
2013 def read(self):
2013 def read(self):
2014 return excludeddir(self._dir, self._node)
2014 return excludeddir(self._dir, self._node)
2015
2015
2016 def write(self, *args):
2016 def write(self, *args):
2017 raise error.ProgrammingError(
2017 raise error.ProgrammingError(
2018 'attempt to write manifest from excluded dir %s' % self._dir)
2018 'attempt to write manifest from excluded dir %s' % self._dir)
2019
2019
2020 class excludedmanifestrevlog(manifestrevlog):
2020 class excludedmanifestrevlog(manifestrevlog):
2021 """Stand-in for excluded treemanifest revlogs.
2021 """Stand-in for excluded treemanifest revlogs.
2022
2022
2023 When narrowing is active on a treemanifest repository, we'll have
2023 When narrowing is active on a treemanifest repository, we'll have
2024 references to directories we can't see due to the revlog being
2024 references to directories we can't see due to the revlog being
2025 skipped. This class exists to conform to the manifestrevlog
2025 skipped. This class exists to conform to the manifestrevlog
2026 interface for those directories and proactively prevent writes to
2026 interface for those directories and proactively prevent writes to
2027 outside the narrowspec.
2027 outside the narrowspec.
2028 """
2028 """
2029
2029
2030 def __init__(self, dir):
2030 def __init__(self, dir):
2031 self._dir = dir
2031 self._dir = dir
2032
2032
2033 def __len__(self):
2033 def __len__(self):
2034 raise error.ProgrammingError(
2034 raise error.ProgrammingError(
2035 'attempt to get length of excluded dir %s' % self._dir)
2035 'attempt to get length of excluded dir %s' % self._dir)
2036
2036
2037 def rev(self, node):
2037 def rev(self, node):
2038 raise error.ProgrammingError(
2038 raise error.ProgrammingError(
2039 'attempt to get rev from excluded dir %s' % self._dir)
2039 'attempt to get rev from excluded dir %s' % self._dir)
2040
2040
2041 def linkrev(self, node):
2041 def linkrev(self, node):
2042 raise error.ProgrammingError(
2042 raise error.ProgrammingError(
2043 'attempt to get linkrev from excluded dir %s' % self._dir)
2043 'attempt to get linkrev from excluded dir %s' % self._dir)
2044
2044
2045 def node(self, rev):
2045 def node(self, rev):
2046 raise error.ProgrammingError(
2046 raise error.ProgrammingError(
2047 'attempt to get node from excluded dir %s' % self._dir)
2047 'attempt to get node from excluded dir %s' % self._dir)
2048
2048
2049 def add(self, *args, **kwargs):
2049 def add(self, *args, **kwargs):
2050 # We should never write entries in dirlogs outside the narrow clone.
2050 # We should never write entries in dirlogs outside the narrow clone.
2051 # However, the method still gets called from writesubtree() in
2051 # However, the method still gets called from writesubtree() in
2052 # _addtree(), so we need to handle it. We should possibly make that
2052 # _addtree(), so we need to handle it. We should possibly make that
2053 # avoid calling add() with a clean manifest (_dirty is always False
2053 # avoid calling add() with a clean manifest (_dirty is always False
2054 # in excludeddir instances).
2054 # in excludeddir instances).
2055 pass
2055 pass
@@ -1,1294 +1,1292 b''
1 #testcases sshv1 sshv2
1 #testcases sshv1 sshv2
2
2
3 #if sshv2
3 #if sshv2
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [experimental]
5 > [experimental]
6 > sshpeer.advertise-v2 = true
6 > sshpeer.advertise-v2 = true
7 > sshserver.support-v2 = true
7 > sshserver.support-v2 = true
8 > EOF
8 > EOF
9 #endif
9 #endif
10
10
11 Prepare repo a:
11 Prepare repo a:
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15 $ echo a > a
15 $ echo a > a
16 $ hg add a
16 $ hg add a
17 $ hg commit -m test
17 $ hg commit -m test
18 $ echo first line > b
18 $ echo first line > b
19 $ hg add b
19 $ hg add b
20
20
21 Create a non-inlined filelog:
21 Create a non-inlined filelog:
22
22
23 $ "$PYTHON" -c 'open("data1", "wb").write(b"".join(b"%d\n" % x for x in range(10000)))'
23 $ "$PYTHON" -c 'open("data1", "wb").write(b"".join(b"%d\n" % x for x in range(10000)))'
24 $ for j in 0 1 2 3 4 5 6 7 8 9; do
24 $ for j in 0 1 2 3 4 5 6 7 8 9; do
25 > cat data1 >> b
25 > cat data1 >> b
26 > hg commit -m test
26 > hg commit -m test
27 > done
27 > done
28
28
29 List files in store/data (should show a 'b.d'):
29 List files in store/data (should show a 'b.d'):
30
30
31 #if reporevlogstore
31 #if reporevlogstore
32 $ for i in .hg/store/data/*; do
32 $ for i in .hg/store/data/*; do
33 > echo $i
33 > echo $i
34 > done
34 > done
35 .hg/store/data/a.i
35 .hg/store/data/a.i
36 .hg/store/data/b.d
36 .hg/store/data/b.d
37 .hg/store/data/b.i
37 .hg/store/data/b.i
38 #endif
38 #endif
39
39
40 Trigger branchcache creation:
40 Trigger branchcache creation:
41
41
42 $ hg branches
42 $ hg branches
43 default 10:a7949464abda
43 default 10:a7949464abda
44 $ ls .hg/cache
44 $ ls .hg/cache
45 branch2-served
45 branch2-served
46 manifestfulltextcache (reporevlogstore !)
47 rbc-names-v1
46 rbc-names-v1
48 rbc-revs-v1
47 rbc-revs-v1
49
48
50 Default operation:
49 Default operation:
51
50
52 $ hg clone . ../b
51 $ hg clone . ../b
53 updating to branch default
52 updating to branch default
54 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
53 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 $ cd ../b
54 $ cd ../b
56
55
57 Ensure branchcache got copied over:
56 Ensure branchcache got copied over:
58
57
59 $ ls .hg/cache
58 $ ls .hg/cache
60 branch2-served
59 branch2-served
61 manifestfulltextcache
62 rbc-names-v1
60 rbc-names-v1
63 rbc-revs-v1
61 rbc-revs-v1
64
62
65 $ cat a
63 $ cat a
66 a
64 a
67 $ hg verify
65 $ hg verify
68 checking changesets
66 checking changesets
69 checking manifests
67 checking manifests
70 crosschecking files in changesets and manifests
68 crosschecking files in changesets and manifests
71 checking files
69 checking files
72 checked 11 changesets with 11 changes to 2 files
70 checked 11 changesets with 11 changes to 2 files
73
71
74 Invalid dest '' must abort:
72 Invalid dest '' must abort:
75
73
76 $ hg clone . ''
74 $ hg clone . ''
77 abort: empty destination path is not valid
75 abort: empty destination path is not valid
78 [255]
76 [255]
79
77
80 No update, with debug option:
78 No update, with debug option:
81
79
82 #if hardlink
80 #if hardlink
83 $ hg --debug clone -U . ../c --config progress.debug=true
81 $ hg --debug clone -U . ../c --config progress.debug=true
84 linking: 1 files
82 linking: 1 files
85 linking: 2 files
83 linking: 2 files
86 linking: 3 files
84 linking: 3 files
87 linking: 4 files
85 linking: 4 files
88 linking: 5 files
86 linking: 5 files
89 linking: 6 files
87 linking: 6 files
90 linking: 7 files
88 linking: 7 files
91 linking: 8 files
89 linking: 8 files
92 linked 8 files (reporevlogstore !)
90 linked 8 files (reporevlogstore !)
93 linking: 9 files (reposimplestore !)
91 linking: 9 files (reposimplestore !)
94 linking: 10 files (reposimplestore !)
92 linking: 10 files (reposimplestore !)
95 linking: 11 files (reposimplestore !)
93 linking: 11 files (reposimplestore !)
96 linking: 12 files (reposimplestore !)
94 linking: 12 files (reposimplestore !)
97 linking: 13 files (reposimplestore !)
95 linking: 13 files (reposimplestore !)
98 linking: 14 files (reposimplestore !)
96 linking: 14 files (reposimplestore !)
99 linking: 15 files (reposimplestore !)
97 linking: 15 files (reposimplestore !)
100 linking: 16 files (reposimplestore !)
98 linking: 16 files (reposimplestore !)
101 linking: 17 files (reposimplestore !)
99 linking: 17 files (reposimplestore !)
102 linking: 18 files (reposimplestore !)
100 linking: 18 files (reposimplestore !)
103 linked 18 files (reposimplestore !)
101 linked 18 files (reposimplestore !)
104 #else
102 #else
105 $ hg --debug clone -U . ../c --config progress.debug=true
103 $ hg --debug clone -U . ../c --config progress.debug=true
106 linking: 1 files
104 linking: 1 files
107 copying: 2 files
105 copying: 2 files
108 copying: 3 files
106 copying: 3 files
109 copying: 4 files
107 copying: 4 files
110 copying: 5 files
108 copying: 5 files
111 copying: 6 files
109 copying: 6 files
112 copying: 7 files
110 copying: 7 files
113 copying: 8 files
111 copying: 8 files
114 copied 8 files (reporevlogstore !)
112 copied 8 files (reporevlogstore !)
115 copying: 9 files (reposimplestore !)
113 copying: 9 files (reposimplestore !)
116 copying: 10 files (reposimplestore !)
114 copying: 10 files (reposimplestore !)
117 copying: 11 files (reposimplestore !)
115 copying: 11 files (reposimplestore !)
118 copying: 12 files (reposimplestore !)
116 copying: 12 files (reposimplestore !)
119 copying: 13 files (reposimplestore !)
117 copying: 13 files (reposimplestore !)
120 copying: 14 files (reposimplestore !)
118 copying: 14 files (reposimplestore !)
121 copying: 15 files (reposimplestore !)
119 copying: 15 files (reposimplestore !)
122 copying: 16 files (reposimplestore !)
120 copying: 16 files (reposimplestore !)
123 copying: 17 files (reposimplestore !)
121 copying: 17 files (reposimplestore !)
124 copying: 18 files (reposimplestore !)
122 copying: 18 files (reposimplestore !)
125 copied 18 files (reposimplestore !)
123 copied 18 files (reposimplestore !)
126 #endif
124 #endif
127 $ cd ../c
125 $ cd ../c
128
126
129 Ensure branchcache got copied over:
127 Ensure branchcache got copied over:
130
128
131 $ ls .hg/cache
129 $ ls .hg/cache
132 branch2-served
130 branch2-served
133 rbc-names-v1
131 rbc-names-v1
134 rbc-revs-v1
132 rbc-revs-v1
135
133
136 $ cat a 2>/dev/null || echo "a not present"
134 $ cat a 2>/dev/null || echo "a not present"
137 a not present
135 a not present
138 $ hg verify
136 $ hg verify
139 checking changesets
137 checking changesets
140 checking manifests
138 checking manifests
141 crosschecking files in changesets and manifests
139 crosschecking files in changesets and manifests
142 checking files
140 checking files
143 checked 11 changesets with 11 changes to 2 files
141 checked 11 changesets with 11 changes to 2 files
144
142
145 Default destination:
143 Default destination:
146
144
147 $ mkdir ../d
145 $ mkdir ../d
148 $ cd ../d
146 $ cd ../d
149 $ hg clone ../a
147 $ hg clone ../a
150 destination directory: a
148 destination directory: a
151 updating to branch default
149 updating to branch default
152 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
153 $ cd a
151 $ cd a
154 $ hg cat a
152 $ hg cat a
155 a
153 a
156 $ cd ../..
154 $ cd ../..
157
155
158 Check that we drop the 'file:' from the path before writing the .hgrc:
156 Check that we drop the 'file:' from the path before writing the .hgrc:
159
157
160 $ hg clone file:a e
158 $ hg clone file:a e
161 updating to branch default
159 updating to branch default
162 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 $ grep 'file:' e/.hg/hgrc
161 $ grep 'file:' e/.hg/hgrc
164 [1]
162 [1]
165
163
166 Check that path aliases are expanded:
164 Check that path aliases are expanded:
167
165
168 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
166 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
169 $ hg -R f showconfig paths.default
167 $ hg -R f showconfig paths.default
170 $TESTTMP/a#0
168 $TESTTMP/a#0
171
169
172 Use --pull:
170 Use --pull:
173
171
174 $ hg clone --pull a g
172 $ hg clone --pull a g
175 requesting all changes
173 requesting all changes
176 adding changesets
174 adding changesets
177 adding manifests
175 adding manifests
178 adding file changes
176 adding file changes
179 added 11 changesets with 11 changes to 2 files
177 added 11 changesets with 11 changes to 2 files
180 new changesets acb14030fe0a:a7949464abda
178 new changesets acb14030fe0a:a7949464abda
181 updating to branch default
179 updating to branch default
182 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
180 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
183 $ hg -R g verify
181 $ hg -R g verify
184 checking changesets
182 checking changesets
185 checking manifests
183 checking manifests
186 crosschecking files in changesets and manifests
184 crosschecking files in changesets and manifests
187 checking files
185 checking files
188 checked 11 changesets with 11 changes to 2 files
186 checked 11 changesets with 11 changes to 2 files
189
187
190 Invalid dest '' with --pull must abort (issue2528):
188 Invalid dest '' with --pull must abort (issue2528):
191
189
192 $ hg clone --pull a ''
190 $ hg clone --pull a ''
193 abort: empty destination path is not valid
191 abort: empty destination path is not valid
194 [255]
192 [255]
195
193
196 Clone to '.':
194 Clone to '.':
197
195
198 $ mkdir h
196 $ mkdir h
199 $ cd h
197 $ cd h
200 $ hg clone ../a .
198 $ hg clone ../a .
201 updating to branch default
199 updating to branch default
202 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
200 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
203 $ cd ..
201 $ cd ..
204
202
205
203
206 *** Tests for option -u ***
204 *** Tests for option -u ***
207
205
208 Adding some more history to repo a:
206 Adding some more history to repo a:
209
207
210 $ cd a
208 $ cd a
211 $ hg tag ref1
209 $ hg tag ref1
212 $ echo the quick brown fox >a
210 $ echo the quick brown fox >a
213 $ hg ci -m "hacked default"
211 $ hg ci -m "hacked default"
214 $ hg up ref1
212 $ hg up ref1
215 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
213 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
216 $ hg branch stable
214 $ hg branch stable
217 marked working directory as branch stable
215 marked working directory as branch stable
218 (branches are permanent and global, did you want a bookmark?)
216 (branches are permanent and global, did you want a bookmark?)
219 $ echo some text >a
217 $ echo some text >a
220 $ hg ci -m "starting branch stable"
218 $ hg ci -m "starting branch stable"
221 $ hg tag ref2
219 $ hg tag ref2
222 $ echo some more text >a
220 $ echo some more text >a
223 $ hg ci -m "another change for branch stable"
221 $ hg ci -m "another change for branch stable"
224 $ hg up ref2
222 $ hg up ref2
225 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
223 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
226 $ hg parents
224 $ hg parents
227 changeset: 13:e8ece76546a6
225 changeset: 13:e8ece76546a6
228 branch: stable
226 branch: stable
229 tag: ref2
227 tag: ref2
230 parent: 10:a7949464abda
228 parent: 10:a7949464abda
231 user: test
229 user: test
232 date: Thu Jan 01 00:00:00 1970 +0000
230 date: Thu Jan 01 00:00:00 1970 +0000
233 summary: starting branch stable
231 summary: starting branch stable
234
232
235
233
236 Repo a has two heads:
234 Repo a has two heads:
237
235
238 $ hg heads
236 $ hg heads
239 changeset: 15:0aae7cf88f0d
237 changeset: 15:0aae7cf88f0d
240 branch: stable
238 branch: stable
241 tag: tip
239 tag: tip
242 user: test
240 user: test
243 date: Thu Jan 01 00:00:00 1970 +0000
241 date: Thu Jan 01 00:00:00 1970 +0000
244 summary: another change for branch stable
242 summary: another change for branch stable
245
243
246 changeset: 12:f21241060d6a
244 changeset: 12:f21241060d6a
247 user: test
245 user: test
248 date: Thu Jan 01 00:00:00 1970 +0000
246 date: Thu Jan 01 00:00:00 1970 +0000
249 summary: hacked default
247 summary: hacked default
250
248
251
249
252 $ cd ..
250 $ cd ..
253
251
254
252
255 Testing --noupdate with --updaterev (must abort):
253 Testing --noupdate with --updaterev (must abort):
256
254
257 $ hg clone --noupdate --updaterev 1 a ua
255 $ hg clone --noupdate --updaterev 1 a ua
258 abort: cannot specify both --noupdate and --updaterev
256 abort: cannot specify both --noupdate and --updaterev
259 [255]
257 [255]
260
258
261
259
262 Testing clone -u:
260 Testing clone -u:
263
261
264 $ hg clone -u . a ua
262 $ hg clone -u . a ua
265 updating to branch stable
263 updating to branch stable
266 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
264 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
267
265
268 Repo ua has both heads:
266 Repo ua has both heads:
269
267
270 $ hg -R ua heads
268 $ hg -R ua heads
271 changeset: 15:0aae7cf88f0d
269 changeset: 15:0aae7cf88f0d
272 branch: stable
270 branch: stable
273 tag: tip
271 tag: tip
274 user: test
272 user: test
275 date: Thu Jan 01 00:00:00 1970 +0000
273 date: Thu Jan 01 00:00:00 1970 +0000
276 summary: another change for branch stable
274 summary: another change for branch stable
277
275
278 changeset: 12:f21241060d6a
276 changeset: 12:f21241060d6a
279 user: test
277 user: test
280 date: Thu Jan 01 00:00:00 1970 +0000
278 date: Thu Jan 01 00:00:00 1970 +0000
281 summary: hacked default
279 summary: hacked default
282
280
283
281
284 Same revision checked out in repo a and ua:
282 Same revision checked out in repo a and ua:
285
283
286 $ hg -R a parents --template "{node|short}\n"
284 $ hg -R a parents --template "{node|short}\n"
287 e8ece76546a6
285 e8ece76546a6
288 $ hg -R ua parents --template "{node|short}\n"
286 $ hg -R ua parents --template "{node|short}\n"
289 e8ece76546a6
287 e8ece76546a6
290
288
291 $ rm -r ua
289 $ rm -r ua
292
290
293
291
294 Testing clone --pull -u:
292 Testing clone --pull -u:
295
293
296 $ hg clone --pull -u . a ua
294 $ hg clone --pull -u . a ua
297 requesting all changes
295 requesting all changes
298 adding changesets
296 adding changesets
299 adding manifests
297 adding manifests
300 adding file changes
298 adding file changes
301 added 16 changesets with 16 changes to 3 files (+1 heads)
299 added 16 changesets with 16 changes to 3 files (+1 heads)
302 new changesets acb14030fe0a:0aae7cf88f0d
300 new changesets acb14030fe0a:0aae7cf88f0d
303 updating to branch stable
301 updating to branch stable
304 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
302 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
305
303
306 Repo ua has both heads:
304 Repo ua has both heads:
307
305
308 $ hg -R ua heads
306 $ hg -R ua heads
309 changeset: 15:0aae7cf88f0d
307 changeset: 15:0aae7cf88f0d
310 branch: stable
308 branch: stable
311 tag: tip
309 tag: tip
312 user: test
310 user: test
313 date: Thu Jan 01 00:00:00 1970 +0000
311 date: Thu Jan 01 00:00:00 1970 +0000
314 summary: another change for branch stable
312 summary: another change for branch stable
315
313
316 changeset: 12:f21241060d6a
314 changeset: 12:f21241060d6a
317 user: test
315 user: test
318 date: Thu Jan 01 00:00:00 1970 +0000
316 date: Thu Jan 01 00:00:00 1970 +0000
319 summary: hacked default
317 summary: hacked default
320
318
321
319
322 Same revision checked out in repo a and ua:
320 Same revision checked out in repo a and ua:
323
321
324 $ hg -R a parents --template "{node|short}\n"
322 $ hg -R a parents --template "{node|short}\n"
325 e8ece76546a6
323 e8ece76546a6
326 $ hg -R ua parents --template "{node|short}\n"
324 $ hg -R ua parents --template "{node|short}\n"
327 e8ece76546a6
325 e8ece76546a6
328
326
329 $ rm -r ua
327 $ rm -r ua
330
328
331
329
332 Testing clone -u <branch>:
330 Testing clone -u <branch>:
333
331
334 $ hg clone -u stable a ua
332 $ hg clone -u stable a ua
335 updating to branch stable
333 updating to branch stable
336 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
337
335
338 Repo ua has both heads:
336 Repo ua has both heads:
339
337
340 $ hg -R ua heads
338 $ hg -R ua heads
341 changeset: 15:0aae7cf88f0d
339 changeset: 15:0aae7cf88f0d
342 branch: stable
340 branch: stable
343 tag: tip
341 tag: tip
344 user: test
342 user: test
345 date: Thu Jan 01 00:00:00 1970 +0000
343 date: Thu Jan 01 00:00:00 1970 +0000
346 summary: another change for branch stable
344 summary: another change for branch stable
347
345
348 changeset: 12:f21241060d6a
346 changeset: 12:f21241060d6a
349 user: test
347 user: test
350 date: Thu Jan 01 00:00:00 1970 +0000
348 date: Thu Jan 01 00:00:00 1970 +0000
351 summary: hacked default
349 summary: hacked default
352
350
353
351
354 Branch 'stable' is checked out:
352 Branch 'stable' is checked out:
355
353
356 $ hg -R ua parents
354 $ hg -R ua parents
357 changeset: 15:0aae7cf88f0d
355 changeset: 15:0aae7cf88f0d
358 branch: stable
356 branch: stable
359 tag: tip
357 tag: tip
360 user: test
358 user: test
361 date: Thu Jan 01 00:00:00 1970 +0000
359 date: Thu Jan 01 00:00:00 1970 +0000
362 summary: another change for branch stable
360 summary: another change for branch stable
363
361
364
362
365 $ rm -r ua
363 $ rm -r ua
366
364
367
365
368 Testing default checkout:
366 Testing default checkout:
369
367
370 $ hg clone a ua
368 $ hg clone a ua
371 updating to branch default
369 updating to branch default
372 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
370 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
373
371
374 Repo ua has both heads:
372 Repo ua has both heads:
375
373
376 $ hg -R ua heads
374 $ hg -R ua heads
377 changeset: 15:0aae7cf88f0d
375 changeset: 15:0aae7cf88f0d
378 branch: stable
376 branch: stable
379 tag: tip
377 tag: tip
380 user: test
378 user: test
381 date: Thu Jan 01 00:00:00 1970 +0000
379 date: Thu Jan 01 00:00:00 1970 +0000
382 summary: another change for branch stable
380 summary: another change for branch stable
383
381
384 changeset: 12:f21241060d6a
382 changeset: 12:f21241060d6a
385 user: test
383 user: test
386 date: Thu Jan 01 00:00:00 1970 +0000
384 date: Thu Jan 01 00:00:00 1970 +0000
387 summary: hacked default
385 summary: hacked default
388
386
389
387
390 Branch 'default' is checked out:
388 Branch 'default' is checked out:
391
389
392 $ hg -R ua parents
390 $ hg -R ua parents
393 changeset: 12:f21241060d6a
391 changeset: 12:f21241060d6a
394 user: test
392 user: test
395 date: Thu Jan 01 00:00:00 1970 +0000
393 date: Thu Jan 01 00:00:00 1970 +0000
396 summary: hacked default
394 summary: hacked default
397
395
398 Test clone with a branch named "@" (issue3677)
396 Test clone with a branch named "@" (issue3677)
399
397
400 $ hg -R ua branch @
398 $ hg -R ua branch @
401 marked working directory as branch @
399 marked working directory as branch @
402 $ hg -R ua commit -m 'created branch @'
400 $ hg -R ua commit -m 'created branch @'
403 $ hg clone ua atbranch
401 $ hg clone ua atbranch
404 updating to branch default
402 updating to branch default
405 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
403 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
406 $ hg -R atbranch heads
404 $ hg -R atbranch heads
407 changeset: 16:798b6d97153e
405 changeset: 16:798b6d97153e
408 branch: @
406 branch: @
409 tag: tip
407 tag: tip
410 parent: 12:f21241060d6a
408 parent: 12:f21241060d6a
411 user: test
409 user: test
412 date: Thu Jan 01 00:00:00 1970 +0000
410 date: Thu Jan 01 00:00:00 1970 +0000
413 summary: created branch @
411 summary: created branch @
414
412
415 changeset: 15:0aae7cf88f0d
413 changeset: 15:0aae7cf88f0d
416 branch: stable
414 branch: stable
417 user: test
415 user: test
418 date: Thu Jan 01 00:00:00 1970 +0000
416 date: Thu Jan 01 00:00:00 1970 +0000
419 summary: another change for branch stable
417 summary: another change for branch stable
420
418
421 changeset: 12:f21241060d6a
419 changeset: 12:f21241060d6a
422 user: test
420 user: test
423 date: Thu Jan 01 00:00:00 1970 +0000
421 date: Thu Jan 01 00:00:00 1970 +0000
424 summary: hacked default
422 summary: hacked default
425
423
426 $ hg -R atbranch parents
424 $ hg -R atbranch parents
427 changeset: 12:f21241060d6a
425 changeset: 12:f21241060d6a
428 user: test
426 user: test
429 date: Thu Jan 01 00:00:00 1970 +0000
427 date: Thu Jan 01 00:00:00 1970 +0000
430 summary: hacked default
428 summary: hacked default
431
429
432
430
433 $ rm -r ua atbranch
431 $ rm -r ua atbranch
434
432
435
433
436 Testing #<branch>:
434 Testing #<branch>:
437
435
438 $ hg clone -u . a#stable ua
436 $ hg clone -u . a#stable ua
439 adding changesets
437 adding changesets
440 adding manifests
438 adding manifests
441 adding file changes
439 adding file changes
442 added 14 changesets with 14 changes to 3 files
440 added 14 changesets with 14 changes to 3 files
443 new changesets acb14030fe0a:0aae7cf88f0d
441 new changesets acb14030fe0a:0aae7cf88f0d
444 updating to branch stable
442 updating to branch stable
445 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
443 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
446
444
447 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
445 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
448
446
449 $ hg -R ua heads
447 $ hg -R ua heads
450 changeset: 13:0aae7cf88f0d
448 changeset: 13:0aae7cf88f0d
451 branch: stable
449 branch: stable
452 tag: tip
450 tag: tip
453 user: test
451 user: test
454 date: Thu Jan 01 00:00:00 1970 +0000
452 date: Thu Jan 01 00:00:00 1970 +0000
455 summary: another change for branch stable
453 summary: another change for branch stable
456
454
457 changeset: 10:a7949464abda
455 changeset: 10:a7949464abda
458 user: test
456 user: test
459 date: Thu Jan 01 00:00:00 1970 +0000
457 date: Thu Jan 01 00:00:00 1970 +0000
460 summary: test
458 summary: test
461
459
462
460
463 Same revision checked out in repo a and ua:
461 Same revision checked out in repo a and ua:
464
462
465 $ hg -R a parents --template "{node|short}\n"
463 $ hg -R a parents --template "{node|short}\n"
466 e8ece76546a6
464 e8ece76546a6
467 $ hg -R ua parents --template "{node|short}\n"
465 $ hg -R ua parents --template "{node|short}\n"
468 e8ece76546a6
466 e8ece76546a6
469
467
470 $ rm -r ua
468 $ rm -r ua
471
469
472
470
473 Testing -u -r <branch>:
471 Testing -u -r <branch>:
474
472
475 $ hg clone -u . -r stable a ua
473 $ hg clone -u . -r stable a ua
476 adding changesets
474 adding changesets
477 adding manifests
475 adding manifests
478 adding file changes
476 adding file changes
479 added 14 changesets with 14 changes to 3 files
477 added 14 changesets with 14 changes to 3 files
480 new changesets acb14030fe0a:0aae7cf88f0d
478 new changesets acb14030fe0a:0aae7cf88f0d
481 updating to branch stable
479 updating to branch stable
482 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
480 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
483
481
484 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
482 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
485
483
486 $ hg -R ua heads
484 $ hg -R ua heads
487 changeset: 13:0aae7cf88f0d
485 changeset: 13:0aae7cf88f0d
488 branch: stable
486 branch: stable
489 tag: tip
487 tag: tip
490 user: test
488 user: test
491 date: Thu Jan 01 00:00:00 1970 +0000
489 date: Thu Jan 01 00:00:00 1970 +0000
492 summary: another change for branch stable
490 summary: another change for branch stable
493
491
494 changeset: 10:a7949464abda
492 changeset: 10:a7949464abda
495 user: test
493 user: test
496 date: Thu Jan 01 00:00:00 1970 +0000
494 date: Thu Jan 01 00:00:00 1970 +0000
497 summary: test
495 summary: test
498
496
499
497
500 Same revision checked out in repo a and ua:
498 Same revision checked out in repo a and ua:
501
499
502 $ hg -R a parents --template "{node|short}\n"
500 $ hg -R a parents --template "{node|short}\n"
503 e8ece76546a6
501 e8ece76546a6
504 $ hg -R ua parents --template "{node|short}\n"
502 $ hg -R ua parents --template "{node|short}\n"
505 e8ece76546a6
503 e8ece76546a6
506
504
507 $ rm -r ua
505 $ rm -r ua
508
506
509
507
510 Testing -r <branch>:
508 Testing -r <branch>:
511
509
512 $ hg clone -r stable a ua
510 $ hg clone -r stable a ua
513 adding changesets
511 adding changesets
514 adding manifests
512 adding manifests
515 adding file changes
513 adding file changes
516 added 14 changesets with 14 changes to 3 files
514 added 14 changesets with 14 changes to 3 files
517 new changesets acb14030fe0a:0aae7cf88f0d
515 new changesets acb14030fe0a:0aae7cf88f0d
518 updating to branch stable
516 updating to branch stable
519 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
517 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
520
518
521 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
519 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
522
520
523 $ hg -R ua heads
521 $ hg -R ua heads
524 changeset: 13:0aae7cf88f0d
522 changeset: 13:0aae7cf88f0d
525 branch: stable
523 branch: stable
526 tag: tip
524 tag: tip
527 user: test
525 user: test
528 date: Thu Jan 01 00:00:00 1970 +0000
526 date: Thu Jan 01 00:00:00 1970 +0000
529 summary: another change for branch stable
527 summary: another change for branch stable
530
528
531 changeset: 10:a7949464abda
529 changeset: 10:a7949464abda
532 user: test
530 user: test
533 date: Thu Jan 01 00:00:00 1970 +0000
531 date: Thu Jan 01 00:00:00 1970 +0000
534 summary: test
532 summary: test
535
533
536
534
537 Branch 'stable' is checked out:
535 Branch 'stable' is checked out:
538
536
539 $ hg -R ua parents
537 $ hg -R ua parents
540 changeset: 13:0aae7cf88f0d
538 changeset: 13:0aae7cf88f0d
541 branch: stable
539 branch: stable
542 tag: tip
540 tag: tip
543 user: test
541 user: test
544 date: Thu Jan 01 00:00:00 1970 +0000
542 date: Thu Jan 01 00:00:00 1970 +0000
545 summary: another change for branch stable
543 summary: another change for branch stable
546
544
547
545
548 $ rm -r ua
546 $ rm -r ua
549
547
550
548
551 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
549 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
552 iterable in addbranchrevs()
550 iterable in addbranchrevs()
553
551
554 $ cat <<EOF > simpleclone.py
552 $ cat <<EOF > simpleclone.py
555 > from mercurial import hg, ui as uimod
553 > from mercurial import hg, ui as uimod
556 > myui = uimod.ui.load()
554 > myui = uimod.ui.load()
557 > repo = hg.repository(myui, b'a')
555 > repo = hg.repository(myui, b'a')
558 > hg.clone(myui, {}, repo, dest=b"ua")
556 > hg.clone(myui, {}, repo, dest=b"ua")
559 > EOF
557 > EOF
560
558
561 $ "$PYTHON" simpleclone.py
559 $ "$PYTHON" simpleclone.py
562 updating to branch default
560 updating to branch default
563 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
561 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
564
562
565 $ rm -r ua
563 $ rm -r ua
566
564
567 $ cat <<EOF > branchclone.py
565 $ cat <<EOF > branchclone.py
568 > from mercurial import extensions, hg, ui as uimod
566 > from mercurial import extensions, hg, ui as uimod
569 > myui = uimod.ui.load()
567 > myui = uimod.ui.load()
570 > extensions.loadall(myui)
568 > extensions.loadall(myui)
571 > extensions.populateui(myui)
569 > extensions.populateui(myui)
572 > repo = hg.repository(myui, b'a')
570 > repo = hg.repository(myui, b'a')
573 > hg.clone(myui, {}, repo, dest=b"ua", branch=[b"stable"])
571 > hg.clone(myui, {}, repo, dest=b"ua", branch=[b"stable"])
574 > EOF
572 > EOF
575
573
576 $ "$PYTHON" branchclone.py
574 $ "$PYTHON" branchclone.py
577 adding changesets
575 adding changesets
578 adding manifests
576 adding manifests
579 adding file changes
577 adding file changes
580 added 14 changesets with 14 changes to 3 files
578 added 14 changesets with 14 changes to 3 files
581 new changesets acb14030fe0a:0aae7cf88f0d
579 new changesets acb14030fe0a:0aae7cf88f0d
582 updating to branch stable
580 updating to branch stable
583 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
581 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
584 $ rm -r ua
582 $ rm -r ua
585
583
586
584
587 Test clone with special '@' bookmark:
585 Test clone with special '@' bookmark:
588 $ cd a
586 $ cd a
589 $ hg bookmark -r a7949464abda @ # branch point of stable from default
587 $ hg bookmark -r a7949464abda @ # branch point of stable from default
590 $ hg clone . ../i
588 $ hg clone . ../i
591 updating to bookmark @
589 updating to bookmark @
592 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
590 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
593 $ hg id -i ../i
591 $ hg id -i ../i
594 a7949464abda
592 a7949464abda
595 $ rm -r ../i
593 $ rm -r ../i
596
594
597 $ hg bookmark -f -r stable @
595 $ hg bookmark -f -r stable @
598 $ hg bookmarks
596 $ hg bookmarks
599 @ 15:0aae7cf88f0d
597 @ 15:0aae7cf88f0d
600 $ hg clone . ../i
598 $ hg clone . ../i
601 updating to bookmark @ on branch stable
599 updating to bookmark @ on branch stable
602 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
600 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
603 $ hg id -i ../i
601 $ hg id -i ../i
604 0aae7cf88f0d
602 0aae7cf88f0d
605 $ cd "$TESTTMP"
603 $ cd "$TESTTMP"
606
604
607
605
608 Testing failures:
606 Testing failures:
609
607
610 $ mkdir fail
608 $ mkdir fail
611 $ cd fail
609 $ cd fail
612
610
613 No local source
611 No local source
614
612
615 $ hg clone a b
613 $ hg clone a b
616 abort: repository a not found!
614 abort: repository a not found!
617 [255]
615 [255]
618
616
619 No remote source
617 No remote source
620
618
621 #if windows
619 #if windows
622 $ hg clone http://$LOCALIP:3121/a b
620 $ hg clone http://$LOCALIP:3121/a b
623 abort: error: * (glob)
621 abort: error: * (glob)
624 [255]
622 [255]
625 #else
623 #else
626 $ hg clone http://$LOCALIP:3121/a b
624 $ hg clone http://$LOCALIP:3121/a b
627 abort: error: *refused* (glob)
625 abort: error: *refused* (glob)
628 [255]
626 [255]
629 #endif
627 #endif
630 $ rm -rf b # work around bug with http clone
628 $ rm -rf b # work around bug with http clone
631
629
632
630
633 #if unix-permissions no-root
631 #if unix-permissions no-root
634
632
635 Inaccessible source
633 Inaccessible source
636
634
637 $ mkdir a
635 $ mkdir a
638 $ chmod 000 a
636 $ chmod 000 a
639 $ hg clone a b
637 $ hg clone a b
640 abort: Permission denied: *$TESTTMP/fail/a/.hg* (glob)
638 abort: Permission denied: *$TESTTMP/fail/a/.hg* (glob)
641 [255]
639 [255]
642
640
643 Inaccessible destination
641 Inaccessible destination
644
642
645 $ hg init b
643 $ hg init b
646 $ cd b
644 $ cd b
647 $ hg clone . ../a
645 $ hg clone . ../a
648 abort: Permission denied: *../a* (glob)
646 abort: Permission denied: *../a* (glob)
649 [255]
647 [255]
650 $ cd ..
648 $ cd ..
651 $ chmod 700 a
649 $ chmod 700 a
652 $ rm -r a b
650 $ rm -r a b
653
651
654 #endif
652 #endif
655
653
656
654
657 #if fifo
655 #if fifo
658
656
659 Source of wrong type
657 Source of wrong type
660
658
661 $ mkfifo a
659 $ mkfifo a
662 $ hg clone a b
660 $ hg clone a b
663 abort: $ENOTDIR$: *$TESTTMP/fail/a/.hg* (glob)
661 abort: $ENOTDIR$: *$TESTTMP/fail/a/.hg* (glob)
664 [255]
662 [255]
665 $ rm a
663 $ rm a
666
664
667 #endif
665 #endif
668
666
669 Default destination, same directory
667 Default destination, same directory
670
668
671 $ hg init q
669 $ hg init q
672 $ hg clone q
670 $ hg clone q
673 destination directory: q
671 destination directory: q
674 abort: destination 'q' is not empty
672 abort: destination 'q' is not empty
675 [255]
673 [255]
676
674
677 destination directory not empty
675 destination directory not empty
678
676
679 $ mkdir a
677 $ mkdir a
680 $ echo stuff > a/a
678 $ echo stuff > a/a
681 $ hg clone q a
679 $ hg clone q a
682 abort: destination 'a' is not empty
680 abort: destination 'a' is not empty
683 [255]
681 [255]
684
682
685
683
686 #if unix-permissions no-root
684 #if unix-permissions no-root
687
685
688 leave existing directory in place after clone failure
686 leave existing directory in place after clone failure
689
687
690 $ hg init c
688 $ hg init c
691 $ cd c
689 $ cd c
692 $ echo c > c
690 $ echo c > c
693 $ hg commit -A -m test
691 $ hg commit -A -m test
694 adding c
692 adding c
695 $ chmod -rx .hg/store/data
693 $ chmod -rx .hg/store/data
696 $ cd ..
694 $ cd ..
697 $ mkdir d
695 $ mkdir d
698 $ hg clone c d 2> err
696 $ hg clone c d 2> err
699 [255]
697 [255]
700 $ test -d d
698 $ test -d d
701 $ test -d d/.hg
699 $ test -d d/.hg
702 [1]
700 [1]
703
701
704 re-enable perm to allow deletion
702 re-enable perm to allow deletion
705
703
706 $ chmod +rx c/.hg/store/data
704 $ chmod +rx c/.hg/store/data
707
705
708 #endif
706 #endif
709
707
710 $ cd ..
708 $ cd ..
711
709
712 Test clone from the repository in (emulated) revlog format 0 (issue4203):
710 Test clone from the repository in (emulated) revlog format 0 (issue4203):
713
711
714 $ mkdir issue4203
712 $ mkdir issue4203
715 $ mkdir -p src/.hg
713 $ mkdir -p src/.hg
716 $ echo foo > src/foo
714 $ echo foo > src/foo
717 $ hg -R src add src/foo
715 $ hg -R src add src/foo
718 $ hg -R src commit -m '#0'
716 $ hg -R src commit -m '#0'
719 $ hg -R src log -q
717 $ hg -R src log -q
720 0:e1bab28bca43
718 0:e1bab28bca43
721 $ hg -R src debugrevlog -c | egrep 'format|flags'
719 $ hg -R src debugrevlog -c | egrep 'format|flags'
722 format : 0
720 format : 0
723 flags : (none)
721 flags : (none)
724 $ hg clone -U -q src dst
722 $ hg clone -U -q src dst
725 $ hg -R dst log -q
723 $ hg -R dst log -q
726 0:e1bab28bca43
724 0:e1bab28bca43
727
725
728 Create repositories to test auto sharing functionality
726 Create repositories to test auto sharing functionality
729
727
730 $ cat >> $HGRCPATH << EOF
728 $ cat >> $HGRCPATH << EOF
731 > [extensions]
729 > [extensions]
732 > share=
730 > share=
733 > EOF
731 > EOF
734
732
735 $ hg init empty
733 $ hg init empty
736 $ hg init source1a
734 $ hg init source1a
737 $ cd source1a
735 $ cd source1a
738 $ echo initial1 > foo
736 $ echo initial1 > foo
739 $ hg -q commit -A -m initial
737 $ hg -q commit -A -m initial
740 $ echo second > foo
738 $ echo second > foo
741 $ hg commit -m second
739 $ hg commit -m second
742 $ cd ..
740 $ cd ..
743
741
744 $ hg init filteredrev0
742 $ hg init filteredrev0
745 $ cd filteredrev0
743 $ cd filteredrev0
746 $ cat >> .hg/hgrc << EOF
744 $ cat >> .hg/hgrc << EOF
747 > [experimental]
745 > [experimental]
748 > evolution.createmarkers=True
746 > evolution.createmarkers=True
749 > EOF
747 > EOF
750 $ echo initial1 > foo
748 $ echo initial1 > foo
751 $ hg -q commit -A -m initial0
749 $ hg -q commit -A -m initial0
752 $ hg -q up -r null
750 $ hg -q up -r null
753 $ echo initial2 > foo
751 $ echo initial2 > foo
754 $ hg -q commit -A -m initial1
752 $ hg -q commit -A -m initial1
755 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
753 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
756 obsoleted 1 changesets
754 obsoleted 1 changesets
757 $ cd ..
755 $ cd ..
758
756
759 $ hg -q clone --pull source1a source1b
757 $ hg -q clone --pull source1a source1b
760 $ cd source1a
758 $ cd source1a
761 $ hg bookmark bookA
759 $ hg bookmark bookA
762 $ echo 1a > foo
760 $ echo 1a > foo
763 $ hg commit -m 1a
761 $ hg commit -m 1a
764 $ cd ../source1b
762 $ cd ../source1b
765 $ hg -q up -r 0
763 $ hg -q up -r 0
766 $ echo head1 > foo
764 $ echo head1 > foo
767 $ hg commit -m head1
765 $ hg commit -m head1
768 created new head
766 created new head
769 $ hg bookmark head1
767 $ hg bookmark head1
770 $ hg -q up -r 0
768 $ hg -q up -r 0
771 $ echo head2 > foo
769 $ echo head2 > foo
772 $ hg commit -m head2
770 $ hg commit -m head2
773 created new head
771 created new head
774 $ hg bookmark head2
772 $ hg bookmark head2
775 $ hg -q up -r 0
773 $ hg -q up -r 0
776 $ hg branch branch1
774 $ hg branch branch1
777 marked working directory as branch branch1
775 marked working directory as branch branch1
778 (branches are permanent and global, did you want a bookmark?)
776 (branches are permanent and global, did you want a bookmark?)
779 $ echo branch1 > foo
777 $ echo branch1 > foo
780 $ hg commit -m branch1
778 $ hg commit -m branch1
781 $ hg -q up -r 0
779 $ hg -q up -r 0
782 $ hg branch branch2
780 $ hg branch branch2
783 marked working directory as branch branch2
781 marked working directory as branch branch2
784 $ echo branch2 > foo
782 $ echo branch2 > foo
785 $ hg commit -m branch2
783 $ hg commit -m branch2
786 $ cd ..
784 $ cd ..
787 $ hg init source2
785 $ hg init source2
788 $ cd source2
786 $ cd source2
789 $ echo initial2 > foo
787 $ echo initial2 > foo
790 $ hg -q commit -A -m initial2
788 $ hg -q commit -A -m initial2
791 $ echo second > foo
789 $ echo second > foo
792 $ hg commit -m second
790 $ hg commit -m second
793 $ cd ..
791 $ cd ..
794
792
795 Clone with auto share from an empty repo should not result in share
793 Clone with auto share from an empty repo should not result in share
796
794
797 $ mkdir share
795 $ mkdir share
798 $ hg --config share.pool=share clone empty share-empty
796 $ hg --config share.pool=share clone empty share-empty
799 (not using pooled storage: remote appears to be empty)
797 (not using pooled storage: remote appears to be empty)
800 updating to branch default
798 updating to branch default
801 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
799 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
802 $ ls share
800 $ ls share
803 $ test -d share-empty/.hg/store
801 $ test -d share-empty/.hg/store
804 $ test -f share-empty/.hg/sharedpath
802 $ test -f share-empty/.hg/sharedpath
805 [1]
803 [1]
806
804
807 Clone with auto share from a repo with filtered revision 0 should not result in share
805 Clone with auto share from a repo with filtered revision 0 should not result in share
808
806
809 $ hg --config share.pool=share clone filteredrev0 share-filtered
807 $ hg --config share.pool=share clone filteredrev0 share-filtered
810 (not using pooled storage: unable to resolve identity of remote)
808 (not using pooled storage: unable to resolve identity of remote)
811 requesting all changes
809 requesting all changes
812 adding changesets
810 adding changesets
813 adding manifests
811 adding manifests
814 adding file changes
812 adding file changes
815 added 1 changesets with 1 changes to 1 files
813 added 1 changesets with 1 changes to 1 files
816 new changesets e082c1832e09
814 new changesets e082c1832e09
817 updating to branch default
815 updating to branch default
818 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
816 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
819
817
820 Clone from repo with content should result in shared store being created
818 Clone from repo with content should result in shared store being created
821
819
822 $ hg --config share.pool=share clone source1a share-dest1a
820 $ hg --config share.pool=share clone source1a share-dest1a
823 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
821 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
824 requesting all changes
822 requesting all changes
825 adding changesets
823 adding changesets
826 adding manifests
824 adding manifests
827 adding file changes
825 adding file changes
828 added 3 changesets with 3 changes to 1 files
826 added 3 changesets with 3 changes to 1 files
829 new changesets b5f04eac9d8f:e5bfe23c0b47
827 new changesets b5f04eac9d8f:e5bfe23c0b47
830 searching for changes
828 searching for changes
831 no changes found
829 no changes found
832 adding remote bookmark bookA
830 adding remote bookmark bookA
833 updating working directory
831 updating working directory
834 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
832 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
835
833
836 The shared repo should have been created
834 The shared repo should have been created
837
835
838 $ ls share
836 $ ls share
839 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
837 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
840
838
841 The destination should point to it
839 The destination should point to it
842
840
843 $ cat share-dest1a/.hg/sharedpath; echo
841 $ cat share-dest1a/.hg/sharedpath; echo
844 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
842 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
845
843
846 The destination should have bookmarks
844 The destination should have bookmarks
847
845
848 $ hg -R share-dest1a bookmarks
846 $ hg -R share-dest1a bookmarks
849 bookA 2:e5bfe23c0b47
847 bookA 2:e5bfe23c0b47
850
848
851 The default path should be the remote, not the share
849 The default path should be the remote, not the share
852
850
853 $ hg -R share-dest1a config paths.default
851 $ hg -R share-dest1a config paths.default
854 $TESTTMP/source1a
852 $TESTTMP/source1a
855
853
856 Clone with existing share dir should result in pull + share
854 Clone with existing share dir should result in pull + share
857
855
858 $ hg --config share.pool=share clone source1b share-dest1b
856 $ hg --config share.pool=share clone source1b share-dest1b
859 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
857 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
860 searching for changes
858 searching for changes
861 adding changesets
859 adding changesets
862 adding manifests
860 adding manifests
863 adding file changes
861 adding file changes
864 added 4 changesets with 4 changes to 1 files (+4 heads)
862 added 4 changesets with 4 changes to 1 files (+4 heads)
865 adding remote bookmark head1
863 adding remote bookmark head1
866 adding remote bookmark head2
864 adding remote bookmark head2
867 new changesets 4a8dc1ab4c13:6bacf4683960
865 new changesets 4a8dc1ab4c13:6bacf4683960
868 updating working directory
866 updating working directory
869 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
867 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
870
868
871 $ ls share
869 $ ls share
872 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
870 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
873
871
874 $ cat share-dest1b/.hg/sharedpath; echo
872 $ cat share-dest1b/.hg/sharedpath; echo
875 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
873 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
876
874
877 We only get bookmarks from the remote, not everything in the share
875 We only get bookmarks from the remote, not everything in the share
878
876
879 $ hg -R share-dest1b bookmarks
877 $ hg -R share-dest1b bookmarks
880 head1 3:4a8dc1ab4c13
878 head1 3:4a8dc1ab4c13
881 head2 4:99f71071f117
879 head2 4:99f71071f117
882
880
883 Default path should be source, not share.
881 Default path should be source, not share.
884
882
885 $ hg -R share-dest1b config paths.default
883 $ hg -R share-dest1b config paths.default
886 $TESTTMP/source1b
884 $TESTTMP/source1b
887
885
888 Checked out revision should be head of default branch
886 Checked out revision should be head of default branch
889
887
890 $ hg -R share-dest1b log -r .
888 $ hg -R share-dest1b log -r .
891 changeset: 4:99f71071f117
889 changeset: 4:99f71071f117
892 bookmark: head2
890 bookmark: head2
893 parent: 0:b5f04eac9d8f
891 parent: 0:b5f04eac9d8f
894 user: test
892 user: test
895 date: Thu Jan 01 00:00:00 1970 +0000
893 date: Thu Jan 01 00:00:00 1970 +0000
896 summary: head2
894 summary: head2
897
895
898
896
899 Clone from unrelated repo should result in new share
897 Clone from unrelated repo should result in new share
900
898
901 $ hg --config share.pool=share clone source2 share-dest2
899 $ hg --config share.pool=share clone source2 share-dest2
902 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
900 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
903 requesting all changes
901 requesting all changes
904 adding changesets
902 adding changesets
905 adding manifests
903 adding manifests
906 adding file changes
904 adding file changes
907 added 2 changesets with 2 changes to 1 files
905 added 2 changesets with 2 changes to 1 files
908 new changesets 22aeff664783:63cf6c3dba4a
906 new changesets 22aeff664783:63cf6c3dba4a
909 searching for changes
907 searching for changes
910 no changes found
908 no changes found
911 updating working directory
909 updating working directory
912 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
910 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
913
911
914 $ ls share
912 $ ls share
915 22aeff664783fd44c6d9b435618173c118c3448e
913 22aeff664783fd44c6d9b435618173c118c3448e
916 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
914 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
917
915
918 remote naming mode works as advertised
916 remote naming mode works as advertised
919
917
920 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
918 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
921 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
919 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
922 requesting all changes
920 requesting all changes
923 adding changesets
921 adding changesets
924 adding manifests
922 adding manifests
925 adding file changes
923 adding file changes
926 added 3 changesets with 3 changes to 1 files
924 added 3 changesets with 3 changes to 1 files
927 new changesets b5f04eac9d8f:e5bfe23c0b47
925 new changesets b5f04eac9d8f:e5bfe23c0b47
928 searching for changes
926 searching for changes
929 no changes found
927 no changes found
930 adding remote bookmark bookA
928 adding remote bookmark bookA
931 updating working directory
929 updating working directory
932 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
930 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
933
931
934 $ ls shareremote
932 $ ls shareremote
935 195bb1fcdb595c14a6c13e0269129ed78f6debde
933 195bb1fcdb595c14a6c13e0269129ed78f6debde
936
934
937 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
935 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
938 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
936 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
939 requesting all changes
937 requesting all changes
940 adding changesets
938 adding changesets
941 adding manifests
939 adding manifests
942 adding file changes
940 adding file changes
943 added 6 changesets with 6 changes to 1 files (+4 heads)
941 added 6 changesets with 6 changes to 1 files (+4 heads)
944 new changesets b5f04eac9d8f:6bacf4683960
942 new changesets b5f04eac9d8f:6bacf4683960
945 searching for changes
943 searching for changes
946 no changes found
944 no changes found
947 adding remote bookmark head1
945 adding remote bookmark head1
948 adding remote bookmark head2
946 adding remote bookmark head2
949 updating working directory
947 updating working directory
950 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
948 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
951
949
952 $ ls shareremote
950 $ ls shareremote
953 195bb1fcdb595c14a6c13e0269129ed78f6debde
951 195bb1fcdb595c14a6c13e0269129ed78f6debde
954 c0d4f83847ca2a873741feb7048a45085fd47c46
952 c0d4f83847ca2a873741feb7048a45085fd47c46
955
953
956 request to clone a single revision is respected in sharing mode
954 request to clone a single revision is respected in sharing mode
957
955
958 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
956 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
959 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
957 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
960 adding changesets
958 adding changesets
961 adding manifests
959 adding manifests
962 adding file changes
960 adding file changes
963 added 2 changesets with 2 changes to 1 files
961 added 2 changesets with 2 changes to 1 files
964 new changesets b5f04eac9d8f:4a8dc1ab4c13
962 new changesets b5f04eac9d8f:4a8dc1ab4c13
965 no changes found
963 no changes found
966 adding remote bookmark head1
964 adding remote bookmark head1
967 updating working directory
965 updating working directory
968 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
966 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
969
967
970 $ hg -R share-1arev log -G
968 $ hg -R share-1arev log -G
971 @ changeset: 1:4a8dc1ab4c13
969 @ changeset: 1:4a8dc1ab4c13
972 | bookmark: head1
970 | bookmark: head1
973 | tag: tip
971 | tag: tip
974 | user: test
972 | user: test
975 | date: Thu Jan 01 00:00:00 1970 +0000
973 | date: Thu Jan 01 00:00:00 1970 +0000
976 | summary: head1
974 | summary: head1
977 |
975 |
978 o changeset: 0:b5f04eac9d8f
976 o changeset: 0:b5f04eac9d8f
979 user: test
977 user: test
980 date: Thu Jan 01 00:00:00 1970 +0000
978 date: Thu Jan 01 00:00:00 1970 +0000
981 summary: initial
979 summary: initial
982
980
983
981
984 making another clone should only pull down requested rev
982 making another clone should only pull down requested rev
985
983
986 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
984 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
987 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
985 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
988 searching for changes
986 searching for changes
989 adding changesets
987 adding changesets
990 adding manifests
988 adding manifests
991 adding file changes
989 adding file changes
992 added 1 changesets with 1 changes to 1 files (+1 heads)
990 added 1 changesets with 1 changes to 1 files (+1 heads)
993 adding remote bookmark head1
991 adding remote bookmark head1
994 adding remote bookmark head2
992 adding remote bookmark head2
995 new changesets 99f71071f117
993 new changesets 99f71071f117
996 updating working directory
994 updating working directory
997 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
995 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
998
996
999 $ hg -R share-1brev log -G
997 $ hg -R share-1brev log -G
1000 @ changeset: 2:99f71071f117
998 @ changeset: 2:99f71071f117
1001 | bookmark: head2
999 | bookmark: head2
1002 | tag: tip
1000 | tag: tip
1003 | parent: 0:b5f04eac9d8f
1001 | parent: 0:b5f04eac9d8f
1004 | user: test
1002 | user: test
1005 | date: Thu Jan 01 00:00:00 1970 +0000
1003 | date: Thu Jan 01 00:00:00 1970 +0000
1006 | summary: head2
1004 | summary: head2
1007 |
1005 |
1008 | o changeset: 1:4a8dc1ab4c13
1006 | o changeset: 1:4a8dc1ab4c13
1009 |/ bookmark: head1
1007 |/ bookmark: head1
1010 | user: test
1008 | user: test
1011 | date: Thu Jan 01 00:00:00 1970 +0000
1009 | date: Thu Jan 01 00:00:00 1970 +0000
1012 | summary: head1
1010 | summary: head1
1013 |
1011 |
1014 o changeset: 0:b5f04eac9d8f
1012 o changeset: 0:b5f04eac9d8f
1015 user: test
1013 user: test
1016 date: Thu Jan 01 00:00:00 1970 +0000
1014 date: Thu Jan 01 00:00:00 1970 +0000
1017 summary: initial
1015 summary: initial
1018
1016
1019
1017
1020 Request to clone a single branch is respected in sharing mode
1018 Request to clone a single branch is respected in sharing mode
1021
1019
1022 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
1020 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
1023 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1021 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1024 adding changesets
1022 adding changesets
1025 adding manifests
1023 adding manifests
1026 adding file changes
1024 adding file changes
1027 added 2 changesets with 2 changes to 1 files
1025 added 2 changesets with 2 changes to 1 files
1028 new changesets b5f04eac9d8f:5f92a6c1a1b1
1026 new changesets b5f04eac9d8f:5f92a6c1a1b1
1029 no changes found
1027 no changes found
1030 updating working directory
1028 updating working directory
1031 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1029 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1032
1030
1033 $ hg -R share-1bbranch1 log -G
1031 $ hg -R share-1bbranch1 log -G
1034 o changeset: 1:5f92a6c1a1b1
1032 o changeset: 1:5f92a6c1a1b1
1035 | branch: branch1
1033 | branch: branch1
1036 | tag: tip
1034 | tag: tip
1037 | user: test
1035 | user: test
1038 | date: Thu Jan 01 00:00:00 1970 +0000
1036 | date: Thu Jan 01 00:00:00 1970 +0000
1039 | summary: branch1
1037 | summary: branch1
1040 |
1038 |
1041 @ changeset: 0:b5f04eac9d8f
1039 @ changeset: 0:b5f04eac9d8f
1042 user: test
1040 user: test
1043 date: Thu Jan 01 00:00:00 1970 +0000
1041 date: Thu Jan 01 00:00:00 1970 +0000
1044 summary: initial
1042 summary: initial
1045
1043
1046
1044
1047 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
1045 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
1048 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1046 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1049 searching for changes
1047 searching for changes
1050 adding changesets
1048 adding changesets
1051 adding manifests
1049 adding manifests
1052 adding file changes
1050 adding file changes
1053 added 1 changesets with 1 changes to 1 files (+1 heads)
1051 added 1 changesets with 1 changes to 1 files (+1 heads)
1054 new changesets 6bacf4683960
1052 new changesets 6bacf4683960
1055 updating working directory
1053 updating working directory
1056 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1054 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1057
1055
1058 $ hg -R share-1bbranch2 log -G
1056 $ hg -R share-1bbranch2 log -G
1059 o changeset: 2:6bacf4683960
1057 o changeset: 2:6bacf4683960
1060 | branch: branch2
1058 | branch: branch2
1061 | tag: tip
1059 | tag: tip
1062 | parent: 0:b5f04eac9d8f
1060 | parent: 0:b5f04eac9d8f
1063 | user: test
1061 | user: test
1064 | date: Thu Jan 01 00:00:00 1970 +0000
1062 | date: Thu Jan 01 00:00:00 1970 +0000
1065 | summary: branch2
1063 | summary: branch2
1066 |
1064 |
1067 | o changeset: 1:5f92a6c1a1b1
1065 | o changeset: 1:5f92a6c1a1b1
1068 |/ branch: branch1
1066 |/ branch: branch1
1069 | user: test
1067 | user: test
1070 | date: Thu Jan 01 00:00:00 1970 +0000
1068 | date: Thu Jan 01 00:00:00 1970 +0000
1071 | summary: branch1
1069 | summary: branch1
1072 |
1070 |
1073 @ changeset: 0:b5f04eac9d8f
1071 @ changeset: 0:b5f04eac9d8f
1074 user: test
1072 user: test
1075 date: Thu Jan 01 00:00:00 1970 +0000
1073 date: Thu Jan 01 00:00:00 1970 +0000
1076 summary: initial
1074 summary: initial
1077
1075
1078
1076
1079 -U is respected in share clone mode
1077 -U is respected in share clone mode
1080
1078
1081 $ hg --config share.pool=share clone -U source1a share-1anowc
1079 $ hg --config share.pool=share clone -U source1a share-1anowc
1082 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1080 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1083 searching for changes
1081 searching for changes
1084 no changes found
1082 no changes found
1085 adding remote bookmark bookA
1083 adding remote bookmark bookA
1086
1084
1087 $ ls share-1anowc
1085 $ ls share-1anowc
1088
1086
1089 Test that auto sharing doesn't cause failure of "hg clone local remote"
1087 Test that auto sharing doesn't cause failure of "hg clone local remote"
1090
1088
1091 $ cd $TESTTMP
1089 $ cd $TESTTMP
1092 $ hg -R a id -r 0
1090 $ hg -R a id -r 0
1093 acb14030fe0a
1091 acb14030fe0a
1094 $ hg id -R remote -r 0
1092 $ hg id -R remote -r 0
1095 abort: repository remote not found!
1093 abort: repository remote not found!
1096 [255]
1094 [255]
1097 $ hg --config share.pool=share -q clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1095 $ hg --config share.pool=share -q clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1098 $ hg -R remote id -r 0
1096 $ hg -R remote id -r 0
1099 acb14030fe0a
1097 acb14030fe0a
1100
1098
1101 Cloning into pooled storage doesn't race (issue5104)
1099 Cloning into pooled storage doesn't race (issue5104)
1102
1100
1103 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1101 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1104 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1102 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1105 $ wait
1103 $ wait
1106
1104
1107 $ hg -R share-destrace1 log -r tip
1105 $ hg -R share-destrace1 log -r tip
1108 changeset: 2:e5bfe23c0b47
1106 changeset: 2:e5bfe23c0b47
1109 bookmark: bookA
1107 bookmark: bookA
1110 tag: tip
1108 tag: tip
1111 user: test
1109 user: test
1112 date: Thu Jan 01 00:00:00 1970 +0000
1110 date: Thu Jan 01 00:00:00 1970 +0000
1113 summary: 1a
1111 summary: 1a
1114
1112
1115
1113
1116 $ hg -R share-destrace2 log -r tip
1114 $ hg -R share-destrace2 log -r tip
1117 changeset: 2:e5bfe23c0b47
1115 changeset: 2:e5bfe23c0b47
1118 bookmark: bookA
1116 bookmark: bookA
1119 tag: tip
1117 tag: tip
1120 user: test
1118 user: test
1121 date: Thu Jan 01 00:00:00 1970 +0000
1119 date: Thu Jan 01 00:00:00 1970 +0000
1122 summary: 1a
1120 summary: 1a
1123
1121
1124 One repo should be new, the other should be shared from the pool. We
1122 One repo should be new, the other should be shared from the pool. We
1125 don't care which is which, so we just make sure we always print the
1123 don't care which is which, so we just make sure we always print the
1126 one containing "new pooled" first, then one one containing "existing
1124 one containing "new pooled" first, then one one containing "existing
1127 pooled".
1125 pooled".
1128
1126
1129 $ (grep 'new pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1127 $ (grep 'new pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1130 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1128 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1131 requesting all changes
1129 requesting all changes
1132 adding changesets
1130 adding changesets
1133 adding manifests
1131 adding manifests
1134 adding file changes
1132 adding file changes
1135 added 3 changesets with 3 changes to 1 files
1133 added 3 changesets with 3 changes to 1 files
1136 new changesets b5f04eac9d8f:e5bfe23c0b47
1134 new changesets b5f04eac9d8f:e5bfe23c0b47
1137 searching for changes
1135 searching for changes
1138 no changes found
1136 no changes found
1139 adding remote bookmark bookA
1137 adding remote bookmark bookA
1140 updating working directory
1138 updating working directory
1141 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1142
1140
1143 $ (grep 'existing pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1141 $ (grep 'existing pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1144 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1142 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1145 searching for changes
1143 searching for changes
1146 no changes found
1144 no changes found
1147 adding remote bookmark bookA
1145 adding remote bookmark bookA
1148 updating working directory
1146 updating working directory
1149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1147 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1150
1148
1151 SEC: check for unsafe ssh url
1149 SEC: check for unsafe ssh url
1152
1150
1153 $ cat >> $HGRCPATH << EOF
1151 $ cat >> $HGRCPATH << EOF
1154 > [ui]
1152 > [ui]
1155 > ssh = sh -c "read l; read l; read l"
1153 > ssh = sh -c "read l; read l; read l"
1156 > EOF
1154 > EOF
1157
1155
1158 $ hg clone 'ssh://-oProxyCommand=touch${IFS}owned/path'
1156 $ hg clone 'ssh://-oProxyCommand=touch${IFS}owned/path'
1159 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1157 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1160 [255]
1158 [255]
1161 $ hg clone 'ssh://%2DoProxyCommand=touch${IFS}owned/path'
1159 $ hg clone 'ssh://%2DoProxyCommand=touch${IFS}owned/path'
1162 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1160 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1163 [255]
1161 [255]
1164 $ hg clone 'ssh://fakehost|touch%20owned/path'
1162 $ hg clone 'ssh://fakehost|touch%20owned/path'
1165 abort: no suitable response from remote hg!
1163 abort: no suitable response from remote hg!
1166 [255]
1164 [255]
1167 $ hg clone 'ssh://fakehost%7Ctouch%20owned/path'
1165 $ hg clone 'ssh://fakehost%7Ctouch%20owned/path'
1168 abort: no suitable response from remote hg!
1166 abort: no suitable response from remote hg!
1169 [255]
1167 [255]
1170
1168
1171 $ hg clone 'ssh://-oProxyCommand=touch owned%20foo@example.com/nonexistent/path'
1169 $ hg clone 'ssh://-oProxyCommand=touch owned%20foo@example.com/nonexistent/path'
1172 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned foo@example.com/nonexistent/path'
1170 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned foo@example.com/nonexistent/path'
1173 [255]
1171 [255]
1174
1172
1175 #if windows
1173 #if windows
1176 $ hg clone "ssh://%26touch%20owned%20/" --debug
1174 $ hg clone "ssh://%26touch%20owned%20/" --debug
1177 running sh -c "read l; read l; read l" "&touch owned " "hg -R . serve --stdio"
1175 running sh -c "read l; read l; read l" "&touch owned " "hg -R . serve --stdio"
1178 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1176 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1179 sending hello command
1177 sending hello command
1180 sending between command
1178 sending between command
1181 abort: no suitable response from remote hg!
1179 abort: no suitable response from remote hg!
1182 [255]
1180 [255]
1183 $ hg clone "ssh://example.com:%26touch%20owned%20/" --debug
1181 $ hg clone "ssh://example.com:%26touch%20owned%20/" --debug
1184 running sh -c "read l; read l; read l" -p "&touch owned " example.com "hg -R . serve --stdio"
1182 running sh -c "read l; read l; read l" -p "&touch owned " example.com "hg -R . serve --stdio"
1185 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1183 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1186 sending hello command
1184 sending hello command
1187 sending between command
1185 sending between command
1188 abort: no suitable response from remote hg!
1186 abort: no suitable response from remote hg!
1189 [255]
1187 [255]
1190 #else
1188 #else
1191 $ hg clone "ssh://%3btouch%20owned%20/" --debug
1189 $ hg clone "ssh://%3btouch%20owned%20/" --debug
1192 running sh -c "read l; read l; read l" ';touch owned ' 'hg -R . serve --stdio'
1190 running sh -c "read l; read l; read l" ';touch owned ' 'hg -R . serve --stdio'
1193 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1191 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1194 sending hello command
1192 sending hello command
1195 sending between command
1193 sending between command
1196 abort: no suitable response from remote hg!
1194 abort: no suitable response from remote hg!
1197 [255]
1195 [255]
1198 $ hg clone "ssh://example.com:%3btouch%20owned%20/" --debug
1196 $ hg clone "ssh://example.com:%3btouch%20owned%20/" --debug
1199 running sh -c "read l; read l; read l" -p ';touch owned ' example.com 'hg -R . serve --stdio'
1197 running sh -c "read l; read l; read l" -p ';touch owned ' example.com 'hg -R . serve --stdio'
1200 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1198 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1201 sending hello command
1199 sending hello command
1202 sending between command
1200 sending between command
1203 abort: no suitable response from remote hg!
1201 abort: no suitable response from remote hg!
1204 [255]
1202 [255]
1205 #endif
1203 #endif
1206
1204
1207 $ hg clone "ssh://v-alid.example.com/" --debug
1205 $ hg clone "ssh://v-alid.example.com/" --debug
1208 running sh -c "read l; read l; read l" v-alid\.example\.com ['"]hg -R \. serve --stdio['"] (re)
1206 running sh -c "read l; read l; read l" v-alid\.example\.com ['"]hg -R \. serve --stdio['"] (re)
1209 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1207 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
1210 sending hello command
1208 sending hello command
1211 sending between command
1209 sending between command
1212 abort: no suitable response from remote hg!
1210 abort: no suitable response from remote hg!
1213 [255]
1211 [255]
1214
1212
1215 We should not have created a file named owned - if it exists, the
1213 We should not have created a file named owned - if it exists, the
1216 attack succeeded.
1214 attack succeeded.
1217 $ if test -f owned; then echo 'you got owned'; fi
1215 $ if test -f owned; then echo 'you got owned'; fi
1218
1216
1219 Cloning without fsmonitor enabled does not print a warning for small repos
1217 Cloning without fsmonitor enabled does not print a warning for small repos
1220
1218
1221 $ hg clone a fsmonitor-default
1219 $ hg clone a fsmonitor-default
1222 updating to bookmark @ on branch stable
1220 updating to bookmark @ on branch stable
1223 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1221 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1224
1222
1225 Lower the warning threshold to simulate a large repo
1223 Lower the warning threshold to simulate a large repo
1226
1224
1227 $ cat >> $HGRCPATH << EOF
1225 $ cat >> $HGRCPATH << EOF
1228 > [fsmonitor]
1226 > [fsmonitor]
1229 > warn_update_file_count = 2
1227 > warn_update_file_count = 2
1230 > EOF
1228 > EOF
1231
1229
1232 We should see a warning about no fsmonitor on supported platforms
1230 We should see a warning about no fsmonitor on supported platforms
1233
1231
1234 #if linuxormacos no-fsmonitor
1232 #if linuxormacos no-fsmonitor
1235 $ hg clone a nofsmonitor
1233 $ hg clone a nofsmonitor
1236 updating to bookmark @ on branch stable
1234 updating to bookmark @ on branch stable
1237 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1235 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1238 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1236 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1239 #else
1237 #else
1240 $ hg clone a nofsmonitor
1238 $ hg clone a nofsmonitor
1241 updating to bookmark @ on branch stable
1239 updating to bookmark @ on branch stable
1242 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1240 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1243 #endif
1241 #endif
1244
1242
1245 We should not see warning about fsmonitor when it is enabled
1243 We should not see warning about fsmonitor when it is enabled
1246
1244
1247 #if fsmonitor
1245 #if fsmonitor
1248 $ hg clone a fsmonitor-enabled
1246 $ hg clone a fsmonitor-enabled
1249 updating to bookmark @ on branch stable
1247 updating to bookmark @ on branch stable
1250 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1248 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1251 #endif
1249 #endif
1252
1250
1253 We can disable the fsmonitor warning
1251 We can disable the fsmonitor warning
1254
1252
1255 $ hg --config fsmonitor.warn_when_unused=false clone a fsmonitor-disable-warning
1253 $ hg --config fsmonitor.warn_when_unused=false clone a fsmonitor-disable-warning
1256 updating to bookmark @ on branch stable
1254 updating to bookmark @ on branch stable
1257 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1255 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1258
1256
1259 Loaded fsmonitor but disabled in config should still print warning
1257 Loaded fsmonitor but disabled in config should still print warning
1260
1258
1261 #if linuxormacos fsmonitor
1259 #if linuxormacos fsmonitor
1262 $ hg --config fsmonitor.mode=off clone a fsmonitor-mode-off
1260 $ hg --config fsmonitor.mode=off clone a fsmonitor-mode-off
1263 updating to bookmark @ on branch stable
1261 updating to bookmark @ on branch stable
1264 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (fsmonitor !)
1262 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (fsmonitor !)
1265 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1263 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1266 #endif
1264 #endif
1267
1265
1268 Warning not printed if working directory isn't empty
1266 Warning not printed if working directory isn't empty
1269
1267
1270 $ hg -q clone a fsmonitor-update
1268 $ hg -q clone a fsmonitor-update
1271 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (?)
1269 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (?)
1272 $ cd fsmonitor-update
1270 $ cd fsmonitor-update
1273 $ hg up acb14030fe0a
1271 $ hg up acb14030fe0a
1274 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1272 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1275 (leaving bookmark @)
1273 (leaving bookmark @)
1276 $ hg up cf0fe1914066
1274 $ hg up cf0fe1914066
1277 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1275 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1278
1276
1279 `hg update` from null revision also prints
1277 `hg update` from null revision also prints
1280
1278
1281 $ hg up null
1279 $ hg up null
1282 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1280 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1283
1281
1284 #if linuxormacos no-fsmonitor
1282 #if linuxormacos no-fsmonitor
1285 $ hg up cf0fe1914066
1283 $ hg up cf0fe1914066
1286 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1284 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1287 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1285 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1288 #else
1286 #else
1289 $ hg up cf0fe1914066
1287 $ hg up cf0fe1914066
1290 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1288 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1291 #endif
1289 #endif
1292
1290
1293 $ cd ..
1291 $ cd ..
1294
1292
@@ -1,656 +1,655 b''
1 $ cat << EOF >> $HGRCPATH
1 $ cat << EOF >> $HGRCPATH
2 > [ui]
2 > [ui]
3 > interactive=yes
3 > interactive=yes
4 > EOF
4 > EOF
5
5
6 $ hg init debugrevlog
6 $ hg init debugrevlog
7 $ cd debugrevlog
7 $ cd debugrevlog
8 $ echo a > a
8 $ echo a > a
9 $ hg ci -Am adda
9 $ hg ci -Am adda
10 adding a
10 adding a
11 $ hg rm .
11 $ hg rm .
12 removing a
12 removing a
13 $ hg ci -Am make-it-empty
13 $ hg ci -Am make-it-empty
14 $ hg revert --all -r 0
14 $ hg revert --all -r 0
15 adding a
15 adding a
16 $ hg ci -Am make-it-full
16 $ hg ci -Am make-it-full
17 #if reporevlogstore
17 #if reporevlogstore
18 $ hg debugrevlog -c
18 $ hg debugrevlog -c
19 format : 1
19 format : 1
20 flags : inline
20 flags : inline
21
21
22 revisions : 3
22 revisions : 3
23 merges : 0 ( 0.00%)
23 merges : 0 ( 0.00%)
24 normal : 3 (100.00%)
24 normal : 3 (100.00%)
25 revisions : 3
25 revisions : 3
26 empty : 0 ( 0.00%)
26 empty : 0 ( 0.00%)
27 text : 0 (100.00%)
27 text : 0 (100.00%)
28 delta : 0 (100.00%)
28 delta : 0 (100.00%)
29 snapshot : 3 (100.00%)
29 snapshot : 3 (100.00%)
30 lvl-0 : 3 (100.00%)
30 lvl-0 : 3 (100.00%)
31 deltas : 0 ( 0.00%)
31 deltas : 0 ( 0.00%)
32 revision size : 191
32 revision size : 191
33 snapshot : 191 (100.00%)
33 snapshot : 191 (100.00%)
34 lvl-0 : 191 (100.00%)
34 lvl-0 : 191 (100.00%)
35 deltas : 0 ( 0.00%)
35 deltas : 0 ( 0.00%)
36
36
37 chunks : 3
37 chunks : 3
38 0x75 (u) : 3 (100.00%)
38 0x75 (u) : 3 (100.00%)
39 chunks size : 191
39 chunks size : 191
40 0x75 (u) : 191 (100.00%)
40 0x75 (u) : 191 (100.00%)
41
41
42 avg chain length : 0
42 avg chain length : 0
43 max chain length : 0
43 max chain length : 0
44 max chain reach : 67
44 max chain reach : 67
45 compression ratio : 0
45 compression ratio : 0
46
46
47 uncompressed data size (min/max/avg) : 57 / 66 / 62
47 uncompressed data size (min/max/avg) : 57 / 66 / 62
48 full revision size (min/max/avg) : 58 / 67 / 63
48 full revision size (min/max/avg) : 58 / 67 / 63
49 inter-snapshot size (min/max/avg) : 0 / 0 / 0
49 inter-snapshot size (min/max/avg) : 0 / 0 / 0
50 delta size (min/max/avg) : 0 / 0 / 0
50 delta size (min/max/avg) : 0 / 0 / 0
51 $ hg debugrevlog -m
51 $ hg debugrevlog -m
52 format : 1
52 format : 1
53 flags : inline, generaldelta
53 flags : inline, generaldelta
54
54
55 revisions : 3
55 revisions : 3
56 merges : 0 ( 0.00%)
56 merges : 0 ( 0.00%)
57 normal : 3 (100.00%)
57 normal : 3 (100.00%)
58 revisions : 3
58 revisions : 3
59 empty : 1 (33.33%)
59 empty : 1 (33.33%)
60 text : 1 (100.00%)
60 text : 1 (100.00%)
61 delta : 0 ( 0.00%)
61 delta : 0 ( 0.00%)
62 snapshot : 2 (66.67%)
62 snapshot : 2 (66.67%)
63 lvl-0 : 2 (66.67%)
63 lvl-0 : 2 (66.67%)
64 deltas : 0 ( 0.00%)
64 deltas : 0 ( 0.00%)
65 revision size : 88
65 revision size : 88
66 snapshot : 88 (100.00%)
66 snapshot : 88 (100.00%)
67 lvl-0 : 88 (100.00%)
67 lvl-0 : 88 (100.00%)
68 deltas : 0 ( 0.00%)
68 deltas : 0 ( 0.00%)
69
69
70 chunks : 3
70 chunks : 3
71 empty : 1 (33.33%)
71 empty : 1 (33.33%)
72 0x75 (u) : 2 (66.67%)
72 0x75 (u) : 2 (66.67%)
73 chunks size : 88
73 chunks size : 88
74 empty : 0 ( 0.00%)
74 empty : 0 ( 0.00%)
75 0x75 (u) : 88 (100.00%)
75 0x75 (u) : 88 (100.00%)
76
76
77 avg chain length : 0
77 avg chain length : 0
78 max chain length : 0
78 max chain length : 0
79 max chain reach : 44
79 max chain reach : 44
80 compression ratio : 0
80 compression ratio : 0
81
81
82 uncompressed data size (min/max/avg) : 0 / 43 / 28
82 uncompressed data size (min/max/avg) : 0 / 43 / 28
83 full revision size (min/max/avg) : 44 / 44 / 44
83 full revision size (min/max/avg) : 44 / 44 / 44
84 inter-snapshot size (min/max/avg) : 0 / 0 / 0
84 inter-snapshot size (min/max/avg) : 0 / 0 / 0
85 delta size (min/max/avg) : 0 / 0 / 0
85 delta size (min/max/avg) : 0 / 0 / 0
86 $ hg debugrevlog a
86 $ hg debugrevlog a
87 format : 1
87 format : 1
88 flags : inline, generaldelta
88 flags : inline, generaldelta
89
89
90 revisions : 1
90 revisions : 1
91 merges : 0 ( 0.00%)
91 merges : 0 ( 0.00%)
92 normal : 1 (100.00%)
92 normal : 1 (100.00%)
93 revisions : 1
93 revisions : 1
94 empty : 0 ( 0.00%)
94 empty : 0 ( 0.00%)
95 text : 0 (100.00%)
95 text : 0 (100.00%)
96 delta : 0 (100.00%)
96 delta : 0 (100.00%)
97 snapshot : 1 (100.00%)
97 snapshot : 1 (100.00%)
98 lvl-0 : 1 (100.00%)
98 lvl-0 : 1 (100.00%)
99 deltas : 0 ( 0.00%)
99 deltas : 0 ( 0.00%)
100 revision size : 3
100 revision size : 3
101 snapshot : 3 (100.00%)
101 snapshot : 3 (100.00%)
102 lvl-0 : 3 (100.00%)
102 lvl-0 : 3 (100.00%)
103 deltas : 0 ( 0.00%)
103 deltas : 0 ( 0.00%)
104
104
105 chunks : 1
105 chunks : 1
106 0x75 (u) : 1 (100.00%)
106 0x75 (u) : 1 (100.00%)
107 chunks size : 3
107 chunks size : 3
108 0x75 (u) : 3 (100.00%)
108 0x75 (u) : 3 (100.00%)
109
109
110 avg chain length : 0
110 avg chain length : 0
111 max chain length : 0
111 max chain length : 0
112 max chain reach : 3
112 max chain reach : 3
113 compression ratio : 0
113 compression ratio : 0
114
114
115 uncompressed data size (min/max/avg) : 2 / 2 / 2
115 uncompressed data size (min/max/avg) : 2 / 2 / 2
116 full revision size (min/max/avg) : 3 / 3 / 3
116 full revision size (min/max/avg) : 3 / 3 / 3
117 inter-snapshot size (min/max/avg) : 0 / 0 / 0
117 inter-snapshot size (min/max/avg) : 0 / 0 / 0
118 delta size (min/max/avg) : 0 / 0 / 0
118 delta size (min/max/avg) : 0 / 0 / 0
119 #endif
119 #endif
120
120
121 Test debugindex, with and without the --verbose/--debug flag
121 Test debugindex, with and without the --verbose/--debug flag
122 $ hg debugrevlogindex a
122 $ hg debugrevlogindex a
123 rev linkrev nodeid p1 p2
123 rev linkrev nodeid p1 p2
124 0 0 b789fdd96dc2 000000000000 000000000000
124 0 0 b789fdd96dc2 000000000000 000000000000
125
125
126 #if no-reposimplestore
126 #if no-reposimplestore
127 $ hg --verbose debugrevlogindex a
127 $ hg --verbose debugrevlogindex a
128 rev offset length linkrev nodeid p1 p2
128 rev offset length linkrev nodeid p1 p2
129 0 0 3 0 b789fdd96dc2 000000000000 000000000000
129 0 0 3 0 b789fdd96dc2 000000000000 000000000000
130
130
131 $ hg --debug debugrevlogindex a
131 $ hg --debug debugrevlogindex a
132 rev offset length linkrev nodeid p1 p2
132 rev offset length linkrev nodeid p1 p2
133 0 0 3 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
133 0 0 3 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
134 #endif
134 #endif
135
135
136 $ hg debugrevlogindex -f 1 a
136 $ hg debugrevlogindex -f 1 a
137 rev flag size link p1 p2 nodeid
137 rev flag size link p1 p2 nodeid
138 0 0000 2 0 -1 -1 b789fdd96dc2
138 0 0000 2 0 -1 -1 b789fdd96dc2
139
139
140 #if no-reposimplestore
140 #if no-reposimplestore
141 $ hg --verbose debugrevlogindex -f 1 a
141 $ hg --verbose debugrevlogindex -f 1 a
142 rev flag offset length size link p1 p2 nodeid
142 rev flag offset length size link p1 p2 nodeid
143 0 0000 0 3 2 0 -1 -1 b789fdd96dc2
143 0 0000 0 3 2 0 -1 -1 b789fdd96dc2
144
144
145 $ hg --debug debugrevlogindex -f 1 a
145 $ hg --debug debugrevlogindex -f 1 a
146 rev flag offset length size link p1 p2 nodeid
146 rev flag offset length size link p1 p2 nodeid
147 0 0000 0 3 2 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
147 0 0000 0 3 2 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
148 #endif
148 #endif
149
149
150 $ hg debugindex -c
150 $ hg debugindex -c
151 rev linkrev nodeid p1 p2
151 rev linkrev nodeid p1 p2
152 0 0 07f494440405 000000000000 000000000000
152 0 0 07f494440405 000000000000 000000000000
153 1 1 8cccb4b5fec2 07f494440405 000000000000
153 1 1 8cccb4b5fec2 07f494440405 000000000000
154 2 2 b1e228c512c5 8cccb4b5fec2 000000000000
154 2 2 b1e228c512c5 8cccb4b5fec2 000000000000
155 $ hg debugindex -c --debug
155 $ hg debugindex -c --debug
156 rev linkrev nodeid p1 p2
156 rev linkrev nodeid p1 p2
157 0 0 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
157 0 0 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
158 1 1 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000
158 1 1 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000
159 2 2 b1e228c512c5d7066d70562ed839c3323a62d6d2 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 0000000000000000000000000000000000000000
159 2 2 b1e228c512c5d7066d70562ed839c3323a62d6d2 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 0000000000000000000000000000000000000000
160 $ hg debugindex -m
160 $ hg debugindex -m
161 rev linkrev nodeid p1 p2
161 rev linkrev nodeid p1 p2
162 0 0 a0c8bcbbb45c 000000000000 000000000000
162 0 0 a0c8bcbbb45c 000000000000 000000000000
163 1 1 57faf8a737ae a0c8bcbbb45c 000000000000
163 1 1 57faf8a737ae a0c8bcbbb45c 000000000000
164 2 2 a35b10320954 57faf8a737ae 000000000000
164 2 2 a35b10320954 57faf8a737ae 000000000000
165 $ hg debugindex -m --debug
165 $ hg debugindex -m --debug
166 rev linkrev nodeid p1 p2
166 rev linkrev nodeid p1 p2
167 0 0 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
167 0 0 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
168 1 1 57faf8a737ae7faf490582941a82319ba6529dca a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000
168 1 1 57faf8a737ae7faf490582941a82319ba6529dca a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000
169 2 2 a35b103209548032201c16c7688cb2657f037a38 57faf8a737ae7faf490582941a82319ba6529dca 0000000000000000000000000000000000000000
169 2 2 a35b103209548032201c16c7688cb2657f037a38 57faf8a737ae7faf490582941a82319ba6529dca 0000000000000000000000000000000000000000
170 $ hg debugindex a
170 $ hg debugindex a
171 rev linkrev nodeid p1 p2
171 rev linkrev nodeid p1 p2
172 0 0 b789fdd96dc2 000000000000 000000000000
172 0 0 b789fdd96dc2 000000000000 000000000000
173 $ hg debugindex --debug a
173 $ hg debugindex --debug a
174 rev linkrev nodeid p1 p2
174 rev linkrev nodeid p1 p2
175 0 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
175 0 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
176
176
177 debugdelta chain basic output
177 debugdelta chain basic output
178
178
179 #if reporevlogstore pure
179 #if reporevlogstore pure
180 $ hg debugindexstats
180 $ hg debugindexstats
181 abort: debugindexstats only works with native code
181 abort: debugindexstats only works with native code
182 [255]
182 [255]
183 #endif
183 #endif
184 #if reporevlogstore no-pure
184 #if reporevlogstore no-pure
185 $ hg debugindexstats
185 $ hg debugindexstats
186 node trie capacity: 4
186 node trie capacity: 4
187 node trie count: 2
187 node trie count: 2
188 node trie depth: 1
188 node trie depth: 1
189 node trie last rev scanned: -1
189 node trie last rev scanned: -1
190 node trie lookups: 4
190 node trie lookups: 4
191 node trie misses: 1
191 node trie misses: 1
192 node trie splits: 1
192 node trie splits: 1
193 revs in memory: 3
193 revs in memory: 3
194 #endif
194 #endif
195
195
196 #if reporevlogstore no-pure
196 #if reporevlogstore no-pure
197 $ hg debugdeltachain -m
197 $ hg debugdeltachain -m
198 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
198 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
199 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
199 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
200 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000 0 0 1.00000 1
200 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000 0 0 1.00000 1
201 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
201 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
202
202
203 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen}\n'
203 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen}\n'
204 0 1 1
204 0 1 1
205 1 2 1
205 1 2 1
206 2 3 1
206 2 3 1
207
207
208 $ hg debugdeltachain -m -Tjson
208 $ hg debugdeltachain -m -Tjson
209 [
209 [
210 {
210 {
211 "chainid": 1,
211 "chainid": 1,
212 "chainlen": 1,
212 "chainlen": 1,
213 "chainratio": 1.02325581395, (no-py3 !)
213 "chainratio": 1.02325581395, (no-py3 !)
214 "chainratio": 1.0232558139534884, (py3 !)
214 "chainratio": 1.0232558139534884, (py3 !)
215 "chainsize": 44,
215 "chainsize": 44,
216 "compsize": 44,
216 "compsize": 44,
217 "deltatype": "base",
217 "deltatype": "base",
218 "extradist": 0,
218 "extradist": 0,
219 "extraratio": 0.0,
219 "extraratio": 0.0,
220 "largestblock": 44,
220 "largestblock": 44,
221 "lindist": 44,
221 "lindist": 44,
222 "prevrev": -1,
222 "prevrev": -1,
223 "readdensity": 1.0,
223 "readdensity": 1.0,
224 "readsize": 44,
224 "readsize": 44,
225 "rev": 0,
225 "rev": 0,
226 "srchunks": 1,
226 "srchunks": 1,
227 "uncompsize": 43
227 "uncompsize": 43
228 },
228 },
229 {
229 {
230 "chainid": 2,
230 "chainid": 2,
231 "chainlen": 1,
231 "chainlen": 1,
232 "chainratio": 0,
232 "chainratio": 0,
233 "chainsize": 0,
233 "chainsize": 0,
234 "compsize": 0,
234 "compsize": 0,
235 "deltatype": "base",
235 "deltatype": "base",
236 "extradist": 0,
236 "extradist": 0,
237 "extraratio": 0,
237 "extraratio": 0,
238 "largestblock": 0,
238 "largestblock": 0,
239 "lindist": 0,
239 "lindist": 0,
240 "prevrev": -1,
240 "prevrev": -1,
241 "readdensity": 1,
241 "readdensity": 1,
242 "readsize": 0,
242 "readsize": 0,
243 "rev": 1,
243 "rev": 1,
244 "srchunks": 1,
244 "srchunks": 1,
245 "uncompsize": 0
245 "uncompsize": 0
246 },
246 },
247 {
247 {
248 "chainid": 3,
248 "chainid": 3,
249 "chainlen": 1,
249 "chainlen": 1,
250 "chainratio": 1.02325581395, (no-py3 !)
250 "chainratio": 1.02325581395, (no-py3 !)
251 "chainratio": 1.0232558139534884, (py3 !)
251 "chainratio": 1.0232558139534884, (py3 !)
252 "chainsize": 44,
252 "chainsize": 44,
253 "compsize": 44,
253 "compsize": 44,
254 "deltatype": "base",
254 "deltatype": "base",
255 "extradist": 0,
255 "extradist": 0,
256 "extraratio": 0.0,
256 "extraratio": 0.0,
257 "largestblock": 44,
257 "largestblock": 44,
258 "lindist": 44,
258 "lindist": 44,
259 "prevrev": -1,
259 "prevrev": -1,
260 "readdensity": 1.0,
260 "readdensity": 1.0,
261 "readsize": 44,
261 "readsize": 44,
262 "rev": 2,
262 "rev": 2,
263 "srchunks": 1,
263 "srchunks": 1,
264 "uncompsize": 43
264 "uncompsize": 43
265 }
265 }
266 ]
266 ]
267
267
268 debugdelta chain with sparse read enabled
268 debugdelta chain with sparse read enabled
269
269
270 $ cat >> $HGRCPATH <<EOF
270 $ cat >> $HGRCPATH <<EOF
271 > [experimental]
271 > [experimental]
272 > sparse-read = True
272 > sparse-read = True
273 > EOF
273 > EOF
274 $ hg debugdeltachain -m
274 $ hg debugdeltachain -m
275 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
275 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
276 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
276 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
277 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000 0 0 1.00000 1
277 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000 0 0 1.00000 1
278 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
278 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
279
279
280 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen} {readsize} {largestblock} {readdensity}\n'
280 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen} {readsize} {largestblock} {readdensity}\n'
281 0 1 1 44 44 1.0
281 0 1 1 44 44 1.0
282 1 2 1 0 0 1
282 1 2 1 0 0 1
283 2 3 1 44 44 1.0
283 2 3 1 44 44 1.0
284
284
285 $ hg debugdeltachain -m -Tjson
285 $ hg debugdeltachain -m -Tjson
286 [
286 [
287 {
287 {
288 "chainid": 1,
288 "chainid": 1,
289 "chainlen": 1,
289 "chainlen": 1,
290 "chainratio": 1.02325581395, (no-py3 !)
290 "chainratio": 1.02325581395, (no-py3 !)
291 "chainratio": 1.0232558139534884, (py3 !)
291 "chainratio": 1.0232558139534884, (py3 !)
292 "chainsize": 44,
292 "chainsize": 44,
293 "compsize": 44,
293 "compsize": 44,
294 "deltatype": "base",
294 "deltatype": "base",
295 "extradist": 0,
295 "extradist": 0,
296 "extraratio": 0.0,
296 "extraratio": 0.0,
297 "largestblock": 44,
297 "largestblock": 44,
298 "lindist": 44,
298 "lindist": 44,
299 "prevrev": -1,
299 "prevrev": -1,
300 "readdensity": 1.0,
300 "readdensity": 1.0,
301 "readsize": 44,
301 "readsize": 44,
302 "rev": 0,
302 "rev": 0,
303 "srchunks": 1,
303 "srchunks": 1,
304 "uncompsize": 43
304 "uncompsize": 43
305 },
305 },
306 {
306 {
307 "chainid": 2,
307 "chainid": 2,
308 "chainlen": 1,
308 "chainlen": 1,
309 "chainratio": 0,
309 "chainratio": 0,
310 "chainsize": 0,
310 "chainsize": 0,
311 "compsize": 0,
311 "compsize": 0,
312 "deltatype": "base",
312 "deltatype": "base",
313 "extradist": 0,
313 "extradist": 0,
314 "extraratio": 0,
314 "extraratio": 0,
315 "largestblock": 0,
315 "largestblock": 0,
316 "lindist": 0,
316 "lindist": 0,
317 "prevrev": -1,
317 "prevrev": -1,
318 "readdensity": 1,
318 "readdensity": 1,
319 "readsize": 0,
319 "readsize": 0,
320 "rev": 1,
320 "rev": 1,
321 "srchunks": 1,
321 "srchunks": 1,
322 "uncompsize": 0
322 "uncompsize": 0
323 },
323 },
324 {
324 {
325 "chainid": 3,
325 "chainid": 3,
326 "chainlen": 1,
326 "chainlen": 1,
327 "chainratio": 1.02325581395, (no-py3 !)
327 "chainratio": 1.02325581395, (no-py3 !)
328 "chainratio": 1.0232558139534884, (py3 !)
328 "chainratio": 1.0232558139534884, (py3 !)
329 "chainsize": 44,
329 "chainsize": 44,
330 "compsize": 44,
330 "compsize": 44,
331 "deltatype": "base",
331 "deltatype": "base",
332 "extradist": 0,
332 "extradist": 0,
333 "extraratio": 0.0,
333 "extraratio": 0.0,
334 "largestblock": 44,
334 "largestblock": 44,
335 "lindist": 44,
335 "lindist": 44,
336 "prevrev": -1,
336 "prevrev": -1,
337 "readdensity": 1.0,
337 "readdensity": 1.0,
338 "readsize": 44,
338 "readsize": 44,
339 "rev": 2,
339 "rev": 2,
340 "srchunks": 1,
340 "srchunks": 1,
341 "uncompsize": 43
341 "uncompsize": 43
342 }
342 }
343 ]
343 ]
344
344
345 $ printf "This test checks things.\n" >> a
345 $ printf "This test checks things.\n" >> a
346 $ hg ci -m a
346 $ hg ci -m a
347 $ hg branch other
347 $ hg branch other
348 marked working directory as branch other
348 marked working directory as branch other
349 (branches are permanent and global, did you want a bookmark?)
349 (branches are permanent and global, did you want a bookmark?)
350 $ for i in `$TESTDIR/seq.py 5`; do
350 $ for i in `$TESTDIR/seq.py 5`; do
351 > printf "shorter ${i}" >> a
351 > printf "shorter ${i}" >> a
352 > hg ci -m "a other:$i"
352 > hg ci -m "a other:$i"
353 > hg up -q default
353 > hg up -q default
354 > printf "for the branch default we want longer chains: ${i}" >> a
354 > printf "for the branch default we want longer chains: ${i}" >> a
355 > hg ci -m "a default:$i"
355 > hg ci -m "a default:$i"
356 > hg up -q other
356 > hg up -q other
357 > done
357 > done
358 $ hg debugdeltachain a -T '{rev} {srchunks}\n' \
358 $ hg debugdeltachain a -T '{rev} {srchunks}\n' \
359 > --config experimental.sparse-read.density-threshold=0.50 \
359 > --config experimental.sparse-read.density-threshold=0.50 \
360 > --config experimental.sparse-read.min-gap-size=0
360 > --config experimental.sparse-read.min-gap-size=0
361 0 1
361 0 1
362 1 1
362 1 1
363 2 1
363 2 1
364 3 1
364 3 1
365 4 1
365 4 1
366 5 1
366 5 1
367 6 1
367 6 1
368 7 1
368 7 1
369 8 1
369 8 1
370 9 1
370 9 1
371 10 2
371 10 2
372 11 1
372 11 1
373 $ hg --config extensions.strip= strip --no-backup -r 1
373 $ hg --config extensions.strip= strip --no-backup -r 1
374 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375
375
376 Test max chain len
376 Test max chain len
377 $ cat >> $HGRCPATH << EOF
377 $ cat >> $HGRCPATH << EOF
378 > [format]
378 > [format]
379 > maxchainlen=4
379 > maxchainlen=4
380 > EOF
380 > EOF
381
381
382 $ printf "This test checks if maxchainlen config value is respected also it can serve as basic test for debugrevlog -d <file>.\n" >> a
382 $ printf "This test checks if maxchainlen config value is respected also it can serve as basic test for debugrevlog -d <file>.\n" >> a
383 $ hg ci -m a
383 $ hg ci -m a
384 $ printf "b\n" >> a
384 $ printf "b\n" >> a
385 $ hg ci -m a
385 $ hg ci -m a
386 $ printf "c\n" >> a
386 $ printf "c\n" >> a
387 $ hg ci -m a
387 $ hg ci -m a
388 $ printf "d\n" >> a
388 $ printf "d\n" >> a
389 $ hg ci -m a
389 $ hg ci -m a
390 $ printf "e\n" >> a
390 $ printf "e\n" >> a
391 $ hg ci -m a
391 $ hg ci -m a
392 $ printf "f\n" >> a
392 $ printf "f\n" >> a
393 $ hg ci -m a
393 $ hg ci -m a
394 $ printf 'g\n' >> a
394 $ printf 'g\n' >> a
395 $ hg ci -m a
395 $ hg ci -m a
396 $ printf 'h\n' >> a
396 $ printf 'h\n' >> a
397 $ hg ci -m a
397 $ hg ci -m a
398
398
399 $ hg debugrevlog -d a
399 $ hg debugrevlog -d a
400 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
400 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
401 0 -1 -1 0 ??? 0 0 0 0 ??? ???? ? 1 0 (glob)
401 0 -1 -1 0 ??? 0 0 0 0 ??? ???? ? 1 0 (glob)
402 1 0 -1 ??? ??? 0 0 0 0 ??? ???? ? 1 1 (glob)
402 1 0 -1 ??? ??? 0 0 0 0 ??? ???? ? 1 1 (glob)
403 2 1 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
403 2 1 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
404 3 2 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
404 3 2 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
405 4 3 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 4 (glob)
405 4 3 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 4 (glob)
406 5 4 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 0 (glob)
406 5 4 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 0 (glob)
407 6 5 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 1 (glob)
407 6 5 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 1 (glob)
408 7 6 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
408 7 6 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
409 8 7 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
409 8 7 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
410 #endif
410 #endif
411
411
412 Test debuglocks command:
412 Test debuglocks command:
413
413
414 $ hg debuglocks
414 $ hg debuglocks
415 lock: free
415 lock: free
416 wlock: free
416 wlock: free
417
417
418 * Test setting the lock
418 * Test setting the lock
419
419
420 waitlock <file> will wait for file to be created. If it isn't in a reasonable
420 waitlock <file> will wait for file to be created. If it isn't in a reasonable
421 amount of time, displays error message and returns 1
421 amount of time, displays error message and returns 1
422 $ waitlock() {
422 $ waitlock() {
423 > start=`date +%s`
423 > start=`date +%s`
424 > timeout=5
424 > timeout=5
425 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do
425 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do
426 > now=`date +%s`
426 > now=`date +%s`
427 > if [ "`expr $now - $start`" -gt $timeout ]; then
427 > if [ "`expr $now - $start`" -gt $timeout ]; then
428 > echo "timeout: $1 was not created in $timeout seconds"
428 > echo "timeout: $1 was not created in $timeout seconds"
429 > return 1
429 > return 1
430 > fi
430 > fi
431 > sleep 0.1
431 > sleep 0.1
432 > done
432 > done
433 > }
433 > }
434 $ dolock() {
434 $ dolock() {
435 > {
435 > {
436 > waitlock .hg/unlock
436 > waitlock .hg/unlock
437 > rm -f .hg/unlock
437 > rm -f .hg/unlock
438 > echo y
438 > echo y
439 > } | hg debuglocks "$@" > /dev/null
439 > } | hg debuglocks "$@" > /dev/null
440 > }
440 > }
441 $ dolock -s &
441 $ dolock -s &
442 $ waitlock .hg/store/lock
442 $ waitlock .hg/store/lock
443
443
444 $ hg debuglocks
444 $ hg debuglocks
445 lock: user *, process * (*s) (glob)
445 lock: user *, process * (*s) (glob)
446 wlock: free
446 wlock: free
447 [1]
447 [1]
448 $ touch .hg/unlock
448 $ touch .hg/unlock
449 $ wait
449 $ wait
450 $ [ -f .hg/store/lock ] || echo "There is no lock"
450 $ [ -f .hg/store/lock ] || echo "There is no lock"
451 There is no lock
451 There is no lock
452
452
453 * Test setting the wlock
453 * Test setting the wlock
454
454
455 $ dolock -S &
455 $ dolock -S &
456 $ waitlock .hg/wlock
456 $ waitlock .hg/wlock
457
457
458 $ hg debuglocks
458 $ hg debuglocks
459 lock: free
459 lock: free
460 wlock: user *, process * (*s) (glob)
460 wlock: user *, process * (*s) (glob)
461 [1]
461 [1]
462 $ touch .hg/unlock
462 $ touch .hg/unlock
463 $ wait
463 $ wait
464 $ [ -f .hg/wlock ] || echo "There is no wlock"
464 $ [ -f .hg/wlock ] || echo "There is no wlock"
465 There is no wlock
465 There is no wlock
466
466
467 * Test setting both locks
467 * Test setting both locks
468
468
469 $ dolock -Ss &
469 $ dolock -Ss &
470 $ waitlock .hg/wlock && waitlock .hg/store/lock
470 $ waitlock .hg/wlock && waitlock .hg/store/lock
471
471
472 $ hg debuglocks
472 $ hg debuglocks
473 lock: user *, process * (*s) (glob)
473 lock: user *, process * (*s) (glob)
474 wlock: user *, process * (*s) (glob)
474 wlock: user *, process * (*s) (glob)
475 [2]
475 [2]
476
476
477 * Test failing to set a lock
477 * Test failing to set a lock
478
478
479 $ hg debuglocks -s
479 $ hg debuglocks -s
480 abort: lock is already held
480 abort: lock is already held
481 [255]
481 [255]
482
482
483 $ hg debuglocks -S
483 $ hg debuglocks -S
484 abort: wlock is already held
484 abort: wlock is already held
485 [255]
485 [255]
486
486
487 $ touch .hg/unlock
487 $ touch .hg/unlock
488 $ wait
488 $ wait
489
489
490 $ hg debuglocks
490 $ hg debuglocks
491 lock: free
491 lock: free
492 wlock: free
492 wlock: free
493
493
494 * Test forcing the lock
494 * Test forcing the lock
495
495
496 $ dolock -s &
496 $ dolock -s &
497 $ waitlock .hg/store/lock
497 $ waitlock .hg/store/lock
498
498
499 $ hg debuglocks
499 $ hg debuglocks
500 lock: user *, process * (*s) (glob)
500 lock: user *, process * (*s) (glob)
501 wlock: free
501 wlock: free
502 [1]
502 [1]
503
503
504 $ hg debuglocks -L
504 $ hg debuglocks -L
505
505
506 $ hg debuglocks
506 $ hg debuglocks
507 lock: free
507 lock: free
508 wlock: free
508 wlock: free
509
509
510 $ touch .hg/unlock
510 $ touch .hg/unlock
511 $ wait
511 $ wait
512
512
513 * Test forcing the wlock
513 * Test forcing the wlock
514
514
515 $ dolock -S &
515 $ dolock -S &
516 $ waitlock .hg/wlock
516 $ waitlock .hg/wlock
517
517
518 $ hg debuglocks
518 $ hg debuglocks
519 lock: free
519 lock: free
520 wlock: user *, process * (*s) (glob)
520 wlock: user *, process * (*s) (glob)
521 [1]
521 [1]
522
522
523 $ hg debuglocks -W
523 $ hg debuglocks -W
524
524
525 $ hg debuglocks
525 $ hg debuglocks
526 lock: free
526 lock: free
527 wlock: free
527 wlock: free
528
528
529 $ touch .hg/unlock
529 $ touch .hg/unlock
530 $ wait
530 $ wait
531
531
532 Test WdirUnsupported exception
532 Test WdirUnsupported exception
533
533
534 $ hg debugdata -c ffffffffffffffffffffffffffffffffffffffff
534 $ hg debugdata -c ffffffffffffffffffffffffffffffffffffffff
535 abort: working directory revision cannot be specified
535 abort: working directory revision cannot be specified
536 [255]
536 [255]
537
537
538 Test cache warming command
538 Test cache warming command
539
539
540 $ rm -rf .hg/cache/
540 $ rm -rf .hg/cache/
541 $ hg debugupdatecaches --debug
541 $ hg debugupdatecaches --debug
542 updating the branch cache
542 updating the branch cache
543 $ ls -r .hg/cache/*
543 $ ls -r .hg/cache/*
544 .hg/cache/tags2-served
544 .hg/cache/tags2-served
545 .hg/cache/tags2
545 .hg/cache/tags2
546 .hg/cache/rbc-revs-v1
546 .hg/cache/rbc-revs-v1
547 .hg/cache/rbc-names-v1
547 .hg/cache/rbc-names-v1
548 .hg/cache/manifestfulltextcache (reporevlogstore !)
549 .hg/cache/branch2-served
548 .hg/cache/branch2-served
550
549
551 Test debugcolor
550 Test debugcolor
552
551
553 #if no-windows
552 #if no-windows
554 $ hg debugcolor --style --color always | egrep 'mode|style|log\.'
553 $ hg debugcolor --style --color always | egrep 'mode|style|log\.'
555 color mode: 'ansi'
554 color mode: 'ansi'
556 available style:
555 available style:
557 \x1b[0;33mlog.changeset\x1b[0m: \x1b[0;33myellow\x1b[0m (esc)
556 \x1b[0;33mlog.changeset\x1b[0m: \x1b[0;33myellow\x1b[0m (esc)
558 #endif
557 #endif
559
558
560 $ hg debugcolor --style --color never
559 $ hg debugcolor --style --color never
561 color mode: None
560 color mode: None
562 available style:
561 available style:
563
562
564 $ cd ..
563 $ cd ..
565
564
566 Test internal debugstacktrace command
565 Test internal debugstacktrace command
567
566
568 $ cat > debugstacktrace.py << EOF
567 $ cat > debugstacktrace.py << EOF
569 > from __future__ import absolute_import
568 > from __future__ import absolute_import
570 > from mercurial import (
569 > from mercurial import (
571 > pycompat,
570 > pycompat,
572 > util,
571 > util,
573 > )
572 > )
574 > def f():
573 > def f():
575 > util.debugstacktrace(f=pycompat.stdout)
574 > util.debugstacktrace(f=pycompat.stdout)
576 > g()
575 > g()
577 > def g():
576 > def g():
578 > util.dst(b'hello from g\\n', skip=1)
577 > util.dst(b'hello from g\\n', skip=1)
579 > h()
578 > h()
580 > def h():
579 > def h():
581 > util.dst(b'hi ...\\nfrom h hidden in g', 1, depth=2)
580 > util.dst(b'hi ...\\nfrom h hidden in g', 1, depth=2)
582 > f()
581 > f()
583 > EOF
582 > EOF
584 $ "$PYTHON" debugstacktrace.py
583 $ "$PYTHON" debugstacktrace.py
585 stacktrace at:
584 stacktrace at:
586 debugstacktrace.py:14 in * (glob)
585 debugstacktrace.py:14 in * (glob)
587 debugstacktrace.py:7 in f
586 debugstacktrace.py:7 in f
588 hello from g at:
587 hello from g at:
589 debugstacktrace.py:14 in * (glob)
588 debugstacktrace.py:14 in * (glob)
590 debugstacktrace.py:8 in f
589 debugstacktrace.py:8 in f
591 hi ...
590 hi ...
592 from h hidden in g at:
591 from h hidden in g at:
593 debugstacktrace.py:8 in f
592 debugstacktrace.py:8 in f
594 debugstacktrace.py:11 in g
593 debugstacktrace.py:11 in g
595
594
596 Test debugcapabilities command:
595 Test debugcapabilities command:
597
596
598 $ hg debugcapabilities ./debugrevlog/
597 $ hg debugcapabilities ./debugrevlog/
599 Main capabilities:
598 Main capabilities:
600 branchmap
599 branchmap
601 $USUAL_BUNDLE2_CAPS$
600 $USUAL_BUNDLE2_CAPS$
602 getbundle
601 getbundle
603 known
602 known
604 lookup
603 lookup
605 pushkey
604 pushkey
606 unbundle
605 unbundle
607 Bundle2 capabilities:
606 Bundle2 capabilities:
608 HG20
607 HG20
609 bookmarks
608 bookmarks
610 changegroup
609 changegroup
611 01
610 01
612 02
611 02
613 digests
612 digests
614 md5
613 md5
615 sha1
614 sha1
616 sha512
615 sha512
617 error
616 error
618 abort
617 abort
619 unsupportedcontent
618 unsupportedcontent
620 pushraced
619 pushraced
621 pushkey
620 pushkey
622 hgtagsfnodes
621 hgtagsfnodes
623 listkeys
622 listkeys
624 phases
623 phases
625 heads
624 heads
626 pushkey
625 pushkey
627 remote-changegroup
626 remote-changegroup
628 http
627 http
629 https
628 https
630 rev-branch-cache
629 rev-branch-cache
631 stream
630 stream
632 v2
631 v2
633
632
634 Test debugpeer
633 Test debugpeer
635
634
636 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" debugpeer ssh://user@dummy/debugrevlog
635 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" debugpeer ssh://user@dummy/debugrevlog
637 url: ssh://user@dummy/debugrevlog
636 url: ssh://user@dummy/debugrevlog
638 local: no
637 local: no
639 pushable: yes
638 pushable: yes
640
639
641 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" --debug debugpeer ssh://user@dummy/debugrevlog
640 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" --debug debugpeer ssh://user@dummy/debugrevlog
642 running "*" "*/tests/dummyssh" 'user@dummy' 'hg -R debugrevlog serve --stdio' (glob) (no-windows !)
641 running "*" "*/tests/dummyssh" 'user@dummy' 'hg -R debugrevlog serve --stdio' (glob) (no-windows !)
643 running "*" "*\tests/dummyssh" "user@dummy" "hg -R debugrevlog serve --stdio" (glob) (windows !)
642 running "*" "*\tests/dummyssh" "user@dummy" "hg -R debugrevlog serve --stdio" (glob) (windows !)
644 devel-peer-request: hello+between
643 devel-peer-request: hello+between
645 devel-peer-request: pairs: 81 bytes
644 devel-peer-request: pairs: 81 bytes
646 sending hello command
645 sending hello command
647 sending between command
646 sending between command
648 remote: 440
647 remote: 440
649 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
648 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
650 remote: 1
649 remote: 1
651 devel-peer-request: protocaps
650 devel-peer-request: protocaps
652 devel-peer-request: caps: * bytes (glob)
651 devel-peer-request: caps: * bytes (glob)
653 sending protocaps command
652 sending protocaps command
654 url: ssh://user@dummy/debugrevlog
653 url: ssh://user@dummy/debugrevlog
655 local: no
654 local: no
656 pushable: yes
655 pushable: yes
@@ -1,518 +1,518 b''
1 #require repofncache
1 #require repofncache
2
2
3 Init repo1:
3 Init repo1:
4
4
5 $ hg init repo1
5 $ hg init repo1
6 $ cd repo1
6 $ cd repo1
7 $ echo "some text" > a
7 $ echo "some text" > a
8 $ hg add
8 $ hg add
9 adding a
9 adding a
10 $ hg ci -m first
10 $ hg ci -m first
11 $ cat .hg/store/fncache | sort
11 $ cat .hg/store/fncache | sort
12 data/a.i
12 data/a.i
13
13
14 Testing a.i/b:
14 Testing a.i/b:
15
15
16 $ mkdir a.i
16 $ mkdir a.i
17 $ echo "some other text" > a.i/b
17 $ echo "some other text" > a.i/b
18 $ hg add
18 $ hg add
19 adding a.i/b
19 adding a.i/b
20 $ hg ci -m second
20 $ hg ci -m second
21 $ cat .hg/store/fncache | sort
21 $ cat .hg/store/fncache | sort
22 data/a.i
22 data/a.i
23 data/a.i.hg/b.i
23 data/a.i.hg/b.i
24
24
25 Testing a.i.hg/c:
25 Testing a.i.hg/c:
26
26
27 $ mkdir a.i.hg
27 $ mkdir a.i.hg
28 $ echo "yet another text" > a.i.hg/c
28 $ echo "yet another text" > a.i.hg/c
29 $ hg add
29 $ hg add
30 adding a.i.hg/c
30 adding a.i.hg/c
31 $ hg ci -m third
31 $ hg ci -m third
32 $ cat .hg/store/fncache | sort
32 $ cat .hg/store/fncache | sort
33 data/a.i
33 data/a.i
34 data/a.i.hg.hg/c.i
34 data/a.i.hg.hg/c.i
35 data/a.i.hg/b.i
35 data/a.i.hg/b.i
36
36
37 Testing verify:
37 Testing verify:
38
38
39 $ hg verify
39 $ hg verify
40 checking changesets
40 checking changesets
41 checking manifests
41 checking manifests
42 crosschecking files in changesets and manifests
42 crosschecking files in changesets and manifests
43 checking files
43 checking files
44 checked 3 changesets with 3 changes to 3 files
44 checked 3 changesets with 3 changes to 3 files
45
45
46 $ rm .hg/store/fncache
46 $ rm .hg/store/fncache
47
47
48 $ hg verify
48 $ hg verify
49 checking changesets
49 checking changesets
50 checking manifests
50 checking manifests
51 crosschecking files in changesets and manifests
51 crosschecking files in changesets and manifests
52 checking files
52 checking files
53 warning: revlog 'data/a.i' not in fncache!
53 warning: revlog 'data/a.i' not in fncache!
54 warning: revlog 'data/a.i.hg/c.i' not in fncache!
54 warning: revlog 'data/a.i.hg/c.i' not in fncache!
55 warning: revlog 'data/a.i/b.i' not in fncache!
55 warning: revlog 'data/a.i/b.i' not in fncache!
56 checked 3 changesets with 3 changes to 3 files
56 checked 3 changesets with 3 changes to 3 files
57 3 warnings encountered!
57 3 warnings encountered!
58 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
58 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
59
59
60 Follow the hint to make sure it works
60 Follow the hint to make sure it works
61
61
62 $ hg debugrebuildfncache
62 $ hg debugrebuildfncache
63 adding data/a.i
63 adding data/a.i
64 adding data/a.i.hg/c.i
64 adding data/a.i.hg/c.i
65 adding data/a.i/b.i
65 adding data/a.i/b.i
66 3 items added, 0 removed from fncache
66 3 items added, 0 removed from fncache
67
67
68 $ hg verify
68 $ hg verify
69 checking changesets
69 checking changesets
70 checking manifests
70 checking manifests
71 crosschecking files in changesets and manifests
71 crosschecking files in changesets and manifests
72 checking files
72 checking files
73 checked 3 changesets with 3 changes to 3 files
73 checked 3 changesets with 3 changes to 3 files
74
74
75 $ cd ..
75 $ cd ..
76
76
77 Non store repo:
77 Non store repo:
78
78
79 $ hg --config format.usestore=False init foo
79 $ hg --config format.usestore=False init foo
80 $ cd foo
80 $ cd foo
81 $ mkdir tst.d
81 $ mkdir tst.d
82 $ echo foo > tst.d/foo
82 $ echo foo > tst.d/foo
83 $ hg ci -Amfoo
83 $ hg ci -Amfoo
84 adding tst.d/foo
84 adding tst.d/foo
85 $ find .hg | sort
85 $ find .hg | sort
86 .hg
86 .hg
87 .hg/00changelog.i
87 .hg/00changelog.i
88 .hg/00manifest.i
88 .hg/00manifest.i
89 .hg/cache
89 .hg/cache
90 .hg/cache/branch2-served
90 .hg/cache/branch2-served
91 .hg/cache/manifestfulltextcache (reporevlogstore !)
92 .hg/cache/rbc-names-v1
91 .hg/cache/rbc-names-v1
93 .hg/cache/rbc-revs-v1
92 .hg/cache/rbc-revs-v1
94 .hg/data
93 .hg/data
95 .hg/data/tst.d.hg
94 .hg/data/tst.d.hg
96 .hg/data/tst.d.hg/foo.i
95 .hg/data/tst.d.hg/foo.i
97 .hg/dirstate
96 .hg/dirstate
98 .hg/fsmonitor.state (fsmonitor !)
97 .hg/fsmonitor.state (fsmonitor !)
99 .hg/last-message.txt
98 .hg/last-message.txt
100 .hg/phaseroots
99 .hg/phaseroots
101 .hg/requires
100 .hg/requires
102 .hg/undo
101 .hg/undo
103 .hg/undo.backup.dirstate
102 .hg/undo.backup.dirstate
104 .hg/undo.backupfiles
103 .hg/undo.backupfiles
105 .hg/undo.bookmarks
104 .hg/undo.bookmarks
106 .hg/undo.branch
105 .hg/undo.branch
107 .hg/undo.desc
106 .hg/undo.desc
108 .hg/undo.dirstate
107 .hg/undo.dirstate
109 .hg/undo.phaseroots
108 .hg/undo.phaseroots
110 .hg/wcache
109 .hg/wcache
111 .hg/wcache/checkisexec (execbit !)
110 .hg/wcache/checkisexec (execbit !)
112 .hg/wcache/checklink (symlink !)
111 .hg/wcache/checklink (symlink !)
113 .hg/wcache/checklink-target (symlink !)
112 .hg/wcache/checklink-target (symlink !)
113 .hg/wcache/manifestfulltextcache (reporevlogstore !)
114 $ cd ..
114 $ cd ..
115
115
116 Non fncache repo:
116 Non fncache repo:
117
117
118 $ hg --config format.usefncache=False init bar
118 $ hg --config format.usefncache=False init bar
119 $ cd bar
119 $ cd bar
120 $ mkdir tst.d
120 $ mkdir tst.d
121 $ echo foo > tst.d/Foo
121 $ echo foo > tst.d/Foo
122 $ hg ci -Amfoo
122 $ hg ci -Amfoo
123 adding tst.d/Foo
123 adding tst.d/Foo
124 $ find .hg | sort
124 $ find .hg | sort
125 .hg
125 .hg
126 .hg/00changelog.i
126 .hg/00changelog.i
127 .hg/cache
127 .hg/cache
128 .hg/cache/branch2-served
128 .hg/cache/branch2-served
129 .hg/cache/manifestfulltextcache (reporevlogstore !)
130 .hg/cache/rbc-names-v1
129 .hg/cache/rbc-names-v1
131 .hg/cache/rbc-revs-v1
130 .hg/cache/rbc-revs-v1
132 .hg/dirstate
131 .hg/dirstate
133 .hg/fsmonitor.state (fsmonitor !)
132 .hg/fsmonitor.state (fsmonitor !)
134 .hg/last-message.txt
133 .hg/last-message.txt
135 .hg/requires
134 .hg/requires
136 .hg/store
135 .hg/store
137 .hg/store/00changelog.i
136 .hg/store/00changelog.i
138 .hg/store/00manifest.i
137 .hg/store/00manifest.i
139 .hg/store/data
138 .hg/store/data
140 .hg/store/data/tst.d.hg
139 .hg/store/data/tst.d.hg
141 .hg/store/data/tst.d.hg/_foo.i
140 .hg/store/data/tst.d.hg/_foo.i
142 .hg/store/phaseroots
141 .hg/store/phaseroots
143 .hg/store/undo
142 .hg/store/undo
144 .hg/store/undo.backupfiles
143 .hg/store/undo.backupfiles
145 .hg/store/undo.phaseroots
144 .hg/store/undo.phaseroots
146 .hg/undo.backup.dirstate
145 .hg/undo.backup.dirstate
147 .hg/undo.bookmarks
146 .hg/undo.bookmarks
148 .hg/undo.branch
147 .hg/undo.branch
149 .hg/undo.desc
148 .hg/undo.desc
150 .hg/undo.dirstate
149 .hg/undo.dirstate
151 .hg/wcache
150 .hg/wcache
152 .hg/wcache/checkisexec (execbit !)
151 .hg/wcache/checkisexec (execbit !)
153 .hg/wcache/checklink (symlink !)
152 .hg/wcache/checklink (symlink !)
154 .hg/wcache/checklink-target (symlink !)
153 .hg/wcache/checklink-target (symlink !)
154 .hg/wcache/manifestfulltextcache (reporevlogstore !)
155 $ cd ..
155 $ cd ..
156
156
157 Encoding of reserved / long paths in the store
157 Encoding of reserved / long paths in the store
158
158
159 $ hg init r2
159 $ hg init r2
160 $ cd r2
160 $ cd r2
161 $ cat <<EOF > .hg/hgrc
161 $ cat <<EOF > .hg/hgrc
162 > [ui]
162 > [ui]
163 > portablefilenames = ignore
163 > portablefilenames = ignore
164 > EOF
164 > EOF
165
165
166 $ hg import -q --bypass - <<EOF
166 $ hg import -q --bypass - <<EOF
167 > # HG changeset patch
167 > # HG changeset patch
168 > # User test
168 > # User test
169 > # Date 0 0
169 > # Date 0 0
170 > # Node ID 1c7a2f7cb77be1a0def34e4c7cabc562ad98fbd7
170 > # Node ID 1c7a2f7cb77be1a0def34e4c7cabc562ad98fbd7
171 > # Parent 0000000000000000000000000000000000000000
171 > # Parent 0000000000000000000000000000000000000000
172 > 1
172 > 1
173 >
173 >
174 > diff --git a/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
174 > diff --git a/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
175 > new file mode 100644
175 > new file mode 100644
176 > --- /dev/null
176 > --- /dev/null
177 > +++ b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
177 > +++ b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
178 > @@ -0,0 +1,1 @@
178 > @@ -0,0 +1,1 @@
179 > +foo
179 > +foo
180 > diff --git a/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
180 > diff --git a/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
181 > new file mode 100644
181 > new file mode 100644
182 > --- /dev/null
182 > --- /dev/null
183 > +++ b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
183 > +++ b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
184 > @@ -0,0 +1,1 @@
184 > @@ -0,0 +1,1 @@
185 > +foo
185 > +foo
186 > diff --git a/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
186 > diff --git a/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
187 > new file mode 100644
187 > new file mode 100644
188 > --- /dev/null
188 > --- /dev/null
189 > +++ b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
189 > +++ b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
190 > @@ -0,0 +1,1 @@
190 > @@ -0,0 +1,1 @@
191 > +foo
191 > +foo
192 > diff --git a/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
192 > diff --git a/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
193 > new file mode 100644
193 > new file mode 100644
194 > --- /dev/null
194 > --- /dev/null
195 > +++ b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
195 > +++ b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
196 > @@ -0,0 +1,1 @@
196 > @@ -0,0 +1,1 @@
197 > +foo
197 > +foo
198 > diff --git a/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
198 > diff --git a/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
199 > new file mode 100644
199 > new file mode 100644
200 > --- /dev/null
200 > --- /dev/null
201 > +++ b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
201 > +++ b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
202 > @@ -0,0 +1,1 @@
202 > @@ -0,0 +1,1 @@
203 > +foo
203 > +foo
204 > EOF
204 > EOF
205
205
206 $ find .hg/store -name *.i | sort
206 $ find .hg/store -name *.i | sort
207 .hg/store/00changelog.i
207 .hg/store/00changelog.i
208 .hg/store/00manifest.i
208 .hg/store/00manifest.i
209 .hg/store/data/bla.aux/pr~6e/_p_r_n/lpt/co~6d3/nu~6c/coma/foo._n_u_l/normal.c.i
209 .hg/store/data/bla.aux/pr~6e/_p_r_n/lpt/co~6d3/nu~6c/coma/foo._n_u_l/normal.c.i
210 .hg/store/dh/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxx168e07b38e65eff86ab579afaaa8e30bfbe0f35f.i
210 .hg/store/dh/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxx168e07b38e65eff86ab579afaaa8e30bfbe0f35f.i
211 .hg/store/dh/au~78/second/x.prn/fourth/fi~3afth/sixth/seventh/eighth/nineth/tenth/loremia20419e358ddff1bf8751e38288aff1d7c32ec05.i
211 .hg/store/dh/au~78/second/x.prn/fourth/fi~3afth/sixth/seventh/eighth/nineth/tenth/loremia20419e358ddff1bf8751e38288aff1d7c32ec05.i
212 .hg/store/dh/enterpri/openesba/contrib-/corba-bc/netbeans/wsdlexte/src/main/java/org.net7018f27961fdf338a598a40c4683429e7ffb9743.i
212 .hg/store/dh/enterpri/openesba/contrib-/corba-bc/netbeans/wsdlexte/src/main/java/org.net7018f27961fdf338a598a40c4683429e7ffb9743.i
213 .hg/store/dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilename0d8e1f4187c650e2f1fdca9fd90f786bc0976b6b.i
213 .hg/store/dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilename0d8e1f4187c650e2f1fdca9fd90f786bc0976b6b.i
214
214
215 $ cd ..
215 $ cd ..
216
216
217 Aborting lock does not prevent fncache writes
217 Aborting lock does not prevent fncache writes
218
218
219 $ cat > exceptionext.py <<EOF
219 $ cat > exceptionext.py <<EOF
220 > from __future__ import absolute_import
220 > from __future__ import absolute_import
221 > import os
221 > import os
222 > from mercurial import commands, error, extensions
222 > from mercurial import commands, error, extensions
223 >
223 >
224 > def lockexception(orig, vfs, lockname, wait, releasefn, *args, **kwargs):
224 > def lockexception(orig, vfs, lockname, wait, releasefn, *args, **kwargs):
225 > def releasewrap():
225 > def releasewrap():
226 > l.held = False # ensure __del__ is a noop
226 > l.held = False # ensure __del__ is a noop
227 > raise error.Abort("forced lock failure")
227 > raise error.Abort("forced lock failure")
228 > l = orig(vfs, lockname, wait, releasewrap, *args, **kwargs)
228 > l = orig(vfs, lockname, wait, releasewrap, *args, **kwargs)
229 > return l
229 > return l
230 >
230 >
231 > def reposetup(ui, repo):
231 > def reposetup(ui, repo):
232 > extensions.wrapfunction(repo, '_lock', lockexception)
232 > extensions.wrapfunction(repo, '_lock', lockexception)
233 >
233 >
234 > cmdtable = {}
234 > cmdtable = {}
235 >
235 >
236 > # wrap "commit" command to prevent wlock from being '__del__()'-ed
236 > # wrap "commit" command to prevent wlock from being '__del__()'-ed
237 > # at the end of dispatching (for intentional "forced lcok failure")
237 > # at the end of dispatching (for intentional "forced lcok failure")
238 > def commitwrap(orig, ui, repo, *pats, **opts):
238 > def commitwrap(orig, ui, repo, *pats, **opts):
239 > repo = repo.unfiltered() # to use replaced repo._lock certainly
239 > repo = repo.unfiltered() # to use replaced repo._lock certainly
240 > wlock = repo.wlock()
240 > wlock = repo.wlock()
241 > try:
241 > try:
242 > return orig(ui, repo, *pats, **opts)
242 > return orig(ui, repo, *pats, **opts)
243 > finally:
243 > finally:
244 > # multiple 'relase()' is needed for complete releasing wlock,
244 > # multiple 'relase()' is needed for complete releasing wlock,
245 > # because "forced" abort at last releasing store lock
245 > # because "forced" abort at last releasing store lock
246 > # prevents wlock from being released at same 'lockmod.release()'
246 > # prevents wlock from being released at same 'lockmod.release()'
247 > for i in range(wlock.held):
247 > for i in range(wlock.held):
248 > wlock.release()
248 > wlock.release()
249 >
249 >
250 > def extsetup(ui):
250 > def extsetup(ui):
251 > extensions.wrapcommand(commands.table, b"commit", commitwrap)
251 > extensions.wrapcommand(commands.table, b"commit", commitwrap)
252 > EOF
252 > EOF
253 $ extpath=`pwd`/exceptionext.py
253 $ extpath=`pwd`/exceptionext.py
254 $ hg init fncachetxn
254 $ hg init fncachetxn
255 $ cd fncachetxn
255 $ cd fncachetxn
256 $ printf "[extensions]\nexceptionext=$extpath\n" >> .hg/hgrc
256 $ printf "[extensions]\nexceptionext=$extpath\n" >> .hg/hgrc
257 $ touch y
257 $ touch y
258 $ hg ci -qAm y
258 $ hg ci -qAm y
259 abort: forced lock failure
259 abort: forced lock failure
260 [255]
260 [255]
261 $ cat .hg/store/fncache
261 $ cat .hg/store/fncache
262 data/y.i
262 data/y.i
263
263
264 Aborting transaction prevents fncache change
264 Aborting transaction prevents fncache change
265
265
266 $ cat > ../exceptionext.py <<EOF
266 $ cat > ../exceptionext.py <<EOF
267 > from __future__ import absolute_import
267 > from __future__ import absolute_import
268 > import os
268 > import os
269 > from mercurial import commands, error, extensions, localrepo
269 > from mercurial import commands, error, extensions, localrepo
270 >
270 >
271 > def wrapper(orig, self, *args, **kwargs):
271 > def wrapper(orig, self, *args, **kwargs):
272 > tr = orig(self, *args, **kwargs)
272 > tr = orig(self, *args, **kwargs)
273 > def fail(tr):
273 > def fail(tr):
274 > raise error.Abort(b"forced transaction failure")
274 > raise error.Abort(b"forced transaction failure")
275 > # zzz prefix to ensure it sorted after store.write
275 > # zzz prefix to ensure it sorted after store.write
276 > tr.addfinalize(b'zzz-forcefails', fail)
276 > tr.addfinalize(b'zzz-forcefails', fail)
277 > return tr
277 > return tr
278 >
278 >
279 > def uisetup(ui):
279 > def uisetup(ui):
280 > extensions.wrapfunction(
280 > extensions.wrapfunction(
281 > localrepo.localrepository, b'transaction', wrapper)
281 > localrepo.localrepository, b'transaction', wrapper)
282 >
282 >
283 > cmdtable = {}
283 > cmdtable = {}
284 >
284 >
285 > EOF
285 > EOF
286
286
287 Clean cached version
287 Clean cached version
288 $ rm -f "${extpath}c"
288 $ rm -f "${extpath}c"
289 $ rm -Rf "`dirname $extpath`/__pycache__"
289 $ rm -Rf "`dirname $extpath`/__pycache__"
290
290
291 $ touch z
291 $ touch z
292 $ hg ci -qAm z
292 $ hg ci -qAm z
293 transaction abort!
293 transaction abort!
294 rollback completed
294 rollback completed
295 abort: forced transaction failure
295 abort: forced transaction failure
296 [255]
296 [255]
297 $ cat .hg/store/fncache
297 $ cat .hg/store/fncache
298 data/y.i
298 data/y.i
299
299
300 Aborted transactions can be recovered later
300 Aborted transactions can be recovered later
301
301
302 $ cat > ../exceptionext.py <<EOF
302 $ cat > ../exceptionext.py <<EOF
303 > from __future__ import absolute_import
303 > from __future__ import absolute_import
304 > import os
304 > import os
305 > from mercurial import (
305 > from mercurial import (
306 > commands,
306 > commands,
307 > error,
307 > error,
308 > extensions,
308 > extensions,
309 > localrepo,
309 > localrepo,
310 > transaction,
310 > transaction,
311 > )
311 > )
312 >
312 >
313 > def trwrapper(orig, self, *args, **kwargs):
313 > def trwrapper(orig, self, *args, **kwargs):
314 > tr = orig(self, *args, **kwargs)
314 > tr = orig(self, *args, **kwargs)
315 > def fail(tr):
315 > def fail(tr):
316 > raise error.Abort(b"forced transaction failure")
316 > raise error.Abort(b"forced transaction failure")
317 > # zzz prefix to ensure it sorted after store.write
317 > # zzz prefix to ensure it sorted after store.write
318 > tr.addfinalize(b'zzz-forcefails', fail)
318 > tr.addfinalize(b'zzz-forcefails', fail)
319 > return tr
319 > return tr
320 >
320 >
321 > def abortwrapper(orig, self, *args, **kwargs):
321 > def abortwrapper(orig, self, *args, **kwargs):
322 > raise error.Abort(b"forced transaction failure")
322 > raise error.Abort(b"forced transaction failure")
323 >
323 >
324 > def uisetup(ui):
324 > def uisetup(ui):
325 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
325 > extensions.wrapfunction(localrepo.localrepository, 'transaction',
326 > trwrapper)
326 > trwrapper)
327 > extensions.wrapfunction(transaction.transaction, '_abort',
327 > extensions.wrapfunction(transaction.transaction, '_abort',
328 > abortwrapper)
328 > abortwrapper)
329 >
329 >
330 > cmdtable = {}
330 > cmdtable = {}
331 >
331 >
332 > EOF
332 > EOF
333
333
334 Clean cached versions
334 Clean cached versions
335 $ rm -f "${extpath}c"
335 $ rm -f "${extpath}c"
336 $ rm -Rf "`dirname $extpath`/__pycache__"
336 $ rm -Rf "`dirname $extpath`/__pycache__"
337
337
338 $ hg up -q 1
338 $ hg up -q 1
339 $ touch z
339 $ touch z
340 $ hg ci -qAm z 2>/dev/null
340 $ hg ci -qAm z 2>/dev/null
341 [255]
341 [255]
342 $ cat .hg/store/fncache | sort
342 $ cat .hg/store/fncache | sort
343 data/y.i
343 data/y.i
344 data/z.i
344 data/z.i
345 $ hg recover
345 $ hg recover
346 rolling back interrupted transaction
346 rolling back interrupted transaction
347 checking changesets
347 checking changesets
348 checking manifests
348 checking manifests
349 crosschecking files in changesets and manifests
349 crosschecking files in changesets and manifests
350 checking files
350 checking files
351 checked 1 changesets with 1 changes to 1 files
351 checked 1 changesets with 1 changes to 1 files
352 $ cat .hg/store/fncache
352 $ cat .hg/store/fncache
353 data/y.i
353 data/y.i
354
354
355 $ cd ..
355 $ cd ..
356
356
357 debugrebuildfncache does nothing unless repo has fncache requirement
357 debugrebuildfncache does nothing unless repo has fncache requirement
358
358
359 $ hg --config format.usefncache=false init nofncache
359 $ hg --config format.usefncache=false init nofncache
360 $ cd nofncache
360 $ cd nofncache
361 $ hg debugrebuildfncache
361 $ hg debugrebuildfncache
362 (not rebuilding fncache because repository does not support fncache)
362 (not rebuilding fncache because repository does not support fncache)
363
363
364 $ cd ..
364 $ cd ..
365
365
366 debugrebuildfncache works on empty repository
366 debugrebuildfncache works on empty repository
367
367
368 $ hg init empty
368 $ hg init empty
369 $ cd empty
369 $ cd empty
370 $ hg debugrebuildfncache
370 $ hg debugrebuildfncache
371 fncache already up to date
371 fncache already up to date
372 $ cd ..
372 $ cd ..
373
373
374 debugrebuildfncache on an up to date repository no-ops
374 debugrebuildfncache on an up to date repository no-ops
375
375
376 $ hg init repo
376 $ hg init repo
377 $ cd repo
377 $ cd repo
378 $ echo initial > foo
378 $ echo initial > foo
379 $ echo initial > .bar
379 $ echo initial > .bar
380 $ hg commit -A -m initial
380 $ hg commit -A -m initial
381 adding .bar
381 adding .bar
382 adding foo
382 adding foo
383
383
384 $ cat .hg/store/fncache | sort
384 $ cat .hg/store/fncache | sort
385 data/.bar.i
385 data/.bar.i
386 data/foo.i
386 data/foo.i
387
387
388 $ hg debugrebuildfncache
388 $ hg debugrebuildfncache
389 fncache already up to date
389 fncache already up to date
390
390
391 debugrebuildfncache restores deleted fncache file
391 debugrebuildfncache restores deleted fncache file
392
392
393 $ rm -f .hg/store/fncache
393 $ rm -f .hg/store/fncache
394 $ hg debugrebuildfncache
394 $ hg debugrebuildfncache
395 adding data/.bar.i
395 adding data/.bar.i
396 adding data/foo.i
396 adding data/foo.i
397 2 items added, 0 removed from fncache
397 2 items added, 0 removed from fncache
398
398
399 $ cat .hg/store/fncache | sort
399 $ cat .hg/store/fncache | sort
400 data/.bar.i
400 data/.bar.i
401 data/foo.i
401 data/foo.i
402
402
403 Rebuild after rebuild should no-op
403 Rebuild after rebuild should no-op
404
404
405 $ hg debugrebuildfncache
405 $ hg debugrebuildfncache
406 fncache already up to date
406 fncache already up to date
407
407
408 A single missing file should get restored, an extra file should be removed
408 A single missing file should get restored, an extra file should be removed
409
409
410 $ cat > .hg/store/fncache << EOF
410 $ cat > .hg/store/fncache << EOF
411 > data/foo.i
411 > data/foo.i
412 > data/bad-entry.i
412 > data/bad-entry.i
413 > EOF
413 > EOF
414
414
415 $ hg debugrebuildfncache
415 $ hg debugrebuildfncache
416 removing data/bad-entry.i
416 removing data/bad-entry.i
417 adding data/.bar.i
417 adding data/.bar.i
418 1 items added, 1 removed from fncache
418 1 items added, 1 removed from fncache
419
419
420 $ cat .hg/store/fncache | sort
420 $ cat .hg/store/fncache | sort
421 data/.bar.i
421 data/.bar.i
422 data/foo.i
422 data/foo.i
423
423
424 $ cd ..
424 $ cd ..
425
425
426 Try a simple variation without dotencode to ensure fncache is ignorant of encoding
426 Try a simple variation without dotencode to ensure fncache is ignorant of encoding
427
427
428 $ hg --config format.dotencode=false init nodotencode
428 $ hg --config format.dotencode=false init nodotencode
429 $ cd nodotencode
429 $ cd nodotencode
430 $ echo initial > foo
430 $ echo initial > foo
431 $ echo initial > .bar
431 $ echo initial > .bar
432 $ hg commit -A -m initial
432 $ hg commit -A -m initial
433 adding .bar
433 adding .bar
434 adding foo
434 adding foo
435
435
436 $ cat .hg/store/fncache | sort
436 $ cat .hg/store/fncache | sort
437 data/.bar.i
437 data/.bar.i
438 data/foo.i
438 data/foo.i
439
439
440 $ rm .hg/store/fncache
440 $ rm .hg/store/fncache
441 $ hg debugrebuildfncache
441 $ hg debugrebuildfncache
442 adding data/.bar.i
442 adding data/.bar.i
443 adding data/foo.i
443 adding data/foo.i
444 2 items added, 0 removed from fncache
444 2 items added, 0 removed from fncache
445
445
446 $ cat .hg/store/fncache | sort
446 $ cat .hg/store/fncache | sort
447 data/.bar.i
447 data/.bar.i
448 data/foo.i
448 data/foo.i
449
449
450 $ cd ..
450 $ cd ..
451
451
452 In repositories that have accumulated a large number of files over time, the
452 In repositories that have accumulated a large number of files over time, the
453 fncache file is going to be large. If we possibly can avoid loading it, so much the better.
453 fncache file is going to be large. If we possibly can avoid loading it, so much the better.
454 The cache should not loaded when committing changes to existing files, or when unbundling
454 The cache should not loaded when committing changes to existing files, or when unbundling
455 changesets that only contain changes to existing files:
455 changesets that only contain changes to existing files:
456
456
457 $ cat > fncacheloadwarn.py << EOF
457 $ cat > fncacheloadwarn.py << EOF
458 > from __future__ import absolute_import
458 > from __future__ import absolute_import
459 > from mercurial import extensions, localrepo
459 > from mercurial import extensions, localrepo
460 >
460 >
461 > def extsetup(ui):
461 > def extsetup(ui):
462 > def wrapstore(orig, requirements, *args):
462 > def wrapstore(orig, requirements, *args):
463 > store = orig(requirements, *args)
463 > store = orig(requirements, *args)
464 > if b'store' in requirements and b'fncache' in requirements:
464 > if b'store' in requirements and b'fncache' in requirements:
465 > instrumentfncachestore(store, ui)
465 > instrumentfncachestore(store, ui)
466 > return store
466 > return store
467 > extensions.wrapfunction(localrepo, 'makestore', wrapstore)
467 > extensions.wrapfunction(localrepo, 'makestore', wrapstore)
468 >
468 >
469 > def instrumentfncachestore(fncachestore, ui):
469 > def instrumentfncachestore(fncachestore, ui):
470 > class instrumentedfncache(type(fncachestore.fncache)):
470 > class instrumentedfncache(type(fncachestore.fncache)):
471 > def _load(self):
471 > def _load(self):
472 > ui.warn(b'fncache load triggered!\n')
472 > ui.warn(b'fncache load triggered!\n')
473 > super(instrumentedfncache, self)._load()
473 > super(instrumentedfncache, self)._load()
474 > fncachestore.fncache.__class__ = instrumentedfncache
474 > fncachestore.fncache.__class__ = instrumentedfncache
475 > EOF
475 > EOF
476
476
477 $ fncachextpath=`pwd`/fncacheloadwarn.py
477 $ fncachextpath=`pwd`/fncacheloadwarn.py
478 $ hg init nofncacheload
478 $ hg init nofncacheload
479 $ cd nofncacheload
479 $ cd nofncacheload
480 $ printf "[extensions]\nfncacheloadwarn=$fncachextpath\n" >> .hg/hgrc
480 $ printf "[extensions]\nfncacheloadwarn=$fncachextpath\n" >> .hg/hgrc
481
481
482 A new file should trigger a load, as we'd want to update the fncache set in that case:
482 A new file should trigger a load, as we'd want to update the fncache set in that case:
483
483
484 $ touch foo
484 $ touch foo
485 $ hg ci -qAm foo
485 $ hg ci -qAm foo
486 fncache load triggered!
486 fncache load triggered!
487
487
488 But modifying that file should not:
488 But modifying that file should not:
489
489
490 $ echo bar >> foo
490 $ echo bar >> foo
491 $ hg ci -qm foo
491 $ hg ci -qm foo
492
492
493 If a transaction has been aborted, the zero-size truncated index file will
493 If a transaction has been aborted, the zero-size truncated index file will
494 not prevent the fncache from being loaded; rather than actually abort
494 not prevent the fncache from being loaded; rather than actually abort
495 a transaction, we simulate the situation by creating a zero-size index file:
495 a transaction, we simulate the situation by creating a zero-size index file:
496
496
497 $ touch .hg/store/data/bar.i
497 $ touch .hg/store/data/bar.i
498 $ touch bar
498 $ touch bar
499 $ hg ci -qAm bar
499 $ hg ci -qAm bar
500 fncache load triggered!
500 fncache load triggered!
501
501
502 Unbundling should follow the same rules; existing files should not cause a load:
502 Unbundling should follow the same rules; existing files should not cause a load:
503
503
504 $ hg clone -q . tobundle
504 $ hg clone -q . tobundle
505 $ echo 'new line' > tobundle/bar
505 $ echo 'new line' > tobundle/bar
506 $ hg -R tobundle ci -qm bar
506 $ hg -R tobundle ci -qm bar
507 $ hg -R tobundle bundle -q barupdated.hg
507 $ hg -R tobundle bundle -q barupdated.hg
508 $ hg unbundle -q barupdated.hg
508 $ hg unbundle -q barupdated.hg
509
509
510 but adding new files should:
510 but adding new files should:
511
511
512 $ touch tobundle/newfile
512 $ touch tobundle/newfile
513 $ hg -R tobundle ci -qAm newfile
513 $ hg -R tobundle ci -qAm newfile
514 $ hg -R tobundle bundle -q newfile.hg
514 $ hg -R tobundle bundle -q newfile.hg
515 $ hg unbundle -q newfile.hg
515 $ hg unbundle -q newfile.hg
516 fncache load triggered!
516 fncache load triggered!
517
517
518 $ cd ..
518 $ cd ..
@@ -1,432 +1,432 b''
1 #require hardlink reporevlogstore
1 #require hardlink reporevlogstore
2
2
3 $ cat > nlinks.py <<EOF
3 $ cat > nlinks.py <<EOF
4 > from __future__ import print_function
4 > from __future__ import print_function
5 > import sys
5 > import sys
6 > from mercurial import pycompat, util
6 > from mercurial import pycompat, util
7 > for f in sorted(sys.stdin.readlines()):
7 > for f in sorted(sys.stdin.readlines()):
8 > f = f[:-1]
8 > f = f[:-1]
9 > print(util.nlinks(pycompat.fsencode(f)), f)
9 > print(util.nlinks(pycompat.fsencode(f)), f)
10 > EOF
10 > EOF
11
11
12 $ nlinksdir()
12 $ nlinksdir()
13 > {
13 > {
14 > find "$@" -type f | "$PYTHON" $TESTTMP/nlinks.py
14 > find "$@" -type f | "$PYTHON" $TESTTMP/nlinks.py
15 > }
15 > }
16
16
17 Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
17 Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
18
18
19 $ cat > linkcp.py <<EOF
19 $ cat > linkcp.py <<EOF
20 > from __future__ import absolute_import
20 > from __future__ import absolute_import
21 > import sys
21 > import sys
22 > from mercurial import pycompat, util
22 > from mercurial import pycompat, util
23 > util.copyfiles(pycompat.fsencode(sys.argv[1]),
23 > util.copyfiles(pycompat.fsencode(sys.argv[1]),
24 > pycompat.fsencode(sys.argv[2]), hardlink=True)
24 > pycompat.fsencode(sys.argv[2]), hardlink=True)
25 > EOF
25 > EOF
26
26
27 $ linkcp()
27 $ linkcp()
28 > {
28 > {
29 > "$PYTHON" $TESTTMP/linkcp.py $1 $2
29 > "$PYTHON" $TESTTMP/linkcp.py $1 $2
30 > }
30 > }
31
31
32 Prepare repo r1:
32 Prepare repo r1:
33
33
34 $ hg init r1
34 $ hg init r1
35 $ cd r1
35 $ cd r1
36
36
37 $ echo c1 > f1
37 $ echo c1 > f1
38 $ hg add f1
38 $ hg add f1
39 $ hg ci -m0
39 $ hg ci -m0
40
40
41 $ mkdir d1
41 $ mkdir d1
42 $ cd d1
42 $ cd d1
43 $ echo c2 > f2
43 $ echo c2 > f2
44 $ hg add f2
44 $ hg add f2
45 $ hg ci -m1
45 $ hg ci -m1
46 $ cd ../..
46 $ cd ../..
47
47
48 $ nlinksdir r1/.hg/store
48 $ nlinksdir r1/.hg/store
49 1 r1/.hg/store/00changelog.i
49 1 r1/.hg/store/00changelog.i
50 1 r1/.hg/store/00manifest.i
50 1 r1/.hg/store/00manifest.i
51 1 r1/.hg/store/data/d1/f2.i
51 1 r1/.hg/store/data/d1/f2.i
52 1 r1/.hg/store/data/f1.i
52 1 r1/.hg/store/data/f1.i
53 1 r1/.hg/store/fncache (repofncache !)
53 1 r1/.hg/store/fncache (repofncache !)
54 1 r1/.hg/store/phaseroots
54 1 r1/.hg/store/phaseroots
55 1 r1/.hg/store/undo
55 1 r1/.hg/store/undo
56 1 r1/.hg/store/undo.backup.fncache (repofncache !)
56 1 r1/.hg/store/undo.backup.fncache (repofncache !)
57 1 r1/.hg/store/undo.backupfiles
57 1 r1/.hg/store/undo.backupfiles
58 1 r1/.hg/store/undo.phaseroots
58 1 r1/.hg/store/undo.phaseroots
59
59
60
60
61 Create hardlinked clone r2:
61 Create hardlinked clone r2:
62
62
63 $ hg clone -U --debug r1 r2 --config progress.debug=true
63 $ hg clone -U --debug r1 r2 --config progress.debug=true
64 linking: 1 files
64 linking: 1 files
65 linking: 2 files
65 linking: 2 files
66 linking: 3 files
66 linking: 3 files
67 linking: 4 files
67 linking: 4 files
68 linking: 5 files
68 linking: 5 files
69 linking: 6 files
69 linking: 6 files
70 linking: 7 files
70 linking: 7 files
71 linked 7 files
71 linked 7 files
72
72
73 Create non-hardlinked clone r3:
73 Create non-hardlinked clone r3:
74
74
75 $ hg clone --pull r1 r3
75 $ hg clone --pull r1 r3
76 requesting all changes
76 requesting all changes
77 adding changesets
77 adding changesets
78 adding manifests
78 adding manifests
79 adding file changes
79 adding file changes
80 added 2 changesets with 2 changes to 2 files
80 added 2 changesets with 2 changes to 2 files
81 new changesets 40d85e9847f2:7069c422939c
81 new changesets 40d85e9847f2:7069c422939c
82 updating to branch default
82 updating to branch default
83 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
84
84
85
85
86 Repos r1 and r2 should now contain hardlinked files:
86 Repos r1 and r2 should now contain hardlinked files:
87
87
88 $ nlinksdir r1/.hg/store
88 $ nlinksdir r1/.hg/store
89 2 r1/.hg/store/00changelog.i
89 2 r1/.hg/store/00changelog.i
90 2 r1/.hg/store/00manifest.i
90 2 r1/.hg/store/00manifest.i
91 2 r1/.hg/store/data/d1/f2.i
91 2 r1/.hg/store/data/d1/f2.i
92 2 r1/.hg/store/data/f1.i
92 2 r1/.hg/store/data/f1.i
93 2 r1/.hg/store/fncache (repofncache !)
93 2 r1/.hg/store/fncache (repofncache !)
94 1 r1/.hg/store/phaseroots
94 1 r1/.hg/store/phaseroots
95 1 r1/.hg/store/undo
95 1 r1/.hg/store/undo
96 1 r1/.hg/store/undo.backup.fncache (repofncache !)
96 1 r1/.hg/store/undo.backup.fncache (repofncache !)
97 1 r1/.hg/store/undo.backupfiles
97 1 r1/.hg/store/undo.backupfiles
98 1 r1/.hg/store/undo.phaseroots
98 1 r1/.hg/store/undo.phaseroots
99
99
100 $ nlinksdir r2/.hg/store
100 $ nlinksdir r2/.hg/store
101 2 r2/.hg/store/00changelog.i
101 2 r2/.hg/store/00changelog.i
102 2 r2/.hg/store/00manifest.i
102 2 r2/.hg/store/00manifest.i
103 2 r2/.hg/store/data/d1/f2.i
103 2 r2/.hg/store/data/d1/f2.i
104 2 r2/.hg/store/data/f1.i
104 2 r2/.hg/store/data/f1.i
105 2 r2/.hg/store/fncache (repofncache !)
105 2 r2/.hg/store/fncache (repofncache !)
106
106
107 Repo r3 should not be hardlinked:
107 Repo r3 should not be hardlinked:
108
108
109 $ nlinksdir r3/.hg/store
109 $ nlinksdir r3/.hg/store
110 1 r3/.hg/store/00changelog.i
110 1 r3/.hg/store/00changelog.i
111 1 r3/.hg/store/00manifest.i
111 1 r3/.hg/store/00manifest.i
112 1 r3/.hg/store/data/d1/f2.i
112 1 r3/.hg/store/data/d1/f2.i
113 1 r3/.hg/store/data/f1.i
113 1 r3/.hg/store/data/f1.i
114 1 r3/.hg/store/fncache (repofncache !)
114 1 r3/.hg/store/fncache (repofncache !)
115 1 r3/.hg/store/phaseroots
115 1 r3/.hg/store/phaseroots
116 1 r3/.hg/store/undo
116 1 r3/.hg/store/undo
117 1 r3/.hg/store/undo.backupfiles
117 1 r3/.hg/store/undo.backupfiles
118 1 r3/.hg/store/undo.phaseroots
118 1 r3/.hg/store/undo.phaseroots
119
119
120
120
121 Create a non-inlined filelog in r3:
121 Create a non-inlined filelog in r3:
122
122
123 $ cd r3/d1
123 $ cd r3/d1
124 >>> f = open('data1', 'wb')
124 >>> f = open('data1', 'wb')
125 >>> for x in range(10000):
125 >>> for x in range(10000):
126 ... f.write(b"%d\n" % x) and None
126 ... f.write(b"%d\n" % x) and None
127 >>> f.close()
127 >>> f.close()
128 $ for j in 0 1 2 3 4 5 6 7 8 9; do
128 $ for j in 0 1 2 3 4 5 6 7 8 9; do
129 > cat data1 >> f2
129 > cat data1 >> f2
130 > hg commit -m$j
130 > hg commit -m$j
131 > done
131 > done
132 $ cd ../..
132 $ cd ../..
133
133
134 $ nlinksdir r3/.hg/store
134 $ nlinksdir r3/.hg/store
135 1 r3/.hg/store/00changelog.i
135 1 r3/.hg/store/00changelog.i
136 1 r3/.hg/store/00manifest.i
136 1 r3/.hg/store/00manifest.i
137 1 r3/.hg/store/data/d1/f2.d
137 1 r3/.hg/store/data/d1/f2.d
138 1 r3/.hg/store/data/d1/f2.i
138 1 r3/.hg/store/data/d1/f2.i
139 1 r3/.hg/store/data/f1.i
139 1 r3/.hg/store/data/f1.i
140 1 r3/.hg/store/fncache (repofncache !)
140 1 r3/.hg/store/fncache (repofncache !)
141 1 r3/.hg/store/phaseroots
141 1 r3/.hg/store/phaseroots
142 1 r3/.hg/store/undo
142 1 r3/.hg/store/undo
143 1 r3/.hg/store/undo.backup.fncache (repofncache !)
143 1 r3/.hg/store/undo.backup.fncache (repofncache !)
144 1 r3/.hg/store/undo.backup.phaseroots
144 1 r3/.hg/store/undo.backup.phaseroots
145 1 r3/.hg/store/undo.backupfiles
145 1 r3/.hg/store/undo.backupfiles
146 1 r3/.hg/store/undo.phaseroots
146 1 r3/.hg/store/undo.phaseroots
147
147
148 Push to repo r1 should break up most hardlinks in r2:
148 Push to repo r1 should break up most hardlinks in r2:
149
149
150 $ hg -R r2 verify
150 $ hg -R r2 verify
151 checking changesets
151 checking changesets
152 checking manifests
152 checking manifests
153 crosschecking files in changesets and manifests
153 crosschecking files in changesets and manifests
154 checking files
154 checking files
155 checked 2 changesets with 2 changes to 2 files
155 checked 2 changesets with 2 changes to 2 files
156
156
157 $ cd r3
157 $ cd r3
158 $ hg push
158 $ hg push
159 pushing to $TESTTMP/r1
159 pushing to $TESTTMP/r1
160 searching for changes
160 searching for changes
161 adding changesets
161 adding changesets
162 adding manifests
162 adding manifests
163 adding file changes
163 adding file changes
164 added 10 changesets with 10 changes to 1 files
164 added 10 changesets with 10 changes to 1 files
165
165
166 $ cd ..
166 $ cd ..
167
167
168 $ nlinksdir r2/.hg/store
168 $ nlinksdir r2/.hg/store
169 1 r2/.hg/store/00changelog.i
169 1 r2/.hg/store/00changelog.i
170 1 r2/.hg/store/00manifest.i
170 1 r2/.hg/store/00manifest.i
171 1 r2/.hg/store/data/d1/f2.i
171 1 r2/.hg/store/data/d1/f2.i
172 2 r2/.hg/store/data/f1.i
172 2 r2/.hg/store/data/f1.i
173 [12] r2/\.hg/store/fncache (re) (repofncache !)
173 [12] r2/\.hg/store/fncache (re) (repofncache !)
174
174
175 #if hardlink-whitelisted repofncache
175 #if hardlink-whitelisted repofncache
176 $ nlinksdir r2/.hg/store/fncache
176 $ nlinksdir r2/.hg/store/fncache
177 2 r2/.hg/store/fncache
177 2 r2/.hg/store/fncache
178 #endif
178 #endif
179
179
180 $ hg -R r2 verify
180 $ hg -R r2 verify
181 checking changesets
181 checking changesets
182 checking manifests
182 checking manifests
183 crosschecking files in changesets and manifests
183 crosschecking files in changesets and manifests
184 checking files
184 checking files
185 checked 2 changesets with 2 changes to 2 files
185 checked 2 changesets with 2 changes to 2 files
186
186
187
187
188 $ cd r1
188 $ cd r1
189 $ hg up
189 $ hg up
190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
190 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
191
191
192 Committing a change to f1 in r1 must break up hardlink f1.i in r2:
192 Committing a change to f1 in r1 must break up hardlink f1.i in r2:
193
193
194 $ echo c1c1 >> f1
194 $ echo c1c1 >> f1
195 $ hg ci -m00
195 $ hg ci -m00
196 $ cd ..
196 $ cd ..
197
197
198 $ nlinksdir r2/.hg/store
198 $ nlinksdir r2/.hg/store
199 1 r2/.hg/store/00changelog.i
199 1 r2/.hg/store/00changelog.i
200 1 r2/.hg/store/00manifest.i
200 1 r2/.hg/store/00manifest.i
201 1 r2/.hg/store/data/d1/f2.i
201 1 r2/.hg/store/data/d1/f2.i
202 1 r2/.hg/store/data/f1.i
202 1 r2/.hg/store/data/f1.i
203 [12] r2/\.hg/store/fncache (re) (repofncache !)
203 [12] r2/\.hg/store/fncache (re) (repofncache !)
204
204
205 #if hardlink-whitelisted repofncache
205 #if hardlink-whitelisted repofncache
206 $ nlinksdir r2/.hg/store/fncache
206 $ nlinksdir r2/.hg/store/fncache
207 2 r2/.hg/store/fncache
207 2 r2/.hg/store/fncache
208 #endif
208 #endif
209
209
210 Create a file which exec permissions we will change
210 Create a file which exec permissions we will change
211 $ cd r3
211 $ cd r3
212 $ echo "echo hello world" > f3
212 $ echo "echo hello world" > f3
213 $ hg add f3
213 $ hg add f3
214 $ hg ci -mf3
214 $ hg ci -mf3
215 $ cd ..
215 $ cd ..
216
216
217 $ cd r3
217 $ cd r3
218 $ hg tip --template '{rev}:{node|short}\n'
218 $ hg tip --template '{rev}:{node|short}\n'
219 12:d3b77733a28a
219 12:d3b77733a28a
220 $ echo bla > f1
220 $ echo bla > f1
221 $ chmod +x f3
221 $ chmod +x f3
222 $ hg ci -m1
222 $ hg ci -m1
223 $ cd ..
223 $ cd ..
224
224
225 Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
225 Create hardlinked copy r4 of r3 (on Linux, we would call 'cp -al'):
226
226
227 $ linkcp r3 r4
227 $ linkcp r3 r4
228
228
229 'checklink' is produced by hardlinking a symlink, which is undefined whether
229 'checklink' is produced by hardlinking a symlink, which is undefined whether
230 the symlink should be followed or not. It does behave differently on Linux and
230 the symlink should be followed or not. It does behave differently on Linux and
231 BSD. Just remove it so the test pass on both platforms.
231 BSD. Just remove it so the test pass on both platforms.
232
232
233 $ rm -f r4/.hg/wcache/checklink
233 $ rm -f r4/.hg/wcache/checklink
234
234
235 r4 has hardlinks in the working dir (not just inside .hg):
235 r4 has hardlinks in the working dir (not just inside .hg):
236
236
237 $ nlinksdir r4
237 $ nlinksdir r4
238 2 r4/.hg/00changelog.i
238 2 r4/.hg/00changelog.i
239 2 r4/.hg/branch
239 2 r4/.hg/branch
240 2 r4/.hg/cache/branch2-base
240 2 r4/.hg/cache/branch2-base
241 2 r4/.hg/cache/branch2-served
241 2 r4/.hg/cache/branch2-served
242 2 r4/.hg/cache/manifestfulltextcache (reporevlogstore !)
243 2 r4/.hg/cache/rbc-names-v1
242 2 r4/.hg/cache/rbc-names-v1
244 2 r4/.hg/cache/rbc-revs-v1
243 2 r4/.hg/cache/rbc-revs-v1
245 2 r4/.hg/dirstate
244 2 r4/.hg/dirstate
246 2 r4/.hg/fsmonitor.state (fsmonitor !)
245 2 r4/.hg/fsmonitor.state (fsmonitor !)
247 2 r4/.hg/hgrc
246 2 r4/.hg/hgrc
248 2 r4/.hg/last-message.txt
247 2 r4/.hg/last-message.txt
249 2 r4/.hg/requires
248 2 r4/.hg/requires
250 2 r4/.hg/store/00changelog.i
249 2 r4/.hg/store/00changelog.i
251 2 r4/.hg/store/00manifest.i
250 2 r4/.hg/store/00manifest.i
252 2 r4/.hg/store/data/d1/f2.d
251 2 r4/.hg/store/data/d1/f2.d
253 2 r4/.hg/store/data/d1/f2.i
252 2 r4/.hg/store/data/d1/f2.i
254 2 r4/.hg/store/data/f1.i
253 2 r4/.hg/store/data/f1.i
255 2 r4/.hg/store/data/f3.i
254 2 r4/.hg/store/data/f3.i
256 2 r4/.hg/store/fncache (repofncache !)
255 2 r4/.hg/store/fncache (repofncache !)
257 2 r4/.hg/store/phaseroots
256 2 r4/.hg/store/phaseroots
258 2 r4/.hg/store/undo
257 2 r4/.hg/store/undo
259 2 r4/.hg/store/undo.backup.fncache (repofncache !)
258 2 r4/.hg/store/undo.backup.fncache (repofncache !)
260 2 r4/.hg/store/undo.backup.phaseroots
259 2 r4/.hg/store/undo.backup.phaseroots
261 2 r4/.hg/store/undo.backupfiles
260 2 r4/.hg/store/undo.backupfiles
262 2 r4/.hg/store/undo.phaseroots
261 2 r4/.hg/store/undo.phaseroots
263 [24] r4/\.hg/undo\.backup\.dirstate (re)
262 [24] r4/\.hg/undo\.backup\.dirstate (re)
264 2 r4/.hg/undo.bookmarks
263 2 r4/.hg/undo.bookmarks
265 2 r4/.hg/undo.branch
264 2 r4/.hg/undo.branch
266 2 r4/.hg/undo.desc
265 2 r4/.hg/undo.desc
267 [24] r4/\.hg/undo\.dirstate (re)
266 [24] r4/\.hg/undo\.dirstate (re)
268 2 r4/.hg/wcache/checkisexec (execbit !)
267 2 r4/.hg/wcache/checkisexec (execbit !)
269 2 r4/.hg/wcache/checklink-target (symlink !)
268 2 r4/.hg/wcache/checklink-target (symlink !)
270 2 r4/.hg/wcache/checknoexec (execbit !)
269 2 r4/.hg/wcache/checknoexec (execbit !)
270 2 r4/.hg/wcache/manifestfulltextcache (reporevlogstore !)
271 2 r4/d1/data1
271 2 r4/d1/data1
272 2 r4/d1/f2
272 2 r4/d1/f2
273 2 r4/f1
273 2 r4/f1
274 2 r4/f3
274 2 r4/f3
275
275
276 Update back to revision 12 in r4 should break hardlink of file f1 and f3:
276 Update back to revision 12 in r4 should break hardlink of file f1 and f3:
277 #if hardlink-whitelisted
277 #if hardlink-whitelisted
278 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
278 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
279 4 r4/.hg/undo.backup.dirstate
279 4 r4/.hg/undo.backup.dirstate
280 4 r4/.hg/undo.dirstate
280 4 r4/.hg/undo.dirstate
281 #endif
281 #endif
282
282
283
283
284 $ hg -R r4 up 12
284 $ hg -R r4 up 12
285 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (execbit !)
285 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (execbit !)
286 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-execbit !)
286 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (no-execbit !)
287
287
288 $ nlinksdir r4
288 $ nlinksdir r4
289 2 r4/.hg/00changelog.i
289 2 r4/.hg/00changelog.i
290 1 r4/.hg/branch
290 1 r4/.hg/branch
291 2 r4/.hg/cache/branch2-base
291 2 r4/.hg/cache/branch2-base
292 2 r4/.hg/cache/branch2-served
292 2 r4/.hg/cache/branch2-served
293 1 r4/.hg/cache/manifestfulltextcache (reporevlogstore !)
294 2 r4/.hg/cache/rbc-names-v1
293 2 r4/.hg/cache/rbc-names-v1
295 2 r4/.hg/cache/rbc-revs-v1
294 2 r4/.hg/cache/rbc-revs-v1
296 1 r4/.hg/dirstate
295 1 r4/.hg/dirstate
297 1 r4/.hg/fsmonitor.state (fsmonitor !)
296 1 r4/.hg/fsmonitor.state (fsmonitor !)
298 2 r4/.hg/hgrc
297 2 r4/.hg/hgrc
299 2 r4/.hg/last-message.txt
298 2 r4/.hg/last-message.txt
300 2 r4/.hg/requires
299 2 r4/.hg/requires
301 2 r4/.hg/store/00changelog.i
300 2 r4/.hg/store/00changelog.i
302 2 r4/.hg/store/00manifest.i
301 2 r4/.hg/store/00manifest.i
303 2 r4/.hg/store/data/d1/f2.d
302 2 r4/.hg/store/data/d1/f2.d
304 2 r4/.hg/store/data/d1/f2.i
303 2 r4/.hg/store/data/d1/f2.i
305 2 r4/.hg/store/data/f1.i
304 2 r4/.hg/store/data/f1.i
306 2 r4/.hg/store/data/f3.i
305 2 r4/.hg/store/data/f3.i
307 2 r4/.hg/store/fncache
306 2 r4/.hg/store/fncache
308 2 r4/.hg/store/phaseroots
307 2 r4/.hg/store/phaseroots
309 2 r4/.hg/store/undo
308 2 r4/.hg/store/undo
310 2 r4/.hg/store/undo.backup.fncache (repofncache !)
309 2 r4/.hg/store/undo.backup.fncache (repofncache !)
311 2 r4/.hg/store/undo.backup.phaseroots
310 2 r4/.hg/store/undo.backup.phaseroots
312 2 r4/.hg/store/undo.backupfiles
311 2 r4/.hg/store/undo.backupfiles
313 2 r4/.hg/store/undo.phaseroots
312 2 r4/.hg/store/undo.phaseroots
314 [24] r4/\.hg/undo\.backup\.dirstate (re)
313 [24] r4/\.hg/undo\.backup\.dirstate (re)
315 2 r4/.hg/undo.bookmarks
314 2 r4/.hg/undo.bookmarks
316 2 r4/.hg/undo.branch
315 2 r4/.hg/undo.branch
317 2 r4/.hg/undo.desc
316 2 r4/.hg/undo.desc
318 [24] r4/\.hg/undo\.dirstate (re)
317 [24] r4/\.hg/undo\.dirstate (re)
319 2 r4/.hg/wcache/checkisexec (execbit !)
318 2 r4/.hg/wcache/checkisexec (execbit !)
320 2 r4/.hg/wcache/checklink-target (symlink !)
319 2 r4/.hg/wcache/checklink-target (symlink !)
321 2 r4/.hg/wcache/checknoexec (execbit !)
320 2 r4/.hg/wcache/checknoexec (execbit !)
321 1 r4/.hg/wcache/manifestfulltextcache (reporevlogstore !)
322 2 r4/d1/data1
322 2 r4/d1/data1
323 2 r4/d1/f2
323 2 r4/d1/f2
324 1 r4/f1
324 1 r4/f1
325 1 r4/f3 (execbit !)
325 1 r4/f3 (execbit !)
326 2 r4/f3 (no-execbit !)
326 2 r4/f3 (no-execbit !)
327
327
328 #if hardlink-whitelisted
328 #if hardlink-whitelisted
329 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
329 $ nlinksdir r4/.hg/undo.backup.dirstate r4/.hg/undo.dirstate
330 4 r4/.hg/undo.backup.dirstate
330 4 r4/.hg/undo.backup.dirstate
331 4 r4/.hg/undo.dirstate
331 4 r4/.hg/undo.dirstate
332 #endif
332 #endif
333
333
334 Test hardlinking outside hg:
334 Test hardlinking outside hg:
335
335
336 $ mkdir x
336 $ mkdir x
337 $ echo foo > x/a
337 $ echo foo > x/a
338
338
339 $ linkcp x y
339 $ linkcp x y
340 $ echo bar >> y/a
340 $ echo bar >> y/a
341
341
342 No diff if hardlink:
342 No diff if hardlink:
343
343
344 $ diff x/a y/a
344 $ diff x/a y/a
345
345
346 Test mq hardlinking:
346 Test mq hardlinking:
347
347
348 $ echo "[extensions]" >> $HGRCPATH
348 $ echo "[extensions]" >> $HGRCPATH
349 $ echo "mq=" >> $HGRCPATH
349 $ echo "mq=" >> $HGRCPATH
350
350
351 $ hg init a
351 $ hg init a
352 $ cd a
352 $ cd a
353
353
354 $ hg qimport -n foo - << EOF
354 $ hg qimport -n foo - << EOF
355 > # HG changeset patch
355 > # HG changeset patch
356 > # Date 1 0
356 > # Date 1 0
357 > diff -r 2588a8b53d66 a
357 > diff -r 2588a8b53d66 a
358 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
358 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
359 > +++ b/a Wed Jul 23 15:54:29 2008 +0200
359 > +++ b/a Wed Jul 23 15:54:29 2008 +0200
360 > @@ -0,0 +1,1 @@
360 > @@ -0,0 +1,1 @@
361 > +a
361 > +a
362 > EOF
362 > EOF
363 adding foo to series file
363 adding foo to series file
364
364
365 $ hg qpush
365 $ hg qpush
366 applying foo
366 applying foo
367 now at: foo
367 now at: foo
368
368
369 $ cd ..
369 $ cd ..
370 $ linkcp a b
370 $ linkcp a b
371 $ cd b
371 $ cd b
372
372
373 $ hg qimport -n bar - << EOF
373 $ hg qimport -n bar - << EOF
374 > # HG changeset patch
374 > # HG changeset patch
375 > # Date 2 0
375 > # Date 2 0
376 > diff -r 2588a8b53d66 a
376 > diff -r 2588a8b53d66 a
377 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
377 > --- /dev/null Thu Jan 01 00:00:00 1970 +0000
378 > +++ b/b Wed Jul 23 15:54:29 2008 +0200
378 > +++ b/b Wed Jul 23 15:54:29 2008 +0200
379 > @@ -0,0 +1,1 @@
379 > @@ -0,0 +1,1 @@
380 > +b
380 > +b
381 > EOF
381 > EOF
382 adding bar to series file
382 adding bar to series file
383
383
384 $ hg qpush
384 $ hg qpush
385 applying bar
385 applying bar
386 now at: bar
386 now at: bar
387
387
388 $ cat .hg/patches/status
388 $ cat .hg/patches/status
389 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
389 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
390 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
390 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c:bar
391
391
392 $ cat .hg/patches/series
392 $ cat .hg/patches/series
393 foo
393 foo
394 bar
394 bar
395
395
396 $ cat ../a/.hg/patches/status
396 $ cat ../a/.hg/patches/status
397 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
397 430ed4828a74fa4047bc816a25500f7472ab4bfe:foo
398
398
399 $ cat ../a/.hg/patches/series
399 $ cat ../a/.hg/patches/series
400 foo
400 foo
401
401
402 Test tags hardlinking:
402 Test tags hardlinking:
403
403
404 $ hg qdel -r qbase:qtip
404 $ hg qdel -r qbase:qtip
405 patch foo finalized without changeset message
405 patch foo finalized without changeset message
406 patch bar finalized without changeset message
406 patch bar finalized without changeset message
407
407
408 $ hg tag -l lfoo
408 $ hg tag -l lfoo
409 $ hg tag foo
409 $ hg tag foo
410
410
411 $ cd ..
411 $ cd ..
412 $ linkcp b c
412 $ linkcp b c
413 $ cd c
413 $ cd c
414
414
415 $ hg tag -l -r 0 lbar
415 $ hg tag -l -r 0 lbar
416 $ hg tag -r 0 bar
416 $ hg tag -r 0 bar
417
417
418 $ cat .hgtags
418 $ cat .hgtags
419 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
419 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
420 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
420 430ed4828a74fa4047bc816a25500f7472ab4bfe bar
421
421
422 $ cat .hg/localtags
422 $ cat .hg/localtags
423 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
423 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
424 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
424 430ed4828a74fa4047bc816a25500f7472ab4bfe lbar
425
425
426 $ cat ../b/.hgtags
426 $ cat ../b/.hgtags
427 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
427 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c foo
428
428
429 $ cat ../b/.hg/localtags
429 $ cat ../b/.hg/localtags
430 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
430 4e7abb4840c46a910f6d7b4d3c3fc7e5209e684c lfoo
431
431
432 $ cd ..
432 $ cd ..
@@ -1,182 +1,182 b''
1 #require unix-permissions
1 #require unix-permissions
2
2
3 test that new files created in .hg inherit the permissions from .hg/store
3 test that new files created in .hg inherit the permissions from .hg/store
4
4
5 $ mkdir dir
5 $ mkdir dir
6
6
7 just in case somebody has a strange $TMPDIR
7 just in case somebody has a strange $TMPDIR
8
8
9 $ chmod g-s dir
9 $ chmod g-s dir
10 $ cd dir
10 $ cd dir
11
11
12 $ cat >printmodes.py <<EOF
12 $ cat >printmodes.py <<EOF
13 > from __future__ import absolute_import, print_function
13 > from __future__ import absolute_import, print_function
14 > import os
14 > import os
15 > import sys
15 > import sys
16 >
16 >
17 > allnames = []
17 > allnames = []
18 > isdir = {}
18 > isdir = {}
19 > for root, dirs, files in os.walk(sys.argv[1]):
19 > for root, dirs, files in os.walk(sys.argv[1]):
20 > for d in dirs:
20 > for d in dirs:
21 > name = os.path.join(root, d)
21 > name = os.path.join(root, d)
22 > isdir[name] = 1
22 > isdir[name] = 1
23 > allnames.append(name)
23 > allnames.append(name)
24 > for f in files:
24 > for f in files:
25 > name = os.path.join(root, f)
25 > name = os.path.join(root, f)
26 > allnames.append(name)
26 > allnames.append(name)
27 > allnames.sort()
27 > allnames.sort()
28 > for name in allnames:
28 > for name in allnames:
29 > suffix = name in isdir and '/' or ''
29 > suffix = name in isdir and '/' or ''
30 > print('%05o %s%s' % (os.lstat(name).st_mode & 0o7777, name, suffix))
30 > print('%05o %s%s' % (os.lstat(name).st_mode & 0o7777, name, suffix))
31 > EOF
31 > EOF
32
32
33 $ cat >mode.py <<EOF
33 $ cat >mode.py <<EOF
34 > from __future__ import absolute_import, print_function
34 > from __future__ import absolute_import, print_function
35 > import os
35 > import os
36 > import sys
36 > import sys
37 > print('%05o' % os.lstat(sys.argv[1]).st_mode)
37 > print('%05o' % os.lstat(sys.argv[1]).st_mode)
38 > EOF
38 > EOF
39
39
40 $ umask 077
40 $ umask 077
41
41
42 $ hg init repo
42 $ hg init repo
43 $ cd repo
43 $ cd repo
44
44
45 $ chmod 0770 .hg/store .hg/cache .hg/wcache
45 $ chmod 0770 .hg/store .hg/cache .hg/wcache
46
46
47 before commit
47 before commit
48 store can be written by the group, other files cannot
48 store can be written by the group, other files cannot
49 store is setgid
49 store is setgid
50
50
51 $ "$PYTHON" ../printmodes.py .
51 $ "$PYTHON" ../printmodes.py .
52 00700 ./.hg/
52 00700 ./.hg/
53 00600 ./.hg/00changelog.i
53 00600 ./.hg/00changelog.i
54 00770 ./.hg/cache/
54 00770 ./.hg/cache/
55 00600 ./.hg/requires
55 00600 ./.hg/requires
56 00770 ./.hg/store/
56 00770 ./.hg/store/
57 00770 ./.hg/wcache/
57 00770 ./.hg/wcache/
58
58
59 $ mkdir dir
59 $ mkdir dir
60 $ touch foo dir/bar
60 $ touch foo dir/bar
61 $ hg ci -qAm 'add files'
61 $ hg ci -qAm 'add files'
62
62
63 after commit
63 after commit
64 working dir files can only be written by the owner
64 working dir files can only be written by the owner
65 files created in .hg can be written by the group
65 files created in .hg can be written by the group
66 (in particular, store/**, dirstate, branch cache file, undo files)
66 (in particular, store/**, dirstate, branch cache file, undo files)
67 new directories are setgid
67 new directories are setgid
68
68
69 $ "$PYTHON" ../printmodes.py .
69 $ "$PYTHON" ../printmodes.py .
70 00700 ./.hg/
70 00700 ./.hg/
71 00600 ./.hg/00changelog.i
71 00600 ./.hg/00changelog.i
72 00770 ./.hg/cache/
72 00770 ./.hg/cache/
73 00660 ./.hg/cache/branch2-served
73 00660 ./.hg/cache/branch2-served
74 00660 ./.hg/cache/manifestfulltextcache (reporevlogstore !)
75 00660 ./.hg/cache/rbc-names-v1
74 00660 ./.hg/cache/rbc-names-v1
76 00660 ./.hg/cache/rbc-revs-v1
75 00660 ./.hg/cache/rbc-revs-v1
77 00660 ./.hg/dirstate
76 00660 ./.hg/dirstate
78 00660 ./.hg/fsmonitor.state (fsmonitor !)
77 00660 ./.hg/fsmonitor.state (fsmonitor !)
79 00660 ./.hg/last-message.txt
78 00660 ./.hg/last-message.txt
80 00600 ./.hg/requires
79 00600 ./.hg/requires
81 00770 ./.hg/store/
80 00770 ./.hg/store/
82 00660 ./.hg/store/00changelog.i
81 00660 ./.hg/store/00changelog.i
83 00660 ./.hg/store/00manifest.i
82 00660 ./.hg/store/00manifest.i
84 00770 ./.hg/store/data/
83 00770 ./.hg/store/data/
85 00770 ./.hg/store/data/dir/
84 00770 ./.hg/store/data/dir/
86 00660 ./.hg/store/data/dir/bar.i (reporevlogstore !)
85 00660 ./.hg/store/data/dir/bar.i (reporevlogstore !)
87 00660 ./.hg/store/data/foo.i (reporevlogstore !)
86 00660 ./.hg/store/data/foo.i (reporevlogstore !)
88 00770 ./.hg/store/data/dir/bar/ (reposimplestore !)
87 00770 ./.hg/store/data/dir/bar/ (reposimplestore !)
89 00660 ./.hg/store/data/dir/bar/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
88 00660 ./.hg/store/data/dir/bar/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
90 00660 ./.hg/store/data/dir/bar/index (reposimplestore !)
89 00660 ./.hg/store/data/dir/bar/index (reposimplestore !)
91 00770 ./.hg/store/data/foo/ (reposimplestore !)
90 00770 ./.hg/store/data/foo/ (reposimplestore !)
92 00660 ./.hg/store/data/foo/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
91 00660 ./.hg/store/data/foo/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
93 00660 ./.hg/store/data/foo/index (reposimplestore !)
92 00660 ./.hg/store/data/foo/index (reposimplestore !)
94 00660 ./.hg/store/fncache (repofncache !)
93 00660 ./.hg/store/fncache (repofncache !)
95 00660 ./.hg/store/phaseroots
94 00660 ./.hg/store/phaseroots
96 00660 ./.hg/store/undo
95 00660 ./.hg/store/undo
97 00660 ./.hg/store/undo.backupfiles
96 00660 ./.hg/store/undo.backupfiles
98 00660 ./.hg/store/undo.phaseroots
97 00660 ./.hg/store/undo.phaseroots
99 00660 ./.hg/undo.backup.dirstate
98 00660 ./.hg/undo.backup.dirstate
100 00660 ./.hg/undo.bookmarks
99 00660 ./.hg/undo.bookmarks
101 00660 ./.hg/undo.branch
100 00660 ./.hg/undo.branch
102 00660 ./.hg/undo.desc
101 00660 ./.hg/undo.desc
103 00660 ./.hg/undo.dirstate
102 00660 ./.hg/undo.dirstate
104 00770 ./.hg/wcache/
103 00770 ./.hg/wcache/
105 00711 ./.hg/wcache/checkisexec
104 00711 ./.hg/wcache/checkisexec
106 007.. ./.hg/wcache/checklink (re)
105 007.. ./.hg/wcache/checklink (re)
107 00600 ./.hg/wcache/checklink-target
106 00600 ./.hg/wcache/checklink-target
107 00660 ./.hg/wcache/manifestfulltextcache (reporevlogstore !)
108 00700 ./dir/
108 00700 ./dir/
109 00600 ./dir/bar
109 00600 ./dir/bar
110 00600 ./foo
110 00600 ./foo
111
111
112 $ umask 007
112 $ umask 007
113 $ hg init ../push
113 $ hg init ../push
114
114
115 before push
115 before push
116 group can write everything
116 group can write everything
117
117
118 $ "$PYTHON" ../printmodes.py ../push
118 $ "$PYTHON" ../printmodes.py ../push
119 00770 ../push/.hg/
119 00770 ../push/.hg/
120 00660 ../push/.hg/00changelog.i
120 00660 ../push/.hg/00changelog.i
121 00770 ../push/.hg/cache/
121 00770 ../push/.hg/cache/
122 00660 ../push/.hg/requires
122 00660 ../push/.hg/requires
123 00770 ../push/.hg/store/
123 00770 ../push/.hg/store/
124 00770 ../push/.hg/wcache/
124 00770 ../push/.hg/wcache/
125
125
126 $ umask 077
126 $ umask 077
127 $ hg -q push ../push
127 $ hg -q push ../push
128
128
129 after push
129 after push
130 group can still write everything
130 group can still write everything
131
131
132 $ "$PYTHON" ../printmodes.py ../push
132 $ "$PYTHON" ../printmodes.py ../push
133 00770 ../push/.hg/
133 00770 ../push/.hg/
134 00660 ../push/.hg/00changelog.i
134 00660 ../push/.hg/00changelog.i
135 00770 ../push/.hg/cache/
135 00770 ../push/.hg/cache/
136 00660 ../push/.hg/cache/branch2-base
136 00660 ../push/.hg/cache/branch2-base
137 00660 ../push/.hg/dirstate
137 00660 ../push/.hg/dirstate
138 00660 ../push/.hg/requires
138 00660 ../push/.hg/requires
139 00770 ../push/.hg/store/
139 00770 ../push/.hg/store/
140 00660 ../push/.hg/store/00changelog.i
140 00660 ../push/.hg/store/00changelog.i
141 00660 ../push/.hg/store/00manifest.i
141 00660 ../push/.hg/store/00manifest.i
142 00770 ../push/.hg/store/data/
142 00770 ../push/.hg/store/data/
143 00770 ../push/.hg/store/data/dir/
143 00770 ../push/.hg/store/data/dir/
144 00660 ../push/.hg/store/data/dir/bar.i (reporevlogstore !)
144 00660 ../push/.hg/store/data/dir/bar.i (reporevlogstore !)
145 00660 ../push/.hg/store/data/foo.i (reporevlogstore !)
145 00660 ../push/.hg/store/data/foo.i (reporevlogstore !)
146 00770 ../push/.hg/store/data/dir/bar/ (reposimplestore !)
146 00770 ../push/.hg/store/data/dir/bar/ (reposimplestore !)
147 00660 ../push/.hg/store/data/dir/bar/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
147 00660 ../push/.hg/store/data/dir/bar/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
148 00660 ../push/.hg/store/data/dir/bar/index (reposimplestore !)
148 00660 ../push/.hg/store/data/dir/bar/index (reposimplestore !)
149 00770 ../push/.hg/store/data/foo/ (reposimplestore !)
149 00770 ../push/.hg/store/data/foo/ (reposimplestore !)
150 00660 ../push/.hg/store/data/foo/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
150 00660 ../push/.hg/store/data/foo/b80de5d138758541c5f05265ad144ab9fa86d1db (reposimplestore !)
151 00660 ../push/.hg/store/data/foo/index (reposimplestore !)
151 00660 ../push/.hg/store/data/foo/index (reposimplestore !)
152 00660 ../push/.hg/store/fncache (repofncache !)
152 00660 ../push/.hg/store/fncache (repofncache !)
153 00660 ../push/.hg/store/undo
153 00660 ../push/.hg/store/undo
154 00660 ../push/.hg/store/undo.backupfiles
154 00660 ../push/.hg/store/undo.backupfiles
155 00660 ../push/.hg/store/undo.phaseroots
155 00660 ../push/.hg/store/undo.phaseroots
156 00660 ../push/.hg/undo.bookmarks
156 00660 ../push/.hg/undo.bookmarks
157 00660 ../push/.hg/undo.branch
157 00660 ../push/.hg/undo.branch
158 00660 ../push/.hg/undo.desc
158 00660 ../push/.hg/undo.desc
159 00660 ../push/.hg/undo.dirstate
159 00660 ../push/.hg/undo.dirstate
160 00770 ../push/.hg/wcache/
160 00770 ../push/.hg/wcache/
161
161
162
162
163 Test that we don't lose the setgid bit when we call chmod.
163 Test that we don't lose the setgid bit when we call chmod.
164 Not all systems support setgid directories (e.g. HFS+), so
164 Not all systems support setgid directories (e.g. HFS+), so
165 just check that directories have the same mode.
165 just check that directories have the same mode.
166
166
167 $ cd ..
167 $ cd ..
168 $ hg init setgid
168 $ hg init setgid
169 $ cd setgid
169 $ cd setgid
170 $ chmod g+rwx .hg/store
170 $ chmod g+rwx .hg/store
171 $ chmod g+s .hg/store 2> /dev/null || true
171 $ chmod g+s .hg/store 2> /dev/null || true
172 $ mkdir dir
172 $ mkdir dir
173 $ touch dir/file
173 $ touch dir/file
174 $ hg ci -qAm 'add dir/file'
174 $ hg ci -qAm 'add dir/file'
175 $ storemode=`"$PYTHON" ../mode.py .hg/store`
175 $ storemode=`"$PYTHON" ../mode.py .hg/store`
176 $ dirmode=`"$PYTHON" ../mode.py .hg/store/data/dir`
176 $ dirmode=`"$PYTHON" ../mode.py .hg/store/data/dir`
177 $ if [ "$storemode" != "$dirmode" ]; then
177 $ if [ "$storemode" != "$dirmode" ]; then
178 > echo "$storemode != $dirmode"
178 > echo "$storemode != $dirmode"
179 > fi
179 > fi
180 $ cd ..
180 $ cd ..
181
181
182 $ cd .. # g-s dir
182 $ cd .. # g-s dir
@@ -1,481 +1,481 b''
1 $ echo "[extensions]" >> $HGRCPATH
1 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "share = " >> $HGRCPATH
2 $ echo "share = " >> $HGRCPATH
3
3
4 prepare repo1
4 prepare repo1
5
5
6 $ hg init repo1
6 $ hg init repo1
7 $ cd repo1
7 $ cd repo1
8 $ echo a > a
8 $ echo a > a
9 $ hg commit -A -m'init'
9 $ hg commit -A -m'init'
10 adding a
10 adding a
11
11
12 share it
12 share it
13
13
14 $ cd ..
14 $ cd ..
15 $ hg share repo1 repo2
15 $ hg share repo1 repo2
16 updating working directory
16 updating working directory
17 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
17 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
18
18
19 share shouldn't have a store dir
19 share shouldn't have a store dir
20
20
21 $ cd repo2
21 $ cd repo2
22 $ test -d .hg/store
22 $ test -d .hg/store
23 [1]
23 [1]
24
24
25 share shouldn't have a full cache dir, original repo should
25 share shouldn't have a full cache dir, original repo should
26
26
27 $ hg branches
27 $ hg branches
28 default 0:d3873e73d99e
28 default 0:d3873e73d99e
29 $ hg tags
29 $ hg tags
30 tip 0:d3873e73d99e
30 tip 0:d3873e73d99e
31 $ test -d .hg/cache
31 $ test -d .hg/cache
32 [1]
32 [1]
33 $ ls -1 .hg/wcache || true
33 $ ls -1 .hg/wcache || true
34 checkisexec (execbit !)
34 checkisexec (execbit !)
35 checklink (symlink !)
35 checklink (symlink !)
36 checklink-target (symlink !)
36 checklink-target (symlink !)
37 manifestfulltextcache (reporevlogstore !)
37 $ ls -1 ../repo1/.hg/cache
38 $ ls -1 ../repo1/.hg/cache
38 branch2-served
39 branch2-served
39 manifestfulltextcache (reporevlogstore !)
40 rbc-names-v1
40 rbc-names-v1
41 rbc-revs-v1
41 rbc-revs-v1
42 tags2-visible
42 tags2-visible
43
43
44 Some sed versions appends newline, some don't, and some just fails
44 Some sed versions appends newline, some don't, and some just fails
45
45
46 $ cat .hg/sharedpath; echo
46 $ cat .hg/sharedpath; echo
47 $TESTTMP/repo1/.hg
47 $TESTTMP/repo1/.hg
48
48
49 trailing newline on .hg/sharedpath is ok
49 trailing newline on .hg/sharedpath is ok
50 $ hg tip -q
50 $ hg tip -q
51 0:d3873e73d99e
51 0:d3873e73d99e
52 $ echo '' >> .hg/sharedpath
52 $ echo '' >> .hg/sharedpath
53 $ cat .hg/sharedpath
53 $ cat .hg/sharedpath
54 $TESTTMP/repo1/.hg
54 $TESTTMP/repo1/.hg
55 $ hg tip -q
55 $ hg tip -q
56 0:d3873e73d99e
56 0:d3873e73d99e
57
57
58 commit in shared clone
58 commit in shared clone
59
59
60 $ echo a >> a
60 $ echo a >> a
61 $ hg commit -m'change in shared clone'
61 $ hg commit -m'change in shared clone'
62
62
63 check original
63 check original
64
64
65 $ cd ../repo1
65 $ cd ../repo1
66 $ hg log
66 $ hg log
67 changeset: 1:8af4dc49db9e
67 changeset: 1:8af4dc49db9e
68 tag: tip
68 tag: tip
69 user: test
69 user: test
70 date: Thu Jan 01 00:00:00 1970 +0000
70 date: Thu Jan 01 00:00:00 1970 +0000
71 summary: change in shared clone
71 summary: change in shared clone
72
72
73 changeset: 0:d3873e73d99e
73 changeset: 0:d3873e73d99e
74 user: test
74 user: test
75 date: Thu Jan 01 00:00:00 1970 +0000
75 date: Thu Jan 01 00:00:00 1970 +0000
76 summary: init
76 summary: init
77
77
78 $ hg update
78 $ hg update
79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 $ cat a # should be two lines of "a"
80 $ cat a # should be two lines of "a"
81 a
81 a
82 a
82 a
83
83
84 commit in original
84 commit in original
85
85
86 $ echo b > b
86 $ echo b > b
87 $ hg commit -A -m'another file'
87 $ hg commit -A -m'another file'
88 adding b
88 adding b
89
89
90 check in shared clone
90 check in shared clone
91
91
92 $ cd ../repo2
92 $ cd ../repo2
93 $ hg log
93 $ hg log
94 changeset: 2:c2e0ac586386
94 changeset: 2:c2e0ac586386
95 tag: tip
95 tag: tip
96 user: test
96 user: test
97 date: Thu Jan 01 00:00:00 1970 +0000
97 date: Thu Jan 01 00:00:00 1970 +0000
98 summary: another file
98 summary: another file
99
99
100 changeset: 1:8af4dc49db9e
100 changeset: 1:8af4dc49db9e
101 user: test
101 user: test
102 date: Thu Jan 01 00:00:00 1970 +0000
102 date: Thu Jan 01 00:00:00 1970 +0000
103 summary: change in shared clone
103 summary: change in shared clone
104
104
105 changeset: 0:d3873e73d99e
105 changeset: 0:d3873e73d99e
106 user: test
106 user: test
107 date: Thu Jan 01 00:00:00 1970 +0000
107 date: Thu Jan 01 00:00:00 1970 +0000
108 summary: init
108 summary: init
109
109
110 $ hg update
110 $ hg update
111 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
111 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
112 $ cat b # should exist with one "b"
112 $ cat b # should exist with one "b"
113 b
113 b
114
114
115 hg serve shared clone
115 hg serve shared clone
116
116
117 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid
117 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid
118 $ cat hg.pid >> $DAEMON_PIDS
118 $ cat hg.pid >> $DAEMON_PIDS
119 $ get-with-headers.py localhost:$HGPORT 'raw-file/'
119 $ get-with-headers.py localhost:$HGPORT 'raw-file/'
120 200 Script output follows
120 200 Script output follows
121
121
122
122
123 -rw-r--r-- 4 a
123 -rw-r--r-- 4 a
124 -rw-r--r-- 2 b
124 -rw-r--r-- 2 b
125
125
126
126
127 Cloning a shared repo via bundle2 results in a non-shared clone
127 Cloning a shared repo via bundle2 results in a non-shared clone
128
128
129 $ cd ..
129 $ cd ..
130 $ hg clone -q --stream --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/`pwd`/repo2 cloned-via-bundle2
130 $ hg clone -q --stream --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/`pwd`/repo2 cloned-via-bundle2
131 $ cat ./cloned-via-bundle2/.hg/requires | grep "shared"
131 $ cat ./cloned-via-bundle2/.hg/requires | grep "shared"
132 [1]
132 [1]
133 $ hg id --cwd cloned-via-bundle2 -r tip
133 $ hg id --cwd cloned-via-bundle2 -r tip
134 c2e0ac586386 tip
134 c2e0ac586386 tip
135 $ cd repo2
135 $ cd repo2
136
136
137 test unshare command
137 test unshare command
138
138
139 $ hg unshare
139 $ hg unshare
140 $ test -d .hg/store
140 $ test -d .hg/store
141 $ test -f .hg/sharedpath
141 $ test -f .hg/sharedpath
142 [1]
142 [1]
143 $ grep shared .hg/requires
143 $ grep shared .hg/requires
144 [1]
144 [1]
145 $ hg unshare
145 $ hg unshare
146 abort: this is not a shared repo
146 abort: this is not a shared repo
147 [255]
147 [255]
148
148
149 check that a change does not propagate
149 check that a change does not propagate
150
150
151 $ echo b >> b
151 $ echo b >> b
152 $ hg commit -m'change in unshared'
152 $ hg commit -m'change in unshared'
153 $ cd ../repo1
153 $ cd ../repo1
154 $ hg id -r tip
154 $ hg id -r tip
155 c2e0ac586386 tip
155 c2e0ac586386 tip
156
156
157 $ cd ..
157 $ cd ..
158
158
159
159
160 test sharing bookmarks
160 test sharing bookmarks
161
161
162 $ hg share -B repo1 repo3
162 $ hg share -B repo1 repo3
163 updating working directory
163 updating working directory
164 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
165 $ cd repo1
165 $ cd repo1
166 $ hg bookmark bm1
166 $ hg bookmark bm1
167 $ hg bookmarks
167 $ hg bookmarks
168 * bm1 2:c2e0ac586386
168 * bm1 2:c2e0ac586386
169 $ cd ../repo2
169 $ cd ../repo2
170 $ hg book bm2
170 $ hg book bm2
171 $ hg bookmarks
171 $ hg bookmarks
172 * bm2 3:0e6e70d1d5f1
172 * bm2 3:0e6e70d1d5f1
173 $ cd ../repo3
173 $ cd ../repo3
174 $ hg bookmarks
174 $ hg bookmarks
175 bm1 2:c2e0ac586386
175 bm1 2:c2e0ac586386
176 $ hg book bm3
176 $ hg book bm3
177 $ hg bookmarks
177 $ hg bookmarks
178 bm1 2:c2e0ac586386
178 bm1 2:c2e0ac586386
179 * bm3 2:c2e0ac586386
179 * bm3 2:c2e0ac586386
180 $ cd ../repo1
180 $ cd ../repo1
181 $ hg bookmarks
181 $ hg bookmarks
182 * bm1 2:c2e0ac586386
182 * bm1 2:c2e0ac586386
183 bm3 2:c2e0ac586386
183 bm3 2:c2e0ac586386
184
184
185 check whether HG_PENDING makes pending changes only in relatd
185 check whether HG_PENDING makes pending changes only in relatd
186 repositories visible to an external hook.
186 repositories visible to an external hook.
187
187
188 In "hg share" case, another transaction can't run in other
188 In "hg share" case, another transaction can't run in other
189 repositories sharing same source repository, because starting
189 repositories sharing same source repository, because starting
190 transaction requires locking store of source repository.
190 transaction requires locking store of source repository.
191
191
192 Therefore, this test scenario ignores checking visibility of
192 Therefore, this test scenario ignores checking visibility of
193 .hg/bookmakrs.pending in repo2, which shares repo1 without bookmarks.
193 .hg/bookmakrs.pending in repo2, which shares repo1 without bookmarks.
194
194
195 $ cat > $TESTTMP/checkbookmarks.sh <<EOF
195 $ cat > $TESTTMP/checkbookmarks.sh <<EOF
196 > echo "@repo1"
196 > echo "@repo1"
197 > hg -R "$TESTTMP/repo1" bookmarks
197 > hg -R "$TESTTMP/repo1" bookmarks
198 > echo "@repo2"
198 > echo "@repo2"
199 > hg -R "$TESTTMP/repo2" bookmarks
199 > hg -R "$TESTTMP/repo2" bookmarks
200 > echo "@repo3"
200 > echo "@repo3"
201 > hg -R "$TESTTMP/repo3" bookmarks
201 > hg -R "$TESTTMP/repo3" bookmarks
202 > exit 1 # to avoid adding new bookmark for subsequent tests
202 > exit 1 # to avoid adding new bookmark for subsequent tests
203 > EOF
203 > EOF
204
204
205 $ cd ../repo1
205 $ cd ../repo1
206 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
206 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
207 @repo1
207 @repo1
208 bm1 2:c2e0ac586386
208 bm1 2:c2e0ac586386
209 bm3 2:c2e0ac586386
209 bm3 2:c2e0ac586386
210 * bmX 2:c2e0ac586386
210 * bmX 2:c2e0ac586386
211 @repo2
211 @repo2
212 * bm2 3:0e6e70d1d5f1
212 * bm2 3:0e6e70d1d5f1
213 @repo3
213 @repo3
214 bm1 2:c2e0ac586386
214 bm1 2:c2e0ac586386
215 * bm3 2:c2e0ac586386
215 * bm3 2:c2e0ac586386
216 bmX 2:c2e0ac586386
216 bmX 2:c2e0ac586386
217 transaction abort!
217 transaction abort!
218 rollback completed
218 rollback completed
219 abort: pretxnclose hook exited with status 1
219 abort: pretxnclose hook exited with status 1
220 [255]
220 [255]
221 $ hg book bm1
221 $ hg book bm1
222
222
223 FYI, in contrast to above test, bmX is invisible in repo1 (= shared
223 FYI, in contrast to above test, bmX is invisible in repo1 (= shared
224 src), because (1) HG_PENDING refers only repo3 and (2)
224 src), because (1) HG_PENDING refers only repo3 and (2)
225 "bookmarks.pending" is written only into repo3.
225 "bookmarks.pending" is written only into repo3.
226
226
227 $ cd ../repo3
227 $ cd ../repo3
228 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
228 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
229 @repo1
229 @repo1
230 * bm1 2:c2e0ac586386
230 * bm1 2:c2e0ac586386
231 bm3 2:c2e0ac586386
231 bm3 2:c2e0ac586386
232 @repo2
232 @repo2
233 * bm2 3:0e6e70d1d5f1
233 * bm2 3:0e6e70d1d5f1
234 @repo3
234 @repo3
235 bm1 2:c2e0ac586386
235 bm1 2:c2e0ac586386
236 bm3 2:c2e0ac586386
236 bm3 2:c2e0ac586386
237 * bmX 2:c2e0ac586386
237 * bmX 2:c2e0ac586386
238 transaction abort!
238 transaction abort!
239 rollback completed
239 rollback completed
240 abort: pretxnclose hook exited with status 1
240 abort: pretxnclose hook exited with status 1
241 [255]
241 [255]
242 $ hg book bm3
242 $ hg book bm3
243
243
244 $ cd ../repo1
244 $ cd ../repo1
245
245
246 test that commits work
246 test that commits work
247
247
248 $ echo 'shared bookmarks' > a
248 $ echo 'shared bookmarks' > a
249 $ hg commit -m 'testing shared bookmarks'
249 $ hg commit -m 'testing shared bookmarks'
250 $ hg bookmarks
250 $ hg bookmarks
251 * bm1 3:b87954705719
251 * bm1 3:b87954705719
252 bm3 2:c2e0ac586386
252 bm3 2:c2e0ac586386
253 $ cd ../repo3
253 $ cd ../repo3
254 $ hg bookmarks
254 $ hg bookmarks
255 bm1 3:b87954705719
255 bm1 3:b87954705719
256 * bm3 2:c2e0ac586386
256 * bm3 2:c2e0ac586386
257 $ echo 'more shared bookmarks' > a
257 $ echo 'more shared bookmarks' > a
258 $ hg commit -m 'testing shared bookmarks'
258 $ hg commit -m 'testing shared bookmarks'
259 created new head
259 created new head
260 $ hg bookmarks
260 $ hg bookmarks
261 bm1 3:b87954705719
261 bm1 3:b87954705719
262 * bm3 4:62f4ded848e4
262 * bm3 4:62f4ded848e4
263 $ cd ../repo1
263 $ cd ../repo1
264 $ hg bookmarks
264 $ hg bookmarks
265 * bm1 3:b87954705719
265 * bm1 3:b87954705719
266 bm3 4:62f4ded848e4
266 bm3 4:62f4ded848e4
267 $ cd ..
267 $ cd ..
268
268
269 non largefiles repos won't enable largefiles
269 non largefiles repos won't enable largefiles
270
270
271 $ hg share --config extensions.largefiles= repo3 sharedrepo
271 $ hg share --config extensions.largefiles= repo3 sharedrepo
272 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
272 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
273 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
273 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
274 updating working directory
274 updating working directory
275 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
275 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 $ [ -f sharedrepo/.hg/hgrc ]
276 $ [ -f sharedrepo/.hg/hgrc ]
277 [1]
277 [1]
278
278
279 test pushing bookmarks works
279 test pushing bookmarks works
280
280
281 $ hg clone repo3 repo4
281 $ hg clone repo3 repo4
282 updating to branch default
282 updating to branch default
283 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
283 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
284 $ cd repo4
284 $ cd repo4
285 $ hg boo bm4
285 $ hg boo bm4
286 $ echo foo > b
286 $ echo foo > b
287 $ hg commit -m 'foo in b'
287 $ hg commit -m 'foo in b'
288 $ hg boo
288 $ hg boo
289 bm1 3:b87954705719
289 bm1 3:b87954705719
290 bm3 4:62f4ded848e4
290 bm3 4:62f4ded848e4
291 * bm4 5:92793bfc8cad
291 * bm4 5:92793bfc8cad
292 $ hg push -B bm4
292 $ hg push -B bm4
293 pushing to $TESTTMP/repo3
293 pushing to $TESTTMP/repo3
294 searching for changes
294 searching for changes
295 adding changesets
295 adding changesets
296 adding manifests
296 adding manifests
297 adding file changes
297 adding file changes
298 added 1 changesets with 1 changes to 1 files
298 added 1 changesets with 1 changes to 1 files
299 exporting bookmark bm4
299 exporting bookmark bm4
300 $ cd ../repo1
300 $ cd ../repo1
301 $ hg bookmarks
301 $ hg bookmarks
302 * bm1 3:b87954705719
302 * bm1 3:b87954705719
303 bm3 4:62f4ded848e4
303 bm3 4:62f4ded848e4
304 bm4 5:92793bfc8cad
304 bm4 5:92793bfc8cad
305 $ cd ../repo3
305 $ cd ../repo3
306 $ hg bookmarks
306 $ hg bookmarks
307 bm1 3:b87954705719
307 bm1 3:b87954705719
308 * bm3 4:62f4ded848e4
308 * bm3 4:62f4ded848e4
309 bm4 5:92793bfc8cad
309 bm4 5:92793bfc8cad
310 $ cd ..
310 $ cd ..
311
311
312 test behavior when sharing a shared repo
312 test behavior when sharing a shared repo
313
313
314 $ hg share -B repo3 missingdir/repo5
314 $ hg share -B repo3 missingdir/repo5
315 updating working directory
315 updating working directory
316 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
316 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
317 $ cd missingdir/repo5
317 $ cd missingdir/repo5
318 $ hg book
318 $ hg book
319 bm1 3:b87954705719
319 bm1 3:b87954705719
320 bm3 4:62f4ded848e4
320 bm3 4:62f4ded848e4
321 bm4 5:92793bfc8cad
321 bm4 5:92793bfc8cad
322 $ cd ../..
322 $ cd ../..
323
323
324 test what happens when an active bookmark is deleted
324 test what happens when an active bookmark is deleted
325
325
326 $ cd repo1
326 $ cd repo1
327 $ hg boo -d bm3
327 $ hg boo -d bm3
328 $ hg boo
328 $ hg boo
329 * bm1 3:b87954705719
329 * bm1 3:b87954705719
330 bm4 5:92793bfc8cad
330 bm4 5:92793bfc8cad
331 $ cd ../repo3
331 $ cd ../repo3
332 $ hg boo
332 $ hg boo
333 bm1 3:b87954705719
333 bm1 3:b87954705719
334 bm4 5:92793bfc8cad
334 bm4 5:92793bfc8cad
335 $ cd ..
335 $ cd ..
336
336
337 verify that bookmarks are not written on failed transaction
337 verify that bookmarks are not written on failed transaction
338
338
339 $ cat > failpullbookmarks.py << EOF
339 $ cat > failpullbookmarks.py << EOF
340 > """A small extension that makes bookmark pulls fail, for testing"""
340 > """A small extension that makes bookmark pulls fail, for testing"""
341 > from __future__ import absolute_import
341 > from __future__ import absolute_import
342 > from mercurial import (
342 > from mercurial import (
343 > error,
343 > error,
344 > exchange,
344 > exchange,
345 > extensions,
345 > extensions,
346 > )
346 > )
347 > def _pullbookmarks(orig, pullop):
347 > def _pullbookmarks(orig, pullop):
348 > orig(pullop)
348 > orig(pullop)
349 > raise error.HookAbort('forced failure by extension')
349 > raise error.HookAbort('forced failure by extension')
350 > def extsetup(ui):
350 > def extsetup(ui):
351 > extensions.wrapfunction(exchange, '_pullbookmarks', _pullbookmarks)
351 > extensions.wrapfunction(exchange, '_pullbookmarks', _pullbookmarks)
352 > EOF
352 > EOF
353 $ cd repo4
353 $ cd repo4
354 $ hg boo
354 $ hg boo
355 bm1 3:b87954705719
355 bm1 3:b87954705719
356 bm3 4:62f4ded848e4
356 bm3 4:62f4ded848e4
357 * bm4 5:92793bfc8cad
357 * bm4 5:92793bfc8cad
358 $ cd ../repo3
358 $ cd ../repo3
359 $ hg boo
359 $ hg boo
360 bm1 3:b87954705719
360 bm1 3:b87954705719
361 bm4 5:92793bfc8cad
361 bm4 5:92793bfc8cad
362 $ hg --config "extensions.failpullbookmarks=$TESTTMP/failpullbookmarks.py" pull $TESTTMP/repo4
362 $ hg --config "extensions.failpullbookmarks=$TESTTMP/failpullbookmarks.py" pull $TESTTMP/repo4
363 pulling from $TESTTMP/repo4
363 pulling from $TESTTMP/repo4
364 searching for changes
364 searching for changes
365 no changes found
365 no changes found
366 adding remote bookmark bm3
366 adding remote bookmark bm3
367 abort: forced failure by extension
367 abort: forced failure by extension
368 [255]
368 [255]
369 $ hg boo
369 $ hg boo
370 bm1 3:b87954705719
370 bm1 3:b87954705719
371 bm4 5:92793bfc8cad
371 bm4 5:92793bfc8cad
372 $ hg pull $TESTTMP/repo4
372 $ hg pull $TESTTMP/repo4
373 pulling from $TESTTMP/repo4
373 pulling from $TESTTMP/repo4
374 searching for changes
374 searching for changes
375 no changes found
375 no changes found
376 adding remote bookmark bm3
376 adding remote bookmark bm3
377 1 local changesets published
377 1 local changesets published
378 $ hg boo
378 $ hg boo
379 bm1 3:b87954705719
379 bm1 3:b87954705719
380 * bm3 4:62f4ded848e4
380 * bm3 4:62f4ded848e4
381 bm4 5:92793bfc8cad
381 bm4 5:92793bfc8cad
382 $ cd ..
382 $ cd ..
383
383
384 verify bookmark behavior after unshare
384 verify bookmark behavior after unshare
385
385
386 $ cd repo3
386 $ cd repo3
387 $ hg unshare
387 $ hg unshare
388 $ hg boo
388 $ hg boo
389 bm1 3:b87954705719
389 bm1 3:b87954705719
390 * bm3 4:62f4ded848e4
390 * bm3 4:62f4ded848e4
391 bm4 5:92793bfc8cad
391 bm4 5:92793bfc8cad
392 $ hg boo -d bm4
392 $ hg boo -d bm4
393 $ hg boo bm5
393 $ hg boo bm5
394 $ hg boo
394 $ hg boo
395 bm1 3:b87954705719
395 bm1 3:b87954705719
396 bm3 4:62f4ded848e4
396 bm3 4:62f4ded848e4
397 * bm5 4:62f4ded848e4
397 * bm5 4:62f4ded848e4
398 $ cd ../repo1
398 $ cd ../repo1
399 $ hg boo
399 $ hg boo
400 * bm1 3:b87954705719
400 * bm1 3:b87954705719
401 bm3 4:62f4ded848e4
401 bm3 4:62f4ded848e4
402 bm4 5:92793bfc8cad
402 bm4 5:92793bfc8cad
403 $ cd ..
403 $ cd ..
404
404
405 test shared clones using relative paths work
405 test shared clones using relative paths work
406
406
407 $ mkdir thisdir
407 $ mkdir thisdir
408 $ hg init thisdir/orig
408 $ hg init thisdir/orig
409 $ hg share -U thisdir/orig thisdir/abs
409 $ hg share -U thisdir/orig thisdir/abs
410 $ hg share -U --relative thisdir/abs thisdir/rel
410 $ hg share -U --relative thisdir/abs thisdir/rel
411 $ cat thisdir/rel/.hg/sharedpath
411 $ cat thisdir/rel/.hg/sharedpath
412 ../../orig/.hg (no-eol)
412 ../../orig/.hg (no-eol)
413 $ grep shared thisdir/*/.hg/requires
413 $ grep shared thisdir/*/.hg/requires
414 thisdir/abs/.hg/requires:shared
414 thisdir/abs/.hg/requires:shared
415 thisdir/rel/.hg/requires:relshared
415 thisdir/rel/.hg/requires:relshared
416 thisdir/rel/.hg/requires:shared
416 thisdir/rel/.hg/requires:shared
417
417
418 test that relative shared paths aren't relative to $PWD
418 test that relative shared paths aren't relative to $PWD
419
419
420 $ cd thisdir
420 $ cd thisdir
421 $ hg -R rel root
421 $ hg -R rel root
422 $TESTTMP/thisdir/rel
422 $TESTTMP/thisdir/rel
423 $ cd ..
423 $ cd ..
424
424
425 now test that relative paths really are relative, survive across
425 now test that relative paths really are relative, survive across
426 renames and changes of PWD
426 renames and changes of PWD
427
427
428 $ hg -R thisdir/abs root
428 $ hg -R thisdir/abs root
429 $TESTTMP/thisdir/abs
429 $TESTTMP/thisdir/abs
430 $ hg -R thisdir/rel root
430 $ hg -R thisdir/rel root
431 $TESTTMP/thisdir/rel
431 $TESTTMP/thisdir/rel
432 $ mv thisdir thatdir
432 $ mv thisdir thatdir
433 $ hg -R thatdir/abs root
433 $ hg -R thatdir/abs root
434 abort: .hg/sharedpath points to nonexistent directory $TESTTMP/thisdir/orig/.hg!
434 abort: .hg/sharedpath points to nonexistent directory $TESTTMP/thisdir/orig/.hg!
435 [255]
435 [255]
436 $ hg -R thatdir/rel root
436 $ hg -R thatdir/rel root
437 $TESTTMP/thatdir/rel
437 $TESTTMP/thatdir/rel
438
438
439 test unshare relshared repo
439 test unshare relshared repo
440
440
441 $ cd thatdir/rel
441 $ cd thatdir/rel
442 $ hg unshare
442 $ hg unshare
443 $ test -d .hg/store
443 $ test -d .hg/store
444 $ test -f .hg/sharedpath
444 $ test -f .hg/sharedpath
445 [1]
445 [1]
446 $ grep shared .hg/requires
446 $ grep shared .hg/requires
447 [1]
447 [1]
448 $ hg unshare
448 $ hg unshare
449 abort: this is not a shared repo
449 abort: this is not a shared repo
450 [255]
450 [255]
451 $ cd ../..
451 $ cd ../..
452
452
453 $ rm -r thatdir
453 $ rm -r thatdir
454
454
455 Demonstrate buggy behavior around requirements validation
455 Demonstrate buggy behavior around requirements validation
456 See comment in localrepo.py:makelocalrepository() for more.
456 See comment in localrepo.py:makelocalrepository() for more.
457
457
458 $ hg init sharenewrequires
458 $ hg init sharenewrequires
459 $ hg share sharenewrequires shareoldrequires
459 $ hg share sharenewrequires shareoldrequires
460 updating working directory
460 updating working directory
461 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
461 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
462
462
463 $ cat >> sharenewrequires/.hg/requires << EOF
463 $ cat >> sharenewrequires/.hg/requires << EOF
464 > missing-requirement
464 > missing-requirement
465 > EOF
465 > EOF
466
466
467 We cannot open the repo with the unknown requirement
467 We cannot open the repo with the unknown requirement
468
468
469 $ hg -R sharenewrequires status
469 $ hg -R sharenewrequires status
470 abort: repository requires features unknown to this Mercurial: missing-requirement!
470 abort: repository requires features unknown to this Mercurial: missing-requirement!
471 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
471 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
472 [255]
472 [255]
473
473
474 BUG: we don't get the same error when opening the shared repo pointing to it
474 BUG: we don't get the same error when opening the shared repo pointing to it
475
475
476 $ hg -R shareoldrequires status
476 $ hg -R shareoldrequires status
477
477
478 Explicitly kill daemons to let the test exit on Windows
478 Explicitly kill daemons to let the test exit on Windows
479
479
480 $ killdaemons.py
480 $ killdaemons.py
481
481
@@ -1,1996 +1,1997 b''
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
1 Let commit recurse into subrepos by default to match pre-2.0 behavior:
2
2
3 $ echo "[ui]" >> $HGRCPATH
3 $ echo "[ui]" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
4 $ echo "commitsubrepos = Yes" >> $HGRCPATH
5
5
6 $ hg init t
6 $ hg init t
7 $ cd t
7 $ cd t
8
8
9 first revision, no sub
9 first revision, no sub
10
10
11 $ echo a > a
11 $ echo a > a
12 $ hg ci -Am0
12 $ hg ci -Am0
13 adding a
13 adding a
14
14
15 add first sub
15 add first sub
16
16
17 $ echo s = s > .hgsub
17 $ echo s = s > .hgsub
18 $ hg add .hgsub
18 $ hg add .hgsub
19 $ hg init s
19 $ hg init s
20 $ echo a > s/a
20 $ echo a > s/a
21
21
22 Issue2232: committing a subrepo without .hgsub
22 Issue2232: committing a subrepo without .hgsub
23
23
24 $ hg ci -mbad s
24 $ hg ci -mbad s
25 abort: can't commit subrepos without .hgsub
25 abort: can't commit subrepos without .hgsub
26 [255]
26 [255]
27
27
28 $ hg -R s add s/a
28 $ hg -R s add s/a
29 $ hg files -S
29 $ hg files -S
30 .hgsub
30 .hgsub
31 a
31 a
32 s/a
32 s/a
33
33
34 `hg files` respects ui.relative-paths
34 `hg files` respects ui.relative-paths
35 BROKEN: shows subrepo paths relative to the subrepo
35 BROKEN: shows subrepo paths relative to the subrepo
36 $ hg files -S --config ui.relative-paths=no
36 $ hg files -S --config ui.relative-paths=no
37 .hgsub
37 .hgsub
38 a
38 a
39 s/a
39 s/a
40
40
41 $ hg -R s ci -Ams0
41 $ hg -R s ci -Ams0
42 $ hg sum
42 $ hg sum
43 parent: 0:f7b1eb17ad24 tip
43 parent: 0:f7b1eb17ad24 tip
44 0
44 0
45 branch: default
45 branch: default
46 commit: 1 added, 1 subrepos
46 commit: 1 added, 1 subrepos
47 update: (current)
47 update: (current)
48 phases: 1 draft
48 phases: 1 draft
49 $ hg ci -m1
49 $ hg ci -m1
50
50
51 test handling .hgsubstate "added" explicitly.
51 test handling .hgsubstate "added" explicitly.
52
52
53 $ hg parents --template '{node}\n{files}\n'
53 $ hg parents --template '{node}\n{files}\n'
54 7cf8cfea66e410e8e3336508dfeec07b3192de51
54 7cf8cfea66e410e8e3336508dfeec07b3192de51
55 .hgsub .hgsubstate
55 .hgsub .hgsubstate
56 $ hg rollback -q
56 $ hg rollback -q
57 $ hg add .hgsubstate
57 $ hg add .hgsubstate
58 $ hg ci -m1
58 $ hg ci -m1
59 $ hg parents --template '{node}\n{files}\n'
59 $ hg parents --template '{node}\n{files}\n'
60 7cf8cfea66e410e8e3336508dfeec07b3192de51
60 7cf8cfea66e410e8e3336508dfeec07b3192de51
61 .hgsub .hgsubstate
61 .hgsub .hgsubstate
62
62
63 Subrepopath which overlaps with filepath, does not change warnings in remove()
63 Subrepopath which overlaps with filepath, does not change warnings in remove()
64
64
65 $ mkdir snot
65 $ mkdir snot
66 $ touch snot/file
66 $ touch snot/file
67 $ hg remove -S snot/file
67 $ hg remove -S snot/file
68 not removing snot/file: file is untracked
68 not removing snot/file: file is untracked
69 [1]
69 [1]
70 $ hg cat snot/filenot
70 $ hg cat snot/filenot
71 snot/filenot: no such file in rev 7cf8cfea66e4
71 snot/filenot: no such file in rev 7cf8cfea66e4
72 [1]
72 [1]
73 $ rm -r snot
73 $ rm -r snot
74
74
75 Revert subrepo and test subrepo fileset keyword:
75 Revert subrepo and test subrepo fileset keyword:
76
76
77 $ echo b > s/a
77 $ echo b > s/a
78 $ hg revert --dry-run "set:subrepo('glob:s*')"
78 $ hg revert --dry-run "set:subrepo('glob:s*')"
79 reverting subrepo s
79 reverting subrepo s
80 reverting s/a
80 reverting s/a
81 $ cat s/a
81 $ cat s/a
82 b
82 b
83 $ hg revert "set:subrepo('glob:s*')"
83 $ hg revert "set:subrepo('glob:s*')"
84 reverting subrepo s
84 reverting subrepo s
85 reverting s/a
85 reverting s/a
86 $ cat s/a
86 $ cat s/a
87 a
87 a
88 $ rm s/a.orig
88 $ rm s/a.orig
89
89
90 Revert subrepo with no backup. The "reverting s/a" line is gone since
90 Revert subrepo with no backup. The "reverting s/a" line is gone since
91 we're really running 'hg update' in the subrepo:
91 we're really running 'hg update' in the subrepo:
92
92
93 $ echo b > s/a
93 $ echo b > s/a
94 $ hg revert --no-backup s
94 $ hg revert --no-backup s
95 reverting subrepo s
95 reverting subrepo s
96
96
97 Issue2022: update -C
97 Issue2022: update -C
98
98
99 $ echo b > s/a
99 $ echo b > s/a
100 $ hg sum
100 $ hg sum
101 parent: 1:7cf8cfea66e4 tip
101 parent: 1:7cf8cfea66e4 tip
102 1
102 1
103 branch: default
103 branch: default
104 commit: 1 subrepos
104 commit: 1 subrepos
105 update: (current)
105 update: (current)
106 phases: 2 draft
106 phases: 2 draft
107 $ hg co -C 1
107 $ hg co -C 1
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 $ hg sum
109 $ hg sum
110 parent: 1:7cf8cfea66e4 tip
110 parent: 1:7cf8cfea66e4 tip
111 1
111 1
112 branch: default
112 branch: default
113 commit: (clean)
113 commit: (clean)
114 update: (current)
114 update: (current)
115 phases: 2 draft
115 phases: 2 draft
116
116
117 commands that require a clean repo should respect subrepos
117 commands that require a clean repo should respect subrepos
118
118
119 $ echo b >> s/a
119 $ echo b >> s/a
120 $ hg backout tip
120 $ hg backout tip
121 abort: uncommitted changes in subrepository "s"
121 abort: uncommitted changes in subrepository "s"
122 [255]
122 [255]
123 $ hg revert -C -R s s/a
123 $ hg revert -C -R s s/a
124
124
125 add sub sub
125 add sub sub
126
126
127 $ echo ss = ss > s/.hgsub
127 $ echo ss = ss > s/.hgsub
128 $ hg init s/ss
128 $ hg init s/ss
129 $ echo a > s/ss/a
129 $ echo a > s/ss/a
130 $ hg -R s add s/.hgsub
130 $ hg -R s add s/.hgsub
131 $ hg -R s/ss add s/ss/a
131 $ hg -R s/ss add s/ss/a
132 $ hg sum
132 $ hg sum
133 parent: 1:7cf8cfea66e4 tip
133 parent: 1:7cf8cfea66e4 tip
134 1
134 1
135 branch: default
135 branch: default
136 commit: 1 subrepos
136 commit: 1 subrepos
137 update: (current)
137 update: (current)
138 phases: 2 draft
138 phases: 2 draft
139 $ hg ci -m2
139 $ hg ci -m2
140 committing subrepository s
140 committing subrepository s
141 committing subrepository s/ss
141 committing subrepository s/ss
142 $ hg sum
142 $ hg sum
143 parent: 2:df30734270ae tip
143 parent: 2:df30734270ae tip
144 2
144 2
145 branch: default
145 branch: default
146 commit: (clean)
146 commit: (clean)
147 update: (current)
147 update: (current)
148 phases: 3 draft
148 phases: 3 draft
149
149
150 test handling .hgsubstate "modified" explicitly.
150 test handling .hgsubstate "modified" explicitly.
151
151
152 $ hg parents --template '{node}\n{files}\n'
152 $ hg parents --template '{node}\n{files}\n'
153 df30734270ae757feb35e643b7018e818e78a9aa
153 df30734270ae757feb35e643b7018e818e78a9aa
154 .hgsubstate
154 .hgsubstate
155 $ hg rollback -q
155 $ hg rollback -q
156 $ hg status -A .hgsubstate
156 $ hg status -A .hgsubstate
157 M .hgsubstate
157 M .hgsubstate
158 $ hg ci -m2
158 $ hg ci -m2
159 $ hg parents --template '{node}\n{files}\n'
159 $ hg parents --template '{node}\n{files}\n'
160 df30734270ae757feb35e643b7018e818e78a9aa
160 df30734270ae757feb35e643b7018e818e78a9aa
161 .hgsubstate
161 .hgsubstate
162
162
163 bump sub rev (and check it is ignored by ui.commitsubrepos)
163 bump sub rev (and check it is ignored by ui.commitsubrepos)
164
164
165 $ echo b > s/a
165 $ echo b > s/a
166 $ hg -R s ci -ms1
166 $ hg -R s ci -ms1
167 $ hg --config ui.commitsubrepos=no ci -m3
167 $ hg --config ui.commitsubrepos=no ci -m3
168
168
169 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
169 leave sub dirty (and check ui.commitsubrepos=no aborts the commit)
170
170
171 $ echo c > s/a
171 $ echo c > s/a
172 $ hg --config ui.commitsubrepos=no ci -m4
172 $ hg --config ui.commitsubrepos=no ci -m4
173 abort: uncommitted changes in subrepository "s"
173 abort: uncommitted changes in subrepository "s"
174 (use --subrepos for recursive commit)
174 (use --subrepos for recursive commit)
175 [255]
175 [255]
176 $ hg id
176 $ hg id
177 f6affe3fbfaa+ tip
177 f6affe3fbfaa+ tip
178 $ hg -R s ci -mc
178 $ hg -R s ci -mc
179 $ hg id
179 $ hg id
180 f6affe3fbfaa+ tip
180 f6affe3fbfaa+ tip
181 $ echo d > s/a
181 $ echo d > s/a
182 $ hg ci -m4
182 $ hg ci -m4
183 committing subrepository s
183 committing subrepository s
184 $ hg tip -R s
184 $ hg tip -R s
185 changeset: 4:02dcf1d70411
185 changeset: 4:02dcf1d70411
186 tag: tip
186 tag: tip
187 user: test
187 user: test
188 date: Thu Jan 01 00:00:00 1970 +0000
188 date: Thu Jan 01 00:00:00 1970 +0000
189 summary: 4
189 summary: 4
190
190
191
191
192 check caching
192 check caching
193
193
194 $ hg co 0
194 $ hg co 0
195 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
195 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
196 $ hg debugsub
196 $ hg debugsub
197
197
198 restore
198 restore
199
199
200 $ hg co
200 $ hg co
201 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
201 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
202 $ hg debugsub
202 $ hg debugsub
203 path s
203 path s
204 source s
204 source s
205 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
205 revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef
206
206
207 new branch for merge tests
207 new branch for merge tests
208
208
209 $ hg co 1
209 $ hg co 1
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
211 $ echo t = t >> .hgsub
211 $ echo t = t >> .hgsub
212 $ hg init t
212 $ hg init t
213 $ echo t > t/t
213 $ echo t > t/t
214 $ hg -R t add t
214 $ hg -R t add t
215 adding t/t
215 adding t/t
216
216
217 5
217 5
218
218
219 $ hg ci -m5 # add sub
219 $ hg ci -m5 # add sub
220 committing subrepository t
220 committing subrepository t
221 created new head
221 created new head
222 $ echo t2 > t/t
222 $ echo t2 > t/t
223
223
224 6
224 6
225
225
226 $ hg st -R s
226 $ hg st -R s
227 $ hg ci -m6 # change sub
227 $ hg ci -m6 # change sub
228 committing subrepository t
228 committing subrepository t
229 $ hg debugsub
229 $ hg debugsub
230 path s
230 path s
231 source s
231 source s
232 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
232 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
233 path t
233 path t
234 source t
234 source t
235 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
235 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
236 $ echo t3 > t/t
236 $ echo t3 > t/t
237
237
238 7
238 7
239
239
240 $ hg ci -m7 # change sub again for conflict test
240 $ hg ci -m7 # change sub again for conflict test
241 committing subrepository t
241 committing subrepository t
242 $ hg rm .hgsub
242 $ hg rm .hgsub
243
243
244 8
244 8
245
245
246 $ hg ci -m8 # remove sub
246 $ hg ci -m8 # remove sub
247
247
248 test handling .hgsubstate "removed" explicitly.
248 test handling .hgsubstate "removed" explicitly.
249
249
250 $ hg parents --template '{node}\n{files}\n'
250 $ hg parents --template '{node}\n{files}\n'
251 96615c1dad2dc8e3796d7332c77ce69156f7b78e
251 96615c1dad2dc8e3796d7332c77ce69156f7b78e
252 .hgsub .hgsubstate
252 .hgsub .hgsubstate
253 $ hg rollback -q
253 $ hg rollback -q
254 $ hg remove .hgsubstate
254 $ hg remove .hgsubstate
255 $ hg ci -m8
255 $ hg ci -m8
256 $ hg parents --template '{node}\n{files}\n'
256 $ hg parents --template '{node}\n{files}\n'
257 96615c1dad2dc8e3796d7332c77ce69156f7b78e
257 96615c1dad2dc8e3796d7332c77ce69156f7b78e
258 .hgsub .hgsubstate
258 .hgsub .hgsubstate
259
259
260 merge tests
260 merge tests
261
261
262 $ hg co -C 3
262 $ hg co -C 3
263 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
263 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
264 $ hg merge 5 # test adding
264 $ hg merge 5 # test adding
265 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 (branch merge, don't forget to commit)
266 (branch merge, don't forget to commit)
267 $ hg debugsub
267 $ hg debugsub
268 path s
268 path s
269 source s
269 source s
270 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
270 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
271 path t
271 path t
272 source t
272 source t
273 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
273 revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382
274 $ hg ci -m9
274 $ hg ci -m9
275 created new head
275 created new head
276 $ hg merge 6 --debug # test change
276 $ hg merge 6 --debug # test change
277 searching for copies back to rev 2
277 searching for copies back to rev 2
278 resolving manifests
278 resolving manifests
279 branchmerge: True, force: False, partial: False
279 branchmerge: True, force: False, partial: False
280 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
280 ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4
281 starting 4 threads for background file closing (?)
281 starting 4 threads for background file closing (?)
282 .hgsubstate: versions differ -> m (premerge)
282 .hgsubstate: versions differ -> m (premerge)
283 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
283 subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec
284 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
284 subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg
285 getting subrepo t
285 getting subrepo t
286 resolving manifests
286 resolving manifests
287 branchmerge: False, force: False, partial: False
287 branchmerge: False, force: False, partial: False
288 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
288 ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a
289 t: remote is newer -> g
289 t: remote is newer -> g
290 getting t
290 getting t
291 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
292 (branch merge, don't forget to commit)
292 (branch merge, don't forget to commit)
293 $ hg debugsub
293 $ hg debugsub
294 path s
294 path s
295 source s
295 source s
296 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
296 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
297 path t
297 path t
298 source t
298 source t
299 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
299 revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad
300 $ echo conflict > t/t
300 $ echo conflict > t/t
301 $ hg ci -m10
301 $ hg ci -m10
302 committing subrepository t
302 committing subrepository t
303 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
303 $ HGMERGE=internal:merge hg merge --debug 7 # test conflict
304 searching for copies back to rev 2
304 searching for copies back to rev 2
305 resolving manifests
305 resolving manifests
306 branchmerge: True, force: False, partial: False
306 branchmerge: True, force: False, partial: False
307 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
307 ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf
308 starting 4 threads for background file closing (?)
308 starting 4 threads for background file closing (?)
309 .hgsubstate: versions differ -> m (premerge)
309 .hgsubstate: versions differ -> m (premerge)
310 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
310 subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4
311 subrepo t: both sides changed
311 subrepo t: both sides changed
312 subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198)
312 subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198)
313 starting 4 threads for background file closing (?)
313 starting 4 threads for background file closing (?)
314 (M)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]? m
314 (M)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]? m
315 merging subrepository "t"
315 merging subrepository "t"
316 searching for copies back to rev 2
316 searching for copies back to rev 2
317 resolving manifests
317 resolving manifests
318 branchmerge: True, force: False, partial: False
318 branchmerge: True, force: False, partial: False
319 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
319 ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198
320 preserving t for resolve of t
320 preserving t for resolve of t
321 starting 4 threads for background file closing (?)
321 starting 4 threads for background file closing (?)
322 t: versions differ -> m (premerge)
322 t: versions differ -> m (premerge)
323 picked tool ':merge' for t (binary False symlink False changedelete False)
323 picked tool ':merge' for t (binary False symlink False changedelete False)
324 merging t
324 merging t
325 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
325 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
326 t: versions differ -> m (merge)
326 t: versions differ -> m (merge)
327 picked tool ':merge' for t (binary False symlink False changedelete False)
327 picked tool ':merge' for t (binary False symlink False changedelete False)
328 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
328 my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a
329 warning: conflicts while merging t! (edit, then use 'hg resolve --mark')
329 warning: conflicts while merging t! (edit, then use 'hg resolve --mark')
330 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
330 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
331 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
331 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
332 subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
332 subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg
333 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 (branch merge, don't forget to commit)
334 (branch merge, don't forget to commit)
335
335
336 should conflict
336 should conflict
337
337
338 $ cat t/t
338 $ cat t/t
339 <<<<<<< local: 20a0db6fbf6c - test: 10
339 <<<<<<< local: 20a0db6fbf6c - test: 10
340 conflict
340 conflict
341 =======
341 =======
342 t3
342 t3
343 >>>>>>> other: 7af322bc1198 - test: 7
343 >>>>>>> other: 7af322bc1198 - test: 7
344
344
345 11: remove subrepo t
345 11: remove subrepo t
346
346
347 $ hg co -C 5
347 $ hg co -C 5
348 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
348 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
349 $ hg revert -r 4 .hgsub # remove t
349 $ hg revert -r 4 .hgsub # remove t
350 $ hg ci -m11
350 $ hg ci -m11
351 created new head
351 created new head
352 $ hg debugsub
352 $ hg debugsub
353 path s
353 path s
354 source s
354 source s
355 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
355 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
356
356
357 local removed, remote changed, keep changed
357 local removed, remote changed, keep changed
358
358
359 $ hg merge 6
359 $ hg merge 6
360 remote [merge rev] changed subrepository t which local [working copy] removed
360 remote [merge rev] changed subrepository t which local [working copy] removed
361 use (c)hanged version or (d)elete? c
361 use (c)hanged version or (d)elete? c
362 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
362 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
363 (branch merge, don't forget to commit)
363 (branch merge, don't forget to commit)
364 BROKEN: should include subrepo t
364 BROKEN: should include subrepo t
365 $ hg debugsub
365 $ hg debugsub
366 path s
366 path s
367 source s
367 source s
368 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
368 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
369 $ cat .hgsubstate
369 $ cat .hgsubstate
370 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
370 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
371 6747d179aa9a688023c4b0cad32e4c92bb7f34ad t
371 6747d179aa9a688023c4b0cad32e4c92bb7f34ad t
372 $ hg ci -m 'local removed, remote changed, keep changed'
372 $ hg ci -m 'local removed, remote changed, keep changed'
373 BROKEN: should include subrepo t
373 BROKEN: should include subrepo t
374 $ hg debugsub
374 $ hg debugsub
375 path s
375 path s
376 source s
376 source s
377 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
377 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
378 BROKEN: should include subrepo t
378 BROKEN: should include subrepo t
379 $ cat .hgsubstate
379 $ cat .hgsubstate
380 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
380 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
381 $ cat t/t
381 $ cat t/t
382 t2
382 t2
383
383
384 local removed, remote changed, keep removed
384 local removed, remote changed, keep removed
385
385
386 $ hg co -C 11
386 $ hg co -C 11
387 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
387 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
388 $ hg merge --config ui.interactive=true 6 <<EOF
388 $ hg merge --config ui.interactive=true 6 <<EOF
389 > d
389 > d
390 > EOF
390 > EOF
391 remote [merge rev] changed subrepository t which local [working copy] removed
391 remote [merge rev] changed subrepository t which local [working copy] removed
392 use (c)hanged version or (d)elete? d
392 use (c)hanged version or (d)elete? d
393 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
393 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 (branch merge, don't forget to commit)
394 (branch merge, don't forget to commit)
395 $ hg debugsub
395 $ hg debugsub
396 path s
396 path s
397 source s
397 source s
398 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
398 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
399 $ cat .hgsubstate
399 $ cat .hgsubstate
400 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
400 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
401 $ hg ci -m 'local removed, remote changed, keep removed'
401 $ hg ci -m 'local removed, remote changed, keep removed'
402 created new head
402 created new head
403 $ hg debugsub
403 $ hg debugsub
404 path s
404 path s
405 source s
405 source s
406 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
406 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
407 $ cat .hgsubstate
407 $ cat .hgsubstate
408 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
408 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
409
409
410 local changed, remote removed, keep changed
410 local changed, remote removed, keep changed
411
411
412 $ hg co -C 6
412 $ hg co -C 6
413 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
413 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
414 $ hg merge 11
414 $ hg merge 11
415 local [working copy] changed subrepository t which remote [merge rev] removed
415 local [working copy] changed subrepository t which remote [merge rev] removed
416 use (c)hanged version or (d)elete? c
416 use (c)hanged version or (d)elete? c
417 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
417 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
418 (branch merge, don't forget to commit)
418 (branch merge, don't forget to commit)
419 BROKEN: should include subrepo t
419 BROKEN: should include subrepo t
420 $ hg debugsub
420 $ hg debugsub
421 path s
421 path s
422 source s
422 source s
423 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
423 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
424 BROKEN: should include subrepo t
424 BROKEN: should include subrepo t
425 $ cat .hgsubstate
425 $ cat .hgsubstate
426 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
426 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
427 $ hg ci -m 'local changed, remote removed, keep changed'
427 $ hg ci -m 'local changed, remote removed, keep changed'
428 created new head
428 created new head
429 BROKEN: should include subrepo t
429 BROKEN: should include subrepo t
430 $ hg debugsub
430 $ hg debugsub
431 path s
431 path s
432 source s
432 source s
433 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
433 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
434 BROKEN: should include subrepo t
434 BROKEN: should include subrepo t
435 $ cat .hgsubstate
435 $ cat .hgsubstate
436 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
436 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
437 $ cat t/t
437 $ cat t/t
438 t2
438 t2
439
439
440 local changed, remote removed, keep removed
440 local changed, remote removed, keep removed
441
441
442 $ hg co -C 6
442 $ hg co -C 6
443 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
443 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
444 $ hg merge --config ui.interactive=true 11 <<EOF
444 $ hg merge --config ui.interactive=true 11 <<EOF
445 > d
445 > d
446 > EOF
446 > EOF
447 local [working copy] changed subrepository t which remote [merge rev] removed
447 local [working copy] changed subrepository t which remote [merge rev] removed
448 use (c)hanged version or (d)elete? d
448 use (c)hanged version or (d)elete? d
449 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
449 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 (branch merge, don't forget to commit)
450 (branch merge, don't forget to commit)
451 $ hg debugsub
451 $ hg debugsub
452 path s
452 path s
453 source s
453 source s
454 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
454 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
455 $ cat .hgsubstate
455 $ cat .hgsubstate
456 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
456 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
457 $ hg ci -m 'local changed, remote removed, keep removed'
457 $ hg ci -m 'local changed, remote removed, keep removed'
458 created new head
458 created new head
459 $ hg debugsub
459 $ hg debugsub
460 path s
460 path s
461 source s
461 source s
462 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
462 revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4
463 $ cat .hgsubstate
463 $ cat .hgsubstate
464 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
464 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
465
465
466 clean up to avoid having to fix up the tests below
466 clean up to avoid having to fix up the tests below
467
467
468 $ hg co -C 10
468 $ hg co -C 10
469 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
469 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
470 $ cat >> $HGRCPATH <<EOF
470 $ cat >> $HGRCPATH <<EOF
471 > [extensions]
471 > [extensions]
472 > strip=
472 > strip=
473 > EOF
473 > EOF
474 $ hg strip -r 11:15
474 $ hg strip -r 11:15
475 saved backup bundle to $TESTTMP/t/.hg/strip-backup/*-backup.hg (glob)
475 saved backup bundle to $TESTTMP/t/.hg/strip-backup/*-backup.hg (glob)
476
476
477 clone
477 clone
478
478
479 $ cd ..
479 $ cd ..
480 $ hg clone t tc
480 $ hg clone t tc
481 updating to branch default
481 updating to branch default
482 cloning subrepo s from $TESTTMP/t/s
482 cloning subrepo s from $TESTTMP/t/s
483 cloning subrepo s/ss from $TESTTMP/t/s/ss
483 cloning subrepo s/ss from $TESTTMP/t/s/ss
484 cloning subrepo t from $TESTTMP/t/t
484 cloning subrepo t from $TESTTMP/t/t
485 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
485 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 $ cd tc
486 $ cd tc
487 $ hg debugsub
487 $ hg debugsub
488 path s
488 path s
489 source s
489 source s
490 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
490 revision fc627a69481fcbe5f1135069e8a3881c023e4cf5
491 path t
491 path t
492 source t
492 source t
493 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
493 revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e
494 $ cd ..
494 $ cd ..
495
495
496 clone with subrepo disabled (update should fail)
496 clone with subrepo disabled (update should fail)
497
497
498 $ hg clone t -U tc2 --config subrepos.allowed=false
498 $ hg clone t -U tc2 --config subrepos.allowed=false
499 $ hg update -R tc2 --config subrepos.allowed=false
499 $ hg update -R tc2 --config subrepos.allowed=false
500 abort: subrepos not enabled
500 abort: subrepos not enabled
501 (see 'hg help config.subrepos' for details)
501 (see 'hg help config.subrepos' for details)
502 [255]
502 [255]
503 $ ls tc2
503 $ ls tc2
504 a
504 a
505
505
506 $ hg clone t tc3 --config subrepos.allowed=false
506 $ hg clone t tc3 --config subrepos.allowed=false
507 updating to branch default
507 updating to branch default
508 abort: subrepos not enabled
508 abort: subrepos not enabled
509 (see 'hg help config.subrepos' for details)
509 (see 'hg help config.subrepos' for details)
510 [255]
510 [255]
511 $ ls tc3
511 $ ls tc3
512 a
512 a
513
513
514 And again with just the hg type disabled
514 And again with just the hg type disabled
515
515
516 $ hg clone t -U tc4 --config subrepos.hg:allowed=false
516 $ hg clone t -U tc4 --config subrepos.hg:allowed=false
517 $ hg update -R tc4 --config subrepos.hg:allowed=false
517 $ hg update -R tc4 --config subrepos.hg:allowed=false
518 abort: hg subrepos not allowed
518 abort: hg subrepos not allowed
519 (see 'hg help config.subrepos' for details)
519 (see 'hg help config.subrepos' for details)
520 [255]
520 [255]
521 $ ls tc4
521 $ ls tc4
522 a
522 a
523
523
524 $ hg clone t tc5 --config subrepos.hg:allowed=false
524 $ hg clone t tc5 --config subrepos.hg:allowed=false
525 updating to branch default
525 updating to branch default
526 abort: hg subrepos not allowed
526 abort: hg subrepos not allowed
527 (see 'hg help config.subrepos' for details)
527 (see 'hg help config.subrepos' for details)
528 [255]
528 [255]
529 $ ls tc5
529 $ ls tc5
530 a
530 a
531
531
532 push
532 push
533
533
534 $ cd tc
534 $ cd tc
535 $ echo bah > t/t
535 $ echo bah > t/t
536 $ hg ci -m11
536 $ hg ci -m11
537 committing subrepository t
537 committing subrepository t
538 $ hg push
538 $ hg push
539 pushing to $TESTTMP/t
539 pushing to $TESTTMP/t
540 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
540 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
541 no changes made to subrepo s since last push to $TESTTMP/t/s
541 no changes made to subrepo s since last push to $TESTTMP/t/s
542 pushing subrepo t to $TESTTMP/t/t
542 pushing subrepo t to $TESTTMP/t/t
543 searching for changes
543 searching for changes
544 adding changesets
544 adding changesets
545 adding manifests
545 adding manifests
546 adding file changes
546 adding file changes
547 added 1 changesets with 1 changes to 1 files
547 added 1 changesets with 1 changes to 1 files
548 searching for changes
548 searching for changes
549 adding changesets
549 adding changesets
550 adding manifests
550 adding manifests
551 adding file changes
551 adding file changes
552 added 1 changesets with 1 changes to 1 files
552 added 1 changesets with 1 changes to 1 files
553
553
554 push -f
554 push -f
555
555
556 $ echo bah > s/a
556 $ echo bah > s/a
557 $ hg ci -m12
557 $ hg ci -m12
558 committing subrepository s
558 committing subrepository s
559 $ hg push
559 $ hg push
560 pushing to $TESTTMP/t
560 pushing to $TESTTMP/t
561 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
561 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
562 pushing subrepo s to $TESTTMP/t/s
562 pushing subrepo s to $TESTTMP/t/s
563 searching for changes
563 searching for changes
564 abort: push creates new remote head 12a213df6fa9! (in subrepository "s")
564 abort: push creates new remote head 12a213df6fa9! (in subrepository "s")
565 (merge or see 'hg help push' for details about pushing new heads)
565 (merge or see 'hg help push' for details about pushing new heads)
566 [255]
566 [255]
567 $ hg push -f
567 $ hg push -f
568 pushing to $TESTTMP/t
568 pushing to $TESTTMP/t
569 pushing subrepo s/ss to $TESTTMP/t/s/ss
569 pushing subrepo s/ss to $TESTTMP/t/s/ss
570 searching for changes
570 searching for changes
571 no changes found
571 no changes found
572 pushing subrepo s to $TESTTMP/t/s
572 pushing subrepo s to $TESTTMP/t/s
573 searching for changes
573 searching for changes
574 adding changesets
574 adding changesets
575 adding manifests
575 adding manifests
576 adding file changes
576 adding file changes
577 added 1 changesets with 1 changes to 1 files (+1 heads)
577 added 1 changesets with 1 changes to 1 files (+1 heads)
578 pushing subrepo t to $TESTTMP/t/t
578 pushing subrepo t to $TESTTMP/t/t
579 searching for changes
579 searching for changes
580 no changes found
580 no changes found
581 searching for changes
581 searching for changes
582 adding changesets
582 adding changesets
583 adding manifests
583 adding manifests
584 adding file changes
584 adding file changes
585 added 1 changesets with 1 changes to 1 files
585 added 1 changesets with 1 changes to 1 files
586
586
587 check that unmodified subrepos are not pushed
587 check that unmodified subrepos are not pushed
588
588
589 $ hg clone . ../tcc
589 $ hg clone . ../tcc
590 updating to branch default
590 updating to branch default
591 cloning subrepo s from $TESTTMP/tc/s
591 cloning subrepo s from $TESTTMP/tc/s
592 cloning subrepo s/ss from $TESTTMP/tc/s/ss
592 cloning subrepo s/ss from $TESTTMP/tc/s/ss
593 cloning subrepo t from $TESTTMP/tc/t
593 cloning subrepo t from $TESTTMP/tc/t
594 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
594 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
595
595
596 the subrepos on the new clone have nothing to push to its source
596 the subrepos on the new clone have nothing to push to its source
597
597
598 $ hg push -R ../tcc .
598 $ hg push -R ../tcc .
599 pushing to .
599 pushing to .
600 no changes made to subrepo s/ss since last push to s/ss
600 no changes made to subrepo s/ss since last push to s/ss
601 no changes made to subrepo s since last push to s
601 no changes made to subrepo s since last push to s
602 no changes made to subrepo t since last push to t
602 no changes made to subrepo t since last push to t
603 searching for changes
603 searching for changes
604 no changes found
604 no changes found
605 [1]
605 [1]
606
606
607 the subrepos on the source do not have a clean store versus the clone target
607 the subrepos on the source do not have a clean store versus the clone target
608 because they were never explicitly pushed to the source
608 because they were never explicitly pushed to the source
609
609
610 $ hg push ../tcc
610 $ hg push ../tcc
611 pushing to ../tcc
611 pushing to ../tcc
612 pushing subrepo s/ss to ../tcc/s/ss
612 pushing subrepo s/ss to ../tcc/s/ss
613 searching for changes
613 searching for changes
614 no changes found
614 no changes found
615 pushing subrepo s to ../tcc/s
615 pushing subrepo s to ../tcc/s
616 searching for changes
616 searching for changes
617 no changes found
617 no changes found
618 pushing subrepo t to ../tcc/t
618 pushing subrepo t to ../tcc/t
619 searching for changes
619 searching for changes
620 no changes found
620 no changes found
621 searching for changes
621 searching for changes
622 no changes found
622 no changes found
623 [1]
623 [1]
624
624
625 after push their stores become clean
625 after push their stores become clean
626
626
627 $ hg push ../tcc
627 $ hg push ../tcc
628 pushing to ../tcc
628 pushing to ../tcc
629 no changes made to subrepo s/ss since last push to ../tcc/s/ss
629 no changes made to subrepo s/ss since last push to ../tcc/s/ss
630 no changes made to subrepo s since last push to ../tcc/s
630 no changes made to subrepo s since last push to ../tcc/s
631 no changes made to subrepo t since last push to ../tcc/t
631 no changes made to subrepo t since last push to ../tcc/t
632 searching for changes
632 searching for changes
633 no changes found
633 no changes found
634 [1]
634 [1]
635
635
636 updating a subrepo to a different revision or changing
636 updating a subrepo to a different revision or changing
637 its working directory does not make its store dirty
637 its working directory does not make its store dirty
638
638
639 $ hg -R s update '.^'
639 $ hg -R s update '.^'
640 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
640 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
641 $ hg push
641 $ hg push
642 pushing to $TESTTMP/t
642 pushing to $TESTTMP/t
643 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
643 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
644 no changes made to subrepo s since last push to $TESTTMP/t/s
644 no changes made to subrepo s since last push to $TESTTMP/t/s
645 no changes made to subrepo t since last push to $TESTTMP/t/t
645 no changes made to subrepo t since last push to $TESTTMP/t/t
646 searching for changes
646 searching for changes
647 no changes found
647 no changes found
648 [1]
648 [1]
649 $ echo foo >> s/a
649 $ echo foo >> s/a
650 $ hg push
650 $ hg push
651 pushing to $TESTTMP/t
651 pushing to $TESTTMP/t
652 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
652 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
653 no changes made to subrepo s since last push to $TESTTMP/t/s
653 no changes made to subrepo s since last push to $TESTTMP/t/s
654 no changes made to subrepo t since last push to $TESTTMP/t/t
654 no changes made to subrepo t since last push to $TESTTMP/t/t
655 searching for changes
655 searching for changes
656 no changes found
656 no changes found
657 [1]
657 [1]
658 $ hg -R s update -C tip
658 $ hg -R s update -C tip
659 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
659 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
660
660
661 committing into a subrepo makes its store (but not its parent's store) dirty
661 committing into a subrepo makes its store (but not its parent's store) dirty
662
662
663 $ echo foo >> s/ss/a
663 $ echo foo >> s/ss/a
664 $ hg -R s/ss commit -m 'test dirty store detection'
664 $ hg -R s/ss commit -m 'test dirty store detection'
665
665
666 $ hg out -S -r `hg log -r tip -T "{node|short}"`
666 $ hg out -S -r `hg log -r tip -T "{node|short}"`
667 comparing with $TESTTMP/t
667 comparing with $TESTTMP/t
668 searching for changes
668 searching for changes
669 no changes found
669 no changes found
670 comparing with $TESTTMP/t/s
670 comparing with $TESTTMP/t/s
671 searching for changes
671 searching for changes
672 no changes found
672 no changes found
673 comparing with $TESTTMP/t/s/ss
673 comparing with $TESTTMP/t/s/ss
674 searching for changes
674 searching for changes
675 changeset: 1:79ea5566a333
675 changeset: 1:79ea5566a333
676 tag: tip
676 tag: tip
677 user: test
677 user: test
678 date: Thu Jan 01 00:00:00 1970 +0000
678 date: Thu Jan 01 00:00:00 1970 +0000
679 summary: test dirty store detection
679 summary: test dirty store detection
680
680
681 comparing with $TESTTMP/t/t
681 comparing with $TESTTMP/t/t
682 searching for changes
682 searching for changes
683 no changes found
683 no changes found
684
684
685 $ hg push
685 $ hg push
686 pushing to $TESTTMP/t
686 pushing to $TESTTMP/t
687 pushing subrepo s/ss to $TESTTMP/t/s/ss
687 pushing subrepo s/ss to $TESTTMP/t/s/ss
688 searching for changes
688 searching for changes
689 adding changesets
689 adding changesets
690 adding manifests
690 adding manifests
691 adding file changes
691 adding file changes
692 added 1 changesets with 1 changes to 1 files
692 added 1 changesets with 1 changes to 1 files
693 no changes made to subrepo s since last push to $TESTTMP/t/s
693 no changes made to subrepo s since last push to $TESTTMP/t/s
694 no changes made to subrepo t since last push to $TESTTMP/t/t
694 no changes made to subrepo t since last push to $TESTTMP/t/t
695 searching for changes
695 searching for changes
696 no changes found
696 no changes found
697 [1]
697 [1]
698
698
699 a subrepo store may be clean versus one repo but not versus another
699 a subrepo store may be clean versus one repo but not versus another
700
700
701 $ hg push
701 $ hg push
702 pushing to $TESTTMP/t
702 pushing to $TESTTMP/t
703 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
703 no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss
704 no changes made to subrepo s since last push to $TESTTMP/t/s
704 no changes made to subrepo s since last push to $TESTTMP/t/s
705 no changes made to subrepo t since last push to $TESTTMP/t/t
705 no changes made to subrepo t since last push to $TESTTMP/t/t
706 searching for changes
706 searching for changes
707 no changes found
707 no changes found
708 [1]
708 [1]
709 $ hg push ../tcc
709 $ hg push ../tcc
710 pushing to ../tcc
710 pushing to ../tcc
711 pushing subrepo s/ss to ../tcc/s/ss
711 pushing subrepo s/ss to ../tcc/s/ss
712 searching for changes
712 searching for changes
713 adding changesets
713 adding changesets
714 adding manifests
714 adding manifests
715 adding file changes
715 adding file changes
716 added 1 changesets with 1 changes to 1 files
716 added 1 changesets with 1 changes to 1 files
717 no changes made to subrepo s since last push to ../tcc/s
717 no changes made to subrepo s since last push to ../tcc/s
718 no changes made to subrepo t since last push to ../tcc/t
718 no changes made to subrepo t since last push to ../tcc/t
719 searching for changes
719 searching for changes
720 no changes found
720 no changes found
721 [1]
721 [1]
722
722
723 update
723 update
724
724
725 $ cd ../t
725 $ cd ../t
726 $ hg up -C # discard our earlier merge
726 $ hg up -C # discard our earlier merge
727 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
727 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
728 updated to "c373c8102e68: 12"
728 updated to "c373c8102e68: 12"
729 2 other heads for branch "default"
729 2 other heads for branch "default"
730 $ echo blah > t/t
730 $ echo blah > t/t
731 $ hg ci -m13
731 $ hg ci -m13
732 committing subrepository t
732 committing subrepository t
733
733
734 backout calls revert internally with minimal opts, which should not raise
734 backout calls revert internally with minimal opts, which should not raise
735 KeyError
735 KeyError
736
736
737 $ hg backout ".^" --no-commit
737 $ hg backout ".^" --no-commit
738 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
738 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
739 changeset c373c8102e68 backed out, don't forget to commit.
739 changeset c373c8102e68 backed out, don't forget to commit.
740
740
741 $ hg up -C # discard changes
741 $ hg up -C # discard changes
742 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
742 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
743 updated to "925c17564ef8: 13"
743 updated to "925c17564ef8: 13"
744 2 other heads for branch "default"
744 2 other heads for branch "default"
745
745
746 pull
746 pull
747
747
748 $ cd ../tc
748 $ cd ../tc
749 $ hg pull
749 $ hg pull
750 pulling from $TESTTMP/t
750 pulling from $TESTTMP/t
751 searching for changes
751 searching for changes
752 adding changesets
752 adding changesets
753 adding manifests
753 adding manifests
754 adding file changes
754 adding file changes
755 added 1 changesets with 1 changes to 1 files
755 added 1 changesets with 1 changes to 1 files
756 new changesets 925c17564ef8
756 new changesets 925c17564ef8
757 (run 'hg update' to get a working copy)
757 (run 'hg update' to get a working copy)
758
758
759 should pull t
759 should pull t
760
760
761 $ hg incoming -S -r `hg log -r tip -T "{node|short}"`
761 $ hg incoming -S -r `hg log -r tip -T "{node|short}"`
762 comparing with $TESTTMP/t
762 comparing with $TESTTMP/t
763 no changes found
763 no changes found
764 comparing with $TESTTMP/t/s
764 comparing with $TESTTMP/t/s
765 searching for changes
765 searching for changes
766 no changes found
766 no changes found
767 comparing with $TESTTMP/t/s/ss
767 comparing with $TESTTMP/t/s/ss
768 searching for changes
768 searching for changes
769 no changes found
769 no changes found
770 comparing with $TESTTMP/t/t
770 comparing with $TESTTMP/t/t
771 searching for changes
771 searching for changes
772 changeset: 5:52c0adc0515a
772 changeset: 5:52c0adc0515a
773 tag: tip
773 tag: tip
774 user: test
774 user: test
775 date: Thu Jan 01 00:00:00 1970 +0000
775 date: Thu Jan 01 00:00:00 1970 +0000
776 summary: 13
776 summary: 13
777
777
778
778
779 $ hg up
779 $ hg up
780 pulling subrepo t from $TESTTMP/t/t
780 pulling subrepo t from $TESTTMP/t/t
781 searching for changes
781 searching for changes
782 adding changesets
782 adding changesets
783 adding manifests
783 adding manifests
784 adding file changes
784 adding file changes
785 added 1 changesets with 1 changes to 1 files
785 added 1 changesets with 1 changes to 1 files
786 new changesets 52c0adc0515a
786 new changesets 52c0adc0515a
787 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
787 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
788 updated to "925c17564ef8: 13"
788 updated to "925c17564ef8: 13"
789 2 other heads for branch "default"
789 2 other heads for branch "default"
790 $ cat t/t
790 $ cat t/t
791 blah
791 blah
792
792
793 bogus subrepo path aborts
793 bogus subrepo path aborts
794
794
795 $ echo 'bogus=[boguspath' >> .hgsub
795 $ echo 'bogus=[boguspath' >> .hgsub
796 $ hg ci -m 'bogus subrepo path'
796 $ hg ci -m 'bogus subrepo path'
797 abort: missing ] in subrepository source
797 abort: missing ] in subrepository source
798 [255]
798 [255]
799
799
800 Issue1986: merge aborts when trying to merge a subrepo that
800 Issue1986: merge aborts when trying to merge a subrepo that
801 shouldn't need merging
801 shouldn't need merging
802
802
803 # subrepo layout
803 # subrepo layout
804 #
804 #
805 # o 5 br
805 # o 5 br
806 # /|
806 # /|
807 # o | 4 default
807 # o | 4 default
808 # | |
808 # | |
809 # | o 3 br
809 # | o 3 br
810 # |/|
810 # |/|
811 # o | 2 default
811 # o | 2 default
812 # | |
812 # | |
813 # | o 1 br
813 # | o 1 br
814 # |/
814 # |/
815 # o 0 default
815 # o 0 default
816
816
817 $ cd ..
817 $ cd ..
818 $ rm -rf sub
818 $ rm -rf sub
819 $ hg init main
819 $ hg init main
820 $ cd main
820 $ cd main
821 $ hg init s
821 $ hg init s
822 $ cd s
822 $ cd s
823 $ echo a > a
823 $ echo a > a
824 $ hg ci -Am1
824 $ hg ci -Am1
825 adding a
825 adding a
826 $ hg branch br
826 $ hg branch br
827 marked working directory as branch br
827 marked working directory as branch br
828 (branches are permanent and global, did you want a bookmark?)
828 (branches are permanent and global, did you want a bookmark?)
829 $ echo a >> a
829 $ echo a >> a
830 $ hg ci -m1
830 $ hg ci -m1
831 $ hg up default
831 $ hg up default
832 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
832 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
833 $ echo b > b
833 $ echo b > b
834 $ hg ci -Am1
834 $ hg ci -Am1
835 adding b
835 adding b
836 $ hg up br
836 $ hg up br
837 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
837 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
838 $ hg merge tip
838 $ hg merge tip
839 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
839 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
840 (branch merge, don't forget to commit)
840 (branch merge, don't forget to commit)
841 $ hg ci -m1
841 $ hg ci -m1
842 $ hg up 2
842 $ hg up 2
843 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
843 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
844 $ echo c > c
844 $ echo c > c
845 $ hg ci -Am1
845 $ hg ci -Am1
846 adding c
846 adding c
847 $ hg up 3
847 $ hg up 3
848 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
848 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
849 $ hg merge 4
849 $ hg merge 4
850 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
850 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
851 (branch merge, don't forget to commit)
851 (branch merge, don't forget to commit)
852 $ hg ci -m1
852 $ hg ci -m1
853
853
854 # main repo layout:
854 # main repo layout:
855 #
855 #
856 # * <-- try to merge default into br again
856 # * <-- try to merge default into br again
857 # .`|
857 # .`|
858 # . o 5 br --> substate = 5
858 # . o 5 br --> substate = 5
859 # . |
859 # . |
860 # o | 4 default --> substate = 4
860 # o | 4 default --> substate = 4
861 # | |
861 # | |
862 # | o 3 br --> substate = 2
862 # | o 3 br --> substate = 2
863 # |/|
863 # |/|
864 # o | 2 default --> substate = 2
864 # o | 2 default --> substate = 2
865 # | |
865 # | |
866 # | o 1 br --> substate = 3
866 # | o 1 br --> substate = 3
867 # |/
867 # |/
868 # o 0 default --> substate = 2
868 # o 0 default --> substate = 2
869
869
870 $ cd ..
870 $ cd ..
871 $ echo 's = s' > .hgsub
871 $ echo 's = s' > .hgsub
872 $ hg -R s up 2
872 $ hg -R s up 2
873 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
873 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
874 $ hg ci -Am1
874 $ hg ci -Am1
875 adding .hgsub
875 adding .hgsub
876 $ hg branch br
876 $ hg branch br
877 marked working directory as branch br
877 marked working directory as branch br
878 (branches are permanent and global, did you want a bookmark?)
878 (branches are permanent and global, did you want a bookmark?)
879 $ echo b > b
879 $ echo b > b
880 $ hg -R s up 3
880 $ hg -R s up 3
881 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
881 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
882 $ hg ci -Am1
882 $ hg ci -Am1
883 adding b
883 adding b
884 $ hg up default
884 $ hg up default
885 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
885 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
886 $ echo c > c
886 $ echo c > c
887 $ hg ci -Am1
887 $ hg ci -Am1
888 adding c
888 adding c
889 $ hg up 1
889 $ hg up 1
890 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
890 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
891 $ hg merge 2
891 $ hg merge 2
892 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
892 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
893 (branch merge, don't forget to commit)
893 (branch merge, don't forget to commit)
894 $ hg ci -m1
894 $ hg ci -m1
895 $ hg up 2
895 $ hg up 2
896 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
896 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
897 $ hg -R s up 4
897 $ hg -R s up 4
898 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
898 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
899 $ echo d > d
899 $ echo d > d
900 $ hg ci -Am1
900 $ hg ci -Am1
901 adding d
901 adding d
902 $ hg up 3
902 $ hg up 3
903 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
903 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
904 $ hg -R s up 5
904 $ hg -R s up 5
905 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
905 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
906 $ echo e > e
906 $ echo e > e
907 $ hg ci -Am1
907 $ hg ci -Am1
908 adding e
908 adding e
909
909
910 $ hg up 5
910 $ hg up 5
911 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
911 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
912 $ hg merge 4 # try to merge default into br again
912 $ hg merge 4 # try to merge default into br again
913 subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88)
913 subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88)
914 (M)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]? m
914 (M)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]? m
915 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
915 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
916 (branch merge, don't forget to commit)
916 (branch merge, don't forget to commit)
917 $ cd ..
917 $ cd ..
918
918
919 test subrepo delete from .hgsubstate
919 test subrepo delete from .hgsubstate
920
920
921 $ hg init testdelete
921 $ hg init testdelete
922 $ mkdir testdelete/nested testdelete/nested2
922 $ mkdir testdelete/nested testdelete/nested2
923 $ hg init testdelete/nested
923 $ hg init testdelete/nested
924 $ hg init testdelete/nested2
924 $ hg init testdelete/nested2
925 $ echo test > testdelete/nested/foo
925 $ echo test > testdelete/nested/foo
926 $ echo test > testdelete/nested2/foo
926 $ echo test > testdelete/nested2/foo
927 $ hg -R testdelete/nested add
927 $ hg -R testdelete/nested add
928 adding testdelete/nested/foo
928 adding testdelete/nested/foo
929 $ hg -R testdelete/nested2 add
929 $ hg -R testdelete/nested2 add
930 adding testdelete/nested2/foo
930 adding testdelete/nested2/foo
931 $ hg -R testdelete/nested ci -m test
931 $ hg -R testdelete/nested ci -m test
932 $ hg -R testdelete/nested2 ci -m test
932 $ hg -R testdelete/nested2 ci -m test
933 $ echo nested = nested > testdelete/.hgsub
933 $ echo nested = nested > testdelete/.hgsub
934 $ echo nested2 = nested2 >> testdelete/.hgsub
934 $ echo nested2 = nested2 >> testdelete/.hgsub
935 $ hg -R testdelete add
935 $ hg -R testdelete add
936 adding testdelete/.hgsub
936 adding testdelete/.hgsub
937 $ hg -R testdelete ci -m "nested 1 & 2 added"
937 $ hg -R testdelete ci -m "nested 1 & 2 added"
938 $ echo nested = nested > testdelete/.hgsub
938 $ echo nested = nested > testdelete/.hgsub
939 $ hg -R testdelete ci -m "nested 2 deleted"
939 $ hg -R testdelete ci -m "nested 2 deleted"
940 $ cat testdelete/.hgsubstate
940 $ cat testdelete/.hgsubstate
941 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
941 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
942 $ hg -R testdelete remove testdelete/.hgsub
942 $ hg -R testdelete remove testdelete/.hgsub
943 $ hg -R testdelete ci -m ".hgsub deleted"
943 $ hg -R testdelete ci -m ".hgsub deleted"
944 $ cat testdelete/.hgsubstate
944 $ cat testdelete/.hgsubstate
945 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
945 bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested
946
946
947 test repository cloning
947 test repository cloning
948
948
949 $ mkdir mercurial mercurial2
949 $ mkdir mercurial mercurial2
950 $ hg init nested_absolute
950 $ hg init nested_absolute
951 $ echo test > nested_absolute/foo
951 $ echo test > nested_absolute/foo
952 $ hg -R nested_absolute add
952 $ hg -R nested_absolute add
953 adding nested_absolute/foo
953 adding nested_absolute/foo
954 $ hg -R nested_absolute ci -mtest
954 $ hg -R nested_absolute ci -mtest
955 $ cd mercurial
955 $ cd mercurial
956 $ hg init nested_relative
956 $ hg init nested_relative
957 $ echo test2 > nested_relative/foo2
957 $ echo test2 > nested_relative/foo2
958 $ hg -R nested_relative add
958 $ hg -R nested_relative add
959 adding nested_relative/foo2
959 adding nested_relative/foo2
960 $ hg -R nested_relative ci -mtest2
960 $ hg -R nested_relative ci -mtest2
961 $ hg init main
961 $ hg init main
962 $ echo "nested_relative = ../nested_relative" > main/.hgsub
962 $ echo "nested_relative = ../nested_relative" > main/.hgsub
963 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
963 $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub
964 $ hg -R main add
964 $ hg -R main add
965 adding main/.hgsub
965 adding main/.hgsub
966 $ hg -R main ci -m "add subrepos"
966 $ hg -R main ci -m "add subrepos"
967 $ cd ..
967 $ cd ..
968 $ hg clone mercurial/main mercurial2/main
968 $ hg clone mercurial/main mercurial2/main
969 updating to branch default
969 updating to branch default
970 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
970 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
971 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
971 $ cat mercurial2/main/nested_absolute/.hg/hgrc \
972 > mercurial2/main/nested_relative/.hg/hgrc
972 > mercurial2/main/nested_relative/.hg/hgrc
973 [paths]
973 [paths]
974 default = $TESTTMP/mercurial/nested_absolute
974 default = $TESTTMP/mercurial/nested_absolute
975 [paths]
975 [paths]
976 default = $TESTTMP/mercurial/nested_relative
976 default = $TESTTMP/mercurial/nested_relative
977 $ rm -rf mercurial mercurial2
977 $ rm -rf mercurial mercurial2
978
978
979 Issue1977: multirepo push should fail if subrepo push fails
979 Issue1977: multirepo push should fail if subrepo push fails
980
980
981 $ hg init repo
981 $ hg init repo
982 $ hg init repo/s
982 $ hg init repo/s
983 $ echo a > repo/s/a
983 $ echo a > repo/s/a
984 $ hg -R repo/s ci -Am0
984 $ hg -R repo/s ci -Am0
985 adding a
985 adding a
986 $ echo s = s > repo/.hgsub
986 $ echo s = s > repo/.hgsub
987 $ hg -R repo ci -Am1
987 $ hg -R repo ci -Am1
988 adding .hgsub
988 adding .hgsub
989 $ hg clone repo repo2
989 $ hg clone repo repo2
990 updating to branch default
990 updating to branch default
991 cloning subrepo s from $TESTTMP/repo/s
991 cloning subrepo s from $TESTTMP/repo/s
992 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
992 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
993 $ hg -q -R repo2 pull -u
993 $ hg -q -R repo2 pull -u
994 $ echo 1 > repo2/s/a
994 $ echo 1 > repo2/s/a
995 $ hg -R repo2/s ci -m2
995 $ hg -R repo2/s ci -m2
996 $ hg -q -R repo2/s push
996 $ hg -q -R repo2/s push
997 $ hg -R repo2/s up -C 0
997 $ hg -R repo2/s up -C 0
998 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
998 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
999 $ echo 2 > repo2/s/b
999 $ echo 2 > repo2/s/b
1000 $ hg -R repo2/s ci -m3 -A
1000 $ hg -R repo2/s ci -m3 -A
1001 adding b
1001 adding b
1002 created new head
1002 created new head
1003 $ hg -R repo2 ci -m3
1003 $ hg -R repo2 ci -m3
1004 $ hg -q -R repo2 push
1004 $ hg -q -R repo2 push
1005 abort: push creates new remote head cc505f09a8b2! (in subrepository "s")
1005 abort: push creates new remote head cc505f09a8b2! (in subrepository "s")
1006 (merge or see 'hg help push' for details about pushing new heads)
1006 (merge or see 'hg help push' for details about pushing new heads)
1007 [255]
1007 [255]
1008 $ hg -R repo update
1008 $ hg -R repo update
1009 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1009 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1010
1010
1011 test if untracked file is not overwritten
1011 test if untracked file is not overwritten
1012
1012
1013 (this also tests that updated .hgsubstate is treated as "modified",
1013 (this also tests that updated .hgsubstate is treated as "modified",
1014 when 'merge.update()' is aborted before 'merge.recordupdates()', even
1014 when 'merge.update()' is aborted before 'merge.recordupdates()', even
1015 if none of mode, size and timestamp of it isn't changed on the
1015 if none of mode, size and timestamp of it isn't changed on the
1016 filesystem (see also issue4583))
1016 filesystem (see also issue4583))
1017
1017
1018 $ echo issue3276_ok > repo/s/b
1018 $ echo issue3276_ok > repo/s/b
1019 $ hg -R repo2 push -f -q
1019 $ hg -R repo2 push -f -q
1020 $ touch -t 200001010000 repo/.hgsubstate
1020 $ touch -t 200001010000 repo/.hgsubstate
1021
1021
1022 $ cat >> repo/.hg/hgrc <<EOF
1022 $ cat >> repo/.hg/hgrc <<EOF
1023 > [fakedirstatewritetime]
1023 > [fakedirstatewritetime]
1024 > # emulate invoking dirstate.write() via repo.status()
1024 > # emulate invoking dirstate.write() via repo.status()
1025 > # at 2000-01-01 00:00
1025 > # at 2000-01-01 00:00
1026 > fakenow = 200001010000
1026 > fakenow = 200001010000
1027 >
1027 >
1028 > [extensions]
1028 > [extensions]
1029 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
1029 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
1030 > EOF
1030 > EOF
1031 $ hg -R repo update
1031 $ hg -R repo update
1032 b: untracked file differs
1032 b: untracked file differs
1033 abort: untracked files in working directory differ from files in requested revision (in subrepository "s")
1033 abort: untracked files in working directory differ from files in requested revision (in subrepository "s")
1034 [255]
1034 [255]
1035 $ cat >> repo/.hg/hgrc <<EOF
1035 $ cat >> repo/.hg/hgrc <<EOF
1036 > [extensions]
1036 > [extensions]
1037 > fakedirstatewritetime = !
1037 > fakedirstatewritetime = !
1038 > EOF
1038 > EOF
1039
1039
1040 $ cat repo/s/b
1040 $ cat repo/s/b
1041 issue3276_ok
1041 issue3276_ok
1042 $ rm repo/s/b
1042 $ rm repo/s/b
1043 $ touch -t 200001010000 repo/.hgsubstate
1043 $ touch -t 200001010000 repo/.hgsubstate
1044 $ hg -R repo revert --all
1044 $ hg -R repo revert --all
1045 reverting repo/.hgsubstate
1045 reverting repo/.hgsubstate
1046 reverting subrepo s
1046 reverting subrepo s
1047 $ hg -R repo update
1047 $ hg -R repo update
1048 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1048 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1049 $ cat repo/s/b
1049 $ cat repo/s/b
1050 2
1050 2
1051 $ rm -rf repo2 repo
1051 $ rm -rf repo2 repo
1052
1052
1053
1053
1054 Issue1852 subrepos with relative paths always push/pull relative to default
1054 Issue1852 subrepos with relative paths always push/pull relative to default
1055
1055
1056 Prepare a repo with subrepo
1056 Prepare a repo with subrepo
1057
1057
1058 $ hg init issue1852a
1058 $ hg init issue1852a
1059 $ cd issue1852a
1059 $ cd issue1852a
1060 $ hg init sub/repo
1060 $ hg init sub/repo
1061 $ echo test > sub/repo/foo
1061 $ echo test > sub/repo/foo
1062 $ hg -R sub/repo add sub/repo/foo
1062 $ hg -R sub/repo add sub/repo/foo
1063 $ echo sub/repo = sub/repo > .hgsub
1063 $ echo sub/repo = sub/repo > .hgsub
1064 $ hg add .hgsub
1064 $ hg add .hgsub
1065 $ hg ci -mtest
1065 $ hg ci -mtest
1066 committing subrepository sub/repo
1066 committing subrepository sub/repo
1067 $ echo test >> sub/repo/foo
1067 $ echo test >> sub/repo/foo
1068 $ hg ci -mtest
1068 $ hg ci -mtest
1069 committing subrepository sub/repo
1069 committing subrepository sub/repo
1070 $ hg cat sub/repo/foo
1070 $ hg cat sub/repo/foo
1071 test
1071 test
1072 test
1072 test
1073 $ hg cat sub/repo/foo -Tjson | sed 's|\\\\|/|g'
1073 $ hg cat sub/repo/foo -Tjson | sed 's|\\\\|/|g'
1074 [
1074 [
1075 {
1075 {
1076 "data": "test\ntest\n",
1076 "data": "test\ntest\n",
1077 "path": "foo"
1077 "path": "foo"
1078 }
1078 }
1079 ]
1079 ]
1080
1080
1081 non-exact match:
1081 non-exact match:
1082
1082
1083 $ hg cat -T '{path|relpath}\n' 'glob:**'
1083 $ hg cat -T '{path|relpath}\n' 'glob:**'
1084 .hgsub
1084 .hgsub
1085 .hgsubstate
1085 .hgsubstate
1086 sub/repo/foo
1086 sub/repo/foo
1087 $ hg cat -T '{path|relpath}\n' 're:^sub'
1087 $ hg cat -T '{path|relpath}\n' 're:^sub'
1088 sub/repo/foo
1088 sub/repo/foo
1089
1089
1090 missing subrepos in working directory:
1090 missing subrepos in working directory:
1091
1091
1092 $ mkdir -p tmp/sub/repo
1092 $ mkdir -p tmp/sub/repo
1093 $ hg cat -r 0 --output tmp/%p_p sub/repo/foo
1093 $ hg cat -r 0 --output tmp/%p_p sub/repo/foo
1094 $ cat tmp/sub/repo/foo_p
1094 $ cat tmp/sub/repo/foo_p
1095 test
1095 test
1096 $ mv sub/repo sub_
1096 $ mv sub/repo sub_
1097 $ hg cat sub/repo/baz
1097 $ hg cat sub/repo/baz
1098 skipping missing subrepository: sub/repo
1098 skipping missing subrepository: sub/repo
1099 [1]
1099 [1]
1100 $ rm -rf sub/repo
1100 $ rm -rf sub/repo
1101 $ mv sub_ sub/repo
1101 $ mv sub_ sub/repo
1102 $ cd ..
1102 $ cd ..
1103
1103
1104 Create repo without default path, pull top repo, and see what happens on update
1104 Create repo without default path, pull top repo, and see what happens on update
1105
1105
1106 $ hg init issue1852b
1106 $ hg init issue1852b
1107 $ hg -R issue1852b pull issue1852a
1107 $ hg -R issue1852b pull issue1852a
1108 pulling from issue1852a
1108 pulling from issue1852a
1109 requesting all changes
1109 requesting all changes
1110 adding changesets
1110 adding changesets
1111 adding manifests
1111 adding manifests
1112 adding file changes
1112 adding file changes
1113 added 2 changesets with 3 changes to 2 files
1113 added 2 changesets with 3 changes to 2 files
1114 new changesets 19487b456929:be5eb94e7215
1114 new changesets 19487b456929:be5eb94e7215
1115 (run 'hg update' to get a working copy)
1115 (run 'hg update' to get a working copy)
1116 $ hg -R issue1852b update
1116 $ hg -R issue1852b update
1117 abort: default path for subrepository not found (in subrepository "sub/repo")
1117 abort: default path for subrepository not found (in subrepository "sub/repo")
1118 [255]
1118 [255]
1119
1119
1120 Ensure a full traceback, not just the SubrepoAbort part
1120 Ensure a full traceback, not just the SubrepoAbort part
1121
1121
1122 $ hg -R issue1852b update --traceback 2>&1 | grep 'raise error\.Abort'
1122 $ hg -R issue1852b update --traceback 2>&1 | grep 'raise error\.Abort'
1123 raise error.Abort(_("default path for subrepository not found"))
1123 raise error.Abort(_("default path for subrepository not found"))
1124
1124
1125 Pull -u now doesn't help
1125 Pull -u now doesn't help
1126
1126
1127 $ hg -R issue1852b pull -u issue1852a
1127 $ hg -R issue1852b pull -u issue1852a
1128 pulling from issue1852a
1128 pulling from issue1852a
1129 searching for changes
1129 searching for changes
1130 no changes found
1130 no changes found
1131
1131
1132 Try the same, but with pull -u
1132 Try the same, but with pull -u
1133
1133
1134 $ hg init issue1852c
1134 $ hg init issue1852c
1135 $ hg -R issue1852c pull -r0 -u issue1852a
1135 $ hg -R issue1852c pull -r0 -u issue1852a
1136 pulling from issue1852a
1136 pulling from issue1852a
1137 adding changesets
1137 adding changesets
1138 adding manifests
1138 adding manifests
1139 adding file changes
1139 adding file changes
1140 added 1 changesets with 2 changes to 2 files
1140 added 1 changesets with 2 changes to 2 files
1141 new changesets 19487b456929
1141 new changesets 19487b456929
1142 cloning subrepo sub/repo from issue1852a/sub/repo
1142 cloning subrepo sub/repo from issue1852a/sub/repo
1143 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1143 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1144
1144
1145 Try to push from the other side
1145 Try to push from the other side
1146
1146
1147 $ hg -R issue1852a push `pwd`/issue1852c
1147 $ hg -R issue1852a push `pwd`/issue1852c
1148 pushing to $TESTTMP/issue1852c
1148 pushing to $TESTTMP/issue1852c
1149 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo
1149 pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo
1150 searching for changes
1150 searching for changes
1151 no changes found
1151 no changes found
1152 searching for changes
1152 searching for changes
1153 adding changesets
1153 adding changesets
1154 adding manifests
1154 adding manifests
1155 adding file changes
1155 adding file changes
1156 added 1 changesets with 1 changes to 1 files
1156 added 1 changesets with 1 changes to 1 files
1157
1157
1158 Incoming and outgoing should not use the default path:
1158 Incoming and outgoing should not use the default path:
1159
1159
1160 $ hg clone -q issue1852a issue1852d
1160 $ hg clone -q issue1852a issue1852d
1161 $ hg -R issue1852d outgoing --subrepos issue1852c
1161 $ hg -R issue1852d outgoing --subrepos issue1852c
1162 comparing with issue1852c
1162 comparing with issue1852c
1163 searching for changes
1163 searching for changes
1164 no changes found
1164 no changes found
1165 comparing with issue1852c/sub/repo
1165 comparing with issue1852c/sub/repo
1166 searching for changes
1166 searching for changes
1167 no changes found
1167 no changes found
1168 [1]
1168 [1]
1169 $ hg -R issue1852d incoming --subrepos issue1852c
1169 $ hg -R issue1852d incoming --subrepos issue1852c
1170 comparing with issue1852c
1170 comparing with issue1852c
1171 searching for changes
1171 searching for changes
1172 no changes found
1172 no changes found
1173 comparing with issue1852c/sub/repo
1173 comparing with issue1852c/sub/repo
1174 searching for changes
1174 searching for changes
1175 no changes found
1175 no changes found
1176 [1]
1176 [1]
1177
1177
1178 Check that merge of a new subrepo doesn't write the uncommitted state to
1178 Check that merge of a new subrepo doesn't write the uncommitted state to
1179 .hgsubstate (issue4622)
1179 .hgsubstate (issue4622)
1180
1180
1181 $ hg init issue1852a/addedsub
1181 $ hg init issue1852a/addedsub
1182 $ echo zzz > issue1852a/addedsub/zz.txt
1182 $ echo zzz > issue1852a/addedsub/zz.txt
1183 $ hg -R issue1852a/addedsub ci -Aqm "initial ZZ"
1183 $ hg -R issue1852a/addedsub ci -Aqm "initial ZZ"
1184
1184
1185 $ hg clone issue1852a/addedsub issue1852d/addedsub
1185 $ hg clone issue1852a/addedsub issue1852d/addedsub
1186 updating to branch default
1186 updating to branch default
1187 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1187 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1188
1188
1189 $ echo def > issue1852a/sub/repo/foo
1189 $ echo def > issue1852a/sub/repo/foo
1190 $ hg -R issue1852a ci -SAm 'tweaked subrepo'
1190 $ hg -R issue1852a ci -SAm 'tweaked subrepo'
1191 adding tmp/sub/repo/foo_p
1191 adding tmp/sub/repo/foo_p
1192 committing subrepository sub/repo
1192 committing subrepository sub/repo
1193
1193
1194 $ echo 'addedsub = addedsub' >> issue1852d/.hgsub
1194 $ echo 'addedsub = addedsub' >> issue1852d/.hgsub
1195 $ echo xyz > issue1852d/sub/repo/foo
1195 $ echo xyz > issue1852d/sub/repo/foo
1196 $ hg -R issue1852d pull -u
1196 $ hg -R issue1852d pull -u
1197 pulling from $TESTTMP/issue1852a
1197 pulling from $TESTTMP/issue1852a
1198 searching for changes
1198 searching for changes
1199 adding changesets
1199 adding changesets
1200 adding manifests
1200 adding manifests
1201 adding file changes
1201 adding file changes
1202 added 1 changesets with 2 changes to 2 files
1202 added 1 changesets with 2 changes to 2 files
1203 new changesets c82b79fdcc5b
1203 new changesets c82b79fdcc5b
1204 subrepository sub/repo diverged (local revision: f42d5c7504a8, remote revision: 46cd4aac504c)
1204 subrepository sub/repo diverged (local revision: f42d5c7504a8, remote revision: 46cd4aac504c)
1205 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1205 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1206 pulling subrepo sub/repo from $TESTTMP/issue1852a/sub/repo
1206 pulling subrepo sub/repo from $TESTTMP/issue1852a/sub/repo
1207 searching for changes
1207 searching for changes
1208 adding changesets
1208 adding changesets
1209 adding manifests
1209 adding manifests
1210 adding file changes
1210 adding file changes
1211 added 1 changesets with 1 changes to 1 files
1211 added 1 changesets with 1 changes to 1 files
1212 new changesets 46cd4aac504c
1212 new changesets 46cd4aac504c
1213 subrepository sources for sub/repo differ
1213 subrepository sources for sub/repo differ
1214 use (l)ocal source (f42d5c7504a8) or (r)emote source (46cd4aac504c)? l
1214 use (l)ocal source (f42d5c7504a8) or (r)emote source (46cd4aac504c)? l
1215 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1215 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1216 $ cat issue1852d/.hgsubstate
1216 $ cat issue1852d/.hgsubstate
1217 f42d5c7504a811dda50f5cf3e5e16c3330b87172 sub/repo
1217 f42d5c7504a811dda50f5cf3e5e16c3330b87172 sub/repo
1218
1218
1219 Check status of files when none of them belong to the first
1219 Check status of files when none of them belong to the first
1220 subrepository:
1220 subrepository:
1221
1221
1222 $ hg init subrepo-status
1222 $ hg init subrepo-status
1223 $ cd subrepo-status
1223 $ cd subrepo-status
1224 $ hg init subrepo-1
1224 $ hg init subrepo-1
1225 $ hg init subrepo-2
1225 $ hg init subrepo-2
1226 $ cd subrepo-2
1226 $ cd subrepo-2
1227 $ touch file
1227 $ touch file
1228 $ hg add file
1228 $ hg add file
1229 $ cd ..
1229 $ cd ..
1230 $ echo subrepo-1 = subrepo-1 > .hgsub
1230 $ echo subrepo-1 = subrepo-1 > .hgsub
1231 $ echo subrepo-2 = subrepo-2 >> .hgsub
1231 $ echo subrepo-2 = subrepo-2 >> .hgsub
1232 $ hg add .hgsub
1232 $ hg add .hgsub
1233 $ hg ci -m 'Added subrepos'
1233 $ hg ci -m 'Added subrepos'
1234 committing subrepository subrepo-2
1234 committing subrepository subrepo-2
1235 $ hg st subrepo-2/file
1235 $ hg st subrepo-2/file
1236
1236
1237 Check that share works with subrepo
1237 Check that share works with subrepo
1238 $ hg --config extensions.share= share . ../shared
1238 $ hg --config extensions.share= share . ../shared
1239 updating working directory
1239 updating working directory
1240 sharing subrepo subrepo-1 from $TESTTMP/subrepo-status/subrepo-1
1240 sharing subrepo subrepo-1 from $TESTTMP/subrepo-status/subrepo-1
1241 sharing subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
1241 sharing subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2
1242 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1242 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1243 $ find ../shared/* | sort
1243 $ find ../shared/* | sort
1244 ../shared/subrepo-1
1244 ../shared/subrepo-1
1245 ../shared/subrepo-1/.hg
1245 ../shared/subrepo-1/.hg
1246 ../shared/subrepo-1/.hg/cache
1246 ../shared/subrepo-1/.hg/cache
1247 ../shared/subrepo-1/.hg/cache/storehash
1247 ../shared/subrepo-1/.hg/cache/storehash
1248 ../shared/subrepo-1/.hg/cache/storehash/* (glob)
1248 ../shared/subrepo-1/.hg/cache/storehash/* (glob)
1249 ../shared/subrepo-1/.hg/hgrc
1249 ../shared/subrepo-1/.hg/hgrc
1250 ../shared/subrepo-1/.hg/requires
1250 ../shared/subrepo-1/.hg/requires
1251 ../shared/subrepo-1/.hg/sharedpath
1251 ../shared/subrepo-1/.hg/sharedpath
1252 ../shared/subrepo-1/.hg/wcache
1252 ../shared/subrepo-1/.hg/wcache
1253 ../shared/subrepo-2
1253 ../shared/subrepo-2
1254 ../shared/subrepo-2/.hg
1254 ../shared/subrepo-2/.hg
1255 ../shared/subrepo-2/.hg/branch
1255 ../shared/subrepo-2/.hg/branch
1256 ../shared/subrepo-2/.hg/cache
1256 ../shared/subrepo-2/.hg/cache
1257 ../shared/subrepo-2/.hg/cache/storehash
1257 ../shared/subrepo-2/.hg/cache/storehash
1258 ../shared/subrepo-2/.hg/cache/storehash/* (glob)
1258 ../shared/subrepo-2/.hg/cache/storehash/* (glob)
1259 ../shared/subrepo-2/.hg/dirstate
1259 ../shared/subrepo-2/.hg/dirstate
1260 ../shared/subrepo-2/.hg/hgrc
1260 ../shared/subrepo-2/.hg/hgrc
1261 ../shared/subrepo-2/.hg/requires
1261 ../shared/subrepo-2/.hg/requires
1262 ../shared/subrepo-2/.hg/sharedpath
1262 ../shared/subrepo-2/.hg/sharedpath
1263 ../shared/subrepo-2/.hg/wcache
1263 ../shared/subrepo-2/.hg/wcache
1264 ../shared/subrepo-2/.hg/wcache/checkisexec (execbit !)
1264 ../shared/subrepo-2/.hg/wcache/checkisexec (execbit !)
1265 ../shared/subrepo-2/.hg/wcache/checklink (symlink !)
1265 ../shared/subrepo-2/.hg/wcache/checklink (symlink !)
1266 ../shared/subrepo-2/.hg/wcache/checklink-target (symlink !)
1266 ../shared/subrepo-2/.hg/wcache/checklink-target (symlink !)
1267 ../shared/subrepo-2/.hg/wcache/manifestfulltextcache (reporevlogstore !)
1267 ../shared/subrepo-2/file
1268 ../shared/subrepo-2/file
1268 $ hg -R ../shared in
1269 $ hg -R ../shared in
1269 abort: repository default not found!
1270 abort: repository default not found!
1270 [255]
1271 [255]
1271 $ hg -R ../shared/subrepo-2 showconfig paths
1272 $ hg -R ../shared/subrepo-2 showconfig paths
1272 paths.default=$TESTTMP/subrepo-status/subrepo-2
1273 paths.default=$TESTTMP/subrepo-status/subrepo-2
1273 $ hg -R ../shared/subrepo-1 sum --remote
1274 $ hg -R ../shared/subrepo-1 sum --remote
1274 parent: -1:000000000000 tip (empty repository)
1275 parent: -1:000000000000 tip (empty repository)
1275 branch: default
1276 branch: default
1276 commit: (clean)
1277 commit: (clean)
1277 update: (current)
1278 update: (current)
1278 remote: (synced)
1279 remote: (synced)
1279
1280
1280 Check hg update --clean
1281 Check hg update --clean
1281 $ cd $TESTTMP/t
1282 $ cd $TESTTMP/t
1282 $ rm -r t/t.orig
1283 $ rm -r t/t.orig
1283 $ hg status -S --all
1284 $ hg status -S --all
1284 C .hgsub
1285 C .hgsub
1285 C .hgsubstate
1286 C .hgsubstate
1286 C a
1287 C a
1287 C s/.hgsub
1288 C s/.hgsub
1288 C s/.hgsubstate
1289 C s/.hgsubstate
1289 C s/a
1290 C s/a
1290 C s/ss/a
1291 C s/ss/a
1291 C t/t
1292 C t/t
1292 $ echo c1 > s/a
1293 $ echo c1 > s/a
1293 $ cd s
1294 $ cd s
1294 $ echo c1 > b
1295 $ echo c1 > b
1295 $ echo c1 > c
1296 $ echo c1 > c
1296 $ hg add b
1297 $ hg add b
1297 $ cd ..
1298 $ cd ..
1298 $ hg status -S
1299 $ hg status -S
1299 M s/a
1300 M s/a
1300 A s/b
1301 A s/b
1301 ? s/c
1302 ? s/c
1302 $ hg update -C
1303 $ hg update -C
1303 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1304 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1304 updated to "925c17564ef8: 13"
1305 updated to "925c17564ef8: 13"
1305 2 other heads for branch "default"
1306 2 other heads for branch "default"
1306 $ hg status -S
1307 $ hg status -S
1307 ? s/b
1308 ? s/b
1308 ? s/c
1309 ? s/c
1309
1310
1310 Sticky subrepositories, no changes
1311 Sticky subrepositories, no changes
1311 $ cd $TESTTMP/t
1312 $ cd $TESTTMP/t
1312 $ hg id
1313 $ hg id
1313 925c17564ef8 tip
1314 925c17564ef8 tip
1314 $ hg -R s id
1315 $ hg -R s id
1315 12a213df6fa9 tip
1316 12a213df6fa9 tip
1316 $ hg -R t id
1317 $ hg -R t id
1317 52c0adc0515a tip
1318 52c0adc0515a tip
1318 $ hg update 11
1319 $ hg update 11
1319 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1320 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1320 $ hg id
1321 $ hg id
1321 365661e5936a
1322 365661e5936a
1322 $ hg -R s id
1323 $ hg -R s id
1323 fc627a69481f
1324 fc627a69481f
1324 $ hg -R t id
1325 $ hg -R t id
1325 e95bcfa18a35
1326 e95bcfa18a35
1326
1327
1327 Sticky subrepositories, file changes
1328 Sticky subrepositories, file changes
1328 $ touch s/f1
1329 $ touch s/f1
1329 $ touch t/f1
1330 $ touch t/f1
1330 $ hg add -S s/f1
1331 $ hg add -S s/f1
1331 $ hg add -S t/f1
1332 $ hg add -S t/f1
1332 $ hg id
1333 $ hg id
1333 365661e5936a+
1334 365661e5936a+
1334 $ hg -R s id
1335 $ hg -R s id
1335 fc627a69481f+
1336 fc627a69481f+
1336 $ hg -R t id
1337 $ hg -R t id
1337 e95bcfa18a35+
1338 e95bcfa18a35+
1338 $ hg update tip
1339 $ hg update tip
1339 subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9)
1340 subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9)
1340 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1341 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1341 subrepository sources for s differ
1342 subrepository sources for s differ
1342 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)? l
1343 use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)? l
1343 subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a)
1344 subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a)
1344 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1345 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1345 subrepository sources for t differ
1346 subrepository sources for t differ
1346 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)? l
1347 use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a)? l
1347 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1348 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1348 $ hg id
1349 $ hg id
1349 925c17564ef8+ tip
1350 925c17564ef8+ tip
1350 $ hg -R s id
1351 $ hg -R s id
1351 fc627a69481f+
1352 fc627a69481f+
1352 $ hg -R t id
1353 $ hg -R t id
1353 e95bcfa18a35+
1354 e95bcfa18a35+
1354 $ hg update --clean tip
1355 $ hg update --clean tip
1355 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1356 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1356
1357
1357 Sticky subrepository, revision updates
1358 Sticky subrepository, revision updates
1358 $ hg id
1359 $ hg id
1359 925c17564ef8 tip
1360 925c17564ef8 tip
1360 $ hg -R s id
1361 $ hg -R s id
1361 12a213df6fa9 tip
1362 12a213df6fa9 tip
1362 $ hg -R t id
1363 $ hg -R t id
1363 52c0adc0515a tip
1364 52c0adc0515a tip
1364 $ cd s
1365 $ cd s
1365 $ hg update -r -2
1366 $ hg update -r -2
1366 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1367 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1367 $ cd ../t
1368 $ cd ../t
1368 $ hg update -r 2
1369 $ hg update -r 2
1369 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1370 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1370 $ cd ..
1371 $ cd ..
1371 $ hg update 10
1372 $ hg update 10
1372 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1373 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1373 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1374 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1374 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c)
1375 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c)
1375 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1376 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1376 subrepository sources for t differ (in checked out version)
1377 subrepository sources for t differ (in checked out version)
1377 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)? l
1378 use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c)? l
1378 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1379 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1379 $ hg id
1380 $ hg id
1380 e45c8b14af55+
1381 e45c8b14af55+
1381 $ hg -R s id
1382 $ hg -R s id
1382 02dcf1d70411
1383 02dcf1d70411
1383 $ hg -R t id
1384 $ hg -R t id
1384 7af322bc1198
1385 7af322bc1198
1385
1386
1386 Sticky subrepository, file changes and revision updates
1387 Sticky subrepository, file changes and revision updates
1387 $ touch s/f1
1388 $ touch s/f1
1388 $ touch t/f1
1389 $ touch t/f1
1389 $ hg add -S s/f1
1390 $ hg add -S s/f1
1390 $ hg add -S t/f1
1391 $ hg add -S t/f1
1391 $ hg id
1392 $ hg id
1392 e45c8b14af55+
1393 e45c8b14af55+
1393 $ hg -R s id
1394 $ hg -R s id
1394 02dcf1d70411+
1395 02dcf1d70411+
1395 $ hg -R t id
1396 $ hg -R t id
1396 7af322bc1198+
1397 7af322bc1198+
1397 $ hg update tip
1398 $ hg update tip
1398 subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9)
1399 subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9)
1399 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1400 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1400 subrepository sources for s differ
1401 subrepository sources for s differ
1401 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)? l
1402 use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9)? l
1402 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a)
1403 subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a)
1403 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1404 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1404 subrepository sources for t differ
1405 subrepository sources for t differ
1405 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)? l
1406 use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a)? l
1406 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1407 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1407 $ hg id
1408 $ hg id
1408 925c17564ef8+ tip
1409 925c17564ef8+ tip
1409 $ hg -R s id
1410 $ hg -R s id
1410 02dcf1d70411+
1411 02dcf1d70411+
1411 $ hg -R t id
1412 $ hg -R t id
1412 7af322bc1198+
1413 7af322bc1198+
1413
1414
1414 Sticky repository, update --clean
1415 Sticky repository, update --clean
1415 $ hg update --clean tip
1416 $ hg update --clean tip
1416 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1417 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1417 $ hg id
1418 $ hg id
1418 925c17564ef8 tip
1419 925c17564ef8 tip
1419 $ hg -R s id
1420 $ hg -R s id
1420 12a213df6fa9 tip
1421 12a213df6fa9 tip
1421 $ hg -R t id
1422 $ hg -R t id
1422 52c0adc0515a tip
1423 52c0adc0515a tip
1423
1424
1424 Test subrepo already at intended revision:
1425 Test subrepo already at intended revision:
1425 $ cd s
1426 $ cd s
1426 $ hg update fc627a69481f
1427 $ hg update fc627a69481f
1427 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1428 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1428 $ cd ..
1429 $ cd ..
1429 $ hg update 11
1430 $ hg update 11
1430 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1431 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f)
1431 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1432 (M)erge, keep (l)ocal [working copy] or keep (r)emote [destination]? m
1432 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1433 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1433 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1434 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1434 $ hg id -n
1435 $ hg id -n
1435 11+
1436 11+
1436 $ hg -R s id
1437 $ hg -R s id
1437 fc627a69481f
1438 fc627a69481f
1438 $ hg -R t id
1439 $ hg -R t id
1439 e95bcfa18a35
1440 e95bcfa18a35
1440
1441
1441 Test that removing .hgsubstate doesn't break anything:
1442 Test that removing .hgsubstate doesn't break anything:
1442
1443
1443 $ hg rm -f .hgsubstate
1444 $ hg rm -f .hgsubstate
1444 $ hg ci -mrm
1445 $ hg ci -mrm
1445 nothing changed
1446 nothing changed
1446 [1]
1447 [1]
1447 $ hg log -vr tip
1448 $ hg log -vr tip
1448 changeset: 13:925c17564ef8
1449 changeset: 13:925c17564ef8
1449 tag: tip
1450 tag: tip
1450 user: test
1451 user: test
1451 date: Thu Jan 01 00:00:00 1970 +0000
1452 date: Thu Jan 01 00:00:00 1970 +0000
1452 files: .hgsubstate
1453 files: .hgsubstate
1453 description:
1454 description:
1454 13
1455 13
1455
1456
1456
1457
1457
1458
1458 Test that removing .hgsub removes .hgsubstate:
1459 Test that removing .hgsub removes .hgsubstate:
1459
1460
1460 $ hg rm .hgsub
1461 $ hg rm .hgsub
1461 $ hg ci -mrm2
1462 $ hg ci -mrm2
1462 created new head
1463 created new head
1463 $ hg log -vr tip
1464 $ hg log -vr tip
1464 changeset: 14:2400bccd50af
1465 changeset: 14:2400bccd50af
1465 tag: tip
1466 tag: tip
1466 parent: 11:365661e5936a
1467 parent: 11:365661e5936a
1467 user: test
1468 user: test
1468 date: Thu Jan 01 00:00:00 1970 +0000
1469 date: Thu Jan 01 00:00:00 1970 +0000
1469 files: .hgsub .hgsubstate
1470 files: .hgsub .hgsubstate
1470 description:
1471 description:
1471 rm2
1472 rm2
1472
1473
1473
1474
1474 Test issue3153: diff -S with deleted subrepos
1475 Test issue3153: diff -S with deleted subrepos
1475
1476
1476 $ hg diff --nodates -S -c .
1477 $ hg diff --nodates -S -c .
1477 diff -r 365661e5936a -r 2400bccd50af .hgsub
1478 diff -r 365661e5936a -r 2400bccd50af .hgsub
1478 --- a/.hgsub
1479 --- a/.hgsub
1479 +++ /dev/null
1480 +++ /dev/null
1480 @@ -1,2 +0,0 @@
1481 @@ -1,2 +0,0 @@
1481 -s = s
1482 -s = s
1482 -t = t
1483 -t = t
1483 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
1484 diff -r 365661e5936a -r 2400bccd50af .hgsubstate
1484 --- a/.hgsubstate
1485 --- a/.hgsubstate
1485 +++ /dev/null
1486 +++ /dev/null
1486 @@ -1,2 +0,0 @@
1487 @@ -1,2 +0,0 @@
1487 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1488 -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1488 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
1489 -e95bcfa18a358dc4936da981ebf4147b4cad1362 t
1489
1490
1490 Test behavior of add for explicit path in subrepo:
1491 Test behavior of add for explicit path in subrepo:
1491 $ cd ..
1492 $ cd ..
1492 $ hg init explicit
1493 $ hg init explicit
1493 $ cd explicit
1494 $ cd explicit
1494 $ echo s = s > .hgsub
1495 $ echo s = s > .hgsub
1495 $ hg add .hgsub
1496 $ hg add .hgsub
1496 $ hg init s
1497 $ hg init s
1497 $ hg ci -m0
1498 $ hg ci -m0
1498 Adding with an explicit path in a subrepo adds the file
1499 Adding with an explicit path in a subrepo adds the file
1499 $ echo c1 > f1
1500 $ echo c1 > f1
1500 $ echo c2 > s/f2
1501 $ echo c2 > s/f2
1501 $ hg st -S
1502 $ hg st -S
1502 ? f1
1503 ? f1
1503 ? s/f2
1504 ? s/f2
1504 $ hg add s/f2
1505 $ hg add s/f2
1505 $ hg st -S
1506 $ hg st -S
1506 A s/f2
1507 A s/f2
1507 ? f1
1508 ? f1
1508 $ hg ci -R s -m0
1509 $ hg ci -R s -m0
1509 $ hg ci -Am1
1510 $ hg ci -Am1
1510 adding f1
1511 adding f1
1511 Adding with an explicit path in a subrepo with -S has the same behavior
1512 Adding with an explicit path in a subrepo with -S has the same behavior
1512 $ echo c3 > f3
1513 $ echo c3 > f3
1513 $ echo c4 > s/f4
1514 $ echo c4 > s/f4
1514 $ hg st -S
1515 $ hg st -S
1515 ? f3
1516 ? f3
1516 ? s/f4
1517 ? s/f4
1517 $ hg add -S s/f4
1518 $ hg add -S s/f4
1518 $ hg st -S
1519 $ hg st -S
1519 A s/f4
1520 A s/f4
1520 ? f3
1521 ? f3
1521 $ hg ci -R s -m1
1522 $ hg ci -R s -m1
1522 $ hg ci -Ama2
1523 $ hg ci -Ama2
1523 adding f3
1524 adding f3
1524 Adding without a path or pattern silently ignores subrepos
1525 Adding without a path or pattern silently ignores subrepos
1525 $ echo c5 > f5
1526 $ echo c5 > f5
1526 $ echo c6 > s/f6
1527 $ echo c6 > s/f6
1527 $ echo c7 > s/f7
1528 $ echo c7 > s/f7
1528 $ hg st -S
1529 $ hg st -S
1529 ? f5
1530 ? f5
1530 ? s/f6
1531 ? s/f6
1531 ? s/f7
1532 ? s/f7
1532 $ hg add
1533 $ hg add
1533 adding f5
1534 adding f5
1534 $ hg st -S
1535 $ hg st -S
1535 A f5
1536 A f5
1536 ? s/f6
1537 ? s/f6
1537 ? s/f7
1538 ? s/f7
1538 $ hg ci -R s -Am2
1539 $ hg ci -R s -Am2
1539 adding f6
1540 adding f6
1540 adding f7
1541 adding f7
1541 $ hg ci -m3
1542 $ hg ci -m3
1542 Adding without a path or pattern with -S also adds files in subrepos
1543 Adding without a path or pattern with -S also adds files in subrepos
1543 $ echo c8 > f8
1544 $ echo c8 > f8
1544 $ echo c9 > s/f9
1545 $ echo c9 > s/f9
1545 $ echo c10 > s/f10
1546 $ echo c10 > s/f10
1546 $ hg st -S
1547 $ hg st -S
1547 ? f8
1548 ? f8
1548 ? s/f10
1549 ? s/f10
1549 ? s/f9
1550 ? s/f9
1550 $ hg add -S
1551 $ hg add -S
1551 adding f8
1552 adding f8
1552 adding s/f10
1553 adding s/f10
1553 adding s/f9
1554 adding s/f9
1554 $ hg st -S
1555 $ hg st -S
1555 A f8
1556 A f8
1556 A s/f10
1557 A s/f10
1557 A s/f9
1558 A s/f9
1558 $ hg ci -R s -m3
1559 $ hg ci -R s -m3
1559 $ hg ci -m4
1560 $ hg ci -m4
1560 Adding with a pattern silently ignores subrepos
1561 Adding with a pattern silently ignores subrepos
1561 $ echo c11 > fm11
1562 $ echo c11 > fm11
1562 $ echo c12 > fn12
1563 $ echo c12 > fn12
1563 $ echo c13 > s/fm13
1564 $ echo c13 > s/fm13
1564 $ echo c14 > s/fn14
1565 $ echo c14 > s/fn14
1565 $ hg st -S
1566 $ hg st -S
1566 ? fm11
1567 ? fm11
1567 ? fn12
1568 ? fn12
1568 ? s/fm13
1569 ? s/fm13
1569 ? s/fn14
1570 ? s/fn14
1570 $ hg add 'glob:**fm*'
1571 $ hg add 'glob:**fm*'
1571 adding fm11
1572 adding fm11
1572 $ hg st -S
1573 $ hg st -S
1573 A fm11
1574 A fm11
1574 ? fn12
1575 ? fn12
1575 ? s/fm13
1576 ? s/fm13
1576 ? s/fn14
1577 ? s/fn14
1577 $ hg ci -R s -Am4
1578 $ hg ci -R s -Am4
1578 adding fm13
1579 adding fm13
1579 adding fn14
1580 adding fn14
1580 $ hg ci -Am5
1581 $ hg ci -Am5
1581 adding fn12
1582 adding fn12
1582 Adding with a pattern with -S also adds matches in subrepos
1583 Adding with a pattern with -S also adds matches in subrepos
1583 $ echo c15 > fm15
1584 $ echo c15 > fm15
1584 $ echo c16 > fn16
1585 $ echo c16 > fn16
1585 $ echo c17 > s/fm17
1586 $ echo c17 > s/fm17
1586 $ echo c18 > s/fn18
1587 $ echo c18 > s/fn18
1587 $ hg st -S
1588 $ hg st -S
1588 ? fm15
1589 ? fm15
1589 ? fn16
1590 ? fn16
1590 ? s/fm17
1591 ? s/fm17
1591 ? s/fn18
1592 ? s/fn18
1592 $ hg add -S 'glob:**fm*'
1593 $ hg add -S 'glob:**fm*'
1593 adding fm15
1594 adding fm15
1594 adding s/fm17
1595 adding s/fm17
1595 $ hg st -S
1596 $ hg st -S
1596 A fm15
1597 A fm15
1597 A s/fm17
1598 A s/fm17
1598 ? fn16
1599 ? fn16
1599 ? s/fn18
1600 ? s/fn18
1600 $ hg ci -R s -Am5
1601 $ hg ci -R s -Am5
1601 adding fn18
1602 adding fn18
1602 $ hg ci -Am6
1603 $ hg ci -Am6
1603 adding fn16
1604 adding fn16
1604
1605
1605 Test behavior of forget for explicit path in subrepo:
1606 Test behavior of forget for explicit path in subrepo:
1606 Forgetting an explicit path in a subrepo untracks the file
1607 Forgetting an explicit path in a subrepo untracks the file
1607 $ echo c19 > s/f19
1608 $ echo c19 > s/f19
1608 $ hg add s/f19
1609 $ hg add s/f19
1609 $ hg st -S
1610 $ hg st -S
1610 A s/f19
1611 A s/f19
1611 $ hg forget s/f19
1612 $ hg forget s/f19
1612 $ hg st -S
1613 $ hg st -S
1613 ? s/f19
1614 ? s/f19
1614 $ rm s/f19
1615 $ rm s/f19
1615 $ cd ..
1616 $ cd ..
1616
1617
1617 Courtesy phases synchronisation to publishing server does not block the push
1618 Courtesy phases synchronisation to publishing server does not block the push
1618 (issue3781)
1619 (issue3781)
1619
1620
1620 $ cp -R main issue3781
1621 $ cp -R main issue3781
1621 $ cp -R main issue3781-dest
1622 $ cp -R main issue3781-dest
1622 $ cd issue3781-dest/s
1623 $ cd issue3781-dest/s
1623 $ hg phase tip # show we have draft changeset
1624 $ hg phase tip # show we have draft changeset
1624 5: draft
1625 5: draft
1625 $ chmod a-w .hg/store/phaseroots # prevent phase push
1626 $ chmod a-w .hg/store/phaseroots # prevent phase push
1626 $ cd ../../issue3781
1627 $ cd ../../issue3781
1627 $ cat >> .hg/hgrc << EOF
1628 $ cat >> .hg/hgrc << EOF
1628 > [paths]
1629 > [paths]
1629 > default=../issue3781-dest/
1630 > default=../issue3781-dest/
1630 > EOF
1631 > EOF
1631 $ hg push --config devel.legacy.exchange=bundle1
1632 $ hg push --config devel.legacy.exchange=bundle1
1632 pushing to $TESTTMP/issue3781-dest
1633 pushing to $TESTTMP/issue3781-dest
1633 pushing subrepo s to $TESTTMP/issue3781-dest/s
1634 pushing subrepo s to $TESTTMP/issue3781-dest/s
1634 searching for changes
1635 searching for changes
1635 no changes found
1636 no changes found
1636 searching for changes
1637 searching for changes
1637 no changes found
1638 no changes found
1638 [1]
1639 [1]
1639 # clean the push cache
1640 # clean the push cache
1640 $ rm s/.hg/cache/storehash/*
1641 $ rm s/.hg/cache/storehash/*
1641 $ hg push # bundle2+
1642 $ hg push # bundle2+
1642 pushing to $TESTTMP/issue3781-dest
1643 pushing to $TESTTMP/issue3781-dest
1643 pushing subrepo s to $TESTTMP/issue3781-dest/s
1644 pushing subrepo s to $TESTTMP/issue3781-dest/s
1644 searching for changes
1645 searching for changes
1645 no changes found
1646 no changes found
1646 searching for changes
1647 searching for changes
1647 no changes found
1648 no changes found
1648 [1]
1649 [1]
1649 $ cd ..
1650 $ cd ..
1650
1651
1651 Test phase choice for newly created commit with "phases.subrepochecks"
1652 Test phase choice for newly created commit with "phases.subrepochecks"
1652 configuration
1653 configuration
1653
1654
1654 $ cd t
1655 $ cd t
1655 $ hg update -q -r 12
1656 $ hg update -q -r 12
1656
1657
1657 $ cat >> s/ss/.hg/hgrc <<EOF
1658 $ cat >> s/ss/.hg/hgrc <<EOF
1658 > [phases]
1659 > [phases]
1659 > new-commit = secret
1660 > new-commit = secret
1660 > EOF
1661 > EOF
1661 $ cat >> s/.hg/hgrc <<EOF
1662 $ cat >> s/.hg/hgrc <<EOF
1662 > [phases]
1663 > [phases]
1663 > new-commit = draft
1664 > new-commit = draft
1664 > EOF
1665 > EOF
1665 $ echo phasecheck1 >> s/ss/a
1666 $ echo phasecheck1 >> s/ss/a
1666 $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1
1667 $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1
1667 committing subrepository ss
1668 committing subrepository ss
1668 transaction abort!
1669 transaction abort!
1669 rollback completed
1670 rollback completed
1670 abort: can't commit in draft phase conflicting secret from subrepository ss
1671 abort: can't commit in draft phase conflicting secret from subrepository ss
1671 [255]
1672 [255]
1672 $ echo phasecheck2 >> s/ss/a
1673 $ echo phasecheck2 >> s/ss/a
1673 $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2
1674 $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2
1674 committing subrepository ss
1675 committing subrepository ss
1675 $ hg -R s/ss phase tip
1676 $ hg -R s/ss phase tip
1676 3: secret
1677 3: secret
1677 $ hg -R s phase tip
1678 $ hg -R s phase tip
1678 6: draft
1679 6: draft
1679 $ echo phasecheck3 >> s/ss/a
1680 $ echo phasecheck3 >> s/ss/a
1680 $ hg -R s commit -S -m phasecheck3
1681 $ hg -R s commit -S -m phasecheck3
1681 committing subrepository ss
1682 committing subrepository ss
1682 warning: changes are committed in secret phase from subrepository ss
1683 warning: changes are committed in secret phase from subrepository ss
1683 $ hg -R s/ss phase tip
1684 $ hg -R s/ss phase tip
1684 4: secret
1685 4: secret
1685 $ hg -R s phase tip
1686 $ hg -R s phase tip
1686 7: secret
1687 7: secret
1687
1688
1688 $ cat >> t/.hg/hgrc <<EOF
1689 $ cat >> t/.hg/hgrc <<EOF
1689 > [phases]
1690 > [phases]
1690 > new-commit = draft
1691 > new-commit = draft
1691 > EOF
1692 > EOF
1692 $ cat >> .hg/hgrc <<EOF
1693 $ cat >> .hg/hgrc <<EOF
1693 > [phases]
1694 > [phases]
1694 > new-commit = public
1695 > new-commit = public
1695 > EOF
1696 > EOF
1696 $ echo phasecheck4 >> s/ss/a
1697 $ echo phasecheck4 >> s/ss/a
1697 $ echo phasecheck4 >> t/t
1698 $ echo phasecheck4 >> t/t
1698 $ hg commit -S -m phasecheck4
1699 $ hg commit -S -m phasecheck4
1699 committing subrepository s
1700 committing subrepository s
1700 committing subrepository s/ss
1701 committing subrepository s/ss
1701 warning: changes are committed in secret phase from subrepository ss
1702 warning: changes are committed in secret phase from subrepository ss
1702 committing subrepository t
1703 committing subrepository t
1703 warning: changes are committed in secret phase from subrepository s
1704 warning: changes are committed in secret phase from subrepository s
1704 created new head
1705 created new head
1705 $ hg -R s/ss phase tip
1706 $ hg -R s/ss phase tip
1706 5: secret
1707 5: secret
1707 $ hg -R s phase tip
1708 $ hg -R s phase tip
1708 8: secret
1709 8: secret
1709 $ hg -R t phase tip
1710 $ hg -R t phase tip
1710 6: draft
1711 6: draft
1711 $ hg phase tip
1712 $ hg phase tip
1712 15: secret
1713 15: secret
1713
1714
1714 $ cd ..
1715 $ cd ..
1715
1716
1716
1717
1717 Test that commit --secret works on both repo and subrepo (issue4182)
1718 Test that commit --secret works on both repo and subrepo (issue4182)
1718
1719
1719 $ cd main
1720 $ cd main
1720 $ echo secret >> b
1721 $ echo secret >> b
1721 $ echo secret >> s/b
1722 $ echo secret >> s/b
1722 $ hg commit --secret --subrepo -m "secret"
1723 $ hg commit --secret --subrepo -m "secret"
1723 committing subrepository s
1724 committing subrepository s
1724 $ hg phase -r .
1725 $ hg phase -r .
1725 6: secret
1726 6: secret
1726 $ cd s
1727 $ cd s
1727 $ hg phase -r .
1728 $ hg phase -r .
1728 6: secret
1729 6: secret
1729 $ cd ../../
1730 $ cd ../../
1730
1731
1731 Test "subrepos" template keyword
1732 Test "subrepos" template keyword
1732
1733
1733 $ cd t
1734 $ cd t
1734 $ hg update -q 15
1735 $ hg update -q 15
1735 $ cat > .hgsub <<EOF
1736 $ cat > .hgsub <<EOF
1736 > s = s
1737 > s = s
1737 > EOF
1738 > EOF
1738 $ hg commit -m "16"
1739 $ hg commit -m "16"
1739 warning: changes are committed in secret phase from subrepository s
1740 warning: changes are committed in secret phase from subrepository s
1740
1741
1741 (addition of ".hgsub" itself)
1742 (addition of ".hgsub" itself)
1742
1743
1743 $ hg diff --nodates -c 1 .hgsubstate
1744 $ hg diff --nodates -c 1 .hgsubstate
1744 diff -r f7b1eb17ad24 -r 7cf8cfea66e4 .hgsubstate
1745 diff -r f7b1eb17ad24 -r 7cf8cfea66e4 .hgsubstate
1745 --- /dev/null
1746 --- /dev/null
1746 +++ b/.hgsubstate
1747 +++ b/.hgsubstate
1747 @@ -0,0 +1,1 @@
1748 @@ -0,0 +1,1 @@
1748 +e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1749 +e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1749 $ hg log -r 1 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1750 $ hg log -r 1 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1750 f7b1eb17ad24 000000000000
1751 f7b1eb17ad24 000000000000
1751 s
1752 s
1752
1753
1753 (modification of existing entry)
1754 (modification of existing entry)
1754
1755
1755 $ hg diff --nodates -c 2 .hgsubstate
1756 $ hg diff --nodates -c 2 .hgsubstate
1756 diff -r 7cf8cfea66e4 -r df30734270ae .hgsubstate
1757 diff -r 7cf8cfea66e4 -r df30734270ae .hgsubstate
1757 --- a/.hgsubstate
1758 --- a/.hgsubstate
1758 +++ b/.hgsubstate
1759 +++ b/.hgsubstate
1759 @@ -1,1 +1,1 @@
1760 @@ -1,1 +1,1 @@
1760 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1761 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1761 +dc73e2e6d2675eb2e41e33c205f4bdab4ea5111d s
1762 +dc73e2e6d2675eb2e41e33c205f4bdab4ea5111d s
1762 $ hg log -r 2 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1763 $ hg log -r 2 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1763 7cf8cfea66e4 000000000000
1764 7cf8cfea66e4 000000000000
1764 s
1765 s
1765
1766
1766 (addition of entry)
1767 (addition of entry)
1767
1768
1768 $ hg diff --nodates -c 5 .hgsubstate
1769 $ hg diff --nodates -c 5 .hgsubstate
1769 diff -r 7cf8cfea66e4 -r 1f14a2e2d3ec .hgsubstate
1770 diff -r 7cf8cfea66e4 -r 1f14a2e2d3ec .hgsubstate
1770 --- a/.hgsubstate
1771 --- a/.hgsubstate
1771 +++ b/.hgsubstate
1772 +++ b/.hgsubstate
1772 @@ -1,1 +1,2 @@
1773 @@ -1,1 +1,2 @@
1773 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1774 e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1774 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1775 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1775 $ hg log -r 5 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1776 $ hg log -r 5 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1776 7cf8cfea66e4 000000000000
1777 7cf8cfea66e4 000000000000
1777 t
1778 t
1778
1779
1779 (removal of existing entry)
1780 (removal of existing entry)
1780
1781
1781 $ hg diff --nodates -c 16 .hgsubstate
1782 $ hg diff --nodates -c 16 .hgsubstate
1782 diff -r 8bec38d2bd0b -r f2f70bc3d3c9 .hgsubstate
1783 diff -r 8bec38d2bd0b -r f2f70bc3d3c9 .hgsubstate
1783 --- a/.hgsubstate
1784 --- a/.hgsubstate
1784 +++ b/.hgsubstate
1785 +++ b/.hgsubstate
1785 @@ -1,2 +1,1 @@
1786 @@ -1,2 +1,1 @@
1786 0731af8ca9423976d3743119d0865097c07bdc1b s
1787 0731af8ca9423976d3743119d0865097c07bdc1b s
1787 -e202dc79b04c88a636ea8913d9182a1346d9b3dc t
1788 -e202dc79b04c88a636ea8913d9182a1346d9b3dc t
1788 $ hg log -r 16 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1789 $ hg log -r 16 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1789 8bec38d2bd0b 000000000000
1790 8bec38d2bd0b 000000000000
1790 t
1791 t
1791
1792
1792 (merging)
1793 (merging)
1793
1794
1794 $ hg diff --nodates -c 9 .hgsubstate
1795 $ hg diff --nodates -c 9 .hgsubstate
1795 diff -r f6affe3fbfaa -r f0d2028bf86d .hgsubstate
1796 diff -r f6affe3fbfaa -r f0d2028bf86d .hgsubstate
1796 --- a/.hgsubstate
1797 --- a/.hgsubstate
1797 +++ b/.hgsubstate
1798 +++ b/.hgsubstate
1798 @@ -1,1 +1,2 @@
1799 @@ -1,1 +1,2 @@
1799 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1800 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1800 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1801 +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1801 $ hg log -r 9 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1802 $ hg log -r 9 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1802 f6affe3fbfaa 1f14a2e2d3ec
1803 f6affe3fbfaa 1f14a2e2d3ec
1803 t
1804 t
1804
1805
1805 (removal of ".hgsub" itself)
1806 (removal of ".hgsub" itself)
1806
1807
1807 $ hg diff --nodates -c 8 .hgsubstate
1808 $ hg diff --nodates -c 8 .hgsubstate
1808 diff -r f94576341bcf -r 96615c1dad2d .hgsubstate
1809 diff -r f94576341bcf -r 96615c1dad2d .hgsubstate
1809 --- a/.hgsubstate
1810 --- a/.hgsubstate
1810 +++ /dev/null
1811 +++ /dev/null
1811 @@ -1,2 +0,0 @@
1812 @@ -1,2 +0,0 @@
1812 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1813 -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s
1813 -7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 t
1814 -7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 t
1814 $ hg log -r 8 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1815 $ hg log -r 8 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}"
1815 f94576341bcf 000000000000
1816 f94576341bcf 000000000000
1816
1817
1817 Test that '[paths]' is configured correctly at subrepo creation
1818 Test that '[paths]' is configured correctly at subrepo creation
1818
1819
1819 $ cd $TESTTMP/tc
1820 $ cd $TESTTMP/tc
1820 $ cat > .hgsub <<EOF
1821 $ cat > .hgsub <<EOF
1821 > # to clear bogus subrepo path 'bogus=[boguspath'
1822 > # to clear bogus subrepo path 'bogus=[boguspath'
1822 > s = s
1823 > s = s
1823 > t = t
1824 > t = t
1824 > EOF
1825 > EOF
1825 $ hg update -q --clean null
1826 $ hg update -q --clean null
1826 $ rm -rf s t
1827 $ rm -rf s t
1827 $ cat >> .hg/hgrc <<EOF
1828 $ cat >> .hg/hgrc <<EOF
1828 > [paths]
1829 > [paths]
1829 > default-push = /foo/bar
1830 > default-push = /foo/bar
1830 > EOF
1831 > EOF
1831 $ hg update -q
1832 $ hg update -q
1832 $ cat s/.hg/hgrc
1833 $ cat s/.hg/hgrc
1833 [paths]
1834 [paths]
1834 default = $TESTTMP/t/s
1835 default = $TESTTMP/t/s
1835 default-push = /foo/bar/s
1836 default-push = /foo/bar/s
1836 $ cat s/ss/.hg/hgrc
1837 $ cat s/ss/.hg/hgrc
1837 [paths]
1838 [paths]
1838 default = $TESTTMP/t/s/ss
1839 default = $TESTTMP/t/s/ss
1839 default-push = /foo/bar/s/ss
1840 default-push = /foo/bar/s/ss
1840 $ cat t/.hg/hgrc
1841 $ cat t/.hg/hgrc
1841 [paths]
1842 [paths]
1842 default = $TESTTMP/t/t
1843 default = $TESTTMP/t/t
1843 default-push = /foo/bar/t
1844 default-push = /foo/bar/t
1844
1845
1845 $ cd $TESTTMP/t
1846 $ cd $TESTTMP/t
1846 $ hg up -qC 0
1847 $ hg up -qC 0
1847 $ echo 'bar' > bar.txt
1848 $ echo 'bar' > bar.txt
1848 $ hg ci -Am 'branch before subrepo add'
1849 $ hg ci -Am 'branch before subrepo add'
1849 adding bar.txt
1850 adding bar.txt
1850 created new head
1851 created new head
1851 $ hg merge -r "first(subrepo('s'))"
1852 $ hg merge -r "first(subrepo('s'))"
1852 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1853 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1853 (branch merge, don't forget to commit)
1854 (branch merge, don't forget to commit)
1854 $ hg status -S -X '.hgsub*'
1855 $ hg status -S -X '.hgsub*'
1855 A s/a
1856 A s/a
1856 ? s/b
1857 ? s/b
1857 ? s/c
1858 ? s/c
1858 ? s/f1
1859 ? s/f1
1859 $ hg status -S --rev 'p2()'
1860 $ hg status -S --rev 'p2()'
1860 A bar.txt
1861 A bar.txt
1861 ? s/b
1862 ? s/b
1862 ? s/c
1863 ? s/c
1863 ? s/f1
1864 ? s/f1
1864 $ hg diff -S -X '.hgsub*' --nodates
1865 $ hg diff -S -X '.hgsub*' --nodates
1865 diff -r 000000000000 s/a
1866 diff -r 000000000000 s/a
1866 --- /dev/null
1867 --- /dev/null
1867 +++ b/s/a
1868 +++ b/s/a
1868 @@ -0,0 +1,1 @@
1869 @@ -0,0 +1,1 @@
1869 +a
1870 +a
1870 $ hg diff -S --rev 'p2()' --nodates
1871 $ hg diff -S --rev 'p2()' --nodates
1871 diff -r 7cf8cfea66e4 bar.txt
1872 diff -r 7cf8cfea66e4 bar.txt
1872 --- /dev/null
1873 --- /dev/null
1873 +++ b/bar.txt
1874 +++ b/bar.txt
1874 @@ -0,0 +1,1 @@
1875 @@ -0,0 +1,1 @@
1875 +bar
1876 +bar
1876
1877
1877 $ cd ..
1878 $ cd ..
1878
1879
1879 test for ssh exploit 2017-07-25
1880 test for ssh exploit 2017-07-25
1880
1881
1881 $ cat >> $HGRCPATH << EOF
1882 $ cat >> $HGRCPATH << EOF
1882 > [ui]
1883 > [ui]
1883 > ssh = sh -c "read l; read l; read l"
1884 > ssh = sh -c "read l; read l; read l"
1884 > EOF
1885 > EOF
1885
1886
1886 $ hg init malicious-proxycommand
1887 $ hg init malicious-proxycommand
1887 $ cd malicious-proxycommand
1888 $ cd malicious-proxycommand
1888 $ echo 's = [hg]ssh://-oProxyCommand=touch${IFS}owned/path' > .hgsub
1889 $ echo 's = [hg]ssh://-oProxyCommand=touch${IFS}owned/path' > .hgsub
1889 $ hg init s
1890 $ hg init s
1890 $ cd s
1891 $ cd s
1891 $ echo init > init
1892 $ echo init > init
1892 $ hg add
1893 $ hg add
1893 adding init
1894 adding init
1894 $ hg commit -m init
1895 $ hg commit -m init
1895 $ cd ..
1896 $ cd ..
1896 $ hg add .hgsub
1897 $ hg add .hgsub
1897 $ hg ci -m 'add subrepo'
1898 $ hg ci -m 'add subrepo'
1898 $ cd ..
1899 $ cd ..
1899 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1900 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1900 updating to branch default
1901 updating to branch default
1901 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
1902 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
1902 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s")
1903 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s")
1903 [255]
1904 [255]
1904
1905
1905 also check that a percent encoded '-' (%2D) doesn't work
1906 also check that a percent encoded '-' (%2D) doesn't work
1906
1907
1907 $ cd malicious-proxycommand
1908 $ cd malicious-proxycommand
1908 $ echo 's = [hg]ssh://%2DoProxyCommand=touch${IFS}owned/path' > .hgsub
1909 $ echo 's = [hg]ssh://%2DoProxyCommand=touch${IFS}owned/path' > .hgsub
1909 $ hg ci -m 'change url to percent encoded'
1910 $ hg ci -m 'change url to percent encoded'
1910 $ cd ..
1911 $ cd ..
1911 $ rm -r malicious-proxycommand-clone
1912 $ rm -r malicious-proxycommand-clone
1912 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1913 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1913 updating to branch default
1914 updating to branch default
1914 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
1915 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path
1915 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s")
1916 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s")
1916 [255]
1917 [255]
1917
1918
1918 also check for a pipe
1919 also check for a pipe
1919
1920
1920 $ cd malicious-proxycommand
1921 $ cd malicious-proxycommand
1921 $ echo 's = [hg]ssh://fakehost|touch${IFS}owned/path' > .hgsub
1922 $ echo 's = [hg]ssh://fakehost|touch${IFS}owned/path' > .hgsub
1922 $ hg ci -m 'change url to pipe'
1923 $ hg ci -m 'change url to pipe'
1923 $ cd ..
1924 $ cd ..
1924 $ rm -r malicious-proxycommand-clone
1925 $ rm -r malicious-proxycommand-clone
1925 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1926 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1926 updating to branch default
1927 updating to branch default
1927 cloning subrepo s from ssh://fakehost%7Ctouch%24%7BIFS%7Downed/path
1928 cloning subrepo s from ssh://fakehost%7Ctouch%24%7BIFS%7Downed/path
1928 abort: no suitable response from remote hg!
1929 abort: no suitable response from remote hg!
1929 [255]
1930 [255]
1930 $ [ ! -f owned ] || echo 'you got owned'
1931 $ [ ! -f owned ] || echo 'you got owned'
1931
1932
1932 also check that a percent encoded '|' (%7C) doesn't work
1933 also check that a percent encoded '|' (%7C) doesn't work
1933
1934
1934 $ cd malicious-proxycommand
1935 $ cd malicious-proxycommand
1935 $ echo 's = [hg]ssh://fakehost%7Ctouch%20owned/path' > .hgsub
1936 $ echo 's = [hg]ssh://fakehost%7Ctouch%20owned/path' > .hgsub
1936 $ hg ci -m 'change url to percent encoded pipe'
1937 $ hg ci -m 'change url to percent encoded pipe'
1937 $ cd ..
1938 $ cd ..
1938 $ rm -r malicious-proxycommand-clone
1939 $ rm -r malicious-proxycommand-clone
1939 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1940 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1940 updating to branch default
1941 updating to branch default
1941 cloning subrepo s from ssh://fakehost%7Ctouch%20owned/path
1942 cloning subrepo s from ssh://fakehost%7Ctouch%20owned/path
1942 abort: no suitable response from remote hg!
1943 abort: no suitable response from remote hg!
1943 [255]
1944 [255]
1944 $ [ ! -f owned ] || echo 'you got owned'
1945 $ [ ! -f owned ] || echo 'you got owned'
1945
1946
1946 and bad usernames:
1947 and bad usernames:
1947 $ cd malicious-proxycommand
1948 $ cd malicious-proxycommand
1948 $ echo 's = [hg]ssh://-oProxyCommand=touch owned@example.com/path' > .hgsub
1949 $ echo 's = [hg]ssh://-oProxyCommand=touch owned@example.com/path' > .hgsub
1949 $ hg ci -m 'owned username'
1950 $ hg ci -m 'owned username'
1950 $ cd ..
1951 $ cd ..
1951 $ rm -r malicious-proxycommand-clone
1952 $ rm -r malicious-proxycommand-clone
1952 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1953 $ hg clone malicious-proxycommand malicious-proxycommand-clone
1953 updating to branch default
1954 updating to branch default
1954 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%20owned@example.com/path
1955 cloning subrepo s from ssh://-oProxyCommand%3Dtouch%20owned@example.com/path
1955 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned@example.com/path' (in subrepository "s")
1956 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned@example.com/path' (in subrepository "s")
1956 [255]
1957 [255]
1957
1958
1958 Test convert subrepositories including merge (issue5526):
1959 Test convert subrepositories including merge (issue5526):
1959
1960
1960 $ hg init tconv
1961 $ hg init tconv
1961 $ hg convert --config extensions.convert= -q t/s tconv/s
1962 $ hg convert --config extensions.convert= -q t/s tconv/s
1962 $ hg convert --config extensions.convert= -q t/s/ss tconv/s/ss
1963 $ hg convert --config extensions.convert= -q t/s/ss tconv/s/ss
1963 $ hg convert --config extensions.convert= -q t/t tconv/t
1964 $ hg convert --config extensions.convert= -q t/t tconv/t
1964
1965
1965 convert shouldn't fail because of pseudo filenode:
1966 convert shouldn't fail because of pseudo filenode:
1966
1967
1967 $ hg convert --config extensions.convert= t tconv
1968 $ hg convert --config extensions.convert= t tconv
1968 scanning source...
1969 scanning source...
1969 sorting...
1970 sorting...
1970 converting...
1971 converting...
1971 17 0
1972 17 0
1972 16 1
1973 16 1
1973 15 2
1974 15 2
1974 14 3
1975 14 3
1975 13 4
1976 13 4
1976 12 5
1977 12 5
1977 11 6
1978 11 6
1978 10 7
1979 10 7
1979 9 8
1980 9 8
1980 8 9
1981 8 9
1981 7 10
1982 7 10
1982 6 11
1983 6 11
1983 5 12
1984 5 12
1984 4 13
1985 4 13
1985 3 rm2
1986 3 rm2
1986 2 phasecheck4
1987 2 phasecheck4
1987 1 16
1988 1 16
1988 0 branch before subrepo add
1989 0 branch before subrepo add
1989
1990
1990 converted .hgsubstate should point to valid nodes:
1991 converted .hgsubstate should point to valid nodes:
1991
1992
1992 $ hg up -R tconv 9
1993 $ hg up -R tconv 9
1993 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1994 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1994 $ cat tconv/.hgsubstate
1995 $ cat tconv/.hgsubstate
1995 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1996 fc627a69481fcbe5f1135069e8a3881c023e4cf5 s
1996 60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
1997 60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t
General Comments 0
You need to be logged in to leave comments. Login now