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 2014/04/20 17:01:50 UTC

svn commit: r1588775 - in /subversion/branches/1.8.x-issue4480: ./ subversion/mod_dav_svn/repos.c subversion/tests/cmdline/commit_tests.py

Author: rhuijben
Date: Sun Apr 20 15:01:49 2014
New Revision: 1588775

URL: http://svn.apache.org/r1588775
Log:
Merge r1577739,1577755,1588772, switching code to deprecated fs_id apis.

Modified:
    subversion/branches/1.8.x-issue4480/   (props changed)
    subversion/branches/1.8.x-issue4480/subversion/mod_dav_svn/repos.c
    subversion/branches/1.8.x-issue4480/subversion/tests/cmdline/commit_tests.py

Propchange: subversion/branches/1.8.x-issue4480/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1577739,1577755,1588772

Modified: subversion/branches/1.8.x-issue4480/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-issue4480/subversion/mod_dav_svn/repos.c?rev=1588775&r1=1588774&r2=1588775&view=diff
==============================================================================
--- subversion/branches/1.8.x-issue4480/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/1.8.x-issue4480/subversion/mod_dav_svn/repos.c Sun Apr 20 15:01:49 2014
@@ -1790,14 +1790,106 @@ do_out_of_date_check(dav_resource_combin
                                 "Could not get created rev of "
                                 "resource", r->pool);
 
-  if (comb->priv.version_name < created_rev)
+  if (SVN_IS_VALID_REVNUM(created_rev))
     {
-      serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
-                               "Item '%s' is out of date",
-                               comb->priv.repos_path);
-      return dav_svn__convert_err(serr, HTTP_CONFLICT,
-                                  "Attempting to modify out-of-date resource.",
-                                  r->pool);
+      if (comb->priv.version_name < created_rev)
+        {
+          serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
+                                   comb->res.collection
+                                    ? "Directory '%s' is out of date"
+                                    : (comb->res.exists
+                                        ? "File '%s' is out of date"
+                                        : "'%s' is out of date"),
+                                   comb->priv.repos_path);
+          return dav_svn__convert_err(serr, HTTP_CONFLICT,
+                                      "Attempting to modify out-of-date resource.",
+                                      r->pool);
+        }
+    }
+  else if (SVN_IS_VALID_REVNUM(comb->priv.version_name)
+           && comb->res.collection)
+    {
+      /* Issue #4480: With HTTPv2 we can receive the first change for a
+         directory after it has been made mutable, because one of its
+         descendants was changed before changing the directory.
+
+         We have to check if whatever the node is in HEAD is equivalent
+         to what it was in the provided BASE revision.
+
+         If the node was copied, we would process it before its decendants
+         and we already performed quite a few checks when making it mutable
+         via its descendant, so what we should really check here is if the
+         properties changed since the BASE version.
+
+         ### I think svn_fs_node_relation() checks for more changes than we
+             should check for here. Needs further review. But it looks like\
+             this check matches the checks in the libsvn_fs commit editor.
+
+             For now I would say reporting out of date in a few too many
+             cases is safer than not reporting out of date when we should.
+       */
+      svn_revnum_t youngest;
+      svn_fs_root_t *youngest_root;
+      svn_fs_root_t *rev_root;
+      svn_fs_id_t *youngest_id;
+      svn_fs_id_t *rev_id;
+
+      serr = svn_fs_youngest_rev(&youngest, comb->res.info->repos->fs,
+                                 r->pool);
+      if (serr != NULL)
+        {
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not determine the youngest "
+                                      "revision for verification against "
+                                      "the baseline being checked out",
+                                      r->pool);
+        }
+
+      if (comb->priv.version_name == youngest)
+        return NULL; /* Easy out: we commit against HEAD */
+
+      serr = svn_fs_revision_root(&youngest_root, comb->res.info->repos->fs,
+                                  youngest, r->pool);
+                                  
+      if (!serr)
+        serr = svn_fs_node_id(&youngest_id, youngest_root,
+                              comb->priv.repos_path, r->pool);
+
+      if (serr != NULL)
+        {
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not open youngest revision root "
+                                      "for verification against the base "
+                                      "revision", r->pool);
+        }
+
+      serr = svn_fs_revision_root(&rev_root, comb->res.info->repos->fs,
+                                  comb->priv.version_name, r->pool);
+
+      if (!serr)
+        serr = svn_fs_node_id(&rev_id, rev_root,
+                              comb->priv.repos_path, r->pool);
+
+      if (serr != NULL)
+        {
+          return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
+                                      "Could not open the base revision"
+                                      "for verification against the youngest "
+                                      "revision", r->pool);
+        }
+
+      svn_fs_close_root(rev_root);
+      svn_fs_close_root(youngest_root);
+
+      if (0 == svn_fs_compare_ids(youngest_id, rev_id))
+        {
+          serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
+                                   "Directory '%s' is out of date",
+                                   comb->priv.repos_path);
+          return dav_svn__convert_err(serr, HTTP_CONFLICT,
+                                      "Attempting to modify out-of-date resource.",
+                                      r->pool);
+        }
     }
 
   return NULL;

