@@ -11,6 +11,7 @@ import (
1111 "net/url"
1212 "os"
1313 "os/exec"
14+ "path/filepath"
1415 "regexp"
1516 "strconv"
1617 "strings"
@@ -290,17 +291,21 @@ func runServ(c *cli.Context) error {
290291 return nil
291292 }
292293
293- // Special handle for Windows.
294- if setting .IsWindows {
295- verb = strings .Replace (verb , "-" , " " , 1 )
296- }
297-
298294 var gitcmd * exec.Cmd
299- verbs := strings .Split (verb , " " )
300- if len (verbs ) == 2 {
301- gitcmd = exec .CommandContext (ctx , verbs [0 ], verbs [1 ], repoPath )
302- } else {
303- gitcmd = exec .CommandContext (ctx , verb , repoPath )
295+ gitBinPath := filepath .Dir (git .GitExecutable ) // e.g. /usr/bin
296+ gitBinVerb := filepath .Join (gitBinPath , verb ) // e.g. /usr/bin/git-upload-pack
297+ if _ , err := os .Stat (gitBinVerb ); err != nil {
298+ // if the command "git-upload-pack" doesn't exist, try to split "git-upload-pack" to use the sub-command with git
299+ // ps: Windows only has "git.exe" in the bin path, so Windows always uses this way
300+ verbFields := strings .SplitN (verb , "-" , 2 )
301+ if len (verbFields ) == 2 {
302+ // use git binary with the sub-command part: "C:\...\bin\git.exe", "upload-pack", ...
303+ gitcmd = exec .CommandContext (ctx , git .GitExecutable , verbFields [1 ], repoPath )
304+ }
305+ }
306+ if gitcmd == nil {
307+ // by default, use the verb (it has been checked above by allowedCommands)
308+ gitcmd = exec .CommandContext (ctx , gitBinVerb , repoPath )
304309 }
305310
306311 process .SetSysProcAttribute (gitcmd )
0 commit comments