---
jupytext:
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
    jupytext_version: 1.11.5
kernelspec:
  display_name: Bash
  language: bash
  name: bash
---

# 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.

- {ref}`sec-tour-merge-fetch` covers the `fetch` extension; this combines pulling
  new changes and merging them with local changes into a single command, `fetch`.

- In [](../advanced-concepts/hook.md), 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; and `notify`
  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.

(sec-hgext-extdiff)=

## Flexible diff support with the `extdiff` extension

Mercurial's built-in `hg diff` command outputs plaintext unified diffs.

```{code-cell}
---
tags: [hide-cell]
---
export HGRCPATH=$PWD/../hgrc4book
mkdir -p /tmp/tmp_mercurial_book
cd /tmp/tmp_mercurial_book
rm -rf /tmp/tmp_mercurial_book/*
```

```{code-cell}
hg init a
cd a
echo 'The first line.' > myfile
hg ci -Ama
echo 'The second line.' >> myfile
```

```{code-cell}
hg diff
```

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.

```{code-cell}
---
tags: [raises-exception]
---
hg extdiff
```

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).

```{code-cell}
---
tags: [raises-exception]
---
hg extdiff -o -NprcC5
```
