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