mercurial/phases.py
changeset 51580 b70628a9aa7e
parent 51579 87655e6dc108
child 51581 e0194b3ea312
equal deleted inserted replaced
51579:87655e6dc108 51580:b70628a9aa7e
   107 import weakref
   107 import weakref
   108 
   108 
   109 from typing import (
   109 from typing import (
   110     Any,
   110     Any,
   111     Callable,
   111     Callable,
       
   112     Collection,
   112     Dict,
   113     Dict,
   113     Iterable,
   114     Iterable,
   114     List,
   115     List,
   115     Optional,
   116     Optional,
   116     Set,
   117     Set,
   125     short,
   126     short,
   126     wdirrev,
   127     wdirrev,
   127 )
   128 )
   128 from . import (
   129 from . import (
   129     error,
   130     error,
   130     pycompat,
       
   131     requirements,
   131     requirements,
   132     smartset,
   132     smartset,
   133     txnutil,
   133     txnutil,
   134     util,
   134     util,
   135 )
   135 )
  1123                 draft_roots.append(rev)
  1123                 draft_roots.append(rev)
  1124         else:
  1124         else:
  1125             msg = _(b'ignoring unexpected root from remote: %i %s\n')
  1125             msg = _(b'ignoring unexpected root from remote: %i %s\n')
  1126             repo.ui.warn(msg % (phase, nhex))
  1126             repo.ui.warn(msg % (phase, nhex))
  1127     # compute heads
  1127     # compute heads
       
  1128     subset_revs = [to_rev(n) for n in subset]
       
  1129     public_heads = new_heads(repo, subset_revs, draft_roots)
  1128     draft_nodes = [to_node(r) for r in draft_roots]
  1130     draft_nodes = [to_node(r) for r in draft_roots]
  1129     publicheads = newheads(repo, subset, draft_nodes)
  1131     public_nodes = [to_node(r) for r in public_heads]
  1130     return publicheads, draft_nodes
  1132     return public_nodes, draft_nodes
  1131 
  1133 
  1132 
  1134 
  1133 class remotephasessummary:
  1135 class remotephasessummary:
  1134     """summarize phase information on the remote side
  1136     """summarize phase information on the remote side
  1135 
  1137 
  1150         # Get the list of all "heads" revs draft on remote
  1152         # Get the list of all "heads" revs draft on remote
  1151         dheads = unfi.set(b'heads(%ln::%ln)', self.draftroots, remotesubset)
  1153         dheads = unfi.set(b'heads(%ln::%ln)', self.draftroots, remotesubset)
  1152         self.draftheads = [c.node() for c in dheads]
  1154         self.draftheads = [c.node() for c in dheads]
  1153 
  1155 
  1154 
  1156 
  1155 def newheads(repo, heads, roots):
  1157 def new_heads(
       
  1158     repo,
       
  1159     heads: Collection[int],
       
  1160     roots: Collection[int],
       
  1161 ) -> Collection[int]:
  1156     """compute new head of a subset minus another
  1162     """compute new head of a subset minus another
  1157 
  1163 
  1158     * `heads`: define the first subset
  1164     * `heads`: define the first subset
  1159     * `roots`: define the second we subtract from the first"""
  1165     * `roots`: define the second we subtract from the first"""
  1160     # prevent an import cycle
  1166     # prevent an import cycle
  1161     # phases > dagop > patch > copies > scmutil > obsolete > obsutil > phases
  1167     # phases > dagop > patch > copies > scmutil > obsolete > obsutil > phases
  1162     from . import dagop
  1168     from . import dagop
  1163 
  1169 
  1164     repo = repo.unfiltered()
       
  1165     cl = repo.changelog
       
  1166     rev = cl.index.get_rev
       
  1167     if not roots:
  1170     if not roots:
  1168         return heads
  1171         return heads
  1169     if not heads or heads == [repo.nullid]:
  1172     if not heads or heads == [nullrev]:
  1170         return []
  1173         return []
  1171     # The logic operated on revisions, convert arguments early for convenience
  1174     # The logic operated on revisions, convert arguments early for convenience
  1172     new_heads = {rev(n) for n in heads if n != repo.nullid}
  1175     # PERF-XXX: maybe heads could directly comes as a set without impacting
  1173     roots = [rev(n) for n in roots]
  1176     # other user of that value
       
  1177     new_heads = set(heads)
       
  1178     new_heads.discard(nullrev)
  1174     # compute the area we need to remove
  1179     # compute the area we need to remove
  1175     affected_zone = repo.revs(b"(%ld::%ld)", roots, new_heads)
  1180     affected_zone = repo.revs(b"(%ld::%ld)", roots, new_heads)
  1176     # heads in the area are no longer heads
  1181     # heads in the area are no longer heads
  1177     new_heads.difference_update(affected_zone)
  1182     new_heads.difference_update(affected_zone)
  1178     # revisions in the area have children outside of it,
  1183     # revisions in the area have children outside of it,
  1186         new_heads.update(candidates)
  1191         new_heads.update(candidates)
  1187         prunestart = repo.revs(b"parents(%ld) and not null", new_heads)
  1192         prunestart = repo.revs(b"parents(%ld) and not null", new_heads)
  1188         pruned = dagop.reachableroots(repo, candidates, prunestart)
  1193         pruned = dagop.reachableroots(repo, candidates, prunestart)
  1189         new_heads.difference_update(pruned)
  1194         new_heads.difference_update(pruned)
  1190 
  1195 
  1191     return pycompat.maplist(cl.node, sorted(new_heads))
  1196     # PERF-XXX: do we actually need a sorted list here? Could we simply return
       
  1197     # a set?
       
  1198     return sorted(new_heads)
  1192 
  1199 
  1193 
  1200 
  1194 def newcommitphase(ui: "uimod.ui") -> int:
  1201 def newcommitphase(ui: "uimod.ui") -> int:
  1195     """helper to get the target phase of new commit
  1202     """helper to get the target phase of new commit
  1196 
  1203