Index: subversion/libsvn_client/client.h
===================================================================
--- subversion/libsvn_client/client.h	(revision 24573)
+++ subversion/libsvn_client/client.h	(working copy)
@@ -887,6 +887,29 @@
                                            svn_client_ctx_t *ctx,
                                            apr_pool_t *pool);
 
+/* Retrieve the oldest revision of the node at REL_PATH at REV since
+   it was last copied (if applicable), and store it in OLDEST_REV.  If
+   REL_PATH does not exist in that REV, set *OLDEST_REV to
+   SVN_INVALID_REVNUM. */
+svn_error_t *
+svn_client__oldest_rev_at_path(svn_revnum_t *oldest_rev,
+                               svn_ra_session_t *ra_session,
+                               const char *rel_path,
+                               svn_revnum_t rev,
+                               apr_pool_t *pool);
+
+
+/* Retrieve the copy source of the node at REL_PATH at REV and store
+   it in COPY_SOURCE. If REL_PATH is not a copy (or doesn't exist),
+   set REV and COPY_SOURCE to NULL. */
+svn_error_t *
+svn_client__get_copy_source(const char **copy_source,
+                            svn_ra_session_t *ra_session,
+                            const char *rel_path,
+                            svn_revnum_t rev,
+                            apr_pool_t *pool);
+
+
 
 #ifdef __cplusplus
 }
Index: subversion/libsvn_client/merge.c
===================================================================
--- subversion/libsvn_client/merge.c	(revision 24573)
+++ subversion/libsvn_client/merge.c	(working copy)
@@ -1350,6 +1350,59 @@
   return SVN_NO_ERROR;
 }
 
+/* Default the values of REVISION1 and REVISION2 to be oldest rev at
+   which ra_session's root got created and HEAD (respectively), if
+   REVISION1 and REVISION2 are unspecified.  This assumed value is set
+   at *ASSUMED_REVISION1 and *ASSUMED_REVISION2.  RA_SESSION is used
+   to retrieve the revision of the current HEAD revision.  Use POOL
+   for temporary allocations. */
+static svn_error_t *
+assume_default_rev_range(const svn_opt_revision_t *revision1,
+                         svn_opt_revision_t *assumed_revision1,
+                         const svn_opt_revision_t *revision2,
+                         svn_opt_revision_t *assumed_revision2,
+                         svn_ra_session_t *ra_session,
+                         apr_pool_t *pool)
+{
+  svn_opt_revision_t head_rev_opt;
+  svn_revnum_t head_revnum = SVN_INVALID_REVNUM;
+  head_rev_opt.kind = svn_opt_revision_head;
+
+  /* Provide reasonable defaults for unspecified revisions. */
+  if (revision1->kind == svn_opt_revision_unspecified)
+    {
+      SVN_ERR(svn_client__get_revision_number(&head_revnum, ra_session,
+                                              &head_rev_opt, "", pool));
+      SVN_ERR(svn_client__oldest_rev_at_path(&assumed_revision1->value.number,
+                                             ra_session, "", head_revnum,
+                                             pool));
+      if (SVN_IS_VALID_REVNUM(assumed_revision1->value.number))
+        assumed_revision1->kind = svn_opt_revision_number;
+    }
+  else
+    {
+      *assumed_revision1 = *revision1;
+    }
+
+  if (revision2->kind == svn_opt_revision_unspecified)
+    {
+      if (SVN_IS_VALID_REVNUM(head_revnum))
+        {
+          assumed_revision2->value.number = head_revnum;
+          assumed_revision2->kind = svn_opt_revision_number;
+        }
+      else
+        {
+          assumed_revision2->kind = svn_opt_revision_head;
+        }
+    }
+  else
+    {
+      *assumed_revision2 = *revision2;
+    }
+  return SVN_NO_ERROR;
+}
+
 /* URL1/PATH1, URL2/PATH2, and TARGET_WCPATH all better be
    directories.  For the single file case, the caller does the merging
    manually.  PATH1 and PATH2 can be NULL.
@@ -1405,10 +1458,23 @@
   const svn_wc_entry_t *entry;
   int i;
   svn_boolean_t inherited;
+  svn_opt_revision_t assumed_initial_revision1, assumed_initial_revision2;
 
-  ENSURE_VALID_REVISION_KINDS(initial_revision1->kind,
-                              initial_revision2->kind);
+  /* Establish first RA session to initial_URL1. */
+  /* FIXME: use initial_URL1 for now which may barf for pegged rev merges */
+  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, initial_URL1, NULL,
+                                               NULL, NULL, FALSE, TRUE, 
+                                               ctx, pool));
+  SVN_ERR(assume_default_rev_range(initial_revision1, 
+                                   &assumed_initial_revision1,
+                                   initial_revision2,
+                                   &assumed_initial_revision2,
+                                   ra_session, 
+                                   pool));
 
