Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db.h?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db.h Tue Feb 24 
15:23:33 2015
@@ -676,13 +676,15 @@ svn_wc__db_base_add_not_present_node(svn
                                      const svn_skel_t *work_items,
                                      apr_pool_t *scratch_pool);
 
+/* Remove a node and all its descendants from the BASE tree. This can
+   be done in two modes:
 
-/* Remove a node and all its descendants from the BASE tree. This handles
-   the deletion of a tree from the update editor and some file external
-   scenarios.
+    * Remove everything, scheduling wq operations to clean up
+      the working copy. (KEEP_WORKING = FALSE)
 
-   The node to remove is indicated by LOCAL_ABSPATH from the local
-   filesystem.
+    * Bump things to WORKING, so the BASE layer is free, but the working
+      copy unmodified, except that everything that was visible from
+      BASE is now a copy of what it used to be. (KEEP_WORKING = TRUE)
 
    This operation *installs* workqueue operations to update the local
    filesystem after the database operation.
@@ -693,21 +695,11 @@ svn_wc__db_base_add_not_present_node(svn
    actual node will be removed if the actual node does not mark a
    conflict.
 
-   If KEEP_AS_WORKING is TRUE, then the base tree is copied to higher
-   layers as a copy of itself before deleting the BASE nodes.
 
-   If KEEP_AS_WORKING is FALSE, and QUEUE_DELETES is TRUE, also queue
-   workqueue items to delete all in-wc representations that aren't
-   shadowed by higher layers.
-   (With KEEP_AS_WORKING TRUE, this is a no-op, as everything is
-    automatically shadowed by the created copy)
-
-   If REMOVE_LOCKS is TRUE, all locks of this node and any subnodes
-   are also removed. This is to be done during commit of deleted nodes.
-
-   If NOT_PRESENT_REVISION specifies a valid revision a not-present
-   node is installed in BASE node with kind NOT_PRESENT_KIND after
-   deleting.
+   If MARK_NOT_PRESENT or MARK_EXCLUDED is TRUE, install a marker
+   of the specified type at the root of the now removed tree, with
+   either the specified revision (or in case of SVN_INVALID_REVNUM)
+   the original revision.
 
    If CONFLICT and/or WORK_ITEMS are passed they are installed as part
    of the operation, after the work items inserted by the operation
@@ -716,10 +708,10 @@ svn_wc__db_base_add_not_present_node(svn
 svn_error_t *
 svn_wc__db_base_remove(svn_wc__db_t *db,
                        const char *local_abspath,
-                       svn_boolean_t keep_as_working,
-                       svn_boolean_t queue_deletes,
-                       svn_boolean_t remove_locks,
-                       svn_revnum_t not_present_revision,
+                       svn_boolean_t keep_working,
+                       svn_boolean_t mark_not_present,
+                       svn_boolean_t mark_excluded,
+                       svn_revnum_t marker_revision,
                        svn_skel_t *conflict,
                        svn_skel_t *work_items,
                        apr_pool_t *scratch_pool);
@@ -1421,8 +1413,8 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
                        const char *original_uuid,
                        svn_revnum_t original_revision,
                        const apr_array_header_t *children,
-                       svn_boolean_t is_move,
                        svn_depth_t depth,
+                       svn_boolean_t is_move,
                        const svn_skel_t *conflict,
                        const svn_skel_t *work_items,
                        apr_pool_t *scratch_pool);
@@ -1463,6 +1455,7 @@ svn_wc__db_op_copy_symlink(svn_wc__db_t
                            const char *original_uuid,
                            svn_revnum_t original_revision,
                            const char *target,
+                           svn_boolean_t is_move,
                            const svn_skel_t *conflict,
                            const svn_skel_t *work_items,
                            apr_pool_t *scratch_pool);
@@ -2136,15 +2129,26 @@ svn_wc__db_read_children_walker_info(apr
 
 
 /**
- * Set *URL to the corresponding url for LOCAL_ABSPATH.
- * If the node is added, return the url it will have in the repository.
- */
-svn_error_t *
-svn_wc__db_read_url(const char **url,
-                    svn_wc__db_t *db,
-                    const char *local_abspath,
-                    apr_pool_t *result_pool,
-                    apr_pool_t *scratch_pool);
+ * Set *revision, *repos_relpath, *repos_root_url, *repos_uuid to
+ * the intended/commit location of LOCAL_ABSPATH. These arguments may be
+ * NULL if they are not needed.
+ *
+ * If the node is deleted, return the url it would have in the repository
+ * if it wouldn't be deleted. If the node is added return the url it will
+ * have in the repository, once committed.
+ *
+ * If the node is not added and has an existing repository location, set
+ * revision to its existing revision, otherwise to SVN_INVALID_REVNUM.
+ */
+svn_error_t *
+svn_wc__db_read_repos_info(svn_revnum_t *revision,
+                           const char **repos_relpath,
+                           const char **repos_root_url,
+                           const char **repos_uuid,
+                           svn_wc__db_t *db,
+                           const char *local_abspath,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool);
 
 
 /* Set *PROPS to the properties of the node LOCAL_ABSPATH in the ACTUAL
@@ -2308,6 +2312,14 @@ svn_wc__db_read_children_of_working_node
                                          apr_pool_t *result_pool,
                                          apr_pool_t *scratch_pool);
 
+svn_error_t *
+svn_wc__db_base_read_not_present_children(
+                                const apr_array_header_t **children,
+                                svn_wc__db_t *db,
+                                const char *local_abspath,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool);
+
 /* Like svn_wc__db_read_children_of_working_node(), except also include any
    path that was a child of a deleted directory that existed at
    LOCAL_ABSPATH, even if that directory is now scheduled to be replaced by
@@ -2396,16 +2408,6 @@ svn_wc__db_read_kind(svn_node_kind_t *ki
                      svn_boolean_t show_hidden,
                      apr_pool_t *scratch_pool);
 
-
-/* An analog to svn_wc__entry_is_hidden().  Set *HIDDEN to TRUE if
-   LOCAL_ABSPATH in DB "is not present, and I haven't scheduled something
-   over the top of it." */
-svn_error_t *
-svn_wc__db_node_hidden(svn_boolean_t *hidden,
-                       svn_wc__db_t *db,
-                       const char *local_abspath,
-                       apr_pool_t *scratch_pool);
-
 /* Checks if a node replaces a node in a different layer. Also check if it
    replaces a BASE (op_depth 0) node or just a node in a higher layer (a copy).
    Finally check if this is the root of the replacement, or if the replacement
@@ -2517,11 +2519,6 @@ svn_wc__db_global_relocate(svn_wc__db_t
    CHANGED_AUTHOR is the (server-side) author of CHANGED_REVISION. It may be
    NULL if the revprop is missing on the revision.
 
-   One or both of NEW_CHECKSUM and NEW_CHILDREN should be NULL. For new:
-     files: NEW_CHILDREN should be NULL
-     dirs: NEW_CHECKSUM should be NULL
-     symlinks: both should be NULL
-
    WORK_ITEMS will be place into the work queue.
 */
 svn_error_t *
