##// 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 12 import platform
13 13 import shutil
14 14 import stat
15 import copy
15 16
16 17 from mercurial import dirstate, httpconnection, match as match_, util, scmutil
17 18 from mercurial.i18n import _
@@ -427,3 +428,112 b' def getlfilestoupload(repo, missing, add'
427 428 for fn in files:
428 429 if isstandin(fn) and fn in ctx:
429 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 263 wlock = self.wlock()
264 264 try:
265 # Case 0: Automated committing
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
265 match = lfutil.updatestandinsbymatch(self, match)
367 266 result = orig(text=text, user=user, date=date, match=match,
368 267 force=force, editor=editor, extra=extra)
369 268 return result
@@ -381,6 +280,8 b' def reposetup(ui, repo):'
381 280 return super(lfilesrepo, self).push(remote, force=force, revs=revs,
382 281 newbranch=newbranch)
383 282
283 # TODO: _subdirlfs should be moved into "lfutil.py", because
284 # it is referred only from "lfutil.updatestandinsbymatch"
384 285 def _subdirlfs(self, files, lfiles):
385 286 '''
386 287 Adjust matched file list
General Comments 0
You need to be logged in to leave comments. Login now