[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

tree-conflicts: please review to determine desired behaviour in detail

From: Neels Hofmeyr <neels_at_elego.de>
Date: Sun, 31 Aug 2008 05:06:57 +0200

Hi tree-conflicts,

I am going through the tree-conflicts tests that use deep_trees (in
subversion/tests/cmdline/update_tests.py, switch_tests.py and merge_tests.py).

Currently, these pass the exact behaviour that the svn tree-conflicts branch
shows now (r32837). I want to change the tests so that they will pass the
actually desired behaviour, showing what still needs to be fixed.

But, when going into detail, it is not quite easy to determine the desired
behaviour.

I'm pasting the expected trees from the tests as they are now, which show
the behaviour of svn as it is now (r32837), and add my comments (see
attached file). Please review to death.

Thanks!
~Neels

-- 
Neels Hofmeyr -- elego Software Solutions GmbH
Gustav-Meyer-Allee 25 / Gebäude 12, 13355 Berlin, Germany
phone: +49 30 23458696  mobile: +49 177 2345869  fax: +49 30 23458695
http://www.elegosoft.com | Geschäftsführer: Olaf Wagner | Sitz: Berlin
Handelsreg: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194

Hi tree-conflicts,

I am going through the tree-conflicts tests that use deep_trees (in
update_tests.py, switch_tests.py and merge_tests.py).

Currently, these pass the exact behaviour that the svn tree-conflicts branch
shows in r32837. I want to change the tests so that they will pass the
actually desired behaviour, showing what still needs to be fixed.

But, when going into detail, it is not quite easy to determine the desired
behaviour.

I'm pasting the expected trees from the tests as they are now, which show the
behaviour of svn as it is now (r32837), and add my comments. Please review to
death.

Thanks!
~Neels

-------------------------------------------------------------

Legend:

  initial tree
    F/alpha file
    D/D1 empty dir
    DF/D1/beta file
    DD/D1/D2 empty dir
    DDF/D1/D2/gamma file
    DDD/D1/D2/D3 empty dir

  leaf edit
    Add text to alpha, beta, gamma
    Add files:
     D/D1/delta
     DD/D1/D2/epsilon
     DDD/D1/D2/D3/zeta
  
  tree delete
    `svn remove' all D1 directories and the file alpha.

  leaf delete
    `svn remove' alpha, beta, gamma and D/D1, DD/D1/D2, DDD/D1/D2/D3

-------------------------------------------------------------

Summary:
This is a list of all deep_trees tests and whether their outcomes match the
actually desired behaviour. Based on the tree-conflicts branch, r32837.

- Columns
Output What svn prints to screen during the operation.
Disk What svn leaves behind in the filesystem after the operation.
Status What status svn reports after the operation.
Skip Which files were stated to be 'skipped' by a merge.

- Values
ok This is exactly what svn should do. (Please review, though)
ok? This is probably what svn should do.
Bad? This might not be what svn should do.
BAD This behaviour is wrong or doesn't match another observed behaviour.

NOTE: All of this is still just my opinion and hasn't had any review at all.

Test's Name Output Disk Status (Skip)
________________________________________ ______ ______ ______ ______
tree_conflicts_on_update_1_1 ok ok BAD
tree_conflicts_on_update_1_2 ok ok BAD
tree_conflicts_on_update_2_1 BAD BAD BAD
tree_conflicts_on_update_2_2 BAD BAD BAD
tree_conflicts_on_update_3 ok ok? ok?
tree_conflicts_on_switch_1_1 BAD ok BAD
tree_conflicts_on_switch_1_2 ok ok BAD
tree_conflicts_on_switch_2_1 BAD BAD BAD
tree_conflicts_on_switch_2_2 BAD BAD BAD
tree_conflicts_on_switch_3 ok ok? ok?
tree_conflicts_on_merge_local_ci_4_1 ok ok ok ok
tree_conflicts_on_merge_local_ci_4_2 ok ok ok ok
tree_conflicts_on_merge_local_ci_5_1 BAD Bad? BAD Bad?
tree_conflicts_on_merge_local_ci_5_2 BAD ok BAD Bad?
tree_conflicts_on_merge_local_ci_6 ok ok? ok Bad?
tree_conflicts_on_merge_no_local_ci_4_1 BAD BAD BAD Bad?
tree_conflicts_on_merge_no_local_ci_4_2 ok ok BAD Bad?
tree_conflicts_on_merge_no_local_ci_5_1 BAD ok BAD Bad?
tree_conflicts_on_merge_no_local_ci_5_2 BAD ok BAD Bad?
tree_conflicts_on_merge_no_local_ci_6 ok ok BAD Bad?

(These tests can be found in subversion/tests/cmdline/ in update_tests.py,
switch_tests.py and merge_tests.py.)

-------------------------------------------------------------
-------------------------------------------------------------
-- DETAILS --------------------------------------------------
-------------------------------------------------------------
-------------------------------------------------------------

-------------------------------------------------------------
--- UPDATE --------------------------------------------------
-------------------------------------------------------------

tree_conflicts_on_update_1_1
Local tree delete, incoming leaf edit.

[[[
  expected_output = wc.State('', {
    'F' : Item(status='C '),
    'F/alpha' : Item(status='U '),
    'D' : Item(status='C '),
    'D/D1/delta' : Item(status='A '),
    'DF' : Item(status='C '),
    'DF/D1' : Item(status='C '),
    'DF/D1/beta' : Item(status='U '),
    'DD' : Item(status='C '),
    'DD/D1' : Item(status='C '),
    'DD/D1/D2/epsilon' : Item(status='A '),
    'DDF' : Item(status='C '),
    'DDF/D1' : Item(status='C '),
    'DDF/D1/D2' : Item(status='C '),
    'DDF/D1/D2/gamma' : Item(status='U '),
    'DDD' : Item(status='C '),
    'DDD/D1' : Item(status='C '),
    'DDD/D1/D2' : Item(status='C '),
    'DDD/D1/D2/D3/zeta' : Item(status='A '),
    })
]]]
Good: Local tree delete is "undone". Incoming leaf edit is carried out (marked
U and A), all directories are in conflict.

[[[
  expected_disk = state_after_leaf_edit
]]]
Good: The incoming leaf edit is on the disk.

[[[
  expected_status = wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'F/alpha' : Item(status='D ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'D/D1' : Item(status='D ', wc_rev='3'),
    'D/D1/delta' : Item(status=' ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DF/D1/beta' : Item(status='D ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2/epsilon' : Item(status=' ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3/zeta' : Item(status=' ', wc_rev='3'),
    })
]]]
** BAD! **
All directories should be marked C.

Directories are marked for deletion, even if they contain files that are not
marked for deletion (delta, epsilon, zeta).

All files that were edited in the update (alpha, beta, gamma) are still marked
for deletion. Should they be unmarked?

-------------------------------------------------------------

tree_conflicts_on_update_1_2
Local tree delete, incoming leaf delete

[[[
  expected_output = wc.State('', {
    'F' : Item(status='C '),
    'F/alpha' : Item(status='D '),
    'D' : Item(status='C '),
    'D/D1' : Item(status='D '),
    'DF' : Item(status='C '),
    'DF/D1' : Item(status='C '),
    'DF/D1/beta' : Item(status='D '),
    'DD' : Item(status='C '),
    'DD/D1' : Item(status='C '),
    'DD/D1/D2' : Item(status='D '),
    'DDF' : Item(status='C '),
    'DDF/D1' : Item(status='C '),
    'DDF/D1/D2' : Item(status='C '),
    'DDF/D1/D2/gamma' : Item(status='D '),
    'DDD' : Item(status='C '),
    'DDD/D1' : Item(status='C '),
    'DDD/D1/D2' : Item(status='C '),
    'DDD/D1/D2/D3' : Item(status='D '),
    })
]]]
Good: Tries to carry out incoming leaf del markings on top of the local
markings from tree del, results in conflicts.

[[[
  expected_disk = state_after_leaf_del
]]]
Good: Files have been removed, but directories remain to be removed by a
commit. Local working copy unchanged.

[[[
  expected_status = wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    })
]]]
** BAD! **
According to the output tree above, all these directories should be marked C.
D/D1, DD/D1/D2, DDD/D1/D2/D3 have become unversioned -- is this ok?

-------------------------------------------------------------

tree_conflicts_on_update_2_1
Local leaf edit, incoming tree delete.

[[[
  expected_output = wc.State('', {
    'F' : Item(status='C '),
    'F/alpha' : Item(status='D '),
    'D/D1' : Item(status='D '),
    'DF/D1' : Item(status='D '),
    'DD/D1' : Item(status='D '),
    'DDF/D1' : Item(status='D '),
    'DDD/D1' : Item(status='D '),
    })

  expected_disk = state_after_leaf_edit

  expected_status = wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'D' : Item(status=' ', wc_rev='3'),
    'DF' : Item(status=' ', wc_rev='3'),
    'DD' : Item(status=' ', wc_rev='3'),
    'DDF' : Item(status=' ', wc_rev='3'),
    'DDD' : Item(status=' ', wc_rev='3'),
    })
]]]
** BAD! **
The update carries out the incoming tree delete, ignoring the local leaf edit.
The disk does, notably, still show the local modifications, but they are now
unversioned.

