diff --git a/hgext/rebase.py b/hgext/rebase.py
index 6411140aeda98aa32d61c2f08390d036e89c8b73_aGdleHQvcmViYXNlLnB5..fac3a24be50e7c4c97757d19f725fa1342db156e_aGdleHQvcmViYXNlLnB5 100644
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -69,11 +69,12 @@
             c(ctx, extra)
     return extrafn
 
-def _destrebase(repo):
-    # Destination defaults to the latest revision in the
-    # current branch
-    branch = repo[None].branch()
-    return repo[branch].rev()
+def _destrebase(repo, sourceset):
+    """small wrapper around destmerge to pass the right extra args
+
+    Please wrap destutil.destmerge instead."""
+    return destutil.destmerge(repo, action='rebase', sourceset=sourceset,
+                              onheadcheck=False)
 
 revsetpredicate = revset.extpredicate()
 
@@ -83,5 +84,4 @@
 
     # default destination for rebase.
     # # XXX: Currently private because I expect the signature to change.
-    # # XXX: - taking rev as arguments,
     # # XXX: - bailing out in case of ambiguity vs returning all data.
@@ -87,3 +87,2 @@
     # # XXX: - bailing out in case of ambiguity vs returning all data.
-    # # XXX: - probably merging with the merge destination.
     # i18n: "_rebasedefaultdest" is a keyword
@@ -89,6 +88,8 @@
     # i18n: "_rebasedefaultdest" is a keyword
-    revset.getargs(x, 0, 0, _("_rebasedefaultdest takes no arguments"))
-    return subset & revset.baseset([_destrebase(repo)])
+    sourceset = None
+    if x is not None:
+        sourceset = revset.getset(repo, revset.fullreposet(repo), x)
+    return subset & revset.baseset([_destrebase(repo, sourceset)])
 
 @command('rebase',
     [('s', 'source', '',
@@ -127,10 +128,13 @@
     Published commits cannot be rebased (see :hg:`help phases`).
     To copy commits, see :hg:`help graft`.
 
-    If you don't specify a destination changeset (``-d/--dest``),
-    rebase uses the current branch tip as the destination. (The
-    destination changeset is not modified by rebasing, but new
-    changesets are added as its descendants.)
+    If you don't specify a destination changeset (``-d/--dest``), rebase
+    will use the same logic as :hg:`merge` to pick a destination.  if
+    the current branch contains exactly one other head, the other head
+    is merged with by default.  Otherwise, an explicit revision with
+    which to merge with must be provided.  (destination changeset is not
+    modified by rebasing, but new changesets are added as its
+    descendants.)
 
     Here are the ways to select changesets:
 
@@ -544,9 +548,6 @@
 
     if destf:
         dest = scmutil.revsingle(repo, destf)
-    else:
-        dest = repo[_destrebase(repo)]
-        destf = str(dest)
 
     if revf:
         rebaseset = scmutil.revrange(repo, revf)
@@ -566,6 +567,10 @@
             ui.status(_('empty "base" revision set - '
                         "can't compute rebase set\n"))
             return None, None
+        if not destf:
+            dest = repo[_destrebase(repo, base)]
+            destf = str(dest)
+
         commonanc = repo.revs('ancestor(%ld, %d)', base, dest).first()
         if commonanc is not None:
             rebaseset = repo.revs('(%d::(%ld) - %d)::',
@@ -599,6 +604,11 @@
                 ui.status(_('nothing to rebase from %s to %s\n') %
                           ('+'.join(str(repo[r]) for r in base), dest))
             return None, None
+
+    if not destf:
+        dest = repo[_destrebase(repo, rebaseset)]
+        destf = str(dest)
+
     return dest, rebaseset
 
 def externalparent(repo, state, targetancestors):
@@ -1198,5 +1208,8 @@
                 # --source.
                 if 'source' in opts:
                     del opts['source']
-                if rebase(ui, repo, **opts) == _nothingtorebase():
+                try:
+                    rebase(ui, repo, **opts)
+                except error.NoMergeDestAbort:
+                    # we can maybe update instead
                     rev, _a, _b = destutil.destupdate(repo)
@@ -1202,5 +1215,8 @@
                     rev, _a, _b = destutil.destupdate(repo)
-                    if rev != repo['.'].rev(): # we could update
+                    if rev == repo['.'].rev():
+                        ui.status(_('nothing to rebase\n'))
+                    else:
+                        ui.status(_('nothing to rebase - updating instead\n'))
                         # not passing argument to get the bare update behavior
                         # with warning and trumpets
                         commands.update(ui, repo)
diff --git a/mercurial/destutil.py b/mercurial/destutil.py
index 6411140aeda98aa32d61c2f08390d036e89c8b73_bWVyY3VyaWFsL2Rlc3R1dGlsLnB5..fac3a24be50e7c4c97757d19f725fa1342db156e_bWVyY3VyaWFsL2Rlc3R1dGlsLnB5 100644
--- a/mercurial/destutil.py
+++ b/mercurial/destutil.py
@@ -141,6 +141,10 @@
             (_("multiple matching bookmarks to merge -"
                " please merge with an explicit rev or bookmark"),
              _("run 'hg heads' to see all heads")),
+         'rebase':
+            (_("multiple matching bookmarks to rebase -"
+               " please rebase to an explicit rev or bookmark"),
+             _("run 'hg heads' to see all heads")),
         },
     # no other matching divergent bookmark
     'nootherbookmarks':
@@ -148,9 +152,13 @@
             (_("no matching bookmark to merge - "
                "please merge with an explicit rev or bookmark"),
              _("run 'hg heads' to see all heads")),
+         'rebase':
+            (_("no matching bookmark to rebase - "
+               "please rebase to an explicit rev or bookmark"),
+             _("run 'hg heads' to see all heads")),
         },
     # branch have too many unbookmarked heads, no obvious destination
     'toomanyheads':
         {'merge':
             (_("branch '%s' has %d heads - please merge with an explicit rev"),
              _("run 'hg heads .' to see heads")),
@@ -151,12 +159,15 @@
         },
     # branch have too many unbookmarked heads, no obvious destination
     'toomanyheads':
         {'merge':
             (_("branch '%s' has %d heads - please merge with an explicit rev"),
              _("run 'hg heads .' to see heads")),
+         'rebase':
+            (_("branch '%s' has %d heads - please rebase to an explicit rev"),
+             _("run 'hg heads .' to see heads")),
         },
     # branch have no other unbookmarked heads
     'bookmarkedheads':
         {'merge':
             (_("heads are bookmarked - please merge with an explicit rev"),
              _("run 'hg heads' to see all heads")),
@@ -157,12 +168,15 @@
         },
     # branch have no other unbookmarked heads
     'bookmarkedheads':
         {'merge':
             (_("heads are bookmarked - please merge with an explicit rev"),
              _("run 'hg heads' to see all heads")),
+         'rebase':
+            (_("heads are bookmarked - please rebase to an explicit rev"),
+             _("run 'hg heads' to see all heads")),
         },
     # branch have just a single heads, but there is other branches
     'nootherbranchheads':
         {'merge':
             (_("branch '%s' has one head - please merge with an explicit rev"),
              _("run 'hg heads' to see all heads")),
@@ -163,9 +177,12 @@
         },
     # branch have just a single heads, but there is other branches
     'nootherbranchheads':
         {'merge':
             (_("branch '%s' has one head - please merge with an explicit rev"),
              _("run 'hg heads' to see all heads")),
+         'rebase':
+            (_("branch '%s' has one head - please rebase to an explicit rev"),
+             _("run 'hg heads' to see all heads")),
         },
     # repository have a single head
     'nootherheads':
@@ -169,12 +186,15 @@
         },
     # repository have a single head
     'nootherheads':
-            {'merge':
-                (_('nothing to merge'),
-         None),
+        {'merge':
+            (_('nothing to merge'),
+            None),
+         'rebase':
+            (_('nothing to rebase'),
+            None),
         },
     # repository have a single head and we are not on it
     'nootherheadsbehind':
         {'merge':
             (_('nothing to merge'),
              _("use 'hg update' instead")),
@@ -175,11 +195,14 @@
         },
     # repository have a single head and we are not on it
     'nootherheadsbehind':
         {'merge':
             (_('nothing to merge'),
              _("use 'hg update' instead")),
+         'rebase':
+            (_('nothing to rebase'),
+             _("use 'hg update' instead")),
         },
     # We are not on a head
     'notatheads':
         {'merge':
             (_('working directory not at a head revision'),
@@ -181,10 +204,13 @@
         },
     # We are not on a head
     'notatheads':
         {'merge':
             (_('working directory not at a head revision'),
-             _("use 'hg update' or merge with an explicit revision"))
+             _("use 'hg update' or merge with an explicit revision")),
+         'rebase':
+            (_('working directory not at a head revision'),
+             _("use 'hg update' or rebase to an explicit revision"))
         },
     'emptysourceset':
         {'merge':
             (_('source set is empty'),
@@ -187,9 +213,12 @@
         },
     'emptysourceset':
         {'merge':
             (_('source set is empty'),
-             None)
+             None),
+         'rebase':
+            (_('source set is empty'),
+             None),
         },
     'multiplebranchessourceset':
         {'merge':
             (_('source set is rooted in multiple branches'),
@@ -192,8 +221,11 @@
         },
     'multiplebranchessourceset':
         {'merge':
             (_('source set is rooted in multiple branches'),
-             None)
+             None),
+         'rebase':
+            (_('rebaseset is rooted in multiple named branches'),
+             _('specify an explicit destination with --dest')),
         },
     }
 
diff --git a/tests/test-largefiles-misc.t b/tests/test-largefiles-misc.t
index 6411140aeda98aa32d61c2f08390d036e89c8b73_dGVzdHMvdGVzdC1sYXJnZWZpbGVzLW1pc2MudA==..fac3a24be50e7c4c97757d19f725fa1342db156e_dGVzdHMvdGVzdC1sYXJnZWZpbGVzLW1pc2MudA== 100644
--- a/tests/test-largefiles-misc.t
+++ b/tests/test-largefiles-misc.t
@@ -1095,7 +1095,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  nothing to rebase - working directory parent is already an ancestor of destination bf5e395ced2c
+  nothing to rebase - updating instead
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ cd ..
diff --git a/tests/test-rebase-named-branches.t b/tests/test-rebase-named-branches.t
index 6411140aeda98aa32d61c2f08390d036e89c8b73_dGVzdHMvdGVzdC1yZWJhc2UtbmFtZWQtYnJhbmNoZXMudA==..fac3a24be50e7c4c97757d19f725fa1342db156e_dGVzdHMvdGVzdC1yZWJhc2UtbmFtZWQtYnJhbmNoZXMudA== 100644
--- a/tests/test-rebase-named-branches.t
+++ b/tests/test-rebase-named-branches.t
@@ -327,6 +327,7 @@
 
   $ hg up -qr 2
   $ hg rebase
-  nothing to rebase - working directory parent is also destination
-  [1]
+  rebasing 2:792845bb77ee "b2"
+  note: rebase of 2:792845bb77ee created no changes to commit
+  saved backup bundle to $TESTTMP/case1/.hg/strip-backup/792845bb77ee-627120ee-backup.hg (glob)
   $ hg tglog
@@ -332,3 +333,3 @@
   $ hg tglog
-  o  3: 'c1' c
+  o  2: 'c1' c
   |
@@ -334,7 +335,5 @@
   |
-  | @  2: 'b2' b
-  |/
-  | o  1: 'b1' b
+  | @  1: 'b1' b
   |/
   o  0: '0'
   
@@ -373,8 +372,9 @@
   o  0: '0'
   
   $ hg rebase
-  nothing to rebase - working directory parent is also destination
-  [1]
+  abort: branch 'c' has one head - please rebase to an explicit rev
+  (run 'hg heads' to see all heads)
+  [255]
   $ hg tglog
   _  4: 'c2 closed' c
   |
diff --git a/tests/test-rebase-pull.t b/tests/test-rebase-pull.t
index 6411140aeda98aa32d61c2f08390d036e89c8b73_dGVzdHMvdGVzdC1yZWJhc2UtcHVsbC50..fac3a24be50e7c4c97757d19f725fa1342db156e_dGVzdHMvdGVzdC1yZWJhc2UtcHVsbC50 100644
--- a/tests/test-rebase-pull.t
+++ b/tests/test-rebase-pull.t
@@ -85,7 +85,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  nothing to rebase - working directory parent is already an ancestor of destination 77ae9631bcca
+  nothing to rebase - updating instead
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   updating bookmark norebase
 
@@ -285,7 +285,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files (+1 heads)
-  nothing to rebase - working directory parent is already an ancestor of destination 65bc164c1d9b
+  nothing to rebase - updating instead
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   1 other heads for branch "default"
   $ hg tglog
diff --git a/tests/test-rebase-scenario-global.t b/tests/test-rebase-scenario-global.t
index 6411140aeda98aa32d61c2f08390d036e89c8b73_dGVzdHMvdGVzdC1yZWJhc2Utc2NlbmFyaW8tZ2xvYmFsLnQ=..fac3a24be50e7c4c97757d19f725fa1342db156e_dGVzdHMvdGVzdC1yZWJhc2Utc2NlbmFyaW8tZ2xvYmFsLnQ= 100644
--- a/tests/test-rebase-scenario-global.t
+++ b/tests/test-rebase-scenario-global.t
@@ -818,6 +818,12 @@
 
 Testing from upper head
 
+  $ hg log -r '_destrebase(4)'
+  changeset:   3:1910d5ff34ea
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     second source with subdir
+  
   $ hg up 4
   1 files updated, 0 files merged, 2 files removed, 0 files unresolved
   $ hg log -r '_destrebase()'
@@ -821,8 +827,6 @@
   $ hg up 4
   1 files updated, 0 files merged, 2 files removed, 0 files unresolved
   $ hg log -r '_destrebase()'
-  changeset:   4:5f7bc9025ed2
-  tag:         tip
-  parent:      1:58d79cc1cf43
+  changeset:   3:1910d5ff34ea
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
@@ -827,4 +831,4 @@
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
-  summary:     aaa
+  summary:     second source with subdir