##// END OF EJS Templates
largefiles: don't break filesets
Dan Villiom Podlaski Christiansen -
r16141:f346de4d stable
parent child Browse files
Show More
@@ -1,450 +1,458 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 '''setup for largefiles repositories: reposetup'''
10 10 import copy
11 11 import types
12 12 import os
13 13
14 14 from mercurial import context, error, manifest, match as match_, util
15 15 from mercurial import node as node_
16 16 from mercurial.i18n import _
17 17
18 18 import lfcommands
19 19 import proto
20 20 import lfutil
21 21
22 22 def reposetup(ui, repo):
23 23 # wire repositories should be given new wireproto functions but not the
24 24 # other largefiles modifications
25 25 if not repo.local():
26 26 return proto.wirereposetup(ui, repo)
27 27
28 28 for name in ('status', 'commitctx', 'commit', 'push'):
29 29 method = getattr(repo, name)
30 30 if (isinstance(method, types.FunctionType) and
31 31 method.func_name == 'wrap'):
32 32 ui.warn(_('largefiles: repo method %r appears to have already been'
33 33 ' wrapped by another extension: '
34 34 'largefiles may behave incorrectly\n')
35 35 % name)
36 36
37 37 class lfiles_repo(repo.__class__):
38 38 lfstatus = False
39 39 def status_nolfiles(self, *args, **kwargs):
40 40 return super(lfiles_repo, self).status(*args, **kwargs)
41 41
42 42 # When lfstatus is set, return a context that gives the names
43 43 # of largefiles instead of their corresponding standins and
44 44 # identifies the largefiles as always binary, regardless of
45 45 # their actual contents.
46 46 def __getitem__(self, changeid):
47 47 ctx = super(lfiles_repo, self).__getitem__(changeid)
48 48 if self.lfstatus:
49 49 class lfiles_manifestdict(manifest.manifestdict):
50 50 def __contains__(self, filename):
51 51 if super(lfiles_manifestdict,
52 52 self).__contains__(filename):
53 53 return True
54 54 return super(lfiles_manifestdict,
55 55 self).__contains__(lfutil.standin(filename))
56 56 class lfiles_ctx(ctx.__class__):
57 57 def files(self):
58 58 filenames = super(lfiles_ctx, self).files()
59 59 return [lfutil.splitstandin(f) or f for f in filenames]
60 60 def manifest(self):
61 61 man1 = super(lfiles_ctx, self).manifest()
62 62 man1.__class__ = lfiles_manifestdict
63 63 return man1
64 64 def filectx(self, path, fileid=None, filelog=None):
65 65 try:
66 result = super(lfiles_ctx, self).filectx(path,
67 fileid, filelog)
66 if filelog is not None:
67 result = super(lfiles_ctx, self).filectx(
68 path, fileid, filelog)
69 else:
70 result = super(lfiles_ctx, self).filectx(
71 path, fileid)
68 72 except error.LookupError:
69 73 # Adding a null character will cause Mercurial to
70 74 # identify this as a binary file.
75 if filelog is not None:
71 76 result = super(lfiles_ctx, self).filectx(
72 77 lfutil.standin(path), fileid, filelog)
78 else:
79 result = super(lfiles_ctx, self).filectx(
80 lfutil.standin(path), fileid)
73 81 olddata = result.data
74 82 result.data = lambda: olddata() + '\0'
75 83 return result
76 84 ctx.__class__ = lfiles_ctx
77 85 return ctx
78 86
79 87 # Figure out the status of big files and insert them into the
80 88 # appropriate list in the result. Also removes standin files
81 89 # from the listing. Revert to the original status if
82 90 # self.lfstatus is False.
83 91 def status(self, node1='.', node2=None, match=None, ignored=False,
84 92 clean=False, unknown=False, listsubrepos=False):
85 93 listignored, listclean, listunknown = ignored, clean, unknown
86 94 if not self.lfstatus:
87 95 return super(lfiles_repo, self).status(node1, node2, match,
88 96 listignored, listclean, listunknown, listsubrepos)
89 97 else:
90 98 # some calls in this function rely on the old version of status
91 99 self.lfstatus = False
92 100 if isinstance(node1, context.changectx):
93 101 ctx1 = node1
94 102 else:
95 103 ctx1 = repo[node1]
96 104 if isinstance(node2, context.changectx):
97 105 ctx2 = node2
98 106 else:
99 107 ctx2 = repo[node2]
100 108 working = ctx2.rev() is None
101 109 parentworking = working and ctx1 == self['.']
102 110
103 111 def inctx(file, ctx):
104 112 try:
105 113 if ctx.rev() is None:
106 114 return file in ctx.manifest()
107 115 ctx[file]
108 116 return True
109 117 except KeyError:
110 118 return False
111 119
112 120 if match is None:
113 121 match = match_.always(self.root, self.getcwd())
114 122
115 123 # First check if there were files specified on the
116 124 # command line. If there were, and none of them were
117 125 # largefiles, we should just bail here and let super
118 126 # handle it -- thus gaining a big performance boost.
119 127 lfdirstate = lfutil.openlfdirstate(ui, self)
120 128 if match.files() and not match.anypats():
121 129 for f in lfdirstate:
122 130 if match(f):
123 131 break
124 132 else:
125 133 return super(lfiles_repo, self).status(node1, node2,
126 134 match, listignored, listclean,
127 135 listunknown, listsubrepos)
128 136
129 137 # Create a copy of match that matches standins instead
130 138 # of largefiles.
131 139 def tostandin(file):
132 140 if inctx(lfutil.standin(file), ctx2):
133 141 return lfutil.standin(file)
134 142 return file
135 143
136 144 # Create a function that we can use to override what is
137 145 # normally the ignore matcher. We've already checked
138 146 # for ignored files on the first dirstate walk, and
139 147 # unecessarily re-checking here causes a huge performance
140 148 # hit because lfdirstate only knows about largefiles
141 149 def _ignoreoverride(self):
142 150 return False
143 151
144 152 m = copy.copy(match)
145 153 m._files = [tostandin(f) for f in m._files]
146 154
147 155 # Get ignored files here even if we weren't asked for them; we
148 156 # must use the result here for filtering later
149 157 result = super(lfiles_repo, self).status(node1, node2, m,
150 158 True, clean, unknown, listsubrepos)
151 159 if working:
152 160 try:
153 161 # Any non-largefiles that were explicitly listed must be
154 162 # taken out or lfdirstate.status will report an error.
155 163 # The status of these files was already computed using
156 164 # super's status.
157 165 # Override lfdirstate's ignore matcher to not do
158 166 # anything
159 167 orig_ignore = lfdirstate._ignore
160 168 lfdirstate._ignore = _ignoreoverride
161 169
162 170 match._files = [f for f in match._files if f in
163 171 lfdirstate]
164 172 # Don't waste time getting the ignored and unknown
165 173 # files again; we already have them
166 174 s = lfdirstate.status(match, [], False,
167 175 listclean, False)
168 176 (unsure, modified, added, removed, missing, unknown,
169 177 ignored, clean) = s
170 178 # Replace the list of ignored and unknown files with
171 179 # the previously caclulated lists, and strip out the
172 180 # largefiles
173 181 lfiles = set(lfdirstate._map)
174 182 ignored = set(result[5]).difference(lfiles)
175 183 unknown = set(result[4]).difference(lfiles)
176 184 if parentworking:
177 185 for lfile in unsure:
178 186 standin = lfutil.standin(lfile)
179 187 if standin not in ctx1:
180 188 # from second parent
181 189 modified.append(lfile)
182 190 elif ctx1[standin].data().strip() \
183 191 != lfutil.hashfile(self.wjoin(lfile)):
184 192 modified.append(lfile)
185 193 else:
186 194 clean.append(lfile)
187 195 lfdirstate.normal(lfile)
188 196 else:
189 197 tocheck = unsure + modified + added + clean
190 198 modified, added, clean = [], [], []
191 199
192 200 for lfile in tocheck:
193 201 standin = lfutil.standin(lfile)
194 202 if inctx(standin, ctx1):
195 203 if ctx1[standin].data().strip() != \
196 204 lfutil.hashfile(self.wjoin(lfile)):
197 205 modified.append(lfile)
198 206 else:
199 207 clean.append(lfile)
200 208 else:
201 209 added.append(lfile)
202 210 finally:
203 211 # Replace the original ignore function
204 212 lfdirstate._ignore = orig_ignore
205 213
206 214 for standin in ctx1.manifest():
207 215 if not lfutil.isstandin(standin):
208 216 continue
209 217 lfile = lfutil.splitstandin(standin)
210 218 if not match(lfile):
211 219 continue
212 220 if lfile not in lfdirstate:
213 221 removed.append(lfile)
214 222
215 223 # Filter result lists
216 224 result = list(result)
217 225
218 226 # Largefiles are not really removed when they're
219 227 # still in the normal dirstate. Likewise, normal
220 228 # files are not really removed if it's still in
221 229 # lfdirstate. This happens in merges where files
222 230 # change type.
223 231 removed = [f for f in removed if f not in repo.dirstate]
224 232 result[2] = [f for f in result[2] if f not in lfdirstate]
225 233
226 234 # Unknown files
227 235 unknown = set(unknown).difference(ignored)
228 236 result[4] = [f for f in unknown
229 237 if (repo.dirstate[f] == '?' and
230 238 not lfutil.isstandin(f))]
231 239 # Ignored files were calculated earlier by the dirstate,
232 240 # and we already stripped out the largefiles from the list
233 241 result[5] = ignored
234 242 # combine normal files and largefiles
235 243 normals = [[fn for fn in filelist
236 244 if not lfutil.isstandin(fn)]
237 245 for filelist in result]
238 246 lfiles = (modified, added, removed, missing, [], [], clean)
239 247 result = [sorted(list1 + list2)
240 248 for (list1, list2) in zip(normals, lfiles)]
241 249 else:
242 250 def toname(f):
243 251 if lfutil.isstandin(f):
244 252 return lfutil.splitstandin(f)
245 253 return f
246 254 result = [[toname(f) for f in items] for items in result]
247 255
248 256 if not listunknown:
249 257 result[4] = []
250 258 if not listignored:
251 259 result[5] = []
252 260 if not listclean:
253 261 result[6] = []
254 262 self.lfstatus = True
255 263 return result
256 264
257 265 # As part of committing, copy all of the largefiles into the
258 266 # cache.
259 267 def commitctx(self, *args, **kwargs):
260 268 node = super(lfiles_repo, self).commitctx(*args, **kwargs)
261 269 lfutil.copyalltostore(self, node)
262 270 return node
263 271
264 272 # Before commit, largefile standins have not had their
265 273 # contents updated to reflect the hash of their largefile.
266 274 # Do that here.
267 275 def commit(self, text="", user=None, date=None, match=None,
268 276 force=False, editor=False, extra={}):
269 277 orig = super(lfiles_repo, self).commit
270 278
271 279 wlock = repo.wlock()
272 280 try:
273 281 # Case 0: Rebase or Transplant
274 282 # We have to take the time to pull down the new largefiles now.
275 283 # Otherwise, any largefiles that were modified in the
276 284 # destination changesets get overwritten, either by the rebase
277 285 # or in the first commit after the rebase or transplant.
278 286 # updatelfiles will update the dirstate to mark any pulled
279 287 # largefiles as modified
280 288 if getattr(repo, "_isrebasing", False) or \
281 289 getattr(repo, "_istransplanting", False):
282 290 lfcommands.updatelfiles(repo.ui, repo, filelist=None,
283 291 printmessage=False)
284 292 result = orig(text=text, user=user, date=date, match=match,
285 293 force=force, editor=editor, extra=extra)
286 294 return result
287 295 # Case 1: user calls commit with no specific files or
288 296 # include/exclude patterns: refresh and commit all files that
289 297 # are "dirty".
290 298 if ((match is None) or
291 299 (not match.anypats() and not match.files())):
292 300 # Spend a bit of time here to get a list of files we know
293 301 # are modified so we can compare only against those.
294 302 # It can cost a lot of time (several seconds)
295 303 # otherwise to update all standins if the largefiles are
296 304 # large.
297 305 lfdirstate = lfutil.openlfdirstate(ui, self)
298 306 dirtymatch = match_.always(repo.root, repo.getcwd())
299 307 s = lfdirstate.status(dirtymatch, [], False, False, False)
300 308 modifiedfiles = []
301 309 for i in s:
302 310 modifiedfiles.extend(i)
303 311 lfiles = lfutil.listlfiles(self)
304 312 # this only loops through largefiles that exist (not
305 313 # removed/renamed)
306 314 for lfile in lfiles:
307 315 if lfile in modifiedfiles:
308 316 if os.path.exists(self.wjoin(lfutil.standin(lfile))):
309 317 # this handles the case where a rebase is being
310 318 # performed and the working copy is not updated
311 319 # yet.
312 320 if os.path.exists(self.wjoin(lfile)):
313 321 lfutil.updatestandin(self,
314 322 lfutil.standin(lfile))
315 323 lfdirstate.normal(lfile)
316 324 for lfile in lfdirstate:
317 325 if lfile in modifiedfiles:
318 326 if not os.path.exists(
319 327 repo.wjoin(lfutil.standin(lfile))):
320 328 lfdirstate.drop(lfile)
321 329
322 330 result = orig(text=text, user=user, date=date, match=match,
323 331 force=force, editor=editor, extra=extra)
324 332 # This needs to be after commit; otherwise precommit hooks
325 333 # get the wrong status
326 334 lfdirstate.write()
327 335 return result
328 336
329 337 for f in match.files():
330 338 if lfutil.isstandin(f):
331 339 raise util.Abort(
332 340 _('file "%s" is a largefile standin') % f,
333 341 hint=('commit the largefile itself instead'))
334 342
335 343 # Case 2: user calls commit with specified patterns: refresh
336 344 # any matching big files.
337 345 smatcher = lfutil.composestandinmatcher(self, match)
338 346 standins = lfutil.dirstate_walk(self.dirstate, smatcher)
339 347
340 348 # No matching big files: get out of the way and pass control to
341 349 # the usual commit() method.
342 350 if not standins:
343 351 return orig(text=text, user=user, date=date, match=match,
344 352 force=force, editor=editor, extra=extra)
345 353
346 354 # Refresh all matching big files. It's possible that the
347 355 # commit will end up failing, in which case the big files will
348 356 # stay refreshed. No harm done: the user modified them and
349 357 # asked to commit them, so sooner or later we're going to
350 358 # refresh the standins. Might as well leave them refreshed.
351 359 lfdirstate = lfutil.openlfdirstate(ui, self)
352 360 for standin in standins:
353 361 lfile = lfutil.splitstandin(standin)
354 362 if lfdirstate[lfile] <> 'r':
355 363 lfutil.updatestandin(self, standin)
356 364 lfdirstate.normal(lfile)
357 365 else:
358 366 lfdirstate.drop(lfile)
359 367
360 368 # Cook up a new matcher that only matches regular files or
361 369 # standins corresponding to the big files requested by the
362 370 # user. Have to modify _files to prevent commit() from
363 371 # complaining "not tracked" for big files.
364 372 lfiles = lfutil.listlfiles(repo)
365 373 match = copy.copy(match)
366 374 orig_matchfn = match.matchfn
367 375
368 376 # Check both the list of largefiles and the list of
369 377 # standins because if a largefile was removed, it
370 378 # won't be in the list of largefiles at this point
371 379 match._files += sorted(standins)
372 380
373 381 actualfiles = []
374 382 for f in match._files:
375 383 fstandin = lfutil.standin(f)
376 384
377 385 # ignore known largefiles and standins
378 386 if f in lfiles or fstandin in standins:
379 387 continue
380 388
381 389 # append directory separator to avoid collisions
382 390 if not fstandin.endswith(os.sep):
383 391 fstandin += os.sep
384 392
385 393 # prevalidate matching standin directories
386 394 if util.any(st for st in match._files
387 395 if st.startswith(fstandin)):
388 396 continue
389 397 actualfiles.append(f)
390 398 match._files = actualfiles
391 399
392 400 def matchfn(f):
393 401 if orig_matchfn(f):
394 402 return f not in lfiles
395 403 else:
396 404 return f in standins
397 405
398 406 match.matchfn = matchfn
399 407 result = orig(text=text, user=user, date=date, match=match,
400 408 force=force, editor=editor, extra=extra)
401 409 # This needs to be after commit; otherwise precommit hooks
402 410 # get the wrong status
403 411 lfdirstate.write()
404 412 return result
405 413 finally:
406 414 wlock.release()
407 415
408 416 def push(self, remote, force=False, revs=None, newbranch=False):
409 417 o = lfutil.findoutgoing(repo, remote, force)
410 418 if o:
411 419 toupload = set()
412 420 o = repo.changelog.nodesbetween(o, revs)[0]
413 421 for n in o:
414 422 parents = [p for p in repo.changelog.parents(n)
415 423 if p != node_.nullid]
416 424 ctx = repo[n]
417 425 files = set(ctx.files())
418 426 if len(parents) == 2:
419 427 mc = ctx.manifest()
420 428 mp1 = ctx.parents()[0].manifest()
421 429 mp2 = ctx.parents()[1].manifest()
422 430 for f in mp1:
423 431 if f not in mc:
424 432 files.add(f)
425 433 for f in mp2:
426 434 if f not in mc:
427 435 files.add(f)
428 436 for f in mc:
429 437 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f,
430 438 None):
431 439 files.add(f)
432 440
433 441 toupload = toupload.union(
434 442 set([ctx[f].data().strip()
435 443 for f in files
436 444 if lfutil.isstandin(f) and f in ctx]))
437 445 lfcommands.uploadlfiles(ui, self, remote, toupload)
438 446 return super(lfiles_repo, self).push(remote, force, revs,
439 447 newbranch)
440 448
441 449 repo.__class__ = lfiles_repo
442 450
443 451 def checkrequireslfiles(ui, repo, **kwargs):
444 452 if 'largefiles' not in repo.requirements and util.any(
445 453 lfutil.shortname+'/' in f[0] for f in repo.store.datafiles()):
446 454 repo.requirements.add('largefiles')
447 455 repo._writerequirements()
448 456
449 457 ui.setconfig('hooks', 'changegroup.lfiles', checkrequireslfiles)
450 458 ui.setconfig('hooks', 'commit.lfiles', checkrequireslfiles)
@@ -1,997 +1,1007 b''
1 1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
2 2 $ USERCACHE=`pwd`/cache; export USERCACHE
3 3 $ mkdir -p ${USERCACHE}
4 4 $ cat >> $HGRCPATH <<EOF
5 5 > [extensions]
6 6 > largefiles=
7 7 > purge=
8 8 > rebase=
9 9 > transplant=
10 10 > [phases]
11 11 > publish=False
12 12 > [largefiles]
13 13 > minsize=2
14 14 > patterns=glob:**.dat
15 15 > usercache=${USERCACHE}
16 16 > [hooks]
17 17 > precommit=echo "Invoking status precommit hook"; hg status
18 18 > EOF
19 19
20 20 Create the repo with a couple of revisions of both large and normal
21 21 files, testing that status correctly shows largefiles and that summary output
22 22 is correct.
23 23
24 24 $ hg init a
25 25 $ cd a
26 26 $ mkdir sub
27 27 $ echo normal1 > normal1
28 28 $ echo normal2 > sub/normal2
29 29 $ echo large1 > large1
30 30 $ echo large2 > sub/large2
31 31 $ hg add normal1 sub/normal2
32 32 $ hg add --large large1 sub/large2
33 33 $ hg commit -m "add files"
34 34 Invoking status precommit hook
35 35 A large1
36 36 A normal1
37 37 A sub/large2
38 38 A sub/normal2
39 39 $ echo normal11 > normal1
40 40 $ echo normal22 > sub/normal2
41 41 $ echo large11 > large1
42 42 $ echo large22 > sub/large2
43 43 $ hg commit -m "edit files"
44 44 Invoking status precommit hook
45 45 M large1
46 46 M normal1
47 47 M sub/large2
48 48 M sub/normal2
49 49 $ hg sum --large
50 50 parent: 1:ce8896473775 tip
51 51 edit files
52 52 branch: default
53 53 commit: (clean)
54 54 update: (current)
55 55 largefiles: No remote repo
56 56
57 57 Commit preserved largefile contents.
58 58
59 59 $ cat normal1
60 60 normal11
61 61 $ cat large1
62 62 large11
63 63 $ cat sub/normal2
64 64 normal22
65 65 $ cat sub/large2
66 66 large22
67 67
68 68 Remove both largefiles and normal files.
69 69
70 70 $ hg remove normal1 large1
71 71 $ hg commit -m "remove files"
72 72 Invoking status precommit hook
73 73 R large1
74 74 R normal1
75 75 $ ls
76 76 sub
77 77 $ echo "testlargefile" > large1-test
78 78 $ hg add --large large1-test
79 79 $ hg st
80 80 A large1-test
81 81 $ hg rm large1-test
82 82 not removing large1-test: file has been marked for add (use forget to undo)
83 83 $ hg st
84 84 A large1-test
85 85 $ hg forget large1-test
86 86 $ hg st
87 87 ? large1-test
88 88 $ rm large1-test
89 89
90 90 Copy both largefiles and normal files (testing that status output is correct).
91 91
92 92 $ hg cp sub/normal2 normal1
93 93 $ hg cp sub/large2 large1
94 94 $ hg commit -m "copy files"
95 95 Invoking status precommit hook
96 96 A large1
97 97 A normal1
98 98 $ cat normal1
99 99 normal22
100 100 $ cat large1
101 101 large22
102 102
103 103 Test moving largefiles and verify that normal files are also unaffected.
104 104
105 105 $ hg mv normal1 normal3
106 106 $ hg mv large1 large3
107 107 $ hg mv sub/normal2 sub/normal4
108 108 $ hg mv sub/large2 sub/large4
109 109 $ hg commit -m "move files"
110 110 Invoking status precommit hook
111 111 A large3
112 112 A normal3
113 113 A sub/large4
114 114 A sub/normal4
115 115 R large1
116 116 R normal1
117 117 R sub/large2
118 118 R sub/normal2
119 119 $ cat normal3
120 120 normal22
121 121 $ cat large3
122 122 large22
123 123 $ cat sub/normal4
124 124 normal22
125 125 $ cat sub/large4
126 126 large22
127 127
128 128 Test archiving the various revisions. These hit corner cases known with
129 129 archiving.
130 130
131 131 $ hg archive -r 0 ../archive0
132 132 $ hg archive -r 1 ../archive1
133 133 $ hg archive -r 2 ../archive2
134 134 $ hg archive -r 3 ../archive3
135 135 $ hg archive -r 4 ../archive4
136 136 $ cd ../archive0
137 137 $ cat normal1
138 138 normal1
139 139 $ cat large1
140 140 large1
141 141 $ cat sub/normal2
142 142 normal2
143 143 $ cat sub/large2
144 144 large2
145 145 $ cd ../archive1
146 146 $ cat normal1
147 147 normal11
148 148 $ cat large1
149 149 large11
150 150 $ cat sub/normal2
151 151 normal22
152 152 $ cat sub/large2
153 153 large22
154 154 $ cd ../archive2
155 155 $ ls
156 156 sub
157 157 $ cat sub/normal2
158 158 normal22
159 159 $ cat sub/large2
160 160 large22
161 161 $ cd ../archive3
162 162 $ cat normal1
163 163 normal22
164 164 $ cat large1
165 165 large22
166 166 $ cat sub/normal2
167 167 normal22
168 168 $ cat sub/large2
169 169 large22
170 170 $ cd ../archive4
171 171 $ cat normal3
172 172 normal22
173 173 $ cat large3
174 174 large22
175 175 $ cat sub/normal4
176 176 normal22
177 177 $ cat sub/large4
178 178 large22
179 179
180 180 Commit corner case: specify files to commit.
181 181
182 182 $ cd ../a
183 183 $ echo normal3 > normal3
184 184 $ echo large3 > large3
185 185 $ echo normal4 > sub/normal4
186 186 $ echo large4 > sub/large4
187 187 $ hg commit normal3 large3 sub/normal4 sub/large4 -m "edit files again"
188 188 Invoking status precommit hook
189 189 M large3
190 190 M normal3
191 191 M sub/large4
192 192 M sub/normal4
193 193 $ cat normal3
194 194 normal3
195 195 $ cat large3
196 196 large3
197 197 $ cat sub/normal4
198 198 normal4
199 199 $ cat sub/large4
200 200 large4
201 201
202 202 One more commit corner case: commit from a subdirectory.
203 203
204 204 $ cd ../a
205 205 $ echo normal33 > normal3
206 206 $ echo large33 > large3
207 207 $ echo normal44 > sub/normal4
208 208 $ echo large44 > sub/large4
209 209 $ cd sub
210 210 $ hg commit -m "edit files yet again"
211 211 Invoking status precommit hook
212 212 M large3
213 213 M normal3
214 214 M sub/large4
215 215 M sub/normal4
216 216 $ cat ../normal3
217 217 normal33
218 218 $ cat ../large3
219 219 large33
220 220 $ cat normal4
221 221 normal44
222 222 $ cat large4
223 223 large44
224 224
225 225 Committing standins is not allowed.
226 226
227 227 $ cd ..
228 228 $ echo large3 > large3
229 229 $ hg commit .hglf/large3 -m "try to commit standin"
230 230 abort: file ".hglf/large3" is a largefile standin
231 231 (commit the largefile itself instead)
232 232 [255]
233 233
234 234 Corner cases for adding largefiles.
235 235
236 236 $ echo large5 > large5
237 237 $ hg add --large large5
238 238 $ hg add --large large5
239 239 large5 already a largefile
240 240 $ mkdir sub2
241 241 $ echo large6 > sub2/large6
242 242 $ echo large7 > sub2/large7
243 243 $ hg add --large sub2
244 244 adding sub2/large6 as a largefile (glob)
245 245 adding sub2/large7 as a largefile (glob)
246 246 $ hg st
247 247 M large3
248 248 A large5
249 249 A sub2/large6
250 250 A sub2/large7
251 251
252 252 Config settings (pattern **.dat, minsize 2 MB) are respected.
253 253
254 254 $ echo testdata > test.dat
255 255 $ dd bs=1k count=2k if=/dev/zero of=reallylarge > /dev/null 2> /dev/null
256 256 $ hg add
257 257 adding reallylarge as a largefile
258 258 adding test.dat as a largefile
259 259
260 260 Test that minsize and --lfsize handle float values;
261 261 also tests that --lfsize overrides largefiles.minsize.
262 262 (0.250 MB = 256 kB = 262144 B)
263 263
264 264 $ dd if=/dev/zero of=ratherlarge bs=1024 count=256 > /dev/null 2> /dev/null
265 265 $ dd if=/dev/zero of=medium bs=1024 count=128 > /dev/null 2> /dev/null
266 266 $ hg --config largefiles.minsize=.25 add
267 267 adding ratherlarge as a largefile
268 268 adding medium
269 269 $ hg forget medium
270 270 $ hg --config largefiles.minsize=.25 add --lfsize=.125
271 271 adding medium as a largefile
272 272 $ dd if=/dev/zero of=notlarge bs=1024 count=127 > /dev/null 2> /dev/null
273 273 $ hg --config largefiles.minsize=.25 add --lfsize=.125
274 274 adding notlarge
275 275 $ hg forget notlarge
276 276
277 277 Test forget on largefiles.
278 278
279 279 $ hg forget large3 large5 test.dat reallylarge ratherlarge medium
280 280 $ hg commit -m "add/edit more largefiles"
281 281 Invoking status precommit hook
282 282 A sub2/large6
283 283 A sub2/large7
284 284 R large3
285 285 ? large5
286 286 ? medium
287 287 ? notlarge
288 288 ? ratherlarge
289 289 ? reallylarge
290 290 ? test.dat
291 291 $ hg st
292 292 ? large3
293 293 ? large5
294 294 ? medium
295 295 ? notlarge
296 296 ? ratherlarge
297 297 ? reallylarge
298 298 ? test.dat
299 299
300 300 Purge with largefiles: verify that largefiles are still in the working
301 301 dir after a purge.
302 302
303 303 $ hg purge --all
304 304 $ cat sub/large4
305 305 large44
306 306 $ cat sub2/large6
307 307 large6
308 308 $ cat sub2/large7
309 309 large7
310 310
311 311 Test addremove: verify that files that should be added as largfiles are added as
312 312 such and that already-existing largfiles are not added as normal files by
313 313 accident.
314 314
315 315 $ rm normal3
316 316 $ rm sub/large4
317 317 $ echo "testing addremove with patterns" > testaddremove.dat
318 318 $ echo "normaladdremove" > normaladdremove
319 319 $ hg addremove
320 320 removing sub/large4
321 321 adding testaddremove.dat as a largefile
322 322 removing normal3
323 323 adding normaladdremove
324 324
325 325 Clone a largefiles repo.
326 326
327 327 $ hg clone . ../b
328 328 updating to branch default
329 329 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
330 330 getting changed largefiles
331 331 3 largefiles updated, 0 removed
332 332 $ cd ../b
333 333 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
334 334 7:daea875e9014 add/edit more largefiles
335 335 6:4355d653f84f edit files yet again
336 336 5:9d5af5072dbd edit files again
337 337 4:74c02385b94c move files
338 338 3:9e8fbc4bce62 copy files
339 339 2:51a0ae4d5864 remove files
340 340 1:ce8896473775 edit files
341 341 0:30d30fe6a5be add files
342 342 $ cat normal3
343 343 normal33
344 344 $ cat sub/normal4
345 345 normal44
346 346 $ cat sub/large4
347 347 large44
348 348 $ cat sub2/large6
349 349 large6
350 350 $ cat sub2/large7
351 351 large7
352 352 $ cd ..
353 353 $ hg clone a -r 3 c
354 354 adding changesets
355 355 adding manifests
356 356 adding file changes
357 357 added 4 changesets with 10 changes to 4 files
358 358 updating to branch default
359 359 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
360 360 getting changed largefiles
361 361 2 largefiles updated, 0 removed
362 362 $ cd c
363 363 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
364 364 3:9e8fbc4bce62 copy files
365 365 2:51a0ae4d5864 remove files
366 366 1:ce8896473775 edit files
367 367 0:30d30fe6a5be add files
368 368 $ cat normal1
369 369 normal22
370 370 $ cat large1
371 371 large22
372 372 $ cat sub/normal2
373 373 normal22
374 374 $ cat sub/large2
375 375 large22
376 376
377 377 Old revisions of a clone have correct largefiles content (this also
378 378 tests update).
379 379
380 380 $ hg update -r 1
381 381 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 382 getting changed largefiles
383 383 1 largefiles updated, 0 removed
384 384 $ cat large1
385 385 large11
386 386 $ cat sub/large2
387 387 large22
388 388
389 389 Rebasing between two repositories does not revert largefiles to old
390 390 revisions (this was a very bad bug that took a lot of work to fix).
391 391
392 392 $ cd ..
393 393 $ hg clone a d
394 394 updating to branch default
395 395 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
396 396 getting changed largefiles
397 397 3 largefiles updated, 0 removed
398 398 $ cd b
399 399 $ echo large4-modified > sub/large4
400 400 $ echo normal3-modified > normal3
401 401 $ hg commit -m "modify normal file and largefile in repo b"
402 402 Invoking status precommit hook
403 403 M normal3
404 404 M sub/large4
405 405 $ cd ../d
406 406 $ echo large6-modified > sub2/large6
407 407 $ echo normal4-modified > sub/normal4
408 408 $ hg commit -m "modify normal file largefile in repo d"
409 409 Invoking status precommit hook
410 410 M sub/normal4
411 411 M sub2/large6
412 412 $ cd ..
413 413 $ hg clone d e
414 414 updating to branch default
415 415 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
416 416 getting changed largefiles
417 417 3 largefiles updated, 0 removed
418 418 $ cd d
419 419 $ hg pull --rebase ../b
420 420 pulling from ../b
421 421 searching for changes
422 422 adding changesets
423 423 adding manifests
424 424 adding file changes
425 425 added 1 changesets with 2 changes to 2 files (+1 heads)
426 426 Invoking status precommit hook
427 427 M sub/normal4
428 428 M sub2/large6
429 429 saved backup bundle to $TESTTMP/d/.hg/strip-backup/f574fb32bb45-backup.hg
430 430 nothing to rebase
431 431 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
432 432 9:598410d3eb9a modify normal file largefile in repo d
433 433 8:a381d2c8c80e modify normal file and largefile in repo b
434 434 7:daea875e9014 add/edit more largefiles
435 435 6:4355d653f84f edit files yet again
436 436 5:9d5af5072dbd edit files again
437 437 4:74c02385b94c move files
438 438 3:9e8fbc4bce62 copy files
439 439 2:51a0ae4d5864 remove files
440 440 1:ce8896473775 edit files
441 441 0:30d30fe6a5be add files
442 442 $ cat normal3
443 443 normal3-modified
444 444 $ cat sub/normal4
445 445 normal4-modified
446 446 $ cat sub/large4
447 447 large4-modified
448 448 $ cat sub2/large6
449 449 large6-modified
450 450 $ cat sub2/large7
451 451 large7
452 452 $ cd ../e
453 453 $ hg pull ../b
454 454 pulling from ../b
455 455 searching for changes
456 456 adding changesets
457 457 adding manifests
458 458 adding file changes
459 459 added 1 changesets with 2 changes to 2 files (+1 heads)
460 460 (run 'hg heads' to see heads, 'hg merge' to merge)
461 461 caching new largefiles
462 462 0 largefiles cached
463 463 $ hg rebase
464 464 Invoking status precommit hook
465 465 M sub/normal4
466 466 M sub2/large6
467 467 saved backup bundle to $TESTTMP/e/.hg/strip-backup/f574fb32bb45-backup.hg
468 468 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
469 469 9:598410d3eb9a modify normal file largefile in repo d
470 470 8:a381d2c8c80e modify normal file and largefile in repo b
471 471 7:daea875e9014 add/edit more largefiles
472 472 6:4355d653f84f edit files yet again
473 473 5:9d5af5072dbd edit files again
474 474 4:74c02385b94c move files
475 475 3:9e8fbc4bce62 copy files
476 476 2:51a0ae4d5864 remove files
477 477 1:ce8896473775 edit files
478 478 0:30d30fe6a5be add files
479 479 $ cat normal3
480 480 normal3-modified
481 481 $ cat sub/normal4
482 482 normal4-modified
483 483 $ cat sub/large4
484 484 large4-modified
485 485 $ cat sub2/large6
486 486 large6-modified
487 487 $ cat sub2/large7
488 488 large7
489 489
490 490 Rollback on largefiles.
491 491
492 492 $ echo large4-modified-again > sub/large4
493 493 $ hg commit -m "Modify large4 again"
494 494 Invoking status precommit hook
495 495 M sub/large4
496 496 $ hg rollback
497 497 repository tip rolled back to revision 9 (undo commit)
498 498 working directory now based on revision 9
499 499 $ hg st
500 500 M sub/large4
501 501 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
502 502 9:598410d3eb9a modify normal file largefile in repo d
503 503 8:a381d2c8c80e modify normal file and largefile in repo b
504 504 7:daea875e9014 add/edit more largefiles
505 505 6:4355d653f84f edit files yet again
506 506 5:9d5af5072dbd edit files again
507 507 4:74c02385b94c move files
508 508 3:9e8fbc4bce62 copy files
509 509 2:51a0ae4d5864 remove files
510 510 1:ce8896473775 edit files
511 511 0:30d30fe6a5be add files
512 512 $ cat sub/large4
513 513 large4-modified-again
514 514
515 515 "update --check" refuses to update with uncommitted changes.
516 516 $ hg update --check 8
517 517 abort: uncommitted local changes
518 518 [255]
519 519
520 520 "update --clean" leaves correct largefiles in working copy.
521 521
522 522 $ hg update --clean
523 523 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
524 524 getting changed largefiles
525 525 1 largefiles updated, 0 removed
526 526 $ cat normal3
527 527 normal3-modified
528 528 $ cat sub/normal4
529 529 normal4-modified
530 530 $ cat sub/large4
531 531 large4-modified
532 532 $ cat sub2/large6
533 533 large6-modified
534 534 $ cat sub2/large7
535 535 large7
536 536
537 537 Now "update check" is happy.
538 538 $ hg update --check 8
539 539 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
540 540 getting changed largefiles
541 541 1 largefiles updated, 0 removed
542 542 $ hg update --check
543 543 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
544 544 getting changed largefiles
545 545 1 largefiles updated, 0 removed
546 546
547 547 Test removing empty largefiles directories on update
548 548 $ test -d sub2 && echo "sub2 exists"
549 549 sub2 exists
550 550 $ hg update -q null
551 551 $ test -d sub2 && echo "error: sub2 should not exist anymore"
552 552 [1]
553 553 $ hg update -q
554 554
555 555 Test hg remove removes empty largefiles directories
556 556 $ test -d sub2 && echo "sub2 exists"
557 557 sub2 exists
558 558 $ hg remove sub2/*
559 559 $ test -d sub2 && echo "error: sub2 should not exist anymore"
560 560 [1]
561 561 $ hg revert sub2/large6 sub2/large7
562 562
563 563 "revert" works on largefiles (and normal files too).
564 564 $ echo hack3 >> normal3
565 565 $ echo hack4 >> sub/normal4
566 566 $ echo hack4 >> sub/large4
567 567 $ rm sub2/large6
568 568 $ hg revert sub2/large6
569 569 $ hg rm sub2/large6
570 570 $ echo new >> sub2/large8
571 571 $ hg add --large sub2/large8
572 572 # XXX we don't really want to report that we're reverting the standin;
573 573 # that's just an implementation detail. But I don't see an obvious fix. ;-(
574 574 $ hg revert sub
575 575 reverting .hglf/sub/large4 (glob)
576 576 reverting sub/normal4 (glob)
577 577 $ hg status
578 578 M normal3
579 579 A sub2/large8
580 580 R sub2/large6
581 581 ? sub/large4.orig
582 582 ? sub/normal4.orig
583 583 $ cat sub/normal4
584 584 normal4-modified
585 585 $ cat sub/large4
586 586 large4-modified
587 587 $ hg revert -a --no-backup
588 588 undeleting .hglf/sub2/large6 (glob)
589 589 forgetting .hglf/sub2/large8 (glob)
590 590 reverting normal3
591 591 $ hg status
592 592 ? sub/large4.orig
593 593 ? sub/normal4.orig
594 594 ? sub2/large8
595 595 $ cat normal3
596 596 normal3-modified
597 597 $ cat sub2/large6
598 598 large6-modified
599 599 $ rm sub/*.orig sub2/large8
600 600
601 601 revert some files to an older revision
602 602 $ hg revert --no-backup -r 8 sub2
603 603 reverting .hglf/sub2/large6 (glob)
604 604 $ cat sub2/large6
605 605 large6
606 606 $ hg revert --no-backup sub2
607 607 reverting .hglf/sub2/large6 (glob)
608 608 $ hg status
609 609
610 610 "verify --large" actually verifies largefiles
611 611
612 612 $ hg verify --large
613 613 checking changesets
614 614 checking manifests
615 615 crosschecking files in changesets and manifests
616 616 checking files
617 617 10 files, 10 changesets, 28 total revisions
618 618 searching 1 changesets for largefiles
619 619 verified existence of 3 revisions of 3 largefiles
620 620
621 621 Merging does not revert to old versions of largefiles and also check
622 622 that merging after having pulled from a non-default remote works
623 623 correctly.
624 624
625 625 $ cd ..
626 626 $ hg clone -r 7 e temp
627 627 adding changesets
628 628 adding manifests
629 629 adding file changes
630 630 added 8 changesets with 24 changes to 10 files
631 631 updating to branch default
632 632 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
633 633 getting changed largefiles
634 634 3 largefiles updated, 0 removed
635 635 $ hg clone temp f
636 636 updating to branch default
637 637 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
638 638 getting changed largefiles
639 639 3 largefiles updated, 0 removed
640 640 # Delete the largefiles in the largefiles system cache so that we have an
641 641 # opportunity to test that caching after a pull works.
642 642 $ rm ${USERCACHE}/*
643 643 $ cd f
644 644 $ echo "large4-merge-test" > sub/large4
645 645 $ hg commit -m "Modify large4 to test merge"
646 646 Invoking status precommit hook
647 647 M sub/large4
648 648 $ hg pull ../e
649 649 pulling from ../e
650 650 searching for changes
651 651 adding changesets
652 652 adding manifests
653 653 adding file changes
654 654 added 2 changesets with 4 changes to 4 files (+1 heads)
655 655 (run 'hg heads' to see heads, 'hg merge' to merge)
656 656 caching new largefiles
657 657 2 largefiles cached
658 658 $ hg merge
659 659 merging sub/large4
660 660 largefile sub/large4 has a merge conflict
661 661 keep (l)ocal or take (o)ther? l
662 662 3 files updated, 1 files merged, 0 files removed, 0 files unresolved
663 663 (branch merge, don't forget to commit)
664 664 getting changed largefiles
665 665 1 largefiles updated, 0 removed
666 666 $ hg commit -m "Merge repos e and f"
667 667 Invoking status precommit hook
668 668 M normal3
669 669 M sub/normal4
670 670 M sub2/large6
671 671 $ cat normal3
672 672 normal3-modified
673 673 $ cat sub/normal4
674 674 normal4-modified
675 675 $ cat sub/large4
676 676 large4-merge-test
677 677 $ cat sub2/large6
678 678 large6-modified
679 679 $ cat sub2/large7
680 680 large7
681 681
682 682 Test status after merging with a branch that introduces a new largefile:
683 683
684 684 $ echo large > large
685 685 $ hg add --large large
686 686 $ hg commit -m 'add largefile'
687 687 Invoking status precommit hook
688 688 A large
689 689 $ hg update -q ".^"
690 690 $ echo change >> normal3
691 691 $ hg commit -m 'some change'
692 692 Invoking status precommit hook
693 693 M normal3
694 694 created new head
695 695 $ hg merge
696 696 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
697 697 (branch merge, don't forget to commit)
698 698 getting changed largefiles
699 699 1 largefiles updated, 0 removed
700 700 $ hg status
701 701 M large
702 702
703 703 Test that a normal file and a largefile with the same name and path cannot
704 704 coexist.
705 705
706 706 $ rm sub2/large7
707 707 $ echo "largeasnormal" > sub2/large7
708 708 $ hg add sub2/large7
709 709 sub2/large7 already a largefile
710 710
711 711 Test that transplanting a largefile change works correctly.
712 712
713 713 $ cd ..
714 714 $ hg clone -r 8 d g
715 715 adding changesets
716 716 adding manifests
717 717 adding file changes
718 718 added 9 changesets with 26 changes to 10 files
719 719 updating to branch default
720 720 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
721 721 getting changed largefiles
722 722 3 largefiles updated, 0 removed
723 723 $ cd g
724 724 $ hg transplant -s ../d 598410d3eb9a
725 725 searching for changes
726 726 searching for changes
727 727 adding changesets
728 728 adding manifests
729 729 adding file changes
730 730 added 1 changesets with 2 changes to 2 files
731 731 $ hg log --template '{rev}:{node|short} {desc|firstline}\n'
732 732 9:598410d3eb9a modify normal file largefile in repo d
733 733 8:a381d2c8c80e modify normal file and largefile in repo b
734 734 7:daea875e9014 add/edit more largefiles
735 735 6:4355d653f84f edit files yet again
736 736 5:9d5af5072dbd edit files again
737 737 4:74c02385b94c move files
738 738 3:9e8fbc4bce62 copy files
739 739 2:51a0ae4d5864 remove files
740 740 1:ce8896473775 edit files
741 741 0:30d30fe6a5be add files
742 742 $ cat normal3
743 743 normal3-modified
744 744 $ cat sub/normal4
745 745 normal4-modified
746 746 $ cat sub/large4
747 747 large4-modified
748 748 $ cat sub2/large6
749 749 large6-modified
750 750 $ cat sub2/large7
751 751 large7
752 752
753 753 Test that renaming a largefile results in correct output for status
754 754
755 755 $ hg rename sub/large4 large4-renamed
756 756 $ hg commit -m "test rename output"
757 757 Invoking status precommit hook
758 758 A large4-renamed
759 759 R sub/large4
760 760 $ cat large4-renamed
761 761 large4-modified
762 762 $ cd sub2
763 763 $ hg rename large6 large6-renamed
764 764 $ hg st
765 765 A sub2/large6-renamed
766 766 R sub2/large6
767 767 $ cd ..
768 768
769 769 Test --normal flag
770 770
771 771 $ dd if=/dev/urandom bs=2k count=11k > new-largefile 2> /dev/null
772 772 $ hg add --normal --large new-largefile
773 773 abort: --normal cannot be used with --large
774 774 [255]
775 775 $ hg add --normal new-largefile
776 776 new-largefile: up to 69 MB of RAM may be required to manage this file
777 777 (use 'hg revert new-largefile' to cancel the pending addition)
778 778 $ cd ..
779 779
780 780 vanilla clients not locked out from largefiles servers on vanilla repos
781 781 $ mkdir r1
782 782 $ cd r1
783 783 $ hg init
784 784 $ echo c1 > f1
785 785 $ hg add f1
786 786 $ hg commit -m "m1"
787 787 Invoking status precommit hook
788 788 A f1
789 789 $ cd ..
790 790 $ hg serve -R r1 -d -p $HGPORT --pid-file hg.pid
791 791 $ cat hg.pid >> $DAEMON_PIDS
792 792 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT r2
793 793 requesting all changes
794 794 adding changesets
795 795 adding manifests
796 796 adding file changes
797 797 added 1 changesets with 1 changes to 1 files
798 798 updating to branch default
799 799 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
800 800
801 801 largefiles clients still work with vanilla servers
802 802 $ hg --config extensions.largefiles=! serve -R r1 -d -p $HGPORT1 --pid-file hg.pid
803 803 $ cat hg.pid >> $DAEMON_PIDS
804 804 $ hg clone http://localhost:$HGPORT1 r3
805 805 requesting all changes
806 806 adding changesets
807 807 adding manifests
808 808 adding file changes
809 809 added 1 changesets with 1 changes to 1 files
810 810 updating to branch default
811 811 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
812 812
813 813 vanilla clients locked out from largefiles http repos
814 814 $ mkdir r4
815 815 $ cd r4
816 816 $ hg init
817 817 $ echo c1 > f1
818 818 $ hg add --large f1
819 819 $ hg commit -m "m1"
820 820 Invoking status precommit hook
821 821 A f1
822 822 $ cd ..
823 823 $ hg serve -R r4 -d -p $HGPORT2 --pid-file hg.pid
824 824 $ cat hg.pid >> $DAEMON_PIDS
825 825 $ hg --config extensions.largefiles=! clone http://localhost:$HGPORT2 r5
826 826 abort: remote error:
827 827
828 828 This repository uses the largefiles extension.
829 829
830 830 Please enable it in your Mercurial config file.
831 831 [255]
832 832
833 833 used all HGPORTs, kill all daemons
834 834 $ "$TESTDIR/killdaemons.py"
835 835
836 836 vanilla clients locked out from largefiles ssh repos
837 837 $ hg --config extensions.largefiles=! clone -e "python $TESTDIR/dummyssh" ssh://user@dummy/r4 r5
838 838 abort: remote error:
839 839
840 840 This repository uses the largefiles extension.
841 841
842 842 Please enable it in your Mercurial config file.
843 843 [255]
844 844
845 845 largefiles clients refuse to push largefiles repos to vanilla servers
846 846 $ mkdir r6
847 847 $ cd r6
848 848 $ hg init
849 849 $ echo c1 > f1
850 850 $ hg add f1
851 851 $ hg commit -m "m1"
852 852 Invoking status precommit hook
853 853 A f1
854 854 $ cat >> .hg/hgrc <<!
855 855 > [web]
856 856 > push_ssl = false
857 857 > allow_push = *
858 858 > !
859 859 $ cd ..
860 860 $ hg clone r6 r7
861 861 updating to branch default
862 862 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
863 863 $ cd r7
864 864 $ echo c2 > f2
865 865 $ hg add --large f2
866 866 $ hg commit -m "m2"
867 867 Invoking status precommit hook
868 868 A f2
869 869 $ hg --config extensions.largefiles=! -R ../r6 serve -d -p $HGPORT --pid-file ../hg.pid
870 870 $ cat ../hg.pid >> $DAEMON_PIDS
871 871 $ hg push http://localhost:$HGPORT
872 872 pushing to http://localhost:$HGPORT/
873 873 searching for changes
874 874 abort: http://localhost:$HGPORT/ does not appear to be a largefile store
875 875 [255]
876 876 $ cd ..
877 877
878 878 putlfile errors are shown (issue3123)
879 879 Corrupt the cached largefile in r7
880 880 $ echo corruption > $USERCACHE/4cdac4d8b084d0b599525cf732437fb337d422a8
881 881 $ hg init empty
882 882 $ hg serve -R empty -d -p $HGPORT1 --pid-file hg.pid \
883 883 > --config 'web.allow_push=*' --config web.push_ssl=False
884 884 $ cat hg.pid >> $DAEMON_PIDS
885 885 $ hg push -R r7 http://localhost:$HGPORT1
886 886 pushing to http://localhost:$HGPORT1/
887 887 searching for changes
888 888 remote: largefiles: failed to put 4cdac4d8b084d0b599525cf732437fb337d422a8 into store: largefile contents do not match hash
889 889 abort: remotestore: could not put $TESTTMP/r7/.hg/largefiles/4cdac4d8b084d0b599525cf732437fb337d422a8 to remote store http://localhost:$HGPORT1/
890 890 [255]
891 891 $ rm -rf empty
892 892
893 893 Clone a local repository owned by another user
894 894 We have to simulate that here by setting $HOME and removing write permissions
895 895 $ ORIGHOME="$HOME"
896 896 $ mkdir alice
897 897 $ HOME="`pwd`/alice"
898 898 $ cd alice
899 899 $ hg init pubrepo
900 900 $ cd pubrepo
901 901 $ dd if=/dev/urandom bs=1k count=11k > a-large-file 2> /dev/null
902 902 $ hg add --large a-large-file
903 903 $ hg commit -m "Add a large file"
904 904 Invoking status precommit hook
905 905 A a-large-file
906 906 $ cd ..
907 907 $ chmod -R a-w pubrepo
908 908 $ cd ..
909 909 $ mkdir bob
910 910 $ HOME="`pwd`/bob"
911 911 $ cd bob
912 912 $ hg clone --pull ../alice/pubrepo pubrepo
913 913 requesting all changes
914 914 adding changesets
915 915 adding manifests
916 916 adding file changes
917 917 added 1 changesets with 1 changes to 1 files
918 918 updating to branch default
919 919 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
920 920 getting changed largefiles
921 921 1 largefiles updated, 0 removed
922 922 $ cd ..
923 923 $ chmod -R u+w alice/pubrepo
924 924 $ HOME="$ORIGHOME"
925 925
926 926 Symlink to a large largefile should behave the same as a symlink to a normal file
927 927 $ hg init largesymlink
928 928 $ cd largesymlink
929 929 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
930 930 $ hg add --large largefile
931 931 $ hg commit -m "commit a large file"
932 932 Invoking status precommit hook
933 933 A largefile
934 934 $ ln -s largefile largelink
935 935 $ hg add largelink
936 936 $ hg commit -m "commit a large symlink"
937 937 Invoking status precommit hook
938 938 A largelink
939 939 $ rm -f largelink
940 940 $ hg up >/dev/null
941 941 $ test -f largelink
942 942 [1]
943 943 $ test -L largelink
944 944 [1]
945 945 $ rm -f largelink # make next part of the test independent of the previous
946 946 $ hg up -C >/dev/null
947 947 $ test -f largelink
948 948 $ test -L largelink
949 949 $ cd ..
950 950
951 951 test for pattern matching on 'hg status':
952 952 to boost performance, largefiles checks whether specified patterns are
953 953 related to largefiles in working directory (NOT to STANDIN) or not.
954 954
955 955 $ hg init statusmatch
956 956 $ cd statusmatch
957 957
958 958 $ mkdir -p a/b/c/d
959 959 $ echo normal > a/b/c/d/e.normal.txt
960 960 $ hg add a/b/c/d/e.normal.txt
961 961 $ echo large > a/b/c/d/e.large.txt
962 962 $ hg add --large a/b/c/d/e.large.txt
963 963 $ mkdir -p a/b/c/x
964 964 $ echo normal > a/b/c/x/y.normal.txt
965 965 $ hg add a/b/c/x/y.normal.txt
966 966 $ hg commit -m 'add files'
967 967 Invoking status precommit hook
968 968 A a/b/c/d/e.large.txt
969 969 A a/b/c/d/e.normal.txt
970 970 A a/b/c/x/y.normal.txt
971 971
972 972 (1) no pattern: no performance boost
973 973 $ hg status -A
974 974 C a/b/c/d/e.large.txt
975 975 C a/b/c/d/e.normal.txt
976 976 C a/b/c/x/y.normal.txt
977 977
978 978 (2) pattern not related to largefiles: performance boost
979 979 $ hg status -A a/b/c/x
980 980 C a/b/c/x/y.normal.txt
981 981
982 982 (3) pattern related to largefiles: no performance boost
983 983 $ hg status -A a/b/c/d
984 984 C a/b/c/d/e.large.txt
985 985 C a/b/c/d/e.normal.txt
986 986
987 987 (4) pattern related to STANDIN (not to largefiles): performance boost
988 988 $ hg status -A .hglf/a
989 989 C .hglf/a/b/c/d/e.large.txt
990 990
991 991 (5) mixed case: no performance boost
992 992 $ hg status -A a/b/c/x a/b/c/d
993 993 C a/b/c/d/e.large.txt
994 994 C a/b/c/d/e.normal.txt
995 995 C a/b/c/x/y.normal.txt
996 996
997 verify that largefiles doesn't break filesets
998
999 $ hg log --rev . --exclude "set:binary()"
1000 changeset: 0:41bd42f10efa
1001 tag: tip
1002 user: test
1003 date: Thu Jan 01 00:00:00 1970 +0000
1004 summary: add files
1005
1006
997 1007 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now