Interestingly enough, F is marked conflicted, which is sane, but has
unversioned its locally modified file alpha, which is insane.

All conflict markings other than for F are missing!

-------------------------------------------------------------

tree_conflicts_on_update_2_2
Local leaf delete, incoming tree delete.

[[[
  expected_output = wc.State('', {
    'D' : Item(status='C '),
    'D/D1' : Item(status='D '),
    'F' : Item(status='C '),
    'F/alpha' : Item(status='D '),
    'DD' : Item(),
    'DD/D1' : Item(status='D '),
    'DF' : Item(),
    'DF/D1' : Item(status='D '),
    'DDD' : Item(),
    'DDD/D1' : Item(status='D '),
    'DDF' : Item(),
    'DDF/D1' : Item(status='D '),
    })
]]]
*** BAD! ***
Conflict markers missing except for F and D!

[[[
  expected_disk = state_after_tree_del
]]]
** BAD! **
Any markings in deeper subdirs of the local working copy have been deleted
from disk by the incoming tree delete. Have there been conflict markings that
could have been examined by the user?

[[[
  expected_status = wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'DD' : Item(status=' ', wc_rev='3'),
    'DF' : Item(status=' ', wc_rev='3'),
    'DDD' : Item(status=' ', wc_rev='3'),
    'DDF' : Item(status=' ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    })
]]]
** BAD! **
Same as above, fails to mark four of the containers as conflicted.

-------------------------------------------------------------

tree_conflicts_on_update_3
Local tree delete, incoming tree delete.

[[[
  expected_output = wc.State('', {
    'F' : Item(status='C '),
    'F/alpha' : Item(status='D '),
    'D' : Item(status='C '),
    'D/D1' : Item(status='D '),
    'DF' : Item(status='C '),
    'DF/D1' : Item(status='D '),
    'DD' : Item(status='C '),
    'DD/D1' : Item(status='D '),
    'DDF' : Item(status='C '),
    'DDF/D1' : Item(status='D '),
    'DDD' : Item(status='C '),
    'DDD/D1' : Item(status='D '),
    })

  expected_disk = state_after_tree_del

  expected_status = wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    })
]]]

