I have two machines, window 7 with TortoiseHG 2.6 and Linux with TortoiseHG 1.5. I use bitbucket as a website to hold my centralized repository. The window machine associates with bitbucket user account, Cassie-win and the linux machine associates with bitbucket user account, Cassie-linux. Here are the steps I have performed.
created a empty centralized repository at butbucket Cassie-linux account
create two files locally, file1.txt and file2.txt on linux machines and push them to the Cassie-linux account.
Add user Cassie-win to the repository
Clone the repository to the window machine, make changes on file2.txt there and push it back to the centralized repository.
Meanwhile, also make some changes on the file2.txt which is on the linux machine and commit locally
Then I pull changes from the centralized repository at Cassie-linux account to my local linux machine. Now my linux local repository has two heads because of different contents in file2.txt and I would like to merge them together.
I used the "merge with" tool of TortoiseHG on my linux machine to merge these two heads. However, it kept failing to do so. I tried like a hundreds times and didn't know where I got it wrong. Both file1 and file2 are test files that have only three lines. I also used a command "hg resolve file2.txt" to check the error. However, it only showed that mergeing fails and didn't shown much information. Does anyone know how to use TortoiseHG merge tool to merge two heads ? And what could be the problem to stop TortoiseHG merging two heads ?
I embedded the screenshot which I took on the Linux machine which has TortoiseHg 1.5.
I right clicked the "from Cassie-win account" and it has "merge with" option. Then, I clicked the "merge" option with "merge" tool but it failed with error messages as below.
Thank you very much,
By "merge with" in TortoiseHg, do you mean you tried "Merge with Local" from the context menu of one head after updating your working directory to the other head? If so, you should have seen a wizard taking you through the steps of a merge. TortoiseHg will expect you to intervene if it cannot automatically merge the two heads. Once it asks you to do that, you have a few options including "Mercurial Resolve" and "Tool Resolve."
If you could post more details about the errors you see when the merge "fails," we might be able to be more helpful.
First things first: A merge just creates a new file version. You must commit it before it can be seen or pushed to your other repo clones.
Now, if you're doing a merge and the same line, or adjacent lines, have been modified in both merge parents, the automatic merge won't succeed and you'll be asked to choose what to do at each conflict point. Kdiff3, the tool that TortoiseHG uses for merging the files on Windows is not terribly intuitive, so here's an overview:
If there are multiple files to merge, you'll see a directory control. Navigate to one of the files and open it so you see two file versions side by side.
Depending on the circumstances, you may now have to activate "Merge this file" (in the Merge menu and on the toolbar), which will show you a third version of the file (the merge result) below the other two.
You can now navigate from change to change, and click on the A and B buttons to select which change to use. Note that the buttons are toggles, and it is possible to activate both together (to import both versions to the merge). Note also that you'll also see diffs that could be automatically merged. In general you can leave them alone (there are navigation buttons that go directly to the next unresolved diff).
Once you've figured out how to work all this and chosen a version for each diff, you'll be able to save and go on to the next file. When you're done, your merge is ready to commit.
Edit:
So you need to do this on the Linux side, and you've got no Kdiff3. Ok, then do it the old-fashioned way: Using the commandline and a regular editor.
When a merge fails, the conflicted file turns into a context diff that includes both revisions. Open it with your favorite editor, look at it carefully and clean up each context-diff region (you'll know them when you see them) until you have a clean, usable file just as you want it to be.
Exit, drop to the command line and type hg resolve -m file2.txt. This removes the file from the list of conflicts.
When you've done this with all conflicted files (you can list them with hg resolve -l) you'll be allowed to commit, and your troubles are over.
PS. If you don't like the merge tools you've got, consider installing kdiff3 (it's available for linux, but no idea how well it works), or p4merge as #LazyBadger suggests.
Side notes
You can exchange data between your hosts without "Bitbucket-in-the-middle": just hg serve on both hosts and hg pull <PARTY> on opposite side
You could use single BB-account from both our hosts (less management on BB-side) and differentiate source of every changeset in Bitbucket interface only by usernames in changesets
To the question of merges
When (in any SCM) you try to merge two diverged lines of coding, there are two possible cases
Independent changes are not overlapped and can be combined into common descendant without user's intervention. If this case merge "just happens"
Changes are intersected and some strings are in conflicted state: i.e we have two different changes for some old data. It this case user's choice is needed and SCM or store merge-result with conflicted parts marked (and note merge as unsucceful and unfinished before appropriate user-action) or run user-defined merge-resolver (read "Visual Merge Tools")
In your situation, obviously, he have second case: some strings from 3 in merge-sources was in conflict and you haven't configured in TortoiseHG Diff/Merge tools (TortoiseHG - Global Setting - TortoiseHG)
Have and add these tools will be best choice for future. Now you have by hand edit file-in-conflict and select correct data in conflicted lines, mark conflict as resolved (check TortoiseHG context menu of file), remove temp-files and, at last, commit merge
Related
I use Tortoise Mercurial tool to manage my mercurial repository.
And I have a separate .diff file containin0g changes to a file in my repository.
Is there any way how to use that diff to update my file ?
thank you
Most Linux repositories comes with the patch program. You can then execute:
patch original.data difference.diff
Patch will modify the original.data file in such a way that if one would calculate the diff between the final and original state, one gets the same difference.diff again.
.diff files are in general not visible in a subversioning respository. They are stored internally to hide the several commits from the user. Diffs however can be usefull to analyze the difference between two commits. Say for instance somebody worked on your project and made a lot of commits, you might want to inspect what that person actually did without having to read the reports of all commits (since some changes can be undone in the next commit)
Mercurial docs about what mercurial does when it has to do a 3way merge:
By default, Mercurial will attempt to do a classic 3-way merge on text
files internally before trying to use an external tool.
When it invokes the external tool, that is always a "manual merge".
Not all merge tools are created equally, and as it turns out my merge tool of choice (Araxis Merge), is often able to do an automatic merge of 3 files, where mercurial's internal merge tool was not able to do so.
This leads to the scenario of big merges where maybe a bunch of files merge cleanly, done by hg's internal mergetool, and then some other files do not merge cleanly but could have if hg would let me specify its mergetool. I find this to make big merges very inefficient, as you need to context switch a lot: hg pops up my merge tool, I think "oh darn, conflict", to then realize "oh wait, theres no conflict at all"
I wonder if I'm missing something here, or if there is really no way to make hg able to use a custom merge tool for its automatic attempts at doing merges.
I think you're looking for a switch to make Araxis Merge close itself automatically if it can auto-merge. I looked at the command line reference and their SCM integration document, but I'm actually not sure what switch it would be. You'll have to experiment yourself.
From Mercurial's point of view there is no such thing as a "manual merge". Mercurial tries to merge internally first (the so-called "premerge" step) and if that fails it looks for an external tool. The merge can still be fully automatic if that tool exists with an exit code of zero (successful exit). Mercurial will then consider the merge successful and go on to the next file. Depending on the tool, you wont notice this at all: Mercurial just runs the tool in the background and you're only prompted for action when there is a serious merge conflict.
You can use a custom merge tool with Mercurial. help merge-tools shows the order in which tools are chosen to run:
1. If a tool has been specified with the --tool option to merge or
resolve, it is used. If it is the name of a tool in the merge-tools
configuration, its configuration is used. Otherwise the specified tool
must be executable by the shell.
2. If the "HGMERGE" environment variable is present, its value is used and
must be executable by the shell.
3. If the filename of the file to be merged matches any of the patterns in
the merge-patterns configuration section, the first usable merge tool
corresponding to a matching pattern is used. Here, binary capabilities
of the merge tool are not considered.
4. If ui.merge is set it will be considered next. If the value is not the
name of a configured tool, the specified value is used and must be
executable by the shell. Otherwise the named tool is used if it is
usable.
5. If any usable merge tools are present in the merge-tools configuration
section, the one with the highest priority is used.
6. If a program named "hgmerge" can be found on the system, it is used -
but it will by default not be used for symlinks and binary files.
7. If the file to be merged is not binary and is not a symlink, then
"internal:merge" is used.
8. The merge of the file fails and must be resolved before commit.
More information can be found in help config - look for merge-tools and merge-patterns
Consider a Hg project with two central branches/clones - e.g. DEV and PRD. When someone pushes a hotfix to PRD, an automated script on the central server goes to DEV and pulls the new changes. It then tries to merge the hotfix into DEV.
The problem is that the merge tool integrated into Hg is terrible - as soon as there are parallel changes to the same file it will fail. Take the following example:
parent:3,7c
four
five
six
seven
child1:3,7c
four
five5
six6
seven7
child2:3,7c
fourmore
five
six
more
seven
As you can see, there are no actual conflicts here. If we do the merge locally with kdiff, it solves this simple case without user input!
I'd like a way to get the central server to manage these cases. I thought of using kdiff3 in silent mode, but I can't install kdiff3 on it (it's a CLI only system that we don't even have admin access to), but maybe there is a way to plug diff3 into hg merge so it can resolve simple cases like this? I tried setting "[ui] /n merge = diff3" in the hgrc, but it just spits out the three versions to stdout. Am i missing some additional configuration? Or is there an easier/better tool?
Thanks a lot
To use diff3 as your merge tool, you need to add
[merge-tools]
diff3.args = $local $base $other -m > $output
to your configuration file. You can set the priority if needed, see the wiki. You'll also find more complicated recipes for using diff3 there.
However, I tested how diff3 treats your scenario with edits on adjacent lines, and just like Mercurial, it also refused to merge this cleanly. Different merge tools have different thresholds for what they consider a "conflict" and it seems that KDiff3 is more forgiving than Mercurial and diff3.
I suggest that you let the developer who makes the hotfix on PRD be responsible for merging it into DEV locally where he has access to tools like KDiff3. Automated merging on a server is generally considered to be bad — merges should be verified just a little by a human before you commit them. It's not much extra work after having made the hotfix.
I'm frustrated with Mercurial and Python since it makes easy things difficult. I have a trivial conflict and since Mercurial does not give any suggestion what to do I don't know even how to resolve this trivial file conflict:
The conflict is trivial but if I can't resolve this I can't resolve anything complicated either. Can I just edit the file to a way I want and commit it again from anywhere? Should I run hg merge? Why can't Mercurial even let me choose a version to keep? Why is something trivial near impossible to do without digging through 1000 poorly written manpages?
You need to look at the KDiff3 documentation, in particular the section on merging and the output window. To resolve the conflict, you need to decide if live or january is the right choice for the line. That decision is yours to make, no tool can know if you meant one or the other.
In KDiff3, you press Ctrl + 2 to select live, press Ctrl + 3 to select january or right-click in the margin of the bottom window and select the line you want. You can also click in the bottom window and edit the line manually.
Mercurial let's you configure your merge tool any way you like. TortoiseHg ships with a default configuration that puts KDiff3 in the top of the list, but you can use another tool if you like. A merge tool is really just a program that accepts four filenames: the three files to compare (base, parent 1, parent 2) and an output file name.
To resolve conflicts on the command-line you need to launch a suitable command-line three-way merge tool. You can for example merge with vim if you like. (I'm afraid I don't know anything about vimdiff, I use KDiff3 myself.)
If you don't like to see merge tools pop up, then you can set
[ui]
merge = internal:merge
to make Mercurial use the internal three-way merger only. It will merge files fine when the edits are not in conflicts. When there is a conflict, the file is marked as "unresolved" and conflict markers are stored in the file.
You then need to edit the file by hand to get the version you want. You can also re-merge and pick either the local (your) version:
$ hg resolve --tool internal:local your-file
or the other version:
$ hg resolve --tool internal:other your-file
You restart the merge completely with hg resolve your-file. The file needs to be marked "resolved" before you can commit it. This is done with hg resolve --mark your-file. See hg resolve --list for the status of the current merge.
Base is the previous version in your local system,
Parent 1 is your current changes,
parent 2 is the file from server.
If you need your changes need to be checked in, select B everywhere in the merge menu.
If you want the latest server version in your local machine, select C everywhere in the merge menu
Because it seems like when
hg up default
or
hg up bugfix
is used in one Bash shell, then the other shell also changes to that branch automatically if an hg branch is used to show which branch it is. (so I think if it is a
Ruby on Rails server running, all of a sudden, the code will change to the other branch)
If using two separate clones, it can be done... as if there are two branches... but can be done using the branch feature of hg?
You have to use two separate clones.
Think about it. You're working on two different versions of a file. They differ in content. You have to change the file to reflect one of the two branches. How can a single file have two different contents at the same time (your two-shell idea)?
A different analogy: a shell is a window. The file is an object in the room. Even if you have two windows looking into the same room, you can't have the one object in the room be two different things at the same time. To do that, make an identical room next door, modify the object, and have the second window attached to the cloned room.
The different shells seem to be working on the same repository directory. This won't work since the directory is where the update happens and not the shell.
So you really need two repository directories i.e. clones in order to do this.
If these directories are on the same filesystem this won't cost much time or space since Mercurial optimizes this case by using hard links.
At least if you are on a operating system supporting hard links.
If by "shell" you mean two command shells open to the same directory, then yes, they both change because they are working with the same working directory.
One working directory can only ever be at one place in the repository history.
To work with two different branches or changesets in the project at the same time, make a second clone from the first, and then you can manipulate each independently.