* subversion/libsvn_repos/repos.c
[svn.git] / notes / tree-conflicts / use-cases.txt
blobccfe681f585fb99264ead3634cb07aefc48ac7d5
1                                -*- text -*-
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 --------------------------------------------------------------------------
14 ==========
15 USE CASE 1
16 ==========
18 Description
20    During an update, a file modification is merged onto a file move.
22 Current Behavior
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
27    copy.
28    
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
35    First problem:
36    
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.
41    
42    Second problem:
43    
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
52               (edit)
53     wcA          -- Foo.c' ------->
54                 /         |
55                /          |commit
56     repos     /           v
57     -- Foo.c -------------- Foo.c' --------------- Bar.c --->
58               \                     |          ^
59                \                    |update    |commit
60                 \                   v          |
61     wcB          -- +Bar.c ---------- +Bar.c ----  Bar.c --->
62              (move) -Foo.c            -Foo.c'     ?Foo.c' (unversioned)
65 Desired behavior
67    When user B updates, A's modifications to Foo.c should be merged into
68    Bar.c. Signal a text conflict if necessary.
69    
70    Foo.c should be deleted from B's working copy.
71    
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
78               (edit)
79     wcA          -- Foo.c' ------->
80                 /          |
81                /           |commit
82     repos     /            v
83     -- Foo.c --------------- Foo.c' ------------------------ Bar.c' --->
84               \                      |           ^        ^
85                \                     |update     |commit  |commit
86                 \                    v           |(fails) |
87     wcB          -- +Bar.c ------------ +Bar.c' -------------->
88              (move) -Foo.c              -Foo.c          ^
89                                                         |
90                                                      resolved
93 ==========
94 USE CASE 2
95 ==========
97 Description
99    During an update, a file move is merged onto a file modification.
100    
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.
104 Current Behavior
106    Developer B modifies Foo.c in his working copy.
107    
108    Developer A has simultaneously moved Foo.c to Bar.c and commits
109    the move to the repository.
110    
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
123    happens.
125 Diagram of Current Behaviour
128               (move)
129     wcA          -- +Bar.c ------->
130                 /   -Foo.c |
131                /           |commit
132     repos     /            v
133     -- Foo.c --------------- Bar.c ----------------------->
134               \                      |            ^
135                \                     |update      |commit
136                 \                    v            |(no-op)
137     wcB          -- Foo.c' ------------  Bar.c  ------->
138              (edit)                     ?Foo.c' (unversioned)
141 Desired Behavior
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.
145    
146    Foo.c should be deleted from B's working copy.
147    
148    A tree conflict should be signaled to inform B that Foo.c has been
149    renamed to Bar.c
151 Diagram of Desired Behaviour
154               (move)
155     wcA          -- +Bar.c ------->
156                 /   -Foo.c |
157                /           |commit
158     repos     /            v
159     -- Foo.c --------------- Bar.c -------------------------- Bar.c'--->
160               \                      |          ^          ^
161                \                     |update    |commit    |commit
162                 \                    v          |(fails)   |
163     wcB          -- Foo.c' ------------+Bar.c' ------------------------>
164              (edit)                    -Foo.c'           ^
165                                                          |
166                                                       resolved
169 ==========
170 USE CASE 3
171 ==========
173 Description
175    During an update, a file move is merged onto a conflicting file move.
177 Current Behavior
179    Developer A moves Foo.c to Bar.c and commits the move to the repository.
180    
181    Developer B has moved Foo.c to Bix.c in his working copy.
182    
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.
192    
193    This may not have been intended.
195 Diagram of Current Behavior
198              (move)
199     wcA          -- +Bar.c ------>
200                 /   -Foo.c |
201                /           |commit
202     archive   /            v
203     -- Foo.c --------------- Bar.c ------------------ Bar.c --->
204               \                    |         ^        Bix.c
205                \                   |update   |commit
206                 \                  v         |
207     wcB          -- +Bix.c ---------- +Bix.c ------->
208              (move) -Foo.c             Bar.c
211 Desired Behavior
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
219              (move)
220     wcA          -- +Bar.c ------>
221                 /   -Foo.c |
222                /           |commit
223     archive   /            v
224     -- Foo.c --------------- Bar.c -------------------------- Bar.c -->
225               \                    |         ^        ^       (or Bix.c,
226                \                   |update   |commit  |commit  or both)
227                 \                  v         |(fails) |
228     wcB          -- +Bix.c ---------- +Bix.c -------------->
229              (move) -Foo.c             Bar.c        ^
230                                                     |
231                                                  resolved
234 ==========
235 USE CASE 4
236 ==========
238 Description
240    A file modification is merged onto the source of a file move.
242 Current Behavior
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.
247    
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
250    copy.
252 Problems With Current Behavior
254    First problem:
255    
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.
258    
259    Second problem:
260    
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
268             (edit)
269     urlA        -- Foo.c' ------------------>
270                /   (r50)              |
271               /                       |
272     -- Foo.c -                        |merge -c50
273               \                       |(Foo.c skipped)
274                \                      |
275     urlB        -- +Bar.c ------------|----------------->
276             (move) -Foo.c \           |         ^
277                            \          |         |commit
278                             \         v         |(no-op)
279     wcB                      -- Bar.c -- Bar.c ------ -->
282 Desired behavior
284    When user B merges, A's modifications to Foo.c should be merged into
285    Bar.c. Signal a text conflict if necessary.
286    
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
293             (edit)
294     urlA        -- Foo.c' ------------------>
295                /   (r50)               |
296               /                        |
297     -- Foo.c -                         |merge -c50
298               \                        |(tree conflict)
299                \                       |
300     urlB        -- +Bar.c -------------|-------------------- Bar.c' -->
301             (move) -Foo.c  \           |          ^        ^
302                             \          |          |commit  |commit
303                              \         v          |(fails) |
304     wcB                       -- Bar.c -- Bar.c' --------------->
305                                                          ^
306                                                          |
307                                                       resolved
310 ==========
311 USE CASE 5
312 ==========
314 Description
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.
321 Current Behavior
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.
326    
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
333    First problem:
334    
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
342             (move)
343     urlA        -- +Bar.c ------------------->
344                /   -Foo.c              |
345               /    (r50)               |
346     -- Foo.c -                         |merge -c50
347               \                        |
348                \                       |
349     urlB        -- Foo.c' -------------|------------ Bar.c --->
350             (edit)        \            |          ^
351                            \           |          |commit
352                             \          v          |
353     wcB                      -- Foo.c' -- +Bar.c ------>
354                                           -Foo.c'
357 Desired behavior
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.
361    
362    Foo.c should be deleted from B's working copy.
363    
364    A tree conflict should be signaled to inform B that Foo.c has been
365    renamed to Bar.c
367 Diagram of desired behaviour
370             (move)
371     urlA        -- +Bar.c ------------------->
372                /   -Foo.c              |
373               /    (r50)               |
374     -- Foo.c -                         |merge -c50
375               \                        |(tree conflict)
376                \                       |
377     urlB        -- Foo.c' -------------|-------------------- Bar.c'-->
378             (edit)        \            |          ^        ^
379                            \           |          |commit  |commit
380                             \          v          |(fails) |
381     wcB                      -- Foo.c' -- Bar.c' --------------->
382                                          -Foo.c'         ^
383                                                          |
384                                                       resolved
387 ==========
388 USE CASE 6
389 ==========
391 Description
393    A file move is merged onto a conflicting file move.
395 Current Behavior
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.
400    
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
413             (move)
414     urlA        -- +Bar.c ------------------>
415                /   -Foo.c             |
416               /    (r50)              |
417     -- Foo.c -                        |merge -c50
418               \                       |
419                \                      |
420     urlB        -- +Bix.c ------------|---------------- Bix.c --->
421             (move) -Foo.c \           |         ^       Bar.c
422                            \          |         |commit
423                             \         v         |
424     wcB                      -- Bix.c -- Bix.c ---------->
425                                         +Bar.c
428 Desired behavior
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
436             (move)
437     urlA        -- +Bar.c ----------------->
438                /   -Foo.c             |
439               /    (r50)              |
440     -- Foo.c -                        |merge -c50
441               \                       |(tree conflict)
442                \                      |
443     urlB        -- +Bix.c ------------|------------------------- Bar.c -->
444             (move) -Foo.c \           |         ^        ^       (or Bix.c,
445                            \          |         |commit  |commit  or both)
446                             \         v         |(fails) |
447     wcB                      -- Bix.c -- Bix.c -------------->
448                                         +Bar.c          ^
449                                                         |
450                                                      resolved