You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2011/10/25 15:35:06 UTC

svn commit: r1188652 - in /subversion/trunk: ./ subversion/libsvn_wc/ subversion/tests/cmdline/ subversion/tests/cmdline/svntest/ subversion/tests/libsvn_wc/

Author: philip
Date: Tue Oct 25 13:35:05 2011
New Revision: 1188652

URL: http://svn.apache.org/viewvc?rev=1188652&view=rev
Log:
Fix issue 4042, commit of incomplete directory asserts.

* subversion/libsvn_wc/adm_ops.c
  (process_committed_leaf): Allow incomplete nodes.

* subversion/libsvn_wc/wc_db.c
  (commit_node): Preserve incomplete status.

* subversion/tests/libsvn_wc/wc-incomplete-tester.c: New.

* build.conf
  (wc-incomplete-tester): New.

* subversion/tests/cmdline/svntest/main.py
  (wc_incomplete_tester_binary, run_wc_incomplete_tester): New.

* subversion/tests/cmdline/svntest/actions.py
  (set_incomplete): New.

* subversion/tests/cmdline/commit_tests.py
  (commit_incomplete): New.
  (test_list): Add new test.

Added:
    subversion/trunk/subversion/tests/libsvn_wc/wc-incomplete-tester.c
Modified:
    subversion/trunk/build.conf
    subversion/trunk/subversion/libsvn_wc/adm_ops.c
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/tests/cmdline/commit_tests.py
    subversion/trunk/subversion/tests/cmdline/svntest/actions.py
    subversion/trunk/subversion/tests/cmdline/svntest/main.py

Modified: subversion/trunk/build.conf
URL: http://svn.apache.org/viewvc/subversion/trunk/build.conf?rev=1188652&r1=1188651&r2=1188652&view=diff
==============================================================================
--- subversion/trunk/build.conf (original)
+++ subversion/trunk/build.conf Tue Oct 25 13:35:05 2011
@@ -1023,6 +1023,14 @@ install = test
 libs = libsvn_wc libsvn_subr apriconv apr
 testing = skip
 
+[wc-incomplete-tester]
+type = exe
+path = subversion/tests/libsvn_wc
+sources = wc-incomplete-tester.c
+install = test
+libs = libsvn_wc libsvn_subr apriconv apr
+testing = skip
+
 # ----------------------------------------------------------------------------
 #
 # EXTERNAL TARGETS (NO BUILD NEEDED)

Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1188652&r1=1188651&r2=1188652&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Tue Oct 25 13:35:05 2011
@@ -174,6 +174,7 @@ process_committed_leaf(svn_wc__db_t *db,
     }
 
   SVN_ERR_ASSERT(status == svn_wc__db_status_normal
+                 || status == svn_wc__db_status_incomplete
                  || status == svn_wc__db_status_added);
 
   if (kind != svn_kind_dir)

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1188652&r1=1188651&r2=1188652&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Oct 25 13:35:05 2011
@@ -8567,6 +8567,7 @@ commit_node(void *baton,
   apr_int64_t repos_id;
   const char *repos_relpath;
   apr_int64_t op_depth;
+  svn_wc__db_status_t old_presence;
 
     /* If we are adding a file or directory, then we need to get
      repository information from the parent node since "this node" does
@@ -8629,6 +8630,8 @@ commit_node(void *baton,
   if (cb->keep_changelist && have_act)
     changelist = svn_sqlite__column_text(stmt_act, 1, scratch_pool);
 
+  old_presence = svn_sqlite__column_token(stmt_info, 3, presence_map);
+
   /* ### other stuff?  */
 
   SVN_ERR(svn_sqlite__reset(stmt_info));
@@ -8684,8 +8687,10 @@ commit_node(void *baton,
   else
     parent_relpath = svn_relpath_dirname(local_relpath, scratch_pool);
 
-  /* ### other presences? or reserve that for separate functions?  */
-  new_presence = svn_wc__db_status_normal;
+  /* Preserve any incomplete status */
+  new_presence = (old_presence == svn_wc__db_status_incomplete
+                  ? svn_wc__db_status_incomplete
+                  : svn_wc__db_status_normal);
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_APPLY_CHANGES_TO_BASE_NODE));

Modified: subversion/trunk/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/commit_tests.py?rev=1188652&r1=1188651&r2=1188652&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/commit_tests.py Tue Oct 25 13:35:05 2011
@@ -2803,6 +2803,28 @@ def commit_multiple_nested_deletes(sbox)
 
   svntest.main.run_svn(None, 'ci', A, A_B, '-m', 'Q')
 
+@Issue(4042)
+def commit_incomplete(sbox):
+  "commit an incomplete dir"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_propset('pname', 'pval', 'A/B')
+  svntest.actions.set_incomplete(sbox.ospath('A/B'), 1)
+
+  expected_output = svntest.wc.State(wc_dir, {
+      'A/B' : Item(verb='Sending'),
+      })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/B',  status='! ', wc_rev=2)
+
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        expected_output,
+                                        expected_status,
+                                        None,
+                                        wc_dir)
+  
 
 ########################################################################
 # Run the tests
