##// END OF EJS Templates
largefiles: factor out procedures to update standins for pre-committing...
FUJIWARA Katsunori -
r23185:9870173e default
parent child Browse files
Show More
@@ -12,6 +12,7 b' import os'
12 import platform
12 import platform
13 import shutil
13 import shutil
14 import stat
14 import stat
15 import copy
15
16
16 from mercurial import dirstate, httpconnection, match as match_, util, scmutil
17 from mercurial import dirstate, httpconnection, match as match_, util, scmutil
17 from mercurial.i18n import _
18 from mercurial.i18n import _
@@ -427,3 +428,112 b' def getlfilestoupload(repo, missing, add'
427 for fn in files:
428 for fn in files:
428 if isstandin(fn) and fn in ctx:
429 if isstandin(fn) and fn in ctx:
429 addfunc(fn, ctx[fn].data().strip())
430 addfunc(fn, ctx[fn].data().strip())
431
432 def updatestandinsbymatch(repo, match):
433 '''Update standins in the working directory according to specified match
434
435 This returns (possibly modified) ``match`` object to be used for
436 subsequent commit process.
437 '''
438
439 ui = repo.ui
440
441 # Case 0: Automated committing
442 #
443 # While automated committing (like rebase, transplant
444 # and so on), this code path is used to avoid:
445 # (1) updating standins, because standins should
446 # be already updated at this point
447 # (2) aborting when standins are matched by "match",
448 # because automated committing may specify them directly
449 #
450 if getattr(repo, "_isrebasing", False) or \
451 getattr(repo, "_istransplanting", False):
452 return match
453
454 # Case 1: user calls commit with no specific files or
455 # include/exclude patterns: refresh and commit all files that
456 # are "dirty".
457 if match is None or match.always():
458 # Spend a bit of time here to get a list of files we know
459 # are modified so we can compare only against those.
460 # It can cost a lot of time (several seconds)
461 # otherwise to update all standins if the largefiles are
462 # large.
463 lfdirstate = openlfdirstate(ui, repo)
464 dirtymatch = match_.always(repo.root, repo.getcwd())
465 unsure, s = lfdirstate.status(dirtymatch, [], False, False,
466 False)
467 modifiedfiles = unsure + s.modified + s.added + s.removed
468 lfiles = listlfiles(repo)
469 # this only loops through largefiles that exist (not
470 # removed/renamed)
471 for lfile in lfiles:
472 if lfile in modifiedfiles:
473 if os.path.exists(
474 repo.wjoin(standin(lfile))):
475 # this handles the case where a rebase is being
476 # performed and the working copy is not updated
477 # yet.
478 if os.path.exists(repo.wjoin(lfile)):
479 updatestandin(repo,
480 standin(lfile))
481
482 return match
483
484 lfiles = listlfiles(repo)
485 match._files = repo._subdirlfs(match.files(), lfiles)
486
487 # Case 2: user calls commit with specified patterns: refresh
488 # any matching big files.
489 smatcher = composestandinmatcher(repo, match)
490 standins = repo.dirstate.walk(smatcher, [], False, False)
491
492 # No matching big files: get out of the way and pass control to
493 # the usual commit() method.
494 if not standins:
495 return match
496
497 # Refresh all matching big files. It's possible that the
498 # commit will end up failing, in which case the big files will
499 # stay refreshed. No harm done: the user modified them and
500 # asked to commit them, so sooner or later we're going to
501 # refresh the standins. Might as well leave them refreshed.
502 lfdirstate = openlfdirstate(ui, repo)
503 for fstandin in standins:
504 lfile = splitstandin(fstandin)
505 if lfdirstate[lfile] != 'r':
506 updatestandin(repo, fstandin)
507
508 # Cook up a new matcher that only matches regular files or
509 # standins corresponding to the big files requested by the
510 # user. Have to modify _files to prevent commit() from
511 # complaining "not tracked" for big files.
512 match = copy.copy(match)
513 origmatchfn = match.matchfn
514
515 # Check both the list of largefiles and the list of
516 # standins because if a largefile was removed, it
517 # won't be in the list of largefiles at this point
518 match._files += sorted(standins)
519
520 actualfiles = []
521 for f in match._files:
522 fstandin = standin(f)
523
524 # ignore known largefiles and standins
525 if f in lfiles or fstandin in standins:
526 continue
527
528 actualfiles.append(f)
529 match._files = actualfiles
530
531 def matchfn(f):
532 if origmatchfn(f):
533 return f not in lfiles
534 else:
535 return f in standins
536
537 match.matchfn = matchfn
538
539 return match
@@ -262,108 +262,7 b' def reposetup(ui, repo):'
262
262
263 wlock = self.wlock()
263 wlock = self.wlock()
264 try:
264 try:
265 # Case 0: Automated committing
265 match = lfutil.updatestandinsbymatch(self, match)
266 #
267 # While automated committing (like rebase, transplant
268 # and so on), this code path is used to avoid:
269 # (1) updating standins, because standins should
270 # be already updated at this point
271 # (2) aborting when standins are matched by "match",
272 # because automated committing may specify them directly
273 #
274 if getattr(self, "_isrebasing", False) or \
275 getattr(self, "_istransplanting", False):
276 result = orig(text=text, user=user, date=date, match=match,
277 force=force, editor=editor, extra=extra)
278 return result
279 # Case 1: user calls commit with no specific files or
280 # include/exclude patterns: refresh and commit all files that
281 # are "dirty".
282 if match is None or match.always():
283 # Spend a bit of time here to get a list of files we know
284 # are modified so we can compare only against those.
285 # It can cost a lot of time (several seconds)
286 # otherwise to update all standins if the largefiles are
287 # large.
288 lfdirstate = lfutil.openlfdirstate(ui, self)
289 dirtymatch = match_.always(self.root, self.getcwd())
290 unsure, s = lfdirstate.status(dirtymatch, [], False, False,
291 False)
292 modifiedfiles = unsure + s.modified + s.added + s.removed
293 lfiles = lfutil.listlfiles(self)
294 # this only loops through largefiles that exist (not
295 # removed/renamed)
296 for lfile in lfiles:
297 if lfile in modifiedfiles:
298 if os.path.exists(
299 self.wjoin(lfutil.standin(lfile))):
300 # this handles the case where a rebase is being
301 # performed and the working copy is not updated
302 # yet.
303 if os.path.exists(self.wjoin(lfile)):
304 lfutil.updatestandin(self,
305 lfutil.standin(lfile))
306
307 result = orig(text=text, user=user, date=date, match=match,
308 force=force, editor=editor, extra=extra)
309
310 return result
311
312 lfiles = lfutil.listlfiles(self)
313 match._files = self._subdirlfs(match.files(), lfiles)
314
315 # Case 2: user calls commit with specified patterns: refresh
316 # any matching big files.
317 smatcher = lfutil.composestandinmatcher(self, match)
318 standins = self.dirstate.walk(smatcher, [], False, False)
319
320 # No matching big files: get out of the way and pass control to
321 # the usual commit() method.
322 if not standins:
323 return orig(text=text, user=user, date=date, match=match,
324 force=force, editor=editor, extra=extra)
325
326 # Refresh all matching big files. It's possible that the
327 # commit will end up failing, in which case the big files will
328 # stay refreshed. No harm done: the user modified them and
329 # asked to commit them, so sooner or later we're going to
330 # refresh the standins. Might as well leave them refreshed.
331 lfdirstate = lfutil.openlfdirstate(ui, self)
332 for standin in standins:
333 lfile = lfutil.splitstandin(standin)
334 if lfdirstate[lfile] != 'r':
335 lfutil.updatestandin(self, standin)
336
337 # Cook up a new matcher that only matches regular files or
338 # standins corresponding to the big files requested by the
339 # user. Have to modify _files to prevent commit() from
340 # complaining "not tracked" for big files.
341 match = copy.copy(match)
342 origmatchfn = match.matchfn
343
344 # Check both the list of largefiles and the list of
345 # standins because if a largefile was removed, it
346 # won't be in the list of largefiles at this point
347 match._files += sorted(standins)
348
349 actualfiles = []
350 for f in match._files:
351 fstandin = lfutil.standin(f)
352
353 # ignore known largefiles and standins
354 if f in lfiles or fstandin in standins:
355 continue
356
357 actualfiles.append(f)
358 match._files = actualfiles
359
360 def matchfn(f):
361 if origmatchfn(f):
362 return f not in lfiles
363 else:
364 return f in standins
365
366 match.matchfn = matchfn
367 result = orig(text=text, user=user, date=date, match=match,
266 result = orig(text=text, user=user, date=date, match=match,
368 force=force, editor=editor, extra=extra)
267 force=force, editor=editor, extra=extra)
369 return result
268 return result
@@ -381,6 +280,8 b' def reposetup(ui, repo):'
381 return super(lfilesrepo, self).push(remote, force=force, revs=revs,
280 return super(lfilesrepo, self).push(remote, force=force, revs=revs,
382 newbranch=newbranch)
281 newbranch=newbranch)
383
282
283 # TODO: _subdirlfs should be moved into "lfutil.py", because
284 # it is referred only from "lfutil.updatestandinsbymatch"
384 def _subdirlfs(self, files, lfiles):
285 def _subdirlfs(self, files, lfiles):
385 '''
286 '''
386 Adjust matched file list
287 Adjust matched file list
General Comments 0
You need to be logged in to leave comments. Login now