Skip to content

Instantly share code, notes, and snippets.

@tomjenkinson
Last active October 10, 2015 13:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tomjenkinson/3699672 to your computer and use it in GitHub Desktop.
Save tomjenkinson/3699672 to your computer and use it in GitHub Desktop.
A simple script to apply a pull request
#!/bin/bash
git remote | grep upstream > /dev/null 2>&1
if [ "$?" -ne 0 ]; then
echo This script assumes you have upstream set as the repo to hand reqs in
exit
fi
if [ ! -d .git ]; then
echo This script assumes you are in the root of a repo clone
exit
fi
upstreamname=`git remote -v | grep upstream | grep fetch | sed "s#upstream.*github.com[:/]\(.*\)/.*#\1#"`
reponame=`git remote -v | grep upstream | grep push | sed "s#.*/\(.*\)\.git.*#\1#g"`
if [ $# -eq 0 ]
then
echo "Checking $upstreamname for $reponame"
wget --no-check-certificate https://github.com/$upstreamname/$reponame/pulls/$pullNumber --no-clobber -O .pulls > /dev/null 2>&1
#grep js-navigation-open .pulls | sort | sed 's# <a href="\(.*\)" class="js-navigation-open">\(.*\)</a>#https://github.com\1 https://issues.jboss.org/browse/\2#'
sed -n '/js-navigation-open">/,/a>/p' .pulls
rm .pulls
exit
fi
if [ $# -lt 2 ]
then
echo "Need pull number and branch"
exit
fi
export pullNumber=$1
shift
export upstreamBranch=$1
shift
if [ "$upstreamBranch" == "-f" ]
then
echo MAJOR ERROR -f in position 2
exit -1
fi
git status | grep "Untracked\|Changes not staged"
if [ $? -eq 0 ]; then
echo Ensure working $upstreamBranch is clean before applying
exit
fi
gitreqrebase $pullNumber $upstreamBranch "$@"
if [ $? -ne 0 ]
then
echo "Problem with rebasing one of our pull requests, maybe you need -f"
exit
fi
echo "Applying pull $pullNumber onto $upstreamBranch"
rm -f $pullNumber $pullNumber.patch
git fetch upstream
git checkout $upstreamBranch
git up upstream $upstreamBranch
git status | grep "Untracked\|Changes not staged"
if [ $? -eq 0 ]; then
echo Ensure working $upstreamBranch is clean before applying
exit
fi
wget --no-check-certificate https://github.com/$upstreamname/$reponame/pull/$pullNumber
if [ $? -ne 0 ]; then
echo Could not download pull req info
exit
fi
wget --no-check-certificate https://github.com/$upstreamname/$reponame/pull/$pullNumber.patch
if [ $? -ne 0 ]; then
echo Could not download patch
exit
fi
git apply --check $pullNumber.patch
if [ $? -ne 0 ]; then
echo patch would not be able to apply
exit
fi
username=$(grep "by .* · Pull" $pullNumber | sed 's#.*by \(.*\) · Pull.*#\1#')
git remote | grep $username
if [ "$?" -ne 0 ]; then
committerrepo=$(grep "commit-id" $pullNumber | sed "s#.*$username/\(.*\)/commit/.*#\1#" | head -1)
if [ "$?" -ne 0 ]; then
echo "Could not find committer repo"
exit
fi
echo git remote add $username git://github.com/$username/$committerrepo.git
git remote add $username git://github.com/$username/$committerrepo.git
fi
git fetch $username
branchname=$(grep "span.*$username.*css-truncate-target" $pullNumber | sed 's#.*">\([A-Za-z0-9\-]*\)<.*#\1#')
expr length $branchname
if [ "$?" -ne 0 ]; then
echo "Could not find branch name, assuming first word of title!"
branchname=$(grep "<title>" 1 | sed 's#.*<title>\([a-zA-Z0-9\-]*\) .*#\1#')
expr length $branchname
if [ "$?" -ne 0 ]; then
echo "Could not find branch name, aborting"
exit
fi
fi
git branch -a | grep $username-$branchname
if [ "$?" -eq 0 ]; then
echo "Local branch already existed"
exit
fi
#Creates merge commit
#git checkout -b $username-$branchname $upstreamBranch
#git pull --rebase --ff-only git://github.com/$username/$reponame.git $branchname
#git checkout $upstreamBranch
#git merge $username-$branchname
git fetch $username
git checkout $upstreamBranch
git reset --hard $username/$branchname
git pull --rebase --ff-only upstream $upstreamBranch
git push upstream $upstreamBranch
git reset --hard upstream/$upstreamBranch
git push origin $upstreamBranch
#git branch -d $username-$branchname
git remote rm $username
rm $pullNumber
rm $pullNumber.patch
xdg-open https://github.com/$upstreamname/$reponame/pull/$pullNumber
@paulrobinson
Copy link

adding --no-check-certificate to all wget commands prevents the script from failing.
Quoting the regex on https://gist.github.com/tomjenkinson/3699672#file-gitreqapply-L73 makes it work on a mac.

See here for my changes: https://gist.github.com/paulrobinson/6915611

@tomjenkinson
Copy link
Author

merged - thanks

@tomjenkinson
Copy link
Author

one thing I have considered is for my own prs what the script could do is rebase the PR branch, force a push then do the merge, this will mean that the PR is "merged" from a GH pov directly

@paulrobinson
Copy link

This script doesn't take into account the fact that forks don't have to be named the same as upstream. This happens if you fork two repos with the same name. See my quickstart repos: https://github.com/paulrobinson?tab=repositories

The fix is to change:

reponame=`git remote -v | grep origin | grep push | sed "s#.*/\(.*\)\.git.*#\1#g"`

To:

reponame=`git remote -v | grep upstream | grep push | sed "s#.*/\(.*\)\.git.*#\1#g"`

@paulrobinson
Copy link

Also, I like to have these at the start of my scripts:

if [ "$2" == "" ]; then
    echo "Usage: $0 <PR number> <target branch>"
    exit 1
fi

@tomjenkinson
Copy link
Author

Thanks for the reponame contribution - I added it :)

@tomjenkinson
Copy link
Author

In terms of usage:

0 params lists all the open PRs
2 params is for pull number and branch
3 params allows you to force a push of your branch during a rebase

I could change it to:
if [ "$4" == "" ]; then

but I am not sure how complex the usage debug would look, maybe I could add a -h option?

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