Version 5 (modified by hvr, 4 years ago) (diff)

add subsection about push-urls

This page as well as the GitRepoReorganization are still work in progress.

See #8545 for the current state of affairs.

Workflows for Handling GHC's Git Submodules

General information about Git's submodule support:

Cloning a fresh GHC source tree

Initial cloning of GHC HEAD (into the folder ./ghc) is a simple as:

git clone --recursive git://

(Obviously, the clone URL can be replaced by any of the supported ghc.git URLs as listed on

Cloning a specific branch, e.g. ghc-7.8; or a specific tag, e.g. ghc-7.8.1-release:

git clone -b ghc-7.8 --recursive git:// ghc-7.8.x
git clone -b ghc-7.8.1-release --recursive git:// ghc-7.8.1

Older tags/branches which were not fully converted into a submodule-configuration, will require an additional ./sync-all get step to synchronize.

Moreover, when cloning from the GitHub GHC Mirror, the submodule url paths need to be rewritten, e.g. ../packages/deepseq.git to ../packages-deepseq.git, so you can't simply use --recursive.

Overriding push-urls

This subsection is only relevant for developers with git push-permissions.

Unless the GHC source tree was cloned from ssh://, the resulting pushurls will not point to a writable location.

The following commands will configure appropriate push-urls for ghc.git and all its submodules:

git remote set-url --push origin ssh://

git submodule foreach 'git remote set-url --push origin \
  ssh://$(git config -f $toplevel/.gitmodules --path "submodule.$name.url" | sed 's,^\.\./,,')'

Updating an existing GHC source tree clone

At the top-level of ghc.git working copy:

git pull --rebase
git submodule update --init

Making changes to GHC submodules

It's very important to keep in mind that Git submodules track commits (i.e. not branches!) to avoid getting confused. Therefore, git submodule update will result in submodules having checked out a so-called detached HEAD.

So, in order to make change to a submodule you can either work directly on the detached HEAD, or checkout the respective branch the commit is supposed to be pointed at from. The example below will demonstrate the latter approach for the utils/haddock submodule:

# do this *before* making changes to the submodule
cd utils/haddock
git checkout master
git pull --rebase

# perform modifications and as many `git {add,rm,commit}`s as you deem necessary
$EDITOR src/somefile.hs

# finally, after you're ready to publish your changes, simply push the changes as for an ordinary Git repo
git push

# go back to ghc.git top-level
cd ../..

At this point, the remote haddock.git contains newer commits in the master branch, which still need to be registered with ghc.git:

# if you want, you can inspect with `git submodule` and/or `git status`
# if there are submodules needing attention;
# specifically, the commands below should report new commits in `util/haddock`
git submodule
git submodule summary
git status

# Register the submodule update for the next `git commit` as you would any other file
# Note: You can think of submodule-references as virtual files which 
#       contain a SHA1 string pointing to the submodule's commit.
git add util/haddock

# you can also add other changes in `ghc.git` (e.g. testsuite changes) and/or other submodules 
# you need to update atomically with the next commit
git add testsuite/...

# prepare a commit, and make sure to mention the string `submodule` in the commit message
git commit -m 'update haddock submodule ... blablabla'

# finally, push the commit to the remote `ghc.git` repo
git push

There are server-side validation hooks in place to make sure for non-wip/ branches that ghc.git never points to non-existing commits. Also, as a safe-guard against accidental submodule reference updates, the string submodule must occur somewhere in commit messages of commits updating submodule references.


  • Describe how to make use of git submodule update --remote