You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/11/25 14:55:47 UTC

svn commit: r1771332 - /subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c

Author: stsp
Date: Fri Nov 25 14:55:47 2016
New Revision: 1771332

URL: http://svn.apache.org/viewvc?rev=1771332&view=rev
Log:
Introduce a special 'add file' editor callback for updates of incoming moves.

* subversion/libsvn_wc/wc_db_update_move.c
  (tc_editor_incoming_add_file): New. Adds a file to the incoming moved tree,
   based on paths and file content provided by the driver.
  (update_incoming_moved_node): Prepare file content and call new function.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c

Modified: subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c?rev=1771332&r1=1771331&r2=1771332&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Fri Nov 25 14:55:47 2016
@@ -852,6 +852,115 @@ tc_editor_add_file(node_move_baton_t *nm
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+tc_editor_incoming_add_file(node_move_baton_t *nmb,
+                            const char *dst_relpath,
+                            svn_node_kind_t old_kind,
+                            const svn_checksum_t *checksum,
+                            apr_hash_t *props,
+                            const char *src_relpath,
+                            const char *content_abspath,
+                            apr_pool_t *scratch_pool)
+{
+  update_move_baton_t *b = nmb->umb;
+  svn_wc_conflict_reason_t reason = svn_wc_conflict_reason_unversioned;
+  svn_node_kind_t wc_kind;
+  const char *dst_abspath;
+  svn_skel_t *work_items = NULL;
+  svn_skel_t *work_item = NULL;
+  svn_skel_t *conflict = NULL;
+
+  SVN_ERR(mark_parent_edited(nmb, scratch_pool));
+  if (nmb->skip)
+    return SVN_NO_ERROR;
+
+  dst_abspath = svn_dirent_join(b->wcroot->abspath, dst_relpath, scratch_pool);
+
+  /* Check for unversioned tree-conflict */
+  SVN_ERR(svn_io_check_path(dst_abspath, &wc_kind, scratch_pool));
+
+  if (wc_kind != svn_node_none
+      && (nmb->shadowed || wc_kind != old_kind)) /* replace */
+    {
+      SVN_ERR(create_node_tree_conflict(&conflict, nmb, dst_relpath,
+                                        old_kind, svn_node_file,
+                                        reason,
+                                        (old_kind == svn_node_none)
+                                          ? svn_wc_conflict_action_add
+                                          : svn_wc_conflict_action_replace,
+                                        NULL,
+                                        scratch_pool, scratch_pool));
+      nmb->skip = TRUE;
+    }
+  else
+    {
+      svn_sqlite__stmt_t *stmt;
+      svn_boolean_t have_row;
+      const char *dst_parent_relpath = svn_relpath_dirname(dst_relpath,
+                                                           scratch_pool);
+      const char *src_abspath = svn_dirent_join(b->wcroot->abspath,
+                                                src_relpath, scratch_pool);
+
+      /* Add a WORKING row for the new file, based on the source. */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+                                        STMT_INSERT_WORKING_NODE_COPY_FROM));
+      SVN_ERR(svn_sqlite__bindf(stmt, "issdst",
+                    b->wcroot->wc_id, src_relpath,
+                    dst_relpath, relpath_depth(dst_relpath),
+                    dst_parent_relpath,
+                    presence_map, svn_wc__db_status_normal));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+
+      /* Copy properties over.  ### This loses changelist association. */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+                                        STMT_SELECT_ACTUAL_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", b->wcroot->wc_id, src_relpath));
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      if (have_row)
+        {
+          apr_size_t props_size;
+          const char *properties;
+
+          properties = svn_sqlite__column_blob(stmt, 1, &props_size,
+                                               scratch_pool);
+          SVN_ERR(svn_sqlite__reset(stmt));
+          SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
+                                            STMT_INSERT_ACTUAL_NODE));
+          SVN_ERR(svn_sqlite__bindf(stmt, "issbs",
+                                    b->wcroot->wc_id, dst_relpath,
+                                    svn_relpath_dirname(dst_relpath,
+                                                        scratch_pool),
+                                    properties, props_size, NULL));
+          SVN_ERR(svn_sqlite__step(&have_row, stmt));
+        }
+
+      /* Update working file. */
+      SVN_ERR(svn_wc__wq_build_file_install(&work_item, b->db, dst_abspath,
+                                            src_abspath,
+                                            FALSE /* FIXME: use_commit_times?*/,
+                                            TRUE  /* record_file_info */,
+                                            scratch_pool, scratch_pool));
+      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+
+      /* Queue removal of temporary content copy. */
+      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, b->db,
+                                           b->wcroot->abspath, src_abspath,
+                                           scratch_pool, scratch_pool));
+    
+      work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
+    }
+
+  SVN_ERR(update_move_list_add(b->wcroot, dst_relpath, b->db,
+                               (old_kind == svn_node_none)
+                                  ? svn_wc_notify_update_add
+                                  : svn_wc_notify_update_replace,
+                               svn_node_file,
+                               svn_wc_notify_state_inapplicable,
+                               svn_wc_notify_state_inapplicable,
+                               conflict, work_items, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
 /* All the info we need about one version of a working node. */
 typedef struct working_node_version_t
 {
@@ -2192,9 +2301,32 @@ update_incoming_moved_node(node_move_bat
     {
       if (working_kind == svn_node_file || working_kind == svn_node_symlink)
         {
-          SVN_ERR(tc_editor_add_file(nmb, dst_relpath, working_kind,
-                                     working_checksum, working_props,
-                                     scratch_pool));
+          const char *victim_abspath;
+          const char *wctemp_abspath;
+          svn_stream_t *working_stream;
+          svn_stream_t *temp_stream;
+          const char *temp_abspath;
+
+          /* Copy the victim's content to a safe place and add it from there. */
+          SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&wctemp_abspath, b->db,
+                                                 b->wcroot->abspath,
+                                                 scratch_pool,
+                                                 scratch_pool));
+
+          victim_abspath = svn_dirent_join(b->wcroot->abspath,
+                                           victim_relpath, scratch_pool);
+          SVN_ERR(svn_stream_open_readonly(&working_stream, victim_abspath,
+                                           scratch_pool, scratch_pool));
+          SVN_ERR(svn_stream_open_unique(&temp_stream, &temp_abspath,
+                                         wctemp_abspath, svn_io_file_del_none,
+                                         scratch_pool, scratch_pool));
+          SVN_ERR(svn_stream_copy3(working_stream, temp_stream, NULL, NULL,
+                                   scratch_pool));
+
+          SVN_ERR(tc_editor_incoming_add_file(nmb, dst_relpath, working_kind,
+                                              working_checksum, working_props,
+                                              victim_relpath, temp_abspath,
+                                              scratch_pool));
         }
       else if (working_kind == svn_node_dir)
         {