You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@subversion.apache.org by "Stefan Sperling (Jira)" <ji...@apache.org> on 2022/11/21 15:10:00 UTC

[jira] [Commented] (SVN-4910) Tree conflict resolution removes unversioned files from the working copy

    [ https://issues.apache.org/jira/browse/SVN-4910?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17636726#comment-17636726 ] 

Stefan Sperling commented on SVN-4910:
--------------------------------------

It seems there is a broken API promise in svn_wc_delete4(). Well, at least the docs are very unclear here:

{code:c}
 * If @a keep_local is FALSE, this function immediately deletes all files,
 * modified and unmodified, versioned and if @a delete_unversioned is TRUE,
 * unversioned from the working copy.
{code}

The advertised delete_unversioned parameter does not exist; a parameter which does exist is called "deleted_unversioned_target", and the conflict resolver sets this parameter to FALSE when calling svn_wc_delete4(), hoping that unversioned files will not be deleted.
However, svn_wc_delete4() ends up removing the entire directory hierarchy, rm -rf style, via svn_io_remove_dir2(), with no regard to the contents. In the actual implementation, the API parameter only applies to the root directory of the to-be-deleted subtree.

Looking at the log message and commit of https://svn.apache.org/r879865, it seems this docstring has always been wrong.

Possible approaches to a fix are:

1) Fix svn_wc_delete4() to leave unversioned files/directories behind on disk as promised. This is probably the cleanest fix, but it would require several internal API changes, as there are about 4 layers of code between the actual call which removes the directory and the conflict resolver code. The work queue operation which deletes directories would have to skip deleting unversioned nodes from disk, and this behaviour would need to be controlled by a new API flag parameter.

2) Have the conflict resolver back up unversioned files/directories before removing the directory from disk, and then copy them back. This is a fragile hack (if something goes wrong in the middle, files will still be lost), but it is easy to implement.

3) Have the conflict resolver attempt to move unversioned files/directory into the rename target directory. This is very difficult, as it is unclear what should happen if new tree-conflicts occur while moving unversioned files/directories into the rename target directory (names could now clash, there could be versioned directories with a name that an unversioned file wants to use, etc.). Leaving the unversioned items behind at their original location is probably better.

> Tree conflict resolution removes unversioned files from the working copy
> ------------------------------------------------------------------------
>
>                 Key: SVN-4910
>                 URL: https://issues.apache.org/jira/browse/SVN-4910
>             Project: Subversion
>          Issue Type: Bug
>    Affects Versions: 1.14.2
>         Environment: Windows:
> svn, version 1.14.2 (r1899510)
>    compiled Aug 12 2022, 12:55:13 on x86_64-microsoft-windows6.2.9200
>  
> macOS:
> svn, version 1.14.2 (r1899510)
>    compiled Apr 13 2022, 14:56:48 on arm-apple-darwin21.3.0
>  
> Linux:
> Ubuntu 22.04 running on WSL.
>            Reporter: Pavel Lyalyakin
>            Priority: Major
>
> It appears that running `svn update` can silently remove unversioned files in the working copy when automatically resolving a tree conflict. The file "unversionedfile.txt" will be removed after following the reproduction script given below.
> Note that when I run `svn update` with the `--accept postpone` option, the unversioned file remains in the working copy.
> Reported in the users@ mailing list:
> [https://lists.apache.org/thread/qmg6xqs5xpjr6kyhblwxvnhykobxwm8x]
> [https://lists.apache.org/thread/phpotj6pvvcmlt1vx9y7lbn6vof0d6y2]
>  
> Info from the user's report in the mailing list:
> {quote}* User 1 renames a svn folder and commits this
> * User 2 has unversioned files and uncommited files in the renamed folder
> * User 2 performs an update
> * Subversion encounter a tree conflict
> * All files are still on the disk during this step * Subversion solves three conflict. * unversioned files are removed from users 2 disk. The unversioned files are retained in the old folder with the old name when the same sequence is executed with no uncommited files on users 2 computer.
> This all has been performed using : Svn, version 1.14.2 (r1899510) compiled Sep 24 2022, 10:21:16 on x86-microsoft-windows using Microsoft Windows [Version 10.0.19045.2130]. {quote}
> And confirmed in the dev@ mailing list:
> [https://lists.apache.org/thread/5gm8wcm0fs714lft0sd5pmczr9okjl02]
> Reproduction script for Windows, macOS and Linux:
>  
> Windows:
> {code:java}
> mkdir C:\marcel-bug-report
> svnadmin create C:\marcel-bug-report\MyRepo
> svn mkdir file:///C:/marcel-bug-report/MyRepo/MyDir -m "Adding a new directory"
> svn checkout file:///C:/marcel-bug-report/MyRepo/ C:\marcel-bug-report\working-copy-one
> echo foo > C:\marcel-bug-report\working-copy-one\MyDir\myfile.txt
> svn add C:\marcel-bug-report\working-copy-one\MyDir\myfile.txt
> svn commit C:\marcel-bug-report\working-copy-one\ -m "Adding a new file"
> echo bar > C:\marcel-bug-report\working-copy-one\MyDir\myfile.txt
> echo baz > C:\marcel-bug-report\working-copy-one\MyDir\unversionedfile.txt
> svn move file:///C:/marcel-bug-report/MyRepo/MyDir file:///C:/marcel-bug-report/MyRepo/RenamedDir -m "Renaming a directory"
> svn update C:\marcel-bug-report\working-copy-one{code}
>  
> macOS and Linux:
> {code:java}
> mkdir $HOME/marcel-bug-report
> svnadmin create $HOME/marcel-bug-report/MyRepo
> svn mkdir file:///$HOME/marcel-bug-report/MyRepo/MyDir -m "Adding a new directory"
> svn checkout file:///$HOME/marcel-bug-report/MyRepo/ $HOME/marcel-bug-report/working-copy-one
> echo foo > $HOME/marcel-bug-report/working-copy-one/MyDir/myfile.txt
> svn add $HOME/marcel-bug-report/working-copy-one/MyDir/myfile.txt
> svn commit $HOME/marcel-bug-report/working-copy-one/ -m "Adding a new file"
> echo bar > $HOME/marcel-bug-report/working-copy-one/MyDir/myfile.txt
> echo baz > $HOME/marcel-bug-report/working-copy-one/MyDir/unversionedfile.txt
> svn move file:///$HOME/marcel-bug-report/MyRepo/MyDir file:///$HOME/marcel-bug-report/MyRepo/RenamedDir -m "Renaming a directory"
> svn update $HOME/marcel-bug-report/working-copy-one/{code}
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)