3 TREE CONFLICTS USE CASES AND DESIRED BEHAVIOURS
6 Issue reference: http://subversion.tigris.org/issues/show_bug.cgi?id=2282
8 (These use cases are based on a scenario paper "SVN move/rename
9 problems & suggested improvements" submitted by a corporate Subversion
10 user, which may be found attached to issue #2282.)
12 --------------------------------------------------------------------------
20 During an update, a file modification is merged onto a file move.
24 Developer A modifies Foo.c and commits it to the repository.
26 Developer B has simultaneously moved Foo.c to Bar.c in his working
29 B cannot commit because the working copy is out of date, so B runs 'svn
30 update'. The update will apply A's modifications to Foo.c in the
31 repository to Foo.c in B's working copy.
33 Problems With Current Behavior
37 A's modification of Foo.c will effectively be reverted by B's new
38 revision. Foo.c will be deleted in the new revision, and Bar.c will be
39 added with the content of the original Foo.c before A's modifications.
40 Hence A will likely get angry with B.
44 B is not explicitly warned about reverting A's modification of Foo.c.
45 The only visible warning is that Foo.c is left behind unversioned in
46 B's working copy because it has "local" modifications (which were in
47 fact made by A). This will likely escape B's attention.
49 Diagram of current behavior
53 wcA -- Foo.c' ------->
57 -- Foo.c -------------- Foo.c' --------------- Bar.c --->
61 wcB -- +Bar.c ---------- +Bar.c ---- Bar.c --->
62 (move) -Foo.c -Foo.c' ?Foo.c' (unversioned)
67 When user B updates, A's modifications to Foo.c should be merged into
68 Bar.c. Signal a text conflict if necessary.
70 Foo.c should be deleted from B's working copy.
72 A tree conflict should be signalled to inform B of the new changes
73 to Bar.c, so that B can review the modified Bar.c before committing it.
75 Diagram of desired behaviour
79 wcA -- Foo.c' ------->
83 -- Foo.c --------------- Foo.c' ------------------------ Bar.c' --->
85 \ |update |commit |commit
87 wcB -- +Bar.c ------------ +Bar.c' -------------->
88 (move) -Foo.c -Foo.c ^
99 During an update, a file move is merged onto a file modification.
101 This is essentially the same as Use Case 1, with the difference that
102 this time, B does the edit and A does the move.
106 Developer B modifies Foo.c in his working copy.
108 Developer A has simultaneously moved Foo.c to Bar.c and commits
109 the move to the repository.
111 B cannot commit because his working copy is out of date, so B runs
112 'svn update'. The next update will add Bar.c (with the same content
113 as the original Foo.c) to B's working copy, and delete Foo.c from
114 B's working copy. Since B made local modifications to Foo.c,
115 it will not be deleted from disk but left behind unversioned.
117 Problems with Current Behavior
119 Developer B may not notice that Foo.c fell out of version control.
120 B's source tree in the working copy likely builds fine because Foo.c
121 is still present on disk. So B may commit an incomplete change set,
122 possibly breaking the tree. Everybody will get angry with B if this
125 Diagram of Current Behaviour
129 wcA -- +Bar.c ------->
133 -- Foo.c --------------- Bar.c ----------------------->
137 wcB -- Foo.c' ------------ Bar.c ------->
138 (edit) ?Foo.c' (unversioned)
143 In B's working copy, the update should add Bar.c and merge the local
144 modifications to Foo.c into Bar.c. Signal a text conflict if necessary.
146 Foo.c should be deleted from B's working copy.
148 A tree conflict should be signaled to inform B that Foo.c has been
151 Diagram of Desired Behaviour
155 wcA -- +Bar.c ------->
159 -- Foo.c --------------- Bar.c -------------------------- Bar.c'--->
161 \ |update |commit |commit
163 wcB -- Foo.c' ------------+Bar.c' ------------------------>
175 During an update, a file move is merged onto a conflicting file move.
179 Developer A moves Foo.c to Bar.c and commits the move to the repository.
181 Developer B has moved Foo.c to Bix.c in his working copy.
183 B cannot commit because his working copy is out of date, so B runs
184 'svn update'. The update will add Bar.c to B's working copy and
185 delete Foo.c from B's working copy (the latter is a no-op).
187 Problems with Current Behavior
189 After B's next commit, the content of the original Foo.c
190 will exist twice in the source tree under two different paths,
191 namely Bar.c and Bix.c, respectively.
193 This may not have been intended.
195 Diagram of Current Behavior
199 wcA -- +Bar.c ------>
203 -- Foo.c --------------- Bar.c ------------------ Bar.c --->
207 wcB -- +Bix.c ---------- +Bix.c ------->
213 A tree conflict should be signaled to inform B of the conflicting rename
214 operation. B can now decide on deleting either file or committing both.
216 Diagram of Desired Behavior
220 wcA -- +Bar.c ------>
224 -- Foo.c --------------- Bar.c -------------------------- Bar.c -->
226 \ |update |commit |commit or both)
228 wcB -- +Bix.c ---------- +Bix.c -------------->
229 (move) -Foo.c Bar.c ^
240 A file modification is merged onto the source of a file move.
244 Developer A modifies Foo.c and commits it to the repository.
246 Developer B moves Foo.c to Bar.c and commits it to the repository.
248 Developer merges A's new revision into his working copy. The merge
249 will apply A's modification to Foo.c to the Foo.c in B's working
252 Problems With Current Behavior
256 A's modification of Foo.c will not be merged to B's line of
257 development because the merge skips the absent file.
261 B is not explicitly warned about reverting A's modification of Foo.c,
262 except for a "skipped" warning in the output of the merge command,
263 which might not be noticed.
265 Diagram of current behavior
269 urlA -- Foo.c' ------------------>
272 -- Foo.c - |merge -c50
275 urlB -- +Bar.c ------------|----------------->
279 wcB -- Bar.c -- Bar.c ------ -->
284 When user B merges, A's modifications to Foo.c should be merged into
285 Bar.c. Signal a text conflict if necessary.
287 A tree conflict should be signalled to inform B of the new changes
288 to Bar.c, so that B can review the modified Bar.c before committing it.
290 Diagram of desired behaviour
294 urlA -- Foo.c' ------------------>
297 -- Foo.c - |merge -c50
300 urlB -- +Bar.c -------------|-------------------- Bar.c' -->
301 (move) -Foo.c \ | ^ ^
304 wcB -- Bar.c -- Bar.c' --------------->
316 A file move is merged onto a modification of the move-source.
318 This is essentially the same as Use Case 4, with the difference that
319 this time, B does the edit and A does the move.
323 Developer A moves Foo.c to Bar.c and commits it to the repository.
325 Developer B modifies Foo.cand commits it to the repository.
327 Developer merges A's new revision into his working copy. The merge
328 will add Bar.c (with the same content as the original Foo.c) and
329 will delete B's Foo.c.
331 Problems With Current Behavior
335 B's has modified Foo.c in the past. This modification will be lost
336 unless B reviews the history of Foo.c and Bar.c at both URLs and
337 corrects the problem (e.g., via 'svn copy').
339 Diagram of current behavior
343 urlA -- +Bar.c ------------------->
346 -- Foo.c - |merge -c50
349 urlB -- Foo.c' -------------|------------ Bar.c --->
353 wcB -- Foo.c' -- +Bar.c ------>
359 In B's working copy, the update should add Bar.c and merge the local
360 modifications to Foo.c into Bar.c. Signal a text conflict if necessary.
362 Foo.c should be deleted from B's working copy.
364 A tree conflict should be signaled to inform B that Foo.c has been
367 Diagram of desired behaviour
371 urlA -- +Bar.c ------------------->
374 -- Foo.c - |merge -c50
377 urlB -- Foo.c' -------------|-------------------- Bar.c'-->
381 wcB -- Foo.c' -- Bar.c' --------------->
393 A file move is merged onto a conflicting file move.
397 Developer A moves Foo.c to Bar.c and commits it to the repository.
399 Developer B moves Foo.c to Bix.c and commits it to the repository.
401 Developer merges A's new revision into his working copy. The merge
402 will add Bar.c with history in B's working copy.
404 Problems With Current Behavior
406 After B's next commit, the content of the original Foo.c will exist
407 twice in the source tree under two different paths (Bar.c and
408 Bix.c). This may not have been intended.
410 Diagram of current behavior
414 urlA -- +Bar.c ------------------>
417 -- Foo.c - |merge -c50
420 urlB -- +Bix.c ------------|---------------- Bix.c --->
421 (move) -Foo.c \ | ^ Bar.c
424 wcB -- Bix.c -- Bix.c ---------->
430 A tree conflict should be signaled to inform B of the conflicting
431 rename operation. B can delete either file or commit both.
433 Diagram of desired behaviour
437 urlA -- +Bar.c ----------------->
440 -- Foo.c - |merge -c50
443 urlB -- +Bix.c ------------|------------------------- Bar.c -->
444 (move) -Foo.c \ | ^ ^ (or Bix.c,
445 \ | |commit |commit or both)
447 wcB -- Bix.c -- Bix.c -------------->