diff --git a/hgext/evolve.py b/hgext/evolve.py
index 2da5af3dadebd2f8cdab6fdfb8b40f38f03cc4d2_aGdleHQvZXZvbHZlLnB5..6c6bb7a23bb5125bf06da73265f039dd3447dafa_aGdleHQvZXZvbHZlLnB5 100644
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -195,6 +195,24 @@
         raise
 
 
+def stabilizableunstable(repo, pctx):
+    """Return a changectx for an unstable changeset which can be
+    stabilized on top of pctx or one of its descendants. None if none
+    can be found.
+    """
+    def selfanddescendants(repo, pctx):
+        yield pctx
+        for ctx in pctx.descendants():
+            yield ctx
+
+    # Look for an unstable which can be stabilized as a child of
+    # node. The unstable must be a child of one of node predecessors.
+    for ctx in selfanddescendants(repo, pctx):
+        unstables = list(repo.set('unstable() and children(obsancestors(%d))',
+                                  ctx.rev()))
+        if unstables:
+            return unstables[0]
+    return None
 
 ### new command
 #############################
@@ -208,5 +226,5 @@
     ],
     '')
 def stabilize(ui, repo, **opts):
-    """move changeset out of the unstable state
+    """rebase an unstable changeset to make it stable again
 
@@ -212,6 +230,12 @@
 
-    By default only works on changeset that will be rebase on ancestors of the
-    current working directory parent (included)"""
+    By default, take the first unstable changeset which could be
+    rebased as child of the working directory parent revision or one
+    of its descendants and rebase it.
+
+    With --any, stabilize any unstable changeset.
+
+    The working directory is updated to the rebased revision.
+    """
 
     obsolete = extensions.find('obsolete')
 
@@ -215,14 +239,11 @@
 
     obsolete = extensions.find('obsolete')
 
-    if opts['any']:
-        rvstargets = 'unstable()'
-    else:
-        rvstargets = 'unstable() and ((suspended() and obsancestors(::.))::)'
-
-    unstable = list(repo.set(rvstargets))
-    if not unstable:
-        unstable = opts['any'] and () or list(repo.set('unstable()'))
-        if unstable:
+    node = None
+    if not opts['any']:
+        node = stabilizableunstable(repo, repo['.'])
+    if node is None:
+        unstables = list(repo.set('unstable()'))
+        if unstables and not opts['any']:
             ui.write_err(_('nothing to stabilize here\n'))
             ui.status(_('(%i unstable changesets, do you want --any ?)\n')
@@ -227,4 +248,4 @@
             ui.write_err(_('nothing to stabilize here\n'))
             ui.status(_('(%i unstable changesets, do you want --any ?)\n')
-                      % len(unstable))
+                      % len(unstables))
             return 2
@@ -230,4 +251,4 @@
             return 2
-        else:
+        elif not unstables:
             ui.write_err(_('no unstable changeset\n'))
             return 1
@@ -232,6 +253,7 @@
             ui.write_err(_('no unstable changeset\n'))
             return 1
-    node = unstable[0]
+        node = unstables[0]
+
     obs = node.parents()[0]
     if not obs.obsolete():
         obs = node.parents()[1]
diff --git a/tests/test-evolve.t b/tests/test-evolve.t
index 2da5af3dadebd2f8cdab6fdfb8b40f38f03cc4d2_dGVzdHMvdGVzdC1ldm9sdmUudA==..6c6bb7a23bb5125bf06da73265f039dd3447dafa_dGVzdHMvdGVzdC1ldm9sdmUudA== 100644
--- a/tests/test-evolve.t
+++ b/tests/test-evolve.t
@@ -211,19 +211,6 @@
   0	: base - test
   $ hg up -q 1
   Working directory parent is obsolete
-  $ hg stabilize -n
-  nothing to stabilize here
-  (1 unstable changesets, do you want --any ?)
-  [2]
-  $ hg stabilize -n --any
-  move:[4] another feature
-  atop:[6] a nifty feature
-  hg rebase -Dr f8111a076f09 -d 23409eba69a0
-  $ hg up -q 6
-  $ hg stabilize -n
-  move:[4] another feature
-  atop:[6] a nifty feature
-  hg rebase -Dr f8111a076f09 -d 23409eba69a0
   $ hg stabilize
   move:[4] another feature
   atop:[6] a nifty feature
