/
usr
/
share
/
doc
/
git
/
technical
/
/usr/share/doc/git/technical
mkdir
upload
Name
Size
Mode
Actions
api-error-handling.html
22259
0644
edit
dl
rm
api-error-handling.txt
3818
0644
edit
dl
rm
api-index-skel.txt
432
0644
edit
dl
rm
api-index.html
17183
0644
edit
dl
rm
api-index.sh
611
0644
edit
dl
rm
api-index.txt
648
0644
edit
dl
rm
api-merge.html
18305
0644
edit
dl
rm
api-merge.txt
1090
0644
edit
dl
rm
api-parse-options.html
36657
0644
edit
dl
rm
api-parse-options.txt
13157
0644
edit
dl
rm
api-simple-ipc.html
22388
0644
edit
dl
rm
api-simple-ipc.txt
4852
0644
edit
dl
rm
api-trace2.html
77619
0644
edit
dl
rm
api-trace2.txt
44255
0644
edit
dl
rm
bitmap-format.html
30403
0644
edit
dl
rm
bitmap-format.txt
8871
0644
edit
dl
rm
bundle-uri.html
51387
0644
edit
dl
rm
bundle-uri.txt
26787
0644
edit
dl
rm
commit-graph.txt
17957
0644
edit
dl
rm
directory-rename-detection.txt
5199
0644
edit
dl
rm
hash-function-transition.html
64539
0644
edit
dl
rm
hash-function-transition.txt
35894
0644
edit
dl
rm
long-running-process-protocol.html
18995
0644
edit
dl
rm
long-running-process-protocol.txt
1929
0644
edit
dl
rm
multi-pack-index.html
22462
0644
edit
dl
rm
multi-pack-index.txt
4459
0644
edit
dl
rm
pack-heuristics.html
43594
0644
edit
dl
rm
pack-heuristics.txt
18040
0644
edit
dl
rm
packfile-uri.txt
3748
0644
edit
dl
rm
parallel-checkout.html
31715
0644
edit
dl
rm
parallel-checkout.txt
12301
0644
edit
dl
rm
partial-clone.html
36496
0644
edit
dl
rm
partial-clone.txt
14968
0644
edit
dl
rm
racy-git.html
27995
0644
edit
dl
rm
racy-git.txt
9121
0644
edit
dl
rm
reftable.html
73792
0644
edit
dl
rm
reftable.txt
37525
0644
edit
dl
rm
remembering-renames.txt
30360
0644
edit
dl
rm
repository-version.txt
4311
0644
edit
dl
rm
rerere.txt
6510
0644
edit
dl
rm
scalar.html
20458
0644
edit
dl
rm
scalar.txt
2935
0644
edit
dl
rm
send-pack-pipeline.html
19315
0644
edit
dl
rm
send-pack-pipeline.txt
1969
0644
edit
dl
rm
shallow.html
19685
0644
edit
dl
rm
shallow.txt
2548
0644
edit
dl
rm
sparse-checkout.txt
47499
0644
edit
dl
rm
sparse-index.txt
9501
0644
edit
dl
rm
trivial-merge.html
22273
0644
edit
dl
rm
trivial-merge.txt
4264
0644
edit
dl
rm
Edit:
/usr/share/doc/git/technical/directory-rename-detection.txt
(5199B)
Directory rename detection ========================== Rename detection logic in diffcore-rename that checks for renames of individual files is also aggregated there and then analyzed in either merge-ort or 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 so that the rename ends up at z/e. * 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/t6423-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/t6423-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) Only apply implicit directory renames to directories if the other side of history is the one doing the renaming. c) Do not perform directory rename detection for directories which had no new paths added to them. 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. Also, while diffcore-rename has most of the logic for detecting directory renames, some of the logic is still found within merge-ort and merge-recursive. Fully supporting directory rename detection in diffs would require copying or moving the remaining bits of logic to the diff machinery. * 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.
Save
cmd:
run