... | ... | @@ -45,26 +45,6 @@ rm -rf libraries/parallel |
|
|
git submodule update --init
|
|
|
```
|
|
|
|
|
|
|
|
|
### `git pullall`
|
|
|
|
|
|
A commonly defined Git alias that combines the two commands into one convenient Git alias is:
|
|
|
|
|
|
```
|
|
|
git config --global alias.pullall '!f(){ git pull --ff-only "$@" && git submodule update --init --recursive; }; f'
|
|
|
```
|
|
|
|
|
|
(the `--global` flag make this alias persist in the `${HOME}/.gitconfig` file, so this needs to be done only once, the `--recursive` option is not needed for GHC but it's commonly used for the `pullall` alias)
|
|
|
|
|
|
After setting this alias, one can now simply use the single invocation
|
|
|
|
|
|
```
|
|
|
git pullall --rebase
|
|
|
```
|
|
|
|
|
|
to update `ghc.git` and all its submodules.
|
|
|
|
|
|
|
|
|
## `git status` and dirty submodules
|
|
|
|
|
|
By default, git will consider your submodule as "dirty" when you do `git status` if it has any changes or any untracked files. Sometimes this can be inconvenient, especially when using [Phabricator](phabricator) which won't allow you to upload a diff if there are dirty submodules. Phabricator will let you ignore untracked files in the main GHC repo, but to ignore untracked files in a submodule you'll need a change to `.git/config` in the GHC repo. For example, to ignore untracked files in the `nofib` repo, add the line `ignore = untracked` to the section for `nofib` in `.git/config`:
|
... | ... | @@ -76,94 +56,48 @@ By default, git will consider your submodule as "dirty" when you do `git status` |
|
|
```
|
|
|
|
|
|
|
|
|
## 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](http://alblue.bandlem.com/2011/08/git-tip-of-week-detached-heads.html).
|
|
|
|
|
|
So, in order to make change to a submodule you can either:
|
|
|
## Making changes to GHC's submodules
|
|
|
|
|
|
1) Work directly on the detached HEAD in the submodule directory.
|
|
|
It's very important to keep in mind that Git submodules track commits, not branches. Therefore, `git submodule update` will result in submodules having checked out a so-called [detached HEAD](http://alblue.bandlem.com/2011/08/git-tip-of-week-detached-heads.html).
|
|
|
|
|
|
2) Checkout the respective branch the commit is supposed to be pointed at from (normally `master`. See the table on [Repositories](repositories) for the full branch/repo summary).
|
|
|
|
|
|
|
|
|
If you merely need to update a submodule to point to the latest upstream commit of that submodule, which also takes care to lookup the proper upstream Git branch (in case it's not `master`) as specified in the `.gitmodules` file.
|
|
|
For example, to update `libraries/Cabal`, you can run the following commands:
|
|
|
|
|
|
```wiki
|
|
|
git submodule update --remote libraries/Cabal
|
|
|
git commit libraries/Cabal
|
|
|
git push
|
|
|
To make a change to a submodule (here we use `Cabal` for concreteness), start by ensuring that your tree's submodules are up-to-date:
|
|
|
```bash
|
|
|
git submodule update --init
|
|
|
```
|
|
|
|
|
|
The example below will demonstrate the latter approach for the `utils/haddock` submodule:
|
|
|
|
|
|
Next, create a branch for your change, ensuring that the name contains the `wip/` prefix (it is common to name the submodule branches similarly to the GHC branch with which they are associated),
|
|
|
```bash
|
|
|
git -C libraries/Cabal checkout -b wip/$BRANCH_NAME
|
|
|
```
|
|
|
# do this *before* making changes to the submodule
|
|
|
cd utils/haddock
|
|
|
git checkout ghc-head
|
|
|
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 ../..
|
|
|
We can now proceed with making the desired changes in the submodule and commit them as usual:
|
|
|
```
|
|
|
|
|
|
At this point, the remote `haddock.git` contains newer commits in the `ghc-head` branch, which still need to be registered with `ghc.git`:
|
|
|
|
|
|
# perform modifications and as many `git {add,rm}`s as you deem necessary
|
|
|
$EDITOR libraries/Cabal/src/somefile.hs
|
|
|
# commit
|
|
|
git -C libraries/Cabal commit
|
|
|
```
|
|
|
# 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'
|
|
|
|
|
|
# for the paranoid, inspect your commit one last time, including the submodule's commit headings
|
|
|
git show --submodule
|
|
|
|
|
|
# finally, push the commit to the remote `ghc.git` repo
|
|
|
git push
|
|
|
Finally, we commit the submodule change in the `ghc` repository.
|
|
|
```bash
|
|
|
git commit
|
|
|
```
|
|
|
In the commit message be sure to mention any submodule changes made; a linter in GHC's CI process checks that any commits containing submodule changes mention the word "submodule" to prevent unintentional submodule changes from accidentally being merged.
|
|
|
|
|
|
Git supports a recursive `git push` operation. If you issue a
|
|
|
|
|
|
```wiki
|
|
|
git push --recurse-submodules=on-demand
|
|
|
To push the changes, we first push the submodule changes to the GHC mirror repository (e.g. ghc/packages/Cabal>). GHC developers have permission to push branches to these mirrors under the `wip/` branch namespace (if you see encounter a permission denied error, ask someone in `#ghc` to grant you Developer rights in the `ghc` group).
|
|
|
```bash
|
|
|
git -C libraries/Cabal remote add gitlab git@gitlab.haskell.org:ghc/packages/Cabal
|
|
|
git -C libraries/Cabal push gitlab wip/$BRANCH_NAME
|
|
|
```
|
|
|
Now create a draft merge request against the upstream projeect (e.g. <https://github.com/haskell/Cabal>) proposing to merge your branch into the branch being tracked by GHC (typically `master`).
|
|
|
|
|
|
this will cause Git to push all submodules changes that have been registered in the revisions
|
|
|
to be pushed to the super repository.
|
|
|
|
|
|
TODO show how to define a `git pushall` alias in the style of the `git pullall` alias
|
|
|
|
|
|
|
|
|
### Validation hooks
|
|
|
|
|
|
GHC's CI infrastructure includes a submodule lint job which ensures that:
|
|
|
Finally, we can push the GHC branch as well:
|
|
|
```bash
|
|
|
git push origin wip/$BRANCH_NAME
|
|
|
```
|
|
|
We can now open a GHC merge request [as usual](https://gitlab.haskell.org/ghc/ghc/-/wikis/Contributing-a-Patch#merge-request-workflow). When doing so, include a list of the associated upstream merge requests for any submodule changes made in the MR.
|
|
|
|
|
|
1. If you update a submodule pointer,
|
|
|
### Merging an MR containing submodule changes
|
|
|
|
|
|
2. You had to have pushed it upstream already,
|
|
|
When an MR containing submodule changes has passed review, it is important that any upstream submodule MRs have been merged *before* the MR is added to the merge queue. While the submodule linting job will catch any MRs which refer to submodule commits not reachable via a persistent branch (e.g. not a `wip/` branch), this will cause @marge-bot jobs to fail, stalling the merge process.
|
|
|
|
|
|
3. And you have to say the word 'submodule' in the commit.
|
|
|
|
|
|
## Upstream repositories
|
|
|
|
... | ... | @@ -172,7 +106,7 @@ Check out the [Repositories](repositories) page for a full breakdown of all the |
|
|
|
|
|
## TODO
|
|
|
|
|
|
- Describe darcs mirroring for `transformers`
|
|
|
- Sort out what to do about `transformers`
|
|
|
- Describe status of `pretty` which is one-off at the moment and doesn't exactly track upstream.
|
|
|
|
|
|
|
... | ... | @@ -192,20 +126,6 @@ To accomplish this we configure the submodule projects as follows: |
|
|
|
|
|
This ensures that commits can only be pushed to `wip/.*`, which the submodule check linter does not consider as roots.
|
|
|
|
|
|
## Testing submodule changes
|
|
|
|
|
|
The submodule references in the GHC tree pull from a set of mirrors maintained at <https://gitlab.haskell.org/ghc/packages> (except for Haddock, which is at `https://gitlab.haskell.org/ghc/haddock` directly; no `packages`). Members of the `ghc` [group](https://gitlab.haskell.org/ghc) (i.e. most GHC developers; if you are not currently a member you can request membership by clicking on the "Request Access" link at the [top of the group page](https://gitlab.haskell.org/groups/ghc)) can push branches with the prefix `wip/` to these mirrors to test their changes without merging them upstream. For instance, one might test changes in the `haddock` submodule via,
|
|
|
```
|
|
|
$ cd utils/contain
|
|
|
$ git checkout -b wip/my-changes
|
|
|
$ git remote add origin-push git@gitlab.haskell.org:ghc/haddock
|
|
|
$ git push origin-push wip/my-changes
|
|
|
```
|
|
|
One can then push a GHC branch needing `wip/my-changes` and CI will find the commits. Note, however, that this is only for testing purposing. Before the GHC branch can be merged any submodule updates much be first merged upstream.
|
|
|
|
|
|
## Merging submodule changes
|
|
|
|
|
|
The CI pipeline of GHC includes a linting step to ensure that all submodules refer only to "persistent" commits of the upstream repositories (e.g. not `wip/` branches, which may disappear in the future). Specifically, the linter checks that any submodules refer to commits that are reachable by at least one branch that doesn't begin with the prefix `wip/`. The linter is allowed to fail for merge requests but must pass in the final pipeline before the merge request is added to the merge queue.
|
|
|
|
|
|
## Submodule-specific policies
|
|
|
|
... | ... | |