Adding functionality with extensions#
While the core of Mercurial is quite complete from a functionality standpoint, it’s deliberately shorn of fancy features. This approach of preserving simplicity keeps the software easy to deal with for both maintainers and users.
However, Mercurial doesn’t box you in with an inflexible command set: you can add features to it as extensions (sometimes known as plugins). We’ve already discussed a few of these extensions in earlier chapters.
Simplifying the pull-merge-commit sequence covers the
fetch
extension; this combines pulling new changes and merging them with local changes into a single command,fetch
.In Handling repository events with hooks, we covered several extensions that are useful for hook-related functionality:
acl
adds access control lists;bugzilla
adds integration with the Bugzilla bug tracking system; andnotify
sends notification emails on new changes.
In this chapter, we’ll cover some of the other extensions that are available for Mercurial, and briefly touch on some of the machinery you’ll need to know about if you want to write an extension of your own.
Flexible diff support with the extdiff
extension#
Mercurial’s built-in hg diff
command outputs plaintext unified diffs.
Show code cell content
export HGRCPATH=$PWD/../hgrc4book
mkdir -p /tmp/tmp_mercurial_book
cd /tmp/tmp_mercurial_book
rm -rf /tmp/tmp_mercurial_book/*
hg init a
cd a
echo 'The first line.' > myfile
hg ci -Ama
echo 'The second line.' >> myfile
adding myfile
hg diff
diff --git a/myfile b/myfile
--- a/myfile
+++ b/myfile
@@ -1,1 +1,2 @@
The first line.
+The second line.
If you would like to use an external tool to display modifications, you’ll want to
use the extdiff
extension. This will let you use, for example, a graphical diff
tool.
The extdiff
extension is bundled with Mercurial, so it’s easy to set up. In the
extensions
section of your ~/.hgrc
, simply add a one-line entry to enable the
extension.
[extensions]
extdiff =
This introduces a command named extdiff
, which by default uses your system’s
diff
command to generate a unified diff in the same form as the built-in
hg diff
command.
hg extdiff
--- /tmp/extdiff.fv9pl0bd/a.e5f03160e083/myfile 2023-09-13 16:14:19.000000000 +0000
+++ /tmp/tmp_mercurial_book/a/myfile 2023-09-13 16:14:19.622110730 +0000
@@ -1 +1,2 @@
The first line.
+The second line.
The result won’t be exactly the same as with the built-in hg diff
variations,
because the output of diff
varies from one system to another, even when passed
the same options.
As the “making snapshot
” lines of output above imply, the extdiff
command
works by creating two snapshots of your source tree. The first snapshot is of the
source revision; the second, of the target revision or working directory. The
extdiff
command generates these snapshots in a temporary directory, passes the
name of each directory to an external diff viewer, then deletes the temporary
directory. For efficiency, it only snapshots the directories and files that have
changed between the two revisions.
Snapshot directory names have the same base name as your repository. If your
repository path is /quux/bar/foo
, then foo
will be the name of each snapshot
directory. Each snapshot directory name has its changeset ID appended, if
appropriate. If a snapshot is of revision a631aca1083f
, the directory will be
named foo.a631aca1083f
. A snapshot of the working directory won’t have a
changeset ID appended, so it would just be foo
in this example. To see what this
looks like in practice, look again at the extdiff
example above. Notice that the
diff has the snapshot directory names embedded in its header.
The extdiff
command accepts two important options. The hg -p
option lets you
choose a program to view differences with, instead of diff
. With the hg -o
option, you can change the options that extdiff
passes to the program (by
default, these options are “-Npru
”, which only make sense if you’re running
diff
). In other respects, the extdiff
command acts similarly to the built-in
hg diff
command: you use the same option names, syntax, and arguments to specify
the revisions you want, the files you want, and so on.
As an example, here’s how to run the normal system diff
command, getting it to
generate context diffs (using the -c
option) instead of unified diffs, and five
lines of context instead of the default three (passing 5
as the argument to the
-C
option).
hg extdiff -o -NprcC5
*** /tmp/extdiff.k_riuzs7/a.e5f03160e083/myfile 2023-09-13 16:14:19.000000000 +0000
--- /tmp/tmp_mercurial_book/a/myfile 2023-09-13 16:14:19.622110730 +0000
***************
*** 1 ****
--- 1,2 ----
The first line.
+ The second line.