зеркало из https://github.com/mislav/hub.git
Improve `hub merge` to not generate leftover remote refs
The previous implementation fetched refs into `refs/remotes/OWNER/BRANCH`. Now, fetch `refs/pull/ID/head` directly into FETCH_HEAD and merge that. It's a more straightforward approach that generates no artefacts. This is for similarity with the reimplemented `hub checkout` command which now also uses `refs/pull/ID/head`.
This commit is contained in:
Родитель
b972284fba
Коммит
cbf7ab1ba3
|
@ -61,23 +61,30 @@ func transformMergeArgs(args *Args) error {
|
|||
return err
|
||||
}
|
||||
|
||||
repo, err := github.LocalRepo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
remote, err := repo.RemoteForRepo(pullRequest.Base.Repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
branch := pullRequest.Head.Ref
|
||||
headRepo := pullRequest.Head.Repo
|
||||
if headRepo == nil {
|
||||
return fmt.Errorf("Error: that fork is not available anymore")
|
||||
}
|
||||
|
||||
u := url.GitURL(headRepo.Name, headRepo.Owner.Login, headRepo.Private)
|
||||
mergeHead := fmt.Sprintf("%s/%s", headRepo.Owner.Login, branch)
|
||||
ref := fmt.Sprintf("+refs/heads/%s:refs/remotes/%s", branch, mergeHead)
|
||||
args.Before("git", "fetch", u, ref)
|
||||
args.Before("git", "fetch", remote.Name, fmt.Sprintf("refs/pull/%s/head", id))
|
||||
|
||||
// Remove pull request URL
|
||||
idx := args.IndexOfParam(mergeURL)
|
||||
args.RemoveParam(idx)
|
||||
|
||||
mergeMsg := fmt.Sprintf("Merge pull request #%v from %s\n\n%s", id, mergeHead, pullRequest.Title)
|
||||
args.AppendParams(mergeHead, "-m", mergeMsg)
|
||||
mergeMsg := fmt.Sprintf("Merge pull request #%s from %s/%s\n\n%s", id, headRepo.Owner.Login, branch, pullRequest.Title)
|
||||
args.AppendParams("FETCH_HEAD", "-m", mergeMsg)
|
||||
|
||||
if args.IndexOfParam("--ff-only") == -1 && args.IndexOfParam("--squash") == -1 && args.IndexOfParam("--ff") == -1 {
|
||||
i := args.IndexOfParam("-m")
|
||||
|
|
|
@ -4,10 +4,21 @@ Feature: hub merge
|
|||
And the "origin" remote has url "git://github.com/defunkt/hub.git"
|
||||
And I am "mislav" on github.com with OAuth token "OTOKEN"
|
||||
|
||||
Scenario: Normal merge
|
||||
When I run `hub merge master`
|
||||
Then the git command should be unchanged
|
||||
|
||||
Scenario: Merge pull request
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
get('/repos/defunkt/hub/pulls/164') { json \
|
||||
:base => {
|
||||
:repo => {
|
||||
:owner => { :login => "defunkt" },
|
||||
:name => "hub",
|
||||
:private => false
|
||||
}
|
||||
},
|
||||
:head => {
|
||||
:ref => "hub_merge",
|
||||
:repo => {
|
||||
|
@ -19,10 +30,10 @@ Feature: hub merge
|
|||
:title => "Add `hub merge` command"
|
||||
}
|
||||
"""
|
||||
And there is a commit named "jfirebaugh/hub_merge"
|
||||
And there is a git FETCH_HEAD
|
||||
When I successfully run `hub merge https://github.com/defunkt/hub/pull/164`
|
||||
Then "git fetch git://github.com/jfirebaugh/hub.git +refs/heads/hub_merge:refs/remotes/jfirebaugh/hub_merge" should be run
|
||||
And "git merge jfirebaugh/hub_merge --no-ff -m Merge pull request #164 from jfirebaugh/hub_merge" should be run
|
||||
Then "git fetch origin refs/pull/164/head" should be run
|
||||
And "git merge FETCH_HEAD --no-ff -m Merge pull request #164 from jfirebaugh/hub_merge" should be run
|
||||
When I successfully run `git show -s --format=%B`
|
||||
Then the output should contain:
|
||||
"""
|
||||
|
@ -31,11 +42,18 @@ Feature: hub merge
|
|||
Add `hub merge` command
|
||||
"""
|
||||
|
||||
Scenario: Merge pull request with --ff-only option
|
||||
Scenario: Merge pull request with options
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
require 'json'
|
||||
get('/repos/defunkt/hub/pulls/164') { json \
|
||||
:base => {
|
||||
:repo => {
|
||||
:owner => { :login => "defunkt" },
|
||||
:name => "hub",
|
||||
:private => false
|
||||
}
|
||||
},
|
||||
:head => {
|
||||
:ref => "hub_merge",
|
||||
:repo => {
|
||||
|
@ -47,97 +65,28 @@ Feature: hub merge
|
|||
:title => "Add `hub merge` command"
|
||||
}
|
||||
"""
|
||||
And there is a commit named "jfirebaugh/hub_merge"
|
||||
When I successfully run `hub merge --ff-only https://github.com/defunkt/hub/pull/164`
|
||||
Then "git fetch git://github.com/jfirebaugh/hub.git +refs/heads/hub_merge:refs/remotes/jfirebaugh/hub_merge" should be run
|
||||
And "git merge --ff-only jfirebaugh/hub_merge -m Merge pull request #164 from jfirebaugh/hub_merge" should be run
|
||||
When I successfully run `git show -s --format=%B`
|
||||
Then the output should contain:
|
||||
"""
|
||||
Fast-forward (no commit created; -m option ignored)
|
||||
"""
|
||||
And there is a git FETCH_HEAD
|
||||
When I successfully run `hub merge --squash https://github.com/defunkt/hub/pull/164 --no-edit`
|
||||
Then "git fetch origin refs/pull/164/head" should be run
|
||||
And "git merge --squash --no-edit FETCH_HEAD -m Merge pull request #164 from jfirebaugh/hub_merge" should be run
|
||||
|
||||
Scenario: Merge pull request with --squash option
|
||||
Scenario: Merge pull request no repo
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
require 'json'
|
||||
get('/repos/defunkt/hub/pulls/164') { json \
|
||||
:head => {
|
||||
:ref => "hub_merge",
|
||||
:base => {
|
||||
:repo => {
|
||||
:owner => { :login => "jfirebaugh" },
|
||||
:owner => { :login => "defunkt" },
|
||||
:name => "hub",
|
||||
:private => false
|
||||
}
|
||||
},
|
||||
:title => "Add `hub merge` command"
|
||||
}
|
||||
"""
|
||||
And there is a commit named "jfirebaugh/hub_merge"
|
||||
When I successfully run `hub merge --squash https://github.com/defunkt/hub/pull/164`
|
||||
Then "git fetch git://github.com/jfirebaugh/hub.git +refs/heads/hub_merge:refs/remotes/jfirebaugh/hub_merge" should be run
|
||||
And "git merge --squash jfirebaugh/hub_merge -m Merge pull request #164 from jfirebaugh/hub_merge" should be run
|
||||
When I successfully run `git show -s --format=%B`
|
||||
Then the output should contain:
|
||||
"""
|
||||
Fast-forward (no commit created; -m option ignored)
|
||||
"""
|
||||
|
||||
Scenario: Merge pull request with --ff option
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
require 'json'
|
||||
get('/repos/defunkt/hub/pulls/164') { json \
|
||||
:head => {
|
||||
:ref => "hub_merge",
|
||||
:repo => {
|
||||
:owner => { :login => "jfirebaugh" },
|
||||
:name => "hub",
|
||||
:private => false
|
||||
}
|
||||
},
|
||||
:title => "Add `hub merge` command"
|
||||
}
|
||||
"""
|
||||
And there is a commit named "jfirebaugh/hub_merge"
|
||||
When I successfully run `hub merge --ff https://github.com/defunkt/hub/pull/164`
|
||||
Then "git fetch git://github.com/jfirebaugh/hub.git +refs/heads/hub_merge:refs/remotes/jfirebaugh/hub_merge" should be run
|
||||
And "git merge --ff jfirebaugh/hub_merge -m Merge pull request #164 from jfirebaugh/hub_merge" should be run
|
||||
When I successfully run `git show -s --format=%B`
|
||||
Then the output should contain:
|
||||
"""
|
||||
Fast-forward (no commit created; -m option ignored)
|
||||
"""
|
||||
|
||||
Scenario: Merge private pull request
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
require 'json'
|
||||
get('/repos/defunkt/hub/pulls/164') { json \
|
||||
:head => {
|
||||
:ref => "hub_merge",
|
||||
:repo => {
|
||||
:owner => { :login => "jfirebaugh" },
|
||||
:name => "hub",
|
||||
:private => true
|
||||
}
|
||||
},
|
||||
:title => "Add `hub merge` command"
|
||||
}
|
||||
"""
|
||||
And there is a commit named "jfirebaugh/hub_merge"
|
||||
When I successfully run `hub merge https://github.com/defunkt/hub/pull/164`
|
||||
Then "git fetch git@github.com:jfirebaugh/hub.git +refs/heads/hub_merge:refs/remotes/jfirebaugh/hub_merge" should be run
|
||||
|
||||
Scenario: Missing repo
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
require 'json'
|
||||
get('/repos/defunkt/hub/pulls/164') { json \
|
||||
:head => {
|
||||
:ref => "hub_merge",
|
||||
:repo => nil
|
||||
}
|
||||
},
|
||||
:title => "Add `hub merge` command"
|
||||
}
|
||||
"""
|
||||
When I run `hub merge https://github.com/defunkt/hub/pull/164`
|
||||
|
@ -146,26 +95,3 @@ Feature: hub merge
|
|||
"""
|
||||
Error: that fork is not available anymore\n
|
||||
"""
|
||||
|
||||
Scenario: Renamed repo
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
require 'json'
|
||||
get('/repos/defunkt/hub/pulls/164') { json \
|
||||
:head => {
|
||||
:ref => "hub_merge",
|
||||
:repo => {
|
||||
:owner => { :login => "jfirebaugh" },
|
||||
:name => "hub-1",
|
||||
:private => false
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
And there is a commit named "jfirebaugh/hub_merge"
|
||||
When I successfully run `hub merge https://github.com/defunkt/hub/pull/164`
|
||||
Then "git fetch git://github.com/jfirebaugh/hub-1.git +refs/heads/hub_merge:refs/remotes/jfirebaugh/hub_merge" should be run
|
||||
|
||||
Scenario: Unchanged merge
|
||||
When I run `hub merge master`
|
||||
Then "git merge master" should be run
|
||||
|
|
|
@ -82,6 +82,17 @@ Given(/^there is a commit named "([^"]+)"$/) do |name|
|
|||
run_silent %(git reset --quiet --hard HEAD^)
|
||||
end
|
||||
|
||||
Given(/^there is a git FETCH_HEAD$/) do
|
||||
empty_commit
|
||||
empty_commit
|
||||
in_current_dir do
|
||||
File.open(".git/FETCH_HEAD", "w") do |fetch_head|
|
||||
fetch_head.puts "%s\t\t'refs/heads/made-up' of git://github.com/made/up.git" % `git rev-parse HEAD`.chomp
|
||||
end
|
||||
end
|
||||
run_silent %(git reset --quiet --hard HEAD^)
|
||||
end
|
||||
|
||||
When(/^I make (a|\d+) commits?(?: with message "([^"]+)")?$/) do |num, msg|
|
||||
num = num == 'a' ? 1 : num.to_i
|
||||
num.times { empty_commit(msg) }
|
||||
|
|
Загрузка…
Ссылка в новой задаче