Modified: subversion/branches/1.8.x-issue4480/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-issue4480/subversion/tests/cmdline/commit_tests.py?rev=1588775&r1=1588774&r2=1588775&view=diff
==============================================================================
--- subversion/branches/1.8.x-issue4480/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/branches/1.8.x-issue4480/subversion/tests/cmdline/commit_tests.py Sun Apr 20 15:01:49 2014
@@ -3067,6 +3067,57 @@ def commit_deep_deleted(sbox):
                                         sbox.ospath('AA'),
                                         sbox.ospath('A'))
 
+@Issue(4480)
+def commit_mergeinfo_ood(sbox):
+  "commit of mergeinfo that should cause out of date"
+
+  sbox.build()
+  sbox.simple_rm('A', 'iota')
+  sbox.simple_commit() # r2
+
+  sbox.simple_mkdir('trunk', 'branch')
+  sbox.simple_commit() # r3
+
+  sbox.simple_append('trunk/a', 'This is a\n')
+  sbox.simple_add('trunk/a')
+  sbox.simple_commit() # r4
+
+  sbox.simple_append('trunk/b', 'This is b\n')
+  sbox.simple_add('trunk/b')
+  sbox.simple_commit() # r5
+
+  sbox.simple_update() # To r5
+
+  expected_output = [
+    '--- Merging r4 into \'%s\':\n' % sbox.ospath('branch'),
+    'A    %s\n' % sbox.ospath('branch/a'),
+    '--- Recording mergeinfo for merge of r4' \
+                                ' into \'%s\':\n' % sbox.ospath('branch'),
+    ' U   %s\n' % sbox.ospath('branch'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge', '-c4', '^/trunk',
+                                     sbox.ospath('branch'))
+
+  sbox.simple_commit()
+
+  sbox.simple_update(revision='5')
+
+  expected_output = [
+    '--- Merging r5 into \'%s\':\n' % sbox.ospath('branch'),
+    'A    %s\n' % sbox.ospath('branch/b'),
+    '--- Recording mergeinfo for merge of r5 into \'%s\':\n' % sbox.ospath('branch'),
+    ' U   %s\n' % sbox.ospath('branch'),
+  ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'merge', '-c5', '^/trunk',
+                                     sbox.ospath('branch'))
+
+  # Currently this commit succeeds with dav over HTTPv2, while it should really fail
+  expected_err = '.*out of date.*'
+  svntest.actions.run_and_verify_svn(None, None, expected_err,
+                                     'commit', sbox.ospath(''), '-m', 'M')
+
 ########################################################################
 # Run the tests
 
@@ -3140,6 +3191,7 @@ test_list = [ None,
               last_changed_of_copied_subdir,
               commit_cp_with_deep_delete,
               commit_deep_deleted,
+              commit_mergeinfo_ood,
              ]
 
 if __name__ == '__main__':