hgext/sparse.py
changeset 33324 33d0859c37bd
parent 33323 252500520d60
child 33353 160efb559f67
equal deleted inserted replaced
33323:252500520d60 33324:33d0859c37bd
    84     error,
    84     error,
    85     extensions,
    85     extensions,
    86     hg,
    86     hg,
    87     localrepo,
    87     localrepo,
    88     match as matchmod,
    88     match as matchmod,
    89     merge as mergemod,
       
    90     registrar,
    89     registrar,
    91     sparse,
    90     sparse,
    92     util,
    91     util,
    93 )
    92 )
    94 
    93 
   147 
   146 
   148         # profiles will only have data if sparse is enabled.
   147         # profiles will only have data if sparse is enabled.
   149         if set(profiles) & set(ctx.files()):
   148         if set(profiles) & set(ctx.files()):
   150             origstatus = repo.status()
   149             origstatus = repo.status()
   151             origsparsematch = sparse.matcher(repo)
   150             origsparsematch = sparse.matcher(repo)
   152             _refresh(repo.ui, repo, origstatus, origsparsematch, True)
   151             sparse.refreshwdir(repo, origstatus, origsparsematch, force=True)
   153 
   152 
   154         sparse.prunetemporaryincludes(repo)
   153         sparse.prunetemporaryincludes(repo)
   155 
   154 
   156     extensions.wrapfunction(context.committablectx, 'markcommitted',
   155     extensions.wrapfunction(context.committablectx, 'markcommitted',
   157         _refreshoncommit)
   156         _refreshoncommit)
   396     if refresh:
   395     if refresh:
   397         try:
   396         try:
   398             wlock = repo.wlock()
   397             wlock = repo.wlock()
   399             fcounts = map(
   398             fcounts = map(
   400                 len,
   399                 len,
   401                 _refresh(ui, repo, repo.status(), sparse.matcher(repo), force))
   400                 sparse.refreshwdir(repo, repo.status(), sparse.matcher(repo),
       
   401                                    force=force))
   402             _verbose_output(ui, opts, 0, 0, 0, *fcounts)
   402             _verbose_output(ui, opts, 0, 0, 0, *fcounts)
   403         finally:
   403         finally:
   404             wlock.release()
   404             wlock.release()
   405 
   405 
   406 def _config(ui, repo, pats, opts, include=False, exclude=False, reset=False,
   406 def _config(ui, repo, pats, opts, include=False, exclude=False, reset=False,
   450                 newexclude.difference_update(pats)
   450                 newexclude.difference_update(pats)
   451 
   451 
   452             sparse.writeconfig(repo, newinclude, newexclude, newprofiles)
   452             sparse.writeconfig(repo, newinclude, newexclude, newprofiles)
   453 
   453 
   454             fcounts = map(
   454             fcounts = map(
   455                 len, _refresh(ui, repo, oldstatus, oldsparsematch, force))
   455                 len,
       
   456                 sparse.refreshwdir(repo, oldstatus, oldsparsematch,
       
   457                                    force=force))
   456 
   458 
   457             profilecount = (len(newprofiles - oldprofiles) -
   459             profilecount = (len(newprofiles - oldprofiles) -
   458                             len(oldprofiles - newprofiles))
   460                             len(oldprofiles - newprofiles))
   459             includecount = (len(newinclude - oldinclude) -
   461             includecount = (len(newinclude - oldinclude) -
   460                             len(oldinclude - newinclude))
   462                             len(oldinclude - newinclude))
   514             oldsparsematch = sparse.matcher(repo)
   516             oldsparsematch = sparse.matcher(repo)
   515             sparse.writeconfig(repo, includes, excludes, profiles)
   517             sparse.writeconfig(repo, includes, excludes, profiles)
   516 
   518 
   517             try:
   519             try:
   518                 fcounts = map(
   520                 fcounts = map(
   519                     len, _refresh(ui, repo, oldstatus, oldsparsematch, force))
   521                     len,
       
   522                     sparse.refreshwdir(repo, oldstatus, oldsparsematch,
       
   523                                        force=force))
   520             except Exception:
   524             except Exception:
   521                 sparse.writeconfig(repo, oincludes, oexcludes, oprofiles)
   525                 sparse.writeconfig(repo, oincludes, oexcludes, oprofiles)
   522                 raise
   526                 raise
   523 
   527 
   524         _verbose_output(ui, opts, profilecount, includecount, excludecount,
   528         _verbose_output(ui, opts, profilecount, includecount, excludecount,
   531 
   535 
   532         if includes or excludes:
   536         if includes or excludes:
   533             oldstatus = repo.status()
   537             oldstatus = repo.status()
   534             oldsparsematch = sparse.matcher(repo)
   538             oldsparsematch = sparse.matcher(repo)
   535             sparse.writeconfig(repo, set(), set(), profiles)
   539             sparse.writeconfig(repo, set(), set(), profiles)
   536             _refresh(ui, repo, oldstatus, oldsparsematch, force)
   540             sparse.refreshwdir(repo, oldstatus, oldsparsematch, force)
   537 
       
   538 def _refresh(ui, repo, origstatus, origsparsematch, force):
       
   539     """Refreshes which files are on disk by comparing the old status and
       
   540     sparsematch with the new sparsematch.
       
   541 
       
   542     Will raise an exception if a file with pending changes is being excluded
       
   543     or included (unless force=True).
       
   544     """
       
   545     modified, added, removed, deleted, unknown, ignored, clean = origstatus
       
   546 
       
   547     # Verify there are no pending changes
       
   548     pending = set()
       
   549     pending.update(modified)
       
   550     pending.update(added)
       
   551     pending.update(removed)
       
   552     sparsematch = sparse.matcher(repo)
       
   553     abort = False
       
   554     for file in pending:
       
   555         if not sparsematch(file):
       
   556             ui.warn(_("pending changes to '%s'\n") % file)
       
   557             abort = not force
       
   558     if abort:
       
   559         raise error.Abort(_("could not update sparseness due to " +
       
   560             "pending changes"))
       
   561 
       
   562     # Calculate actions
       
   563     dirstate = repo.dirstate
       
   564     ctx = repo['.']
       
   565     added = []
       
   566     lookup = []
       
   567     dropped = []
       
   568     mf = ctx.manifest()
       
   569     files = set(mf)
       
   570 
       
   571     actions = {}
       
   572 
       
   573     for file in files:
       
   574         old = origsparsematch(file)
       
   575         new = sparsematch(file)
       
   576         # Add files that are newly included, or that don't exist in
       
   577         # the dirstate yet.
       
   578         if (new and not old) or (old and new and not file in dirstate):
       
   579             fl = mf.flags(file)
       
   580             if repo.wvfs.exists(file):
       
   581                 actions[file] = ('e', (fl,), '')
       
   582                 lookup.append(file)
       
   583             else:
       
   584                 actions[file] = ('g', (fl, False), '')
       
   585                 added.append(file)
       
   586         # Drop files that are newly excluded, or that still exist in
       
   587         # the dirstate.
       
   588         elif (old and not new) or (not old and not new and file in dirstate):
       
   589             dropped.append(file)
       
   590             if file not in pending:
       
   591                 actions[file] = ('r', [], '')
       
   592 
       
   593     # Verify there are no pending changes in newly included files
       
   594     abort = False
       
   595     for file in lookup:
       
   596         ui.warn(_("pending changes to '%s'\n") % file)
       
   597         abort = not force
       
   598     if abort:
       
   599         raise error.Abort(_("cannot change sparseness due to " +
       
   600             "pending changes (delete the files or use --force " +
       
   601             "to bring them back dirty)"))
       
   602 
       
   603     # Check for files that were only in the dirstate.
       
   604     for file, state in dirstate.iteritems():
       
   605         if not file in files:
       
   606             old = origsparsematch(file)
       
   607             new = sparsematch(file)
       
   608             if old and not new:
       
   609                 dropped.append(file)
       
   610 
       
   611     # Apply changes to disk
       
   612     typeactions = dict((m, []) for m in 'a f g am cd dc r dm dg m e k'.split())
       
   613     for f, (m, args, msg) in actions.iteritems():
       
   614         if m not in typeactions:
       
   615             typeactions[m] = []
       
   616         typeactions[m].append((f, args, msg))
       
   617     mergemod.applyupdates(repo, typeactions, repo[None], repo['.'], False)
       
   618 
       
   619     # Fix dirstate
       
   620     for file in added:
       
   621         dirstate.normal(file)
       
   622 
       
   623     for file in dropped:
       
   624         dirstate.drop(file)
       
   625 
       
   626     for file in lookup:
       
   627         # File exists on disk, and we're bringing it back in an unknown state.
       
   628         dirstate.normallookup(file)
       
   629 
       
   630     return added, dropped, lookup
       
   631 
   541 
   632 def _verbose_output(ui, opts, profilecount, includecount, excludecount, added,
   542 def _verbose_output(ui, opts, profilecount, includecount, excludecount, added,
   633                     dropped, lookup):
   543                     dropped, lookup):
   634     """Produce --verbose and templatable output
   544     """Produce --verbose and templatable output
   635 
   545