You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2012/07/13 01:58:53 UTC
svn commit: r1361007 - /subversion/trunk/subversion/libsvn_wc/merge.c
Author: rhuijben
Date: Thu Jul 12 23:58:53 2012
New Revision: 1361007
URL: http://svn.apache.org/viewvc?rev=1361007&view=rev
Log:
Make sure 'svn merge' can't break the workqueue by copying files that are not
in the working copy, into the working copy temp dir before installing a
workqueue item that references it.
The merge code calls this function with files in the system temp directory.
* subversion/libsvn_wc/merge.c
(merge_file_trivial): Add cancel_func arguments. Copy to be installed file
to the workingcopy temp dir if necessary.
(svn_wc__internal_merge): Update caller.
Modified:
subversion/trunk/subversion/libsvn_wc/merge.c
Modified: subversion/trunk/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/merge.c?rev=1361007&r1=1361006&r2=1361007&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/merge.c (original)
+++ subversion/trunk/subversion/libsvn_wc/merge.c Thu Jul 12 23:58:53 2012
@@ -626,6 +626,8 @@ merge_file_trivial(svn_skel_t **work_ite
const char *detranslated_target_abspath,
svn_boolean_t dry_run,
svn_wc__db_t *db,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -670,6 +672,40 @@ merge_file_trivial(svn_skel_t **work_ite
*merge_outcome = svn_wc_merge_merged;
if (!dry_run)
{
+ const char *wcroot_abspath;
+ svn_boolean_t delete_src;
+ /* The right_abspath might be outside our working copy. In that
+ case we should copy the file to a safe location before
+ installing to avoid breaking the workqueue */
+
+ SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath,
+ db, target_abspath,
+ scratch_pool, scratch_pool));
+
+ if (!svn_dirent_is_child(wcroot_abspath, right_abspath, NULL))
+ {
+ svn_stream_t *tmp_src;
+ svn_stream_t *tmp_dst;
+
+ SVN_ERR(svn_stream_open_readonly(&tmp_src, right_abspath,
+ scratch_pool,
+ scratch_pool));
+
+ SVN_ERR(svn_wc__open_writable_base(&tmp_dst, &right_abspath,
+ NULL, NULL,
+ db, target_abspath,
+ scratch_pool,
+ scratch_pool));
+
+ SVN_ERR(svn_stream_copy3(tmp_src, tmp_dst,
+ cancel_func, cancel_baton,
+ scratch_pool));
+
+ /* no need to strdup right_abspath, as the wq_build_()
+ call already does that for us */
+ delete_src = TRUE;
+ }
+
SVN_ERR(svn_wc__wq_build_file_install(
&work_item, db, target_abspath, right_abspath,
FALSE /* use_commit_times */,
@@ -677,6 +713,15 @@ merge_file_trivial(svn_skel_t **work_ite
result_pool, scratch_pool));
*work_items = svn_wc__wq_merge(*work_items, work_item,
result_pool);
+
+ if (delete_src)
+ {
+ SVN_ERR(svn_wc__wq_build_file_remove(
+ &work_item, db, right_abspath,
+ result_pool, scratch_pool));
+ *work_items = svn_wc__wq_merge(*work_items, work_item,
+ result_pool);
+ }
}
}
@@ -1019,7 +1064,8 @@ svn_wc__internal_merge(svn_skel_t **work
SVN_ERR(merge_file_trivial(work_items, merge_outcome,
left_abspath, right_abspath,
target_abspath, detranslated_target_abspath,
- dry_run, db, result_pool, scratch_pool));
+ dry_run, db, cancel_func, cancel_baton,
+ result_pool, scratch_pool));
if (*merge_outcome == svn_wc_merge_no_merge)
{
if (is_binary)