directory-rename-detection.txt: technical docs on abilities and limitations
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Elijah Newren committed
Jun 27, 2018 at 00:23 UTC
4d34dffbdd2226034df9d7612f1e221b7143fc6a
1 file changed
+92
Documentation/technical/directory-rename-detection.txt
new
+92
@@ -0,0 +1,92 @@
1
+Directory rename detection
2
+==========================
3
+
4
+Rename detection logic in diffcore-rename that checks for renames of
5
+individual files is aggregated and analyzed in merge-recursive for cases
6
+where combinations of renames indicate that a full directory has been
7
+renamed.
8
+
9
+Scope of abilities
10
+------------------
11
+
12
+It is perhaps easiest to start with an example:
13
+
14
+ * When all of x/a, x/b and x/c have moved to z/a, z/b and z/c, it is
15
+ likely that x/d added in the meantime would also want to move to z/d by
16
+ taking the hint that the entire directory 'x' moved to 'z'.
17
+
18
+More interesting possibilities exist, though, such as:
19
+
20
+ * one side of history renames x -> z, and the other renames some file to
21
+ x/e, causing the need for the merge to do a transitive rename.
22
+
23
+ * one side of history renames x -> z, but also renames all files within
24
+ x. For example, x/a -> z/alpha, x/b -> z/bravo, etc.
25
+
26
+ * both 'x' and 'y' being merged into a single directory 'z', with a
27
+ directory rename being detected for both x->z and y->z.
28
+
29
+ * not all files in a directory being renamed to the same location;
30
+ i.e. perhaps most the files in 'x' are now found under 'z', but a few
31
+ are found under 'w'.
32
+
33
+ * a directory being renamed, which also contained a subdirectory that was
34
+ renamed to some entirely different location. (And perhaps the inner
35
+ directory itself contained inner directories that were renamed to yet
36
+ other locations).
37
+
38
+ * combinations of the above; see t/t6043-merge-rename-directories.sh for
39
+ various interesting cases.
40
+
41
+Limitations -- applicability of directory renames
42
+-------------------------------------------------
43
+
44
+In order to prevent edge and corner cases resulting in either conflicts
45
+that cannot be represented in the index or which might be too complex for
46
+users to try to understand and resolve, a couple basic rules limit when
47
+directory rename detection applies:
48
+
49
+ 1) If a given directory still exists on both sides of a merge, we do
50
+ not consider it to have been renamed.
51
+
52
+ 2) If a subset of to-be-renamed files have a file or directory in the
53
+ way (or would be in the way of each other), "turn off" the directory
54
+ rename for those specific sub-paths and report the conflict to the
55
+ user.
56
+
57
+ 3) If the other side of history did a directory rename to a path that
58
+ your side of history renamed away, then ignore that particular
59
+ rename from the other side of history for any implicit directory
60
+ renames (but warn the user).
61
+
62
+Limitations -- detailed rules and testcases
63
+-------------------------------------------
64
+
65
+t/t6043-merge-rename-directories.sh contains extensive tests and commentary
66
+which generate and explore the rules listed above. It also lists a few
67
+additional rules:
68
+
69
+ a) If renames split a directory into two or more others, the directory
70
+ with the most renames, "wins".
71
+
72
+ b) Avoid directory-rename-detection for a path, if that path is the
73
+ source of a rename on either side of a merge.
74
+
75
+ c) Only apply implicit directory renames to directories if the other side
76
+ of history is the one doing the renaming.
77
+
78
+Limitations -- support in different commands
79
+--------------------------------------------
80
+
81
+Directory rename detection is supported by 'merge' and 'cherry-pick'.
82
+Other git commands which users might be surprised to see limited or no
83
+directory rename detection support in:
84
+
85
+ * diff
86
+
87
+ Folks have requested in the past that `git diff` detect directory
88
+ renames and somehow simplify its output. It is not clear whether this
89
+ would be desirable or how the output should be simplified, so this was
90
+ simply not implemented. Further, to implement this, directory rename
91
+ detection logic would need to move from merge-recursive to
92
+ diffcore-rename.