When merging conflicting changes using hg merge, Mercurial inserts a set of markers into the files to be merged in my working copy like this:
<<<<<<< local
version = 0.2
=======
version = 0.1
>>>>>>> other
Then I manually edit all files marked as U from a list produced by hg resolve --all -l and then I tell mercurial I have resolved them by hg resolve -m file1 file2 file3 ...
In many situations I would like however accept either my-only or their-only changes on some conflicting files. I am thinking to create two simple sed/awk/whatever scripts named accept-theirs.sh and accept-my.sh or is there any "proper" way to do it?
Use
hg resolve -t internal:other --all
to accept theirs and
hg resolve -t internal:local --all
to accept yours
Try this:
hg merge --tool internal:other
See also hg help merge-tools for more information.
To ensure we use the trunk version of some files when merging we use internal:local:
[merge-patterns]
.hgtags = internal:local
pom.xml = internal:local
It seems in some cases, the merge does NOT use the local file, it does actually merge the changes from the remote repository. Why would this be happening?
The Mercurial "premerge" internal merge is actually successfully resolving merge conflicts for certain files before even launching a merge tool.
If the chosen merge tools premerge is
True then an internal merge is
attempted, and if it seems successful
then the result it will silently be
used without running the actual merge
tool
Check out this article on merge tool configuration for more info. Turning off premerge for a particular type of file (or directory) can be done using these modifications to your Mercurial.ini file:
[merge-tools]
<name>.premerge = False
<name>.args = --auto $base $other $other -o $output
<name>.executable = kdiff3
[merge-patterns]
**.xml = <name>
.hgtags = <name>
Note that kdiff3 should come with TortoiseHg by default, and <name> can be anything you want; call it, 'localFilesOnly' or something like that.
I'd like to use TortoiseMerge with Mercurial to resolve conflicts, but its reporting every line in theirs and mine as added as though its not comparing properly
here is my mercurial.ini:
[ui]
merge = TortoiseMerge
[merge-tools]
TortoiseMerge.executable=C:\Program Files\TortoiseSVN\bin\TortoiseMerge.exe
TortoiseMerge.args=/mine:$local /theirs:$other /base:$base -o /merged:$output
I'm using Hg 1.7.5
What's going on?
Update: When using KDiff or BeyondCompare, the base is always empty.
Thanks
Your setup appears correct.
This is symptomatic of having no copy of the file in the base revision, in which case Mercurial acts as if the file was present but empty.
There are a couple ways of figuring out what's going on here. If there are no copies or renames involved, you should be able to simply do:
$ hg log -r "ancestor(p1(), p2())"
..to determine the ancestor of the merge, then:
$ hg manifest -r <rev> | grep <your file>
..to determine if the file was in fact present.
Alternately, you can run 'hg merge --debug' or 'hg update --debug' to see what changeset and file it's choosing for the merge (including rename/copy details).
If you find that the file is present in the common ancestor Mercurial chooses, then you should report a bug (including your debug output) at:
https://www.mercurial-scm.org/wiki/BugTracker
I am currently using the commmand hg diffmerge -r 32 -r 30 myfile, but this only displays two windows, not three. How can I make it do a three way merge?
.hgrc
[ui]
merge=diffmerge
[extensions]
collapse=~/.hgext/collapse.py
hgext.purge=
hgext.extdiff=
hgext.graphlog=
[extdiff]
cmd.diffmerge=/usr/bin/diffmerge
[merge-tools]
diffmerge.executable=/usr/bin/diffmerge
diffmerge.args= --result=$output -t1="Local Version" -t2=$output -t3="Other Version" --caption=$output $local $base $other
diffmerge.binary=False
diffmerge.symlinks=False
diffmerge.gui=True
diffmerge.premerge=True
I suppose you mean you're using SourceGear DiffMerge as external merge tool. What's your .hgrc? Is it based on the sample from hg website?
My guess is that your diffmerge.args is problematic. You can try running diffmerge manually with those arguments to make sure it works.
With your .hgrc it's clear now. Your command hg diffmerge -r 32 -r 30 myfile is NOT a merge command, instead you're asking hg to use diffmerge as the external diff tool (specified in [extdiff] section) to compare myfile between version 32 and 30. There's not a 3rd version involved.
For merge you run hg merge [-r<the other head>], and since your .hgrc tells hg to use diffmerge as merge tool (specified in [ui] section) hg will use diffmerge for the 3-way merge. I verified that it works in my Windows setup with identical hgrc.
I have a platform neutral mercurial code repo called "Simulator"
and want to apply patches that target specific platform's optimizations before a build.
According to the guide we can accomplish this by the use of patches with guards.
Windows Experimental.patch +windows
Unix Experimental.patch +unix
Mac Experimental.patch +mac
However its starting to get cumbersome because our patch queue contains 100+ patches named like windows-memory-optimization.patch +windows, unix-memory-optimization.patch +unix, windows-io-experimental-bug-fix.patch +windows, etc etc. We organized it as groups in the series file, but the file is getting huge and using qseries / qapplied is getting unmanageable
Instead we would like to have a queue for windows, unix and mac.
So that patches can be organized as:
Windows Patch Stack: memory-opt.patch, io-opt.patch, etc
Unix Patch Stack: disk.patch, graphics.patch, etc
Mac Patch Stack: io-fix.patch, io-opt.patch, experimental.patch, etc
Then swap the patch stacks for each platform in and out of the simulator repo. So that I can work on the windows patch stack and pop/push various subsystem optimization patches and work on them independently of the unix or mac patch stacks.
It does not look like I can do that, other than making 3 different repos specific to the each platform and maintaining the patch stacks that way.
Is there a way to, other than manually copying the .hg/patches directory in and out of the repo, to accomplish "swapping" patch stacks?
Interesting use of Mercurial Queues :)
I assume here that you are already versioning your mercurial queues somewhere. If you don't/for those that don't know how to do this, have a look at the relevant section from the hgbook: it's a great way to collaborate/save incrementally your work without applying the patches.
Three named branches
It should be possible to maintain three different named branches, one for each platform, in your MQ repository.
To switch platform, just switch the active branch.
(with alias mq='hg -R $(hg root)/.hg/patches')
First create a windows branch:
$ mq branch windows
marked working directory as branch windows
created, but not yet committed.
Do some stuff, add patches:
$ hg qnew windowspatch
... do some stuff
Refresh, pop and commit:
$ hg qref
$ hg qpop -a
$ mq ci -m 'new windows branch'
You now have the default branch and the new windows branch:
$ mq branches
windows 65:5fd4ef0b96c9
default 64:06c1a56a3c08 (inactive)
Now create an Unix branch.
First switch back to the base default branch:
$ mq up default
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
Create a new unix branch and add a unix-specific patch:
$ mq branch unix
marked working directory as branch unix
$ hg qnew unixpatch
... blahblah
$ hg qref
$ hg qpop -a
$ mq ci -m 'adding unix branch'
$ mq branches
unix 66:c51bb2c7b413
windows 65:5fd4ef0b96c9
default 64:06c1a56a3c08 (inactive)
Usage
Don't forget to qpop -a before operating on the mq repos...
Push all the windows patches
$ mq up windows
xx files updated, yy files merged, zz files removed, ww files unresolved
$ hg qpush -a
Three physical repos
Maintaining three separate (mercurial queue) branches can look a bit scary. If so, you can just use three different MQ repositories: one for each platform, each of them versioned in a different place.
For example :
$ cd mqs
$ hg qclone mq-windows windows
$ hg qclone mq-unix unix
$ hg qclone mq-mac mac
To work on different platforms, just switch folders (repos). The concept is similar to the first approach. But instead of having three internal branches in one MQ repo, you use three separate MQ repos.
To make an equivalent Windows alias for "mq", create a batch file in the same directory as "hg.exe" (e.g., "C:\Program Files\TortoiseHg"), name it "mq.cmd", and paste this code:
#echo off
FOR /F "tokens=1 delims=" %%A in ('hg root') do SET hgRoot=%%A
hg -R %hgRoot%/.hg/patches %1 %2 %3 %4 %5 %6 %7 %8 %9
I know this question is old, but may be someone could be interested to know there's another solution. I think this wasn't possible at the time the question got asked, but here it is more info regarding this situation: Multiple Patch Queues on MQ