Formatting C++ Code With clang-format

Mozilla uses the Google coding style for whitespace, which is enforced using clang-format. A specific version of the binary will be installed when ./mach clang-format or ./mach bootstrap are run. We build our own binaries and update them as needed.

Options are explicitly defined in clang-format itself. If the options are changed in clang upstream, this might cause some changes in the Firefox tree. For this reason, it is best to use the mozilla-provided binaries.

Manual formatting

We provide a mach subcommand for running clang-format from the command-line. This wrapper handles ensuring the correct version of clang-format is installed and run.

If clang-format isn’t installed, the binaries will be automatically downloaded from taskcluster and installed into ~/.mozbuild. We build our own clang-format binaries.

Formatting local changes

$ ./mach clang-format

When run without arguments, it will run on a local diff. This could miss some reformatting (for example, when blocks are touched). (dxr)

Formatting specific paths

$ ./mach clang-format -p <path>     # Format <path> in-place
$ ./mach clang-format -p <path> -s  # Show changes

The command also accepts a -p argument to reformat a specific directory or file, and a -s flag to show the changes instead of applying them to the working directory (dxr)

Formatting specific commits / revisions

$ ./mach clang-format -c HEAD # Format a single git commit
$ ./mach clang-format -c HEAD~~..HEAD # Format a range of git commits
$ ./mach clang-format -c . # Format a single mercurial revision

The command accepts a -c argument that takes a revision number or commit range, and will format the lines modified by those commits.

Scripting Clang-Format

Clang format expects that the path being passed to it is the path on-disk. If this is not the case, for example when formatting a temporary file, the "real" path must be specified. This can be done with the --assume-filename <path> argument.

Configuring the clang-format commit hook

To run clang-format at commit phase, run mach boostrap or just add the following line in the hgrc file:

clang-format = ~/.mozbuild/version-control-tools/hgext/clang-format

We use a hg extension as they are more flexible than hooks.

With git, the configuration is the following:

# From the root git directory:
$ ln -s $(pwd)/tools/lint/ .git/hooks/pre-commit

You'll likely need to install the python-hglib package for your OS, or else you may get errors like abort: No module named hglib.client! when you try to commit.

Editor integration

It is possible to configure many editors to support running clang-format automatically on save, or when run from within the editor.

Editor plugins


These tools generally run clang-format themselves, and won't use ./mach clang-format. The binary installed by our tooling will be located at ~/.mozbuild/clang-tools/clang-tidy/bin/clang-format.

You typically shouldn't need to specify any other special configuration in your editor besides the clang-format binary. Most of the configuration that clang-format relies on for formatting is stored inside our source tree. More specifically, using the .clang-format file located in the root of the repository. Please note that this doesn't include the list of ignored files and directories (provided by .clang-format-ignore which is a feature provided by the mach command wrapper).


Coding style configuration is done within clang-format itself. When we change the configuration (incorrect configuration, new feature in clang, etc), we use local overrides.

Ignored files & directories

We maintain a list of ignored directories and files, which is used by ./mach clang-format. This is generally only used for code broken by clang-format, and third-party code.

Ignored code hunks

Sections of code may have formatting disabled using comments. If a section must not be formatted, the following comments will disable the reformat:

// clang-format off
my code which should not be reformated
// clang-format on

You can find an example of code not formatted.

Merging formatted and unformatted code

During the transition to using chromium style enforced by clang-format for all code in tree, it will often be necessary to rebase non-formatted code onto a formatted tree.


The format-source extension, now bundled with version-control-tools, and installed by ./mach bootstrap, may be used to seamlessly handle this situation. More details may be found in this document.

The parent changeset of the reformat has been tagged as PRE_TREEWIDE_CLANG_FORMAT.


To perform a rebase onto mozilla-central after the merge, a handy merge driver, clang-format-merge, has been written:

$ git clone
$ /path/to/clang-format-merge/git-wrapper rebase <upstream>

The wrapper should clean up after itself, and the clone may be deleted after the rebase is complete.

Ignore lists

To make sure that the blame/annotate features of Mercurial or git aren't affected. Two files are maintained to keep track of the reformatting commits.


The list is stored in
Commit messages should also contain the string # ignore-this-changeset

The syntax in this file is generated using the following syntax:

$ hg log --template '{node} - {author|person} - {desc|strip|firstline}\n'


The list is stored in and contains git revisions for both gecko-dev and the git cinnabar repository.