@@ -2532,7 +2529,6 @@ svn_wc__db_global_commit(svn_wc__db_t *d
                          apr_time_t changed_date,
                          const char *changed_author,
                          const svn_checksum_t *new_checksum,
-                         const apr_array_header_t *new_children,
                          apr_hash_t *new_dav_cache,
                          svn_boolean_t keep_changelist,
                          svn_boolean_t no_unlock,
@@ -2935,34 +2931,6 @@ svn_wc__db_upgrade_begin(svn_sqlite__db_
                          const char *repos_uuid,
                          apr_pool_t *scratch_pool);
 
-
-svn_error_t *
-svn_wc__db_upgrade_apply_dav_cache(svn_sqlite__db_t *sdb,
-                                   const char *dir_relpath,
-                                   apr_hash_t *cache_values,
-                                   apr_pool_t *scratch_pool);
-
-
-/* ### need much more docco
-
-   ### this function should be called within a sqlite transaction. it makes
-   ### assumptions around this fact.
-
-   Apply the various sets of properties to the database nodes based on
-   their existence/presence, the current state of the node, and the original
-   format of the working copy which provided these property sets.
-*/
-svn_error_t *
-svn_wc__db_upgrade_apply_props(svn_sqlite__db_t *sdb,
-                               const char *dir_abspath,
-                               const char *local_relpath,
-                               apr_hash_t *base_props,
-                               apr_hash_t *revert_props,
-                               apr_hash_t *working_props,
-                               int original_format,
-                               apr_int64_t wc_id,
-                               apr_pool_t *scratch_pool);
-
 /* Simply insert (or replace) one row in the EXTERNALS table. */
 svn_error_t *
 svn_wc__db_upgrade_insert_external(svn_wc__db_t *db,
@@ -2977,20 +2945,6 @@ svn_wc__db_upgrade_insert_external(svn_w
                                    svn_revnum_t def_revision,
                                    apr_pool_t *scratch_pool);
 
-/* Get the repository identifier corresponding to REPOS_ROOT_URL from the
-   database in SDB. The value is returned in *REPOS_ID. All allocations
-   are allocated in SCRATCH_POOL.
-
-   NOTE: the row in REPOSITORY must exist. If not, then SVN_ERR_WC_DB_ERROR
-   is returned.
-
-   ### unclear on whether/how this interface will stay/evolve.  */
-svn_error_t *
-svn_wc__db_upgrade_get_repos_id(apr_int64_t *repos_id,
-                                svn_sqlite__db_t *sdb,
-                                const char *repos_root_url,
-                                apr_pool_t *scratch_pool);
-
 /* Upgrade the metadata concerning the WC at WCROOT_ABSPATH, in DB,
  * to the SVN_WC__VERSION format.
  *
@@ -3131,10 +3085,6 @@ svn_wc__db_wclock_owns_lock(svn_boolean_
    This operation always recursively removes all nodes at and below
    LOCAL_ABSPATH from NODES and ACTUAL.
 
-   If NOT_PRESENT_REVISION specifies a valid revision, leave a not_present
-   BASE node at local_abspath of the specified status and kind.
-   (Requires an existing BASE node before removing)
-
    If DESTROY_WC is TRUE, this operation *installs* workqueue operations to
    update the local filesystem after the database operation. If DESTROY_CHANGES
    is FALSE, modified and unversioned files are left after running this
@@ -3152,9 +3102,6 @@ svn_wc__db_op_remove_node(svn_boolean_t
                           const char *local_abspath,
                           svn_boolean_t destroy_wc,
                           svn_boolean_t destroy_changes,
-                          svn_revnum_t not_present_revision,
-                          svn_wc__db_status_t not_present_status,
-                          svn_node_kind_t not_present_kind,
                           const svn_skel_t *conflict,
                           const svn_skel_t *work_items,
                           svn_cancel_func_t cancel_func,
@@ -3317,7 +3264,8 @@ svn_wc__db_get_not_present_descendants(c
  *
  * Indicate in *IS_SPARSE_CHECKOUT whether any of the nodes within
  * LOCAL_ABSPATH is sparse.
- * Indicate in *IS_MODIFIED whether the working copy has local modifications.
+ * Indicate in *IS_MODIFIED whether the working copy has local modifications
+ * recorded for it in DB.
  *
  * Indicate in *IS_SWITCHED whether any node beneath LOCAL_ABSPATH
  * is switched. If TRAIL_URL is non-NULL, use it to determine if LOCAL_ABSPATH
@@ -3338,8 +3286,6 @@ svn_wc__db_revision_status(svn_revnum_t
                            const char *local_abspath,
                            const char *trail_url,
                            svn_boolean_t committed,
-                           svn_cancel_func_t cancel_func,
-                           void *cancel_baton,
                            apr_pool_t *scratch_pool);
 
 /* Set *MIN_REVISION and *MAX_REVISION to the lowest and highest revision
@@ -3400,16 +3346,13 @@ svn_wc__db_get_excluded_subtrees(apr_has
 /* Indicate in *IS_MODIFIED whether the working copy has local modifications,
  * using DB. Use SCRATCH_POOL for temporary allocations.
  *
- * This function provides a subset of the functionality of
- * svn_wc__db_revision_status() and is more efficient if the caller
- * doesn't need all information returned by svn_wc__db_revision_status(). */
+ * This function does not check the working copy state, but is a lot more
+ * efficient than a full status walk. */
 svn_error_t *
-svn_wc__db_has_local_mods(svn_boolean_t *is_modified,
-                          svn_wc__db_t *db,
-                          const char *local_abspath,
-                          svn_cancel_func_t cancel_func,
-                          void *cancel_baton,
-                          apr_pool_t *scratch_pool);
+svn_wc__db_has_db_mods(svn_boolean_t *is_modified,
+                       svn_wc__db_t *db,
+                       const char *local_abspath,
+                       apr_pool_t *scratch_pool);
 
 
 /* Verify the consistency of metadata concerning the WC that contains
@@ -3526,6 +3469,28 @@ svn_wc__required_lock_for_resolve(const
                                   apr_pool_t *scratch_pool);
 /* @} */
 
+typedef svn_error_t * (*svn_wc__db_verify_cb_t)(void *baton,
+                                                const char *wc_abspath,
+                                                const char *local_relpath,
+                                                int op_depth,
+                                                int id,
+                                                const char *description,
+                                                apr_pool_t *scratch_pool);
+
+/* Checks the database for FULL-correctness according to the spec.
+
+   Note that typical 1.7-1.9 databases WILL PRODUCE warnings.
+
+   This is mainly useful for WC-NG developers, as there will be
+   warnings without the database being corrupt
+*/
+svn_error_t *
+svn_wc__db_verify_db_full(svn_wc__db_t *db,
+                          const char *wri_abspath,
+                          svn_wc__db_verify_cb_t callback,
+                          void *baton,
+                          apr_pool_t *scratch_pool);
+
 
 #ifdef __cplusplus
 }

Modified: 
subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_private.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_private.h?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_private.h 
(original)
+++ subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_private.h 
Tue Feb 24 15:23:33 2015
@@ -400,6 +400,7 @@ svn_wc__db_op_copy_layer_internal(svn_wc
 svn_error_t *
 svn_wc__db_op_make_copy_internal(svn_wc__db_wcroot_t *wcroot,
                                  const char *local_relpath,
+                                 svn_boolean_t move_move_info,
                                  const svn_skel_t *conflicts,
                                  const svn_skel_t *work_items,
                                  apr_pool_t *scratch_pool);
@@ -511,4 +512,10 @@ svn_wc__db_update_move_list_notify(svn_w
                                    void *notify_baton,
                                    apr_pool_t *scratch_pool);
 
+svn_error_t *
+svn_wc__db_verify_db_full_internal(svn_wc__db_wcroot_t *wcroot,
+                                   svn_wc__db_verify_cb_t callback,
+                                   void *baton,
+                                   apr_pool_t *scratch_pool);
+
 #endif /* WC_DB_PRIVATE_H */

Modified: 
subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_update_move.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_update_move.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- 
subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_update_move.c 
(original)
+++ 
subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_update_move.c 
Tue Feb 24 15:23:33 2015
@@ -1228,7 +1228,7 @@ tc_editor_delete(node_move_baton_t *nmb,
 
   local_abspath = svn_dirent_join(b->wcroot->abspath, relpath, scratch_pool);
   SVN_ERR(svn_wc__node_has_local_mods(&is_modified, &is_all_deletes,
-                                      nmb->umb->db, local_abspath,
+                                      nmb->umb->db, local_abspath, FALSE,
                                       NULL, NULL, scratch_pool));
   if (is_modified)
     {
@@ -1242,7 +1242,7 @@ tc_editor_delete(node_move_baton_t *nmb,
             * it is not the/an op-root. (or we can't make us a copy)
        */
 
-      SVN_ERR(svn_wc__db_op_make_copy_internal(b->wcroot, relpath,
+      SVN_ERR(svn_wc__db_op_make_copy_internal(b->wcroot, relpath, FALSE,
                                                NULL, NULL, scratch_pool));
 
       reason = svn_wc_conflict_reason_edited;

Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_util.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_util.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_util.c 
(original)
+++ subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_util.c Tue 
Feb 24 15:23:33 2015
@@ -83,7 +83,7 @@ static svn_error_t *
 relpath_depth_sqlite(svn_sqlite__context_t *sctx,
                      int argc,
                      svn_sqlite__value_t *values[],
-                     apr_pool_t *scratch_pool)
+                     void *baton)
 {
   const char *path = NULL;
   apr_int64_t depth;

Modified: 
subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_wcroot.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_wcroot.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_wcroot.c 
(original)
+++ subversion/branches/svn-info-detail/subversion/libsvn_wc/wc_db_wcroot.c Tue 
Feb 24 15:23:33 2015
@@ -28,6 +28,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_hash.h"
 #include "svn_path.h"
+#include "svn_pools.h"
 #include "svn_version.h"
 
 #include "wc.h"
@@ -42,7 +43,7 @@
 #define UNKNOWN_WC_ID ((apr_int64_t) -1)
 #define FORMAT_FROM_SDB (-1)
 
-
+/* #define VERIFY_ON_CLOSE */
 
 /* Get the format version from a wc-1 directory. If it is not a working copy
    directory, then it sets VERSION to zero and returns no error.  */
@@ -162,6 +163,27 @@ svn_wc__db_verify_no_work(svn_sqlite__db
   return SVN_NO_ERROR;
 }
 
+#if defined(VERIFY_ON_CLOSE) && defined(SVN_DEBUG)
+/* Implements svn_wc__db_verify_cb_t */
+static svn_error_t *
+verify_db_cb(void *baton,
+             const char *wc_abspath,
+             const char *local_relpath,
+             int op_depth,
+             int id,
+             const char *msg,
+             apr_pool_t *scratch_pool)
+{
+  if (op_depth >= 0)
+    SVN_DBG(("DB-VRFY: %s: %s (%d): SV%04d %s",
+              wc_abspath, local_relpath, op_depth, id, msg));
+  else
+    SVN_DBG(("DB-VRFY: %s: %s: SV%04d %s",
+              wc_abspath, local_relpath, id, msg));
+
+  return SVN_NO_ERROR;
+}
+#endif
 
 /* */
 static apr_status_t
@@ -172,6 +194,18 @@ close_wcroot(void *data)
 
   SVN_ERR_ASSERT_NO_RETURN(wcroot->sdb != NULL);
 
+#if defined(VERIFY_ON_CLOSE) && defined(SVN_DEBUG)
+  if (getenv("SVN_CMDLINE_VERIFY_SQL_AT_CLOSE"))
+    {
+      apr_pool_t *scratch_pool = svn_pool_create(NULL);
+
+      svn_error_clear(svn_wc__db_verify_db_full_internal(
+                                    wcroot, verify_db_cb, NULL, scratch_pool));
+
+      svn_pool_destroy(scratch_pool);
+    }
+#endif
+
   err = svn_sqlite__close(wcroot->sdb);
   wcroot->sdb = NULL;
   if (err)

Modified: subversion/branches/svn-info-detail/subversion/libsvn_wc/workqueue.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/libsvn_wc/workqueue.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/libsvn_wc/workqueue.c 
(original)
+++ subversion/branches/svn-info-detail/subversion/libsvn_wc/workqueue.c Tue 
Feb 24 15:23:33 2015
@@ -143,8 +143,7 @@ run_base_remove(work_item_baton_t *wqb,
 
   SVN_ERR(svn_wc__db_base_remove(db, local_abspath,
                                  FALSE /* keep_as_working */,
-                                 TRUE /* queue_deletes */,
-                                 FALSE /* remove_locks */,
+                                 SVN_IS_VALID_REVNUM(not_present_rev), FALSE,
                                  not_present_rev,
                                  NULL, NULL, scratch_pool));
 

Modified: 
subversion/branches/svn-info-detail/subversion/mod_dav_svn/mod_dav_svn.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/mod_dav_svn/mod_dav_svn.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/mod_dav_svn/mod_dav_svn.c 
(original)
+++ subversion/branches/svn-info-detail/subversion/mod_dav_svn/mod_dav_svn.c 
Tue Feb 24 15:23:33 2015
@@ -143,6 +143,25 @@ init(apr_pool_t *p, apr_pool_t *plog, ap
   return OK;
 }
 
+static svn_error_t *
+malfunction_handler(svn_boolean_t can_return,
+                    const char *file, int line,
+                    const char *expr)
+{
+  if (expr)
+    ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL,
+                 "mod_dav_svn: file '%s', line %d, assertion \"%s\" failed",
+                 file, line, expr);
+  else
+    ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL,
+                 "mod_dav_svn: file '%s', line %d, internal malfunction",
+                 file, line);
+  abort();
+
+  /* Should not be reached. */
+  return SVN_NO_ERROR;
+}
+
 static int
 init_dso(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
 {
@@ -162,6 +181,8 @@ init_dso(apr_pool_t *pconf, apr_pool_t *
       return HTTP_INTERNAL_SERVER_ERROR;
     }
 
+  svn_error_set_malfunction_handler(malfunction_handler);
+
   return OK;
 }
 

Modified: subversion/branches/svn-info-detail/subversion/svn/blame-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/svn/blame-cmd.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/svn/blame-cmd.c (original)
+++ subversion/branches/svn-info-detail/subversion/svn/blame-cmd.c Tue Feb 24 
15:23:33 2015
@@ -31,6 +31,7 @@
 #include "svn_pools.h"
 #include "svn_props.h"
 #include "svn_cmdline.h"
+#include "svn_sorts.h"
 #include "svn_xml.h"
 #include "svn_time.h"
 #include "cl.h"
@@ -42,6 +43,8 @@ typedef struct blame_baton_t
   svn_cl__opt_state_t *opt_state;
   svn_stream_t *out;
   svn_stringbuf_t *sbuf;
+
+  int rev_maxlength;
 } blame_baton_t;
 
 
@@ -63,9 +66,9 @@ blame_receiver_xml(void *baton,
                    svn_boolean_t local_change,
                    apr_pool_t *pool)
 {
-  svn_cl__opt_state_t *opt_state =
-    ((blame_baton_t *) baton)->opt_state;
-  svn_stringbuf_t *sb = ((blame_baton_t *) baton)->sbuf;
+  blame_baton_t *bb = baton;
+  svn_cl__opt_state_t *opt_state = bb->opt_state;
+  svn_stringbuf_t *sb = bb->sbuf;
 
   /* "<entry ...>" */
   /* line_no is 0-based, but the rest of the world is probably Pascal
@@ -119,23 +122,13 @@ print_line_info(svn_stream_t *out,
                 const char *date,
                 const char *path,
                 svn_boolean_t verbose,
-                svn_revnum_t end_revnum,
+                int rev_maxlength,
                 apr_pool_t *pool)
 {
   const char *time_utf8;
   const char *time_stdout;
   const char *rev_str;
-  int rev_maxlength;
 
-  /* The standard column width for the revision number is 6 characters.
-     If the revision number can potentially be larger (i.e. if the end_revnum
-     is larger than 1000000), we increase the column width as needed. */
-  rev_maxlength = 6;
-  while (end_revnum >= 1000000)
-    {
-      rev_maxlength++;
-      end_revnum = end_revnum / 10;
-    }
   rev_str = SVN_IS_VALID_REVNUM(revision)
     ? apr_psprintf(pool, "%*ld", rev_maxlength, revision)
     : apr_psprintf(pool, "%*s", rev_maxlength, "-");
@@ -189,11 +182,26 @@ blame_receiver(void *baton,
                svn_boolean_t local_change,
                apr_pool_t *pool)
 {
-  svn_cl__opt_state_t *opt_state =
-    ((blame_baton_t *) baton)->opt_state;
-  svn_stream_t *out = ((blame_baton_t *)baton)->out;
+  blame_baton_t *bb = baton;
+  svn_cl__opt_state_t *opt_state = bb->opt_state;
+  svn_stream_t *out = bb->out;
   svn_boolean_t use_merged = FALSE;
 
+  if (!bb->rev_maxlength)
+    {
+      svn_revnum_t max_revnum = MAX(start_revnum, end_revnum);
+      /* The standard column width for the revision number is 6 characters.
+         If the revision number can potentially be larger (i.e. if the 
end_revnum
+          is larger than 1000000), we increase the column width as needed. */
+
+      bb->rev_maxlength = 6;
+      while (max_revnum >= 1000000)
+        {
+          bb->rev_maxlength++;
+          max_revnum = max_revnum / 10;
+        }
+    }
+
   if (opt_state->use_merge_history)
     {
       /* Choose which revision to use.  If they aren't equal, prefer the
@@ -216,7 +224,8 @@ blame_receiver(void *baton,
                                                SVN_PROP_REVISION_AUTHOR),
                             svn_prop_get_value(merged_rev_props,
                                                SVN_PROP_REVISION_DATE),
-                            merged_path, opt_state->verbose, end_revnum,
+                            merged_path, opt_state->verbose,
+                            bb->rev_maxlength,
                             pool));
   else
     SVN_ERR(print_line_info(out, revision,
@@ -224,7 +233,8 @@ blame_receiver(void *baton,
                                                SVN_PROP_REVISION_AUTHOR),
                             svn_prop_get_value(rev_props,
                                                SVN_PROP_REVISION_DATE),
-                            NULL, opt_state->verbose, end_revnum,
+                            NULL, opt_state->verbose,
+                            bb->rev_maxlength,
                             pool));
 
   return svn_stream_printf(out, pool, "%s%s", line, APR_EOL_STR);
@@ -286,6 +296,7 @@ svn_cl__blame(apr_getopt_t *os,
     bl.sbuf = svn_stringbuf_create_empty(pool);
 
   bl.opt_state = opt_state;
+  bl.rev_maxlength = 0;
 
   subpool = svn_pool_create(pool);
 

Modified: subversion/branches/svn-info-detail/subversion/svn/changelist-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/svn/changelist-cmd.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/svn/changelist-cmd.c 
(original)
+++ subversion/branches/svn-info-detail/subversion/svn/changelist-cmd.c Tue Feb 
24 15:23:33 2015
@@ -72,25 +72,7 @@ svn_cl__changelist(apr_getopt_t *os,
   SVN_ERR(svn_cl__check_targets_are_local_paths(targets));
 
   if (opt_state->quiet)
-    /* FIXME: This is required because svn_client_create_context()
-       always initializes ctx->notify_func2 to a wrapper function
-       which calls ctx->notify_func() if it isn't NULL.  In other
-       words, typically, ctx->notify_func2 is never NULL.  This isn't
-       usually a problem, but the changelist logic generates
-       svn_error_t's as part of its notification.
-
-       So, svn_wc_set_changelist() checks its notify_func (our
-       ctx->notify_func2) for NULL-ness, and seeing non-NULL-ness,
-       generates a notificaton object and svn_error_t to describe some
-       problem.  It passes that off to its notify_func (our
-       ctx->notify_func2) which drops the notification on the floor
-       (because it wraps a NULL ctx->notify_func).  But svn_error_t's
-       dropped on the floor cause SEGFAULTs at pool cleanup time --
-       they need instead to be cleared.
-
-       SOOOooo... we set our ctx->notify_func2 to NULL so the WC code
-       doesn't even generate the errors.  */
-    ctx->notify_func2 = NULL;
+    ctx->notify_func2 = NULL; /* Easy out: avoid unneeded work */
 
   if (depth == svn_depth_unknown)
     depth = svn_depth_empty;

Modified: subversion/branches/svn-info-detail/subversion/svn/commit-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/svn/commit-cmd.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/svn/commit-cmd.c (original)
+++ subversion/branches/svn-info-detail/subversion/svn/commit-cmd.c Tue Feb 24 
15:23:33 2015
@@ -137,7 +137,9 @@ svn_cl__commit(apr_getopt_t *os,
   if (opt_state->depth == svn_depth_unknown)
     opt_state->depth = svn_depth_infinity;
 
-  cfg = svn_hash_gets(ctx->config, SVN_CONFIG_CATEGORY_CONFIG);
+  cfg = ctx->config
+           ? svn_hash_gets(ctx->config, SVN_CONFIG_CATEGORY_CONFIG)
+           : NULL;
   if (cfg)
     SVN_ERR(svn_config_get_bool(cfg, &no_unlock,
                                 SVN_CONFIG_SECTION_MISCELLANY,

Modified: subversion/branches/svn-info-detail/subversion/svn/copy-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/svn/copy-cmd.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/svn/copy-cmd.c (original)
+++ subversion/branches/svn-info-detail/subversion/svn/copy-cmd.c Tue Feb 24 
15:23:33 2015
@@ -169,6 +169,7 @@ svn_cl__copy(apr_getopt_t *os,
 
   err = svn_client_copy7(sources, dst_path, TRUE,
                          opt_state->parents, opt_state->ignore_externals,
+                         FALSE /* metadata_only */,
                          opt_state->pin_externals,
                          NULL, /* pin all externals */
                          opt_state->revprop_table,

Modified: subversion/branches/svn-info-detail/subversion/svn/diff-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/svn/diff-cmd.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/svn/diff-cmd.c (original)
+++ subversion/branches/svn-info-detail/subversion/svn/diff-cmd.c Tue Feb 24 
15:23:33 2015
@@ -344,7 +344,7 @@ svn_cl__diff(apr_getopt_t *os,
     {
       ignore_content_type = TRUE;
     }
-  else
+  else if (ctx->config)
     {
       SVN_ERR(svn_config_get_bool(svn_hash_gets(ctx->config,
                                                 SVN_CONFIG_CATEGORY_CONFIG),
@@ -353,6 +353,10 @@ svn_cl__diff(apr_getopt_t *os,
                                   SVN_CONFIG_OPTION_DIFF_IGNORE_CONTENT_TYPE,
                                   FALSE));
     }
+  else
+    {
+      ignore_content_type = FALSE;
+    }
 
   svn_opt_push_implicit_dot_target(targets, pool);
 

Modified: subversion/branches/svn-info-detail/subversion/svn/status.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/svn/status.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/svn/status.c (original)
+++ subversion/branches/svn-info-detail/subversion/svn/status.c Tue Feb 24 
15:23:33 2015
@@ -138,37 +138,38 @@ generate_status_desc(enum svn_wc_status_
 
 /* Make a relative path containing '..' elements as needed.
    TARGET_ABSPATH shall be the absolute version of TARGET_PATH.
-   TARGET_ABSPATH, TARGET_PATH and PATH shall be canonical.
+   TARGET_ABSPATH, TARGET_PATH and LOCAL_ABSPATH shall be canonical
 
    If above conditions are met, a relative path that leads to PATH
    from TARGET_PATH is returned, but there is no error checking involved.
 
    The returned path is allocated from RESULT_POOL, all other
-   allocations are made in SCRATCH_POOL.  */
+   allocations are made in SCRATCH_POOL.
+
+   Note that it is not possible to just join the resulting path to
+   reconstruct the real path as the "../" paths are relative from
+   a different base than the normal relative paths!
+ */
 static const char *
 make_relpath(const char *target_abspath,
              const char *target_path,
-             const char *path,
+             const char *local_abspath,
              apr_pool_t *result_pool,
              apr_pool_t *scratch_pool)
 {
   const char *la;
   const char *parent_dir_els = "";
-  const char *abspath, *relative;
-  svn_error_t *err = svn_dirent_get_absolute(&abspath, path, scratch_pool);
+  const char *t_relpath;
+  const char *p_relpath;
 
-  if (err)
-    {
-      /* We probably got passed some invalid path. */
-      svn_error_clear(err);
-      return apr_pstrdup(result_pool, path);
-    }
+#ifdef SVN_DEBUG
+  SVN_ERR_ASSERT_NO_RETURN(svn_dirent_is_absolute(local_abspath));
+#endif
 
-  relative = svn_dirent_skip_ancestor(target_abspath, abspath);
-  if (relative)
-    {
-      return svn_dirent_join(target_path, relative, result_pool);
-    }
+  t_relpath = svn_dirent_skip_ancestor(target_abspath, local_abspath);
+
+  if (t_relpath)
+    return svn_dirent_join(target_path, t_relpath, result_pool);
 
   /* An example:
    *  relative_to_path = /a/b/c
@@ -180,17 +181,16 @@ make_relpath(const char *target_abspath,
    *  path             = C:/wc
    *  result           = C:/wc
    */
-
   /* Skip the common ancestor of both paths, here '/a'. */
-  la = svn_dirent_get_longest_ancestor(target_abspath, abspath,
+  la = svn_dirent_get_longest_ancestor(target_abspath, local_abspath,
                                        scratch_pool);
   if (*la == '\0')
     {
       /* Nothing in common: E.g. C:/ vs F:/ on Windows */
-      return apr_pstrdup(result_pool, path);
+      return apr_pstrdup(result_pool, local_abspath);
     }
-  relative = svn_dirent_skip_ancestor(la, target_abspath);
-  path = svn_dirent_skip_ancestor(la, path);
+  t_relpath = svn_dirent_skip_ancestor(la, target_abspath);
+  p_relpath = svn_dirent_skip_ancestor(la, local_abspath);
 
   /* In above example, we'd now have:
    *  relative_to_path = b/c
@@ -198,14 +198,14 @@ make_relpath(const char *target_abspath,
 
   /* Count the elements of relative_to_path and prepend as many '..' elements
    * to path. */
-  while (*relative)
+  while (*t_relpath)
     {
-      svn_dirent_split(&relative, NULL, relative,
-                       scratch_pool);
+      t_relpath = svn_dirent_dirname(t_relpath, scratch_pool);
       parent_dir_els = svn_dirent_join(parent_dir_els, "..", scratch_pool);
     }
 
-  return svn_dirent_join(parent_dir_els, path, result_pool);
+  /* This returns a ../ style path relative from the status target */
+  return svn_dirent_join(parent_dir_els, p_relpath, result_pool);
 }
 
 
@@ -232,8 +232,6 @@ print_status(const char *target_abspath,
   const char *moved_from_line = "";
   const char *moved_to_line = "";
 
-  path = make_relpath(target_abspath, target_path, path, pool, pool);
-
   /* For historic reasons svn ignores the property status for added nodes, even
      if these nodes were copied and have local property changes.
 
@@ -487,8 +485,6 @@ svn_cl__print_status_xml(const char *tar
     SVN_ERR(svn_wc_conflicted_p3(NULL, NULL, &tree_conflicted,
                                  ctx->wc_ctx, local_abspath, pool));
 
-  path = make_relpath(target_abspath, target_path, path, pool, pool);
-
   svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
                         "path", svn_dirent_local_style(path, pool),
                         SVN_VA_NULL);

Modified: subversion/branches/svn-info-detail/subversion/svn/svn.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/svn/svn.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/svn/svn.c (original)
+++ subversion/branches/svn-info-detail/subversion/svn/svn.c Tue Feb 24 
15:23:33 2015
@@ -510,12 +510,27 @@ const svn_opt_subcommand_desc2_t svn_cl_
     },
 
   { "blame", svn_cl__blame, {"praise", "annotate", "ann"}, N_
-    ("Output the content of specified files or\n"
-     "URLs with revision and author information in-line.\n"
-     "usage: blame TARGET[@REV]...\n"
+    ("Show when each line of a file was last (or\n"
+     "next) changed.\n"
+     "usage: blame [-rM:N] TARGET[@REV]...\n"
+     "\n"
+     "  Annotate each line of a file with the revision number and author of 
the\n"
+     "  last change (or optionally the next change) to that line.\n"
+     "\n"
+     "  With no revision range (same as -r0:REV), or with '-r M:N' where M < 
N,\n"
+     "  annotate each line that is present in revision N of the file, with\n"
+     "  the last revision at or before rN that changed or added the line,\n"
+     "  looking back no further than rM.\n"
+     "\n"
+     "  With a reverse revision range '-r M:N' where M > N,\n"
+     "  annotate each line that is present in revision N of the file, with\n"
+     "  the next revision after rN that changed or deleted the line,\n"
+     "  looking forward no further than rM.\n"
      "\n"
      "  If specified, REV determines in which revision the target is first\n"
-     "  looked up.\n"),
+     "  looked up.\n"
+     "\n"
+     "  Write the annotated result to standard output.\n"),
     {'r', 'v', 'g', opt_incremental, opt_xml, 'x', opt_force} },
 
   { "cat", svn_cl__cat, {0}, N_

Modified: subversion/branches/svn-info-detail/subversion/svn/util.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/svn/util.c?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/svn/util.c (original)
+++ subversion/branches/svn-info-detail/subversion/svn/util.c Tue Feb 24 
15:23:33 2015
@@ -204,7 +204,7 @@ svn_cl__make_log_msg_baton(void **baton,
                            apr_hash_t *config,
                            apr_pool_t *pool)
 {
-  struct log_msg_baton *lmb = apr_palloc(pool, sizeof(*lmb));
+  struct log_msg_baton *lmb = apr_pcalloc(pool, sizeof(*lmb));
 
   if (opt_state->filedata)
     {
@@ -237,8 +237,10 @@ svn_cl__make_log_msg_baton(void **baton,
                      SVN_CONFIG_OPTION_LOG_ENCODING,
                      NULL);
     }
+  else
+    lmb->message_encoding = NULL;
 
-  lmb->base_dir = base_dir ? base_dir : "";
+  lmb->base_dir = base_dir;
   lmb->tmpfile_left = NULL;
   lmb->config = config;
   lmb->keep_locks = opt_state->no_unlock;
@@ -390,14 +392,11 @@ svn_cl__get_log_message(const char **log
 
           if (! path)
             path = item->url;
-          else if (! *path)
-            path = ".";
-
-          if (! svn_path_is_url(path) && lmb->base_dir)
+          else if (lmb->base_dir)
             path = svn_dirent_is_child(lmb->base_dir, path, pool);
 
           /* If still no path, then just use current directory. */
-          if (! path)
+          if (! path || !*path)
             path = ".";
 
           if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_DELETE)
@@ -436,7 +435,8 @@ svn_cl__get_log_message(const char **log
       if (! lmb->non_interactive)
         {
           err = svn_cmdline__edit_string_externally(&msg_string, 
&lmb->tmpfile_left,
-                                                    lmb->editor_cmd, 
lmb->base_dir,
+                                                    lmb->editor_cmd,
+                                                    lmb->base_dir ? 
lmb->base_dir : "",
                                                     msg_string, "svn-commit",
                                                     lmb->config, TRUE,
                                                     lmb->message_encoding,

Modified: subversion/branches/svn-info-detail/subversion/tests/cmdline/README
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/README?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/tests/cmdline/README 
(original)
+++ subversion/branches/svn-info-detail/subversion/tests/cmdline/README Tue Feb 
24 15:23:33 2015
@@ -180,8 +180,8 @@ or if you're running an individual test,
 
 $ ./basic_tests.py --url=svn://localhost --enable-sasl 3
 
-Note that to do this you'll have to have a subversion.conf file in your
-SASL lib dir (i.e. something like /usr/lib/sasl2/subversion.conf), it
+Note that to do this you'll have to have a svn.conf file in your
+SASL lib dir (i.e. something like /usr/lib/sasl2/svn.conf), it
 should contain something like:
 
 pwcheck_method: auxprop
@@ -195,6 +195,16 @@ $ saslpasswd2 -c -u svntest jconstant
 
 As usual, both users should use the password 'rayjandom'.
 
+To enable DUMP_LOAD_CROSS_CHECK to work a third user is required,
+
+$ saslpasswd2 -c -u svntest __dumpster__
+
+with password '__loadster__'.
+
+The user running the tests will need read access to the sasl database
+and on some systems this can be arranged by adding the user to the sasl
+group.
+
 There are 'make svnserveautocheck' and ./svnserveautocheck.sh commands,
 analogous to davautocheck.sh documented above.
 

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/blame_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/blame_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/tests/cmdline/blame_tests.py 
(original)
+++ subversion/branches/svn-info-detail/subversion/tests/cmdline/blame_tests.py 
Tue Feb 24 15:23:33 2015
@@ -748,7 +748,7 @@ def blame_output_after_merge(sbox):
   # Next test with the -g option with -rN:M
   expected_output = [ "       -          - New version of file 'mu'.\n",
                       "       -          - 2nd line in file 'mu'.\n",
-                      "G      -          - new 3rd line in file 'mu'.\n",
+                      "G      5    jrandom new 3rd line in file 'mu'.\n",
                       "G      6    jrandom add 3.5 line in file 'mu'.\n",
                       "       -          - 4th line in file 'mu'.\n",
                       "       -          - 5th line in file 'mu'.\n",
@@ -950,23 +950,115 @@ def blame_youngest_to_oldest(sbox):
   orig_line = open(iota).read()
   line = "New contents for iota\n"
   svntest.main.file_append(iota, line)
-  sbox.simple_commit()
+  sbox.simple_commit() #r2
 
   # Move the file, to check that the operation will peg correctly.
   iota_moved = sbox.ospath('iota_moved')
   sbox.simple_move('iota', 'iota_moved')
-  sbox.simple_commit()
+  sbox.simple_commit() #r3
 
   # Delete a line.
   open(iota_moved, 'w').write(line)
-  sbox.simple_commit()
+  sbox.simple_commit() #r4
 
   expected_output = [
-        '     %d    jrandom %s\n' % (3, orig_line[:-1]),
+        '     %d    jrandom %s\n' % (4, orig_line[:-1]),
   ]
   svntest.actions.run_and_verify_svn(expected_output, [],
                                      'blame', '-r4:1', iota_moved)
 
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-rHEAD:1', iota_moved)
+
+  expected_output = [
+        '     %d    jrandom %s\n' % (2, line[:-1]),
+  ]
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-r1:HEAD', iota_moved)
+
+@Issue(4467)
+def blame_reverse_no_change(sbox):
+  "blame reverse towards a revision with no change"
+
+  sbox.build()
+
+  # Introduce a revision where iota doesn't change!
+  sbox.simple_propset('a', 'b', 'A')
+  sbox.simple_commit('') #r2
+
+  sbox.simple_append('iota', 'new line\n')
+  sbox.simple_commit('') #r3
+
+  sbox.simple_append('iota', 'another new line\n')
+  sbox.simple_commit('') #r4
+
+  expected_output = [
+    '     -          - This is the file \'iota\'.\n',
+    '     3    jrandom new line\n',
+    '     4    jrandom another new line\n',
+  ]
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-r2:HEAD', sbox.ospath('iota'))
+
+  expected_output = [
+    '     -          - This is the file \'iota\'.\n',
+  ]
+  # This used to trigger an assertion on 1.9.x before 1.9.0
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-rHEAD:2', sbox.ospath('iota'))
+
+  # Drop the middle line
+  sbox.simple_append('iota', 'This is the file \'iota\'.\n'
+                             'another new line\n', truncate=True)
+  sbox.simple_commit('') #r5
+
+  # Back to start
+  sbox.simple_append('iota', 'This is the file \'iota\'.\n', truncate=True)
+  sbox.simple_commit('') #r6
+
+  expected_output = [
+    '     -          - This is the file \'iota\'.\n',
+  ]
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-rHEAD:2', sbox.ospath('iota'))
+
+  expected_output = [
+    '     -          - This is the file \'iota\'.\n',
+    '     5    jrandom new line\n',
+  ]
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-rHEAD:3', sbox.ospath('iota'))
+
+  expected_output = [
+    '     -          - This is the file \'iota\'.\n',
+    '     5    jrandom new line\n',
+    '     6    jrandom another new line\n',
+  ]
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-rHEAD:4', sbox.ospath('iota'))
+
+  expected_output = [
+    '     -          - This is the file \'iota\'.\n',
+    '     6    jrandom another new line\n',
+  ]
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-rHEAD:5', sbox.ospath('iota'))
+
+  expected_output = [
+    '     -          - This is the file \'iota\'.\n',
+  ]
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-rHEAD:6', sbox.ospath('iota'))
+
+
+  expected_output = [
+    '     -          - This is the file \'iota\'.\n',
+    '     5    jrandom new line\n',
+  ]
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'blame', '-r5:3', sbox.ospath('iota'))
+
+
 ########################################################################
 # Run the tests
 
@@ -991,6 +1083,7 @@ test_list = [ None,
               blame_multiple_targets,
               blame_eol_handling,
               blame_youngest_to_oldest,
+              blame_reverse_no_change,
              ]
 
 if __name__ == '__main__':

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/copy_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/copy_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/tests/cmdline/copy_tests.py 
(original)
+++ subversion/branches/svn-info-detail/subversion/tests/cmdline/copy_tests.py 
Tue Feb 24 15:23:33 2015
@@ -1005,8 +1005,7 @@ def repos_to_wc(sbox):
 
   expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_output.add({
-    'pi' : Item(status='A ',  wc_rev='0', entry_rev='1'),
-    # And from the foreign repository
+    'pi'            : Item(status='A ', wc_rev='0'),
     'E'             : Item(status='A ', wc_rev='0'),
     'E/beta'        : Item(status='A ', wc_rev='0'),
     'E/alpha'       : Item(status='A ', wc_rev='0'),
@@ -1762,7 +1761,34 @@ def mixed_wc_to_url(sbox):
                                      'mkdir', Y_path)
 
   # Now copy local A/D/G to create new directory A/D/Z the repository.
-  svntest.actions.run_and_verify_svn(None, [],
+
+  expected_status = svntest.wc.State(G_path, {
+    ''                  : Item(status='  ', wc_rev='1'),
+    'X'                 : Item(status='A ', copied='+', wc_rev='-'),
+    'X/F'               : Item(status='  ', copied='+', wc_rev='-'),
+    'X/E'               : Item(status='  ', copied='+', wc_rev='-'),
+    'X/E/alpha'         : Item(status='D ', copied='+', wc_rev='-'),
+    'X/E/beta'          : Item(status='  ', copied='+', wc_rev='-'),
+    'X/lambda'          : Item(status='  ', copied='+', wc_rev='-'),
+    'Y'                 : Item(status='A ', wc_rev='-'),
+    'rho'               : Item(status='M ', wc_rev='3'),
+    'tau'               : Item(status='  ', wc_rev='1'),
+  })
+
+  svntest.actions.run_and_verify_status(G_path, expected_status)
+
+  expected_output = svntest.verify.UnorderedOutput([
+      'Adding copy of        %s\n' % sbox.ospath('A/D/G'),
+      'Adding copy of        %s\n' % sbox.ospath('A/D/G/X'),
+      'Deleting copy of      %s\n' % sbox.ospath('A/D/G/X/E/alpha'),
+      'Adding copy of        %s\n' % sbox.ospath('A/D/G/Y'),
+      'Deleting copy of      %s\n' % sbox.ospath('A/D/G/pi'),
+      'Replacing copy of     %s\n' % sbox.ospath('A/D/G/rho'),
+      'Transmitting file data .done\n',
+      'Committing transaction...\n',
+      'Committed revision 4.\n',
+  ])
+  svntest.actions.run_and_verify_svn(expected_output, [],
                                      'cp', '-m', "Make a copy.",
                                      G_path, Z_url)
   expected_output = svntest.verify.UnorderedOutput([
@@ -5430,6 +5456,13 @@ def copy_and_move_conflicts(sbox):
                          'D/G/pi',
                          'D/G/rho',
                          'D/G/tau')
+  expected_status.tweak('B', moved_from='../A/B')
+  expected_status.tweak('D', moved_from='../A/D')
+  expected_status.tweak('H', moved_from='D/H')
+  expected_status.tweak('Q', moved_from='../A/Q')
+  expected_status.tweak('D/H', moved_to='H')
+  expected_status.tweak('alpha', moved_from='B/E/alpha')
+  expected_status.tweak('B/E/alpha', moved_to='alpha')
   svntest.actions.run_and_verify_status(wc('move-dest'), expected_status)
 
   expected_disk = svntest.wc.State('', {

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/depth_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/depth_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/tests/cmdline/depth_tests.py 
(original)
+++ subversion/branches/svn-info-detail/subversion/tests/cmdline/depth_tests.py 
Tue Feb 24 15:23:33 2015
@@ -1955,22 +1955,29 @@ def fold_tree_with_unversioned_modified_
   # Fold the A dir to empty, expect the modified & unversioned ones left
   # unversioned rather than removed, along with paths to those items.
 
-  # Even though the directory B and D is not deleted because of local
-  # modificatoin or unversioned items, there will be only one notification at
-  # B and D.
+  # Directories B and D won't be deleted, because that would remove their
+  # local modifications. Their unmodified descendants are deleted though.
   expected_output = svntest.wc.State(wc_dir, {
-    'A/B'            : Item(status='D '),
+    'A/B/E'          : Item(status='D '),
+    'A/B/F'          : Item(status='D '),
+    'A/B/lambda'     : Item(status='D '),
     'A/C'            : Item(status='D '),
-    'A/D'            : Item(status='D '),
-    'A/mu'           : Item(status='D '),
+    'A/D/G/rho'      : Item(status='D '),
+    'A/D/G/tau'      : Item(status='D '),
+    'A/D/H'          : Item(status='D '),
+    'A/D/gamma'      : Item(status='D '),
     })
   # unversioned items will be ignored in in the status tree, since the
   # run_and_verify_update() function uses a quiet version of svn status
-  # Dir A is still versioned, since the wc root is in depth-infinity
   expected_status = svntest.wc.State(wc_dir, {
     ''               : Item(status='  ', wc_rev=1),
     'iota'           : Item(status='  ', wc_rev=1),
-    'A'              : Item(status='  ', wc_rev=1)
+    'A'              : Item(status='  ', wc_rev=1),
+    'A/D'            : Item(status='  ', wc_rev='1'),
+    'A/D/G'          : Item(status='  ', wc_rev='1'),
+    'A/D/G/pi'       : Item(status='M ', wc_rev='1'),
+    'A/B'            : Item(status='  ', wc_rev='1'),
+    'A/mu'           : Item(status='M ', wc_rev='1'),
     })
   expected_disk = svntest.wc.State('', {
     'iota'           : Item(contents="This is the file 'iota'.\n"),
@@ -2886,6 +2893,82 @@ def spurious_nodes_row(sbox):
     # ra_neon added a spurious not-present row that does not show up in status
     raise svntest.Failure("count changed from '%s' to '%s'" % (val1, val2))
 
+def commit_excluded(sbox):
+  "commit an excluded node"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/D/G' : Item(status='D '),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.remove('A/D/G', 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau')
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        expected_status,
+                                        None, None, None, None, None, False,
+                                        "--set-depth=exclude",
+                                        sbox.ospath('A/D/G'))
+
+  sbox.simple_copy('A/D', 'D')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'D' : Item(verb='Adding'),
+  })
+  
+  expected_status.add({
+    'D'          : Item(status='  ', wc_rev='2'),
+    'D/H'        : Item(status='  ', wc_rev='2'),
+    'D/H/chi'    : Item(status='  ', wc_rev='2'),
+    'D/H/psi'    : Item(status='  ', wc_rev='2'),
+    'D/H/omega'  : Item(status='  ', wc_rev='2'),
+    'D/gamma'    : Item(status='  ', wc_rev='2')
+  })
+
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        expected_output,
+                                        expected_status,
+                                        None, wc_dir)
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/D/G'     : Item(status='A '),
+    'A/D/G/pi'  : Item(status='A '),
+    'A/D/G/tau' : Item(status='A '),
+    'A/D/G/rho' : Item(status='A '),
+    'D/G'       : Item(status='A '),
+    'D/G/pi'    : Item(status='A '),
+    'D/G/tau'   : Item(status='A '),
+    'D/G/rho'   : Item(status='A ')
+  })
+
+  expected_status.tweak(wc_rev=2)
+
+  expected_status.add({
+    'D'         : Item(status='  ', wc_rev='2'),
+    'D/G'       : Item(status='  ', wc_rev='2'),
+    'D/G/pi'    : Item(status='  ', wc_rev='2'),
+    'D/G/rho'   : Item(status='  ', wc_rev='2'),
+    'D/G/tau'   : Item(status='  ', wc_rev='2'),
+    'D/H'       : Item(status='  ', wc_rev='2'),
+    'D/H/chi'   : Item(status='  ', wc_rev='2'),
+    'D/H/psi'   : Item(status='  ', wc_rev='2'),
+    'D/H/omega' : Item(status='  ', wc_rev='2'),
+    'D/gamma'   : Item(status='  ', wc_rev='2'),
+    'A/D/G'     : Item(status='  ', wc_rev='2'),
+    'A/D/G/rho' : Item(status='  ', wc_rev='2'),
+    'A/D/G/tau' : Item(status='  ', wc_rev='2'),
+    'A/D/G/pi'  : Item(status='  ', wc_rev='2')
+  })
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        expected_status,
+                                        None, None, None, None, None, False,
+                                        "--set-depth=infinity", wc_dir)
 
 #----------------------------------------------------------------------
 # list all tests here, starting with None:
@@ -2937,6 +3020,7 @@ test_list = [ None,
               commit_then_immediates_update,
               revert_depth_files,
               spurious_nodes_row,
+              commit_excluded,
               ]
 
 if __name__ == "__main__":

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/externals_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/externals_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- 
subversion/branches/svn-info-detail/subversion/tests/cmdline/externals_tests.py 
(original)
+++ 
subversion/branches/svn-info-detail/subversion/tests/cmdline/externals_tests.py 
Tue Feb 24 15:23:33 2015
@@ -3343,7 +3343,6 @@ def file_external_versioned_obstruction(
                                         expected_status)
 
 @Issue(4495)
-@XFail()
 def update_external_peg_rev(sbox):
   "update external peg rev"
 
@@ -3873,6 +3872,207 @@ def copy_pin_externals_wc_mixed_revision
                                      os.path.join(wc_dir, 'A_copy'),
                                      '--pin-externals')
 
+@Issue(4558)
+def copy_pin_externals_whitepace_dir(sbox):
+  "copy --pin-externals with whitepace dir"
+
+  sbox.build(empty=True)
+  repo_url = sbox.repo_url
+  wc_dir = sbox.wc_dir
+  ss_path = repo_url[repo_url.find('//'):]
+
+  extdef = sbox.get_tempname('extdef')
+  info = sbox.get_tempname('info')
+
+  open(extdef, 'w').write(
+      '"' + ss_path +'/deps/sqlite"  ext/sqlite\n' +
+      '"^/deps/A P R" \'ext/A P R\'\n' +
+      '^/deps/B\ D\ B\' ext/B\ D\ B\'\n' +
+      repo_url + '/deps/wors%23+t ext/wors#+t')
+  open(info, 'w').write('info\n')
+
+  svntest.actions.run_and_verify_svnmucc(None, [], '-U', repo_url,
+                                         'mkdir', 'trunk',
+                                         'mkdir', 'branches',
+                                         'mkdir', 'deps',
+                                         'mkdir', 'deps/sqlite',
+                                         'put', info, 'deps/sqlite/readme',
+                                         'mkdir', 'deps/A P R',
+                                         'put', info, 'deps/A P R/about',
+                                         'mkdir', 'deps/B D B\'',
+                                         'put', info, 'deps/B D B\'/copying',
+                                         'mkdir', 'deps/wors#+t',
+                                         'put', info, 'deps/wors#+t/brood',
+                                         'propsetf', 'svn:externals', extdef,
+                                                    'trunk',
+                                         '-mm'
+                                         )
+
+  svntest.actions.run_and_verify_svn(None, [], 'update', sbox.ospath('trunk'),
+                                     '--ignore-externals')
+  sbox.simple_update('branches')
+
+  expected_status = svntest.wc.State(wc_dir, {
+    ''                          : Item(status='  ', wc_rev='0'),
+    'trunk'                     : Item(status='  ', wc_rev='1'),
+    'branches'                  : Item(status='  ', wc_rev='1'),
+  })
+
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+  trunk_url = repo_url + '/trunk'
+  branches_url = repo_url + '/branches'
+  trunk_wc = sbox.ospath('trunk')
+
+  # Create a new revision to creat interesting pinning revisions
+  sbox.simple_propset('A', 'B', 'trunk')
+  sbox.simple_commit('trunk')
+
+  # And let's copy/pin
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', '--pin-externals',
+                                     trunk_url, branches_url + '/url-url', 
'-mm')
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', '--pin-externals',
+                                     trunk_url, sbox.ospath('branches/url-wc'))
+  sbox.simple_commit('branches/url-wc')
+
+  # Now try to copy without externals in the WC
+  expected_err = '.*E155035: Cannot pin external.*'
+  svntest.actions.run_and_verify_svn(None, expected_err,
+                                     'copy', '--pin-externals',
+                                     trunk_wc, branches_url + '/wc-url', '-mm')
+
+  svntest.actions.run_and_verify_svn(None, expected_err,
+                                     'copy', '--pin-externals',
+                                     trunk_wc, sbox.ospath('branches/wc-wc'))
+
+  # Bring in the externals on trunk
+  svntest.actions.run_and_verify_svn(None, [], 'update', sbox.ospath('trunk'))
+  expected_status = svntest.wc.State(wc_dir, {
+    'trunk'                     : Item(status='  ', wc_rev='4'),
+    'trunk/ext'                 : Item(status='X '),
+    'trunk/ext/sqlite'          : Item(status='  ', wc_rev='4'),
+    'trunk/ext/sqlite/readme'   : Item(status='  ', wc_rev='4'),
+    'trunk/ext/A P R'           : Item(status='  ', wc_rev='4'),
+    'trunk/ext/A P R/about'     : Item(status='  ', wc_rev='4'),
+    'trunk/ext/B D B\''         : Item(status='  ', wc_rev='4'),
+    'trunk/ext/B D B\'/copying' : Item(status='  ', wc_rev='4'),
+    'trunk/ext/wors#+t'         : Item(status='  ', wc_rev='4'),
+    'trunk/ext/wors#+t/brood'   : Item(status='  ', wc_rev='4'),
+  })
+  svntest.actions.run_and_verify_status(sbox.ospath('trunk'), expected_status)
+
+  # And copy again
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', '--pin-externals',
+                                     trunk_wc, branches_url + '/wc-url', '-mm')
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', '--pin-externals',
+                                     trunk_wc, sbox.ospath('branches/wc-wc'))
+  sbox.simple_commit('branches/wc-wc')
+
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'branches/url-url'                      : Item(status='A '),
+    'branches/url-url/ext/A P R/about'      : Item(status='A '),
+    'branches/url-url/ext/B D B\'/copying'  : Item(status='A '),
+    'branches/url-url/ext/wors#+t/brood'    : Item(status='A '),
+    'branches/url-url/ext/sqlite/readme'    : Item(status='A '),
+
+    # url-wc is already up to date
+
+    'branches/wc-url'                       : Item(status='A '),
+    'branches/wc-url/ext/wors#+t/brood'     : Item(status='A '),
+    'branches/wc-url/ext/sqlite/readme'     : Item(status='A '),
+    'branches/wc-url/ext/B D B\'/copying'   : Item(status='A '),
+    'branches/wc-url/ext/A P R/about'       : Item(status='A '),
+
+    ## branches/wc-wc should checkout its externals here
+  })
+  expected_status = svntest.wc.State(wc_dir, {
+    'branches'                              : Item(status='  ', wc_rev='6'),
+
+    'branches/url-url'                      : Item(status='  ', wc_rev='6'),
+    'branches/url-url/ext'                  : Item(status='X '),
+    'branches/url-url/ext/A P R'            : Item(status='  ', wc_rev='2'),
+    'branches/url-url/ext/A P R/about'      : Item(status='  ', wc_rev='2'),
+    'branches/url-url/ext/sqlite'           : Item(status='  ', wc_rev='2'),
+    'branches/url-url/ext/sqlite/readme'    : Item(status='  ', wc_rev='2'),
+    'branches/url-url/ext/wors#+t'          : Item(status='  ', wc_rev='2'),
+    'branches/url-url/ext/wors#+t/brood'    : Item(status='  ', wc_rev='2'),
+    'branches/url-url/ext/B D B\''          : Item(status='  ', wc_rev='2'),
+    'branches/url-url/ext/B D B\'/copying'  : Item(status='  ', wc_rev='2'),
+
+    'branches/url-wc'                       : Item(status='  ', wc_rev='6'),
+    'branches/url-wc/ext'                   : Item(status='X '),
+    'branches/url-wc/ext/wors#+t'           : Item(status='  ', wc_rev='3'),
+    'branches/url-wc/ext/wors#+t/brood'     : Item(status='  ', wc_rev='3'),
+    'branches/url-wc/ext/B D B\''           : Item(status='  ', wc_rev='3'),
+    'branches/url-wc/ext/B D B\'/copying'   : Item(status='  ', wc_rev='3'),
+    'branches/url-wc/ext/sqlite'            : Item(status='  ', wc_rev='3'),
+    'branches/url-wc/ext/sqlite/readme'     : Item(status='  ', wc_rev='3'),
+    'branches/url-wc/ext/A P R'             : Item(status='  ', wc_rev='3'),
+    'branches/url-wc/ext/A P R/about'       : Item(status='  ', wc_rev='3'),
+
+    'branches/wc-url'                       : Item(status='  ', wc_rev='6'),
+    'branches/wc-url/ext'                   : Item(status='X '),
+    'branches/wc-url/ext/wors#+t'           : Item(status='  ', wc_rev='4'),
+    'branches/wc-url/ext/wors#+t/brood'     : Item(status='  ', wc_rev='4'),
+    'branches/wc-url/ext/sqlite'            : Item(status='  ', wc_rev='4'),
+    'branches/wc-url/ext/sqlite/readme'     : Item(status='  ', wc_rev='4'),
+    'branches/wc-url/ext/B D B\''           : Item(status='  ', wc_rev='4'),
+    'branches/wc-url/ext/B D B\'/copying'   : Item(status='  ', wc_rev='4'),
+    'branches/wc-url/ext/A P R'             : Item(status='  ', wc_rev='4'),
+    'branches/wc-url/ext/A P R/about'       : Item(status='  ', wc_rev='4'),
+
+    'branches/wc-wc'                        : Item(status='  ', wc_rev='6'),
+    'branches/wc-wc/ext'                    : Item(status='X '),
+    'branches/wc-wc/ext/wors#+t'            : Item(status='  ', wc_rev='4'),
+    'branches/wc-wc/ext/wors#+t/brood'      : Item(status='  ', wc_rev='4'),
+    'branches/wc-wc/ext/sqlite'             : Item(status='  ', wc_rev='4'),
+    'branches/wc-wc/ext/sqlite/readme'      : Item(status='  ', wc_rev='4'),
+    'branches/wc-wc/ext/B D B\''            : Item(status='  ', wc_rev='4'),
+    'branches/wc-wc/ext/B D B\'/copying'    : Item(status='  ', wc_rev='4'),
+    'branches/wc-wc/ext/A P R'              : Item(status='  ', wc_rev='4'),
+    'branches/wc-wc/ext/A P R/about'        : Item(status='  ', wc_rev='4'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir + '/branches', expected_output,
+                                        None, expected_status, [])
+
+  # Now let's use our existing setup to perform some copies with dynamic
+  # destinations
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', '--parents', '--pin-externals',
+                                     repo_url + '/branches/wc-url',
+                                     repo_url + '/branches/url-url',
+                                     trunk_url,
+                                     branches_url + '/3x-url-url',
+                                     '-mm')
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', '--parents', '--pin-externals',
+                                     repo_url + '/branches/wc-url',
+                                     repo_url + '/branches/url-url',
+                                     trunk_url,
+                                     sbox.ospath('branches/3x-url-wc'))
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', '--parents', '--pin-externals',
+                                     sbox.ospath('branches/wc-url'),
+                                     sbox.ospath('branches/url-url'),
+                                     sbox.ospath('trunk'),
+                                     branches_url + '/3x-wc-url',
+                                     '-mm')
+
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'copy', '--parents', '--pin-externals',
+                                     sbox.ospath('branches/wc-url'),
+                                     sbox.ospath('branches/url-url'),
+                                     sbox.ospath('trunk'),
+                                     sbox.ospath('branches/3x-wc-wc'))
 
 def nested_notification(sbox):
   "notification for nested externals"
@@ -3981,6 +4181,7 @@ test_list = [ None,
               copy_pin_externals_wc_local_mods,
               copy_pin_externals_wc_switched_subtrees,
               copy_pin_externals_wc_mixed_revisions,
+              copy_pin_externals_whitepace_dir,
               nested_notification,
              ]
 

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/info_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/info_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/tests/cmdline/info_tests.py 
(original)
+++ subversion/branches/svn-info-detail/subversion/tests/cmdline/info_tests.py 
Tue Feb 24 15:23:33 2015
@@ -591,6 +591,51 @@ def relpath_escaping(sbox):
   svntest.actions.run_and_verify_update(wc_dir,
                                         expected_output, None, None)
 
+def node_hidden_info(sbox):
+  "fetch svn info on 'hidden' nodes"
+
+  sbox.build()
+
+  sbox.simple_rm('A/B/E/alpha')
+  sbox.simple_commit()
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'up', '--set-depth', 'exclude',
+                                     sbox.ospath('A/B/E/beta'))
+
+  sbox.simple_copy('A/B/E', 'E')
+
+  # Running info on BASE not-present fails
+  expected_err = '.*(E|W)155010: The node \'.*alpha\' was not found.*'
+  svntest.actions.run_and_verify_svn(None, expected_err,
+                                     'info', sbox.ospath('A/B/E/alpha'))
+
+  expected_info = [
+    {
+        'Path': re.escape(sbox.ospath('A/B/E/beta')),
+        'Schedule': 'normal',
+        'Depth': 'exclude',
+        'Node Kind': 'file',
+    },
+    {
+        'Path': re.escape(sbox.ospath('E/alpha')),
+        'Schedule': 'delete',
+        'Depth': 'exclude',
+        'Node Kind': 'unknown',
+    },
+    {
+        'Path': re.escape(sbox.ospath('E/beta')),
+        'Schedule': 'normal',
+        'Depth': 'exclude',
+        'Node Kind': 'file',
+    }
+  ]
+
+  svntest.actions.run_and_verify_info(expected_info,
+                                      sbox.ospath('A/B/E/beta'),
+                                      sbox.ospath('E/alpha'),
+                                      sbox.ospath('E/beta'))
+
+
 ########################################################################
 # Run the tests
 
@@ -606,6 +651,7 @@ test_list = [ None,
               info_show_exclude,
               binary_tree_conflict,
               relpath_escaping,
+              node_hidden_info,
              ]
 
 if __name__ == '__main__':

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/lock_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/lock_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/tests/cmdline/lock_tests.py 
(original)
+++ subversion/branches/svn-info-detail/subversion/tests/cmdline/lock_tests.py 
Tue Feb 24 15:23:33 2015
@@ -1997,7 +1997,6 @@ def failing_post_hooks(sbox):
                                      'unlock', pi_path)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
-@XFail()
 def break_delete_add(sbox):
   "break a lock, delete and add the file"
 
@@ -2384,22 +2383,20 @@ def delete_dir_with_lots_of_locked_files
   nfiles = 75 # NOTE: test XPASSES with 50 files!!!
   locked_paths = []
   for i in range(nfiles):
-      locked_paths.append("A/locked_files/file-%i" % i)
+      locked_paths.append(sbox.ospath("A/locked_files/file-%i" % i))
 
   # Create files at these paths
   os.mkdir(sbox.ospath("A/locked_files"))
   for file_path in locked_paths:
-    svntest.main.file_write(sbox.ospath(file_path), "This is a file\n")
+    svntest.main.file_write(file_path, "This is '%s'.\n" % (file_path,))
   sbox.simple_add("A/locked_files")
   sbox.simple_commit()
   sbox.simple_update()
 
   # lock all the files
-  for file_path in locked_paths:
-    svntest.actions.run_and_verify_svn(None, [], 'lock',
-                                       '--username', 'jrandom',
-                                       '-m', 'lock %s' % file_path,
-                                       sbox.ospath(file_path))
+  svntest.actions.run_and_verify_svn(None, [], 'lock',
+                                     '-m', 'All locks',
+                                      *locked_paths)
   # Locally delete A
   sbox.simple_rm("A")
 
@@ -2411,6 +2408,62 @@ def delete_dir_with_lots_of_locked_files
   # This problem was introduced on the 1.8.x branch in r1606976.
   sbox.simple_commit()
 
+def delete_locks_on_depth_commit(sbox):
+  "delete locks on depth-limited commit"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  svntest.actions.run_and_verify_svn(None, [], 'lock',
+                                     '-m', 'All files',
+                                      *(sbox.ospath(x)
+                                        for x in ['iota', 'A/B/E/alpha',
+                                                  'A/B/E/beta', 'A/B/lambda',
+                                                  'A/D/G/pi', 'A/D/G/rho',
+                                                  'A/D/G/tau', 'A/D/H/chi',
+                                                  'A/D/H/omega', 'A/D/H/psi',
+                                                  'A/D/gamma', 'A/mu']))
+
+  sbox.simple_rm("A")
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'A' : Item(verb='Deleting'),
+  })
+
+  expected_status = svntest.wc.State(wc_dir, {
+    ''      : Item(status='  ', wc_rev='1'),
+    'iota'  : Item(status='  ', wc_rev='1'),
+  })
+
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, [],
+                                        wc_dir, '--depth', 'immediates')
+
+  sbox.simple_update() # r2
+
+  svntest.actions.run_and_verify_svn(None, [], 'cp',
+                                     sbox.repo_url + '/A@1', sbox.ospath('A'))
+
+  expected_output = [
+    'Adding         %s\n' % sbox.ospath('A'),
+    'svn: The depth of this commit is \'immediates\', but copies ' \
+        'are always performed recursively in the repository.\n',
+    'Committing transaction...\n',
+    'Committed revision 3.\n',
+  ]
+
+  # Verifying the warning line... so can't use verify_commit()
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'commit', wc_dir, '--depth', 'immediates',
+                                     '-mm')
+
+  # Verify that all locks are gone at the server and at the client
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+  expected_status.tweak('', 'iota', wc_rev=2)
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+
+
 ########################################################################
 # Run the tests
 
@@ -2477,6 +2530,7 @@ test_list = [ None,
               lock_commit_bump,
               copy_dir_with_locked_file,
               delete_dir_with_lots_of_locked_files,
+              delete_locks_on_depth_commit,
             ]
 
 if __name__ == '__main__':

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/log_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/log_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/tests/cmdline/log_tests.py 
(original)
+++ subversion/branches/svn-info-detail/subversion/tests/cmdline/log_tests.py 
Tue Feb 24 15:23:33 2015
@@ -2618,6 +2618,77 @@ def merge_sensitive_log_xml_reverse_merg
   svntest.actions.run_and_verify_log_xml(expected_log_attrs=log_attrs,
                                          args=['-g', '-r8', D_COPY_path])
 
+def log_revision_move_copy(sbox):
+  "log revision handling over move/copy"
+
+  sbox.build()
+
+  sbox.simple_move('iota', 'iotb')
+  sbox.simple_append('iotb', 'new line\n')
+
+  sbox.simple_copy('A/mu', 'mutb')
+  sbox.simple_append('mutb', 'mutb\n')
+
+  sbox.simple_move('A/B/E', 'E')
+  sbox.simple_move('E/alpha', 'alpha')
+
+  #r2
+  svntest.actions.run_and_verify_svn(None, [],
+                                     'rm', sbox.repo_url + '/A/D', '-mm')
+
+  sbox.simple_commit() #r3
+
+  # This introduces a copy and a move in r3, but check how the history
+  # of these nodes behaves in r2.
+
+  # This one might change behavior once we improve move handling
+  expected_output = [
+    
'------------------------------------------------------------------------\n'
+  ]
+  expected_err = []
+  svntest.actions.run_and_verify_svn(expected_output, expected_err,
+                                     'log', '-v',sbox.ospath('iotb'),
+                                     '-r2')
+
+  # While this one
+  expected_output = []
+  expected_err = '.*E195012: Unable to find repository location.*'
+  svntest.actions.run_and_verify_svn(expected_output, expected_err,
+                                     'log', '-v', sbox.ospath('mutb'),
+                                     '-r2')
+
+  # And just for fun, do the same thing for blame
+  expected_output = [
+    '     1    jrandom This is the file \'iota\'.\n'
+  ]
+  expected_err = []
+  svntest.actions.run_and_verify_svn(expected_output, expected_err,
+                                     'blame', sbox.ospath('iotb'),
+                                     '-r2')
+
+  expected_output = None
+  expected_err = '.*E195012: Unable to find repository location.*'
+  svntest.actions.run_and_verify_svn(expected_output, expected_err,
+                                     'blame', sbox.ospath('mutb'),
+                                     '-r2')
+
+  expected_output = svntest.verify.RegexListOutput([
+    '-+\\n',
+    'r3\ .*\n',
+    re.escape('Changed paths:\n'),
+    re.escape('   D /A/B/E\n'),
+    re.escape('   A /E (from /A/B/E:2)\n'), # Patched - Direct move
+    re.escape('   D /E/alpha\n'),
+    re.escape('   A /alpha (from /A/B/E/alpha:1)\n'), # Indirect move - Not 
patched
+    re.escape('   D /iota\n'),
+    re.escape('   A /iotb (from /iota:2)\n'), # Patched - Direct move
+    re.escape('   A /mutb (from /A/mu:1)\n'), # Copy (always r1)
+    '-+\\n'
+  ])
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', '-v', '-q', sbox.wc_dir,
+                                     '-c3')
+
 
 ########################################################################
 # Run the tests
@@ -2667,6 +2738,7 @@ test_list = [ None,
               log_multiple_revs_spanning_rename,
               mergeinfo_log,
               merge_sensitive_log_xml_reverse_merges,
+              log_revision_move_copy,
              ]
 
 if __name__ == '__main__':

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/move_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/move_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- subversion/branches/svn-info-detail/subversion/tests/cmdline/move_tests.py 
(original)
+++ subversion/branches/svn-info-detail/subversion/tests/cmdline/move_tests.py 
Tue Feb 24 15:23:33 2015
@@ -1156,23 +1156,11 @@ def move_missing(sbox):
   expected_status.tweak('A/D/G', 'A/D/G/tau', 'A/D/G/pi', 'A/D/G/rho',
                         status='! ', entry_status='  ')
 
-  expected_status.add({
-    'R'                 : Item(status='! ', wc_rev='-',
-                               entry_status='A ', entry_copied='+'),
-    'R/pi'              : Item(status='! ', wc_rev='-',
-                               entry_status='  ', entry_copied='+'),
-    'R/tau'             : Item(status='! ', wc_rev='-',
-                               entry_status='  ', entry_copied='+'),
-    'R/rho'             : Item(status='! ', wc_rev='-',
-                               entry_status='  ', entry_copied='+'),
-  })
-
   # Verify that the status processing doesn't crash
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # The issue is a crash when the destination is present
   os.mkdir(sbox.ospath('R'))
-  expected_status.tweak('R', status='A ', copied='+')
 
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/special_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/special_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- 
subversion/branches/svn-info-detail/subversion/tests/cmdline/special_tests.py 
(original)
+++ 
subversion/branches/svn-info-detail/subversion/tests/cmdline/special_tests.py 
Tue Feb 24 15:23:33 2015
@@ -612,31 +612,70 @@ def replace_symlink_with_dir(sbox):
 # test for issue #1808: svn up deletes local symlink that obstructs
 # versioned file
 @Issue(1808)
-@SkipUnless(svntest.main.is_posix_os)
 def update_obstructing_symlink(sbox):
   "symlink obstructs incoming delete"
 
   sbox.build()
   wc_dir = sbox.wc_dir
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  mu_url = sbox.repo_url + '/A/mu'
-  iota_path = os.path.join(wc_dir, 'iota')
-
-  # delete A/mu and replace it with a symlink
-  svntest.main.run_svn(None, 'rm', mu_path)
-  os.symlink(iota_path, mu_path)
+  mu_path = sbox.ospath('A/mu')
 
-  svntest.main.run_svn(None, 'rm', mu_url,
-                       '-m', 'log msg')
+  iota_abspath = os.path.abspath(sbox.ospath('iota'))
 
-  svntest.main.run_svn(None,
-                       'up', wc_dir)
+  # delete mu and replace it with an (not-added) symlink
+  sbox.simple_rm('A/mu')
+  sbox.simple_symlink(iota_abspath, 'A/mu')
+
+  # delete pi and replace it with an added symlink
+  sbox.simple_rm('A/D/G/pi')
+  sbox.simple_add_symlink(iota_abspath, 'A/D/G/pi')
+
+  if not os.path.exists(mu_path):
+      raise svntest.Failure("mu should be there")
+
+  # Now remove mu and pi in the repository
+  svntest.main.run_svn(None, 'rm', '-m', 'log msg',
+                       sbox.repo_url + '/A/mu',
+                       sbox.repo_url + '/A/D/G/pi')
+
+  # We expect tree conflicts
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/mu':         Item(status='  ', treeconflict='C'),
+    'A/D/G/pi':     Item(status='  ', treeconflict='C')
+  })
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.tweak('A/mu', status='? ', treeconflict='C',
+                        wc_rev=None)
+
+  expected_status.tweak('A/D/G/pi', status='A ',treeconflict='C',
+                        wc_rev='-')
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output, None,
+                                        expected_status)
+
+  expected_info = [
+    {
+      'Path': re.escape(sbox.ospath('A/D/G/pi')),
+      'Tree conflict': 'local file replace, incoming file delete or move.*'
+    },
+    {
+      'Path': re.escape(sbox.ospath('A/mu')),
+      'Tree conflict': 'local file delete, incoming file delete or move.*'
+    }
+  ]
+
+  svntest.actions.run_and_verify_info(expected_info,
+                                      sbox.ospath('A/D/G/pi'),
+                                      sbox.ospath('A/mu'))
 
   # check that the symlink is still there
-  target = os.readlink(mu_path)
-  if target != iota_path:
-    raise svntest.Failure
-
+  if not os.path.exists(mu_path):
+      raise svntest.Failure("mu should be there")
+  if svntest.main.is_posix_os():
+    target = os.readlink(mu_path)
+    if target != iota_abspath:
+      raise svntest.Failure("mu no longer points to the same location")
 
 def warn_on_reserved_name(sbox):
   "warn when attempt operation on a reserved name"

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/svnadmin_tests.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/svnadmin_tests.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- 
subversion/branches/svn-info-detail/subversion/tests/cmdline/svnadmin_tests.py 
(original)
+++ 
subversion/branches/svn-info-detail/subversion/tests/cmdline/svnadmin_tests.py 
Tue Feb 24 15:23:33 2015
@@ -2930,6 +2930,30 @@ def load_txdelta(sbox):
     ".*Verified revision *"):
     raise svntest.Failure
 
+@Issues(4563)
+def load_no_svndate_r0(sbox):
+  "load without svn:date on r0"
+
+  sbox.build(create_wc=False, empty=True)
+
+  # svn:date exits
+  svntest.actions.run_and_verify_svnlook(['  svn:date\n'], [],
+                                         'proplist', '--revprop', '-r0',
+                                         sbox.repo_dir)
+
+  dump_old = ["SVN-fs-dump-format-version: 2\n", "\n",
+              "UUID: bf52886d-358d-4493-a414-944a6e5ad4f5\n", "\n",
+              "Revision-number: 0\n",
+              "Prop-content-length: 10\n",
+              "Content-length: 10\n", "\n",
+              "PROPS-END\n", "\n"]
+  svntest.actions.run_and_verify_load(sbox.repo_dir, dump_old)
+  
+  # svn:date should have been removed
+  svntest.actions.run_and_verify_svnlook([], [],
+                                         'proplist', '--revprop', '-r0',
+                                         sbox.repo_dir)
+
 ########################################################################
 # Run the tests
 
@@ -2984,6 +3008,7 @@ test_list = [ None,
               freeze_same_uuid,
               upgrade,
               load_txdelta,
+              load_no_svndate_r0,
              ]
 
 if __name__ == '__main__':

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/svntest/actions.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/svntest/actions.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- 
subversion/branches/svn-info-detail/subversion/tests/cmdline/svntest/actions.py 
(original)
+++ 
subversion/branches/svn-info-detail/subversion/tests/cmdline/svntest/actions.py 
Tue Feb 24 15:23:33 2015
@@ -1524,7 +1524,7 @@ def run_and_verify_status(wc_dir_name, s
   exit_code, output, errput = main.run_svn(None, 'status', '-v', '-u', '-q',
                                            wc_dir_name)
 
-  actual_status = svntest.wc.State.from_status(output)
+  actual_status = svntest.wc.State.from_status(output, wc_dir=wc_dir_name)
 
   # Verify actual output against expected output.
   if isinstance(status_tree, wc.State):
@@ -1569,7 +1569,7 @@ def run_and_verify_unquiet_status(wc_dir
   exit_code, output, errput = main.run_svn(None, 'status', '-v',
                                            '-u', wc_dir_name)
 
-  actual_status = svntest.wc.State.from_status(output)
+  actual_status = svntest.wc.State.from_status(output, wc_dir=wc_dir_name)
 
   # Verify actual output against expected output.
   if isinstance(status_tree, wc.State):

Modified: 
subversion/branches/svn-info-detail/subversion/tests/cmdline/svntest/factory.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/svn-info-detail/subversion/tests/cmdline/svntest/factory.py?rev=1661981&r1=1661980&r2=1661981&view=diff
==============================================================================
--- 
subversion/branches/svn-info-detail/subversion/tests/cmdline/svntest/factory.py 
(original)
+++ 
subversion/branches/svn-info-detail/subversion/tests/cmdline/svntest/factory.py 
Tue Feb 24 15:23:33 2015
@@ -1035,7 +1035,7 @@ class TestFactory:
 
     make_py, prev_status = self.get_prev_status(wc)
 
-    actual_status = svntest.wc.State.from_status(output)
+    actual_status = svntest.wc.State.from_status(output, wc_dir=wc.realpath)
 
     # The tests currently compare SVNTreeNode trees, so let's do that too.
     prev_status_tree = prev_status.old_tree()


Reply via email to