##// END OF EJS Templates
largefiles: enable islfilesrepo() prior to a commit (issue3541)...
Matt Harbison -
r17659:ae57920a stable
parent child Browse files
Show More
@@ -1,467 +1,470 b''
1 1 # Copyright 2009-2010 Gregory P. Ward
2 2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 3 # Copyright 2010-2011 Fog Creek Software
4 4 # Copyright 2010-2011 Unity Technologies
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 '''largefiles utility code: must not import other modules in this package.'''
10 10
11 11 import os
12 12 import errno
13 13 import platform
14 14 import shutil
15 15 import stat
16 16
17 17 from mercurial import dirstate, httpconnection, match as match_, util, scmutil
18 18 from mercurial.i18n import _
19 19
20 20 shortname = '.hglf'
21 21 longname = 'largefiles'
22 22
23 23
24 24 # -- Portability wrappers ----------------------------------------------
25 25
26 26 def dirstatewalk(dirstate, matcher, unknown=False, ignored=False):
27 27 return dirstate.walk(matcher, [], unknown, ignored)
28 28
29 29 def repoadd(repo, list):
30 30 add = repo[None].add
31 31 return add(list)
32 32
33 33 def reporemove(repo, list, unlink=False):
34 34 def remove(list, unlink):
35 35 wlock = repo.wlock()
36 36 try:
37 37 if unlink:
38 38 for f in list:
39 39 try:
40 40 util.unlinkpath(repo.wjoin(f))
41 41 except OSError, inst:
42 42 if inst.errno != errno.ENOENT:
43 43 raise
44 44 repo[None].forget(list)
45 45 finally:
46 46 wlock.release()
47 47 return remove(list, unlink=unlink)
48 48
49 49 def repoforget(repo, list):
50 50 forget = repo[None].forget
51 51 return forget(list)
52 52
53 53 def findoutgoing(repo, remote, force):
54 54 from mercurial import discovery
55 55 common, _anyinc, _heads = discovery.findcommonincoming(repo,
56 56 remote.peer(), force=force)
57 57 return repo.changelog.findmissing(common)
58 58
59 59 # -- Private worker functions ------------------------------------------
60 60
61 61 def getminsize(ui, assumelfiles, opt, default=10):
62 62 lfsize = opt
63 63 if not lfsize and assumelfiles:
64 64 lfsize = ui.config(longname, 'minsize', default=default)
65 65 if lfsize:
66 66 try:
67 67 lfsize = float(lfsize)
68 68 except ValueError:
69 69 raise util.Abort(_('largefiles: size must be number (not %s)\n')
70 70 % lfsize)
71 71 if lfsize is None:
72 72 raise util.Abort(_('minimum size for largefiles must be specified'))
73 73 return lfsize
74 74
75 75 def link(src, dest):
76 76 try:
77 77 util.oslink(src, dest)
78 78 except OSError:
79 79 # if hardlinks fail, fallback on atomic copy
80 80 dst = util.atomictempfile(dest)
81 81 for chunk in util.filechunkiter(open(src, 'rb')):
82 82 dst.write(chunk)
83 83 dst.close()
84 84 os.chmod(dest, os.stat(src).st_mode)
85 85
86 86 def usercachepath(ui, hash):
87 87 path = ui.configpath(longname, 'usercache', None)
88 88 if path:
89 89 path = os.path.join(path, hash)
90 90 else:
91 91 if os.name == 'nt':
92 92 appdata = os.getenv('LOCALAPPDATA', os.getenv('APPDATA'))
93 93 if appdata:
94 94 path = os.path.join(appdata, longname, hash)
95 95 elif platform.system() == 'Darwin':
96 96 home = os.getenv('HOME')
97 97 if home:
98 98 path = os.path.join(home, 'Library', 'Caches',
99 99 longname, hash)
100 100 elif os.name == 'posix':
101 101 path = os.getenv('XDG_CACHE_HOME')
102 102 if path:
103 103 path = os.path.join(path, longname, hash)
104 104 else:
105 105 home = os.getenv('HOME')
106 106 if home:
107 107 path = os.path.join(home, '.cache', longname, hash)
108 108 else:
109 109 raise util.Abort(_('unknown operating system: %s\n') % os.name)
110 110 return path
111 111
112 112 def inusercache(ui, hash):
113 113 path = usercachepath(ui, hash)
114 114 return path and os.path.exists(path)
115 115
116 116 def findfile(repo, hash):
117 117 if instore(repo, hash):
118 118 repo.ui.note(_('found %s in store\n') % hash)
119 119 return storepath(repo, hash)
120 120 elif inusercache(repo.ui, hash):
121 121 repo.ui.note(_('found %s in system cache\n') % hash)
122 122 path = storepath(repo, hash)
123 123 util.makedirs(os.path.dirname(path))
124 124 link(usercachepath(repo.ui, hash), path)
125 125 return path
126 126 return None
127 127
128 128 class largefilesdirstate(dirstate.dirstate):
129 129 def __getitem__(self, key):
130 130 return super(largefilesdirstate, self).__getitem__(unixpath(key))
131 131 def normal(self, f):
132 132 return super(largefilesdirstate, self).normal(unixpath(f))
133 133 def remove(self, f):
134 134 return super(largefilesdirstate, self).remove(unixpath(f))
135 135 def add(self, f):
136 136 return super(largefilesdirstate, self).add(unixpath(f))
137 137 def drop(self, f):
138 138 return super(largefilesdirstate, self).drop(unixpath(f))
139 139 def forget(self, f):
140 140 return super(largefilesdirstate, self).forget(unixpath(f))
141 141 def normallookup(self, f):
142 142 return super(largefilesdirstate, self).normallookup(unixpath(f))
143 143
144 def openlfdirstate(ui, repo):
144 def openlfdirstate(ui, repo, create=True):
145 145 '''
146 146 Return a dirstate object that tracks largefiles: i.e. its root is
147 147 the repo root, but it is saved in .hg/largefiles/dirstate.
148 148 '''
149 149 admin = repo.join(longname)
150 150 opener = scmutil.opener(admin)
151 151 lfdirstate = largefilesdirstate(opener, ui, repo.root,
152 152 repo.dirstate._validate)
153 153
154 154 # If the largefiles dirstate does not exist, populate and create
155 155 # it. This ensures that we create it on the first meaningful
156 156 # largefiles operation in a new clone.
157 if not os.path.exists(os.path.join(admin, 'dirstate')):
157 if create and not os.path.exists(os.path.join(admin, 'dirstate')):
158 158 util.makedirs(admin)
159 159 matcher = getstandinmatcher(repo)
160 160 for standin in dirstatewalk(repo.dirstate, matcher):
161 161 lfile = splitstandin(standin)
162 162 hash = readstandin(repo, lfile)
163 163 lfdirstate.normallookup(lfile)
164 164 try:
165 165 if hash == hashfile(repo.wjoin(lfile)):
166 166 lfdirstate.normal(lfile)
167 167 except OSError, err:
168 168 if err.errno != errno.ENOENT:
169 169 raise
170 170 return lfdirstate
171 171
172 172 def lfdirstatestatus(lfdirstate, repo, rev):
173 173 match = match_.always(repo.root, repo.getcwd())
174 174 s = lfdirstate.status(match, [], False, False, False)
175 175 unsure, modified, added, removed, missing, unknown, ignored, clean = s
176 176 for lfile in unsure:
177 177 if repo[rev][standin(lfile)].data().strip() != \
178 178 hashfile(repo.wjoin(lfile)):
179 179 modified.append(lfile)
180 180 else:
181 181 clean.append(lfile)
182 182 lfdirstate.normal(lfile)
183 183 return (modified, added, removed, missing, unknown, ignored, clean)
184 184
185 185 def listlfiles(repo, rev=None, matcher=None):
186 186 '''return a list of largefiles in the working copy or the
187 187 specified changeset'''
188 188
189 189 if matcher is None:
190 190 matcher = getstandinmatcher(repo)
191 191
192 192 # ignore unknown files in working directory
193 193 return [splitstandin(f)
194 194 for f in repo[rev].walk(matcher)
195 195 if rev is not None or repo.dirstate[f] != '?']
196 196
197 197 def instore(repo, hash):
198 198 return os.path.exists(storepath(repo, hash))
199 199
200 200 def storepath(repo, hash):
201 201 return repo.join(os.path.join(longname, hash))
202 202
203 203 def copyfromcache(repo, hash, filename):
204 204 '''Copy the specified largefile from the repo or system cache to
205 205 filename in the repository. Return true on success or false if the
206 206 file was not found in either cache (which should not happened:
207 207 this is meant to be called only after ensuring that the needed
208 208 largefile exists in the cache).'''
209 209 path = findfile(repo, hash)
210 210 if path is None:
211 211 return False
212 212 util.makedirs(os.path.dirname(repo.wjoin(filename)))
213 213 # The write may fail before the file is fully written, but we
214 214 # don't use atomic writes in the working copy.
215 215 shutil.copy(path, repo.wjoin(filename))
216 216 return True
217 217
218 218 def copytostore(repo, rev, file, uploaded=False):
219 219 hash = readstandin(repo, file)
220 220 if instore(repo, hash):
221 221 return
222 222 copytostoreabsolute(repo, repo.wjoin(file), hash)
223 223
224 224 def copyalltostore(repo, node):
225 225 '''Copy all largefiles in a given revision to the store'''
226 226
227 227 ctx = repo[node]
228 228 for filename in ctx.files():
229 229 if isstandin(filename) and filename in ctx.manifest():
230 230 realfile = splitstandin(filename)
231 231 copytostore(repo, ctx.node(), realfile)
232 232
233 233
234 234 def copytostoreabsolute(repo, file, hash):
235 235 util.makedirs(os.path.dirname(storepath(repo, hash)))
236 236 if inusercache(repo.ui, hash):
237 237 link(usercachepath(repo.ui, hash), storepath(repo, hash))
238 238 else:
239 239 dst = util.atomictempfile(storepath(repo, hash),
240 240 createmode=repo.store.createmode)
241 241 for chunk in util.filechunkiter(open(file, 'rb')):
242 242 dst.write(chunk)
243 243 dst.close()
244 244 linktousercache(repo, hash)
245 245
246 246 def linktousercache(repo, hash):
247 247 path = usercachepath(repo.ui, hash)
248 248 if path:
249 249 util.makedirs(os.path.dirname(path))
250 250 link(storepath(repo, hash), path)
251 251
252 252 def getstandinmatcher(repo, pats=[], opts={}):
253 253 '''Return a match object that applies pats to the standin directory'''
254 254 standindir = repo.pathto(shortname)
255 255 if pats:
256 256 # patterns supplied: search standin directory relative to current dir
257 257 cwd = repo.getcwd()
258 258 if os.path.isabs(cwd):
259 259 # cwd is an absolute path for hg -R <reponame>
260 260 # work relative to the repository root in this case
261 261 cwd = ''
262 262 pats = [os.path.join(standindir, cwd, pat) for pat in pats]
263 263 elif os.path.isdir(standindir):
264 264 # no patterns: relative to repo root
265 265 pats = [standindir]
266 266 else:
267 267 # no patterns and no standin dir: return matcher that matches nothing
268 268 match = match_.match(repo.root, None, [], exact=True)
269 269 match.matchfn = lambda f: False
270 270 return match
271 271 return getmatcher(repo, pats, opts, showbad=False)
272 272
273 273 def getmatcher(repo, pats=[], opts={}, showbad=True):
274 274 '''Wrapper around scmutil.match() that adds showbad: if false,
275 275 neuter the match object's bad() method so it does not print any
276 276 warnings about missing files or directories.'''
277 277 match = scmutil.match(repo[None], pats, opts)
278 278
279 279 if not showbad:
280 280 match.bad = lambda f, msg: None
281 281 return match
282 282
283 283 def composestandinmatcher(repo, rmatcher):
284 284 '''Return a matcher that accepts standins corresponding to the
285 285 files accepted by rmatcher. Pass the list of files in the matcher
286 286 as the paths specified by the user.'''
287 287 smatcher = getstandinmatcher(repo, rmatcher.files())
288 288 isstandin = smatcher.matchfn
289 289 def composedmatchfn(f):
290 290 return isstandin(f) and rmatcher.matchfn(splitstandin(f))
291 291 smatcher.matchfn = composedmatchfn
292 292
293 293 return smatcher
294 294
295 295 def standin(filename):
296 296 '''Return the repo-relative path to the standin for the specified big
297 297 file.'''
298 298 # Notes:
299 299 # 1) Most callers want an absolute path, but _createstandin() needs
300 300 # it repo-relative so lfadd() can pass it to repoadd(). So leave
301 301 # it up to the caller to use repo.wjoin() to get an absolute path.
302 302 # 2) Join with '/' because that's what dirstate always uses, even on
303 303 # Windows. Change existing separator to '/' first in case we are
304 304 # passed filenames from an external source (like the command line).
305 305 return shortname + '/' + util.pconvert(filename)
306 306
307 307 def isstandin(filename):
308 308 '''Return true if filename is a big file standin. filename must be
309 309 in Mercurial's internal form (slash-separated).'''
310 310 return filename.startswith(shortname + '/')
311 311
312 312 def splitstandin(filename):
313 313 # Split on / because that's what dirstate always uses, even on Windows.
314 314 # Change local separator to / first just in case we are passed filenames
315 315 # from an external source (like the command line).
316 316 bits = util.pconvert(filename).split('/', 1)
317 317 if len(bits) == 2 and bits[0] == shortname:
318 318 return bits[1]
319 319 else:
320 320 return None
321 321
322 322 def updatestandin(repo, standin):
323 323 file = repo.wjoin(splitstandin(standin))
324 324 if os.path.exists(file):
325 325 hash = hashfile(file)
326 326 executable = getexecutable(file)
327 327 writestandin(repo, standin, hash, executable)
328 328
329 329 def readstandin(repo, filename, node=None):
330 330 '''read hex hash from standin for filename at given node, or working
331 331 directory if no node is given'''
332 332 return repo[node][standin(filename)].data().strip()
333 333
334 334 def writestandin(repo, standin, hash, executable):
335 335 '''write hash to <repo.root>/<standin>'''
336 336 writehash(hash, repo.wjoin(standin), executable)
337 337
338 338 def copyandhash(instream, outfile):
339 339 '''Read bytes from instream (iterable) and write them to outfile,
340 340 computing the SHA-1 hash of the data along the way. Close outfile
341 341 when done and return the binary hash.'''
342 342 hasher = util.sha1('')
343 343 for data in instream:
344 344 hasher.update(data)
345 345 outfile.write(data)
346 346
347 347 # Blecch: closing a file that somebody else opened is rude and
348 348 # wrong. But it's so darn convenient and practical! After all,
349 349 # outfile was opened just to copy and hash.
350 350 outfile.close()
351 351
352 352 return hasher.digest()
353 353
354 354 def hashrepofile(repo, file):
355 355 return hashfile(repo.wjoin(file))
356 356
357 357 def hashfile(file):
358 358 if not os.path.exists(file):
359 359 return ''
360 360 hasher = util.sha1('')
361 361 fd = open(file, 'rb')
362 362 for data in blockstream(fd):
363 363 hasher.update(data)
364 364 fd.close()
365 365 return hasher.hexdigest()
366 366
367 367 class limitreader(object):
368 368 def __init__(self, f, limit):
369 369 self.f = f
370 370 self.limit = limit
371 371
372 372 def read(self, length):
373 373 if self.limit == 0:
374 374 return ''
375 375 length = length > self.limit and self.limit or length
376 376 self.limit -= length
377 377 return self.f.read(length)
378 378
379 379 def close(self):
380 380 pass
381 381
382 382 def blockstream(infile, blocksize=128 * 1024):
383 383 """Generator that yields blocks of data from infile and closes infile."""
384 384 while True:
385 385 data = infile.read(blocksize)
386 386 if not data:
387 387 break
388 388 yield data
389 389 # same blecch as copyandhash() above
390 390 infile.close()
391 391
392 392 def writehash(hash, filename, executable):
393 393 util.makedirs(os.path.dirname(filename))
394 394 util.writefile(filename, hash + '\n')
395 395 os.chmod(filename, getmode(executable))
396 396
397 397 def getexecutable(filename):
398 398 mode = os.stat(filename).st_mode
399 399 return ((mode & stat.S_IXUSR) and
400 400 (mode & stat.S_IXGRP) and
401 401 (mode & stat.S_IXOTH))
402 402
403 403 def getmode(executable):
404 404 if executable:
405 405 return 0755
406 406 else:
407 407 return 0644
408 408
409 409 def urljoin(first, second, *arg):
410 410 def join(left, right):
411 411 if not left.endswith('/'):
412 412 left += '/'
413 413 if right.startswith('/'):
414 414 right = right[1:]
415 415 return left + right
416 416
417 417 url = join(first, second)
418 418 for a in arg:
419 419 url = join(url, a)
420 420 return url
421 421
422 422 def hexsha1(data):
423 423 """hexsha1 returns the hex-encoded sha1 sum of the data in the file-like
424 424 object data"""
425 425 h = util.sha1()
426 426 for chunk in util.filechunkiter(data):
427 427 h.update(chunk)
428 428 return h.hexdigest()
429 429
430 430 def httpsendfile(ui, filename):
431 431 return httpconnection.httpsendfile(ui, filename, 'rb')
432 432
433 433 def unixpath(path):
434 434 '''Return a version of path normalized for use with the lfdirstate.'''
435 435 return util.pconvert(os.path.normpath(path))
436 436
437 437 def islfilesrepo(repo):
438 return ('largefiles' in repo.requirements and
439 util.any(shortname + '/' in f[0] for f in repo.store.datafiles()))
438 if ('largefiles' in repo.requirements and
439 util.any(shortname + '/' in f[0] for f in repo.store.datafiles())):
440 return True
441
442 return util.any(openlfdirstate(repo.ui, repo, False))
440 443
441 444 class storeprotonotcapable(Exception):
442 445 def __init__(self, storetypes):
443 446 self.storetypes = storetypes
444 447
445 448 def getcurrentheads(repo):
446 449 branches = repo.branchmap()
447 450 heads = []
448 451 for branch in branches:
449 452 newheads = repo.branchheads(branch)
450 453 heads = heads + newheads
451 454 return heads
452 455
453 456 def getstandinsstate(repo):
454 457 standins = []
455 458 matcher = getstandinmatcher(repo)
456 459 for standin in dirstatewalk(repo.dirstate, matcher):
457 460 lfile = splitstandin(standin)
458 461 standins.append((lfile, readstandin(repo, lfile)))
459 462 return standins
460 463
461 464 def getlfilestoupdate(oldstandins, newstandins):
462 465 changedstandins = set(oldstandins).symmetric_difference(set(newstandins))
463 466 filelist = []
464 467 for f in changedstandins:
465 468 if f[0] not in filelist:
466 469 filelist.append(f[0])
467 470 return filelist
@@ -1,1585 +1,1622 b''
1 1 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
2 2 $ mkdir "${USERCACHE}"
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > largefiles=
6 6 > purge=
7 7 > rebase=
8 8 > transplant=
9 9 > [phases]
10 10 > publish=False
11 11 > [largefiles]
12 12 > minsize=2
13 13 > patterns=glob:**.dat
14 14 > usercache=${USERCACHE}
15 15 > [hooks]
16 16 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
17 17 > EOF
18 18
19 19 Create the repo with a couple of revisions of both large and normal
20 20 files, testing that status correctly shows largefiles and that summary output
21 21 is correct.
22 22
23 23 $ hg init a
24 24 $ cd a
25 25 $ mkdir sub
26 26 $ echo normal1 > normal1
27 27 $ echo normal2 > sub/normal2
28 28 $ echo large1 > large1
29 29 $ echo large2 > sub/large2
30 30 $ hg add normal1 sub/normal2
31 31 $ hg add --large large1 sub/large2
32 32 $ hg commit -m "add files"
33 33 Invoking status precommit hook
34 34 A large1
35 35 A normal1
36 36 A sub/large2
37 37 A sub/normal2
38 38 $ echo normal11 > normal1
39 39 $ echo normal22 > sub/normal2
40 40 $ echo large11 > large1
41 41 $ echo large22 > sub/large2
42 42 $ hg commit -m "edit files"
43 43 Invoking status precommit hook
44 44 M large1
45 45 M normal1
46 46 M sub/large2
47 47 M sub/normal2
48 48 $ hg sum --large
49 49 parent: 1:ce8896473775 tip
50 50 edit files
51 51 branch: default
52 52 commit: (clean)
53 53 update: (current)
54 54 largefiles: No remote repo
55 55
56 56 Commit preserved largefile contents.
57 57
58 58 $ cat normal1
59 59 normal11
60 60 $ cat large1
61 61 large11
62 62 $ cat sub/normal2
63 63 normal22
64 64 $ cat sub/large2
65 65 large22
66 66
67 67 Test status, subdir and unknown files
68 68
69 69 $ echo unknown > sub/unknown
70 70 $ hg st --all
71 71 ? sub/unknown
72 72 C large1
73 73 C normal1
74 74 C sub/large2
75 75 C sub/normal2
76 76 $ hg st --all sub
77 77 ? sub/unknown
78 78 C sub/large2
79 79 C sub/normal2
80 80 $ rm sub/unknown
81 81
82 82 Test exit codes for remove warning cases (modified and still exiting)
83 83
84 84 $ hg remove -A large1
85 85 not removing large1: file still exists (use forget to undo)
86 86 [1]
87 87 $ echo 'modified' > large1
88 88 $ hg remove large1
89 89 not removing large1: file is modified (use forget to undo)
90 90 [1]
91 91 $ hg up -Cq
92 92
93 93 Remove both largefiles and normal files.
94 94
95 95 $ hg remove normal1 large1
96 96 $ hg status large1
97 97 R large1
98 98 $ hg commit -m "remove files"
99 99 Invoking status precommit hook
100 100 R large1
101 101 R normal1
102 102 $ ls
103 103 sub
104 104 $ echo "testlargefile" > large1-test
105 105 $ hg add --large large1-test
106 106 $ hg st
107 107 A large1-test
108 108 $ hg rm large1-test
109 109 not removing large1-test: file has been marked for add (use forget to undo)
110 110 [1]
111 111 $ hg st
112 112 A large1-test
113 113 $ hg forget large1-test
114 114 $ hg st
115 115 ? large1-test
116 116 $ hg remove large1-test
117 117 not removing large1-test: file is untracked
118 118 [1]
119 119 $ hg forget large1-test
120 120 not removing large1-test: file is already untracked
121 121 [1]
122 122 $ rm large1-test
123 123
124 124 Copy both largefiles and normal files (testing that status output is correct).
125 125
126 126 $ hg cp sub/normal2 normal1
127 127 $ hg cp sub/large2 large1
128 128 $ hg commit -m "copy files"
129 129 Invoking status precommit hook
130 130 A large1
131 131 A normal1
132 132 $ cat normal1
133 133 normal22
134 134 $ cat large1
135 135 large22
136 136
137 137 Test moving largefiles and verify that normal files are also unaffected.
138 138
139 139 $ hg mv normal1 normal3
140 140 $ hg mv large1 large3
141 141 $ hg mv sub/normal2 sub/normal4
142 142 $ hg mv sub/large2 sub/large4
143 143 $ hg commit -m "move files"
144 144 Invoking status precommit hook
145 145 A large3
146 146 A normal3
147 147 A sub/large4
148 148 A sub/normal4
149 149 R large1
150 150 R normal1
151 151 R sub/large2
152 152 R sub/normal2
153 153 $ cat normal3
154 154 normal22
155 155 $ cat large3
156 156 large22
157 157 $ cat sub/normal4
158 158 normal22
159 159 $ cat sub/large4
160 160 large22
161 161
162 162 Test copies and moves from a directory other than root (issue3516)
163 163
164 164 $ cd ..
165 165 $ hg init lf_cpmv
166 166 $ cd lf_cpmv
167 167 $ mkdir dira
168 168 $ mkdir dira/dirb
169 169 $ touch dira/dirb/largefile
170 170 $ hg add --large dira/dirb/largefile
171 171 $ hg commit -m "added"
172 172 Invoking status precommit hook
173 173 A dira/dirb/largefile
174 174 $ cd dira
175 175 $ hg cp dirb/largefile foo/largefile
176 176 $ hg ci -m "deep copy"
177 177 Invoking status precommit hook
178 178 A dira/foo/largefile
179 179 $ find . | sort
180 180 .
181 181 ./dirb
182 182 ./dirb/largefile
183 183 ./foo
184 184 ./foo/largefile
185 185 $ hg mv foo/largefile baz/largefile
186 186 $ hg ci -m "moved"
187 187 Invoking status precommit hook
188 188 A dira/baz/largefile
189 189 R dira/foo/largefile
190 190 $ find . | sort
191 191 .
192 192 ./baz
193 193 ./baz/largefile
194 194 ./dirb
195 195 ./dirb/largefile
196 196 ./foo
197 197 $ cd ../../a
198 198
199 199 #if hgweb
200 200 Test display of largefiles in hgweb
201 201
202 202 $ hg serve -d -p $HGPORT --pid-file ../hg.pid
203 203 $ cat ../hg.pid >> $DAEMON_PIDS
204 204 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/?style=raw'
205 205 200 Script output follows
206 206
207 207
208 208 drwxr-xr-x sub
209 209 -rw-r--r-- 41 large3
210 210 -rw-r--r-- 9 normal3
211 211
212 212
213 213 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT 'file/tip/sub/?style=raw'
214 214 200 Script output follows
215 215
216 216
217 217 -rw-r--r-- 41 large4
218 218 -rw-r--r-- 9 normal4
219 219
220 220
221 221 $ "$TESTDIR/killdaemons.py"
222 222 #endif
223 223
224 224 Test archiving the various revisions. These hit corner cases known with
225 225 archiving.
226 226
227 227 $ hg archive -r 0 ../archive0
228 228 $ hg archive -r 1 ../archive1
229 229 $ hg archive -r 2 ../archive2
230 230 $ hg archive -r 3 ../archive3
231 231 $ hg archive -r 4 ../archive4
232 232 $ cd ../archive0
233 233 $ cat normal1
234 234 normal1
235 235 $ cat large1
236 236 large1
237 237 $ cat sub/normal2
238 238 normal2
239 239 $ cat sub/large2
240 240 large2
241 241 $ cd ../archive1
242 242 $ cat normal1
243 243 normal11
244 244 $ cat large1
245 245 large11
246 246 $ cat sub/normal2
247 247 normal22
248 248 $ cat sub/large2
249 249 large22
250 250 $ cd ../archive2
251 251 $ ls
252 252 sub
253 253 $ cat sub/normal2
254 254 normal22
255 255 $ cat sub/large2
256 256 large22
257 257 $ cd ../archive3
258 258 $ cat normal1
259 259 normal22
260 260 $ cat large1
261 261 large22
262 262 $ cat sub/normal2
263 263 normal22
264 264 $ cat sub/large2
265 265 large22
266 266 $ cd ../archive4
267 267 $ cat normal3
268 268 normal22
269 269 $ cat large3
270 270 large22
271 271 $ cat sub/normal4
272 272 normal22
273 273 $ cat sub/large4
274 274 large22
275 275
276 276 Commit corner case: specify files to commit.
277 277
278 278 $ cd ../a
279 279 $ echo normal3 > normal3
280 280 $ echo large3 > large3
281 281 $ echo normal4 > sub/normal4
282 282 $ echo large4 > sub/large4
283 283 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
284 284 Invoking status precommit hook
285 285 M large3
286 286 M normal3
287 287 M sub/large4
288 288 M sub/normal4
289 289 $ cat normal3
290 290 normal3
291 291 $ cat large3
292 292 large3
293 293 $ cat sub/normal4
294 294 normal4
295 295 $ cat sub/large4
296 296 large4
297 297
298 298 One more commit corner case: commit from a subdirectory.
299 299
300 300 $ cd ../a
301 301 $ echo normal33 > normal3
302 302 $ echo large33 > large3
303 303 $ echo normal44 > sub/normal4
304 304 $ echo large44 > sub/large4
305 305 $ cd sub
306 306 $ hg commit -m "edit files yet again"
307 307 Invoking status precommit hook
308 308 M large3
309 309 M normal3
310 310 M sub/large4
311 311 M sub/normal4
312 312 $ cat ../normal3
313 313 normal33
314 314 $ cat ../large3
315 315 large33
316 316 $ cat normal4
317 317 normal44
318 318 $ cat large4
319 319 large44
320 320
321 321 Committing standins is not allowed.
322 322
323 323 $ cd ..
324 324 $ echo large3 > large3
325 325 $ hg commit .hglf/large3 -m "try to commit standin"
326 326 abort: file ".hglf/large3" is a largefile standin
327 327 (commit the largefile itself instead)
328 328 [255]
329 329
330 330 Corner cases for adding largefiles.
331 331
332 332 $ echo large5 > large5
333 333 $ hg add --large large5
334 334 $ hg add --large large5
335 335 large5 already a largefile
336 336 $ mkdir sub2
337 337 $ echo large6 > sub2/large6
338 338 $ echo large7 > sub2/large7
339 339 $ hg add --large sub2
340 340 adding sub2/large6 as a largefile (glob)
341 341 adding sub2/large7 as a largefile (glob)
342 342 $ hg st
343 343 M large3
344 344 A large5
345 345 A sub2/large6
346 346 A sub2/large7
347 347
348 348 Test "hg status" with combination of 'file pattern' and 'directory
349 349 pattern' for largefiles:
350 350
351 351 $ hg status sub2/large6 sub2
352 352 A sub2/large6
353 353 A sub2/large7
354 354
355 355 Config settings (pattern **.dat, minsize 2 MB) are respected.
356 356
357 357 $ echo testdata > test.dat
358 358 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
359 359 $ hg add
360 360 adding reallylarge as a largefile
361 361 adding test.dat as a largefile
362 362
363 363 Test that minsize and --lfsize handle float values;
364 364 also tests that --lfsize overrides largefiles.minsize.
365 365 (0.250 MB = 256 kB = 262144 B)
366 366
367 367 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
368 368 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
369 369 $ hg --config largefiles.minsize=.25 add
370 370 adding ratherlarge as a largefile
371 371 adding medium
372 372 $ hg forget medium
373 373 $ hg --config largefiles.minsize=.25 add --lfsize=.125
374 374 adding medium as a largefile
375 375 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
376 376 $ hg --config largefiles.minsize=.25 add --lfsize=.125
377 377 adding notlarge
378 378 $ hg forget notlarge
379 379
380 380 Test forget on largefiles.
381 381
382 382 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
383 383 $ hg commit -m "add/edit more largefiles"
384 384 Invoking status precommit hook
385 385 A sub2/large6
386 386 A sub2/large7
387 387 R large3
388 388 ? large5
389 389 ? medium
390 390 ? notlarge
391 391 ? ratherlarge
392 392 ? reallylarge
393 393 ? test.dat
394 394 $ hg st
395 395 ? large3
396 396 ? large5
397 397 ? medium
398 398 ? notlarge
399 399 ? ratherlarge
400 400 ? reallylarge
401 401 ? test.dat
402 402
403 403 Purge with largefiles: verify that largefiles are still in the working
404 404 dir after a purge.
405 405
406 406 $ hg purge --all
407 407 $ cat sub/large4
408 408 large44
409 409 $ cat sub2/large6
410 410 large6
411 411 $ cat sub2/large7
412 412 large7
413 413
414 414 Test addremove: verify that files that should be added as largfiles are added as
415 415 such and that already-existing largfiles are not added as normal files by
416 416 accident.
417 417
418 418 $ rm normal3
419 419 $ rm sub/large4
420 420 $ echo "testing addremove with patterns" > testaddremove.dat
421 421 $ echo "normaladdremove" > normaladdremove
422 422 $ hg addremove
423 423 removing sub/large4
424 424 adding testaddremove.dat as a largefile
425 425 removing normal3
426 426 adding normaladdremove
427 427
428 428 Test addremove with -R
429 429
430 430 $ hg up -C
431 431 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 432 getting changed largefiles
433 433 1 largefiles updated, 0 removed
434 434 $ rm normal3
435 435 $ rm sub/large4
436 436 $ echo "testing addremove with patterns" > testaddremove.dat
437 437 $ echo "normaladdremove" > normaladdremove
438 438 $ cd ..
439 439 $ hg -R a addremove
440 440 removing sub/large4
441 441 adding a/testaddremove.dat as a largefile (glob)
442 442 removing normal3
443 443 adding normaladdremove
444 444 $ cd a
445 445
446 446 Test 3364
447 447 $ hg clone . ../addrm
448 448 updating to branch default
449 449 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 450 getting changed largefiles
451 451 3 largefiles updated, 0 removed
452 452 $ cd ../addrm
453 453 $ cat >> .hg/hgrc <<EOF
454 454 > [hooks]
455 455 > post-commit.stat=sh -c "echo \\"Invoking status postcommit hook\\"; hg status -A"
456 456 > EOF
457 457 $ touch foo
458 458 $ hg add --large foo
459 459 $ hg ci -m "add foo"
460 460 Invoking status precommit hook
461 461 A foo
462 462 Invoking status postcommit hook
463 463 C foo
464 464 C normal3
465 465 C sub/large4
466 466 C sub/normal4
467 467 C sub2/large6
468 468 C sub2/large7
469 469 $ rm foo
470 470 $ hg st
471 471 ! foo
472 472 hmm.. no precommit invoked, but there is a postcommit??
473 473 $ hg ci -m "will not checkin"
474 474 nothing changed
475 475 Invoking status postcommit hook
476 476 ! foo
477 477 C normal3
478 478 C sub/large4
479 479 C sub/normal4
480 480 C sub2/large6
481 481 C sub2/large7
482 482 [1]
483 483 $ hg addremove
484 484 removing foo
485 485 $ hg st
486 486 R foo
487 487 $ hg ci -m "used to say nothing changed"
488 488 Invoking status precommit hook
489 489 R foo
490 490 Invoking status postcommit hook
491 491 C normal3
492 492 C sub/large4
493 493 C sub/normal4
494 494 C sub2/large6
495 495 C sub2/large7
496 496 $ hg st
497 497
498 498 Test 3507 (both normal files and largefiles were a problem)
499 499
500 500 $ touch normal
501 501 $ touch large
502 502 $ hg add normal
503 503 $ hg add --large large
504 504 $ hg ci -m "added"
505 505 Invoking status precommit hook
506 506 A large
507 507 A normal
508 508 Invoking status postcommit hook
509 509 C large
510 510 C normal
511 511 C normal3
512 512 C sub/large4
513 513 C sub/normal4
514 514 C sub2/large6
515 515 C sub2/large7
516 516 $ hg remove normal
517 517 $ hg addremove --traceback
518 518 $ hg ci -m "addremoved normal"
519 519 Invoking status precommit hook
520 520 R normal
521 521 Invoking status postcommit hook
522 522 C large
523 523 C normal3
524 524 C sub/large4
525 525 C sub/normal4
526 526 C sub2/large6
527 527 C sub2/large7
528 528 $ hg up -C '.^'
529 529 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
530 530 getting changed largefiles
531 531 0 largefiles updated, 0 removed
532 532 $ hg remove large
533 533 $ hg addremove --traceback
534 534 $ hg ci -m "removed large"
535 535 Invoking status precommit hook
536 536 R large
537 537 created new head
538 538 Invoking status postcommit hook
539 539 C normal
540 540 C normal3
541 541 C sub/large4
542 542 C sub/normal4
543 543 C sub2/large6
544 544 C sub2/large7
545 545
546 546 Test commit -A (issue 3542)
547 547 $ echo large8 > large8
548 548 $ hg add --large large8
549 549 $ hg ci -Am 'this used to add large8 as normal and commit both'
550 550 Invoking status precommit hook
551 551 A large8
552 552 Invoking status postcommit hook
553 553 C large8
554 554 C normal
555 555 C normal3
556 556 C sub/large4
557 557 C sub/normal4
558 558 C sub2/large6
559 559 C sub2/large7
560 560 $ rm large8
561 561 $ hg ci -Am 'this used to not notice the rm'
562 562 removing large8
563 563 Invoking status precommit hook
564 564 R large8
565 565 Invoking status postcommit hook
566 566 C normal
567 567 C normal3
568 568 C sub/large4
569 569 C sub/normal4
570 570 C sub2/large6
571 571 C sub2/large7
572 572
573 573 Test that a standin can't be added as a large file
574 574
575 575 $ touch large
576 576 $ hg add --large large
577 577 $ hg ci -m "add"
578 578 Invoking status precommit hook
579 579 A large
580 580 Invoking status postcommit hook
581 581 C large
582 582 C normal
583 583 C normal3
584 584 C sub/large4
585 585 C sub/normal4
586 586 C sub2/large6
587 587 C sub2/large7
588 588 $ hg remove large
589 589 $ touch large
590 590 $ hg addremove --config largefiles.patterns=**large --traceback
591 591 adding large as a largefile
592 592
593 593 Test that outgoing --large works (with revsets too)
594 594 $ hg outgoing --rev '.^' --large
595 595 comparing with $TESTTMP/a (glob)
596 596 searching for changes
597 597 changeset: 8:c02fd3b77ec4
598 598 user: test
599 599 date: Thu Jan 01 00:00:00 1970 +0000
600 600 summary: add foo
601 601
602 602 changeset: 9:289dd08c9bbb
603 603 user: test
604 604 date: Thu Jan 01 00:00:00 1970 +0000
605 605 summary: used to say nothing changed
606 606
607 607 changeset: 10:34f23ac6ac12
608 608 user: test
609 609 date: Thu Jan 01 00:00:00 1970 +0000
610 610 summary: added
611 611
612 612 changeset: 12:710c1b2f523c
613 613 parent: 10:34f23ac6ac12
614 614 user: test
615 615 date: Thu Jan 01 00:00:00 1970 +0000
616 616 summary: removed large
617 617
618 618 changeset: 13:0a3e75774479
619 619 user: test
620 620 date: Thu Jan 01 00:00:00 1970 +0000
621 621 summary: this used to add large8 as normal and commit both
622 622
623 623 changeset: 14:84f3d378175c
624 624 user: test
625 625 date: Thu Jan 01 00:00:00 1970 +0000
626 626 summary: this used to not notice the rm
627 627
628 628 searching for changes
629 629 largefiles to upload:
630 630 large8
631 631 large
632 632 foo
633 633
634 634 $ cd ../a
635 635
636 636 Clone a largefiles repo.
637 637
638 638 $ hg clone . ../b
639 639 updating to branch default
640 640 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
641 641 getting changed largefiles
642 642 3 largefiles updated, 0 removed
643 643 $ cd ../b
644 644 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
645 645 7:daea875e9014 add/edit more largefiles
646 646 6:4355d653f84f edit files yet again
647 647 5:9d5af5072dbd edit files again
648 648 4:74c02385b94c move files
649 649 3:9e8fbc4bce62 copy files
650 650 2:51a0ae4d5864 remove files
651 651 1:ce8896473775 edit files
652 652 0:30d30fe6a5be add files
653 653 $ cat normal3
654 654 normal33
655 655 $ cat sub/normal4
656 656 normal44
657 657 $ cat sub/large4
658 658 large44
659 659 $ cat sub2/large6
660 660 large6
661 661 $ cat sub2/large7
662 662 large7
663 663 $ cd ..
664 664 $ hg clone a -r 3 c
665 665 adding changesets
666 666 adding manifests
667 667 adding file changes
668 668 added 4 changesets with 10 changes to 4 files
669 669 updating to branch default
670 670 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
671 671 getting changed largefiles
672 672 2 largefiles updated, 0 removed
673 673 $ cd c
674 674 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
675 675 3:9e8fbc4bce62 copy files
676 676 2:51a0ae4d5864 remove files
677 677 1:ce8896473775 edit files
678 678 0:30d30fe6a5be add files
679 679 $ cat normal1
680 680 normal22
681 681 $ cat large1
682 682 large22
683 683 $ cat sub/normal2
684 684 normal22
685 685 $ cat sub/large2
686 686 large22
687 687
688 688 Old revisions of a clone have correct largefiles content (this also
689 689 tests update).
690 690
691 691 $ hg update -r 1
692 692 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
693 693 getting changed largefiles
694 694 1 largefiles updated, 0 removed
695 695 $ cat large1
696 696 large11
697 697 $ cat sub/large2
698 698 large22
699 699 $ cd ..
700 700
701 701 Test cloning with --all-largefiles flag
702 702
703 703 $ rm "${USERCACHE}"/*
704 704 $ hg clone --all-largefiles a a-backup
705 705 updating to branch default
706 706 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
707 707 getting changed largefiles
708 708 3 largefiles updated, 0 removed
709 709 8 additional largefiles cached
710 710
711 711 $ rm "${USERCACHE}"/*
712 712 $ hg clone --all-largefiles -u 0 a a-clone0
713 713 updating to branch default
714 714 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
715 715 getting changed largefiles
716 716 2 largefiles updated, 0 removed
717 717 9 additional largefiles cached
718 718 $ hg -R a-clone0 sum
719 719 parent: 0:30d30fe6a5be
720 720 add files
721 721 branch: default
722 722 commit: (clean)
723 723 update: 7 new changesets (update)
724 724
725 725 $ rm "${USERCACHE}"/*
726 726 $ hg clone --all-largefiles -u 1 a a-clone1
727 727 updating to branch default
728 728 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
729 729 getting changed largefiles
730 730 2 largefiles updated, 0 removed
731 731 8 additional largefiles cached
732 732 $ hg -R a-clone1 sum
733 733 parent: 1:ce8896473775
734 734 edit files
735 735 branch: default
736 736 commit: (clean)
737 737 update: 6 new changesets (update)
738 738
739 739 $ rm "${USERCACHE}"/*
740 740 $ hg clone --all-largefiles -U a a-clone-u
741 741 11 additional largefiles cached
742 742 $ hg -R a-clone-u sum
743 743 parent: -1:000000000000 (no revision checked out)
744 744 branch: default
745 745 commit: (clean)
746 746 update: 8 new changesets (update)
747 747
748 748 $ mkdir xyz
749 749 $ cd xyz
750 750 $ hg clone ../a
751 751 destination directory: a
752 752 updating to branch default
753 753 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
754 754 getting changed largefiles
755 755 3 largefiles updated, 0 removed
756 756 $ cd ..
757 757
758 758 Ensure base clone command argument validation
759 759
760 760 $ hg clone -U -u 0 a a-clone-failure
761 761 abort: cannot specify both --noupdate and --updaterev
762 762 [255]
763 763
764 764 $ hg clone --all-largefiles a ssh://localhost/a
765 765 abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
766 766 [255]
767 767
768 768 Test pulling with --all-largefiles flag
769 769
770 770 $ rm -Rf a-backup
771 771 $ hg clone -r 1 a a-backup
772 772 adding changesets
773 773 adding manifests
774 774 adding file changes
775 775 added 2 changesets with 8 changes to 4 files
776 776 updating to branch default
777 777 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
778 778 getting changed largefiles
779 779 2 largefiles updated, 0 removed
780 780 $ rm "${USERCACHE}"/*
781 781 $ cd a-backup
782 782 $ hg pull --all-largefiles
783 783 pulling from $TESTTMP/a (glob)
784 784 searching for changes
785 785 adding changesets
786 786 adding manifests
787 787 adding file changes
788 788 added 6 changesets with 16 changes to 8 files
789 789 (run 'hg update' to get a working copy)
790 790 caching new largefiles
791 791 3 largefiles cached
792 792 3 additional largefiles cached
793 793 $ cd ..
794 794
795 795 Rebasing between two repositories does not revert largefiles to old
796 796 revisions (this was a very bad bug that took a lot of work to fix).
797 797
798 798 $ hg clone a d
799 799 updating to branch default
800 800 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
801 801 getting changed largefiles
802 802 3 largefiles updated, 0 removed
803 803 $ cd b
804 804 $ echo large4-modified > sub/large4
805 805 $ echo normal3-modified > normal3
806 806 $ hg commit -m "modify normal file and largefile in repo b"
807 807 Invoking status precommit hook
808 808 M normal3
809 809 M sub/large4
810 810 $ cd ../d
811 811 $ echo large6-modified > sub2/large6
812 812 $ echo normal4-modified > sub/normal4
813 813 $ hg commit -m "modify normal file largefile in repo d"
814 814 Invoking status precommit hook
815 815 M sub/normal4
816 816 M sub2/large6
817 817 $ cd ..
818 818 $ hg clone d e
819 819 updating to branch default
820 820 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
821 821 getting changed largefiles
822 822 3 largefiles updated, 0 removed
823 823 $ cd d
824 824 $ hg pull --rebase ../b
825 825 pulling from ../b
826 826 searching for changes
827 827 adding changesets
828 828 adding manifests
829 829 adding file changes
830 830 added 1 changesets with 2 changes to 2 files (+1 heads)
831 831 Invoking status precommit hook
832 832 M sub/normal4
833 833 M sub2/large6
834 834 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
835 835 nothing to rebase
836 836 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
837 837 9:598410d3eb9a modify normal file largefile in repo d
838 838 8:a381d2c8c80e modify normal file and largefile in repo b
839 839 7:daea875e9014 add/edit more largefiles
840 840 6:4355d653f84f edit files yet again
841 841 5:9d5af5072dbd edit files again
842 842 4:74c02385b94c move files
843 843 3:9e8fbc4bce62 copy files
844 844 2:51a0ae4d5864 remove files
845 845 1:ce8896473775 edit files
846 846 0:30d30fe6a5be add files
847 847 $ cat normal3
848 848 normal3-modified
849 849 $ cat sub/normal4
850 850 normal4-modified
851 851 $ cat sub/large4
852 852 large4-modified
853 853 $ cat sub2/large6
854 854 large6-modified
855 855 $ cat sub2/large7
856 856 large7
857 857 $ cd ../e
858 858 $ hg pull ../b
859 859 pulling from ../b
860 860 searching for changes
861 861 adding changesets
862 862 adding manifests
863 863 adding file changes
864 864 added 1 changesets with 2 changes to 2 files (+1 heads)
865 865 (run 'hg heads' to see heads, 'hg merge' to merge)
866 866 caching new largefiles
867 867 0 largefiles cached
868 868 $ hg rebase
869 869 Invoking status precommit hook
870 870 M sub/normal4
871 871 M sub2/large6
872 872 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg (glob)
873 873 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
874 874 9:598410d3eb9a modify normal file largefile in repo d
875 875 8:a381d2c8c80e modify normal file and largefile in repo b
876 876 7:daea875e9014 add/edit more largefiles
877 877 6:4355d653f84f edit files yet again
878 878 5:9d5af5072dbd edit files again
879 879 4:74c02385b94c move files
880 880 3:9e8fbc4bce62 copy files
881 881 2:51a0ae4d5864 remove files
882 882 1:ce8896473775 edit files
883 883 0:30d30fe6a5be add files
884 884 $ cat normal3
885 885 normal3-modified
886 886 $ cat sub/normal4
887 887 normal4-modified
888 888 $ cat sub/large4
889 889 large4-modified
890 890 $ cat sub2/large6
891 891 large6-modified
892 892 $ cat sub2/large7
893 893 large7
894 894
895 895 Rollback on largefiles.
896 896
897 897 $ echo large4-modified-again > sub/large4
898 898 $ hg commit -m "Modify large4 again"
899 899 Invoking status precommit hook
900 900 M sub/large4
901 901 $ hg rollback
902 902 repository tip rolled back to revision 9 (undo commit)
903 903 working directory now based on revision 9
904 904 $ hg st
905 905 M sub/large4
906 906 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
907 907 9:598410d3eb9a modify normal file largefile in repo d
908 908 8:a381d2c8c80e modify normal file and largefile in repo b
909 909 7:daea875e9014 add/edit more largefiles
910 910 6:4355d653f84f edit files yet again
911 911 5:9d5af5072dbd edit files again
912 912 4:74c02385b94c move files
913 913 3:9e8fbc4bce62 copy files
914 914 2:51a0ae4d5864 remove files
915 915 1:ce8896473775 edit files
916 916 0:30d30fe6a5be add files
917 917 $ cat sub/large4
918 918 large4-modified-again
919 919
920 920 "update --check" refuses to update with uncommitted changes.
921 921 $ hg update --check 8
922 922 abort: uncommitted local changes
923 923 [255]
924 924
925 925 "update --clean" leaves correct largefiles in working copy.
926 926
927 927 $ hg update --clean
928 928 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
929 929 getting changed largefiles
930 930 1 largefiles updated, 0 removed
931 931 $ cat normal3
932 932 normal3-modified
933 933 $ cat sub/normal4
934 934 normal4-modified
935 935 $ cat sub/large4
936 936 large4-modified
937 937 $ cat sub2/large6
938 938 large6-modified
939 939 $ cat sub2/large7
940 940 large7
941 941
942 942 Now "update check" is happy.
943 943 $ hg update --check 8
944 944 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
945 945 getting changed largefiles
946 946 1 largefiles updated, 0 removed
947 947 $ hg update --check
948 948 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
949 949 getting changed largefiles
950 950 1 largefiles updated, 0 removed
951 951
952 952 Test removing empty largefiles directories on update
953 953 $ test -d sub2 && echo "sub2 exists"
954 954 sub2 exists
955 955 $ hg update -q null
956 956 $ test -d sub2 && echo "error: sub2 should not exist anymore"
957 957 [1]
958 958 $ hg update -q
959 959
960 960 Test hg remove removes empty largefiles directories
961 961 $ test -d sub2 && echo "sub2 exists"
962 962 sub2 exists
963 963 $ hg remove sub2/*
964 964 $ test -d sub2 && echo "error: sub2 should not exist anymore"
965 965 [1]
966 966 $ hg revert sub2/large6 sub2/large7
967 967
968 968 "revert" works on largefiles (and normal files too).
969 969 $ echo hack3 >> normal3
970 970 $ echo hack4 >> sub/normal4
971 971 $ echo hack4 >> sub/large4
972 972 $ rm sub2/large6
973 973 $ hg revert sub2/large6
974 974 $ hg rm sub2/large6
975 975 $ echo new >> sub2/large8
976 976 $ hg add --large sub2/large8
977 977 # XXX we don't really want to report that we're reverting the standin;
978 978 # that's just an implementation detail. But I don't see an obvious fix. ;-(
979 979 $ hg revert sub
980 980 reverting .hglf/sub/large4 (glob)
981 981 reverting sub/normal4 (glob)
982 982 $ hg status
983 983 M normal3
984 984 A sub2/large8
985 985 R sub2/large6
986 986 ? sub/large4.orig
987 987 ? sub/normal4.orig
988 988 $ cat sub/normal4
989 989 normal4-modified
990 990 $ cat sub/large4
991 991 large4-modified
992 992 $ hg revert -a --no-backup
993 993 undeleting .hglf/sub2/large6 (glob)
994 994 forgetting .hglf/sub2/large8 (glob)
995 995 reverting normal3
996 996 $ hg status
997 997 ? sub/large4.orig
998 998 ? sub/normal4.orig
999 999 ? sub2/large8
1000 1000 $ cat normal3
1001 1001 normal3-modified
1002 1002 $ cat sub2/large6
1003 1003 large6-modified
1004 1004 $ rm sub/*.orig sub2/large8
1005 1005
1006 1006 revert some files to an older revision
1007 1007 $ hg revert --no-backup -r 8 sub2
1008 1008 reverting .hglf/sub2/large6 (glob)
1009 1009 $ cat sub2/large6
1010 1010 large6
1011 1011 $ hg revert --no-backup -C -r '.^' sub2
1012 1012 reverting .hglf/sub2/large6 (glob)
1013 1013 $ hg revert --no-backup sub2
1014 1014 reverting .hglf/sub2/large6 (glob)
1015 1015 $ hg status
1016 1016
1017 1017 "verify --large" actually verifies largefiles
1018 1018
1019 1019 $ hg verify --large
1020 1020 checking changesets
1021 1021 checking manifests
1022 1022 crosschecking files in changesets and manifests
1023 1023 checking files
1024 1024 10 files, 10 changesets, 28 total revisions
1025 1025 searching 1 changesets for largefiles
1026 1026 verified existence of 3 revisions of 3 largefiles
1027 1027
1028 1028 Merging does not revert to old versions of largefiles and also check
1029 1029 that merging after having pulled from a non-default remote works
1030 1030 correctly.
1031 1031
1032 1032 $ cd ..
1033 1033 $ hg clone -r 7 e temp
1034 1034 adding changesets
1035 1035 adding manifests
1036 1036 adding file changes
1037 1037 added 8 changesets with 24 changes to 10 files
1038 1038 updating to branch default
1039 1039 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1040 1040 getting changed largefiles
1041 1041 3 largefiles updated, 0 removed
1042 1042 $ hg clone temp f
1043 1043 updating to branch default
1044 1044 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1045 1045 getting changed largefiles
1046 1046 3 largefiles updated, 0 removed
1047 1047 # Delete the largefiles in the largefiles system cache so that we have an
1048 1048 # opportunity to test that caching after a pull works.
1049 1049 $ rm "${USERCACHE}"/*
1050 1050 $ cd f
1051 1051 $ echo "large4-merge-test" > sub/large4
1052 1052 $ hg commit -m "Modify large4 to test merge"
1053 1053 Invoking status precommit hook
1054 1054 M sub/large4
1055 1055 $ hg pull ../e
1056 1056 pulling from ../e
1057 1057 searching for changes
1058 1058 adding changesets
1059 1059 adding manifests
1060 1060 adding file changes
1061 1061 added 2 changesets with 4 changes to 4 files (+1 heads)
1062 1062 (run 'hg heads' to see heads, 'hg merge' to merge)
1063 1063 caching new largefiles
1064 1064 2 largefiles cached
1065 1065 $ hg merge
1066 1066 merging sub/large4
1067 1067 largefile sub/large4 has a merge conflict
1068 1068 keep (l)ocal or take (o)ther? l
1069 1069 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
1070 1070 (branch merge, don't forget to commit)
1071 1071 getting changed largefiles
1072 1072 1 largefiles updated, 0 removed
1073 1073 $ hg commit -m "Merge repos e and f"
1074 1074 Invoking status precommit hook
1075 1075 M normal3
1076 1076 M sub/normal4
1077 1077 M sub2/large6
1078 1078 $ cat normal3
1079 1079 normal3-modified
1080 1080 $ cat sub/normal4
1081 1081 normal4-modified
1082 1082 $ cat sub/large4
1083 1083 large4-merge-test
1084 1084 $ cat sub2/large6
1085 1085 large6-modified
1086 1086 $ cat sub2/large7
1087 1087 large7
1088 1088
1089 1089 Test status after merging with a branch that introduces a new largefile:
1090 1090
1091 1091 $ echo large > large
1092 1092 $ hg add --large large
1093 1093 $ hg commit -m 'add largefile'
1094 1094 Invoking status precommit hook
1095 1095 A large
1096 1096 $ hg update -q ".^"
1097 1097 $ echo change >> normal3
1098 1098 $ hg commit -m 'some change'
1099 1099 Invoking status precommit hook
1100 1100 M normal3
1101 1101 created new head
1102 1102 $ hg merge
1103 1103 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1104 1104 (branch merge, don't forget to commit)
1105 1105 getting changed largefiles
1106 1106 1 largefiles updated, 0 removed
1107 1107 $ hg status
1108 1108 M large
1109 1109
1110 1110 Test that a normal file and a largefile with the same name and path cannot
1111 1111 coexist.
1112 1112
1113 1113 $ rm sub2/large7
1114 1114 $ echo "largeasnormal" > sub2/large7
1115 1115 $ hg add sub2/large7
1116 1116 sub2/large7 already a largefile
1117 1117
1118 1118 Test that transplanting a largefile change works correctly.
1119 1119
1120 1120 $ cd ..
1121 1121 $ hg clone -r 8 d g
1122 1122 adding changesets
1123 1123 adding manifests
1124 1124 adding file changes
1125 1125 added 9 changesets with 26 changes to 10 files
1126 1126 updating to branch default
1127 1127 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
1128 1128 getting changed largefiles
1129 1129 3 largefiles updated, 0 removed
1130 1130 $ cd g
1131 1131 $ hg transplant -s ../d 598410d3eb9a
1132 1132 searching for changes
1133 1133 searching for changes
1134 1134 adding changesets
1135 1135 adding manifests
1136 1136 adding file changes
1137 1137 added 1 changesets with 2 changes to 2 files
1138 1138 getting changed largefiles
1139 1139 1 largefiles updated, 0 removed
1140 1140 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
1141 1141 9:598410d3eb9a modify normal file largefile in repo d
1142 1142 8:a381d2c8c80e modify normal file and largefile in repo b
1143 1143 7:daea875e9014 add/edit more largefiles
1144 1144 6:4355d653f84f edit files yet again
1145 1145 5:9d5af5072dbd edit files again
1146 1146 4:74c02385b94c move files
1147 1147 3:9e8fbc4bce62 copy files
1148 1148 2:51a0ae4d5864 remove files
1149 1149 1:ce8896473775 edit files
1150 1150 0:30d30fe6a5be add files
1151 1151 $ cat normal3
1152 1152 normal3-modified
1153 1153 $ cat sub/normal4
1154 1154 normal4-modified
1155 1155 $ cat sub/large4
1156 1156 large4-modified
1157 1157 $ cat sub2/large6
1158 1158 large6-modified
1159 1159 $ cat sub2/large7
1160 1160 large7
1161 1161
1162 1162 Cat a largefile
1163 1163 $ hg cat normal3
1164 1164 normal3-modified
1165 1165 $ hg cat sub/large4
1166 1166 large4-modified
1167 1167 $ rm "${USERCACHE}"/*
1168 1168 $ hg cat -r a381d2c8c80e -o cat.out sub/large4
1169 1169 $ cat cat.out
1170 1170 large4-modified
1171 1171 $ rm cat.out
1172 1172 $ hg cat -r a381d2c8c80e normal3
1173 1173 normal3-modified
1174 1174 $ hg cat -r '.^' normal3
1175 1175 normal3-modified
1176 1176 $ hg cat -r '.^' sub/large4
1177 1177 large4-modified
1178 1178
1179 1179 Test that renaming a largefile results in correct output for status
1180 1180
1181 1181 $ hg rename sub/large4 large4-renamed
1182 1182 $ hg commit -m "test rename output"
1183 1183 Invoking status precommit hook
1184 1184 A large4-renamed
1185 1185 R sub/large4
1186 1186 $ cat large4-renamed
1187 1187 large4-modified
1188 1188 $ cd sub2
1189 1189 $ hg rename large6 large6-renamed
1190 1190 $ hg st
1191 1191 A sub2/large6-renamed
1192 1192 R sub2/large6
1193 1193 $ cd ..
1194 1194
1195 1195 Test --normal flag
1196 1196
1197 1197 $ dd if=/dev/zero bs=2k count=11k > new-largefile 2> /dev/null
1198 1198 $ hg add --normal --large new-largefile
1199 1199 abort: --normal cannot be used with --large
1200 1200 [255]
1201 1201 $ hg add --normal new-largefile
1202 1202 new-largefile: up to 69 MB of RAM may be required to manage this file
1203 1203 (use 'hg revert new-largefile' to cancel the pending addition)
1204 1204 $ cd ..
1205 1205
1206 1206 #if serve
1207 1207 vanilla clients not locked out from largefiles servers on vanilla repos
1208 1208 $ mkdir r1
1209 1209 $ cd r1
1210 1210 $ hg init
1211 1211 $ echo c1 > f1
1212 1212 $ hg add f1
1213 1213 $ hg commit -m "m1"
1214 1214 Invoking status precommit hook
1215 1215 A f1
1216 1216 $ cd ..
1217 1217 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
1218 1218 $ cat hg.pid >> $DAEMON_PIDS
1219 1219 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
1220 1220 requesting all changes
1221 1221 adding changesets
1222 1222 adding manifests
1223 1223 adding file changes
1224 1224 added 1 changesets with 1 changes to 1 files
1225 1225 updating to branch default
1226 1226 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1227 1227
1228 1228 largefiles clients still work with vanilla servers
1229 1229 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
1230 1230 $ cat hg.pid >> $DAEMON_PIDS
1231 1231 $ hg clone http://localhost:$HGPORT1 r3
1232 1232 requesting all changes
1233 1233 adding changesets
1234 1234 adding manifests
1235 1235 adding file changes
1236 1236 added 1 changesets with 1 changes to 1 files
1237 1237 updating to branch default
1238 1238 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1239 1239 #endif
1240 1240
1241 1241
1242 1242 vanilla clients locked out from largefiles http repos
1243 1243 $ mkdir r4
1244 1244 $ cd r4
1245 1245 $ hg init
1246 1246 $ echo c1 > f1
1247 1247 $ hg add --large f1
1248 1248 $ hg commit -m "m1"
1249 1249 Invoking status precommit hook
1250 1250 A f1
1251 1251 $ cd ..
1252 1252
1253 1253 largefiles can be pushed locally (issue3583)
1254 1254 $ hg init dest
1255 1255 $ cd r4
1256 1256 $ hg outgoing ../dest
1257 1257 comparing with ../dest
1258 1258 searching for changes
1259 1259 changeset: 0:639881c12b4c
1260 1260 tag: tip
1261 1261 user: test
1262 1262 date: Thu Jan 01 00:00:00 1970 +0000
1263 1263 summary: m1
1264 1264
1265 1265 $ hg push ../dest
1266 1266 pushing to ../dest
1267 1267 searching for changes
1268 1268 searching for changes
1269 1269 adding changesets
1270 1270 adding manifests
1271 1271 adding file changes
1272 1272 added 1 changesets with 1 changes to 1 files
1273 1273
1274 1274 exit code with nothing outgoing (issue3611)
1275 1275 $ hg outgoing ../dest
1276 1276 comparing with ../dest
1277 1277 searching for changes
1278 1278 no changes found
1279 1279 [1]
1280 1280 $ cd ..
1281 1281
1282 1282 #if serve
1283 1283 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
1284 1284 $ cat hg.pid >> $DAEMON_PIDS
1285 1285 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
1286 1286 abort: remote error:
1287 1287
1288 1288 This repository uses the largefiles extension.
1289 1289
1290 1290 Please enable it in your Mercurial config file.
1291 1291 [255]
1292 1292
1293 1293 used all HGPORTs, kill all daemons
1294 1294 $ "$TESTDIR/killdaemons.py"
1295 1295 #endif
1296 1296
1297 1297 vanilla clients locked out from largefiles ssh repos
1298 1298 $ hg --config extensions.largefiles=! clone -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/r4 r5
1299 1299 abort: remote error:
1300 1300
1301 1301 This repository uses the largefiles extension.
1302 1302
1303 1303 Please enable it in your Mercurial config file.
1304 1304 [255]
1305 1305
1306 1306 #if serve
1307 1307
1308 1308 largefiles clients refuse to push largefiles repos to vanilla servers
1309 1309 $ mkdir r6
1310 1310 $ cd r6
1311 1311 $ hg init
1312 1312 $ echo c1 > f1
1313 1313 $ hg add f1
1314 1314 $ hg commit -m "m1"
1315 1315 Invoking status precommit hook
1316 1316 A f1
1317 1317 $ cat >> .hg/hgrc <<!
1318 1318 > [web]
1319 1319 > push_ssl = false
1320 1320 > allow_push = *
1321 1321 > !
1322 1322 $ cd ..
1323 1323 $ hg clone r6 r7
1324 1324 updating to branch default
1325 1325 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1326 1326 $ cd r7
1327 1327 $ echo c2 > f2
1328 1328 $ hg add --large f2
1329 1329 $ hg commit -m "m2"
1330 1330 Invoking status precommit hook
1331 1331 A f2
1332 1332 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
1333 1333 $ cat ../hg.pid >> $DAEMON_PIDS
1334 1334 $ hg push http://localhost:$HGPORT
1335 1335 pushing to http://localhost:$HGPORT/
1336 1336 searching for changes
1337 1337 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
1338 1338 [255]
1339 1339 $ cd ..
1340 1340
1341 1341 putlfile errors are shown (issue3123)
1342 1342 Corrupt the cached largefile in r7 and in the usercache (required for testing on vfat)
1343 1343 $ echo corruption > "$TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8"
1344 1344 $ echo corruption > "$USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8"
1345 1345 $ hg init empty
1346 1346 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
1347 1347 > --config 'web.allow_push=*' --config web.push_ssl=False
1348 1348 $ cat hg.pid >> $DAEMON_PIDS
1349 1349 $ hg push -R r7 http://localhost:$HGPORT1
1350 1350 pushing to http://localhost:$HGPORT1/
1351 1351 searching for changes
1352 1352 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
1353 1353 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/ (glob)
1354 1354 [255]
1355 1355 $ rm -rf empty
1356 1356
1357 1357 Push a largefiles repository to a served empty repository
1358 1358 $ hg init r8
1359 1359 $ echo c3 > r8/f1
1360 1360 $ hg add --large r8/f1 -R r8
1361 1361 $ hg commit -m "m1" -R r8
1362 1362 Invoking status precommit hook
1363 1363 A f1
1364 1364 $ hg init empty
1365 1365 $ hg serve -R empty -d -p $HGPORT2 --pid-file hg.pid \
1366 1366 > --config 'web.allow_push=*' --config web.push_ssl=False
1367 1367 $ cat hg.pid >> $DAEMON_PIDS
1368 1368 $ rm "${USERCACHE}"/*
1369 1369 $ hg push -R r8 http://localhost:$HGPORT2
1370 1370 pushing to http://localhost:$HGPORT2/
1371 1371 searching for changes
1372 1372 searching for changes
1373 1373 remote: adding changesets
1374 1374 remote: adding manifests
1375 1375 remote: adding file changes
1376 1376 remote: added 1 changesets with 1 changes to 1 files
1377 1377 $ rm -rf empty
1378 1378
1379 1379 used all HGPORTs, kill all daemons
1380 1380 $ "$TESTDIR/killdaemons.py"
1381 1381
1382 1382 #endif
1383 1383
1384 1384
1385 1385 #if unix-permissions
1386 1386
1387 1387 Clone a local repository owned by another user
1388 1388 We have to simulate that here by setting $HOME and removing write permissions
1389 1389 $ ORIGHOME="$HOME"
1390 1390 $ mkdir alice
1391 1391 $ HOME="`pwd`/alice"
1392 1392 $ cd alice
1393 1393 $ hg init pubrepo
1394 1394 $ cd pubrepo
1395 1395 $ dd if=/dev/zero bs=1k count=11k > a-large-file 2> /dev/null
1396 1396 $ hg add --large a-large-file
1397 1397 $ hg commit -m "Add a large file"
1398 1398 Invoking status precommit hook
1399 1399 A a-large-file
1400 1400 $ cd ..
1401 1401 $ chmod -R a-w pubrepo
1402 1402 $ cd ..
1403 1403 $ mkdir bob
1404 1404 $ HOME="`pwd`/bob"
1405 1405 $ cd bob
1406 1406 $ hg clone --pull ../alice/pubrepo pubrepo
1407 1407 requesting all changes
1408 1408 adding changesets
1409 1409 adding manifests
1410 1410 adding file changes
1411 1411 added 1 changesets with 1 changes to 1 files
1412 1412 updating to branch default
1413 1413 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1414 1414 getting changed largefiles
1415 1415 1 largefiles updated, 0 removed
1416 1416 $ cd ..
1417 1417 $ chmod -R u+w alice/pubrepo
1418 1418 $ HOME="$ORIGHOME"
1419 1419
1420 1420 #endif
1421 1421
1422 1422 #if symlink
1423 1423
1424 1424 Symlink to a large largefile should behave the same as a symlink to a normal file
1425 1425 $ hg init largesymlink
1426 1426 $ cd largesymlink
1427 1427 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
1428 1428 $ hg add --large largefile
1429 1429 $ hg commit -m "commit a large file"
1430 1430 Invoking status precommit hook
1431 1431 A largefile
1432 1432 $ ln -s largefile largelink
1433 1433 $ hg add largelink
1434 1434 $ hg commit -m "commit a large symlink"
1435 1435 Invoking status precommit hook
1436 1436 A largelink
1437 1437 $ rm -f largelink
1438 1438 $ hg up >/dev/null
1439 1439 $ test -f largelink
1440 1440 [1]
1441 1441 $ test -L largelink
1442 1442 [1]
1443 1443 $ rm -f largelink # make next part of the test independent of the previous
1444 1444 $ hg up -C >/dev/null
1445 1445 $ test -f largelink
1446 1446 $ test -L largelink
1447 1447 $ cd ..
1448 1448
1449 1449 #endif
1450 1450
1451 1451 test for pattern matching on 'hg status':
1452 1452 to boost performance, largefiles checks whether specified patterns are
1453 1453 related to largefiles in working directory (NOT to STANDIN) or not.
1454 1454
1455 1455 $ hg init statusmatch
1456 1456 $ cd statusmatch
1457 1457
1458 1458 $ mkdir -p a/b/c/d
1459 1459 $ echo normal > a/b/c/d/e.normal.txt
1460 1460 $ hg add a/b/c/d/e.normal.txt
1461 1461 $ echo large > a/b/c/d/e.large.txt
1462 1462 $ hg add --large a/b/c/d/e.large.txt
1463 1463 $ mkdir -p a/b/c/x
1464 1464 $ echo normal > a/b/c/x/y.normal.txt
1465 1465 $ hg add a/b/c/x/y.normal.txt
1466 1466 $ hg commit -m 'add files'
1467 1467 Invoking status precommit hook
1468 1468 A a/b/c/d/e.large.txt
1469 1469 A a/b/c/d/e.normal.txt
1470 1470 A a/b/c/x/y.normal.txt
1471 1471
1472 1472 (1) no pattern: no performance boost
1473 1473 $ hg status -A
1474 1474 C a/b/c/d/e.large.txt
1475 1475 C a/b/c/d/e.normal.txt
1476 1476 C a/b/c/x/y.normal.txt
1477 1477
1478 1478 (2) pattern not related to largefiles: performance boost
1479 1479 $ hg status -A a/b/c/x
1480 1480 C a/b/c/x/y.normal.txt
1481 1481
1482 1482 (3) pattern related to largefiles: no performance boost
1483 1483 $ hg status -A a/b/c/d
1484 1484 C a/b/c/d/e.large.txt
1485 1485 C a/b/c/d/e.normal.txt
1486 1486
1487 1487 (4) pattern related to STANDIN (not to largefiles): performance boost
1488 1488 $ hg status -A .hglf/a
1489 1489 C .hglf/a/b/c/d/e.large.txt
1490 1490
1491 1491 (5) mixed case: no performance boost
1492 1492 $ hg status -A a/b/c/x a/b/c/d
1493 1493 C a/b/c/d/e.large.txt
1494 1494 C a/b/c/d/e.normal.txt
1495 1495 C a/b/c/x/y.normal.txt
1496 1496
1497 1497 verify that largefiles doesn't break filesets
1498 1498
1499 1499 $ hg log --rev . --exclude "set:binary()"
1500 1500 changeset: 0:41bd42f10efa
1501 1501 tag: tip
1502 1502 user: test
1503 1503 date: Thu Jan 01 00:00:00 1970 +0000
1504 1504 summary: add files
1505 1505
1506 1506 verify that large files in subrepos handled properly
1507 1507 $ hg init subrepo
1508 1508 $ echo "subrepo = subrepo" > .hgsub
1509 1509 $ hg add .hgsub
1510 1510 $ hg ci -m "add subrepo"
1511 1511 Invoking status precommit hook
1512 1512 A .hgsub
1513 1513 ? .hgsubstate
1514 1514 $ echo "rev 1" > subrepo/large.txt
1515 1515 $ hg -R subrepo add --large subrepo/large.txt
1516 1516 $ hg sum
1517 1517 parent: 1:8ee150ea2e9c tip
1518 1518 add subrepo
1519 1519 branch: default
1520 1520 commit: 1 subrepos
1521 1521 update: (current)
1522 1522 $ hg st
1523 1523 $ hg st -S
1524 1524 A subrepo/large.txt
1525 1525 $ hg ci -S -m "commit top repo"
1526 1526 committing subrepository subrepo
1527 1527 Invoking status precommit hook
1528 1528 A large.txt
1529 1529 Invoking status precommit hook
1530 1530 M .hgsubstate
1531 1531 # No differences
1532 1532 $ hg st -S
1533 1533 $ hg sum
1534 1534 parent: 2:ce4cd0c527a6 tip
1535 1535 commit top repo
1536 1536 branch: default
1537 1537 commit: (clean)
1538 1538 update: (current)
1539 1539 $ echo "rev 2" > subrepo/large.txt
1540 1540 $ hg st -S
1541 1541 M subrepo/large.txt
1542 1542 $ hg sum
1543 1543 parent: 2:ce4cd0c527a6 tip
1544 1544 commit top repo
1545 1545 branch: default
1546 1546 commit: 1 subrepos
1547 1547 update: (current)
1548 1548 $ hg ci -m "this commit should fail without -S"
1549 1549 abort: uncommitted changes in subrepo subrepo
1550 1550 (use --subrepos for recursive commit)
1551 1551 [255]
1552 1552
1553 1553 Add a normal file to the subrepo, then test archiving
1554 1554
1555 1555 $ echo 'normal file' > subrepo/normal.txt
1556 1556 $ hg -R subrepo add subrepo/normal.txt
1557 1557
1558 1558 Lock in subrepo, otherwise the change isn't archived
1559 1559
1560 1560 $ hg ci -S -m "add normal file to top level"
1561 1561 committing subrepository subrepo
1562 1562 Invoking status precommit hook
1563 1563 M large.txt
1564 1564 A normal.txt
1565 1565 Invoking status precommit hook
1566 1566 M .hgsubstate
1567 1567 $ hg archive -S lf_subrepo_archive
1568 1568 $ find lf_subrepo_archive | sort
1569 1569 lf_subrepo_archive
1570 1570 lf_subrepo_archive/.hg_archival.txt
1571 1571 lf_subrepo_archive/.hgsub
1572 1572 lf_subrepo_archive/.hgsubstate
1573 1573 lf_subrepo_archive/a
1574 1574 lf_subrepo_archive/a/b
1575 1575 lf_subrepo_archive/a/b/c
1576 1576 lf_subrepo_archive/a/b/c/d
1577 1577 lf_subrepo_archive/a/b/c/d/e.large.txt
1578 1578 lf_subrepo_archive/a/b/c/d/e.normal.txt
1579 1579 lf_subrepo_archive/a/b/c/x
1580 1580 lf_subrepo_archive/a/b/c/x/y.normal.txt
1581 1581 lf_subrepo_archive/subrepo
1582 1582 lf_subrepo_archive/subrepo/large.txt
1583 1583 lf_subrepo_archive/subrepo/normal.txt
1584 1584
1585 1585 $ cd ..
1586
1587 Test that addremove picks up largefiles prior to the initial commit (issue3541)
1588
1589 $ hg init addrm2
1590 $ cd addrm2
1591 $ touch large.dat
1592 $ touch large2.dat
1593 $ touch normal
1594 $ hg add --large large.dat
1595 $ hg addremove -v
1596 adding large2.dat as a largefile
1597 adding normal
1598
1599 Test that forgetting all largefiles reverts to islfilesrepo() == False
1600 (addremove will add *.dat as normal files now)
1601 $ hg forget large.dat
1602 $ hg forget large2.dat
1603 $ hg addremove -v
1604 adding large.dat
1605 adding large2.dat
1606
1607 Test commit's addremove option prior to the first commit
1608 $ hg forget large.dat
1609 $ hg forget large2.dat
1610 $ hg add --large large.dat
1611 $ hg ci -Am "commit"
1612 adding large2.dat as a largefile
1613 Invoking status precommit hook
1614 A large.dat
1615 A large2.dat
1616 A normal
1617 $ find .hglf/ | sort
1618 .hglf/
1619 .hglf/large.dat
1620 .hglf/large2.dat
1621
1622 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now