Note:
This page is primarily intended for developers of Mercurial.
Note:
This page is no longer relevant but is kept for historical purposes.
Rename Plan
Status: completed.
See CopyMergeCases for use cases.
The use cases indicate two different areas we need to handle renames:
- merge on a file that has been renamed remotely and locally to the same file
- files that have been copied/renamed on one side and possibly modified on the other
The first can be addressed by a rename-aware ancestor algorithm placed in filectx and used by merge3. (implemented)
- create an ancestry graph spanning all the renames in question
- find the roots of the graph
- create a child graph and find the distance from the roots
- visit each node searching for the common ancestor as in revlog.ancestor()
The second operates at the manifestmerge level. (implemented)
- find the ancestor changeset - no renames before this point are interesting
- find all files that aren't paired (local, remote)
- find all historic copies/renames for all unpaired files back to ancestor changeset
- find most recent ancestors between (unpaired local, remote) and (local, unpaired remote)
- use this data for unpaired files when merging
Some thoughts on directory rename detection:
- generate a list of directories for each manifest
- scan the copy map, constructing a directory copy map
- if a directory gets "copied" to two places, remove it from the map
- remove entries in the directory copy map for all directories that still exist
- construct lists of unpaired dirs (local, remote)
- if a rename above moves a file from an unpaired dir elsewhere, it's probably a directory rename
- again, use this data as a fallback for dealing with unpaired files in manifest merging