Last active
January 6, 2016 02:46
-
-
Save jaredru/89ab7a83546a7931aaad to your computer and use it in GitHub Desktop.
a git command to open pull requests in the default difftool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -fu -o pipefail | |
# prepare some help info | |
OPTS_SPEC="\ | |
git prdifftool <github pull request url> | |
git prdifftool <github remote> <pull request number> | |
git prdifftool <pull request number> | |
git prdifftool opens a GitHub pull request in the default difftool | |
-- | |
" | |
if [[ $# -eq 0 ]]; then | |
set -- -h | |
fi | |
eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)" | |
shift | |
die () { | |
echo >&2 "$@" | |
exit 1 | |
} | |
# if the first argument is a github url, parse it into repo and pr number | |
if [[ $1 =~ github\.com/([[:alnum:]]+/[[:alnum:]]+)/pull/([[:digit:]]+) ]]; then | |
repo=${BASH_REMATCH[1]} | |
pr=${BASH_REMATCH[2]} | |
# from the repo, we can find the user's remote name | |
remote=`git remote -v | grep -E -i -m1 "github\.com(:|/)$repo" | awk '{print $1}'` | |
elif [[ $# -eq 2 ]]; then | |
remote=$1 | |
pr=$2 | |
else | |
remote=origin | |
pr=$1 | |
fi | |
# verify that we have valid arguments | |
[[ $remote ]] || die "FATAL: missing github remote" | |
[[ $(git remote -v | grep "^$remote\b.*github\.com") ]] || die "FATAL: invalid github remote '$remote'" | |
[[ $pr ]] || die "FATAL: missing pull request number" | |
[[ $pr =~ ^[[:digit:]]+$ ]] || die "FATAL: invalid pull request number '$pr'" | |
refname_head="refs/pull/$pr/head" | |
refname_merge="refs/pull/$pr/merge" | |
# list the remote's refs, and try to match a merge ref for the pr | |
ls_remote=`git ls-remote $remote` | |
head_ref=$(echo "$ls_remote" | grep "$refname_head") | |
merge_ref=`echo "$ls_remote" | grep "$refname_merge"` | |
# make sure the pr head ref exists in the given remote | |
[[ $head_ref ]] || die "FATAL: pull request '$pr' does not existing in remote '$remote'" | |
# we'll fetch one of two possible refs depending on the state of the pr | |
fetch=`git config remote.${remote}.fetch` | |
if [[ $merge_ref ]]; then | |
# we found a merge ref, fetch it, and save its sha | |
git fetch $remote $fetch refs/pull/$pr/merge | |
merge_sha=`echo $merge_ref | awk '{print $1}'` | |
else | |
# we didn't find a merge ref, so fetch the head ref | |
git fetch $remote $fetch refs/pull/$pr/head | |
pr_sha=`echo "$ls_remote" | grep "refs/pull/$pr/head" | awk '{print $1}'` | |
# list all the refs (and their children) except those that are ancestors of | |
# the pr, find the first child of it, and save its sha. | |
merge_sha=`git rev-list --all --children --not $pr_sha^@ | grep -m1 "^$pr_sha" | awk '{print $2}'` | |
fi | |
# diff the merge sha in the user's difftool | |
git difftool $merge_sha^..$merge_sha |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Save in your path (probably /usr/local/bin) as
git-prdifftool
. The command can then be used asgit prdifftool
.