Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fetch&rebase support for pull requests #56

Open
wants to merge 14 commits into from

2 participants

Kohsuke Kawaguchi nixon
Kohsuke Kawaguchi

I work on projects on GitHub that receives a fair number of pull requests, and most of the time I need to make some slight adjustments on them before merging changes. I also do fetch+rebase when merging pull requests in an attempt to create more linear history. I find it easier to comprehend what was going on that way.

To that end, I added a command to do this in one shot:

  • you run "github fetch-pull 3" where 3 indicates a pull request ID.
  • the command looks at your remote and figure out which repository this is.
  • it then fetches and rebases the pull request, then finishes.

If you find this command useful, would you please consider merging it?

nixon

Here's a commit that adds support for private repos to kohsuke's fetch-pull feature:

nixon@d856a17

Kohsuke Kawaguchi

The change mentioned in the comment from nixon is now merged into this pull request.

nixon and others added some commits
nixon nixon provide a fetch-pull merge alternative
add merge, rebase and do-nothing options to the fetch-pull command.  i
like being able to fetch a pull request by number, but sometimes i'd
rather not have the rebase happen automatically.
d09ed2f
Kohsuke Kawaguchi kohsuke Merge pull request #2 from nixon/fetch-pull_with_options
Fetch pull with options
372d3ec
Kohsuke Kawaguchi kohsuke Merge remote-tracking branch 'upstream/master'
Conflicts:
	.gitignore
6e25860
Kohsuke Kawaguchi kohsuke Switching to OAuth token
There's a lot more work to be done to convert other calls, but this is a
start.
188b226
Kohsuke Kawaguchi kohsuke If the user is in org, check out via SSH. 77bd86c
Kohsuke Kawaguchi kohsuke canonicalize the path so that link to bin can be a symlink 11ba1ae
Kohsuke Kawaguchi kohsuke improved the definition 7013e65
Kohsuke Kawaguchi kohsuke far simpler implementation of fetch-pull a71785f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 15, 2011
  1. Kohsuke Kawaguchi
  2. Kohsuke Kawaguchi

    Ignore rubymine files.

    kohsuke authored
Commits on Jun 17, 2011
  1. Kohsuke Kawaguchi

    improved error handling

    kohsuke authored
  2. Kohsuke Kawaguchi
Commits on Jun 27, 2011
  1. nixon
Commits on Jun 28, 2011
  1. Kohsuke Kawaguchi

    Merge pull request #1 from nixon/fetch-pull_orgs

    kohsuke authored
    Support for private repositories.
  2. nixon

    provide a fetch-pull merge alternative

    nixon authored
    add merge, rebase and do-nothing options to the fetch-pull command.  i
    like being able to fetch a pull request by number, but sometimes i'd
    rather not have the rebase happen automatically.
  3. Kohsuke Kawaguchi

    Merge pull request #2 from nixon/fetch-pull_with_options

    kohsuke authored
    Fetch pull with options
Commits on Jun 21, 2012
  1. Kohsuke Kawaguchi

    Merge remote-tracking branch 'upstream/master'

    kohsuke authored
    Conflicts:
    	.gitignore
Commits on Jun 22, 2012
  1. Kohsuke Kawaguchi

    Switching to OAuth token

    kohsuke authored
    There's a lot more work to be done to convert other calls, but this is a
    start.
  2. Kohsuke Kawaguchi
Commits on Jun 30, 2012
  1. Kohsuke Kawaguchi
Commits on Mar 20, 2013
  1. Kohsuke Kawaguchi

    improved the definition

    kohsuke authored
Commits on Apr 25, 2013
  1. Kohsuke Kawaguchi
