Hi!
Is 'svn switch does not update keywords' a problem that needs solving?
Is the performance of this solution acceptable (traverse the entire wc
one more time after the editor drive)?
Alternatives?
* Custom db-query that only returns the paths with matching property set
on them. Could be used by 'svn pg -R' later on.
* Do the recording during the crawling of the wc. Saves us the extra
traversal.
And why is it not working? :)
I'm translating the file in the WC back into Normal Form and then I
install it through the workqueue mecanism. It does get translated but
not to the current URL but to the previous.
[[[
Fix issue #1975 - 'svn switch does not update keywords'.
Only files affected by the switch gets keyword translation, possibly
making some $URL$ keywords incorrect. We do a complete traversal of
the WC to check for the files that have svn:keywords pristine props
set and retranslate those files. */
* subversion/libsvn_wc/update_editor.c
(reinstall_target_baton): New
(reinstall_target_with_keywords): New.
(close_edit): walk all children and call
reinstall_target_with_keywords().
]]]
Daniel
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;
}