Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
github
hub
提交
13240c70
H
hub
项目概览
github
/
hub
10 个月 前同步成功
通知
3
Star
22523
Fork
2406
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hub
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
13240c70
编写于
7月 02, 2013
作者:
J
Jingwen Owen Ou
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement merge
上级
c4425a04
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
173 addition
and
40 deletion
+173
-40
cmd/cmd.go
cmd/cmd.go
+5
-0
commands/args.go
commands/args.go
+12
-2
commands/args_test.go
commands/args_test.go
+19
-5
commands/checkout.go
commands/checkout.go
+30
-15
commands/clone_test.go
commands/clone_test.go
+4
-4
commands/merge.go
commands/merge.go
+51
-1
commands/merge_test.go
commands/merge_test.go
+39
-0
commands/remote_test.go
commands/remote_test.go
+4
-4
commands/runner.go
commands/runner.go
+9
-9
未找到文件。
cmd/cmd.go
浏览文件 @
13240c70
...
...
@@ -4,6 +4,7 @@ import (
"fmt"
"os"
"os/exec"
"strings"
"syscall"
)
...
...
@@ -12,6 +13,10 @@ type Cmd struct {
Args
[]
string
}
func
(
cmd
Cmd
)
String
()
string
{
return
fmt
.
Sprintf
(
"%s %s"
,
cmd
.
Name
,
strings
.
Join
(
cmd
.
Args
,
" "
))
}
func
(
cmd
*
Cmd
)
WithArg
(
arg
string
)
*
Cmd
{
cmd
.
Args
=
append
(
cmd
.
Args
,
arg
)
...
...
commands/args.go
浏览文件 @
13240c70
...
...
@@ -6,6 +6,7 @@ import (
)
type
Args
struct
{
Command
string
args
[]
string
beforeChain
[]
*
cmd
.
Cmd
afterChain
[]
*
cmd
.
Cmd
...
...
@@ -28,7 +29,7 @@ func (a *Args) Commands() []*cmd.Cmd {
}
func
(
a
*
Args
)
ToCmd
()
*
cmd
.
Cmd
{
return
cmd
.
New
(
"git"
)
.
WithArgs
(
a
.
Array
()
...
)
return
cmd
.
New
(
"git"
)
.
WithArg
(
a
.
Command
)
.
WithArg
s
(
a
.
Array
()
...
)
}
func
(
a
*
Args
)
Get
(
i
int
)
string
{
...
...
@@ -93,7 +94,16 @@ func (a *Args) Prepend(args ...string) {
}
func
NewArgs
(
args
[]
string
)
*
Args
{
return
&
Args
{
args
,
make
([]
*
cmd
.
Cmd
,
0
),
make
([]
*
cmd
.
Cmd
,
0
)}
var
command
string
var
a
[]
string
if
len
(
args
)
==
0
{
a
=
[]
string
{}
}
else
{
command
=
args
[
0
]
a
=
args
[
1
:
]
}
return
&
Args
{
command
,
a
,
make
([]
*
cmd
.
Cmd
,
0
),
make
([]
*
cmd
.
Cmd
,
0
)}
}
func
removeItem
(
slice
[]
string
,
index
int
)
(
newSlice
[]
string
,
item
string
)
{
...
...
commands/args_test.go
浏览文件 @
13240c70
...
...
@@ -5,12 +5,26 @@ import (
"testing"
)
func
TestNewArgs
(
t
*
testing
.
T
)
{
args
:=
NewArgs
([]
string
{})
assert
.
Equal
(
t
,
""
,
args
.
Command
)
assert
.
Equal
(
t
,
0
,
args
.
Size
())
args
=
NewArgs
([]
string
{
"command"
})
assert
.
Equal
(
t
,
"command"
,
args
.
Command
)
assert
.
Equal
(
t
,
0
,
args
.
Size
())
args
=
NewArgs
([]
string
{
"command"
,
"args"
})
assert
.
Equal
(
t
,
"command"
,
args
.
Command
)
assert
.
Equal
(
t
,
1
,
args
.
Size
())
}
func
TestRemove
(
t
*
testing
.
T
)
{
args
:=
NewArgs
([]
string
{
"1"
,
"2"
,
"3"
})
item
:=
args
.
Remove
(
1
)
args
:=
NewArgs
([]
string
{
"1"
,
"2"
,
"3"
,
"4"
})
assert
.
Equal
(
t
,
"2"
,
item
)
item
:=
args
.
Remove
(
1
)
assert
.
Equal
(
t
,
"3"
,
item
)
assert
.
Equal
(
t
,
2
,
args
.
Size
())
assert
.
Equal
(
t
,
"
1
"
,
args
.
First
())
assert
.
Equal
(
t
,
"
3
"
,
args
.
Get
(
1
))
assert
.
Equal
(
t
,
"
2
"
,
args
.
First
())
assert
.
Equal
(
t
,
"
4
"
,
args
.
Get
(
1
))
}
commands/checkout.go
浏览文件 @
13240c70
...
...
@@ -5,6 +5,7 @@ import (
"github.com/jingweno/gh/git"
"github.com/jingweno/gh/github"
"github.com/jingweno/gh/utils"
"github.com/jingweno/octokat"
"regexp"
)
...
...
@@ -28,9 +29,8 @@ set with BRANCH.
$ gh checkout https://github.com/jingweno/gh/pull/73 custom-branch-name
**/
func
checkout
(
command
*
Command
,
args
*
Args
)
{
var
err
error
if
!
args
.
IsEmpty
()
{
err
=
transformCheckoutArgs
(
args
)
err
:
=
transformCheckoutArgs
(
args
)
utils
.
Fatal
(
err
)
}
}
...
...
@@ -39,17 +39,13 @@ func transformCheckoutArgs(args *Args) error {
id
:=
parsePullRequestId
(
args
.
First
())
if
id
!=
""
{
url
:=
args
.
Remove
(
0
)
gh
:=
github
.
New
()
pullRequest
,
err
:=
gh
.
PullRequest
(
id
)
pullRequest
,
err
:=
fetchPullRequest
(
id
)
if
err
!=
nil
{
return
err
}
user
:=
pullRequest
.
User
.
Login
branch
:=
pullRequest
.
Head
.
Ref
if
pullRequest
.
Head
.
Repo
.
ID
==
0
{
return
fmt
.
Errorf
(
"%s's fork is not available anymore"
,
user
)
}
remoteExists
,
err
:=
checkIfRemoteExists
(
user
)
if
err
!=
nil
{
...
...
@@ -59,10 +55,13 @@ func transformCheckoutArgs(args *Args) error {
if
remoteExists
{
updateExistingRemote
(
args
,
user
,
branch
)
}
else
{
err
=
addRmote
(
args
,
user
,
branch
,
url
,
pullRequest
.
Head
.
Repo
.
Private
)
isSSH
:=
pullRequest
.
Head
.
Repo
.
Private
sshURL
,
err
:=
convertPullRequestURLToGitURL
(
url
,
user
,
isSSH
)
if
err
!=
nil
{
return
err
}
addRmote
(
args
,
user
,
branch
,
sshURL
)
}
var
newBranchName
string
...
...
@@ -90,6 +89,21 @@ func parsePullRequestId(url string) string {
return
""
}
func
fetchPullRequest
(
id
string
)
(
*
octokat
.
PullRequest
,
error
)
{
gh
:=
github
.
New
()
pullRequest
,
err
:=
gh
.
PullRequest
(
id
)
if
err
!=
nil
{
return
nil
,
err
}
if
pullRequest
.
Head
.
Repo
.
ID
==
0
{
user
:=
pullRequest
.
User
.
Login
return
nil
,
fmt
.
Errorf
(
"%s's fork is not available anymore"
,
user
)
}
return
pullRequest
,
nil
}
func
checkIfRemoteExists
(
remote
string
)
(
bool
,
error
)
{
remotes
,
err
:=
git
.
Remotes
()
if
err
!=
nil
{
...
...
@@ -111,14 +125,15 @@ func updateExistingRemote(args *Args, user, branch string) {
args
.
Before
(
"git"
,
"fetch"
,
user
,
remoteURL
)
}
func
addRmote
(
args
*
Args
,
user
,
branch
,
url
string
,
isPrivate
bool
)
error
{
project
,
err
:=
github
.
ParseProjectFromURL
(
url
)
func
addRmote
(
args
*
Args
,
user
,
branch
,
sshURL
string
)
{
args
.
Before
(
"git"
,
"remote"
,
"add"
,
"-f"
,
"-t"
,
branch
,
user
,
sshURL
)
}
func
convertPullRequestURLToGitURL
(
pullRequestURL
,
user
string
,
isSSH
bool
)
(
string
,
error
)
{
project
,
err
:=
github
.
ParseProjectFromURL
(
pullRequestURL
)
if
err
!=
nil
{
return
err
return
""
,
err
}
sshURL
:=
project
.
GitURL
(
""
,
user
,
isPrivate
)
args
.
Before
(
"git"
,
"remote"
,
"add"
,
"-f"
,
"-t"
,
branch
,
user
,
sshURL
)
return
nil
return
project
.
GitURL
(
""
,
user
,
isSSH
),
nil
}
commands/clone_test.go
浏览文件 @
13240c70
...
...
@@ -14,25 +14,25 @@ func TestTransformCloneArgs(t *testing.T) {
github
.
SaveConfig
(
&
config
)
defer
os
.
RemoveAll
(
filepath
.
Dir
(
github
.
DefaultConfigFile
))
args
:=
NewArgs
([]
string
{
"foo/gh"
})
args
:=
NewArgs
([]
string
{
"
clone"
,
"
foo/gh"
})
transformCloneArgs
(
args
)
assert
.
Equal
(
t
,
1
,
args
.
Size
())
assert
.
Equal
(
t
,
"git://github.com/foo/gh.git"
,
args
.
First
())
args
=
NewArgs
([]
string
{
"-p"
,
"foo/gh"
})
args
=
NewArgs
([]
string
{
"
clone"
,
"
-p"
,
"foo/gh"
})
transformCloneArgs
(
args
)
assert
.
Equal
(
t
,
1
,
args
.
Size
())
assert
.
Equal
(
t
,
"git@github.com:foo/gh.git"
,
args
.
First
())
args
=
NewArgs
([]
string
{
"jingweno/gh"
})
args
=
NewArgs
([]
string
{
"
clone"
,
"
jingweno/gh"
})
transformCloneArgs
(
args
)
assert
.
Equal
(
t
,
1
,
args
.
Size
())
assert
.
Equal
(
t
,
"git@github.com:jingweno/gh.git"
,
args
.
First
())
args
=
NewArgs
([]
string
{
"-p"
,
"acl-services/devise-acl"
})
args
=
NewArgs
([]
string
{
"
clone"
,
"
-p"
,
"acl-services/devise-acl"
})
transformCloneArgs
(
args
)
assert
.
Equal
(
t
,
1
,
args
.
Size
())
...
...
commands/merge.go
浏览文件 @
13240c70
package
commands
import
()
import
(
"fmt"
"github.com/jingweno/gh/utils"
"github.com/jingweno/octokat"
)
var
cmdMerge
=
&
Command
{
Run
:
merge
,
...
...
@@ -12,5 +16,51 @@ ID and title, similar to the GitHub Merge Button.
`
,
}
/*
$ gh merge https://github.com/jingweno/gh/pull/73
> git fetch git://github.com/jingweno/gh.git +refs/heads/feature:refs/remotes/jingweno/feature
> git merge jingweno/feature --no-ff -m 'Merge pull request #73 from jingweno/feature...'
*/
func
merge
(
command
*
Command
,
args
*
Args
)
{
if
!
args
.
IsEmpty
()
{
err
:=
transformMergeArgs
(
args
)
utils
.
Fatal
(
err
)
}
}
func
transformMergeArgs
(
args
*
Args
)
error
{
id
:=
parsePullRequestId
(
args
.
First
())
if
id
!=
""
{
pullRequest
,
err
:=
fetchPullRequest
(
id
)
if
err
!=
nil
{
return
err
}
err
=
fetchAndMerge
(
args
,
pullRequest
)
if
err
!=
nil
{
return
err
}
}
return
nil
}
func
fetchAndMerge
(
args
*
Args
,
pullRequest
*
octokat
.
PullRequest
)
error
{
user
:=
pullRequest
.
User
.
Login
branch
:=
pullRequest
.
Head
.
Ref
isSSH
:=
pullRequest
.
Head
.
Repo
.
Private
url
,
err
:=
convertPullRequestURLToGitURL
(
pullRequest
.
URL
,
user
,
isSSH
)
if
err
!=
nil
{
return
err
}
args
.
Remove
(
0
)
// Remove the pull request URL
mergeHead
:=
fmt
.
Sprintf
(
"%s/%s"
,
user
,
branch
)
ref
:=
fmt
.
Sprintf
(
"+refs/heads/%s:refs/remotes/%s"
,
branch
,
mergeHead
)
args
.
Before
(
"git"
,
"fetch"
,
url
,
ref
)
mergeMsg
:=
fmt
.
Sprintf
(
"'Merge pull request #%v from %s
\n\n
%s'"
,
pullRequest
.
Id
,
mergeHead
,
pullRequest
.
Title
)
args
.
Append
(
mergeHead
,
"--no-ff"
,
"-m"
,
mergeMsg
)
return
nil
}
commands/merge_test.go
0 → 100644
浏览文件 @
13240c70
package
commands
import
(
"github.com/bmizerany/assert"
"github.com/jingweno/octokat"
"testing"
)
func
TestFetchAndMerge
(
t
*
testing
.
T
)
{
url
:=
"https://github.com/jingweno/gh/pull/73"
args
:=
NewArgs
([]
string
{
"merge"
,
url
})
id
:=
73
title
:=
"title"
userLogin
:=
"jingweno"
user
:=
octokat
.
User
{
Login
:
userLogin
}
repoPrivate
:=
true
repo
:=
octokat
.
Repository
{
Private
:
repoPrivate
}
headRef
:=
"new-feature"
head
:=
octokat
.
Commit
{
Ref
:
headRef
,
Repo
:
repo
}
pullRequest
:=
octokat
.
PullRequest
{
Id
:
id
,
Title
:
title
,
URL
:
url
,
User
:
user
,
Head
:
head
}
err
:=
fetchAndMerge
(
args
,
&
pullRequest
)
assert
.
Equal
(
t
,
nil
,
err
)
cmds
:=
args
.
Commands
()
assert
.
Equal
(
t
,
2
,
len
(
cmds
))
cmd
:=
cmds
[
0
]
assert
.
Equal
(
t
,
"git fetch git@github.com:jingweno/gh.git +refs/heads/new-feature:refs/remotes/jingweno/new-feature"
,
cmd
.
String
())
cmd
=
cmds
[
1
]
assert
.
Equal
(
t
,
"git merge jingweno/new-feature --no-ff -m 'Merge pull request #73 from jingweno/new-feature
\n\n
title'"
,
cmd
.
String
())
}
commands/remote_test.go
浏览文件 @
13240c70
...
...
@@ -24,7 +24,7 @@ func TestParseRepoNameOwner(t *testing.T) {
}
func
TestTransformRemoteArgs
(
t
*
testing
.
T
)
{
args
:=
NewArgs
([]
string
{
"add"
,
"jingweno"
})
args
:=
NewArgs
([]
string
{
"
remote"
,
"
add"
,
"jingweno"
})
transformRemoteArgs
(
args
)
assert
.
Equal
(
t
,
3
,
args
.
Size
())
...
...
@@ -33,7 +33,7 @@ func TestTransformRemoteArgs(t *testing.T) {
reg
:=
regexp
.
MustCompile
(
"^git://github.com/jingweno/.+
\\
.git$"
)
assert
.
T
(
t
,
reg
.
MatchString
(
args
.
Get
(
2
)))
args
=
NewArgs
([]
string
{
"add"
,
"-p"
,
"jingweno"
})
args
=
NewArgs
([]
string
{
"
remote"
,
"
add"
,
"-p"
,
"jingweno"
})
transformRemoteArgs
(
args
)
assert
.
Equal
(
t
,
3
,
args
.
Size
())
...
...
@@ -47,7 +47,7 @@ func TestTransformRemoteArgs(t *testing.T) {
github
.
SaveConfig
(
&
config
)
defer
os
.
RemoveAll
(
filepath
.
Dir
(
github
.
DefaultConfigFile
))
args
=
NewArgs
([]
string
{
"add"
,
"origin"
})
args
=
NewArgs
([]
string
{
"
remote"
,
"
add"
,
"origin"
})
transformRemoteArgs
(
args
)
assert
.
Equal
(
t
,
3
,
args
.
Size
())
...
...
@@ -56,7 +56,7 @@ func TestTransformRemoteArgs(t *testing.T) {
reg
=
regexp
.
MustCompile
(
"^git://github.com/.+/.+
\\
.git$"
)
assert
.
T
(
t
,
reg
.
MatchString
(
args
.
Get
(
2
)))
args
=
NewArgs
([]
string
{
"add"
,
"jingweno"
,
"git@github.com:jingweno/gh.git"
})
args
=
NewArgs
([]
string
{
"
remote"
,
"
add"
,
"jingweno"
,
"git@github.com:jingweno/gh.git"
})
transformRemoteArgs
(
args
)
assert
.
Equal
(
t
,
3
,
args
.
Size
())
...
...
commands/runner.go
浏览文件 @
13240c70
...
...
@@ -12,29 +12,30 @@ type Runner struct {
func
(
r
*
Runner
)
Execute
()
error
{
args
:=
NewArgs
(
os
.
Args
[
1
:
])
if
args
.
Size
()
<
1
{
if
args
.
Command
==
""
{
usage
()
}
expandAlias
(
args
)
for
_
,
cmd
:=
range
All
()
{
if
cmd
.
Name
()
==
args
.
First
()
&&
cmd
.
Runnable
()
{
cmdArgs
:=
args
.
Rest
()
if
cmd
.
Name
()
==
args
.
Command
&&
cmd
.
Runnable
()
{
if
!
cmd
.
GitExtension
{
cmd
.
Flag
.
Usage
=
func
()
{
cmd
.
PrintUsage
()
}
cmdArgs
:=
args
.
Array
()
if
err
:=
cmd
.
Flag
.
Parse
(
cmdArgs
);
err
!=
nil
{
return
err
}
cmdArgs
=
cmd
.
Flag
.
Args
()
newArgs
:=
[]
string
{
cmd
.
Name
()}
newArgs
=
append
(
newArgs
,
cmdArgs
...
)
args
=
NewArgs
(
newArgs
)
}
args
=
NewArgs
(
cmdArgs
)
cmd
.
Run
(
cmd
,
args
)
args
.
Prepend
(
cmd
.
Name
())
cmds
:=
args
.
Commands
()
length
:=
len
(
cmds
)
...
...
@@ -55,14 +56,13 @@ func (r *Runner) Execute() error {
}
}
return
git
.
SysExec
(
args
.
First
(),
args
.
Rest
()
...
)
return
git
.
SysExec
(
args
.
Command
,
args
.
Array
()
...
)
}
func
expandAlias
(
args
*
Args
)
{
cmd
:=
args
.
First
()
cmd
:=
args
.
Command
expandedCmd
,
err
:=
git
.
Config
(
fmt
.
Sprintf
(
"alias.%s"
,
cmd
))
if
err
==
nil
&&
expandedCmd
!=
""
{
args
.
Remove
(
0
)
args
.
Prepend
(
expandedCmd
)
args
.
Command
=
expandedCmd
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录