Git commit可以通过命令行工作,但在Golang代码中失败。

huangapple go评论78阅读模式
英文:

Git commit works from command line, but fails from golang code

问题

我正在尝试执行下面提到的代码。该代码创建一个分支,然后从工作树目录进行工作树和提交。

该代码失败,并显示以下错误:

error= exit status 1

如果我直接从命令行执行提交(Cmd3),则可以正常工作:

sh-3.2# /usr/bin/git -C /Users/gitissue/folder1/Outer commit -m Commiting-from-folder1-Outer
On branch Outer
nothing to commit, working tree clean

步骤:

  1. 创建文件夹 /Users/gitissue
  2. cd /Users/gitissue
  3. git init
  4. touch t.txt
  5. git add .
  6. git commit -m "commit"
  7. mkdir -p /Users/gitissue/folder1
  8. 执行下面提到的 Go 代码

环境详细信息:

  • MAC OS
  • git 版本 2.37.0
  • go 版本 go1.18.1 darwin/amd64

代码:

package main

import (
"fmt"
"io"
exec "os/exec"
)

func main() {

Cmd := exec.Command("git", "-C", "/Users/gitissue", "branch", "Outer")
fmt.Print("Cmd1= " + Cmd.String())
err := execBashCmd(Cmd)
if err != nil {
	fmt.Print("error1= " + err.Error())
}


Cmd = exec.Command("git", "-C", "/Users/gitissue/folder1", "worktree", "add", "Outer", "Outer")
fmt.Print("Cmd2= " + Cmd.String())
err = execBashCmd(Cmd)
if err != nil {
	fmt.Print("error2= " + err.Error())
}

Cmd = exec.Command("git", "-C", "/Users/gitissue/folder1/Outer", "commit", "-m", "Commiting-from-folder1-Outer")
fmt.Print("Cmd3= " + Cmd.String())

err = execBashCmd(Cmd)
if err != nil {
	fmt.Print("error3= " + err.Error())
}

}

func execBashCmd(cmd *exec.Cmd) error {

stderr, _ := cmd.StderrPipe()

if err := cmd.Start(); err != nil {
	fmt.Print("error= " + err.Error())
}

slurp, _ := io.ReadAll(stderr)
fmt.Printf("%s\n", slurp)

if slurp != nil {
}

if err := cmd.Wait(); err != nil {
	fmt.Print("error= " + err.Error())
	return err
}
return nil

}

以上代码的输出:

Cmd1= /usr/bin/git -C /Users/gitissue branch Outer
Cmd2= /usr/bin/git -C /Users/gitissue/folder1 worktree add Outer OuterPreparing worktree (checking out 'Outer')

Cmd3= /usr/bin/git -C /Users/gitissue/folder1/Outer commit -m Commiting-from-folder1-Outer
error= exit status 1error3= exit status 1
英文:

I am trying to execute the code mentioned below. The code creates a branch, and then a worktree and commit is done from worktree directory

The code fails with below error:

error= exit status 1

If I execute the commit (Cmd3) directly from command line, it works fine:

sh-3.2# /usr/bin/git -C /Users/gitissue/folder1/Outer commit -m Commiting-from-folder1-Outer
On branch Outer
nothing to commit, working tree clean

Steps:

  1. Created folder /Users/gitissue
  2. cd /Users/gitissue
  3. git init
  4. touch t.txt
  5. git add .
  6. git commit -m "commit"
  7. mkdir -p /Users/gitissue/folder1
  8. execute go code mentioned below

Env details:

  • MAC OS
  • git version 2.37.0
  • go version go1.18.1 darwin/amd64

Code:

package main

import (
"fmt"
"io"
exec "os/exec"
)

func main() {

Cmd := exec.Command("git", "-C", "/Users/gitissue", "branch", "Outer")
fmt.Print("Cmd1= " + Cmd.String())
err := execBashCmd(Cmd)
if err != nil {
	fmt.Print("error1= " + err.Error())
}


Cmd = exec.Command("git", "-C", "/Users/gitissue/folder1", "worktree", "add", "Outer", "Outer")
fmt.Print("Cmd2= " + Cmd.String())
err = execBashCmd(Cmd)
if err != nil {
	fmt.Print("error2= " + err.Error())
}

Cmd = exec.Command("git", "-C", "/Users/gitissue/folder1/Outer", "commit", "-m", "Commiting-from-folder1-Outer")
fmt.Print("Cmd3= " + Cmd.String())

err = execBashCmd(Cmd)
if err != nil {
	fmt.Print("error3= " + err.Error())
}

}

func execBashCmd(cmd *exec.Cmd) error {

stderr, _ := cmd.StderrPipe()

if err := cmd.Start(); err != nil {
	fmt.Print("error= " + err.Error())
}

slurp, _ := io.ReadAll(stderr)
fmt.Printf("%s\n", slurp)

if slurp != nil {
}

if err := cmd.Wait(); err != nil {
	fmt.Print("error= " + err.Error())
	return err
}
return nil

}

Output of above code:

Cmd1= /usr/bin/git -C /Users/gitissue branch Outer
Cmd2= /usr/bin/git -C /Users/gitissue/folder1 worktree add Outer OuterPreparing worktree (checking out 'Outer')

Cmd3= /usr/bin/git -C /Users/gitissue/folder1/Outer commit -m Commiting-from-folder1-Outer
error= exit status 1error3= exit status 1

答案1

得分: 5

完全没有错误。当没有要提交的内容时,Git 以退出码 1 退出。

根据 Go wait() 的文档 描述,"如果命令运行正常,没有问题地复制 stdin、stdout 和 stderr,并且以零退出状态退出,返回的错误为 nil"。

如果你愿意,你可以包装错误,看它是否实现了 ExitCode() 方法,这意味着生成的错误是由于非零的退出码,然后如果退出码是 1,可以忽略它(或者你可以使用任何其他类型的逻辑来处理这种情况)。

if err := cmd.Wait(); err != nil {
    if e, ok := err.(interface{ExitCode() int}); ok {
        if e.ExitCode() != 1 {
            // 退出码既不是零(因为有错误),也不是一
            fmt.Print("error= " + err.Error())
            return err
        }
    } else {
        return err
    }
}
英文:

There is no error at all. When there is nothing to commit, Git exits with exit code 1.

As described in the documentation for Go wait(), "the returned error is nil if the command runs, has no problems copying stdin, stdout, and stderr, and exits with a zero exit status."

If you want, you can wrap around the error to see if it implements the method ExitCode(), which means the error generated was because of a non-zero exit code, and then if the exit code was 1, ignore it (or you could use any other type of logic to handle this situation).

if err := cmd.Wait(); err != nil {
    if e, ok := err.(interface{ExitCode() int}); ok {
        if e.ExitCode() != 1 {
            // exit code is neither zero (as we have an error) or one
            fmt.Print("error= " + err.Error())
            return err
        }
    } else {
        return err
    }
}

huangapple
  • 本文由 发表于 2022年10月3日 19:31:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/73934805.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定