+  ENSURE_VALID_REVISION_KINDS(assumed_initial_revision1.kind,
+                              assumed_initial_revision2.kind);
+
   /* If we are performing a pegged merge, we need to find out what our
      actual URLs will be. */
   if (peg_revision->kind != svn_opt_revision_unspecified)
@@ -1419,8 +1485,8 @@
                                           initial_path2 ? initial_path2
                                           : initial_URL2,
                                           peg_revision,
-                                          initial_revision1,
-                                          initial_revision2,
+                                          &assumed_initial_revision1,
+                                          &assumed_initial_revision2,
                                           ctx, pool));
 
       merge_b->url = URL2;
@@ -1435,15 +1501,11 @@
       path1 = initial_path1;
       path2 = initial_path2;
       revision1 = apr_pcalloc(pool, sizeof(*revision1));
-      *revision1 = *initial_revision1;
+      *revision1 = assumed_initial_revision1;
       revision2 = apr_pcalloc(pool, sizeof(*revision2));
-      *revision2 = *initial_revision2;
+      *revision2 = assumed_initial_revision2;
     }
   
-  /* Establish first RA session to URL1. */
-  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, URL1, NULL,
-                                               NULL, NULL, FALSE, TRUE, 
-                                               ctx, pool));
 
   notify_b.same_urls = (strcmp(URL1, URL2) == 0);
   if (!notify_b.same_urls && merge_b->record_only)
@@ -1709,17 +1771,30 @@
   svn_opt_revision_t *revision1, *revision2;
   svn_error_t *err;
   svn_merge_range_t range;
-  svn_ra_session_t *ra_session1, *ra_session2;
+  svn_ra_session_t *ra_session, *ra_session1, *ra_session2;
   enum merge_type merge_type;
   svn_boolean_t is_revert;
   apr_hash_t *target_mergeinfo;
   const svn_wc_entry_t *entry;
   int i;
   svn_boolean_t inherited = FALSE;
+  svn_opt_revision_t assumed_initial_revision1, assumed_initial_revision2;
 
-  ENSURE_VALID_REVISION_KINDS(initial_revision1->kind,
-                              initial_revision2->kind);
+  /* Establish first RA session to URL1. */
+  /* FIXME: use initial_URL1 for now which may barf for pegged rev merges */
+  SVN_ERR(svn_client__open_ra_session_internal(&ra_session, initial_URL1, NULL,
+                                               NULL, NULL, FALSE, TRUE,
+                                               ctx, pool));
+  SVN_ERR(assume_default_rev_range(initial_revision1,
+                                   &assumed_initial_revision1,
+                                   initial_revision2,
+                                   &assumed_initial_revision2,
+                                   ra_session,
+                                   pool));
 
+  ENSURE_VALID_REVISION_KINDS(assumed_initial_revision1.kind,
+                              assumed_initial_revision2.kind);
+
   /* If we are performing a pegged merge, we need to find out what our
      actual URLs will be. */
   if (peg_revision->kind != svn_opt_revision_unspecified)
@@ -1730,8 +1805,8 @@
                                           initial_path2 ? initial_path2
                                           : initial_URL2,
                                           peg_revision,
-                                          initial_revision1,
-                                          initial_revision2,
+                                          &assumed_initial_revision1,
+                                          &assumed_initial_revision2,
                                           ctx, pool));
 
       merge_b->url = URL2;
@@ -1746,9 +1821,9 @@
       path1 = initial_path1;
       path2 = initial_path2;
       revision1 = apr_pcalloc(pool, sizeof(*revision1));
-      *revision1 = *initial_revision1;
+      *revision1 = assumed_initial_revision1;
       revision2 = apr_pcalloc(pool, sizeof(*revision2));
-      *revision2 = *initial_revision2;
+      *revision2 = assumed_initial_revision2;
     }
 
   /* Establish RA sessions to both URLs. */
