diff options
Diffstat (limited to 'Documentation/technical/directory-rename-detection.txt')
-rw-r--r-- | Documentation/technical/directory-rename-detection.txt | 115 |
1 files changed, 0 insertions, 115 deletions
diff --git a/Documentation/technical/directory-rename-detection.txt b/Documentation/technical/directory-rename-detection.txt deleted file mode 100644 index 844629c8c441..000000000000 --- a/Documentation/technical/directory-rename-detection.txt +++ /dev/null @@ -1,115 +0,0 @@ -Directory rename detection -========================== - -Rename detection logic in diffcore-rename that checks for renames of -individual files is aggregated and analyzed in merge-recursive for cases -where combinations of renames indicate that a full directory has been -renamed. - -Scope of abilities ------------------- - -It is perhaps easiest to start with an example: - - * When all of x/a, x/b and x/c have moved to z/a, z/b and z/c, it is - likely that x/d added in the meantime would also want to move to z/d by - taking the hint that the entire directory 'x' moved to 'z'. - -More interesting possibilities exist, though, such as: - - * one side of history renames x -> z, and the other renames some file to - x/e, causing the need for the merge to do a transitive rename. - - * one side of history renames x -> z, but also renames all files within x. - For example, x/a -> z/alpha, x/b -> z/bravo, etc. - - * both 'x' and 'y' being merged into a single directory 'z', with a - directory rename being detected for both x->z and y->z. - - * not all files in a directory being renamed to the same location; - i.e. perhaps most the files in 'x' are now found under 'z', but a few - are found under 'w'. - - * a directory being renamed, which also contained a subdirectory that was - renamed to some entirely different location. (And perhaps the inner - directory itself contained inner directories that were renamed to yet - other locations). - - * combinations of the above; see t/t6043-merge-rename-directories.sh for - various interesting cases. - -Limitations -- applicability of directory renames -------------------------------------------------- - -In order to prevent edge and corner cases resulting in either conflicts -that cannot be represented in the index or which might be too complex for -users to try to understand and resolve, a couple basic rules limit when -directory rename detection applies: - - 1) If a given directory still exists on both sides of a merge, we do - not consider it to have been renamed. - - 2) If a subset of to-be-renamed files have a file or directory in the - way (or would be in the way of each other), "turn off" the directory - rename for those specific sub-paths and report the conflict to the - user. - - 3) If the other side of history did a directory rename to a path that - your side of history renamed away, then ignore that particular - rename from the other side of history for any implicit directory - renames (but warn the user). - -Limitations -- detailed rules and testcases -------------------------------------------- - -t/t6043-merge-rename-directories.sh contains extensive tests and commentary -which generate and explore the rules listed above. It also lists a few -additional rules: - - a) If renames split a directory into two or more others, the directory - with the most renames, "wins". - - b) Avoid directory-rename-detection for a path, if that path is the - source of a rename on either side of a merge. - - c) Only apply implicit directory renames to directories if the other side - of history is the one doing the renaming. - -Limitations -- support in different commands --------------------------------------------- - -Directory rename detection is supported by 'merge' and 'cherry-pick'. -Other git commands which users might be surprised to see limited or no -directory rename detection support in: - - * diff - - Folks have requested in the past that `git diff` detect directory - renames and somehow simplify its output. It is not clear whether this - would be desirable or how the output should be simplified, so this was - simply not implemented. Further, to implement this, directory rename - detection logic would need to move from merge-recursive to - diffcore-rename. - - * am - - git-am tries to avoid a full three way merge, instead calling - git-apply. That prevents us from detecting renames at all, which may - defeat the directory rename detection. There is a fallback, though; if - the initial git-apply fails and the user has specified the -3 option, - git-am will fall back to a three way merge. However, git-am lacks the - necessary information to do a "real" three way merge. Instead, it has - to use build_fake_ancestor() to get a merge base that is missing files - whose rename may have been important to detect for directory rename - detection to function. - - * rebase - - Since am-based rebases work by first generating a bunch of patches - (which no longer record what the original commits were and thus don't - have the necessary info from which we can find a real merge-base), and - then calling git-am, this implies that am-based rebases will not always - successfully detect directory renames either (see the 'am' section - above). merged-based rebases (rebase -m) and cherry-pick-based rebases - (rebase -i) are not affected by this shortcoming, and fully support - directory rename detection. |