Index: subversion/include/svn_wc.h
===================================================================
--- subversion/include/svn_wc.h	(revision 31039)
+++ subversion/include/svn_wc.h	(working copy)
@@ -2756,6 +2756,9 @@
  *
  * If @a path does not exist, return @c SVN_ERR_WC_PATH_NOT_FOUND.
  *
+ * If @a path is a directory, add it at @a depth; otherwise, ignore
+ * @a depth.
+ *
  * If @a copyfrom_url is non-NULL, it and @a copyfrom_rev are used as
  * `copyfrom' args.  This is for copy operations, where one wants
  * to schedule @a path for addition with a particular history.
@@ -2799,9 +2802,27 @@
  * ### Update: see "###" comment in svn_wc_add_repos_file()'s doc
  * string about this.
  *
- * @since New in 1.2.
+ * @since New in 1.5.
  */
 svn_error_t *
+svn_wc_add3(const char *path,
+            svn_wc_adm_access_t *parent_access,
+            svn_depth_t depth,
+            const char *copyfrom_url,
+            svn_revnum_t copyfrom_rev,
+            svn_cancel_func_t cancel_func,
+            void *cancel_baton,
+            svn_wc_notify_func2_t notify_func,
+            void *notify_baton,
+            apr_pool_t *pool);
+
+/**
+ * Similar to svn_wc_add3(), but with the @a depth parameter always
+ * @c svn_depth_infinity.
+ *
+ * @deprecated Provided for backward compatibility with the 1.2 API.
+ */
+svn_error_t *
 svn_wc_add2(const char *path,
             svn_wc_adm_access_t *parent_access,
             const char *copyfrom_url,
Index: subversion/libsvn_wc/copy.c
===================================================================
--- subversion/libsvn_wc/copy.c	(revision 31039)
+++ subversion/libsvn_wc/copy.c	(working copy)
@@ -75,8 +75,8 @@
 
   if (src_is_added)
     {
-      SVN_ERR(svn_wc_add2(dst_path, dst_parent_access, NULL,
-                          SVN_INVALID_REVNUM, cancel_func,
+      SVN_ERR(svn_wc_add3(dst_path, dst_parent_access, svn_depth_infinity,
+                          NULL, SVN_INVALID_REVNUM, cancel_func,
                           cancel_baton, notify_func,
                           notify_baton, pool));
     }
@@ -150,7 +150,7 @@
 
       /* Add the directory, adding locking access for dst_path
          to dst_parent_access at the same time. */
-      SVN_ERR(svn_wc_add2(dst_path, dst_parent_access, NULL,
+      SVN_ERR(svn_wc_add3(dst_path, dst_parent_access, svn_depth_infinity, NULL,
                           SVN_INVALID_REVNUM, cancel_func, cancel_baton,
                           notify_func, notify_baton, pool));
 
@@ -755,7 +755,7 @@
 
     SVN_ERR(svn_wc_adm_close(adm_access));
 
-    SVN_ERR(svn_wc_add2(dst_path, dst_parent,
+    SVN_ERR(svn_wc_add3(dst_path, dst_parent, svn_depth_infinity,
                         copyfrom_url, copyfrom_rev,
                         cancel_func, cancel_baton,
                         notify_copied, notify_baton, pool));
Index: subversion/libsvn_wc/adm_ops.c
===================================================================
--- subversion/libsvn_wc/adm_ops.c	(revision 31039)
+++ subversion/libsvn_wc/adm_ops.c	(working copy)
@@ -1377,8 +1377,9 @@
 
 
 svn_error_t *
-svn_wc_add2(const char *path,
+svn_wc_add3(const char *path,
             svn_wc_adm_access_t *parent_access,
+            svn_depth_t depth,
             const char *copyfrom_url,
             svn_revnum_t copyfrom_rev,
             svn_cancel_func_t cancel_func,
@@ -1526,13 +1527,6 @@
 
   if (kind == svn_node_dir) /* scheduling a directory for addition */
     {
-      /* Note that both calls to svn_wc_ensure_adm3() below pass
-         svn_depth_infinity.  Even if 'svn add' were invoked with some
-         other depth, we'd want to create the adm area with
-         svn_depth_infinity, because when the user passes add a depth,
-         that's just a way of telling Subversion what items to add,
-         not a way of telling Subversion what depth the resultant
-         newly-versioned directory should have. */
 
       if (! copyfrom_url)
         {
@@ -1550,7 +1544,7 @@
           /* Make sure this new directory has an admistrative subdirectory
              created inside of it */
           SVN_ERR(svn_wc_ensure_adm3(path, NULL, new_url, p_entry->repos,
-                                     0, svn_depth_infinity, pool));
+                                     0, depth, pool));
         }
       else
         {
@@ -1560,7 +1554,7 @@
              copyfrom arguments to the ensure call. */
           SVN_ERR(svn_wc_ensure_adm3(path, NULL, copyfrom_url,
                                      parent_entry->repos, copyfrom_rev,
-                                     svn_depth_infinity, pool));
+                                     depth, pool));
         }
 
       /* We want the locks to persist, so use the access baton's pool */
@@ -1604,7 +1598,7 @@
 
           /* Change the entry urls recursively (but not the working rev). */
           SVN_ERR(svn_wc__do_update_cleanup(path, adm_access,
-                                            svn_depth_infinity, new_url,
+                                            depth, new_url,
                                             parent_entry->repos,
                                             SVN_INVALID_REVNUM, NULL,
                                             NULL, FALSE, apr_hash_make(pool),
@@ -1636,6 +1630,22 @@
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_wc_add2(const char *path,
+            svn_wc_adm_access_t *parent_access,
+            const char *copyfrom_url,
+            svn_revnum_t copyfrom_rev,
+            svn_cancel_func_t cancel_func,
+            void *cancel_baton,
+            svn_wc_notify_func2_t notify_func,
+            void *notify_baton,
+            apr_pool_t *pool)
+{
+  return svn_wc_add3(path, parent_access, svn_depth_infinity, 
+                     copyfrom_url, copyfrom_rev, 
+                     cancel_func, cancel_baton, 
+                     notify_func, notify_baton, pool);
+}
 
 svn_error_t *
 svn_wc_add(const char *path,
@@ -1658,7 +1668,6 @@
                      svn_wc__compat_call_notify_func, &nb, pool);
 }
 
-
 
 /* Thoughts on Reversion.
 
Index: subversion/libsvn_client/merge.c
===================================================================
--- subversion/libsvn_client/merge.c	(revision 31039)
+++ subversion/libsvn_client/merge.c	(working copy)
@@ -1100,7 +1100,7 @@
       else
         {
           SVN_ERR(svn_io_make_dir_recursively(path, subpool));
-          SVN_ERR(svn_wc_add2(path, adm_access,
+          SVN_ERR(svn_wc_add3(path, adm_access, svn_depth_infinity,
                               copyfrom_url, copyfrom_rev,
                               merge_b->ctx->cancel_func,
                               merge_b->ctx->cancel_baton,
@@ -1117,7 +1117,7 @@
       if (! entry || entry->schedule == svn_wc_schedule_delete)
         {
           if (!merge_b->dry_run)
-            SVN_ERR(svn_wc_add2(path, adm_access,
+            SVN_ERR(svn_wc_add3(path, adm_access, svn_depth_infinity,
                                 copyfrom_url, copyfrom_rev,
                                 merge_b->ctx->cancel_func,
                                 merge_b->ctx->cancel_baton,
Index: subversion/libsvn_client/copy.c
===================================================================
--- subversion/libsvn_client/copy.c	(revision 31039)
+++ subversion/libsvn_client/copy.c	(working copy)
@@ -1389,8 +1389,8 @@
           /* Schedule dst_path for addition in parent, with copy history.
              (This function also recursively puts a 'copied' flag on every
              entry). */
-          SVN_ERR(svn_wc_add2(pair->dst, adm_access, pair->src,
-                              src_revnum,
+          SVN_ERR(svn_wc_add3(pair->dst, adm_access, svn_depth_infinity, 
+                              pair->src, src_revnum,
                               ctx->cancel_func, ctx->cancel_baton,
                               ctx->notify_func2, ctx->notify_baton2, pool));
 
Index: subversion/libsvn_client/add.c
===================================================================
--- subversion/libsvn_client/add.c	(revision 31039)
+++ subversion/libsvn_client/add.c	(working copy)
@@ -232,8 +232,8 @@
                                        pool));
 
   /* Add the file */
-  SVN_ERR(svn_wc_add2(path, adm_access, NULL, SVN_INVALID_REVNUM,
-                      ctx->cancel_func, ctx->cancel_baton,
+  SVN_ERR(svn_wc_add3(path, adm_access, svn_depth_infinity, NULL,
+                      SVN_INVALID_REVNUM, ctx->cancel_func, ctx->cancel_baton,
                       NULL, NULL, pool));
 
   if (is_special)
@@ -308,9 +308,8 @@
     SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
   /* Add this directory to revision control. */
-  err = svn_wc_add2(dirname, adm_access,
-                    NULL, SVN_INVALID_REVNUM,
-                    ctx->cancel_func, ctx->cancel_baton,
+  err = svn_wc_add3(dirname, adm_access, depth, NULL, SVN_INVALID_REVNUM,
+                    ctx->cancel_func, ctx->cancel_baton, 
                     ctx->notify_func2, ctx->notify_baton2, pool);
   if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
     svn_error_clear(err);
@@ -430,13 +429,18 @@
   svn_error_t *err;
 
   SVN_ERR(svn_io_check_path(path, &kind, pool));
-  if (kind == svn_node_dir && depth >= svn_depth_files)
-    err = add_dir_recursive(path, adm_access, depth,
-                            force, no_ignore, ctx, pool);
+  if (kind == svn_node_dir)
+    {
+      /* We use add_dir_recursive for all directory targets
+         and pass depth along no matter what it is, so that the
+         target's depth will be set correctly. */
+      err = add_dir_recursive(path, adm_access, depth,
+                              force, no_ignore, ctx, pool);
+    }
   else if (kind == svn_node_file)
     err = add_file(path, ctx, adm_access, pool);
   else
-    err = svn_wc_add2(path, adm_access, NULL, SVN_INVALID_REVNUM,
+    err = svn_wc_add3(path, adm_access, depth, NULL, SVN_INVALID_REVNUM,
                       ctx->cancel_func, ctx->cancel_baton,
                       ctx->notify_func2, ctx->notify_baton2, pool);
 
@@ -482,7 +486,8 @@
           SVN_ERR(add_parent_dirs(parent_path, &adm_access, ctx, pool));
           SVN_ERR(svn_wc_adm_retrieve(&adm_access, adm_access, parent_path,
                                       pool));
-          SVN_ERR(svn_wc_add2(path, adm_access, NULL, SVN_INVALID_REVNUM,
+          SVN_ERR(svn_wc_add3(path, adm_access, svn_depth_infinity, 
+                              NULL, SVN_INVALID_REVNUM,
                               ctx->cancel_func, ctx->cancel_baton,
                               ctx->notify_func2, ctx->notify_baton2, pool));
         }
@@ -796,7 +797,11 @@
   else
     SVN_ERR(svn_io_dir_make(path, APR_OS_DEFAULT, pool));
 
-  err = svn_client_add4(path, svn_depth_empty, FALSE, FALSE,
+  /* Should no longer use svn_depth_empty to indicate that only the directory
+     itself is added, since it not only constraints the operation depth, but
+     also defines the depth of the target directory now. Moreover, the new
+     directory will have no children at all.*/
+  err = svn_client_add4(path, svn_depth_infinity, FALSE, FALSE,
                         make_parents, ctx, pool);
 
   /* If we created a new directory, but couldn't add it to version
Index: subversion/tests/cmdline/depth_tests.py
===================================================================
--- subversion/tests/cmdline/depth_tests.py	(revision 31039)
+++ subversion/tests/cmdline/depth_tests.py	(working copy)
@@ -1210,17 +1210,38 @@
   # Check that the new directory was added at depth=empty.
   verify_depth(None, "empty", other_I_path)
 
-def add_tree_with_depth_files(sbox):
-  "add multi-subdir tree with --depth=files"  # For issue #2931
+def add_tree_with_depth(sbox):
+  "add multi-subdir tree with --depth options"  # For issue #2931
   sbox.build()
   wc_dir = sbox.wc_dir
   new1_path = os.path.join(wc_dir, 'new1')
   new2_path = os.path.join(new1_path, 'new2')
+  new3_path = os.path.join(new2_path, 'new3')
+  new4_path = os.path.join(new3_path, 'new4')
   os.mkdir(new1_path)
   os.mkdir(new2_path)
+  os.mkdir(new3_path)
+  os.mkdir(new4_path)
+  # Simple case, add new1 only, set depth to files
   svntest.actions.run_and_verify_svn(None, None, [],
                                      "add", "--depth", "files", new1_path)
+  verify_depth(None, "files", new1_path)
 
+  # Force add new1 at new1 again, should include new2 at empty, the depth of
+  # new1 should not change 
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     "add", "--depth", "immediates", 
+                                     "--force", new1_path)
+  verify_depth(None, "files", new1_path)
+  verify_depth(None, "empty", new2_path)
+
+  # add new4 with intermediate path, the intermediate path is added at empty
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     "add", "--depth", "immediates",
+                                     "--parents", new4_path)
+  verify_depth(None, "infinity", new3_path)
+  verify_depth(None, "immediates", new4_path)
+
 def upgrade_from_above(sbox):
   "upgrade a depth=empty wc from above"
 
@@ -2016,7 +2037,7 @@
               diff_in_depthy_wc,
               commit_depth_immediates,
               depth_immediates_receive_new_dir,
-              add_tree_with_depth_files,
+              add_tree_with_depth,
               upgrade_from_above,
               status_in_depthy_wc,
               depthy_update_above_dir_to_be_deleted,