@@ -2230,18 +2305,56 @@
   const char *path;
   apr_array_header_t *children_with_mergeinfo;
 
-  /* If source is a path, we need to get the underlying URL
-   * from the wc and save the initial path we were passed so we can use it as 
-   * a path parameter (either in the baton or not).  otherwise, the path 
-   * will just be NULL, which means we won't be able to figure out some kind 
-   * of revision specifications, but in that case it won't matter, because 
-   * those ways of specifying a revision are meaningless for a url.
-   */
-  SVN_ERR(svn_client_url_from_path(&URL, source, pool));
-  if (! URL)
-    return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
-                             _("'%s' has no URL"),
-                             svn_path_local_style(source, pool));
+  if (source)
+    {
+      /* If source is a path, we need to get the underlying URL
+       * from the wc and save the initial path we were passed so we can use it as 
+       * a path parameter (either in the baton or not).  otherwise, the path 
+       * will just be NULL, which means we won't be able to figure out some kind 
+       * of revision specifications, but in that case it won't matter, because 
+       * those ways of specifying a revision are meaningless for a url.
+       */
+      SVN_ERR(svn_client_url_from_path(&URL, source, pool));
+      if (! URL) 
+        return svn_error_createf(SVN_ERR_ENTRY_MISSING_URL, NULL,
+                                 _("'%s' has no URL"),
+                                 svn_path_local_style(source, pool));
+    }
+  else
+    {
+      /* If a merge source was not specified, try to derive it from
+         copy source. */
+      svn_ra_session_t *ra_session;
+      svn_revnum_t working_rev_num;
+      svn_opt_revision_t working_copy_rev_num_opt;
+      working_copy_rev_num_opt.kind = svn_opt_revision_working;
+      const char *copy_source_path, *working_copy_url;
+      SVN_ERR(svn_client__ra_session_from_path(&ra_session,
+                                               &working_rev_num,
+                                               &working_copy_url,
+                                               target_wcpath,
+                                               &working_copy_rev_num_opt,
+                                               &working_copy_rev_num_opt,
+                                               ctx,
+                                               pool));
+      SVN_ERR(svn_client__get_copy_source(&copy_source_path, ra_session,
+                                          "", working_rev_num, pool));
+      if (copy_source_path)
+        {
+          const char *repos_root;
+          SVN_ERR(svn_ra_get_repos_root(ra_session, &repos_root, pool));
+          URL = apr_pstrcat(pool, repos_root, copy_source_path, NULL);
+        }
+      else
+        {
+          return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+                                   _("Unable to determine merge source for "
+                                     "'%s', please provide source explicitly"),
+                                   svn_path_local_style(source ? source : ".",
+                                                        pool));
+        }
+    }
+
   if (URL == source)
     path = NULL;
   else
Index: subversion/libsvn_client/copy.c
===================================================================
--- subversion/libsvn_client/copy.c	(revision 24573)
+++ subversion/libsvn_client/copy.c	(working copy)
@@ -349,22 +349,6 @@
   svn_boolean_t is_move;
 };
 
-/* A log callback conforming to the svn_log_message_receiver_t
-   interface for obtaining the last revision of a node at a path and
-   storing it in *BATON (an svn_revnum_t). */
-static svn_error_t *
-revnum_receiver(void *baton,
-                apr_hash_t *changed_paths,
-                svn_revnum_t revision,
-                const char *author,
-                const char *date,
-                const char *message,
-                apr_pool_t *pool)
-{
-  *((svn_revnum_t *) baton) = revision;
-  return SVN_NO_ERROR;
-}
-
 /* Obtain the implied merge info of repository-relative path PATH in
    *IMPLIED_MERGEINFO (e.g. every revision of the node at PATH since
    it last appeared).  REL_PATH corresponds to PATH, but is relative
@@ -377,33 +361,17 @@
                        svn_revnum_t rev,
                        apr_pool_t *pool)
 {
-  svn_error_t *err;
-  svn_revnum_t oldest_rev = SVN_INVALID_REVNUM;
+  svn_revnum_t oldest_rev;
   svn_merge_range_t *range;
   apr_array_header_t *rangelist;
-  apr_array_header_t *rel_paths = apr_array_make(pool, 1, sizeof(rel_path));
 
   *implied_mergeinfo = apr_hash_make(pool);
-  APR_ARRAY_PUSH(rel_paths, const char *) = rel_path;
 
-  /* Trace back in history to find the revision at which this node
-     was created (copied or added). */
-  err = svn_ra_get_log(ra_session, rel_paths, 1, rev, 1, FALSE, TRUE,
-                       revnum_receiver, &oldest_rev, pool);
-  if (err)
-    {
-      if (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
-          err->apr_err == SVN_ERR_RA_DAV_REQUEST_FAILED)
-        {
-          /* A locally-added but uncommitted versioned resource won't
-             exist in the repository. */
-          svn_error_clear(err);
-          err = SVN_NO_ERROR;
-        }
+  SVN_ERR(svn_client__oldest_rev_at_path(&oldest_rev, ra_session, rel_path,
+                                         rev, pool));
+  if (oldest_rev == SVN_INVALID_REVNUM)
+    return SVN_NO_ERROR;
 
-      return err;
-    }
-
   range = apr_palloc(pool, sizeof(*range));
   range->start = oldest_rev;
   range->end = rev;
