Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

github, merge PR(s) just by number(s) #1759

Merged
merged 5 commits into from
Jun 13, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 26 additions & 2 deletions tools/gh_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,32 @@ def post_gist(content, description='', filename='file', auth=False):
response_data = json.loads(response.text)
return response_data['html_url']

def get_pull_request(project, num):
url = "https://api.github.com/repos/{project}/pulls/{num}".format(project=project, num=num)
def get_pull_request(project, num, github_api=3):
"""get pull request info by number

github_api : version of github api to use
"""
if github_api==2 :
url = "http://github.com/api/v2/json/pulls/{project}/{num}".format(project=project, num=num)
elif github_api == 3:
url = "https://api.github.com/repos/{project}/pulls/{num}".format(project=project, num=num)
response = requests.get(url)
response.raise_for_status()
if github_api == 2 :
return json.loads(response.text)['pull']
return json.loads(response.text)

def get_pulls_list(project, github_api=3):
"""get pull request list

github_api : version of github api to use
"""
if github_api == 3 :
url = "https://api.github.com/repos/{project}/pulls".format(project=project)
else :
url = "http://github.com/api/v2/json/pulls/{project}".format(project=project)
response = requests.get(url)
response.raise_for_status()
if github_api == 2 :
return json.loads(response.text)['pulls']
return json.loads(response.text)
127 changes: 127 additions & 0 deletions tools/git-mpr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Usage:
python git-mpr.py -m 1657
"""
from __future__ import print_function

import argparse
from subprocess import check_call, CalledProcessError

import gh_api

ipy_repository = 'git://github.com/ipython/ipython.git'
gh_project = "ipython/ipython"
not_merged = {}

def merge_branch(repo, branch ):
"""try to merge the givent branch into the current one

If something does not goes smoothly, merge is aborted

Returns True if merge sucessfull, False otherwise
"""
# Delete the branch first
try :
check_call(['git', 'pull', '--no-edit', repo, branch])
except CalledProcessError :
check_call(['git', 'merge', '--abort'])
return False
return True


def merge_pr(num, github_api=3):
""" try to merge the branch of PR `num` into current branch

github_api : use github api v2 (to bypass https and issues with proxy) to find the
remote branch that should be merged by it's number
"""
# Get Github authorisation first, so that the user is prompted straight away
# if their login is needed.

pr = gh_api.get_pull_request(gh_project, num, github_api)
if github_api == 2:
repo = pr['head']['repository']['url']
elif github_api == 3 :
repo = pr['head']['repo']['clone_url']


branch = pr['head']['ref']
mergeable = merge_branch(repo=repo,
branch=branch,
)
if not mergeable :
cmd = "git pull "+repo+" "+branch
not_merged[str(num)] = cmd
print("==============================================================================")
print("Something went wrong merging this branch, you can try it manually by runngin :")
print(cmd)
print("==============================================================================")


def main(*args):
parser = argparse.ArgumentParser(
description="""
Merge (one|many) github pull request by their number.\

If pull request can't be merge as is, cancel merge,
and continue to the next if any.
"""
)
parser.add_argument('-v2', '--githubapiv2', action='store_const', const=2)

grp = parser.add_mutually_exclusive_group()
grp.add_argument(
'-l',
'--list',
action='store_const',
const=True,
help='list PR, their number and their mergeability')
grp.add_argument('-a',
'--merge-all',
action='store_const',
const=True ,
help='try to merge as many PR as possible, one by one')
grp.add_argument('-m',
'--merge',
type=int,
help="The pull request numbers",
nargs='*',
metavar='pr-number')
args = parser.parse_args()
if args.githubapiv2 == 2 :
github_api = 2
else :
github_api = 3

if(args.list):
pr_list = gh_api.get_pulls_list(gh_project, github_api)
for pr in pr_list :
mergeable = gh_api.get_pull_request(gh_project, pr['number'], github_api=github_api)['mergeable']

ismgb = u"√" if mergeable else " "
print(u"* #{number} [{ismgb}]: {title}".format(
number=pr['number'],
title=pr['title'],
ismgb=ismgb))

if(args.merge_all):
pr_list = gh_api.get_pulls_list(gh_project)
for pr in pr_list :
merge_pr(pr['number'])


elif args.merge:
for num in args.merge :
merge_pr(num, github_api=github_api)

if not_merged :
print('*************************************************************************************')
print('the following branch have not been merged automatically, considere doing it by hand :')
for num, cmd in not_merged.items() :
print( "PR {num}: {cmd}".format(num=num, cmd=cmd))
print('*************************************************************************************')

if __name__ == '__main__':
main()