Doesn't look to bad. All containers picked up the conflict as in use case 3.

But: Shouldn't the local working copy still have its skeleton of empty
directories present, with its local deletion markings?

-------------------------------------------------------------
-- SWITCH ---------------------------------------------------
-------------------------------------------------------------

tree_conflicts_on_switch_1_1
Local tree delete, incoming leaf edit.

[[[
  expected_output = svntest.wc.State('', {
    'D' : Item(status='C '),
    'D/D1' : Item(),
    'D/D1/delta' : Item(status='A '),
    'F' : Item(status='C '),
    'F/alpha' : Item(status='U '),
    'DD' : Item(status='C '),
    'DD/D1' : Item(status='C '),
    'DD/D1/D2' : Item(),
    'DD/D1/D2/epsilon' : Item(status='A '),
    'DF' : Item(status='C '),
    'DF/D1' : Item(status='C '),
    'DF/D1/beta' : Item(status='U '),
    'DDD' : Item(status='C '),
    'DDD/D1' : Item(status='C '),
    'DDD/D1/D2' : Item(status='C '),
    'DDD/D1/D2/D3' : Item(),
    'DDD/D1/D2/D3/zeta' : Item(status='A '),
    'DDF' : Item(status='C '),
    'DDF/D1' : Item(status='C '),
    'DDF/D1/D2' : Item(status='C '),
    'DDF/D1/D2/gamma' : Item(status='U '),
    })
]]]
** BAD! **
Even though most things look good, the parent dirs of added files are not
marked conflicted. This is different from tree_conflicts_on_update_1_1, which
does get this right.

[[[
  expected_disk = state_after_leaf_edit

  expected_status = svntest.wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'D/D1' : Item(status='D ', wc_rev='3'),
    'D/D1/delta' : Item(status=' ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'F/alpha' : Item(status='D ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2/epsilon' : Item(status=' ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DF/D1/beta' : Item(status='D ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3/zeta' : Item(status=' ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3'),
    })
]]]
** BAD! **
Same as for tree_conflicts_on_update_1_1:

-------------------------------------------------------------

tree_conflicts_on_switch_1_2
Local tree delete, incoming leaf delete.

[[[
  expected_output = svntest.wc.State('', {
    'D' : Item(status='C '),
    'D/D1' : Item(status='D '),
    'F' : Item(status='C '),
    'F/alpha' : Item(status='D '),
    'DD' : Item(status='C '),
    'DD/D1' : Item(status='C '),
    'DD/D1/D2' : Item(status='D '),
    'DF' : Item(status='C '),
    'DF/D1' : Item(status='C '),
    'DF/D1/beta' : Item(status='D '),
    'DDD' : Item(status='C '),
    'DDD/D1' : Item(status='C '),
    'DDD/D1/D2' : Item(status='C '),
    'DDD/D1/D2/D3' : Item(status='D '),
    'DDF' : Item(status='C '),
    'DDF/D1' : Item(status='C '),
    'DDF/D1/D2' : Item(status='C '),
    'DDF/D1/D2/gamma' : Item(status='D '),
    })

  expected_disk = state_after_leaf_del

  expected_status = svntest.wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    })
]]]
** BAD! **
This is exactly the same as tree_conflicts_on_update_1_2.

-------------------------------------------------------------

tree_conflicts_on_switch_2_1
Local leaf edit, incoming tree delete

(This test is special, since its subtests mostly cause svn to exit with error.
Only one of these errors can be seen for each svn run, so this test needs to
be split up, each container dir getting a distinct test setup)

-- F --
[[[
  expected_output = svntest.wc.State('', {
    'F' : Item(status='C '),
    'F/alpha' : Item(status='D '),
    })

  expected_disk = svntest.actions.deep_trees_virginal_state.copy()
  expected_disk.tweak('F/alpha', contents="This is the file 'alpha'.\nMore text for file alpha.\n")

  expected_status = svntest.wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'DDF' : Item(status=' ', wc_rev='3'),
    'DDF/D1' : Item(status=' ', wc_rev='3'),
    'DDF/D1/D2' : Item(status=' ', wc_rev='3'),
    'DDF/D1/D2/gamma' : Item(status=' ', wc_rev='3'),
    'D' : Item(status=' ', wc_rev='3'),
    'D/D1' : Item(status=' ', wc_rev='3'),
    'DD' : Item(status=' ', wc_rev='3'),
    'DD/D1' : Item(status=' ', wc_rev='3'),
    'DD/D1/D2' : Item(status=' ', wc_rev='3'),
    'DF' : Item(status=' ', wc_rev='3'),
    'DF/D1' : Item(status=' ', wc_rev='3'),
    'DF/D1/beta' : Item(status=' ', wc_rev='3'),
    'DDD' : Item(status=' ', wc_rev='3'),
    'DDD/D1' : Item(status=' ', wc_rev='3'),
    'DDD/D1/D2' : Item(status=' ', wc_rev='3'),
    'DDD/D1/D2/D3' : Item(status=' ', wc_rev='3'),
    })
]]]

** BAD! **
This is the same as tree_conflicts_on_update_2_1: local modifications become
unversioned.

-- D, DF, DD, DDF, DDD --
[[[
  error_re_string = "Won't delete locally modified directory"
]]]

Is this good? No other of the current tree-conflicts tests returns a similar
error.

-------------------------------------------------------------

tree_conflicts_on_switch_2_2
Local leaf delete, incoming tree delete

[[[
  expected_output = svntest.wc.State('', {
    'D' : Item(status='C '),
    'D/D1' : Item(status='D '),
    'F' : Item(status='C '),
    'F/alpha' : Item(status='D '),
    'DD' : Item(),
    'DD/D1' : Item(status='D '),
    'DF' : Item(),
    'DF/D1' : Item(status='D '),
    'DDD' : Item(),
    'DDD/D1' : Item(status='D '),
    'DDF' : Item(),
    'DDF/D1' : Item(status='D '),
    })

  expected_disk = state_after_tree_del

  expected_status = svntest.wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'DD' : Item(status=' ', wc_rev='3'),
    'DF' : Item(status=' ', wc_rev='3'),
    'DDD' : Item(status=' ', wc_rev='3'),
    'DDF' : Item(status=' ', wc_rev='3'),
    })
]]]

** BAD! **
This is exactly the same as tree_conflicts_on_update_2_2.

-------------------------------------------------------------

tree_conflicts_on_switch_3
Local tree delete, incoming tree delete

