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 2013/02/11 22:22:00 UTC

svn commit: r1444966 - in /subversion/trunk/subversion: libsvn_wc/diff_editor.c tests/cmdline/diff_tests.py

Author: rhuijben
Date: Mon Feb 11 21:22:00 2013
New Revision: 1444966

URL: http://svn.apache.org/r1444966
Log:
Delay the handling of incoming deletes in the repos-wc diff handling to allow
reporting them after the incoming add when necessary.

* subversion/libsvn_wc/diff_editor.c
  (dir_baton_t): Add deletes hash.
  (ensure_local_only_handled): Handle repository deletes if scheduled, not
    via argument
  (delete_entry): Store deletes for handling later.

  (add_directory,
   open_directory: Update caller.

  (close_directory): Process deletes that weren't already handled.

  (add_file,
   open_file): Don't process local changes yet, but wait till file_close.

  (close_file): Handle local changes before remote if needed.
  (close_edit): Update comment.

* subversion/tests/cmdline/diff_tests.py
  (simple_ancestry): Extend test. Make sure nodes are not related to make the
    result before and after commit the same.

Modified:
    subversion/trunk/subversion/libsvn_wc/diff_editor.c
    subversion/trunk/subversion/tests/cmdline/diff_tests.py

Modified: subversion/trunk/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_editor.c?rev=1444966&r1=1444965&r2=1444966&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/diff_editor.c Mon Feb 11 21:22:00 2013
@@ -282,6 +282,10 @@ struct dir_baton_t
 
   apr_hash_t *local_info;
 
+  /* A hash containing the basenames of the nodes reported deleted by the
+     repository (or NULL for no values). */
+  apr_hash_t *deletes;
+
   /* Identifies those directory elements that get compared while running
      the crawler.  These elements should not be compared again when
      recursively looking for local modifications.
@@ -1277,17 +1281,17 @@ report_local_only_dir(struct edit_baton_
   return SVN_NO_ERROR;
 }
 
+/* Ensures that local changes are reported to pb->eb->processor if there
+   are any. */
 static svn_error_t *
 ensure_local_only_handled(struct dir_baton_t *pb,
                           const char *name,
-                          svn_boolean_t for_delete,
                           apr_pool_t *scratch_pool)
 {
   struct edit_baton_t *eb = pb->eb;
   const struct svn_wc__db_info_t *info;
-
-  if (eb->ignore_ancestry && !for_delete)
-    return SVN_NO_ERROR;
+  svn_boolean_t repos_delete = (pb->deletes
+                                && svn_hash_gets(pb->deletes, name));
 
   assert(!strchr(name, '/'));
   assert(!pb->added || eb->ignore_ancestry);
@@ -1295,6 +1299,10 @@ ensure_local_only_handled(struct dir_bat
   if (svn_hash_gets(pb->compared, name))
     return SVN_NO_ERROR;
 
+  SVN_DBG(("Repos del %s: %d\n", name, repos_delete));
+
+  svn_hash_sets(pb->compared, apr_pstrdup(pb->pool, name), "");
+
   SVN_ERR(ensure_local_info(pb, scratch_pool));
 
   info = svn_hash_gets(pb->local_info, name);
@@ -1302,9 +1310,6 @@ ensure_local_only_handled(struct dir_bat
   if (info == NULL)
     return SVN_NO_ERROR;
 
-  if (for_delete)
-    svn_hash_sets(pb->compared, apr_pstrdup(pb->pool, name), "");
-
   switch (info->status)
     {
       case svn_wc__db_status_not_present:
@@ -1314,12 +1319,13 @@ ensure_local_only_handled(struct dir_bat
         return SVN_NO_ERROR; /* Not local only */
 
       case svn_wc__db_status_normal:
-        if (! for_delete)
+        if (!repos_delete)
           return SVN_NO_ERROR; /* Local and remote */
+        svn_hash_sets(pb->deletes, name, NULL);
         break;
 
       case svn_wc__db_status_deleted:
-        if (!eb->diff_pristine)
+        if (!(eb->diff_pristine && repos_delete))
           return SVN_NO_ERROR;
         break;
 
@@ -1328,9 +1334,6 @@ ensure_local_only_handled(struct dir_bat
         break;
     }
 
-  if (!for_delete)
-    svn_hash_sets(pb->compared, apr_pstrdup(pb->pool, name), "");
-
   if (info->kind == svn_kind_dir)
     {
       svn_depth_t depth ;
@@ -1344,7 +1347,7 @@ ensure_local_only_handled(struct dir_bat
                       eb,
                       svn_dirent_join(pb->local_abspath, name, scratch_pool),
                       svn_relpath_join(pb->path, name, scratch_pool),
-                      for_delete ? svn_depth_infinity : depth,
+                      repos_delete ? svn_depth_infinity : depth,
                       pb->pdb,
                       scratch_pool));
     }
@@ -1397,13 +1400,12 @@ delete_entry(const char *path,
              apr_pool_t *pool)
 {
   struct dir_baton_t *pb = parent_baton;
-  const char *name = svn_dirent_basename(path, NULL);
+  const char *name = svn_dirent_basename(path, pb->pool);
 
-  /* Mark this node as compared in the parent directory's baton. */
-  SVN_ERR(ensure_local_only_handled(pb,
-                                    name,
-                                    TRUE /* for_delete */,
-                                    pool));
+  if (!pb->deletes)
+    pb->deletes = apr_hash_make(pb->pool);
+
+  svn_hash_sets(pb->deletes, name, "");
   return SVN_NO_ERROR;
 }
 
@@ -1428,10 +1430,9 @@ add_directory(const char *path,
                       dir_pool);
   *child_baton = db;
 
-  if (pb && eb->local_before_remote && !pb->added)
+  if (pb && eb->local_before_remote && !pb->added && !eb->ignore_ancestry)
     SVN_ERR(ensure_local_only_handled(pb,
                                       db->name,
-                                      FALSE /* for_delete */,
                                       dir_pool));
 
   /* Issue #3797: Don't add this filename to the parent directory's list of
@@ -1472,8 +1473,8 @@ open_directory(const char *path,
   db = make_dir_baton(path, pb, pb->eb, FALSE, subdir_depth, dir_pool);
   *child_baton = db;
 
-  if (eb->local_before_remote)
-    SVN_ERR(ensure_local_only_handled(pb, db->name, FALSE, dir_pool));
+  if (eb->local_before_remote && !eb->ignore_ancestry)
+    SVN_ERR(ensure_local_only_handled(pb, db->name, dir_pool));
 
   db->left_src  = svn_diff__source_create(eb->revnum, db->pool);
   db->right_src = svn_diff__source_create(SVN_INVALID_REVNUM, db->pool);
@@ -1508,6 +1509,23 @@ close_directory(void *dir_baton,
   apr_pool_t *scratch_pool = db->pool;
   svn_boolean_t reported_closed = FALSE;
 
+  if (db->deletes)
+    {
+      apr_hash_index_t *hi;
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+      for (hi = apr_hash_first(scratch_pool, db->deletes); hi;
+           hi = apr_hash_next(hi))
+        {
+          const char *name = svn__apr_hash_index_key(hi);
+
+          svn_pool_clear(iterpool);
+          SVN_ERR(ensure_local_only_handled(db, name, iterpool));
+        }
+
+      svn_pool_destroy(iterpool);
+    }
+
   /* Mark the properties of this directory as having already been
      compared so that we know not to show any local modifications
      in walk_local_nodes_diff. */
@@ -1610,7 +1628,7 @@ close_directory(void *dir_baton,
                                       scratch_pool));
 
   if (db->parent_baton)
-    SVN_ERR(ensure_local_only_handled(db->parent_baton, db->name, FALSE,
+    SVN_ERR(ensure_local_only_handled(db->parent_baton, db->name,
                                       scratch_pool));
   SVN_ERR(maybe_done(db)); /* destroys scratch_pool */
 
@@ -1635,12 +1653,6 @@ add_file(const char *path,
   fb = make_file_baton(path, TRUE, pb, file_pool);
   *file_baton = fb;
 
-  if (eb->local_before_remote)
-    SVN_ERR(ensure_local_only_handled(pb,
-                                      fb->name,
-                                      FALSE /* for_delete */,
-                                      file_pool));
-
   /* Issue #3797: Don't add this filename to the parent directory's list of
      elements that have been compared, to show local additions via the local
      diff. The repository node is unrelated from the working copy version
@@ -1676,9 +1688,6 @@ open_file(const char *path,
   fb = make_file_baton(path, FALSE, pb, file_pool);
   *file_baton = fb;
 
-  if (eb->local_before_remote)
-    SVN_ERR(ensure_local_only_handled(pb, fb->name, FALSE, file_pool));
-
   /* Add this filename to the parent directory's list of elements that
      have been compared. */
   svn_hash_sets(pb->compared, apr_pstrdup(pb->pool, fb->name), "");
@@ -1841,6 +1850,14 @@ close_file(void *file_baton,
                                                    scratch_pool));
     }
 
+  if (fb->added
+      && eb->local_before_remote
+      && !pb->added 
+      && !eb->ignore_ancestry)
+    {
+      SVN_ERR(ensure_local_only_handled(pb, fb->name, scratch_pool));
+    }
+
   err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, &pristine_checksum, NULL,
                              &original_repos_relpath,
@@ -2038,7 +2055,7 @@ close_file(void *file_baton,
                                           scratch_pool));
     }
 
-  SVN_ERR(ensure_local_only_handled(pb, fb->name, FALSE, scratch_pool));
+  SVN_ERR(ensure_local_only_handled(pb, fb->name, scratch_pool));
   svn_pool_destroy(fb->pool); /* destroys scratch_pool */
   SVN_ERR(maybe_done(fb->parent_baton));
   return SVN_NO_ERROR;
@@ -2108,7 +2125,7 @@ close_edit(void *edit_baton,
                                     eb->anchor_abspath,
                                     "",
                                     eb->depth,
-                                    NULL,
+                                    NULL /* compared */,
                                     NULL /* No parent_baton */,
                                     eb->pool));
     }

Modified: subversion/trunk/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/diff_tests.py?rev=1444966&r1=1444965&r2=1444966&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/diff_tests.py Mon Feb 11 21:22:00 2013
@@ -4249,15 +4249,13 @@ def simple_ancestry(sbox):
                                         '--show-copies-as-adds',
                                         '--no-diff-added')
 
