223 def buildstate(orig, repo, dest, rebaseset, *ags, **kws): |
223 def buildstate(orig, repo, dest, rebaseset, *ags, **kws): |
224 """wrapper for rebase 's buildstate that exclude obsolete changeset""" |
224 """wrapper for rebase 's buildstate that exclude obsolete changeset""" |
225 rebaseset = repo.revs('%ld - extinct()', rebaseset) |
225 rebaseset = repo.revs('%ld - extinct()', rebaseset) |
226 return orig(repo, dest, rebaseset, *ags, **kws) |
226 return orig(repo, dest, rebaseset, *ags, **kws) |
227 |
227 |
228 |
228 def defineparents(orig, repo, rev, target, state, *args, **kwargs): |
229 def concludenode(orig, repo, rev, *args, **kwargs): |
229 rebasestate = getattr(repo, '_rebasestate', None) |
|
230 if rebasestate is not None: |
|
231 repo._rebasestate = dict(state) |
|
232 repo._rebasetarget = target |
|
233 return orig(repo, rev, target, state, *args, **kwargs) |
|
234 |
|
235 def concludenode(orig, repo, rev, p1, *args, **kwargs): |
230 """wrapper for rebase 's concludenode that set obsolete relation""" |
236 """wrapper for rebase 's concludenode that set obsolete relation""" |
231 newrev = orig(repo, rev, *args, **kwargs) |
237 newrev = orig(repo, rev, p1, *args, **kwargs) |
232 oldnode = repo[rev].node() |
238 rebasestate = getattr(repo, '_rebasestate', None) |
233 if newrev is not None: |
239 if rebasestate is not None: |
234 newnode = repo[newrev].node() |
240 if newrev is not None: |
235 else: |
241 nrev = repo[newrev].rev() |
236 # Revision was emptied and removed, there is no successor. |
242 else: |
237 newnode = nullid |
243 nrev = p1 |
238 repo.addobsolete(newnode, oldnode) |
244 repo._rebasestate[rev] = nrev |
239 return newrev |
245 return newrev |
240 |
246 |
241 def cmdrebase(orig, ui, repo, *args, **kwargs): |
247 def cmdrebase(orig, ui, repo, *args, **kwargs): |
242 if kwargs.get('keep', False): |
248 if kwargs.get('keep', False): |
243 raise util.Abort(_('rebase --keep option is unsupported with obsolete ' |
249 raise util.Abort(_('rebase --keep option is unsupported with obsolete ' |
244 'extension'), hint=_("see 'hg help obsolete'")) |
250 'extension'), hint=_("see 'hg help obsolete'")) |
245 kwargs = dict(kwargs) |
251 kwargs = dict(kwargs) |
246 kwargs['keep'] = True |
252 kwargs['keep'] = True |
247 return orig(ui, repo, *args, **kwargs) |
253 |
248 |
254 # We want to mark rebased revision as obsolete and set their |
|
255 # replacements if any. Doing it in concludenode() prevents |
|
256 # aborting the rebase, and is not called with all relevant |
|
257 # revisions in --collapse case. Instead, we try to track the |
|
258 # rebase state structure by sampling/updating it in |
|
259 # defineparents() and concludenode(). The obsolete markers are |
|
260 # added from this state after a successful call. |
|
261 repo._rebasestate = {} |
|
262 repo._rebasetarget = None |
|
263 maxrev = len(repo) - 1 |
|
264 try: |
|
265 res = orig(ui, repo, *args, **kwargs) |
|
266 if not res and not kwargs.get('abort') and repo._rebasetarget: |
|
267 # We have to tell rewritten revisions from removed |
|
268 # ones. When collapsing, removed revisions are considered |
|
269 # to be collapsed onto the final one, while in the normal |
|
270 # case their are marked obsolete without successor. |
|
271 emptynode = nullid |
|
272 if kwargs.get('collapse'): |
|
273 emptynode = repo[max(repo._rebasestate.values())].node() |
|
274 # Rebased revisions are assumed to be descendants of |
|
275 # targetrev. If a source revision is mapped to targetrev |
|
276 # or to another rebased revision, it must have been |
|
277 # removed. |
|
278 targetrev = repo[repo._rebasetarget].rev() |
|
279 newrevs = set([targetrev]) |
|
280 for rev, newrev in sorted(repo._rebasestate.items()): |
|
281 oldnode = repo[rev].node() |
|
282 if newrev not in newrevs and newrev >= 0: |
|
283 newnode = repo[newrev].node() |
|
284 newrevs.add(newrev) |
|
285 else: |
|
286 newnode = emptynode |
|
287 repo.addobsolete(newnode, oldnode) |
|
288 return res |
|
289 finally: |
|
290 delattr(repo, '_rebasestate') |
|
291 delattr(repo, '_rebasetarget') |
249 |
292 |
250 |
293 |
251 def extsetup(ui): |
294 def extsetup(ui): |
252 |
295 |
253 revset.symbols["obsolete"] = revsetobsolete |
296 revset.symbols["obsolete"] = revsetobsolete |