265 res = orig(ui, repo, *args, **kwargs) |
265 res = orig(ui, repo, *args, **kwargs) |
266 # Filter nullmerge or unrebased entries |
266 # Filter nullmerge or unrebased entries |
267 repo._rebasestate = dict(p for p in repo._rebasestate.iteritems() |
267 repo._rebasestate = dict(p for p in repo._rebasestate.iteritems() |
268 if p[1] >= 0) |
268 if p[1] >= 0) |
269 if not res and not kwargs.get('abort') and repo._rebasestate: |
269 if not res and not kwargs.get('abort') and repo._rebasestate: |
270 # We have to tell rewritten revisions from removed |
|
271 # ones. When collapsing, removed revisions are considered |
|
272 # to be collapsed onto the final one, while in the normal |
|
273 # case their are marked obsolete without successor. |
|
274 emptynode = nullid |
|
275 if kwargs.get('collapse'): |
|
276 emptynode = repo[max(repo._rebasestate.values())].node() |
|
277 # Rebased revisions are assumed to be descendants of |
270 # Rebased revisions are assumed to be descendants of |
278 # targetrev. If a source revision is mapped to targetrev |
271 # targetrev. If a source revision is mapped to targetrev |
279 # or to another rebased revision, it must have been |
272 # or to another rebased revision, it must have been |
280 # removed. |
273 # removed. |
281 targetrev = repo[repo._rebasetarget].rev() |
274 targetrev = repo[repo._rebasetarget].rev() |
282 newrevs = set([targetrev]) |
275 newrevs = set([targetrev]) |
|
276 replacements = {} |
283 for rev, newrev in sorted(repo._rebasestate.items()): |
277 for rev, newrev in sorted(repo._rebasestate.items()): |
284 oldnode = repo[rev].node() |
278 oldnode = repo[rev].node() |
285 if newrev not in newrevs: |
279 if newrev not in newrevs: |
286 newnode = repo[newrev].node() |
280 newnode = repo[newrev].node() |
287 newrevs.add(newrev) |
281 newrevs.add(newrev) |
288 else: |
282 else: |
289 newnode = emptynode |
283 newnode = nullid |
290 repo.addobsolete(newnode, oldnode) |
284 replacements[oldnode] = newnode |
|
285 |
|
286 if kwargs.get('collapse'): |
|
287 newnodes = set(n for n in replacements.values() if n != nullid) |
|
288 if newnodes: |
|
289 # Collapsing into more than one revision? |
|
290 assert len(newnodes) == 1, newnodes |
|
291 newnode = newnodes.pop() |
|
292 else: |
|
293 newnode = nullid |
|
294 repo.addcollapsedobsolete(replacements, newnode) |
|
295 else: |
|
296 for oldnode, newnode in replacements.iteritems(): |
|
297 repo.addobsolete(newnode, oldnode) |
291 return res |
298 return res |
292 finally: |
299 finally: |
293 delattr(repo, '_rebasestate') |
300 delattr(repo, '_rebasestate') |
294 delattr(repo, '_rebasetarget') |
301 delattr(repo, '_rebasetarget') |
295 |
302 |
811 self._turn_extinct_secret() |
818 self._turn_extinct_secret() |
812 return mid |
819 return mid |
813 finally: |
820 finally: |
814 lock.release() |
821 lock.release() |
815 |
822 |
|
823 def addcollapsedobsolete(self, oldnodes, newnode): |
|
824 """Mark oldnodes as collapsed into newnode.""" |
|
825 # Assume oldnodes are all descendants of a single rev |
|
826 rootrevs = self.revs('roots(%ln)', oldnodes) |
|
827 assert len(rootrevs) == 1, rootrevs |
|
828 rootnode = self[rootrevs[0]].node() |
|
829 for n in oldnodes: |
|
830 if n != rootnode: |
|
831 self.addobsolete(n, rootnode) |
|
832 self.addobsolete(newnode, n) |
|
833 |
816 def _turn_extinct_secret(self): |
834 def _turn_extinct_secret(self): |
817 """ensure all extinct changeset are secret""" |
835 """ensure all extinct changeset are secret""" |
818 self._clearobsoletecache() |
836 self._clearobsoletecache() |
819 # this is mainly for safety purpose |
837 # this is mainly for safety purpose |
820 # both pull and push |
838 # both pull and push |