Make 'svn update' not record a tree conflict when deleting an unmodified directory which happens to contain unversioned items. Instead, just leave the unversioned items behind on disk when deleting the unmodified directory, which matches the behaviour of Subversion 1.8.
* subversion/libsvn_wc/update_editor.c (check_tree_conflict): Ignore unversioned items during check for local mods. This prevents a tree conflict from being recorded.
* subversion/tests/cmdline/switch_tests.py (tolerate_local_mods): Don't expect an unversioned item to cause a tree conflict. Add the item to version control instead to meet this test's expectations.
* subversion/tests/cmdline/update_tests.py (update_keeps_unversioned_items_in_deleted_dir, test_list): New test which ensures that update will leave unversioned items on disk when deleting an unmodified directory.
Record the move target path in a moved-away tree conflict skel.
Updates can modify the NODES table in ways which discard local move information about tree conflict victims. One example is:
echo foo >> epsilon/foo.txt svn mv epsilon alpha svn ci # create r2 svn up -r1 svn mv epsilon beta svn up -r2
When 'epsilon' is updated to r2, a tree conflict is raised and the move 'epsilon' -> 'beta' is deleted from the NODES table. 'beta' remains a copy.
$ svn status A + beta ! C epsilon > local dir moved away, incoming dir delete or move upon update $
The conflict skel for the tree conflict on 'epsilon' now contains: (tree () moved-away deleted epsilon)
This leaves the resolver with insufficient information about the local move 'epsilon' -> 'beta' which existed before the update. To resolve this conflict we must be able to identify the copy 'beta' as one potential move target. The fact that copyfrom on 'beta' points to 'epsilon' is insufficient because, in the general case, this copy could have occurred independently of the tree conflict.
As of this commit, the tree conflict skel also records a move destination path, 'beta' in our example: (tree () moved-away deleted epsilon beta)
Apart from recording the path in the skel, this commit introduces no other visible change in behaviour. In the future, the conflict resolver will be able to make use of this new information to correlate the copy 'beta' with the conflict victim 'epsilon' in the above example.
Note that old clients will simply ignore the new extra element at the end of the conflict skel.
* subversion/libsvn_wc/conflicts.c (svn_wc__conflict_skel_add_tree_conflict): Add move_dst_op_root_abspath parameter and append it to the skel if it is non-NULL. (svn_wc__conflict_read_tree_conflict): Return the move_dst_op_root_abspath if present in the conflict skel. (read_tree_conflict_desc, resolve_tree_conflict_on_node, svn_wc__conflict_tree_update_break_moved_away, svn_wc__conflict_tree_update_incoming_move, svn_wc__conflict_tree_update_local_add): Update callers.
* subversion/libsvn_wc/conflicts.h (svn_wc__conflict_skel_add_tree_conflict, svn_wc__conflict_read_tree_conflict): Update declaration and docstring.