@@ -411,7 +379,7 @@
   APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = range;
   apr_hash_set(*implied_mergeinfo, path, APR_HASH_KEY_STRING, rangelist);
 
-  return err;
+  return SVN_NO_ERROR;
 }
 
 /* Obtain the implied merge info and the existing merge info of the
Index: subversion/libsvn_client/log.c
===================================================================
--- subversion/libsvn_client/log.c	(revision 24573)
+++ subversion/libsvn_client/log.c	(working copy)
@@ -371,3 +371,114 @@
 
   return err;
 }
+
+/* A log callback conforming to the svn_log_message_receiver_t
+   interface for obtaining the last revision of a node at a path and
+   storing it in *BATON (an svn_revnum_t). */
+static svn_error_t *
+revnum_receiver(void *baton,
+                apr_hash_t *changed_paths,
+                svn_revnum_t revision,
+                const char *author,
+                const char *date,
+                const char *message,
+                apr_pool_t *pool)
+{
+  *((svn_revnum_t *) baton) = revision;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client__oldest_rev_at_path(svn_revnum_t *oldest_rev,
+                               svn_ra_session_t *ra_session,
+                               const char *rel_path,
+                               svn_revnum_t rev,
+                               apr_pool_t *pool)
+{
+  svn_error_t *err;
+  *oldest_rev = SVN_INVALID_REVNUM;
+  apr_array_header_t *rel_paths = apr_array_make(pool, 1, sizeof(rel_path));
+  APR_ARRAY_PUSH(rel_paths, const char *) = rel_path;
+
+  /* Trace back in history to find the revision at which this node
+     was created (copied or added). */
+  err = svn_ra_get_log(ra_session, rel_paths, 1, rev, 1, FALSE, TRUE,
+                       revnum_receiver, oldest_rev, pool);
+  if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
+              err->apr_err == SVN_ERR_RA_DAV_REQUEST_FAILED))
+    {
+      /* A locally-added but uncommitted versioned resource won't
+         exist in the repository. */
+      svn_error_clear(err);
+      err = SVN_NO_ERROR;
+    }
+  return err;
+}
+
+struct copy_source_baton
+{
+  const char **copy_source;
+  apr_pool_t *pool;
+};
+
+/* A log callback conforming to the svn_log_message_receiver_t
+   interface for obtaining the copy source of a node at a path and
+   storing it in *BATON (a struct copy_source_baton *). */
+static svn_error_t *
+copy_source_receiver(void *baton,
+                     apr_hash_t *changed_paths,
+                     svn_revnum_t revision,
+                     const char *author,
+                     const char *date,
+                     const char *message,
+                     apr_pool_t *pool)
+{
+  apr_hash_index_t *hi;
+  void *val;
+  const char *copy_source_path;
+  svn_log_changed_path_t *changed_path;
+  struct copy_source_baton *copy_source_baton;
+  copy_source_baton = baton;
+  /*FIXME: if the rev at which this node is created has few other node 
+   changes too extract only our node. */
+  for (hi = apr_hash_first(pool, changed_paths); hi; hi = apr_hash_next(hi))
+    {
+      apr_hash_this(hi, NULL, NULL, &val);
+      changed_path = val;
+    }
+  copy_source_path = changed_path->copyfrom_path;
+  
+  *((char **) copy_source_baton->copy_source) = 
+                     apr_pstrdup(copy_source_baton->pool, copy_source_path);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client__get_copy_source(const char **copy_source,
+                            svn_ra_session_t *ra_session,
+                            const char *rel_path,
+                            svn_revnum_t rev,
+                            apr_pool_t *pool)
+{
+  svn_error_t *err;
+  *copy_source = NULL;
+  struct copy_source_baton copy_source_baton;
+  copy_source_baton.copy_source = copy_source;
+  copy_source_baton.pool = pool;
+  apr_array_header_t *rel_paths = apr_array_make(pool, 1, sizeof(rel_path));
+  APR_ARRAY_PUSH(rel_paths, const char *) = rel_path;
+
+  /* Trace back in history to find the revision at which this node
+     was created (copied or added). */
+  err = svn_ra_get_log(ra_session, rel_paths, 1, rev, 1, TRUE, TRUE,
+                       copy_source_receiver, &copy_source_baton, pool);
+  if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
+              err->apr_err == SVN_ERR_RA_DAV_REQUEST_FAILED))
+    {
+      /* A locally-added but uncommitted versioned resource won't
+         exist in the repository. */
+      svn_error_clear(err);
+      err = SVN_NO_ERROR;
+    }
+  return err;
+}
Index: subversion/tests/cmdline/merge_tests.py
===================================================================
--- subversion/tests/cmdline/merge_tests.py	(revision 24573)
+++ subversion/tests/cmdline/merge_tests.py	(working copy)
@@ -1243,7 +1243,7 @@
 def merge_with_implicit_target_helper(sbox, arg_flav):
   "ARG_FLAV is one of 'r' (revision range) or 'c' (single change)."
 
