Using git with GHC

This page will help you to use git effectively when contributing patches to GHC, and extends upon the instructions provided in getting the sources.

A single GHC git tree


See git submodules when making changes to one of the libraries or utils that have their own repository in a GHC tree.


The stable branch

The releases page has a list of stable branches.

Development branches

See ActiveBranches for a description of known development branches.

The live list of currently existing branches in the ghc repository can be browsed via

New development branches names should be prefixed with wip/ (e.g. "wip/dependent-types"), as otherwise the current Git server-side configuration disallows branch deletion and non-fast-forward updates.

Working with a separate build tree

Sometimes we want to separate the build tree from the source tree. There are a few advantages to doing this:

  • You can make multiple different builds from the same sources, perhaps for testing different build settings, or for building on different platforms.
  • You might want to put the source tree on a remote, backed-up, filesystem, but keep your build tree on a local fast unbacked-up drive (this is a configuration we use regularly at GHC HQ). It doesn't matter if you lose the build tree: it can easily be regenerated.
  • It's easy to blow away a build tree and start again, without modifying your source tree. make maintainer-clean is usually good for this too, but it can miss files that it doesn't know about, or files that are remnants from older versions of GHC.
  • It helps to avoid mistakes whereby you edit a file that happens to be automatically generated, instead of the original source file (e.g. editing instead of If you only edit files in the source tree, then this can't happen.

However, if you just want to build the software once on a single platform, then your source tree can also be your build tree, and you can skip the rest of this section.

Creating a build tree with lndir

Windows users: so far as we know, symbolic links do not work right on MSYS at least, so we never use separate source and build trees on Windows.

Mac OS X 10.8 users: Apple no longer includes X11 with Xcode (which provided lndir). Install XQuartz >= 2.7.2 or build it directly in utils/lndir (as below).

A build tree is just an exact copy of the source tree, except that every file in it is a symbolic link to the appropriate file in the source tree. There are "standard" Unix utilities that make such copies, so standard that they go by different names: lndir and mkshadowdir are two (If you don't have either, the GHC source tree contains sources for the X11 lndir check out utils/lndir). To create a separate build tree, the typical sequence is something like this:

  $ mkdir ghc-build
  $ cd ghc-build
  $ lndir <source>
  $ ln -s <source>/.git .

Where <source> is the directory containing your source tree. Note the last step: GHC's configure script likes to see the .git directory, and by default lndir will not link .git directories. Things will still work if you omit this step, but the GHC version number for your build won't contain the date (i.e. it will be "7.7" instead of something like "7.7.20121218").

You need to be a bit careful when using a build tree, that any new files you create (if you do any development work) are in the source tree, not the build tree! This is especially easy to mess up when creating new tests, so watch out.

Creating a buildtree with git-new-workdir

Since Git 2.9, `git worktree` works well enough with submodules, so that the `wtas` alias does what we want: git clone --recursive git:// pristine && cd pristine/ && git wtas ../<feature-worktree>. If you can't get it to work, read on.

I (ezyang) use Git workdirs to manage all of my GHC checkouts. It is quite nice: there is logically only one local repository, and just many checkouts of it, so it's very easy to share patches between various checkouts and your branches are all in one centralized place. However, sharing all of your submodules too takes a bit of work to setup, since Git doesn't natively support this workflow.

Here's what I do:

  1. Start by making some pristine GHC checkout (call it ghc-pristine) which is an ordinary Git clone of the main GHC repository.
  1. Remove all of the submodules that Git recursively created. This is because they are in the wrong format. You can do it with this command: for i in `git submodule status | cut -d' ' -f3`; do rm -rf $i; done
  1. Re-checkout the submodules using a normal git clone, rather than the submodule tool. This can be done with this command: for i in `git submodule status | cut -d' ' -f2`; do git clone git://`echo "$i" | sed s/libraries/packages/ | sed s/utils\\///`.git $i; done (On OS X you might have to escape the backslash two more times)
  1. Finish off the configuration by running git submodule init and git submodule update

Now, to create a new workdir, run git-new-workdir ghc-pristine ghc-newdir, and then inside ghc-newdir, run for i in `git submodule status | cut -d' ' -f2`; do rmdir $i; git-new-workdir ../ghc-pristine/$i $i; done to recursively make workdirs of all the submodules.

Creating a buildtree with git-new-workdir-recursive

This is a script to automate the steps from the previous section:

Push access

If (as a developer) you have been granted push privileges to, you need to take into account that only the ssh:// URLs support authentication (and hence git pushing to).

The following Git URL rewrite rules (which need to be configured only once as they're persisted in the ${HOME}/.gitconfig file due to --global) take care of transparently redirecting git pushes to the ssh:// Git URL counterparts:

git config --global url."ssh://".pushInsteadOf git:// 

This uses the ssh:// protocol (which has much higher latency due to the SSH handshake occurring for each connect) only for git push operations, and the very fast unauthenticated git:// protocol for everything else (if you originally cloned git://

  • If possible, commit often. This helps to avoid conflicts.

More git tips

The Git Tricks page describes some more suggestions and tips for using Git.

Last modified 2 years ago Last modified on Feb 15, 2018 1:56:52 PM