diff --git a/tests/test-stabilize-order.t b/tests/test-stabilize-order.t
new file mode 100644
index 0000000000000000000000000000000000000000..6c6bb7a23bb5125bf06da73265f039dd3447dafa_dGVzdHMvdGVzdC1zdGFiaWxpemUtb3JkZXIudA==
--- /dev/null
+++ b/tests/test-stabilize-order.t
@@ -0,0 +1,158 @@
+  $ cat >> $HGRCPATH <<EOF
+  > [defaults]
+  > amend=-d "0 0"
+  > [extensions]
+  > hgext.rebase=
+  > hgext.graphlog=
+  > EOF
+  $ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext/obsolete.py" >> $HGRCPATH
+  $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext/evolve.py" >> $HGRCPATH
+
+  $ glog() {
+  >   hg glog --template '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
+  > }
+
+  $ hg init repo
+  $ cd repo
+  $ echo root > root
+  $ hg ci -Am addroot
+  adding root
+  $ echo a > a
+  $ hg ci -Am adda
+  adding a
+  $ echo b > b
+  $ hg ci -Am addb
+  adding b
+  $ echo c > c
+  $ hg ci -Am addc
+  adding c
+  $ glog
+  @  3:7a7552255fb5@default(draft) addc
+  |
+  o  2:ef23d6ef94d6@default(draft) addb
+  |
+  o  1:93418d2c0979@default(draft) adda
+  |
+  o  0:c471ef929e6a@default(draft) addroot
+  
+  $ hg gdown
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [2] addb
+  $ echo b >> b
+  $ hg amend
+  1 new unstables changesets
+  $ hg gdown
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  [1] adda
+  $ echo a >> a
+  $ hg amend
+  1 new unstables changesets
+  $ glog
+  @  7:f5ff10856e5a@default(draft) adda
+  |
+  | o  5:ab8cbb6d87ff@default(draft) addb
+  | |
+  | | o  3:7a7552255fb5@default(draft) addc
+  | | |
+  | | o  2:ef23d6ef94d6@default(draft) addb
+  | |/
+  | o  1:93418d2c0979@default(draft) adda
+  |/
+  o  0:c471ef929e6a@default(draft) addroot
+  
+
+Test stabilizing a predecessor child
+
+  $ hg stabilize -v
+  move:[5] addb
+  atop:[7] adda
+  hg rebase -Dr ab8cbb6d87ff -d f5ff10856e5a
+  resolving manifests
+  getting b
+  b
+  $ glog
+  @  8:6bf44048e43f@default(draft) addb
+  |
+  o  7:f5ff10856e5a@default(draft) adda
+  |
+  | o  3:7a7552255fb5@default(draft) addc
+  | |
+  | o  2:ef23d6ef94d6@default(draft) addb
+  | |
+  | o  1:93418d2c0979@default(draft) adda
+  |/
+  o  0:c471ef929e6a@default(draft) addroot
+  
+
+Test stabilizing a descendant predecessors child
+
+  $ hg up 7
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg stabilize -v
+  move:[3] addc
+  atop:[8] addb
+  hg rebase -Dr 7a7552255fb5 -d 6bf44048e43f
+  resolving manifests
+  getting b
+  resolving manifests
+  getting c
+  c
+  $ glog
+  @  9:5e819fbb0d27@default(draft) addc
+  |
+  o  8:6bf44048e43f@default(draft) addb
+  |
+  o  7:f5ff10856e5a@default(draft) adda
+  |
+  o  0:c471ef929e6a@default(draft) addroot
+  
+  $ hg stabilize -v
+  no unstable changeset
+  [1]
+
+Test behaviour with --any
+
+  $ hg up 8
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo b >> b
+  $ hg amend
+  1 new unstables changesets
+  $ glog
+  @  11:4e7cec6b4afe@default(draft) addb
+  |
+  | o  9:5e819fbb0d27@default(draft) addc
+  | |
+  | o  8:6bf44048e43f@default(draft) addb
+  |/
+  o  7:f5ff10856e5a@default(draft) adda
+  |
+  o  0:c471ef929e6a@default(draft) addroot
+  
+  $ hg up 9
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg stabilize -v
+  nothing to stabilize here
+  (1 unstable changesets, do you want --any ?)
+  [2]
+  $ hg stabilize --any -v
+  move:[9] addc
+  atop:[11] addb
+  hg rebase -Dr 5e819fbb0d27 -d 4e7cec6b4afe
+  resolving manifests
+  removing c
+  getting b
+  resolving manifests
+  getting c
+  c
+  $ glog
+  @  12:24f95816bb21@default(draft) addc
+  |
+  o  11:4e7cec6b4afe@default(draft) addb
+  |
+  o  7:f5ff10856e5a@default(draft) adda
+  |
+  o  0:c471ef929e6a@default(draft) addroot
+  
+  $ hg stabilize --any -v
+  no unstable changeset
+  [1]