Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fetch&rebase support for pull requests #56

Open
wants to merge 14 commits into from

2 participants

@kohsuke

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

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 kohsuke Merge pull request #2 from nixon/fetch-pull_with_options
Fetch pull with options
372d3ec
@kohsuke kohsuke Merge remote-tracking branch 'upstream/master'
Conflicts:
	.gitignore
6e25860
@kohsuke 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 kohsuke If the user is in org, check out via SSH. 77bd86c
@kohsuke kohsuke canonicalize the path so that link to bin can be a symlink 11ba1ae
@kohsuke kohsuke improved the definition 7013e65
@kohsuke 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
  2. @kohsuke

    Ignore rubymine files.

    kohsuke authored
Commits on Jun 17, 2011
  1. @kohsuke

    improved error handling

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

    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

    Merge pull request #2 from nixon/fetch-pull_with_options

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

    Merge remote-tracking branch 'upstream/master'

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

    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
Commits on Jun 30, 2012
  1. @kohsuke
Commits on Mar 20, 2013
  1. @kohsuke

    improved the definition

    kohsuke authored
Commits on Apr 25, 2013
  1. @kohsuke
This page is out of date. Refresh to see the latest.
View
3  .gitignore
@@ -3,4 +3,5 @@ InstalledFiles
pkg
*.gem
.bundle
-Gemfile.lock
+Gemfile.lock
+.idea
View
4 bin/gh
@@ -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'
View
4 bin/github
@@ -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'
View
27 lib/commands/commands.rb
@@ -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
View
26 lib/github/command.rb
@@ -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.