Reputation: 29567
Mercurial 3.4.1 on Mac Yosemite (10.10.5) here. I don't know why I find hg
so confusing. I cloned a repo several weeks ago and have been pecking away at it here and there. I'm now ready to push all my changes to the remote hg
server but several other developers have made changes (both conflicting and non-conflicting) in the meantime. This project uses pure mainline development (no branching) against default
.
I ran hg add .
and then hg commit -m "Fixing x, y and z."
, and now I need to merge my local default
HEAD with the default
HEAD on the remote/origin hg
server. So I need:
Not sure that it makes a difference, but a lot of my changes also refactored the basic project structure (deleted/renamed/moved both source files and directories). So these changes should be pretty significant.
Reading the hg merge
doc, I'm now even more confused than before! No where does that doc specify how to explicitly merge my local default
HEAD with the remote default
HEAD. Furthermore, the doc mentions:
"hg resolve" must be used to resolve unresolved files.
What are unresolved files?!? Do I have to run this command prior to hg merge
? How does it affect/interact with the merging process?
Upvotes: 0
Views: 1222
Reputation: 8740
The hg merge
command merges the files in the current working directory with the changes in the revision specified by the -r
argument (if the current working directory is the checkout of a head of a branch and the branch has exactly one other head, then the other revision to merge with is inferred automatically). The result of the merge can then be committed and (upon commit) becomes a child revision of these two revisions. What you usually do is therefore:
hg update ORIGINAL_REVISION
hg merge -r NEW_REVISION
Both ORIGINAL_REVISION
and NEW_REVISION
can be specified as described in hg help revisions
or hg help revsets
.
The result of hg merge
will be the result of combining the changes in NEW_REVISION
with ORIGINAL_REVISION
. Whenever Mercurial can combine the changes without any apparent conflicts, it will do that. Note that hg merge
will not commit the combined changes, but only update the working directory; committing them to create a merge commit is a separate step.
What happens if there is a conflict? If there is a merge tool available (Mercurial will try to be smart about available merge tools and select one from a list it knows about if one is available, but you may have to specify it explicitly, e.g. via the --tool
option; see hg help mergetools
for more details), this tool will be started and you can resolve the conflict in there. If no tool from its list is available and you haven't specified one (via your .hgrc
, the HGMERGE
environment variable, or the --tool
option), Mercurial will fall back to its internal conflict resolution tool (equivalent to --tool :merge
), which will simply add conflict markers to the file that can then be resolved either manually inside your editor of choice or with a tool that knows how to handle such conflict markers.
You can use hg resolve
to review and update the list of files with conflicts. Specifically, hg resolve -l
will list the files that had conflicts, prefixed by R
if the conflict has been resolved (e.g. by a merge tool or because you marked it as resolved) or U
if the conflict remains unresolved. You can use hg resolve -m FILE
to mark FILE
as resolved or hg resolved -u FILE
to mark it as unresolved (you can also provide a list of files or -a
to mark all files). You can use hg resolve --tool TOOL FILE
or hg resolve FILE
to redo the merge for a specific file.
Once hg resolve -l
shows no more unresolved conflicts, you can then commit the merge.
If at any point during the merge your working directory ends up in a state that you cannot seem to recover from, hg update -C
will abort the merge and undo the entire merge (careful: you will lose any merging resolutions that you have done so far).
If (as you indicated) you also renamed or deleted files, additional effort may be necessary. Normally, you should use hg mv
to rename files, hg cp
to copy them, and hg rm
or hg forget
to remove them. This will inform hg merge
what their common ancestor is and allows changes from both branches to the same file to be combined, even if both branches have them ending up in different files. If you didn't do that, you can use hg addremove -s PERCENTAGE
to try and let Mercurial smartly discover renames and copies (mind you, this still has to be done before you commit or merge the changes). The -s
/--similarity
argument is a percentage (by default 100) that indicates how similar files have to be in order to be seen as a rename/copy of one another. You can use -n
or --dry-run
to just have hg addremove
list what it would do without actually doing it.
Upvotes: 3
Reputation: 6044
A merge is always a local operation where you merge one revision into another from another branch or head.
When you used the internal merge tool, it will add conflict markers to the places where it needs internal intervention. You usually visit those files, fix the conflict and then mark the conflicts resolved within those file(s) explicitly by using hg resolve --mark FILE
. You cannot commit the merge before not all those merge conflicts have been marked as handled. You can mark all conflicts as handled at once: hg resolve --mark --all
- but be sure that you actually handled all merge conflicts or your files will be committed with merge conflict indicators remaining which likely is not what you want.
Upvotes: 1