A sane way to rename a directory in subversion working copy

前端 未结 4 1366
Happy的楠姐
Happy的楠姐 2021-02-02 05:05

While somehow versed in VCS (regular svn, git and git-svn user) I can\'t seem to wrap my head around this peculiar SVN behavior.

Whenever I need to rename a directory in

4条回答
  •  星月不相逢
    2021-02-02 05:52

    OK, I bumped into this - and can finally reconstruct the problem with a simple terminal session: the problem happens if you svn mv (move/rename) a file; then commit that change; then (without doing an svn update first), svn mv the parent directory of the file whose move/rename was previously committed - and finally do an svn commit on the change of the directory name - or as accepted answer puts it: "you also need to update and commit a file contained in the folder, but not update the folder itself"; but all of this executed in a parent (or rather, ancestor) directory. Here's command line log demonstrating the problem:

    $ cd /tmp
    $ svnadmin create myrepo
    $ svn co file:///tmp/myrepo myrepo-wc
    Checked out revision 0.
    
    $ cd myrepo-wc/
    $ mkdir -p dir1/dir2/dir3
    $ svn add dir1/
    A         dir1
    A         dir1/dir2
    A         dir1/dir2/dir3
    
    $ svn ci -m 'add dir1/'
    Adding         dir1
    Adding         dir1/dir2
    Adding         dir1/dir2/dir3
    
    Committed revision 1.
    
    $ echo test1 >> dir1/dir2/dir3/test1.txt
    $ echo test2 >> dir1/dir2/dir3/test2.txt
    $ svn add dir1/
    svn: warning: 'dir1' is already under version control
    $ svn add dir1/*
    svn: warning: 'dir1/dir2' is already under version control
    $ svn add dir1/dir2/dir3/*
    A         dir1/dir2/dir3/test1.txt
    A         dir1/dir2/dir3/test2.txt
    $ svn status
    A       dir1/dir2/dir3/test2.txt
    A       dir1/dir2/dir3/test1.txt
    $ svn ci -m 'add dir1/dir2/dir3/*'
    Adding         dir1/dir2/dir3/test1.txt
    Adding         dir1/dir2/dir3/test2.txt
    Transmitting file data ..
    Committed revision 2.
    
    $ svn mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt
    A         dir1/dir2/dir3/test2X.txt
    D         dir1/dir2/dir3/test2.txt
    $ svn status
    D       dir1/dir2/dir3/test2.txt
    A  +    dir1/dir2/dir3/test2X.txt
    $ svn ci -m 'mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt'
    Deleting       dir1/dir2/dir3/test2.txt
    Adding         dir1/dir2/dir3/test2X.txt
    
    Committed revision 3.
    
    $ svn status
    $ svn mv dir1/dir2/dir3 dir1/dir2/dir3X
    A         dir1/dir2/dir3X
    D         dir1/dir2/dir3/test2X.txt
    D         dir1/dir2/dir3/test1.txt
    D         dir1/dir2/dir3
    $ svn status
    D       dir1/dir2/dir3
    D       dir1/dir2/dir3/test2X.txt
    D       dir1/dir2/dir3/test1.txt
    A  +    dir1/dir2/dir3X
    D  +    dir1/dir2/dir3X/test2.txt
    $ svn ci -m 'mv dir1/dir2/dir3 dir1/dir2/dir3X'
    Deleting       dir1/dir2/dir3
    svn: Commit failed (details follow):
    svn: Directory '/dir1/dir2/dir3' is out of date
    $ svn status
    D       dir1/dir2/dir3
    D       dir1/dir2/dir3/test2X.txt
    D       dir1/dir2/dir3/test1.txt
    A  +    dir1/dir2/dir3X
    D  +    dir1/dir2/dir3X/test2.txt
    $ svn up
       C dir1/dir2/dir3
    At revision 3.
    Summary of conflicts:
      Tree conflicts: 1
    

    And this is how it should have been - doing an svn up after the file move/rename was comitted; note how the version numbers reported by svn status -v change after the svn update command:

    $ cd /tmp
    $ rm -rf myrepo*
    
    $ svnadmin create myrepo
    $ svn co file:///tmp/myrepo myrepo-wc
    Checked out revision 0.
    
    $ cd myrepo-wc/
    $ mkdir -p dir1/dir2/dir3
    $ svn add dir1/
    A         dir1
    A         dir1/dir2
    A         dir1/dir2/dir3
    $ svn ci -m 'add dir1/'
    Adding         dir1
    Adding         dir1/dir2
    Adding         dir1/dir2/dir3
    
    Committed revision 1.
    
    $ echo test1 >> dir1/dir2/dir3/test1.txt
    $ echo test2 >> dir1/dir2/dir3/test2.txt
    $ svn add dir1/dir2/dir3/*
    A         dir1/dir2/dir3/test1.txt
    A         dir1/dir2/dir3/test2.txt
    $ svn status
    A       dir1/dir2/dir3/test2.txt
    A       dir1/dir2/dir3/test1.txt
    $ svn ci -m 'add dir1/dir2/dir3/*'
    Adding         dir1/dir2/dir3/test1.txt
    Adding         dir1/dir2/dir3/test2.txt
    Transmitting file data ..
    Committed revision 2.
    
    $ svn mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt
    A         dir1/dir2/dir3/test2X.txt
    D         dir1/dir2/dir3/test2.txt
    $ svn status
    D       dir1/dir2/dir3/test2.txt
    A  +    dir1/dir2/dir3/test2X.txt
    $ svn ci -m 'mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt'
    Deleting       dir1/dir2/dir3/test2.txt
    Adding         dir1/dir2/dir3/test2X.txt
    
    Committed revision 3.
    
    $ svn status
    $ svn status -v
                     0        0  ?           .
                     1        1 username dir1
                     1        1 username dir1/dir2
                     1        1 username dir1/dir2/dir3
                     3        3 username dir1/dir2/dir3/test2X.txt
                     2        2 username dir1/dir2/dir3/test1.txt
    $ svn up
    At revision 3.
    $ svn status -v
                     3        3 username .
                     3        3 username dir1
                     3        3 username dir1/dir2
                     3        3 username dir1/dir2/dir3
                     3        3 username dir1/dir2/dir3/test2X.txt
                     3        2 username dir1/dir2/dir3/test1.txt
    $ svn mv dir1/dir2/dir3 dir1/dir2/dir3X
    A         dir1/dir2/dir3X
    D         dir1/dir2/dir3/test2X.txt
    D         dir1/dir2/dir3/test1.txt
    D         dir1/dir2/dir3
    $ svn status
    D       dir1/dir2/dir3
    D       dir1/dir2/dir3/test2X.txt
    D       dir1/dir2/dir3/test1.txt
    A  +    dir1/dir2/dir3X
    $ svn ci -m 'mv dir1/dir2/dir3 dir1/dir2/dir3X'
    Deleting       dir1/dir2/dir3
    Adding         dir1/dir2/dir3X
    
    Committed revision 4.
    
    $ svn status
    $ svn status -v
                     3        3 username .
                     3        3 username dir1
                     3        3 username dir1/dir2
                     4        4 username dir1/dir2/dir3X
                     4        4 username dir1/dir2/dir3X/test2X.txt
                     4        4 username dir1/dir2/dir3X/test1.txt
    $ svn up
    At revision 4.
    $ svn status -v
                     4        4 username .
                     4        4 username dir1
                     4        4 username dir1/dir2
                     4        4 username dir1/dir2/dir3X
                     4        4 username dir1/dir2/dir3X/test2X.txt
                     4        4 username dir1/dir2/dir3X/test1.txt
    

    And as OP said - should one forget to do the svn update before a new move/rename+commit, and the "Commit failed" occured - then one can use svn resolve --accept working -R . to be able to finish the commit action.

提交回复
热议问题