2

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
  • 3
    Grab the [`CombinedOutput`](https://pkg.go.dev/os/exec#Cmd.CombinedOutput) from each command and see what is causing it to error out. – Adrian Oct 03 '22 at 13:35
  • error= exec: already startedpanic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x1075854] `cmd.Wait()` should close it, right? I tried adding some time.sleep(), but doesn't help – Shiv Industries Oct 03 '22 at 15:13
  • Your code has no concurrency so I don't see why a sleep would help. That output implies you have a `nil` value somewhere, which should have been in the original output of your code. – Adrian Oct 03 '22 at 15:32
  • Related, possibly even a dup: [How to git commit nothing without an error?](https://stackoverflow.com/q/8123674/184546) – TTT Oct 03 '22 at 16:29
  • `Cmd = exec.Command("git", "-C", "/Users/gitissue/folder1/Outer", "commit", "-m", "Commiting-from-folder1-Outer")` `stdoutStderr, err := Cmd.CombinedOutput()` – Shiv Industries Oct 03 '22 at 17:13
  • Output: sh-3.2# go run hello.go 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 Std Out and err:- On branch Outer nothing to commit, working tree clean` – Shiv Industries Oct 03 '22 at 17:15
  • @Adrian, I misunderstood Cmd.CombinedOutput(). I added that, but did not comment the execBash earlier. So basically if I change the code as above, commenting execBash, the commit works fine. Thanks for your input – Shiv Industries Oct 03 '22 at 17:18

1 Answers1

5

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
    }
}
Marc Sances
  • 2,402
  • 1
  • 19
  • 34
  • Thanks @Marc. The commit is indeed successful, because if I check `git log` from /Users/gitissue/folder1/Outer , it shows a commit. – Shiv Industries Oct 03 '22 at 17:17