-  if arg_flav not in ('r', 'c'):
+  if arg_flav not in ('r', 'c', '*'):
     raise svntest.Failure("Unrecognized flavor of merge argument")
 
   sbox.build()
@@ -1293,10 +1293,15 @@
     elif arg_flav == 'c':
       svntest.actions.run_and_verify_svn(None, ['U    mu\n'], [],
                                          'merge', '-c', '-2', mu_url)
+    elif arg_flav == '*':
+      # Implicit merge source URL and revision range detection is for
+      # forward merges only (e.g. non-reverts).
+      pass
 
     # sanity-check resulting file
     if (svntest.tree.get_text('mu') != orig_mu_text):
-      raise svntest.Failure("Unexpected text in 'mu'")
+      raise svntest.Failure("Unexpected text '%s' in 'mu', expected '%s'" %
+                            (svntest.tree.get_text('mu'), orig_mu_text))
 
     # merge using filename for sourcepath
     # Cannot use run_and_verify_merge with a file target
@@ -1306,6 +1311,9 @@
     elif arg_flav == 'c':
       svntest.actions.run_and_verify_svn(None, ['G    mu\n'], [],
                                          'merge', '-c', '2', 'mu')
+    elif arg_flav == '*':
+      svntest.actions.run_and_verify_svn(None, ['G    mu\n'], [],
+                                         'merge', 'mu')
 
     # sanity-check resulting file
     if (svntest.tree.get_text('mu') != orig_mu_text + added_mu_text):
@@ -1322,6 +1330,11 @@
   "merging a file w/no explicit target path using -c"
   merge_with_implicit_target_helper(sbox, 'c')
 
+def merge_with_implicit_target_and_revs(sbox):
+  "merging a file w/no explicit target path or revs"
+  merge_with_implicit_target_helper(sbox, '*')
+
+
 #----------------------------------------------------------------------
 
 def merge_with_prev (sbox):
@@ -5421,6 +5434,7 @@
               simple_property_merges,
               merge_with_implicit_target_using_r,
               merge_with_implicit_target_using_c,
+              merge_with_implicit_target_and_revs,
               merge_catches_nonexistent_target,
               merge_tree_deleted_in_target,
               merge_similar_unrelated_trees,
Index: subversion/svn/merge-cmd.c
===================================================================
--- subversion/svn/merge-cmd.c	(revision 24573)
+++ subversion/svn/merge-cmd.c	(working copy)
@@ -43,12 +43,32 @@
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
-  const char *sourcepath1, *sourcepath2, *targetpath;
+  const char *sourcepath1 = NULL, *sourcepath2 = NULL, *targetpath = "";
   svn_boolean_t using_rev_range_syntax = FALSE;
   svn_error_t *err;
