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 2012/11/08 01:37:31 UTC

svn commit: r1406877 - in /subversion/branches/1.7.x-issue4091: ./ subversion/libsvn_wc/update_editor.c subversion/tests/cmdline/special_tests.py

Author: philip
Date: Thu Nov  8 00:37:30 2012
New Revision: 1406877

URL: http://svn.apache.org/viewvc?rev=1406877&view=rev
Log:
On the 1.7.x-issue4091 branch, merge r1356167,1406870 and resolve conflicts.

Modified:
    subversion/branches/1.7.x-issue4091/   (props changed)
    subversion/branches/1.7.x-issue4091/subversion/libsvn_wc/update_editor.c
    subversion/branches/1.7.x-issue4091/subversion/tests/cmdline/special_tests.py

Propchange: subversion/branches/1.7.x-issue4091/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1356167,1406870

Modified: subversion/branches/1.7.x-issue4091/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4091/subversion/libsvn_wc/update_editor.c?rev=1406877&r1=1406876&r2=1406877&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4091/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/1.7.x-issue4091/subversion/libsvn_wc/update_editor.c Thu Nov  8 00:37:30 2012
@@ -4074,29 +4074,39 @@ close_file(void *file_baton,
 
       if (local_is_link != incoming_is_link)
         {
-          svn_wc_conflict_description2_t *tree_conflict = NULL;
+          svn_boolean_t is_locally_modified;
 
-          fb->shadowed = TRUE;
-          fb->obstruction_found = TRUE;
-          fb->add_existed = FALSE;
-
-          /* ### Performance: We should just create the conflict here, without
-             ### verifying again */
-          SVN_ERR(check_tree_conflict(&tree_conflict, eb, fb->local_abspath,
-                                      svn_wc__db_status_added,
-                                      svn_wc__db_kind_file, TRUE,
-                                      svn_wc_conflict_action_add,
-                                      svn_node_file, fb->new_relpath,
-                                      scratch_pool, scratch_pool));
-          SVN_ERR_ASSERT(tree_conflict != NULL);
-          SVN_ERR(svn_wc__db_op_set_tree_conflict(eb->db,
-                                                  fb->local_abspath,
-                                                  tree_conflict,
-                                                  scratch_pool));
-
-          fb->already_notified = TRUE;
-          do_notification(eb, fb->local_abspath, svn_node_unknown,
-                          svn_wc_notify_tree_conflict, scratch_pool);
+          SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified,
+                                                   eb->db, fb->local_abspath,
+                                                   FALSE /* exact_comparison */,
+                                                   scratch_pool));
+
+          if (is_locally_modified)
+            {
+              svn_wc_conflict_description2_t *tree_conflict = NULL;
+
+              fb->shadowed = TRUE;
+              fb->obstruction_found = TRUE;
+              fb->add_existed = FALSE;
+
+              /* ### Performance: We should just create the conflict
+                 ### here, without verifying again */
+              SVN_ERR(check_tree_conflict(&tree_conflict, eb, fb->local_abspath,
+                                          svn_wc__db_status_added,
+                                          svn_wc__db_kind_file, TRUE,
+                                          svn_wc_conflict_action_add,
+                                          svn_node_file, fb->new_relpath,
+                                          scratch_pool, scratch_pool));
+              SVN_ERR_ASSERT(tree_conflict != NULL);
+              SVN_ERR(svn_wc__db_op_set_tree_conflict(eb->db,
+                                                      fb->local_abspath,
+                                                      tree_conflict,
+                                                      scratch_pool));
+
+              fb->already_notified = TRUE;
+              do_notification(eb, fb->local_abspath, svn_node_unknown,
+                              svn_wc_notify_tree_conflict, scratch_pool);
+            }
         }
     }
 

Modified: subversion/branches/1.7.x-issue4091/subversion/tests/cmdline/special_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x-issue4091/subversion/tests/cmdline/special_tests.py?rev=1406877&r1=1406876&r2=1406877&view=diff
==============================================================================
--- subversion/branches/1.7.x-issue4091/subversion/tests/cmdline/special_tests.py (original)
+++ subversion/branches/1.7.x-issue4091/subversion/tests/cmdline/special_tests.py Thu Nov  8 00:37:30 2012
@@ -25,12 +25,12 @@
 ######################################################################
 
 # General modules
-import sys, os, re
+import sys, os, re, copy
 
 # Our testing module
 import svntest
 
-from svntest.main import server_has_mergeinfo
+from svntest.main import server_has_mergeinfo, run_svn, file_write
 
 # (abbreviation)
 Skip = svntest.testcase.Skip_deco
@@ -906,6 +906,172 @@ def update_symlink(sbox):
                                         None, None, None,
                                         None, None, 1)
 
+@Issue(4091)
+@SkipUnless(svntest.main.is_posix_os)
+def replace_symlinks(sbox):
+  "replace symlinks"
+  sbox.build()
+  wc = sbox.ospath
+
+  # Some of these tests are implemented for git (in test script
+  # t/t9100-git-svn-basic.sh) using the Perl bindings for Subversion.
+  # Our issue #4091 is about 'svn update' failures in the git tests.
+
+  sbox.simple_mkdir('A/D/G/Z')
+  sbox.simple_mkdir('A/D/Gx')
+  sbox.simple_mkdir('A/D/Gx/Z')
+  sbox.simple_mkdir('A/D/Hx')
+  sbox.simple_mkdir('A/D/Y')
+  sbox.simple_mkdir('Ax')
+
+  os.symlink('../Y', wc('A/D/H/Z'))
+  os.symlink('../Y', wc('A/D/Hx/Z'))
+  sbox.simple_add('A/D/H/Z',
+                  'A/D/Hx/Z')
+
+  for p in ['Ax/mu',
+            'A/D/Gx/pi',
+            'A/D/Hx/chi',
+            ]:
+      file_write(wc(p), 'This starts as a normal file.\n')
+      sbox.simple_add(p)
+  for p in ['iota.sh',
+            'A/mu.sh',
+            'Ax/mu.sh',
+            'A/D/gamma.sh',
+            'A/B/E/beta.sh',
+            'A/D/G/rho.sh',
+            'A/D/Gx/rho.sh',
+            'A/D/H/psi.sh',
+            'A/D/Hx/psi.sh',
+            ]:
+      file_write(wc(p), '#!/bin/sh\necho "hello, svn!"\n')
+      os.chmod(wc(p), 0775)
+      sbox.simple_add(p)
+  sbox.simple_commit() # r2
+  sbox.simple_update()
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 2)
+  expected_status.add({
+    'A/D/Y'         : Item(status='  ', wc_rev=2),
+    'A/D/G/Z'       : Item(status='  ', wc_rev=2),
+    'A/D/G/rho.sh'  : Item(status='  ', wc_rev=2),
+    'A/D/Hx'        : Item(status='  ', wc_rev=2),
+    'A/D/Hx/Z'      : Item(status='  ', wc_rev=2),
+    'A/D/Hx/chi'    : Item(status='  ', wc_rev=2),
+    'A/D/Hx/psi.sh' : Item(status='  ', wc_rev=2),
+    'A/D/H/psi.sh'  : Item(status='  ', wc_rev=2),
+    'A/D/H/Z'       : Item(status='  ', wc_rev=2),
+    'A/D/Gx'        : Item(status='  ', wc_rev=2),
+    'A/D/Gx/Z'      : Item(status='  ', wc_rev=2),
+    'A/D/Gx/pi'     : Item(status='  ', wc_rev=2),
+    'A/D/Gx/rho.sh' : Item(status='  ', wc_rev=2),
+    'A/D/gamma.sh'  : Item(status='  ', wc_rev=2),
+    'A/B/E/beta.sh' : Item(status='  ', wc_rev=2),
+    'Ax'            : Item(status='  ', wc_rev=2),
+    'Ax/mu'         : Item(status='  ', wc_rev=2),
+    'Ax/mu.sh'      : Item(status='  ', wc_rev=2),
+    'A/mu.sh'       : Item(status='  ', wc_rev=2),
+    'iota.sh'       : Item(status='  ', wc_rev=2),
+    })
+  expected_status_r2 = copy.deepcopy(expected_status)
+  svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status_r2)
+
+  # Failing git-svn test: 'new symlink is added to a file that was
+  # also just made executable', i.e., in the same revision.
+  sbox.simple_propset("svn:executable", "*", 'A/B/E/alpha')
+  os.symlink('alpha', wc('A/B/E/sym-alpha'))
+  sbox.simple_add('A/B/E/sym-alpha')
+
+  # Add a symlink to a file made non-executable in the same revision.
+  sbox.simple_propdel("svn:executable", 'A/B/E/beta.sh')
+  os.symlink('beta.sh', wc('A/B/E/sym-beta.sh'))
+  sbox.simple_add('A/B/E/sym-beta.sh')
+
+  # Replace a normal {file, exec, dir} with a symlink to the same kind
+  # via Subversion replacement.
+  sbox.simple_rm('A/D/G/pi',
+                 'A/D/G/rho.sh',
+                 #'A/D/G/Z', # Ooops, not compatible with --bin=svn1.6.
+                 )
+  os.symlink(wc('../gamma'), wc('A/D/G/pi'))
+  os.symlink(wc('../gamma.sh'), wc('A/D/G/rho.sh'))
+  #os.symlink(wc('../Y'), wc('A/D/G/Z'))
+  sbox.simple_add('A/D/G/pi',
+                  'A/D/G/rho.sh',
+                  #'A/D/G/Z',
+                  )
+
+  # Replace a symlink to {file, exec, dir} with a normal item of the
+  # same kind via Subversion replacement.
+  sbox.simple_rm('A/D/H/chi',
+                 'A/D/H/psi.sh',
+                 #'A/D/H/Z',
+                 )
+  os.symlink(wc('../gamma'), wc('A/D/H/chi'))
+  os.symlink(wc('../gamma.sh'), wc('A/D/H/psi.sh'))
+  #os.symlink(wc('../Y'), wc('A/D/H/Z'))
+  sbox.simple_add('A/D/H/chi',
+                  'A/D/H/psi.sh',
+                  #'A/D/H/Z',
+                  )
+
+  # Replace a normal {file, exec} with a symlink to {exec, file} via
+  # Subversion replacement.
+  sbox.simple_rm('A/mu',
+                 'A/mu.sh')
+  os.symlink('../iota2', wc('A/mu'))
+  os.symlink('../iota', wc('A/mu.sh'))
+  sbox.simple_add('A/mu',
+                  'A/mu.sh')
+
+  # Ditto, without the Subversion replacement.  Failing git-svn test
+  # 'executable file becomes a symlink to bar/zzz (file)'.
+  os.remove(wc('Ax/mu'))
+  os.remove(wc('Ax/mu.sh'))
+  os.symlink('../iota2', wc('Ax/mu'))
+  os.symlink('../iota', wc('Ax/mu.sh'))
+  sbox.simple_propset('svn:special', '*',
+                      'Ax/mu',
+                      'Ax/mu.sh')
+  sbox.simple_propdel('svn:executable', 'Ax/mu.sh')
+
+  ### TODO Replace a normal {file, exec, dir, dir} with a symlink to
+  ### {dir, dir, file, exec}.  And the same symlink-to-normal.
+
+  expected_status.tweak('A/D/G/pi',
+                        'A/D/G/rho.sh',
+                        'A/D/H/psi.sh',
+                        'A/D/H/chi',
+                        'A/mu',
+                        'A/mu.sh',
+                        status='RM')
+  expected_status.tweak('A/B/E/beta.sh',
+                        'A/B/E/alpha',
+                        status=' M')
+  expected_status.tweak('Ax/mu',
+                        'Ax/mu.sh',
+                        status='MM')
+  expected_status.add({
+      'A/B/E/sym-alpha'   : Item(status='A ', wc_rev=0),
+      'A/B/E/sym-beta.sh' : Item(status='A ', wc_rev=0),
+      })
+  svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status)
+
+  sbox.simple_commit() # r3
+  sbox.simple_update()
+
+  expected_status.tweak(status='  ', wc_rev=3)
+  expected_status_r3 = expected_status
+  svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status_r3)
+
+  # Try updating from HEAD-1 to HEAD.  This is currently XFAIL as the
+  # update to HEAD-1 produces a tree conflict.
+  run_svn(None, 'up', '-r2', sbox.wc_dir)
+  svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status_r2)
+  sbox.simple_update()
+  svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status_r3)
+
+
 @Issue(4102)
 @SkipUnless(svntest.main.is_posix_os)
 def externals_as_symlink_targets(sbox):
@@ -964,6 +1130,7 @@ test_list = [ None,
               symlink_to_wc_basic,
               symlink_to_wc_svnversion,
               update_symlink,
+              replace_symlinks,
               externals_as_symlink_targets,
              ]