##// END OF EJS Templates
phases: sparsify phase lists...
Joerg Sonnenberger -
r45677:b1e51ef4 default
parent child Browse files
Show More
@@ -2208,7 +2208,7 b' def handlecheckphases(op, inpart):'
2208 b'remote repository changed while pushing - please try again '
2208 b'remote repository changed while pushing - please try again '
2209 b'(%s is %s expected %s)'
2209 b'(%s is %s expected %s)'
2210 )
2210 )
2211 for expectedphase, nodes in enumerate(phasetonodes):
2211 for expectedphase, nodes in pycompat.iteritems(phasetonodes):
2212 for n in nodes:
2212 for n in nodes:
2213 actualphase = phasecache.phase(unfi, cl.rev(n))
2213 actualphase = phasecache.phase(unfi, cl.rev(n))
2214 if actualphase != expectedphase:
2214 if actualphase != expectedphase:
@@ -1024,12 +1024,12 b' def _pushb2checkphases(pushop, bundler):'
1024 hasphaseheads = b'heads' in b2caps.get(b'phases', ())
1024 hasphaseheads = b'heads' in b2caps.get(b'phases', ())
1025 if pushop.remotephases is not None and hasphaseheads:
1025 if pushop.remotephases is not None and hasphaseheads:
1026 # check that the remote phase has not changed
1026 # check that the remote phase has not changed
1027 checks = [[] for p in phases.allphases]
1027 checks = {p: [] for p in phases.allphases}
1028 checks[phases.public].extend(pushop.remotephases.publicheads)
1028 checks[phases.public].extend(pushop.remotephases.publicheads)
1029 checks[phases.draft].extend(pushop.remotephases.draftroots)
1029 checks[phases.draft].extend(pushop.remotephases.draftroots)
1030 if any(checks):
1030 if any(pycompat.itervalues(checks)):
1031 for nodes in checks:
1031 for phase in checks:
1032 nodes.sort()
1032 checks[phase].sort()
1033 checkdata = phases.binaryencode(checks)
1033 checkdata = phases.binaryencode(checks)
1034 bundler.newpart(b'check:phases', data=checkdata)
1034 bundler.newpart(b'check:phases', data=checkdata)
1035
1035
@@ -1104,7 +1104,7 b' def _pushb2phaseheads(pushop, bundler):'
1104 """push phase information through a bundle2 - binary part"""
1104 """push phase information through a bundle2 - binary part"""
1105 pushop.stepsdone.add(b'phases')
1105 pushop.stepsdone.add(b'phases')
1106 if pushop.outdatedphases:
1106 if pushop.outdatedphases:
1107 updates = [[] for p in phases.allphases]
1107 updates = {p: [] for p in phases.allphases}
1108 updates[0].extend(h.node() for h in pushop.outdatedphases)
1108 updates[0].extend(h.node() for h in pushop.outdatedphases)
1109 phasedata = phases.binaryencode(updates)
1109 phasedata = phases.binaryencode(updates)
1110 bundler.newpart(b'phase-heads', data=phasedata)
1110 bundler.newpart(b'phase-heads', data=phasedata)
@@ -2658,9 +2658,9 b' def _getbundlephasespart('
2658 headsbyphase[phases.public].add(node(r))
2658 headsbyphase[phases.public].add(node(r))
2659
2659
2660 # transform data in a format used by the encoding function
2660 # transform data in a format used by the encoding function
2661 phasemapping = []
2661 phasemapping = {
2662 for phase in phases.allphases:
2662 phase: sorted(headsbyphase[phase]) for phase in phases.allphases
2663 phasemapping.append(sorted(headsbyphase[phase]))
2663 }
2664
2664
2665 # generate the actual part
2665 # generate the actual part
2666 phasedata = phases.binaryencode(phasemapping)
2666 phasedata = phases.binaryencode(phasemapping)
@@ -82,15 +82,12 b' def pull(pullop):'
82 phases.registernew(repo, tr, phases.draft, csetres[b'added'])
82 phases.registernew(repo, tr, phases.draft, csetres[b'added'])
83
83
84 # And adjust the phase of all changesets accordingly.
84 # And adjust the phase of all changesets accordingly.
85 for phase in phases.phasenames:
85 for phasenumber, phase in phases.phasenames.items():
86 if phase == b'secret' or not csetres[b'nodesbyphase'][phase]:
86 if phase == b'secret' or not csetres[b'nodesbyphase'][phase]:
87 continue
87 continue
88
88
89 phases.advanceboundary(
89 phases.advanceboundary(
90 repo,
90 repo, tr, phasenumber, csetres[b'nodesbyphase'][phase],
91 tr,
92 phases.phasenames.index(phase),
93 csetres[b'nodesbyphase'][phase],
94 )
91 )
95
92
96 # Write bookmark updates.
93 # Write bookmark updates.
@@ -361,7 +358,7 b' def _processchangesetdata(repo, tr, objs'
361 # so we can set the linkrev accordingly when manifests are added.
358 # so we can set the linkrev accordingly when manifests are added.
362 manifestnodes[cl.rev(node)] = revision.manifest
359 manifestnodes[cl.rev(node)] = revision.manifest
363
360
364 nodesbyphase = {phase: set() for phase in phases.phasenames}
361 nodesbyphase = {phase: set() for phase in phases.phasenames.values()}
365 remotebookmarks = {}
362 remotebookmarks = {}
366
363
367 # addgroup() expects a 7-tuple describing revisions. This normalizes
364 # addgroup() expects a 7-tuple describing revisions. This normalizes
@@ -128,25 +128,28 b' from . import ('
128
128
129 _fphasesentry = struct.Struct(b'>i20s')
129 _fphasesentry = struct.Struct(b'>i20s')
130
130
131 INTERNAL_FLAG = 64 # Phases for mercurial internal usage only
132 HIDEABLE_FLAG = 32 # Phases that are hideable
133
134 # record phase index
131 # record phase index
135 public, draft, secret = range(3)
132 public, draft, secret = range(3)
136 internal = INTERNAL_FLAG | HIDEABLE_FLAG
133 archived = 32 # non-continuous for compatibility
137 archived = HIDEABLE_FLAG
134 internal = 96 # non-continuous for compatibility
138 allphases = list(range(internal + 1))
135 allphases = (public, draft, secret, archived, internal)
139 trackedphases = allphases[1:]
136 trackedphases = (draft, secret, archived, internal)
140 # record phase names
137 # record phase names
141 cmdphasenames = [b'public', b'draft', b'secret'] # known to `hg phase` command
138 cmdphasenames = [b'public', b'draft', b'secret'] # known to `hg phase` command
142 phasenames = [None] * len(allphases)
139 phasenames = dict(enumerate(cmdphasenames))
143 phasenames[: len(cmdphasenames)] = cmdphasenames
144 phasenames[archived] = b'archived'
140 phasenames[archived] = b'archived'
145 phasenames[internal] = b'internal'
141 phasenames[internal] = b'internal'
142 # map phase name to phase number
143 phasenumber = {name: phase for phase, name in phasenames.items()}
144 # like phasenumber, but also include maps for the numeric and binary
145 # phase number to the phase number
146 phasenumber2 = phasenumber.copy()
147 phasenumber2.update({phase: phase for phase in phasenames})
148 phasenumber2.update({b'%i' % phase: phase for phase in phasenames})
146 # record phase property
149 # record phase property
147 mutablephases = tuple(allphases[1:])
150 mutablephases = (draft, secret, archived, internal)
148 remotehiddenphases = tuple(allphases[2:])
151 remotehiddenphases = (secret, archived, internal)
149 localhiddenphases = tuple(p for p in allphases if p & HIDEABLE_FLAG)
152 localhiddenphases = (internal, archived)
150
153
151
154
152 def supportinternal(repo):
155 def supportinternal(repo):
@@ -167,7 +170,7 b' def _readroots(repo, phasedefaults=None)'
167 """
170 """
168 repo = repo.unfiltered()
171 repo = repo.unfiltered()
169 dirty = False
172 dirty = False
170 roots = [set() for i in allphases]
173 roots = [set() for i in range(max(allphases) + 1)]
171 try:
174 try:
172 f, pending = txnutil.trypending(repo.root, repo.svfs, b'phaseroots')
175 f, pending = txnutil.trypending(repo.root, repo.svfs, b'phaseroots')
173 try:
176 try:
@@ -189,11 +192,10 b' def _readroots(repo, phasedefaults=None)'
189 def binaryencode(phasemapping):
192 def binaryencode(phasemapping):
190 """encode a 'phase -> nodes' mapping into a binary stream
193 """encode a 'phase -> nodes' mapping into a binary stream
191
194
192 Since phases are integer the mapping is actually a python list:
195 The revision lists are encoded as (phase, root) pairs.
193 [[PUBLIC_HEADS], [DRAFTS_HEADS], [SECRET_HEADS]]
194 """
196 """
195 binarydata = []
197 binarydata = []
196 for phase, nodes in enumerate(phasemapping):
198 for phase, nodes in pycompat.iteritems(phasemapping):
197 for head in nodes:
199 for head in nodes:
198 binarydata.append(_fphasesentry.pack(phase, head))
200 binarydata.append(_fphasesentry.pack(phase, head))
199 return b''.join(binarydata)
201 return b''.join(binarydata)
@@ -202,8 +204,9 b' def binaryencode(phasemapping):'
202 def binarydecode(stream):
204 def binarydecode(stream):
203 """decode a binary stream into a 'phase -> nodes' mapping
205 """decode a binary stream into a 'phase -> nodes' mapping
204
206
205 Since phases are integer the mapping is actually a python list."""
207 The (phase, root) pairs are turned back into a dictionary with
206 headsbyphase = [[] for i in allphases]
208 the phase as index and the aggregated roots of that phase as value."""
209 headsbyphase = {i: [] for i in allphases}
207 entrysize = _fphasesentry.size
210 entrysize = _fphasesentry.size
208 while True:
211 while True:
209 entry = stream.read(entrysize)
212 entry = stream.read(entrysize)
@@ -427,12 +430,16 b' class phasecache(object):'
427 nativeroots.append(
430 nativeroots.append(
428 pycompat.maplist(repo.changelog.rev, self.phaseroots[phase])
431 pycompat.maplist(repo.changelog.rev, self.phaseroots[phase])
429 )
432 )
430 return repo.changelog.computephases(nativeroots)
433 revslen, phasesets = repo.changelog.computephases(nativeroots)
434 phasesets2 = [set() for phase in range(max(allphases) + 1)]
435 for phase, phaseset in zip(allphases, phasesets):
436 phasesets2[phase] = phaseset
437 return revslen, phasesets2
431
438
432 def _computephaserevspure(self, repo):
439 def _computephaserevspure(self, repo):
433 repo = repo.unfiltered()
440 repo = repo.unfiltered()
434 cl = repo.changelog
441 cl = repo.changelog
435 self._phasesets = [set() for phase in allphases]
442 self._phasesets = [set() for phase in range(max(allphases) + 1)]
436 lowerroots = set()
443 lowerroots = set()
437 for phase in reversed(trackedphases):
444 for phase in reversed(trackedphases):
438 roots = pycompat.maplist(cl.rev, self.phaseroots[phase])
445 roots = pycompat.maplist(cl.rev, self.phaseroots[phase])
@@ -533,7 +540,7 b' class phasecache(object):'
533
540
534 changes = set() # set of revisions to be changed
541 changes = set() # set of revisions to be changed
535 delroots = [] # set of root deleted by this path
542 delroots = [] # set of root deleted by this path
536 for phase in pycompat.xrange(targetphase + 1, len(allphases)):
543 for phase in (phase for phase in allphases if phase > targetphase):
537 # filter nodes that are not in a compatible phase already
544 # filter nodes that are not in a compatible phase already
538 nodes = [
545 nodes = [
539 n for n in nodes if self.phase(repo, repo[n].rev()) >= phase
546 n for n in nodes if self.phase(repo, repo[n].rev()) >= phase
@@ -766,7 +773,7 b' def subsetphaseheads(repo, subset):'
766 """
773 """
767 cl = repo.changelog
774 cl = repo.changelog
768
775
769 headsbyphase = [[] for i in allphases]
776 headsbyphase = {i: [] for i in allphases}
770 # No need to keep track of secret phase; any heads in the subset that
777 # No need to keep track of secret phase; any heads in the subset that
771 # are not mentioned are implicitly secret.
778 # are not mentioned are implicitly secret.
772 for phase in allphases[:secret]:
779 for phase in allphases[:secret]:
@@ -897,13 +904,11 b' def newcommitphase(ui):'
897 """
904 """
898 v = ui.config(b'phases', b'new-commit')
905 v = ui.config(b'phases', b'new-commit')
899 try:
906 try:
900 return phasenames.index(v)
907 return phasenumber2[v]
901 except ValueError:
908 except KeyError:
902 try:
909 raise error.ConfigError(
903 return int(v)
910 _(b"phases.new-commit: not a valid phase name ('%s')") % v
904 except ValueError:
911 )
905 msg = _(b"phases.new-commit: not a valid phase name ('%s')")
906 raise error.ConfigError(msg % v)
907
912
908
913
909 def hassecret(repo):
914 def hassecret(repo):
General Comments 0
You need to be logged in to leave comments. Login now