-  svn_opt_revision_t peg_revision;
+  svn_opt_revision_t peg_revision1, peg_revision2;
   apr_array_header_t *options;
 
+  SVN_ERR(svn_opt_args_to_target_array2(&targets, os,
+                                        opt_state->targets, pool));
+  if (targets->nelts >= 1)
+    {
+      SVN_ERR(svn_opt_parse_path(&peg_revision1, &sourcepath1,
+                                 APR_ARRAY_IDX(targets, 0, const char *),
+                                 pool));
+      if (targets->nelts >= 2)
+        SVN_ERR(svn_opt_parse_path(&peg_revision2, &sourcepath2,
+                                   APR_ARRAY_IDX(targets, 1, const char *),
+                                   pool));
+    }
+
+  if (targets->nelts <= 1 ||
+      (targets->nelts == 2 &&
+       svn_path_is_url(sourcepath1) && !svn_path_is_url(sourcepath2)))
+    {
+      using_rev_range_syntax = TRUE;
+    }
+
   /* If the first opt_state revision is filled in at this point, then
      we know the user must have used the '-r' or '-c' switch. */
   if (opt_state->start_revision.kind != svn_opt_revision_unspecified)
@@ -60,33 +80,35 @@
 
       using_rev_range_syntax = TRUE;
     }
-
-  SVN_ERR(svn_opt_args_to_target_array2(&targets, os, 
-                                        opt_state->targets, pool));
-
   if (using_rev_range_syntax)
     {
-      if (targets->nelts < 1)
-        return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL, NULL);
       if (targets->nelts > 2)
         return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                 _("Too many arguments given"));
 
-      SVN_ERR(svn_opt_parse_path(&peg_revision, &sourcepath1,
-                                 APR_ARRAY_IDX(targets, 0, const char *),
-                                 pool));
-      sourcepath2 = sourcepath1;
+      opt_state->start_revision = peg_revision1;
+      opt_state->end_revision = peg_revision2;
 
-      /* Set the default peg revision if one was not specified. */
-      if (peg_revision.kind == svn_opt_revision_unspecified)
-        peg_revision.kind = svn_path_is_url(sourcepath1)
-          ? svn_opt_revision_head : svn_opt_revision_working;
+      if (targets->nelts == 0)
+        {
+          /* Set the default peg revision if one was not specified. */
+          if (peg_revision1.kind == svn_opt_revision_unspecified)
+            peg_revision1.kind = svn_opt_revision_head;
+        }
+      else
+        {
+          /* targets->nelts is 1 or 2 here. */
+          if (targets->nelts == 1)
+            sourcepath2 = sourcepath1;
+          /* Set the default peg revision if one was not specified. */
+          if (peg_revision1.kind == svn_opt_revision_unspecified)
+            peg_revision1.kind = svn_path_is_url(sourcepath1)
+              ? svn_opt_revision_head : svn_opt_revision_working;
 
-      /* decide where to apply the diffs, defaulting to '.' */
-      if (targets->nelts == 2)
-        targetpath = APR_ARRAY_IDX(targets, 1, const char *);
-      else
-        targetpath = "";
+          /* Decide where to apply the delta, defaulting to ".". */
+          if (targets->nelts == 2)
+            targetpath = APR_ARRAY_IDX(targets, 1, const char *);
+        }
     }
   else /* using @rev syntax */
     {
@@ -96,14 +118,6 @@
         return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                 _("Too many arguments given"));
 
-      /* the first two paths become the 'sources' */
-      SVN_ERR(svn_opt_parse_path(&opt_state->start_revision, &sourcepath1,
-                                 APR_ARRAY_IDX(targets, 0, const char *),
-                                 pool));
-      SVN_ERR(svn_opt_parse_path(&opt_state->end_revision, &sourcepath2,
-                                 APR_ARRAY_IDX(targets, 1, const char *),
-                                 pool));
-      
       /* Catch 'svn merge wc_path1 wc_path2 [target]' without explicit
          revisions--since it ignores local modifications it may not do what
          the user expects.  Forcing the user to specify a repository
@@ -117,37 +131,35 @@
           (SVN_ERR_CLIENT_BAD_REVISION, 0,
            _("A working copy merge source needs an explicit revision"));
 
-      /* decide where to apply the diffs, defaulting to '.' */
+      /* Decide where to apply the delta, defaulting to ".". */
       if (targets->nelts == 3)
         targetpath = APR_ARRAY_IDX(targets, 2, const char *);
