@@ -51,12 +51,12 @@ A repository can be supplied as an argument in any of the following formats:
5151}
5252
5353var repoCloneCmd = & cobra.Command {
54- Use : "clone <repo>" ,
54+ Use : "clone <repo> [<directory>] " ,
5555 Args : cobra .MinimumNArgs (1 ),
5656 Short : "Clone a repository locally" ,
5757 Long : `Clone a GitHub repository locally.
5858
59- To pass 'git clone' options , separate them with '--'.` ,
59+ To pass 'git clone' flags , separate them with '--'.` ,
6060 RunE : repoClone ,
6161}
6262
@@ -87,6 +87,41 @@ With no argument, the repository for the current directory is displayed.`,
8787 RunE : repoView ,
8888}
8989
90+ func parseCloneArgs (extraArgs []string ) (args []string , target string ) {
91+ args = extraArgs
92+
93+ if len (args ) > 0 {
94+ if ! strings .HasPrefix (args [0 ], "-" ) {
95+ target , args = args [0 ], args [1 :]
96+ }
97+ }
98+ return
99+ }
100+
101+ func runClone (cloneURL string , args []string ) (target string , err error ) {
102+ cloneArgs , target := parseCloneArgs (args )
103+
104+ cloneArgs = append (cloneArgs , cloneURL )
105+
106+ // If the args contain an explicit target, pass it to clone
107+ // otherwise, parse the URL to determine where git cloned it to so we can return it
108+ if target != "" {
109+ cloneArgs = append (cloneArgs , target )
110+ } else {
111+ target = path .Base (strings .TrimSuffix (cloneURL , ".git" ))
112+ }
113+
114+ cloneArgs = append ([]string {"clone" }, cloneArgs ... )
115+
116+ cloneCmd := git .GitCommand (cloneArgs ... )
117+ cloneCmd .Stdin = os .Stdin
118+ cloneCmd .Stdout = os .Stdout
119+ cloneCmd .Stderr = os .Stderr
120+
121+ err = run .PrepareCmd (cloneCmd ).Run ()
122+ return
123+ }
124+
90125func repoClone (cmd * cobra.Command , args []string ) error {
91126 cloneURL := args [0 ]
92127 if ! strings .Contains (cloneURL , ":" ) {
@@ -115,21 +150,13 @@ func repoClone(cmd *cobra.Command, args []string) error {
115150 }
116151 }
117152
118- cloneArgs := []string {"clone" }
119- cloneArgs = append (cloneArgs , args [1 :]... )
120- cloneArgs = append (cloneArgs , cloneURL )
121-
122- cloneCmd := git .GitCommand (cloneArgs ... )
123- cloneCmd .Stdin = os .Stdin
124- cloneCmd .Stdout = os .Stdout
125- cloneCmd .Stderr = os .Stderr
126- err := run .PrepareCmd (cloneCmd ).Run ()
153+ cloneDir , err := runClone (cloneURL , args [1 :])
127154 if err != nil {
128155 return err
129156 }
130157
131158 if parentRepo != nil {
132- err := addUpstreamRemote (parentRepo , cloneURL )
159+ err := addUpstreamRemote (parentRepo , cloneDir )
133160 if err != nil {
134161 return err
135162 }
@@ -138,10 +165,9 @@ func repoClone(cmd *cobra.Command, args []string) error {
138165 return nil
139166}
140167
141- func addUpstreamRemote (parentRepo ghrepo.Interface , cloneURL string ) error {
168+ func addUpstreamRemote (parentRepo ghrepo.Interface , cloneDir string ) error {
142169 // TODO: support SSH remote URLs
143170 upstreamURL := fmt .Sprintf ("https://github.com/%s.git" , ghrepo .FullName (parentRepo ))
144- cloneDir := path .Base (strings .TrimSuffix (cloneURL , ".git" ))
145171
146172 cloneCmd := git .GitCommand ("-C" , cloneDir , "remote" , "add" , "upstream" , upstreamURL )
147173 cloneCmd .Stdout = os .Stdout
@@ -425,16 +451,12 @@ func repoFork(cmd *cobra.Command, args []string) error {
425451 }
426452 }
427453 if cloneDesired {
428- cloneCmd := git .GitCommand ("clone" , forkedRepo .CloneURL )
429- cloneCmd .Stdin = os .Stdin
430- cloneCmd .Stdout = os .Stdout
431- cloneCmd .Stderr = os .Stderr
432- err = run .PrepareCmd (cloneCmd ).Run ()
454+ cloneDir , err := runClone (forkedRepo .CloneURL , []string {})
433455 if err != nil {
434456 return fmt .Errorf ("failed to clone fork: %w" , err )
435457 }
436458
437- err = addUpstreamRemote (toFork , forkedRepo . CloneURL )
459+ err = addUpstreamRemote (toFork , cloneDir )
438460 if err != nil {
439461 return err
440462 }
0 commit comments