[[[
  expected_output = svntest.wc.State('', {
    'D' : Item(status='C '),
    'D/D1' : Item(status='D '),
    'F' : Item(status='C '),
    'F/alpha' : Item(status='D '),
    'DD' : Item(status='C '),
    'DD/D1' : Item(status='D '),
    'DF' : Item(status='C '),
    'DF/D1' : Item(status='D '),
    'DDD' : Item(status='C '),
    'DDD/D1' : Item(status='D '),
    'DDF' : Item(status='C '),
    'DDF/D1' : Item(status='D '),
  })

  expected_disk = state_after_tree_del

  expected_status = svntest.wc.State('', {
    '' : Item(status=' ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    })
]]]

Same as tree_conflicts_on_update_3.

-------------------------------------------------------------
-- MERGE ----------------------------------------------------
-------------------------------------------------------------

tree_conflicts_on_merge_local_ci_4_1
Local tree delete, incoming leaf edit.

[[[
  expected_output = svntest.wc.State('', {
    'F' : Item(status='C '),
    'D' : Item(status='C '),
    'DF' : Item(status='C '),
    'DD' : Item(status='C '),
    'DDF' : Item(status='C '),
    'DDD' : Item(status='C '),
    })

  expected_disk = state_after_tree_del

  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    })
]]]
Good: The incoming leaf edit has not been carried out, but all container dirs
have been marked conflicted. (This can be seen as the flipside of update,
where the incoming is "stronger". Here, with merge, the local is "stronger".)

[[[
  expected_skip = svntest.wc.State('', {
    'F/alpha' : Item(),
    'DF/D1/beta' : Item(),
    'DDF/D1/D2/gamma' : Item(),
    'D/D1/delta' : Item(),
    'DD/D1/D2/epsilon' : Item(),
    'DDD/D1/D2/D3/zeta' : Item(),
    })
]]]
Good: All the modifications that could not be merged because of tree conflicts
are printed out as "Skipped".

-------------------------------------------------------------

tree_conflicts_on_merge_local_ci_4_2
Local tree delete, incoming leaf delete.

[[[
  expected_output = svntest.wc.State('', {
    'F' : Item(status='C '),
    'D' : Item(status='C '),
    'DF' : Item(status='C '),
    'DD' : Item(status='C '),
    'DDF' : Item(status='C '),
    'DDD' : Item(status='C '),
    })

  expected_disk = state_after_tree_del

  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    })

  expected_skip = svntest.wc.State('', {
    'F/alpha' : Item(),
    'DF/D1/beta' : Item(),
    'DDF/D1/D2/gamma' : Item(),
    'D/D1' : Item(),
    'DD/D1/D2' : Item(),
    'DDD/D1/D2/D3' : Item(),
    })
]]]
Good: Same as tree_conflicts_on_merge_local_ci_4_1.

-------------------------------------------------------------

tree_conflicts_on_merge_local_ci_5_1
Local leaf edit, incoming tree delete.

[[[
  expected_output = svntest.wc.State('', {
    'D/D1' : Item(status='D '),
    'F' : Item(status='C '),
    'DD/D1' : Item(status='D '),
    'DF/D1' : Item(status='D '),
    'DDD/D1' : Item(status='D '),
    'DDF/D1' : Item(status='D '),
    })
]]]
** BAD! **
Same as tree_conflicts_on_update_2_1

[[[
  expected_disk = svntest.wc.State('', {
    'DF/D1' : Item(),
    'DDF/D1/D2' : Item(),
    'F/alpha' : Item(contents="This is the file 'alpha'.\nMore text for file alpha.\n"),
    'DDD/D1/D2/D3' : Item(),
    'DD/D1/D2' : Item(),
    'D/D1' : Item(),
    })
]]]
Bad?
One of the local leaf edits is still there (alpha, the case where no
directories are involved), all the other local edits are undone by the
incoming tree delete.
It's not that bad since local edits have already been committed on the local
branch. But why is there a difference between the cases alpha and beta?

