The Wrong Way
Hate is a strong word, but I very much dislike Github’s PR review / approve / merge flow.
My Better Way
I don’t like merge commits. I also don’t like merging in 5+ commits with names like “wip”, “bugfix”, “trying again” on a feature add.
To avoid all of that without having a lot of back and forth, here’s my approach
-
Work from the PR branch
git remote add ...
the user/org of the PR request, locallygit checkout ...
their branch, as is
-
Rebase on the latest, and squash junk commits
git rebase ...
the with the currentmain
/master
git rebase -i ...
to squash the fixups
-
Update the PR with the up-to-date, conflict free history:
git push --force ...
to update the PR- note: this only works if the user/org has allowed you to write to their PR branch - which is usually the case since it’s the default
However, that’s a real headache to do because github doesn’t provide a nice copy/paste snippet.
And so I created my own little script so that I can just copy/paste two pieces of info from the PR page and get rolling:
# Usage
gh-review <project-name> <fork-abbrev> [branch-name] [fork-project-name]
# Example
gh-review awesome-sauce rando:patch-1 add-feature-x
Here’s the source:
gh-review
:
#!/bin/bash
set -e
set -u
# The goal here is to be able to copy and paste from the limited info
# that we get from Github and review a PR _The Right Way™_:
if [[ -z ${2:-} ]]; then
echo ""
echo "Usage:"
echo ' gh-review <project-name> <fork-abbrev> [branch-name] [fork-project-name]'
echo ""
echo "Example:"
echo " gh-review awesome-sauce rando:patch-1 add-feature-x"
echo ""
echo "Scenario:"
echo " - You maintain 'github.com/you/awesome-sauce'"
echo " - A PR comes in from 'guthub.com/rando/awesome-sauce'"
echo " - They've used the default branch name of 'patch-1'"
echo " - You want to work on this as branch 'add-feature-x'"
echo ""
exit 1
fi
# Here we "parse" the fork abbrevation we get from github:
my_repo="${1}"
my_pr="${2}"
pr_remote="$(echo "${my_pr}" | cut -d':' -f1)"
pr_branch="$(echo "${my_pr}" | cut -d':' -f2-99)"
our_branch="${3:-"${pr_branch}"}"
their_repo="${4:-"${my_repo}"}"
# This (filled out) is the copy/paste snippet that I wish github would give me:
git remote add "${pr_remote}" "ssh://git@github.com/${pr_remote}/${their_repo}.git" || true
git fetch "${pr_remote}"
git checkout -b "${our_branch}" "${pr_remote}/${pr_branch}"
# This is my process for keeping my git history clean:
echo ""
echo "Here are your next steps:"
echo ""
echo " # to bring up-to-date"
echo " git rebase main"
echo ""
echo " # squash extraneous commits messages with 'f' or 's' "
echo " git rebase -i main"
echo ""
echo " # push the clean history back to the remote"
echo " git push --force '${pr_remote}' '${our_branch}':'${pr_branch}'"
echo ""
How to install gh-review
:
chmod a+x gh-review
mkdir ~/.local/bin
mv gh-review ~/.local/bin
curl https://webinstall.dev/pathman | bash
pathman add ~/.local/bin
Another Shortcut
I maintain webinstall.dev
, so I made a shorcut script webi-review
that calls gh-review
with the project name webi-installers
so that I can copy/type less.
webi-review
:
#!/bin/bash
set -e
set -u
gh-review webi-installers "$@"