Author: rhuijben
Date: Sun May 8 15:22:01 2011
New Revision: 1100756
URL: http://svn.apache.org/viewvc?rev=1100756&view=rev
Log:
Extract some logic from the update_editor's merge_file code to its own function
to allow reusing it from the file external editor.
This in preparation for moving file externals from the NODES table to their
own EXTERNALS table in wc.db.
* subversion/libsvn_wc/update_editor.c
(close_directory): Remove unnecessary NULL check.
(svn_wc__perform_file_merge): New function. Extracted from...
(merge_file): ... here. Which calls svn_wc__perform_file_merge now.
(close_file): Remove unnecessary NULL check.
* subversion/libsvn_wc/wc.h
(svn_wc__perform_file_merge): New function.
Modified:
subversion/trunk/subversion/libsvn_wc/update_editor.c
subversion/trunk/subversion/libsvn_wc/wc.h
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=1100756&r1=1100755&r2=1100756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Sun May 8 15:22:01
2011
@@ -2498,7 +2498,7 @@ close_directory(void *dir_baton,
changed_rev, changed_date, changed_author,
NULL /* children */,
depth,
- (dav_prop_changes && dav_prop_changes->nelts > 0)
+ (dav_prop_changes->nelts > 0)
? svn_prop_array_to_hash(dav_prop_changes, pool)
: NULL,
NULL /* conflict */,
@@ -3216,6 +3216,128 @@ change_file_prop(void *file_baton,
return SVN_NO_ERROR;
}
+/* Perform the actual merge of file changes between an original file,
+ identified by ORIGINAL_CHECKSUM (an empty file if NULL) to a new file
+ identified by NEW_CHECKSUM.
+
+ Merge the result into LOCAL_ABSPATH, which is part of the working copy
+ identified by WRI_ABSPATH. Use OLD_REVISION and TARGET_REVISION for naming
+ the intermediate files.
+
+ The rest of the arguments are passed to svn_wc__internal_merge.
+ */
+svn_error_t *
+svn_wc__perform_file_merge(svn_skel_t **work_items,
+ enum svn_wc_merge_outcome_t *merge_outcome,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ const char *wri_abspath,
+ const svn_checksum_t *new_checksum,
+ const svn_checksum_t *original_checksum,
+ const apr_array_header_t *ext_patterns,
+ svn_revnum_t old_revision,
+ svn_revnum_t target_revision,
+ const apr_array_header_t *propchanges,
+ const char *diff3_cmd,
+ svn_wc_conflict_resolver_func2_t conflict_func,
+ void *conflict_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ /* Actual file exists and has local mods:
+ Now we need to let loose svn_wc__merge_internal() to merge
+ the textual changes into the working file. */
+ const char *oldrev_str, *newrev_str, *mine_str;
+ const char *merge_left;
+ svn_boolean_t delete_left = FALSE;
+ const char *path_ext = "";
+ const char *new_text_base_tmp_abspath;
+ svn_skel_t *work_item;
+
+ *work_items = NULL;
+
+ SVN_ERR(svn_wc__db_pristine_get_path(&new_text_base_tmp_abspath,
+ db, wri_abspath, new_checksum,
+ scratch_pool, scratch_pool));
+
+ /* If we have any file extensions we're supposed to
+ preserve in generated conflict file names, then find
+ this path's extension. But then, if it isn't one of
+ the ones we want to keep in conflict filenames,
+ pretend it doesn't have an extension at all. */
+ if (ext_patterns && ext_patterns->nelts)
+ {
+ svn_path_splitext(NULL, &path_ext, local_abspath, scratch_pool);
+ if (! (*path_ext && svn_cstring_match_glob_list(path_ext, ext_patterns)))
+ path_ext = "";
+ }
+
+ /* old_revision can be invalid when the conflict is against a
+ local addition */
+ if (!SVN_IS_VALID_REVNUM(old_revision))
+ old_revision = 0;
+
+ oldrev_str = apr_psprintf(scratch_pool, ".r%ld%s%s",
+ old_revision,
+ *path_ext ? "." : "",
+ *path_ext ? path_ext : "");
+
+ newrev_str = apr_psprintf(scratch_pool, ".r%ld%s%s",
+ target_revision,
+ *path_ext ? "." : "",
+ *path_ext ? path_ext : "");
+ mine_str = apr_psprintf(scratch_pool, ".mine%s%s",
+ *path_ext ? "." : "",
+ *path_ext ? path_ext : "");
+
+ if (! original_checksum)
+ {
+ SVN_ERR(get_empty_tmp_file(&merge_left, db, wri_abspath,
+ result_pool, scratch_pool));
+ delete_left = TRUE;
+ }
+ else
+ SVN_ERR(svn_wc__db_pristine_get_path(&merge_left, db, wri_abspath,
+ original_checksum,
+ result_pool, scratch_pool));
+
+ /* Merge the changes from the old textbase to the new
+ textbase into the file we're updating.
+ Remember that this function wants full paths! */
+ /* ### TODO: Pass version info here. */
+ /* ### NOTE: if this call bails out, then we must ensure
+ ### that no work items have been queued which might
+ ### place this file into an inconsistent state.
+ ### in the future, all the state changes should be
+ ### made atomically. */
+ SVN_ERR(svn_wc__internal_merge(&work_item,
+ merge_outcome,
+ db,
+ merge_left, NULL,
+ new_text_base_tmp_abspath, NULL,
+ local_abspath,
+ NULL /* copyfrom_abspath */,
+ oldrev_str, newrev_str, mine_str,
+ FALSE /* dry_run */,
+ diff3_cmd, NULL, propchanges,
+ conflict_func, conflict_baton,
+ cancel_func, cancel_baton,
+ result_pool, scratch_pool));
+
+ *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+
+ /* If we created a temporary left merge file, get rid of it. */
+ if (delete_left)
+ {
+ SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db, merge_left,
+ result_pool, scratch_pool));
+ *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+ }
+
+ return SVN_NO_ERROR;
+}
/* This is the small planet. It has the complex responsibility of
* "integrating" a new revision of a file into a working copy.
@@ -3338,105 +3460,26 @@ merge_file(svn_skel_t **work_items,
}
else if (fb->new_text_base_sha1_checksum)
{
- /* Working file exists and has local mods:
- Now we need to let loose svn_wc__merge_internal() to merge
- the textual changes into the working file. */
- const char *oldrev_str, *newrev_str, *mine_str;
- const char *merge_left;
- svn_boolean_t delete_left = FALSE;
- const char *path_ext = "";
- const char *new_text_base_tmp_abspath;
- svn_revnum_t old_revision;
-
- SVN_ERR(svn_wc__db_pristine_get_path(&new_text_base_tmp_abspath,
- eb->db, pb->local_abspath,
- fb->new_text_base_sha1_checksum,
- scratch_pool, scratch_pool));
-
- /* If we have any file extensions we're supposed to
- preserve in generated conflict file names, then find
- this path's extension. But then, if it isn't one of
- the ones we want to keep in conflict filenames,
- pretend it doesn't have an extension at all. */
- if (eb->ext_patterns && eb->ext_patterns->nelts)
- {
- svn_path_splitext(NULL, &path_ext, fb->local_abspath,
- scratch_pool);
- if (! (*path_ext
- && svn_cstring_match_glob_list(path_ext,
- eb->ext_patterns)))
- path_ext = "";
- }
-
- old_revision = fb->old_revision;
-
- /* old_revision can be invalid when the conflict is against a
- local addition */
- if (!SVN_IS_VALID_REVNUM(old_revision))
- old_revision = 0;
-
- oldrev_str = apr_psprintf(scratch_pool, ".r%ld%s%s",
- old_revision,
- *path_ext ? "." : "",
- *path_ext ? path_ext : "");
-
- newrev_str = apr_psprintf(scratch_pool, ".r%ld%s%s",
- *eb->target_revision,
- *path_ext ? "." : "",
- *path_ext ? path_ext : "");
- mine_str = apr_psprintf(scratch_pool, ".mine%s%s",
- *path_ext ? "." : "",
- *path_ext ? path_ext : "");
-
- if (fb->add_existed)
- {
- SVN_ERR(get_empty_tmp_file(&merge_left, eb->db,
- pb->local_abspath,
- result_pool, scratch_pool));
- delete_left = TRUE;
- }
- else
- SVN_ERR(svn_wc__db_pristine_get_path(&merge_left, eb->db,
- fb->local_abspath,
- fb->original_checksum,
- result_pool, scratch_pool));
-
- /* Merge the changes from the old textbase to the new
- textbase into the file we're updating.
- Remember that this function wants full paths! */
- /* ### TODO: Pass version info here. */
- /* ### NOTE: if this call bails out, then we must ensure
- ### that no work items have been queued which might
- ### place this file into an inconsistent state.
- ### in the future, all the state changes should be
- ### made atomically. */
- SVN_ERR(svn_wc__internal_merge(
- &work_item,
- &merge_outcome,
- eb->db,
- merge_left, NULL,
- new_text_base_tmp_abspath, NULL,
- fb->local_abspath,
- NULL /* copyfrom_abspath */,
- oldrev_str, newrev_str, mine_str,
- FALSE /* dry_run */,
- eb->diff3_cmd, NULL, fb->propchanges,
- eb->conflict_func, eb->conflict_baton,
- eb->cancel_func, eb->cancel_baton,
- result_pool, scratch_pool));
- *work_items = svn_wc__wq_merge(*work_items, work_item,
- result_pool);
-
- /* If we created a temporary left merge file, get rid of it. */
- if (delete_left)
- {
- SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
- eb->db, merge_left,
- result_pool,
- scratch_pool));
- *work_items = svn_wc__wq_merge(*work_items, work_item,
- result_pool);
- }
+ /* Actual file exists and has local mods:
+ Now we need to let loose svn_wc__merge_internal() to merge
+ the textual changes into the working file. */
+ SVN_ERR(svn_wc__perform_file_merge(work_items,
+ &merge_outcome,
+ eb->db,
+ fb->local_abspath,
+ pb->local_abspath,
+ fb->new_text_base_sha1_checksum,
+ fb->add_existed
+ ? NULL
+ : fb->original_checksum,
+ eb->ext_patterns,
+ fb->old_revision,
+ *eb->target_revision,
+ fb->propchanges,
+ eb->diff3_cmd,
+ eb->conflict_func, eb->conflict_baton,
+ eb->cancel_func, eb->cancel_baton,
+ result_pool, scratch_pool));
} /* end: working file exists and has mods */
else
{
@@ -3933,8 +3976,7 @@ close_file(void *file_baton,
new_changed_date,
new_changed_author,
new_checksum,
- (dav_prop_changes
- && dav_prop_changes->nelts > 0)
+ (dav_prop_changes->nelts > 0)
? svn_prop_array_to_hash(
dav_prop_changes,
scratch_pool)
Modified: subversion/trunk/subversion/libsvn_wc/wc.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc.h?rev=1100756&r1=1100755&r2=1100756&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc.h Sun May 8 15:22:01 2011
@@ -728,6 +728,35 @@ svn_wc__write_check(svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *scratch_pool);
+/* Perform the actual merge of file changes between an original file,
+ identified by ORIGINAL_CHECKSUM (an empty file if NULL) to a new file
+ identified by NEW_CHECKSUM.
+
+ Merge the result into LOCAL_ABSPATH, which is part of the working copy
+ identified by WRI_ABSPATH. Use OLD_REVISION and TARGET_REVISION for naming
+ the intermediate files.
+
+ The rest of the arguments are passed to svn_wc__internal_merge.
+ */
+svn_error_t *
+svn_wc__perform_file_merge(svn_skel_t **work_items,
+ enum svn_wc_merge_outcome_t *merge_outcome,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ const char *wri_abspath,
+ const svn_checksum_t *new_checksum,
+ const svn_checksum_t *original_checksum,
+ const apr_array_header_t *ext_patterns,
+ svn_revnum_t old_revision,
+ svn_revnum_t target_revision,
+ const apr_array_header_t *propchanges,
+ const char *diff3_cmd,
+ svn_wc_conflict_resolver_func2_t conflict_func,
+ void *conflict_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
#ifdef __cplusplus
}