Site building and maintenance

Blog. Development. Mercurial: commits and merge


This article is for the beginners, I will try to explain some tricky moments (assuming that all basic things are already in mind) of work in HG.

When you work with a repository alone, as a rule, there aren’t any problems. Misunderstandings occur when the repository is used by 2 persons or more. Visual software - TortoiseHg, for instance, adds mess. People want to press a single button and have everything done. Here we’ve got a lot of buttons with easy-to-understand functional meaning.

That’s why I strongly recommend to start studying HG with the console.

The most dramatical thing you’re to understand: HG is a decentralized version control system. At any specific time there are at least two fully working repositories: one on a remote server and a local one in the project folder. All changes are first done in the local repository. To update the server one, you need to make some extra steps.

So, the working process starts.
Once you’re at work, we start working and run the command in the console in the project directory (I assume, that the project already exists and the evening before you accurately loaded everything to the server):

hg pull -u

With the command hg pull we update our local repository from the server (only repository! the project files aren’t touched). The flag -u is responsible for project files update. All this is done in case of any changes in the code were implemented.

Now we actually start working: write the code and once every logic unit is completed, we commit it (and immediately comment):

hg commit -m "Fixed error #58"

With this command we fixed code changes in the local repository. Another developers don’t have access to your changes yet! They are saved only at your local repository.

By the end of the working day we have a local repository with several commits into it.
Now we should send all our treasures to a remote server to make our changes available to other developers. Let’s run a command:

hg push

With this command we send all the changes from the local repository to the remote one. If there weren’t any changes in the remote repository since the morning - everything works smoothly.

But we’ll overview a case with a conflict. That’s why in response we receive:

pushing to ...
searching for changes
abort: push creates new remote heads on branch 'default'!
(you should pull and merge or use push -f to force)

Don’t be afraid of this message - this only means that some changes were done in the remote repository and we have to update our local one and merge our changes with other developers’.
For this we run:

hg pull

With this command we update a local repository from the remote one. We get the message:

pulling from ...
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

   Now we’re having an interesting situation - there are 2 branches. The first branch contains the changes from the server, the second one - our changes.
But we have to turn those 2 branches into one, which will contain all the changes. For this we run the command:

hg merge

And if the mergence was conflict-free - we get the code of the project with all the changes applied.
We must commit all these changes:

hg commit -m "Mergence"

And push them to the server:

hg push

If the mergence had some conflicts - then you’ll see three versions of the conflict file. This window usually overhelms all the beginners :)
If the window doesn’t open, then the merging tool might not be configured or installed. I recommend to set up and configure it - you’ll find lots of articles on the topic in the Internet.

There are a lot of merging tools, I won’t rest on a particular one, just let me tell about the common principles.
All of them differ in appearance, management, some of them are remarkable by their flaws (in-built merging tool in NetBeans 6.9.1 drives me mad by its inconvenience, that’s why I am using meld).

So, you can see there versions of the file: local, base, remote (some have the forth version - merged). That’s BASE/MERGED which knocks everybody out.

Let me decode what that all means:
LOCAL is the file with your changes,
REMOTE is the file from the server,
BASE the original file, which was not changed, was attempted to be changed (locally or from the server). 

Here we approach to a very delicate issue. As I said above - we have two branches. In this case both branches are anonimous, that means they don’t have a name and they were formed because of the conflict. That’s why we apply all the changes to the file LOCAL - that means, to our current project.

I can’t say how exactly you can solve the conflict - here you should use your own head and decide how to modify the code, to keep all the changes in the resulting file.

We check and fix all the conflicts, then save and quit the program.

After all the fixes are done, we check the working capacity of the code (it’s important, if the changes weren’t obvious). After that we commit our mergence and push it to the server by commands:

hg commit -m "Mergence"
hg push

The working day is over, we can go home with a clear conscience. Many thanks to all of you!