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()
