hub/commands/clone.go

157 строки
3.5 KiB
Go
Исходник Обычный вид История

2013-07-01 21:11:02 +04:00
package commands
import (
"fmt"
2013-07-01 21:11:02 +04:00
"regexp"
"strings"
"github.com/github/hub/github"
"github.com/github/hub/utils"
2013-07-01 21:11:02 +04:00
)
var cmdClone = &Command{
Run: clone,
GitExtension: true,
Usage: "clone [-p] [<OPTIONS>] [<USER>/]<REPOSITORY> [<DESTINATION>]",
Long: `Clone a repository from GitHub.
## Options:
-p
(Deprecated) Clone private repositories over SSH.
[<USER>/]<REPOSITORY>
<USER> defaults to your own GitHub username.
<DESTINATION>
Directory name to clone into (default: <REPOSITORY>).
## Protocol used for cloning
The 'git:' protocol will be used for cloning public repositories, while the SSH
protocol will be used for private repositories and those that you have push
2018-08-31 20:38:04 +03:00
access to. Alternatively, hub can be configured to use HTTPS protocol for
everything. See "HTTPS instead of git protocol" and "HUB_PROTOCOL" of hub(1).
## Examples:
$ hub clone rtomayko/ronn
> git clone git://github.com/rtomayko/ronn.git
2016-01-24 18:50:01 +03:00
## See also:
hub-fork(1), hub(1), git-clone(1)
2013-07-01 22:12:46 +04:00
`,
2013-07-01 21:11:02 +04:00
}
func init() {
CmdRunner.Use(cmdClone)
}
2013-07-01 21:11:02 +04:00
func clone(command *Command, args *Args) {
2013-07-02 22:56:45 +04:00
if !args.IsParamsEmpty() {
2013-07-01 21:11:02 +04:00
transformCloneArgs(args)
}
}
func transformCloneArgs(args *Args) {
isSSH := parseClonePrivateFlag(args)
// git help clone | grep -e '^ \+-.\+<'
p := utils.NewArgsParser()
p.RegisterValue("--branch", "-b")
p.RegisterValue("--depth")
p.RegisterValue("--reference")
if args.Command == "submodule" {
p.RegisterValue("--name")
} else {
p.RegisterValue("--config", "-c")
p.RegisterValue("--jobs", "-j")
p.RegisterValue("--origin", "-o")
p.RegisterValue("--reference-if-able")
p.RegisterValue("--separate-git-dir")
p.RegisterValue("--shallow-exclude")
p.RegisterValue("--shallow-since")
p.RegisterValue("--template")
p.RegisterValue("--upload-pack", "-u")
}
p.Parse(args.Params)
2013-07-01 21:11:02 +04:00
nameWithOwnerRegexp := regexp.MustCompile(NameWithOwnerRe)
for _, i := range p.PositionalIndices {
2013-12-11 12:04:30 +04:00
a := args.Params[i]
if nameWithOwnerRegexp.MatchString(a) && !isCloneable(a) {
url := getCloneUrl(a, isSSH, args.Command != "submodule")
args.ReplaceParam(i, url)
2013-07-01 21:11:02 +04:00
}
break
2013-07-01 21:11:02 +04:00
}
}
func parseClonePrivateFlag(args *Args) bool {
2013-07-02 22:56:45 +04:00
if i := args.IndexOfParam("-p"); i != -1 {
args.RemoveParam(i)
2013-07-01 21:11:02 +04:00
return true
}
return false
}
2013-07-01 21:37:40 +04:00
func getCloneUrl(nameWithOwner string, isSSH, allowSSH bool) string {
name := nameWithOwner
owner := ""
if strings.Contains(name, "/") {
split := strings.SplitN(name, "/", 2)
2013-07-01 21:37:40 +04:00
owner = split[0]
name = split[1]
}
var host *github.Host
if owner == "" {
config := github.CurrentConfig()
h, err := config.DefaultHost()
if err != nil {
utils.Check(github.FormatError("cloning repository", err))
}
host = h
owner = host.User
}
var hostStr string
if host != nil {
hostStr = host.Host
}
expectWiki := strings.HasSuffix(name, ".wiki")
if expectWiki {
name = strings.TrimSuffix(name, ".wiki")
}
project := github.NewProject(owner, name, hostStr)
gh := github.NewClient(project.Host)
repo, err := gh.Repository(project)
if err != nil {
if strings.Contains(err.Error(), "HTTP 404") {
err = fmt.Errorf("Error: repository %s/%s doesn't exist", project.Owner, project.Name)
}
utils.Check(err)
}
owner = repo.Owner.Login
name = repo.Name
if expectWiki {
if !repo.HasWiki {
utils.Check(fmt.Errorf("Error: %s/%s doesn't have a wiki", owner, name))
} else {
name = name + ".wiki"
}
}
if !isSSH &&
allowSSH &&
!github.IsHttpsProtocol() {
isSSH = repo.Private || repo.Permissions.Push
2013-07-01 21:37:40 +04:00
}
return project.GitURL(name, owner, isSSH)
2013-07-01 21:37:40 +04:00
}