-      else
-        targetpath = "";
     }
-
-  /* If no targetpath was specified, see if we can infer it from the
-     sourcepaths. */
-  if (! strcmp(targetpath, ""))
+  /* If targetpath was not specified, see if we can infer it from the
+     source paths. */
+  if (sourcepath1 && sourcepath2 && strcmp(targetpath, "") == 0)
     {
       char *sp1_basename, *sp2_basename;
       sp1_basename = svn_path_basename(sourcepath1, pool);
       sp2_basename = svn_path_basename(sourcepath2, pool);
 
-      if (! strcmp(sp1_basename, sp2_basename))
+      if (strcmp(sp1_basename, sp2_basename) == 0)
         {
           svn_node_kind_t kind;
           const char *decoded_path = svn_path_uri_decode(sp1_basename, pool);
           SVN_ERR(svn_io_check_path(decoded_path, &kind, pool));
           if (kind == svn_node_file) 
-            {
-              targetpath = decoded_path;
-            }
+            targetpath = decoded_path;
         }
     }
 
-  if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
-    opt_state->start_revision.kind = svn_opt_revision_head;
-  if (opt_state->end_revision.kind == svn_opt_revision_unspecified)
-    opt_state->end_revision.kind = svn_opt_revision_head;
+  if (!using_rev_range_syntax)
+    {
+      if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
+        opt_state->start_revision.kind = svn_opt_revision_head;
+      if (opt_state->end_revision.kind == svn_opt_revision_unspecified)
+        opt_state->end_revision.kind = svn_opt_revision_head;
+    }
 
   if (! opt_state->quiet)
     svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, FALSE,
@@ -163,7 +175,7 @@
       err = svn_client_merge_peg3(sourcepath1,
                                   &(opt_state->start_revision),
                                   &(opt_state->end_revision),
-                                  &peg_revision,
+                                  &peg_revision1,
                                   targetpath,
                                   opt_state->depth,
                                   opt_state->ignore_ancestry,
Index: subversion/svn/main.c
===================================================================
--- subversion/svn/main.c	(revision 24573)
+++ subversion/svn/main.c	(working copy)
@@ -513,7 +513,7 @@
     ("Apply the differences between two sources to a working copy path.\n"
      "usage: 1. merge sourceURL1[@N] sourceURL2[@M] [WCPATH]\n"
      "       2. merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]\n"
-     "       3. merge [-c M | -r N:M] SOURCE[@REV] [WCPATH]\n"
+     "       3. merge [-c M | -r N:M] [SOURCE[@REV] [WCPATH]]\n"
      "\n"
      "  1. In the first form, the source URLs are specified at revisions\n"
      "     N and M.  These are the two sources to be compared.  The revisions\n"
@@ -524,11 +524,15 @@
      "     be specified.\n"
      "\n"
      "  3. In the third form, SOURCE can be a URL, or working copy item\n"
-     "     in which case the corresponding URL is used.  This URL in\n"
-     "     revision REV is compared as it existed between revisions N and \n"
-     "     M.  If REV is not specified, HEAD is assumed.\n"
-     "     The '-c M' option is equivalent to '-r N:M' where N = M-1.\n"
-     "     Using '-c -M' does the reverse: '-r M:N' where N = M-1.\n"
+     "     in which case the corresponding URL is used.  If not specified,\n"
+     "     the copy source URL of SOURCE is used. If the WCPATH cannot be\n"
+     "     determined automatically, an error is displayed asking for an\n"
+     "     explicit SOURCE. This URL in revision REV is compared as it\n"
+     "     existed between revisions N and M.  If REV is not specified, HEAD\n"
+     "     is assumed. The '-c M' option is equivalent to '-r N:M' where\n"
+     "     N = M-1.  Using '-c -M' does the reverse: '-r M:N' where N = M-1.\n"
+     "     If a revision range is not specified, it is assumed to be\n"
+     "     -r OLDEST_REV_OF_SOURCE_AT_URL:HEAD.\n"
      "\n"
      "  WCPATH is the working copy path that will receive the changes.\n"
      "  If WCPATH is omitted, a default value of '.' is assumed, unless\n"

