2.4. Dealing With Patches

Although you can pull changes directly from other people’s repositories too, and this may the best way to handle very large external contributions such as reintegrating forks, generally external contributions are still handled via patches. There’s a difference between patches in Mercurial and patches for Subversion or CVS though, because patches in centralised systems are always a one-shot deal of a working copy compared against a single upstream version. In Mercurial, because contributors can commit locally, patches are actually exported changesets, with a full commit history. This fine grained change information can make patches easier to integrate, but it also comes with some added considerations. We’ll talk about generating and consuming patches in this section.

Applying patches is also fairly simple in itself, but there are a couple of nuances. Here’s the standard command:

hg import PATCH_FILES...

It doesn’t matter whether the patch file is in GNU style or Git style, it will work either way. But it’s important to understand what this does - each patch file (usually) contains a single commit, and those commits are applied on top of your current repository, on to your current branch. Unlike a patch for Subversion, which applies to your working copy which you then need to commit, this actually transfers commits directly, including the original author names & emails.

[Note]Note

Well, at least it tries to preserve the author & commit message, if the patch was generated from a commit using hg export. If alternatively the patch was generated from hg diff in a working copy, or the header was chopped off by someone before submission, then actually hg import will bring up your editor and asks you to provide a new commit message (and will commit it under your own name).

[Tip]Tip

If you would prefer to just import the patch into your working copy rather than as a commit, use "hg import --no-commit PATCH_FILES…"

Because it tries to apply the commits in the patch to the current base, failures are possible if conflicting changes have occurred. In this case, hg import just aborts. A good way to deal with this is to use the --exact parameter, which then applies the changes to the revision that is listed as the base in the patch file (which should therefore always succeed unless the patch is broken). This will create one or more new heads on the branch in question which you should then merge or rebase into your own branch, resolving the conflicts as appropriate. See Parallel Development for more information.