diff --git a/commands.go b/commands.go index dd64c0f..a2bdf38 100644 --- a/commands.go +++ b/commands.go @@ -29,6 +29,7 @@ var cloneFlags = []cli.Flag{ &cli.BoolFlag{Name: "look, l", Usage: "Look after get"}, &cli.StringFlag{Name: "vcs", Usage: "Specify VCS backend for cloning"}, &cli.BoolFlag{Name: "silent, s", Usage: "clone or update silently"}, + &cli.StringFlag{Name: "branch, b", Usage: "Specify branch name. This flag implies --single-branch on Git"}, } var commandGet = cli.Command{ @@ -140,6 +141,7 @@ func doGet(c *cli.Context) error { ssh: c.Bool("p"), vcs: c.String("vcs"), silent: c.Bool("silent"), + branch: c.String("branch"), } if argURL == "" { diff --git a/getter.go b/getter.go index bbc9514..de37c9a 100644 --- a/getter.go +++ b/getter.go @@ -28,7 +28,7 @@ func getRepoLock(localRepoRoot string) bool { type getter struct { update, shallow, silent, ssh bool - vcs string + vcs, branch string } func (g *getter) get(argURL string) error { @@ -135,7 +135,7 @@ func (g *getter) getRemoteRepository(remote RemoteRepository) error { } if getRepoLock(localRepoRoot) { - return vcs.Clone(repoURL, localRepoRoot, g.shallow, g.silent) + return vcs.Clone(repoURL, localRepoRoot, g.shallow, g.silent, g.branch) } return nil } diff --git a/vcs.go b/vcs.go index 4e5c847..e9487e0 100644 --- a/vcs.go +++ b/vcs.go @@ -26,14 +26,14 @@ func runInDir(silent bool) func(dir, command string, args ...string) error { // A VCSBackend represents a VCS backend. type VCSBackend struct { // Clones a remote repository to local path. - Clone func(*url.URL, string, bool, bool) error + Clone func(*url.URL, string, bool, bool, string) error // Updates a cloned local repository. Update func(string, bool) error } var GitBackend = &VCSBackend{ // support submodules? - Clone: func(remote *url.URL, local string, shallow, silent bool) error { + Clone: func(remote *url.URL, local string, shallow, silent bool, branch string) error { dir, _ := filepath.Split(local) err := os.MkdirAll(dir, 0755) if err != nil { @@ -44,6 +44,9 @@ var GitBackend = &VCSBackend{ if shallow { args = append(args, "--depth", "1") } + if branch != "" { + args = append(args, "--branch", branch, "--single-branch") + } args = append(args, remote.String(), local) return run(silent)("git", args...) @@ -54,7 +57,7 @@ var GitBackend = &VCSBackend{ } var SubversionBackend = &VCSBackend{ - Clone: func(remote *url.URL, local string, shallow, silent bool) error { + Clone: func(remote *url.URL, local string, shallow, silent bool, branch string) error { dir, _ := filepath.Split(local) err := os.MkdirAll(dir, 0755) if err != nil { @@ -65,6 +68,9 @@ var SubversionBackend = &VCSBackend{ if shallow { args = append(args, "--depth", "1") } + if branch != "" { + remote.Path += "/branches/" + url.PathEscape(branch) + } args = append(args, remote.String(), local) return run(silent)("svn", args...) @@ -76,12 +82,15 @@ var SubversionBackend = &VCSBackend{ var GitsvnBackend = &VCSBackend{ // git-svn seems not supporting shallow clone currently. - Clone: func(remote *url.URL, local string, ignoredShallow, silent bool) error { + Clone: func(remote *url.URL, local string, ignoredShallow, silent bool, branch string) error { dir, _ := filepath.Split(local) err := os.MkdirAll(dir, 0755) if err != nil { return err } + if branch != "" { + remote.Path += "/branches/" + url.PathEscape(branch) + } return run(silent)("git", "svn", "clone", remote.String(), local) }, @@ -92,14 +101,18 @@ var GitsvnBackend = &VCSBackend{ var MercurialBackend = &VCSBackend{ // Mercurial seems not supporting shallow clone currently. - Clone: func(remote *url.URL, local string, ignoredShallow, silent bool) error { + Clone: func(remote *url.URL, local string, ignoredShallow, silent bool, branch string) error { dir, _ := filepath.Split(local) err := os.MkdirAll(dir, 0755) if err != nil { return err } + args := []string{"clone", remote.String(), local} + if branch != "" { + args = append(args, "--branch", branch) + } - return run(silent)("hg", "clone", remote.String(), local) + return run(silent)("hg", args...) }, Update: func(local string, silent bool) error { return runInDir(silent)(local, "hg", "pull", "--update") @@ -107,7 +120,11 @@ var MercurialBackend = &VCSBackend{ } var DarcsBackend = &VCSBackend{ - Clone: func(remote *url.URL, local string, shallow, silent bool) error { + Clone: func(remote *url.URL, local string, shallow, silent bool, branch string) error { + if branch != "" { + return errors.New("Darcs does not support branch") + } + dir, _ := filepath.Split(local) err := os.MkdirAll(dir, 0755) if err != nil { @@ -128,7 +145,7 @@ var DarcsBackend = &VCSBackend{ } var cvsDummyBackend = &VCSBackend{ - Clone: func(remote *url.URL, local string, ignoredShallow, silent bool) error { + Clone: func(remote *url.URL, local string, ignoredShallow, silent bool, branch string) error { return errors.New("CVS clone is not supported") }, Update: func(local string, silent bool) error { @@ -139,7 +156,10 @@ var cvsDummyBackend = &VCSBackend{ const fossilRepoName = ".fossil" // same as Go var FossilBackend = &VCSBackend{ - Clone: func(remote *url.URL, local string, shallow, silent bool) error { + Clone: func(remote *url.URL, local string, shallow, silent bool, branch string) error { + if branch != "" { + return errors.New("Fossil does not support cloning specific branch") + } if err := os.MkdirAll(local, 0755); err != nil { return err } @@ -156,7 +176,10 @@ var FossilBackend = &VCSBackend{ var BazaarBackend = &VCSBackend{ // bazaar seems not supporting shallow clone currently. - Clone: func(remote *url.URL, local string, ignoredShallow, silent bool) error { + Clone: func(remote *url.URL, local string, ignoredShallow, silent bool, branch string) error { + if branch != "" { + return errors.New("--branch option is unavailable for Bazaar since branch is included in remote URL") + } dir, _ := filepath.Split(local) err := os.MkdirAll(dir, 0755) if err != nil {