-  # Now introduce a replacements and a delete-deletes
+  # Now introduce a replacements and some delete-deletes
   sbox.simple_update()
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'cp', sbox.repo_url + '/A/B/E@1',
-                                           sbox.ospath('A/B/E'))
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'cp', sbox.repo_url + '/A/D/G/rho@1',
-                                           sbox.repo_url + '/A/D/G/tau@1',
-                                           sbox.ospath('A/D/G'))
+  sbox.simple_mkdir('A/B/E')
+  sbox.simple_add_text('New alpha', 'A/B/E/alpha')
+  sbox.simple_add_text('New beta', 'A/B/E/beta')
+  sbox.simple_add_text('New rho', 'A/D/G/rho')
+  sbox.simple_add_text('New tau', 'A/D/G/tau')
   sbox.simple_rm('A/B/E_copied', 'A/D/G/pi-2', 'A/D/G/rho-2')
 
   expected_output = svntest.verify.UnorderedOutput([
@@ -4289,6 +4287,17 @@ def simple_ancestry(sbox):
                                         '--show-copies-as-adds',
                                         '--no-diff-added')
 
+  sbox.simple_commit()
+  sbox.simple_update()
+
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'diff', sbox.wc_dir,
+                                        '-r', '1',
+                                        '--notice-ancestry',
+                                        '--no-diff-deleted',
+                                        '--show-copies-as-adds',
+                                        '--no-diff-added')
+
 
 ########################################################################
 #Run the tests