git-pr-chain
is an opinionated tool that manages dependent GitHub pull
requests.
Using git-pr-chain
you will be able to:
- ✅ Create multiple Github PRs with one local git branch (each with one or more commits)
- ✅ Include the list of depedent PRs in the PR summary automatically
- ✅ Rebase all PRs on top of the latest changes with one command
- ✅ Update all PRs with one one command
git-pr-chain
works if you use a rebase/rewrite-history workflow locally, i.e.
when you want to get new changes from upstream, you rebase onto the new master
rather than merging master into your branch. The tool has no opinion on how PRs
should be landed -- you can merge them or rebase and commit them with or
without squashing.
To use git-pr-chain
, create a branch with linear history (i.e. no merges).
From this branch we'll create a chain of dependent pull requests. Each PR
contains one or more commits in your branch; you annotate the commits' commit
messages with git-pr-chain: foo
to indicate which commits belong to which PRs.
git-pr-chain
takes care of creating new PRs and updating existing ones when
you
- add or remove commits,
- rewrite history to modify a commit,
- rewrite history to reorder PRs, or
- merge a PR (and thus lose a PR in your chain).
$ touch foo && git add foo
$ git commit -m "Add foo"
$ git-pr-chain new
$ echo "blah blah" > foo
$ git commit -a -m "Update foo"
# You can also add the git-pr-chain annotation to the commit message yourself
$ touch bar && git add bar
$ git commit -m "Add bar\ngit-pr-chain: add-bar"
# We need to know what "upstream" is.
$ git branch --set-upstream-to origin/master
$ git-pr-chain show
Current branch is downstream from origin/master, 3 commit(s) ahead.
Github branch add-foo
5bc1c5f Add foo
c58163a Update foo
Github branch add-bar
be6db17 (HEAD -> test) Add bar
$ git-pr-chain push
# Creates two PRs
# - one for the two commits in add-foo, and
# - one for add-bar
$ git-pr-chain merge --merge-method=rebase
# Merges "add-foo" (equivalent of clicking "merge" button on github)
Follow these steps before using git-pr-chain.
Sorry, I haven't bothered to learn how to do Python packaging, so you have to do this yourself.
$ pip install pyyaml pygithub
Note that it's pygithub
and not github
. That's a different package that
doesn't work. :)
git-pr-chain
reads your github oauth token from
gh
, because oauth is hard. So you'll need to
sign in to github with that tool.
Clone the repo and set it up as an executable
$ git clone git@github.com:jlebar/git-pr-chain.git
$ ln -s /path/to/git-pr-chain/git-pr-chain.py /usr/local/bin/git-pr-chain
Run git-pr-chain
to see available commands. Currently, the following commands are supported
log List commits in chain
new Mark HEAD as starting a new PR in the chain
end-chain Add a commit to mark the end of the chain. No commits beyond this point will be uploaded to github.
push Create and update PRs in github
merge Merge one (default) or more PRs (not yet implemented)
-
If the
git-pr-chain:
annotation is missing, the commit will live on the same branch as the previous commit. (The second commit in the example above takes advantage of this.) -
If any commit message contains the string
git-pr-chain: STOP
, it and all further commits will not be pushed. -
git-pr-chain
adds info about the whole chain to each PR's description, but it won't (or, shouldn't!) overwrite changes you make to the PR outside of its<git-pr-chain>
section. -
You can add following config to add a prefix to the branches created by git-pr-chain
~/.gitconfig
:[pr-chain] branch-prefix = "something/"
This way if you have a commit with
git-pr-chain: foo
, it will correspond to a remote branch namedsomething/foo
. Consider setting it to your username. -
You can write
GPC:
instead ofgit-pr-chain:
in commit messages, if you like.
-
At the moment you need to
pip3 install pyyaml PyGithub
, because I don't understand Python packaging. -
Your branches can't live in a fork; they must live in the same repo you're trying to push to (and therefore you must have permission to create branches in that repo). This is a limitation of github, as far as I can tell. Let me know if you know how to work around it.
-
If you merge many PRs in quick succession, Travis/CircleCI won't be able to keep up with the rapidly-changing branch bases and may send you many "build failed" emails. CircleCI's seems to be less noisy in this failure mode than Travis; with Travis I once memorably got
O(n^2)
emails for a 20-PR chain.
I don't.
You can; the tool only requires that your local history has no merges.
- Make this a proper Python package, and make an executable that doesn't end in
.py
. - Write tests. I'm sure my code has no bugs. :)
- If this catches on, move into https://jazzband.co/?
git-pr-chain is inspired by git-pr-train and git-chain, and a tool written by @mina86.