|  | Status of this file: In progress. | 
|  |  | 
|  | Purpose of the file: To record the requirements and principles that guide the design of tree-conflict handling. ("Policy" is not a good name for it.) | 
|  |  | 
|  |  | 
|  | BACKGROUND AND TERMINOLOGY | 
|  | ========================== | 
|  |  | 
|  | MERGE TRACKING | 
|  | -------------- | 
|  |  | 
|  | The merge tracking feature helps the client software to determine which changes | 
|  | (revisions) from the source branch to apply to the specified target tree. After | 
|  | that has been determined, the application of one change to one target is where | 
|  | conflict detection becomes involved. | 
|  |  | 
|  | At this level of applying changes to the target, merge tracking is irrelevant. | 
|  |  | 
|  | MERGE IS DIFF-AND-APPLY | 
|  | ----------------------- | 
|  |  | 
|  | Subversion's definition of "merging" is to determine the difference between two | 
|  | source trees SOURCE-LEFT and SOURCE-RIGHT, and try to apply that difference to | 
|  | a TARGET tree. The diff that it tries to apply is an arbitrary low-level | 
|  | representation of the overall difference between SOURCE-LEFT and SOURCE-RIGHT, | 
|  | not the series of logically meaningful transformations by which the user | 
|  | originally transformed SOURCE-LEFT into SOURCE-RIGHT. | 
|  |  | 
|  | Typically, SOURCE-LEFT is an ancestor of SOURCE-RIGHT in a source branch, but | 
|  | this need not be so. (One effect of the "--ignore-ancestry" option is to force | 
|  | the merge to perform a detailed diff between the sources even if they are not | 
|  | so related, where it would otherwise present the diff as "delete SOURCE-LEFT; | 
|  | add SOURCE-RIGHT".) | 
|  |  | 
|  | The differences are applied to a working copy of the TARGET tree (which may | 
|  | include some local modifications against its base). | 
|  |  | 
|  | The degree of success of a merge depends on the degree to which the TARGET tree | 
|  | is similar enough to SOURCE-LEFT for Subversion to be able to match each file | 
|  | or directory involved in the diff to a corresponding file or directory in | 
|  | TARGET. This matching is done purely by path. Where this matching fails, the | 
|  | merge cannot apply that part of the diff. Some of these failures will be | 
|  | defined as "tree conflicts". | 
|  |  | 
|  |  | 
|  | USE CASES | 
|  | ========= | 
|  |  | 
|  | The use cases (in "use-cases.txt") illustrate some of the cases that are to be | 
|  | handled, but are not a complete set of requirements. | 
|  |  | 
|  | The user-level requirements are presented in terms of user-interface actions. | 
|  | Note that the design is formulated and presented in terms of lower-level | 
|  | operations that do not include a "rename" operation. | 
|  |  | 
|  |  | 
|  | REQUIREMENTS | 
|  | ============ | 
|  |  | 
|  | These requirements specify what a tree conflict means, how a tree conflict | 
|  | behaves, and under exactly what conditions a tree conflict is raised. These | 
|  | requirements are intended to apply in all merge, switch and update commands | 
|  | unless otherwise stated. | 
|  |  | 
|  | DEFINITION OF A TREE CONFLICT | 
|  | ----------------------------- | 
|  |  | 
|  | A conflict is the condition that occurs when Subversion cannot apply a source | 
|  | change correctly and with certainty to a corresponding target object. A tree | 
|  | conflict is a kind of conflict that occurs due to a part of the TARGET tree | 
|  | being in some sense "incompatible" with the SOURCE-LEFT tree in kind, name, | 
|  | location, absence or presence. | 
|  |  | 
|  | Every tree conflict shall be signaled both by an indication when the conflict | 
|  | occurs and by being marked in the WC in a way that shows up as a conflict in | 
|  | the "svn status" output. | 
|  |  | 
|  | The state of conflict shall persist until the user confirms that it has been | 
|  | resolved. The user shall be able to confirm the resolution of each and every | 
|  | conflict individually, and shall also be able to confirm the resolution of all | 
|  | conflicts in a tree with a single command. | 
|  |  | 
|  | Confirming the resolution of each and every tree conflict means being | 
|  | able to confirm the resolution of a tree conflict with a single tree conflict | 
|  | victim, even though there might be more than one tree conflict victim | 
|  | in a directory. A tree conflict victim is a file or directory in the tree | 
|  | which is affected by a tree conflict. For example, it might be a file | 
|  | which is deleted during an update operation while carrying local modifications, | 
|  | or it might be a file being blocked during a merge by an unversioned file of | 
|  | the same name. Each tree conflict has only a single victim. | 
|  |  | 
|  | Every condition that results in the source diff not being fully applied to the | 
|  | target shall result in either a conflict or an error exit, with a strong | 
|  | preference for a conflict. | 
|  |  | 
|  | CONSEQUENCES OF A TREE CONFLICT | 
|  | ------------------------------- | 
|  |  | 
|  | A commit shall be disallowed if any item considered as part of the commit is | 
|  | marked with a conflict (a tree conflict or any other conflict). | 
|  |  | 
|  | A merge or switch or update shall be disallowed if it affects a part of the WC | 
|  | that is marked with a conflict. | 
|  |  | 
|  | NON-REQUIREMENTS | 
|  | ---------------- | 
|  |  | 
|  | It is desirable for a tree conflict to be resolved automatically (and thus not | 
|  | to be signaled as a conflict) when there is a way to do so that is clearly what | 
|  | the user wants. This might require some configurable rules. This is not | 
|  | presently a requirement. | 
|  |  | 
|  | FAILURE TO GENERATE THE DIFF | 
|  | ---------------------------- | 
|  |  | 
|  | When the diff cannot be completely determined due to read access restrictions | 
|  | in the source repository, tree conflicts shall be handled as defined herein for | 
|  | those parts of the diff that are determined. Rules for whether and how to | 
|  | proceed with an incomplete diff are out of scope of this tree-conflicts | 
|  | document. | 
|  |  | 
|  | FAILURE TO APPLY THE DIFF | 
|  | ------------------------- | 
|  |  | 
|  | When a part of the diff should apply to a part of the WC that is switched, the | 
|  | rule for whether to apply the diff to this switched subtree or to the natural | 
|  | (unswitched) subtree or to both or to neither is out of scope of this | 
|  | tree-conflicts document, but tree conflict handling shall apply wherever the | 
|  | diff is applied. | 
|  |  | 
|  | When a part of the diff cannot be applied, due to not finding a corresponding | 
|  | object or due to an unversioned item being present in the working copy at this | 
|  | path, a conflict is to be signaled. (Previously, in some cases a conflict was | 
|  | raised, in some cases a warning was issued, and in some cases the change was | 
|  | silently discarded.) | 
|  |  | 
|  | When a part of the diff should apply to a part of the WC that is absent | 
|  | (perhaps due to authz restrictions or due to an intentionally sparse WC), a | 
|  | conflict shall be signaled. ###? This seems to be use case 4, right? | 
|  |  | 
|  | LOCAL WC MODIFICATIONS | 
|  | ---------------------- | 
|  |  | 
|  | Correct behaviour with local WC mods in TARGET is conceptually the same as if | 
|  | that uncommitted revision were just another committed revision. (Any necessary | 
|  | differences are to be detailed on delivery.) Correct behaviour with local mods | 
|  | is required for "update". For "switch" and "merge", correct behaviour with | 
|  | local mods is desired but not required for initial delivery. | 
|  |  | 
|  | If there is already a conflict in a part of the WC that is to be affected by | 
|  | the merge, then the application of the merge shall be disallowed and no part of | 
|  | the WC shall be altered. | 
|  |  | 
|  | ### TODO: How can users use 'svn merge' to resolve a tree conflict? | 
|  |  | 
|  | NON-CONFLICTS | 
|  | ------------- | 
|  |  | 
|  | When a file is to be deleted or renamed, there shall be a conflict unless the | 
|  | target file is identical to the SOURCE-LEFT file. Identical shall mean | 
|  | identical text and properties except for "svn:mergeinfo". | 
|  |  | 
|  | When a directory is to be deleted or renamed, there shall be a conflict unless | 
|  | the target directory is identical to the SOURCE-LEFT directory. Identical shall | 
|  | mean identical properties except for "svn:mergeinfo", and an identical list of | 
|  | children (including their types), and recursively identical directory children | 
|  | and file children according to these definitions of "identical" for directories | 
|  | and for files respectively. | 
|  |  | 
|  | ### Is that last test (directory being identical) too expensive/impractical to | 
|  | calculate? | 
|  |  | 
|  | ### This is something I've also been thinking about - determining equality | 
|  | of directories may turn out to be a major problem. Would requiring only | 
|  | the direct children to be equal be an acceptable compromise? | 
|  |  |