[[[
  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'D' : Item(status=' ', wc_rev='3'),
    'D/D1' : Item(status='D ', wc_rev='3'),
    'D/D1/delta' : Item(status='D ', wc_rev='4'),
    'F' : Item(status='C ', wc_rev='3'),
    'F/alpha' : Item(status=' M', wc_rev='4'),
    'DD' : Item(status=' ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2/epsilon' : Item(status='D ', wc_rev='4'),
    'DF' : Item(status=' ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DF/D1/beta' : Item(status='D ', wc_rev='4'),
    'DDD' : Item(status=' ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3/zeta' : Item(status='D ', wc_rev='4'),
    'DDF' : Item(status=' ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='4'),
    })
]]]
** BAD! **
Except for F, all conflict markers are missing.
alpha is marked prop-modified, why?
The incoming merge of a tree delete should not actually modify alpha -- it
should either remove it or leave it unchanged.

[[[
  expected_skip = svntest.wc.State('', {
    'F/alpha' : Item(),
    })
]]]
Should it really be considered "skipped"?

-------------------------------------------------------------

tree_conflicts_on_merge_local_ci_5_2
Local leaf del, incoming tree delete.

[[[
  expected_output = svntest.wc.State('', {
    'D' : Item(status='C '),
    'F' : Item(status='C '),
    'DD' : Item(),
    'DD/D1' : Item(status='D '),
    'DF' : Item(),
    'DF/D1' : Item(status='D '),
    'DDD' : Item(),
    'DDD/D1' : Item(status='D '),
    'DDF' : Item(),
    'DDF/D1' : Item(status='D '),
    })
]]]
** BAD! **
Same as tree_conflicts_on_update_2_2

[[[
  expected_disk = svntest.wc.State('', {
    'F' : Item(),
    'D' : Item(),
    'DF/D1' : Item(),
    'DD/D1' : Item(),
    'DDF/D1/D2' : Item(),
    'DDD/D1/D2' : Item(),
    })
]]]
Good. Either way, the empty directory skeleton would remain on disk.

[[[
  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'DD' : Item(status=' ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DF' : Item(status=' ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DDD' : Item(status=' ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF' : Item(status=' ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    })
]]]
** BAD! **
Almost the same as tree_conflicts_on_update_2_2, in that only F and D are
marked C. The rest is marked to be deleted (in update_2_2 it is already gone).

[[[
  expected_skip = svntest.wc.State('', {
    'F/alpha' : Item(),
    'D/D1' : Item(),
    })
]]]
Should they really be considered "skipped"?

-------------------------------------------------------------

tree_conflicts_on_merge_local_ci_6
Local tree delete, incoming tree delete.

[[[
  expected_output = svntest.wc.State('', {
    'F' : Item(status='C '),
    'D' : Item(status='C '),
    'DF' : Item(status='C '),
    'DD' : Item(status='C '),
    'DDF' : Item(status='C '),
    'DDD' : Item(status='C '),
    })

  expected_disk = state_after_tree_del

  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    })
]]]
Same as tree_conflicts_on_update_3.

[[[
  expected_skip = svntest.wc.State('', {
    'D/D1' : Item(),
    'F/alpha' : Item(),
    'DD/D1' : Item(),
    'DF/D1' : Item(),
    'DDD/D1' : Item(),
    'DDF/D1' : Item(),
    })
]]]
Should they really be considered "skipped"?

-------------------------------------------------------------
-- MERGE without local commit -------------------------------
-------------------------------------------------------------

tree_conflicts_on_merge_no_local_ci_4_1
Local tree delete, incoming leaf edit.

[[[
  expected_output = svntest.wc.State('', {
    'F' : Item(status='C '),
    'D' : Item(status='C '),
    'D/D1' : Item(),
    'D/D1/delta' : Item(status='A '),
    'DF' : Item(status='C '),
    'DF/D1' : Item(status='C '),
    'DD' : Item(status='C '),
    'DD/D1' : Item(status='C '),
    'DD/D1/D2' : Item(),
    'DD/D1/D2/epsilon' : Item(status='A '),
    'DDF' : Item(status='C '),
    'DDF/D1' : Item(status='C '),
    'DDF/D1/D2' : Item(status='C '),
    'DDD' : Item(status='C '),
    'DDD/D1' : Item(status='C '),
    'DDD/D1/D2' : Item(status='C '),
    'DDD/D1/D2/D3' : Item(),
    'DDD/D1/D2/D3/zeta' : Item(status='A '),
    })

  expected_disk = svntest.wc.State('', {
    'F' : Item(),
    'D/D1/delta' : Item(contents="This is the file 'delta'.\n"),
    'DF/D1' : Item(),
    'DD/D1/D2/epsilon' : Item(contents="This is the file 'epsilon'.\n"),
    'DDF/D1/D2' : Item(),
    'DDD/D1/D2/D3/zeta' : Item(contents="This is the file 'zeta'.\n"),
    })
]]]

** BAD! **
Incomingly modified files alpha, beta, gamma are not mentioned in the output,
nor added to the local working copy. The local tree delete "overrules" these,
but incoming file additions *were* carried out. This is different than update.

Directory victims are not marked conflicted, only their parents -- AFAIK
that's ok.

[[[
  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'F/alpha' : Item(status='D ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2/epsilon' : Item(status='A ', copied='+', wc_rev='-'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DF/D1/beta' : Item(status='D ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3/zeta' : Item(status='A ', copied='+', wc_rev='-'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'D/D1' : Item(status='D ', wc_rev='3'),
    'D/D1/delta' : Item(status='A ', copied='+', wc_rev='-'),
    })

  expected_skip = alpha_beta_gamma
]]]

** BAD! **
Only the outer containers were marked conflicted, not the directories within,
as opposed to what the output said.

Same as above, half the incoming leaf edit overruled and the other half was
overruled by the local tree delete.

alpha, beta and gamma are skipped, but delta, epsilon and zeta are not.

-------------------------------------------------------------

tree_conflicts_on_merge_no_local_ci_4_2
Local tree delete, incoming leaf delete.

[[[
  expected_output = svntest.wc.State('', {
    'F' : Item(status='C '),
    'D' : Item(status='C '),
    'D/D1' : Item(status='D '),
    'DF' : Item(status='C '),
    'DF/D1' : Item(status='C '),
    'DD' : Item(status='C '),
    'DD/D1' : Item(status='C '),
    'DD/D1/D2' : Item(status='D '),
    'DDF' : Item(status='C '),
    'DDF/D1' : Item(status='C '),
    'DDF/D1/D2' : Item(status='C '),
    'DDD' : Item(status='C '),
    'DDD/D1' : Item(status='C '),
    'DDD/D1/D2' : Item(status='C '),
    'DDD/D1/D2/D3' : Item(status='D '),
    })
]]]
Good: see below.

[[[
  expected_disk = svntest.wc.State('', {
    'F' : Item(),
    'D/D1' : Item(),
    'DF/D1' : Item(),
    'DD/D1/D2' : Item(),
    'DDF/D1/D2' : Item(),
    'DDD/D1/D2/D3' : Item(),
    })
]]]
(This is the same as `expected_disk = state_after_leaf_del')
Same as tree_conflicts_on_update_1_2, ok.

[[[
  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'F/alpha' : Item(status='D ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'D/D1' : Item(status='D ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DF/D1/beta' : Item(status='D ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
    })

  expected_skip = alpha_beta_gamma
]]]

** BAD! **
Most conflict markers as shown in the output are not found in the status.

Good aspect: Although this differs from tree_conflicts_on_update_1_2, this
behaviour is ok for merge: There, the files are actually removed, here they
are left lying around marked for deletion.

-------------------------------------------------------------

tree_conflicts_on_merge_no_local_ci_5_1
Local leaf edit, incoming tree delete.

[[[
  expected_output = svntest.wc.State('', {
    'F' : Item(status='C '),
    })
]]]
** BAD! **
No conflicts detected except in F!

[[[
  expected_disk = state_after_leaf_edit
]]]
Good: Local edits are still on disk.

[[[
  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'D' : Item(status=' ', wc_rev='3'),
    'D/D1' : Item(status=' M', wc_rev='3'),
    'D/D1/delta' : Item(status='A ', wc_rev='0'),
    'F' : Item(status='C ', wc_rev='3'),
    'F/alpha' : Item(status='MM', wc_rev='3'),
    'DD' : Item(status=' ', wc_rev='3'),
    'DD/D1' : Item(status=' M', wc_rev='3'),
    'DD/D1/D2' : Item(status=' ', wc_rev='3'),
    'DD/D1/D2/epsilon' : Item(status='A ', wc_rev='0'),
    'DF' : Item(status=' ', wc_rev='3'),
    'DF/D1' : Item(status=' M', wc_rev='3'),
    'DF/D1/beta' : Item(status='M ', wc_rev='3'),
    'DDD' : Item(status=' ', wc_rev='3'),
    'DDD/D1' : Item(status=' M', wc_rev='3'),
    'DDD/D1/D2' : Item(status=' ', wc_rev='3'),
    'DDD/D1/D2/D3' : Item(status=' ', wc_rev='3'),
    'DDD/D1/D2/D3/zeta' : Item(status='A ', wc_rev='0'),
    'DDF' : Item(status=' ', wc_rev='3'),
    'DDF/D1' : Item(status=' M', wc_rev='3'),
    'DDF/D1/D2' : Item(status=' ', wc_rev='3'),
    'DDF/D1/D2/gamma' : Item(status='M ', wc_rev='3'),
    })
]]]
Good: Local file additions and modifications are still marked as such.

** BAD! **
No properties have been modified, neither local nor incoming. Why are
properties marked modified for wc_dir, F/alpha, and all D1s?

[[[
  expected_skip = svntest.wc.State('', {
    'D/D1' : Item(),
    'F/alpha' : Item(),
    'DD/D1' : Item(),
    'DF/D1' : Item(),
    'DDD/D1' : Item(),
    'DDF/D1' : Item(),
    })
]]]
Should they really be considered "skipped"?

-------------------------------------------------------------

tree_conflicts_on_merge_no_local_ci_5_2
Local leaf del, incoming tree delete.

[[[
  expected_output = svntest.wc.State('', {
    'D' : Item(status='C '),
    'D/D1' : Item(status='D '),
    'F' : Item(status='C '),
    'DD' : Item(),
    'DD/D1' : Item(status='D '),
    'DF' : Item(),
    'DF/D1' : Item(status='D '),
    'DDD' : Item(),
    'DDD/D1' : Item(status='D '),
    'DDF' : Item(),
    'DDF/D1' : Item(status='D '),
    })
]]]
** BAD! **
Same as tree_conflicts_on_update_2_2, but file alpha is not mentioned here.

[[[
  expected_disk = svntest.wc.State('', {
    'F' : Item(),
    'D/D1' : Item(),
    'DF/D1' : Item(),
    'DD/D1/D2' : Item(),
    'DDF/D1/D2' : Item(),
    'DDD/D1/D2/D3' : Item(),
    })
]]]
(This is the same as `expected_disk = state_after_leaf_del')
Good: Local working copy so far unchanged.

[[[
  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'F/alpha' : Item(status='D ', wc_rev='3'),
    'DD' : Item(status=' ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DF' : Item(status=' ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DF/D1/beta' : Item(status='D ', wc_rev='3'),
    'DDD' : Item(status=' ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
    'DDF' : Item(status=' ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'D/D1' : Item(status='D ', wc_rev='3'),
    })
]]]
** BAD! **
Fails to mark conflicts except for F and D.

[[[
  expected_skip = svntest.wc.State('', {
    'F/alpha' : Item(),
    })
]]]
If alpha was skipped, why not beta and gamma?

-------------------------------------------------------------

tree_conflicts_on_merge_no_local_ci_6
Local tree delete, incoming tree delete.

[[[
  expected_output = svntest.wc.State('', {
    'D' : Item(status='C '),
    'D/D1' : Item(status='D '),
    'F' : Item(status='C '),
    'DD' : Item(status='C '),
    'DD/D1' : Item(status='D '),
    'DF' : Item(status='C '),
    'DF/D1' : Item(status='D '),
    'DDD' : Item(status='C '),
    'DDD/D1' : Item(status='D '),
    'DDF' : Item(status='C '),
    'DDF/D1' : Item(status='D '),
    })
]]]
Good.

[[[
  expected_disk = svntest.wc.State('', {
    'F' : Item(),
    'D/D1' : Item(),
    'DF/D1' : Item(),
    'DD/D1/D2' : Item(),
    'DDF/D1/D2' : Item(),
    'DDD/D1/D2/D3' : Item(),
    })
]]]
(This is the same as `expected_disk = state_after_leaf_del')
Good: The local tree delete was not committed yet. Files have been deleted but
directories are still around.

[[[
  expected_status = svntest.wc.State('', {
    '' : Item(status=' M', wc_rev='3'),
    'DDF' : Item(status='C ', wc_rev='3'),
    'DDF/D1' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3'),
    'D' : Item(status='C ', wc_rev='3'),
    'D/D1' : Item(status='D ', wc_rev='3'),
    'F' : Item(status='C ', wc_rev='3'),
    'F/alpha' : Item(status='D ', wc_rev='3'),
    'DD' : Item(status='C ', wc_rev='3'),
    'DD/D1' : Item(status='D ', wc_rev='3'),
    'DD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DF' : Item(status='C ', wc_rev='3'),
    'DF/D1' : Item(status='D ', wc_rev='3'),
    'DF/D1/beta' : Item(status='D ', wc_rev='3'),
    'DDD' : Item(status='C ', wc_rev='3'),
    'DDD/D1' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
    'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
    })

  expected_skip = svntest.wc.State('', {
    'F/alpha' : Item(),
    })
]]]
** BAD! **
Should subdirs also be marked C?
If alpha was skipped, why not beta and gamma?

Received on 2008-08-31 05:12:09 CEST

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.