Skip to content

Commit

Permalink
Add hub merge command
Browse files Browse the repository at this point in the history
It does what GitHub's "Merge pull request" button does:
merges the pull request with a nice commit message that
includes the pull request ID and title. Like `hub checkout`,
it creates a remote, but it does not create a local branch.
  • Loading branch information
jfirebaugh authored and mislav committed May 7, 2012
1 parent 77caa60 commit e307ce9
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 1 deletion.
28 changes: 28 additions & 0 deletions lib/hub/commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,34 @@ def checkout(args)
end
end

# $ git merge https://github.com/defunkt/hub/pull/73
# > git remote add -f -t feature git://github:com/mislav/hub.git
# > git merge mislav/feature --no-ff -m 'Merge pull request #73 from mislav/feature...'
def merge(args)
_, url_arg, new_branch_name = args.words
if url = resolve_github_url(url_arg) and url.project_path =~ /^pull\/(\d+)/
pull_id = $1
pull_data = api_client.pullrequest_info(url.project, pull_id)

args.delete new_branch_name
user, branch = pull_data['head']['label'].split(':', 2)
abort "Error: #{user}'s fork is not available anymore" unless pull_data['head']['repo']

if remotes.include? user
args.before ['remote', 'set-branches', '--add', user, branch]
args.before ['fetch', user, "+refs/heads/#{branch}:refs/remotes/#{user}/#{branch}"]
else
url = github_project(url.project_name, user).git_url(:private => pull_data['head']['repo']['private'],
:https => https_protocol?)
args.before ['remote', 'add', '-f', '-t', branch, user, url]
end
idx = args.index url_arg
args.delete_at idx
args.insert idx, "#{user}/#{branch}", '--no-ff', '-m',
"Merge pull request ##{pull_id} from #{user}/#{branch}\n\n#{pull_data['title']}"
end
end

# $ git cherry-pick http://github.com/mislav/hub/commit/a319d88#comments
# > git remote add -f mislav git://github.com/mislav/hub.git
# > git cherry-pick a319d88
Expand Down
4 changes: 4 additions & 0 deletions man/hub.1
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ Adds missing remote(s) with \fBgit remote add\fR prior to fetching\. New remotes
Checks out the head of the pull request as a local branch, to allow for reviewing, rebasing and otherwise cleaning up the commits in the pull request before merging\. The name of the local branch can explicitly be set with \fIBRANCH\fR\.
.
.TP
\fBgit merge\fR \fIPULLREQ\-URL\fR
Merge the pull request with a nice commit message that includes the pull request ID and title\. Adds a remote but not a local branch\.
.
.TP
\fBgit cherry\-pick\fR \fIGITHUB\-REF\fR
Cherry\-pick a commit from a fork using either full URL to the commit or GitHub\-flavored Markdown notation, which is \fBuser@sha\fR\. If the remote doesn\'t yet exist, it will be added\. A \fBgit fetch <user>\fR is issued prior to the cherry\-pick attempt\.
.
Expand Down
2 changes: 2 additions & 0 deletions man/hub.1.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions man/hub.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ hub enhances various git commands to ease most common workflows with GitHub.
request before merging. The name of the local branch can explicitly be
set with <BRANCH>.

* `git merge` <PULLREQ-URL>:
Merge the pull request with a nice commit message that includes the pull
request ID and title. Adds a remote but not a local branch.

* `git cherry-pick` <GITHUB-REF>:
Cherry-pick a commit from a fork using either full URL to the commit
or GitHub-flavored Markdown notation, which is `user@sha`. If the remote
Expand Down
36 changes: 35 additions & 1 deletion test/hub_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,40 @@ def test_checkout_pullrequest_existing_remote
"checkout https://github.com/defunkt/hub/pull/73/files"
end

def test_merge_no_changes
assert_forwarded "merge master"
end

def test_merge_pullrequest
stub_request(:get, "https://api.github.com/repos/defunkt/hub/pulls/73").
to_return(:body => mock_pull_response('blueyed:feature'))

assert_commands "git remote add -f -t feature blueyed git://github.com/blueyed/hub.git",
"git merge blueyed/feature --no-ff -m 'Merge pull request #73 from blueyed/feature\n\nMake eyes blue'",
"merge https://github.com/defunkt/hub/pull/73/files"
end

def test_merge_private_pullrequest
stub_request(:get, "https://api.github.com/repos/defunkt/hub/pulls/73").
to_return(:body => mock_pull_response('blueyed:feature', :private))

assert_commands "git remote add -f -t feature blueyed git@github.com:blueyed/hub.git",
"git merge blueyed/feature --no-ff -m 'Merge pull request #73 from blueyed/feature\n\nMake eyes blue'",
"merge https://github.com/defunkt/hub/pull/73/files"
end

def test_merge_pullrequest_existing_remote
stub_command_output 'remote', "origin\nblueyed"

stub_request(:get, "https://api.github.com/repos/defunkt/hub/pulls/73").
to_return(:body => mock_pull_response('blueyed:feature'))

assert_commands "git remote set-branches --add blueyed feature",
"git fetch blueyed +refs/heads/feature:refs/remotes/blueyed/feature",
"git merge blueyed/feature --no-ff -m 'Merge pull request #73 from blueyed/feature\n\nMake eyes blue'",
"merge https://github.com/defunkt/hub/pull/73/files"
end

def test_version
out = hub('--version')
assert_includes "git version 1.7.0.4", out
Expand Down Expand Up @@ -967,7 +1001,7 @@ def mock_pull_response(label, priv = false)
Hub::JSON.generate :head => {
:label => label,
:repo => {:private => !!priv}
}
}, :title => "Make eyes blue"
end

def improved_help_text
Expand Down

0 comments on commit e307ce9

Please sign in to comment.