This page is out of date. Refresh to see the latest.
3  .gitignore
View
@@ -3,4 +3,5 @@ InstalledFiles
pkg
*.gem
.bundle
-Gemfile.lock
+Gemfile.lock
+.idea
4 bin/gh
View
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
-
-lib_dir = File.join(File.dirname(__FILE__), '..', 'lib')
+require 'pathname'
+lib_dir = File.join(File.dirname(Pathname.new(__FILE__).realpath.to_s), '..', 'lib')
$LOAD_PATH.unshift lib_dir if File.directory?(lib_dir)
require 'github'
4 bin/github
View
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
-
-lib_dir = File.join(File.dirname(__FILE__), '..', 'lib')
+require 'pathname'
+lib_dir = File.join(File.dirname(Pathname.new(__FILE__).realpath.to_s), '..', 'lib')
$LOAD_PATH.unshift lib_dir if File.directory?(lib_dir)
require 'github'
27 lib/commands/commands.rb
View
@@ -161,7 +161,7 @@
end
if repo
- if options[:ssh] || current_user?(user)
+ if options[:ssh] || current_user?(user) || in_org?(user)
git_exec "clone git@github.com:#{user}/#{repo}.git" + (dir ? " #{dir}" : "")
else
git_exec "clone git://github.com/#{user}/#{repo}.git" + (dir ? " #{dir}" : "")
@@ -193,7 +193,7 @@
flags :rst => 'Create README.rst'
flags :private => 'Create private repository'
command :create do |repo|
- command = "curl -F 'name=#{repo}' -F 'public=#{options[:private] ? 0 : 1}' -F 'login=#{github_user}' -F 'token=#{github_token}' https://github.com/api/v2/json/repos/create"
+ command = "curl -F 'name=#{repo}' -F 'public=#{options[:private] ? 0 : 1}' -H 'Authorization: token #{github_token}' https://github.com/api/v2/json/repos/create"
output_json = sh command
output = JSON.parse(output_json)
if output["error"]
@@ -231,7 +231,7 @@
current_origin = git "config remote.origin.url"
- output_json = sh "curl -F 'login=#{github_user}' -F 'token=#{github_token}' https://github.com/api/v2/json/repos/fork/#{user}/#{repo}"
+ output_json = sh "curl -H 'Authorization: token #{github_token}' https://github.com/api/v2/json/repos/fork/#{user}/#{repo}"
output = JSON.parse(output_json)
if output["error"]
die output["error"]
@@ -261,7 +261,7 @@
end
is_repo = !git("status").match(/fatal/)
raise "Not a git repository. Use 'gh create' instead" unless is_repo
- command = "curl -F 'name=#{repo}' -F 'public=#{options[:private] ? 0 : 1}' -F 'login=#{github_user}' -F 'token=#{github_token}' https://github.com/api/v2/json/repos/create"
+ command = "curl -F 'name=#{repo}' -F 'public=#{options[:private] ? 0 : 1}' -H 'Authorization: token #{github_token}' https://github.com/api/v2/json/repos/create"
output_json = sh command
output = JSON.parse(output_json)
if output["error"]
@@ -283,3 +283,22 @@
puts "No results found"
end
end
+
+desc "Fetch a pull request and possibly rebase or merge it to the current tip"
+usage "github fetch-pull [pullRequestId] [rebase | merge]"
+command :'fetch-pull' do |n,action|
+ user, repo = nil,nil
+ # figure out the user+repo name from git-remote
+ git("remote -v").split("\n").each do |line|
+ m = /git@github\.com[:\/]([^\/]+)\/(.+)\.git/.match(line)
+ if m
+ user = m[1]
+ repo = m[2]
+ end
+ end
+ die "Cannot infer repository from git-remote" unless user && repo
+
+ pgit "fetch https://github.com/#{user}/#{repo}.git refs/pull/#{n}/head:pull-#{n}"
+ pgit "checkout pull-#{n}"
+ pgit "#{action} #{tip}" if ["rebase", "merge"].include?(action)
+end
26 lib/github/command.rb
View
@@ -76,7 +76,7 @@ def github_user
end
def github_token
- token = git("config --get github.token")
+ token = git("config --get github.oauth")
if token.empty?
request_github_credentials
token = github_token
@@ -89,17 +89,23 @@ def request_github_credentials
user = highline.ask("Username: ") while user.nil? || user.empty?
git("config --global github.user '#{user}'")
- puts("Your account token is at https://github.com/account under 'Account Admin'.")
- puts("Press Enter to launch page in browser.")
- token = highline.ask("Token: ")
- while token.strip.empty?
- helper.open "https://github.com/account"
- token = highline.ask("Token: ")
- end
- git("config --global github.token '#{token}'")
+ puts "We now need to ask you to give your GitHub password."
+ puts("We use this to generate OAuth token and store that. Password will not be persisted.")
+
+ token = highline.ask("Password: ") { |q| q.echo = false }
+ data = JSON.parse(`curl -s -L -u '#{github_user}:#{token}' --data-binary '{"scopes":["repo","gist"],"note":"GitHub Gem"}' -X POST https://api.github.com/authorizations`)
+ git("config --global github.oauth '#{data["token"]}'")
true
end
-
+
+ # is the current user in the given org?
+ def in_org?(name)
+ command = "curl -H 'Authorization: token #{github_token}' https://api.github.com/user/orgs"
+ output_json = sh command
+ orgs = JSON.parse(output_json)
+ return orgs.find {|o| o['login']==name }!=nil
+ end
+
def highline
@highline ||= HighLine.new
end
Something went wrong with that request. Please try again.