Skip to content

Instantly share code, notes, and snippets.

@nh2
Created January 16, 2020 17:40
Show Gist options
  • Save nh2/64c78a7e7eb8f3905678406b99d9d02e to your computer and use it in GitHub Desktop.
Save nh2/64c78a7e7eb8f3905678406b99d9d02e to your computer and use it in GitHub Desktop.
Haskell: Type-checking a git history of commits fast with interactive rebasing and ghci -e

Type-checking your whole Pull Request before submission

You want to make a pull request to a Haskell project, which requires that each commit in your PR compiles fine individually.

Here is an easy, automated and fast way to check it:

git rebase --interactive HEAD~~~ --exec "! grep 'error:' <(stack ghci mylibrary:lib --ghci-options='-e 1' 2>&1)"

Replace mylibrary:lib to put your Haskell package's name in. You can also give other targets like executables (see stack ide targets output).

Replace HEAD~~~ by how many commits you want to go back in history (this goes back 3).

If your Haskell project is in a subdirectory of your git repository, insert a cd like this: ... --exec 'cd subdirectory && ! grep ...

Explanation

  • git rebase --interactive allows you to go through the commit history of your branch and perform actions at each step.
  • One possible action is to run a command; --exec puts the given command after each commit.
  • The invocation above will pop up you editor to show what will be done; save and close that file to start the process. To abort at any time, use git rebase --abort.
  • We use ghci's -e option to evaluate a simple expression (like -e 1 to evaluate the number 1) after all modules have been typechecked. This ensures ghci quits by itself after successful typechecking.
  • We use grep as the command, searchin for error: messages in the ghci output (with 2>&1 redirecting stderr to stdout so we can grep that too).
  • If there's a typechecking error, the interactive rebase will drop you in a shell at that commit, so you can fix it.
  • Read the tutorials on interactive rebasing from git ready or from the Git book to learn how exactly interactive rebasing works.
@neilmayhew
Copy link

I just discovered you can omit --interactive and then it doesn't bring up the initial editor.

Also, you could use HEAD~N (where N is an integer) to go back further in history without having to add N tildes. Alternatively, you can use something like master@{u}.. if your PR is targetting the upstream of master.

@nh2
Copy link
Author

nh2 commented Feb 5, 2020

👍

@nh2
Copy link
Author

nh2 commented Jun 13, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment