Created
August 12, 2011 10:44
-
-
Save jcayzac/1141843 to your computer and use it in GitHub Desktop.
Git subcommand to create GitHub pull request (place it in your PATH)
This file contains hidden or 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
source "http://rubygems.org" | |
octokit | |
This file contains hidden or 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 ruby | |
require 'rubygems' | |
require 'optparse' | |
require 'tempfile' | |
require 'octokit' | |
class GitPullRequest | |
@@branch_owner_re = /github\.com.(.*?)\/(.*)/ | |
def git(command) | |
`git #{command}`.chomp | |
end | |
def branch_owner(branch) | |
remote = git("config branch.#{branch}.remote") | |
url = git("config remote.#{remote}.url") | |
m = @@branch_owner_re.match(url) | |
if m | |
return m[1], m[2].sub(/\.git\Z/, "") | |
end | |
return nil, nil | |
end | |
def run | |
github_token = git("config --get-all github.token") | |
if github_token.size == 0 | |
abort <<-eot | |
Could not find value for key "github.token" in git's configuration. | |
eot | |
end | |
upstream = 'develop' | |
message = '' | |
OptionParser.new do |opts| | |
opts.on("-m", "--message msg", "Set this pull request's title") do |msg| | |
message = msg | |
end | |
opts.on("-u", "--upstream branch", "Set the upstream branch (default: develop)") do |up| | |
upstream = up | |
end | |
opts.on("-h", "--help", "Show usage") do | |
abort <<-eot | |
Usage: | |
git create-pull-request [-m msg] [-u branchname] [-h] | |
Creates a pull request based on the current locally-tracked branch. | |
-m, --message=msg Set the pull request's title (and no body). | |
-u, --upstream=branchname Set the upstream branch. Defaults to 'develop'. | |
-h, --help Display this help page and exits. | |
eot | |
end | |
end.parse! | |
team, repo_name = branch_owner(upstream) | |
if not team or not repo_name | |
abort <<-eot | |
Could not deduce upstream repository from branch #{upstream}. Bad remote? | |
eot | |
end | |
branch = git('symbolic-ref HEAD').split('/')[-1] | |
user, fork_name = branch_owner(branch) | |
if repo_name != fork_name | |
abort <<-eot | |
#{user}/#{fork_name} doesn't look like a fork of #{team}/#{repo_name}. | |
eot | |
end | |
if not user | |
user = git("config --get-all github.user") | |
end | |
if not user | |
abort <<-eot | |
Could not deduce your GitHub user name from branch #{branch}, \ | |
and no value was found in Git's configuration for key "github.user". | |
eot | |
end | |
Octokit.configure do |config| | |
config.login = user | |
config.token = github_token | |
end | |
title = '' | |
body = '' | |
if message.size > 0 | |
title = message | |
else | |
f = Tempfile.new('pull-request-message') | |
path = f.path | |
f.puts '' | |
f.puts '' | |
f.puts "# Please enter the pull request message. Lines starting" | |
f.puts "# with '#' will be ignored, and an empty message aborts" | |
f.puts "# the pull request." | |
f.puts "#" | |
f.puts "# Asks to apply branch:" | |
f.puts "# #{user}/#{repo_name}:#{branch}" | |
f.puts "# Onto branch:" | |
f.puts "# #{team}/#{repo_name}:#{upstream}" | |
f.puts "#" | |
f.puts "# vim: set filetype=gitcommit :" | |
f.flush | |
f.close | |
if not system("#{ENV['EDITOR']} #{path}") | |
File.delete(path) | |
abort "#{ENV['EDITOR']} exited with non-zero return code, aborting..." | |
end | |
f = File.open(path, "r") | |
lines = f.read.split("\n") | |
f.close | |
File.delete(path) | |
title_ = [] | |
body_ = [] | |
jumps = 0 | |
lines.each do |line| | |
chomped = line.chomp | |
next if chomped.size > 0 and chomped[0].chr == '#' | |
if chomped.size == 0 | |
jumps = jumps + 1 | |
end | |
if jumps == 0 | |
break if chomped.size == 0 | |
title_ << chomped | |
else | |
next if chomped.size == 0 | |
body_ << line | |
end | |
end | |
title = title_.join(' ') | |
body = body_.join("\n") | |
end | |
if title.size == 0 | |
abort "No message, aborting!" | |
end | |
Octokit.create_pull_request( | |
"#{team}/#{repo_name}", | |
"#{team}:#{upstream}", | |
"#{user}:#{branch}", | |
"#{title}", | |
"#{body}" | |
) | |
end | |
end | |
GitPullRequest.new().run | |
# vim: set fileencodings=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment