Index: subversion/libsvn_wc/update_editor.c =================================================================== --- subversion/libsvn_wc/update_editor.c (revision 957424) +++ subversion/libsvn_wc/update_editor.c (arbetskopia) @@ -5080,13 +5080,83 @@ close_file(void *file_baton, return SVN_NO_ERROR; } +struct reinstall_target_baton +{ + svn_wc__db_t *db; + svn_cancel_func_t cancel_func; + void *cancel_baton; + /* ### Do we need a result_pool here? How is the apr pool cleanup handler + * configured? We need a pool with the handler activated in case we get + * cancelled. ### */ +}; + +/* Reinstall target to assure svn:keywords expand correctly. */ +static svn_error_t * +reinstall_target_with_keywords(const char *local_abspath, + void *walk_baton, + apr_pool_t *scratch_pool) +{ + struct reinstall_target_baton *rtb = walk_baton; + apr_hash_t *props; + const char *tmptext; + + SVN_DBG(("reinstall_target() %s\n", local_abspath)); + + SVN_ERR(svn_wc__get_pristine_props(&props, rtb->db, local_abspath, + scratch_pool, scratch_pool)); + + /* ### There must be a constant for svn:keywords somewhere, but where? */ + if (props && apr_hash_get(props, "svn:keywords", APR_HASH_KEY_STRING)) + { + svn_skel_t *all_work_items; + svn_skel_t *work_item; + + SVN_DBG(("svn:keywords found\n")); + SVN_ERR(svn_wc__internal_translated_file(&tmptext, local_abspath, + rtb->db, local_abspath, + SVN_WC_TRANSLATE_TO_NF + | SVN_WC_TRANSLATE_NO_OUTPUT_CLEANUP, + rtb->cancel_func, + rtb->cancel_baton, + scratch_pool, scratch_pool)); + + SVN_ERR(svn_wc__wq_build_file_install(&all_work_items, rtb->db, + local_abspath, + tmptext, /* install_from */ + TRUE, /* use_commit_times */ + TRUE, /* record_fileinfo */ + scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__wq_build_file_remove(&work_item, rtb->db, tmptext, + scratch_pool, scratch_pool)); + all_work_items = svn_wc__wq_merge(all_work_items, work_item, + scratch_pool); + + /* ### Should we really run the wq here? close_file() and + * close_directory() runs wq's so I assume that we want them performed + * on each item. I had this notion about wq's as something containing + * all items in a WC, e.g. we check what needs to be done and then do + * it all in one batch. What happens if we have three files done but + * three more should have been installed when we get an interrupt? + * Does the editor have some way of marking what has been done and + * what has not? E.g. if we run svn_wc_cleanup() on a WC, we're + * supposed to finish the remaining work items but the update_editor + * may not have recorded all work items, right? Do we check that + * revisions match or what? ### */ + SVN_ERR(svn_wc__wq_run(rtb->db, local_abspath, rtb->cancel_func, + rtb->cancel_baton, scratch_pool)); + } + + return SVN_NO_ERROR; +} + /* An svn_delta_editor_t function. */ static svn_error_t * close_edit(void *edit_baton, apr_pool_t *pool) { struct edit_baton *eb = edit_baton; + struct reinstall_target_baton rtb; /* If there is a target and that target is missing, then it apparently wasn't re-added by the update process, so we'll @@ -5151,6 +5221,27 @@ close_edit(void *edit_baton, eb->close_edit_complete = TRUE; svn_pool_destroy(eb->pool); + rtb.db = eb->db; + rtb.cancel_func = eb->cancel_func; + rtb.cancel_baton = eb->cancel_baton; + + /* #1975 - svn switch does not update keywords, exposes the need to update + * each and every file with svn:keywords set to have the correct $URL$ + * set. + * + * ### An extra walk of the entire wc? Seriously? Shouldn't switch be + * ### blazingly fast? + * + * ### This */ + if (eb->switch_relpath) + SVN_ERR(svn_wc__internal_walk_children(eb->db, eb->target_abspath, + FALSE /* show_hidden */, + reinstall_target_with_keywords, + &rtb, + svn_depth_infinity, /* ### Fix */ + eb->cancel_func, + eb->cancel_baton, pool)); + return SVN_NO_ERROR; }