@@ -2871,6 +2893,7 @@ test_list = [ None,
               tree_conflicts_block_commit,
               tree_conflicts_resolved,
               commit_multiple_nested_deletes,
+              commit_incomplete,
              ]
 
 if __name__ == '__main__':

Modified: subversion/trunk/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svntest/actions.py?rev=1188652&r1=1188651&r2=1188652&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svntest/actions.py Tue Oct 25 13:35:05 2011
@@ -1748,6 +1748,11 @@ def lock_admin_dir(wc_dir, recursive=Fal
 
   svntest.main.run_wc_lock_tester(recursive, wc_dir)
 
+def set_incomplete(wc_dir, revision):
+  "Make wc_dir incomplete at revision"
+
+  svntest.main.run_wc_incomplete_tester(wc_dir, revision)
+
 def get_wc_uuid(wc_dir):
   "Return the UUID of the working copy at WC_DIR."
   return run_and_parse_info(wc_dir)[0]['Repository UUID']

Modified: subversion/trunk/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svntest/main.py?rev=1188652&r1=1188651&r2=1188652&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svntest/main.py Tue Oct 25 13:35:05 2011
@@ -165,6 +165,7 @@ entriesdump_binary = os.path.abspath('en
 atomic_ra_revprop_change_binary = os.path.abspath('atomic-ra-revprop-change' + \
                                                   _exe)
 wc_lock_tester_binary = os.path.abspath('../libsvn_wc/wc-lock-tester' + _exe)
+wc_incomplete_tester_binary = os.path.abspath('../libsvn_wc/wc-incomplete-tester' + _exe)
 svnmucc_binary=os.path.abspath('../../../tools/client-side/svnmucc/svnmucc' + \
                                _exe)
 
@@ -683,6 +684,10 @@ def run_wc_lock_tester(recursive, path):
     option = "-1"
   return run_command(wc_lock_tester_binary, False, False, option, path)
 
+def run_wc_incomplete_tester(wc_dir, revision):
+  "Run the wc-incomplete tool, returning its exit code, stdout and stderr"
+  return run_command(wc_incomplete_tester_binary, False, False,
+                     wc_dir, revision)
 
 def youngest(repos_path):
   "run 'svnlook youngest' on REPOS_PATH, returns revision as int"

Added: subversion/trunk/subversion/tests/libsvn_wc/wc-incomplete-tester.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/wc-incomplete-tester.c?rev=1188652&view=auto
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/wc-incomplete-tester.c (added)
+++ subversion/trunk/subversion/tests/libsvn_wc/wc-incomplete-tester.c Tue Oct 25 13:35:05 2011
@@ -0,0 +1,97 @@
+/*
+ * wc-incomplete-tester.c :  mark a directory incomplete at a given revision
+ *
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+
+#include "svn_pools.h"
+#include "svn_types.h"
+#include "svn_path.h"
+#include "../../libsvn_wc/wc.h"
+#include "../../libsvn_wc/wc_db.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static
+svn_error_t *incomplete(const char *wc_path,
+                        const char *rev_str,
+                        const char *repos_relpath,
+                        apr_pool_t *pool)
+{
+  svn_wc_context_t *wc_ctx;
+  const char *local_abspath;
+  svn_revnum_t revnum;
+
+  SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));
+
+  SVN_ERR(svn_path_cstring_to_utf8(&wc_path, wc_path, pool));
+  wc_path = svn_dirent_canonicalize(wc_path, pool);
+  SVN_ERR(svn_dirent_get_absolute(&local_abspath, wc_path, pool));
+
+  SVN_ERR(svn_cstring_atoi64(&revnum, rev_str));
+
+  if (repos_relpath)
+    repos_relpath = svn_relpath_canonicalize(repos_relpath, pool);
+  else
+    SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL,
+                                 &repos_relpath,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 wc_ctx->db, local_abspath, pool, pool));
+
+  SVN_ERR(svn_wc__db_temp_op_start_directory_update(wc_ctx->db,
+                                                    local_abspath,
+                                                    repos_relpath,
+                                                    revnum,
+                                                    pool));
+
+  return SVN_NO_ERROR;
+}
+
+int main(int argc, const char *argv[])
+{
+  apr_pool_t *pool;
+  svn_error_t *err;
+
+  if (argc != 3 && argc != 4)
+    {
+      fprintf(stderr,
+              "Usage: wc-incomplete-tester WCPATH REVISION [REPOS_RELPATH]\n"
+              "Mark WCPATH incomplete at REVISION [and REPOS_RELPATH]\n");
+      exit(EXIT_FAILURE);
+    }
+          
+  if (apr_initialize())
+    {
+      fprintf(stderr, "apr_initialize failed\n");
+      exit(EXIT_FAILURE);
+    }
+  pool = svn_pool_create(NULL);
+
+  err = incomplete(argv[1], argv[2], (argc == 4 ? argv[3] : NULL), pool);
+  if (err)
+    svn_handle_error2(err, stderr, TRUE, "wc-incomplete-tester: ");
+
+  svn_pool_destroy(pool);
+  apr_terminate();
+
+  return EXIT_SUCCESS;
+}