193 # Invalidate the previous setparents |
193 # Invalidate the previous setparents |
194 repo.dirstate.invalidate() |
194 repo.dirstate.invalidate() |
195 raise |
195 raise |
196 |
196 |
197 |
197 |
|
198 def stabilizableunstable(repo, pctx): |
|
199 """Return a changectx for an unstable changeset which can be |
|
200 stabilized on top of pctx or one of its descendants. None if none |
|
201 can be found. |
|
202 """ |
|
203 def selfanddescendants(repo, pctx): |
|
204 yield pctx |
|
205 for ctx in pctx.descendants(): |
|
206 yield ctx |
|
207 |
|
208 # Look for an unstable which can be stabilized as a child of |
|
209 # node. The unstable must be a child of one of node predecessors. |
|
210 for ctx in selfanddescendants(repo, pctx): |
|
211 unstables = list(repo.set('unstable() and children(obsancestors(%d))', |
|
212 ctx.rev())) |
|
213 if unstables: |
|
214 return unstables[0] |
|
215 return None |
198 |
216 |
199 ### new command |
217 ### new command |
200 ############################# |
218 ############################# |
201 cmdtable = {} |
219 cmdtable = {} |
202 command = cmdutil.command(cmdtable) |
220 command = cmdutil.command(cmdtable) |
206 ('n', 'dry-run', False, 'Do nothing but printing what should be done'), |
224 ('n', 'dry-run', False, 'Do nothing but printing what should be done'), |
207 ('A', 'any', False, 'Stabilize unstable change on any topological branch'), |
225 ('A', 'any', False, 'Stabilize unstable change on any topological branch'), |
208 ], |
226 ], |
209 '') |
227 '') |
210 def stabilize(ui, repo, **opts): |
228 def stabilize(ui, repo, **opts): |
211 """move changeset out of the unstable state |
229 """rebase an unstable changeset to make it stable again |
212 |
230 |
213 By default only works on changeset that will be rebase on ancestors of the |
231 By default, take the first unstable changeset which could be |
214 current working directory parent (included)""" |
232 rebased as child of the working directory parent revision or one |
|
233 of its descendants and rebase it. |
|
234 |
|
235 With --any, stabilize any unstable changeset. |
|
236 |
|
237 The working directory is updated to the rebased revision. |
|
238 """ |
215 |
239 |
216 obsolete = extensions.find('obsolete') |
240 obsolete = extensions.find('obsolete') |
217 |
241 |
218 if opts['any']: |
242 node = None |
219 rvstargets = 'unstable()' |
243 if not opts['any']: |
220 else: |
244 node = stabilizableunstable(repo, repo['.']) |
221 rvstargets = 'unstable() and ((suspended() and obsancestors(::.))::)' |
245 if node is None: |
222 |
246 unstables = list(repo.set('unstable()')) |
223 unstable = list(repo.set(rvstargets)) |
247 if unstables and not opts['any']: |
224 if not unstable: |
|
225 unstable = opts['any'] and () or list(repo.set('unstable()')) |
|
226 if unstable: |
|
227 ui.write_err(_('nothing to stabilize here\n')) |
248 ui.write_err(_('nothing to stabilize here\n')) |
228 ui.status(_('(%i unstable changesets, do you want --any ?)\n') |
249 ui.status(_('(%i unstable changesets, do you want --any ?)\n') |
229 % len(unstable)) |
250 % len(unstables)) |
230 return 2 |
251 return 2 |
231 else: |
252 elif not unstables: |
232 ui.write_err(_('no unstable changeset\n')) |
253 ui.write_err(_('no unstable changeset\n')) |
233 return 1 |
254 return 1 |
234 node = unstable[0] |
255 node = unstables[0] |
|
256 |
235 obs = node.parents()[0] |
257 obs = node.parents()[0] |
236 if not obs.obsolete(): |
258 if not obs.obsolete(): |
237 obs = node.parents()[1] |
259 obs = node.parents()[1] |
238 assert obs.obsolete() |
260 assert obs.obsolete() |
239 newer = obsolete.newerversion(repo, obs.node()) |
261 newer = obsolete.newerversion(repo, obs.node()) |