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

update fails to replace a file external with an actual node

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • trunk
    • unscheduled
    • libsvn_wc

    Description

      When update brings in both a removal of an svn:externals definition followed by
      a normal addition of a versioned node at the external's target path, update
      fails to bring in the versioned node.
      
      This is because update first brings in versioned nodes, and after that handles
      svn:externals property changes. When the versioned node gets pulled into the WC,
      the external-to-be-deleted is still around.
      
      When the external was a dir external, a subsequent update brings in the new
      versioned node, as now the obstructing external has been removed. That's just a
      minor problem.
      
      However, when the external was a file external, no number of (recursive) updates
      brings the versioned node in as expected. The new versioned node's WC-path has
      to be passed as explicit target for the update to notice that it should be
      brought in. A user can't be expected to know which paths to pass to 'update' to
      get a consistent WC, so this is a bit worse than with dir externals.
      
      Note: it makes no difference if the versioned node is a file or a dir (tested
      all), only the external's kind has an effect on this issue.
      
      
      Reproduce replacing file external with versioned file node:
      
      Most minimal:
      [[[
      set -x
      svnadmin create /tmp/repos
      svn co file:///tmp/repos /tmp/wc
      cd /tmp/wc
      
      echo a > a
      svn add a
      echo obstr > xa
      svn add xa
      svn ci -m1
      svn up
      
      svn rm xa
      svn ci -m2
      svn up
      
      svn ps svn:externals "^/a xa" .
      svn ci -m3
      svn up
      
      # time-warp the WC back to where the versioned node existed:
      svn up -r1  # collision, no versioned node
      svn up -r1  # still no versioned node
      svn up --set-depth=infinity -r1  # still none
      svn st -v
      svn up -r1 xa  # only this helps
      svn st -v
      ]]]
      
      
      Output:
      [[[
      + svn up
      Updating '.':
      
      Fetching external item into 'xa':
      A    xa
      Updated external to revision 3.
      
      At revision 3.
      + svn up -r1
      Updating '.':
      Skipped 'xa' -- An obstructing working copy was found
       U   .
      Removed external 'xa'
      Updated to revision 1.
      Summary of conflicts:
        Skipped paths: 1
      + svn up -r1
      Updating '.':
      At revision 1.
      + svn up --set-depth=infinity -r1
      Updating '.':
      At revision 1.
      + svn st -v
                       1        1 neels        .
                       1        1 neels        a
      + svn up -r1 xa
      Updating 'xa':
      A    xa
      Updated to revision 1.
      + svn st -v
                       1        1 neels        .
                       1        1 neels        a
                       1        1 neels        xa
      ]]]
      
      
      
      And if you don't believe me that it can happen with an update-to-HEAD:
      [[[
      svnadmin create /tmp/repos
      svn co file:///tmp/repos /tmp/wc
      cd /tmp/wc
      
      echo a > a
      svn add a
      svn ci -m1
      svn up
      svn ps svn:externals "^/a xa" .
      svn ci -m2
      svn up
      
      svn pd svn:externals
      
      svn ci -mm # can be left out without effect
      
      svn up
      echo new > xa
      svn add xa
      svn ci -mm
      svn up
      
      # time-warp the WC back to r2, where the external existed.
      svn up -r2
      # (Removes the versioned node and adds the externals definition
      # in one update flush. In this direction it works fine.)
      
      # now bring in the changes in one update.
      svn up  # collision
      svn up  # external is gone, should definitely work now
      # (if xa had been a dir external, the WC would become consistent
      # with above update.)
      
      # but in this test, xa was a file external, and the versioned
      # node is still missing. --set-depth doesn't help either:
      svn up --set-depth=infinity
      svn st -v
      # 'xa' is still not here.
      # Only this brings in 'xa':
      svn up xa  
      svn st -v
      ]]]
      
      
      Yields:
      [[[
      + svn up -r2
      Updating '.':
      D    xa
       U   .
      
      Fetching external item into 'xa':
      A    xa
      Updated external to revision 4.
      
      At revision 2.
      + svn up
      Updating '.':
      Skipped 'xa' -- An obstructing working copy was found
       U   .
      Removed external 'xa'
      Updated to revision 4.
      Summary of conflicts:
        Skipped paths: 1
      + svn up
      Updating '.':
      At revision 4.
      + svn up --set-depth=infinity
      Updating '.':
      At revision 4.
      + svn st -v
                       4        4 neels        .
                       4        1 neels        a
      + svn up xa
      Updating 'xa':
      A    xa
      Updated to revision 4.
      + svn st -v
                       4        4 neels        .
                       4        1 neels        a
                       4        4 neels        xa
      ]]]
      

      Original issue reported by neels

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              subversion-importer Subversion Importer
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated: