Uploaded image for project: 'Subversion'
  1. Subversion
  2. SVN-3115

Case only renames resulting from merges don't work or break the WC on case-insensitive file systems

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • trunk
    • 1.7.0
    • libsvn_wc
    • None

    Description

      If performing a merge where the following are true:
      
      1) WC is on a case insensitive file system
      2) The merge attempts to rename a path within the same directory
      3) The source and destination of the move differ *only* by case
      
      Then the merge doesn't work (if the path is a dir) or works, but breaks the WC
      (if the path is a file).  See
      http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=135710 for some
      more background and discussion of possible fixes.
      
      (All examples which follow start with a standard greek tree from the test suite
      when r2 is a copy of 'A' to 'A_COPY'):
      
      CASE ONLY FILE MOVE:
      
      
      >svn st merge_tests-87 -v
                     1        1 jrandom      merge_tests-87
                     1        1 jrandom      merge_tests-87\A
                     1        1 jrandom      merge_tests-87\A\B
                     1        1 jrandom      merge_tests-87\A\B\lambda
                     1        1 jrandom      merge_tests-87\A\B\E
                     1        1 jrandom      merge_tests-87\A\B\E\alpha
                     1        1 jrandom      merge_tests-87\A\B\E\beta
                     1        1 jrandom      merge_tests-87\A\B\F
                     1        1 jrandom      merge_tests-87\A\mu
                     1        1 jrandom      merge_tests-87\A\C
                     1        1 jrandom      merge_tests-87\A\D
                     1        1 jrandom      merge_tests-87\A\D\gamma
                     1        1 jrandom      merge_tests-87\A\D\G
                     1        1 jrandom      merge_tests-87\A\D\G\pi
                     1        1 jrandom      merge_tests-87\A\D\G\rho
                     1        1 jrandom      merge_tests-87\A\D\G\tau
                     1        1 jrandom      merge_tests-87\A\D\H
                     1        1 jrandom      merge_tests-87\A\D\H\chi
                     1        1 jrandom      merge_tests-87\A\D\H\omega
                     1        1 jrandom      merge_tests-87\A\D\H\psi
                     2        2 jrandom      merge_tests-87\A_COPY
                     2        2 jrandom      merge_tests-87\A_COPY\B
                     2        2 jrandom      merge_tests-87\A_COPY\B\lambda
                     2        2 jrandom      merge_tests-87\A_COPY\B\E
                     2        2 jrandom      merge_tests-87\A_COPY\B\E\alpha
                     2        2 jrandom      merge_tests-87\A_COPY\B\E\beta
                     2        2 jrandom      merge_tests-87\A_COPY\B\F
                     2        2 jrandom      merge_tests-87\A_COPY\mu
                     2        2 jrandom      merge_tests-87\A_COPY\C
                     2        2 jrandom      merge_tests-87\A_COPY\D
                     2        2 jrandom      merge_tests-87\A_COPY\D\gamma
                     2        2 jrandom      merge_tests-87\A_COPY\D\G
                     2        2 jrandom      merge_tests-87\A_COPY\D\G\pi
                     2        2 jrandom      merge_tests-87\A_COPY\D\G\rho
                     2        2 jrandom      merge_tests-87\A_COPY\D\G\tau
                     2        2 jrandom      merge_tests-87\A_COPY\D\H
                     2        2 jrandom      merge_tests-87\A_COPY\D\H\chi
                     2        2 jrandom      merge_tests-87\A_COPY\D\H\omega
                     2        2 jrandom      merge_tests-87\A_COPY\D\H\psi
                     1        1 jrandom      merge_tests-87\iota
      
      >svn move %url%/A/mu %url%/A/MU -m "case only file move"
      
      Committed revision 3.
      
      >svn merge %url%/A merge_tests-87\A_COPY -c3
      --- Merging r3 into 'merge_tests-87\A_COPY':
      A    merge_tests-87\A_COPY\MU
      D    merge_tests-87\A_COPY\mu
      
      # Can't have the text bases for both 'mu' and 'MU' on a case
      # insensitive file system.  This is the start of our troubles.
      >dir merge_tests-87\A_COPY\.svn\text-base
       Volume in drive C is Local Disk
       Volume Serial Number is FCC3-CBDB
      
       Directory of merge_tests-87\A_COPY\.svn\text-base
      
      03/03/2008  02:52 PM    <DIR>          .
      03/03/2008  02:52 PM    <DIR>          ..
      03/03/2008  02:52 PM                23 MU.svn-base
                    1 File(s)             23 bytes
                    2 Dir(s)  26,149,707,776 bytes free
      
      # We can commit the above change, but...
      >svn ci -m "" merge_tests-87
      Sending        merge_tests-87\A_COPY
      Adding         merge_tests-87\A_COPY\MU
      Deleting       merge_tests-87\A_COPY\mu
      
      Committed revision 4.
      
      # ...svn_client_commit4() when running the log deletes the 'MU' text base
      # when it tries to delete the 'mu' text base and without a text base for 'MU'...
      >dir merge_tests-87\A_COPY\.svn\text-base
       Volume in drive C is Local Disk
       Volume Serial Number is FCC3-CBDB
      
       Directory of merge_tests-87\A_COPY\.svn\text-base
      
      03/03/2008  02:53 PM    <DIR>          .
      03/03/2008  02:53 PM    <DIR>          ..
                    0 File(s)              0 bytes
                    2 Dir(s)  26,149,707,776 bytes free
      
      # ...revert is forever broken on this WC:
      >svn revert -R merge_tests-87
      ..\..\..\subversion\libsvn_wc\adm_ops.c:1823: (apr_err=2)
      svn: Error restoring text for 'merge_tests-87\A_COPY\MU'
      
      The only solutions are to checkout new version of the working copy or delete
      'A_COPY' via the OS and then update the WC.  An update alone isn't sufficient
      since update doesn't restore missing text bases.
      
      Obviously this isn't a huge problem as a lot of things have to go just right
      (wrong?) for the problem to occur.  Notably, unlike merge, update doesn't need
      to be "revertable" so the deletion can take place first and then the add (see
      r12616) so only the user doing the merge is impacted.
      
      CASE ONLY DIRECTORY MOVE:
      
      # Do a case-only move of a directory within the same parent:
      >svn move %url%/A/D %url%/A/d -m ""
      
      Committed revision 3.
      
      # Merge that move into 'A_COPY':
      >svn merge %url%/A merge_tests-87\A_COPY -c3
      ..\..\..\subversion\libsvn_wc\lock.c:366: (apr_err=155004)
      svn: Working copy 'merge_tests-87\A_COPY\d' locked
      svn: run 'svn cleanup' to remove locks (type 'svn help cleanup' for details)
      
      The problem is that the whole tree rooted at 'A_COPY' gets locked at the start
      of the merge.  Then the svn_wc_diff_callbacks2_t callback merge_dir_added()
      doesn't find 'A_COPY/d' in the admin access (since that *is* case sensitive) and
      not finding it attempts to open a new access, but in doing so runs into the
      existing 'A_COPY/D'.
      

      Attachments

        1. 1_Issue.3115.test.diff
          6 kB
          Paul Burba

        Issue Links

          Activity

            People

              Unassigned Unassigned
              pburba Paul Burba
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: