Hg rename issues
From Genunix
Contents |
Overview
Large projects in ON rely on Teamware's handling of renames. In particular, Teamware can apply content updates to renamed files, and it detects conflicting renames (i.e., the parent and child each moved a file to a different location). Rename support is in Mercurial 0.9.3, but light testing shows that it doesn't always produce the behavior that Teamware users expect.
This page documents the behavior that we expect for rename, as well as any discussion, random notes related to rename, etc. If there are issues that need changes in Mercurial, it's not clear whether we'll track them here or at http://bugs.grommit.com (in addition to filing Mercurial bugs).
Operations, Conflicts
Users can introduce two types of changes into a workspace: namespace changes and content changes. Namespace changes are
- create foo
- delete foo
- rename foo bar
(Copy is a special case of "create").
Mercurial includes a "mv -f foo bar" operation; that should be treated as
- delete bar
- mv foo bar
rather than
- update bar with the contents of foo
- delete foo
When updating from another workspace, any of these scenarios can be considered a conflict:
- content updates to the same file
- different namespace operations on the same file
- deletion of a file that has a content update
For rename, both the old and new names need to be looked at.
Expected Behavior
The handling of content conflicts is pretty well understood. Hand the parent, child, and ancestor to some code that resolves the conflict, perhaps with the user's help.
Creation of the same file in the parent and child, but with different contents, should be treated as a content conflict.
For namespace conflicts: give the user a choice of operations, any of which will resolve the conflict; see Open Issues below. A namespace conflict occurs when any two namespace operations (rename, create, delete) affect the same file, regardless of the type of the operation.
For delete/content conflicts: give the user the choice of whether to keep the modified file or delete it.
For non-conflicting operations (e.g., parent renames and child updates the contents), the user should end up with the new contents at the new name.
optimizations
For content updates, the SCM may detect the case where the file has the exact same contents in both workspaces, even though the changeset history is different. In that case, the SCM can optimize out any conflict handling, but that's not required.
Similarly, if the parent does "mv foo bar" and the child does "mv foo foo2; mv foo2 bar", the SCM can optimize out the conflict handling, but it's not required.
Open Issues
Mercurial handles some namespace conflicts by telling the user what the parent ("remote") and child ("local") workspaces have done, and requiring the user to pick one. For example:
$ hg merge local changed foo which remote deleted (k)eep or (d)elete?
This seems like a pretty good model, but we need to consider what choices the user is given, particularly in the case of rename. If the parent does "rename P foo" and the child does "rename C foo", the options might look like
- delete parent's file
- delete child's file
- give the parent's file a new name
- give the child's file a new name
For the related scenario, where the parent does "rename foo P" and the child does "rename foo C", the options might look like
- keep P (only)
- keep C (only)
- keep both P and C
If both P and C have been modified, there is a content conflict, even if both files are kept. This is to ensure that the edits are reviewed--they might be applicable to both files.
Another issue is that at the time the user is prompted to make a choice, she might not have enough information to make that choice. One way to handle that would be to have a "skip" choice, which lets the user come back to the file later. Or, don't require a choice at all: just issue a warning and assume that the user will deal with it.
