Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: 1.20 broke buildvcs inside bare Git repositories with worktrees #59068

Closed
tie opened this issue Mar 16, 2023 · 7 comments
Closed

cmd/go: 1.20 broke buildvcs inside bare Git repositories with worktrees #59068

tie opened this issue Mar 16, 2023 · 7 comments

Comments

@tie
Copy link
Contributor

tie commented Mar 16, 2023

What version of Go are you using (go version)?

$ go version
go version go1.20.2 linux/arm64

Does this issue reproduce with the latest release?

Yes, this issue was introduced in Go 1.20 release.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/home/tie/.cache/go-build"
GOENV="/home/tie/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS="-trimpath"
GOHOSTARCH="arm64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/tie/go/pkg/mod"
GONOPROXY="go.pact.im/private"
GONOSUMDB="go.pact.im/private"
GOOS="linux"
GOPATH="/home/tie/go"
GOPRIVATE="go.pact.im/private"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/nix/store/hi9hs61z09yi1c9v5paw4273cbyhf51w-go-1.20.2/share/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/nix/store/hi9hs61z09yi1c9v5paw4273cbyhf51w-go-1.20.2/share/go/pkg/tool/linux_arm64"
GOVCS=""
GOVERSION="go1.20.2"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="0"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build711157649=/tmp/go-build -gno-record-gcc-switches"

What did you do?

go20-buildvcs-issue.sh
#!/bin/sh
set -eu

temp=$(mktemp -d)
cleanup() {
        rm -r -f -- "$temp"
}
trap cleanup EXIT

cd "$temp"

cat >go.mod <<EOF
module test
EOF

cat >main.go <<EOF
package main

import "fmt"

func main() {
        fmt.Println("OK")
}
EOF

(
        mkdir source && cd source
        git init --quiet
        cp ../go.mod ../main.go .
        git add go.mod main.go
        git commit --quiet --message 'initial commit'
)

gobuild() {
        go build -o out
        go version -m out
        ./out && rm out
}

go version

(
        echo && echo "Git repository"
        git clone --quiet ./source good && cd good
        gobuild
)
(
        echo && echo "Git repository with nested worktree"
        git clone --quiet ./source nested-worktree && cd nested-worktree
        git worktree add --quiet nested && cd nested
        gobuild
)
(
        echo && echo "Bare Git repository with worktree"
        git clone --quiet --bare ./source bare/.git && cd bare
        git worktree add --quiet main && cd main
        gobuild
)
Go 1.19
$ nix shell nixpkgs#go_1_19 -c sh go20-buildvcs-issue.sh 
go version go1.19.6 linux/arm64

Git repository
out: go1.19.6
        path    test
        mod     test    (devel)
        build   -compiler=gc
        build   -trimpath=true
        build   CGO_ENABLED=0
        build   GOARCH=arm64
        build   GOOS=linux
        build   vcs=git
        build   vcs.revision=043649dd3ee451e187991c8ce7d54934b2d47cda
        build   vcs.time=2023-03-16T03:13:43Z
        build   vcs.modified=false
OK

Git repository with nested worktree
out: go1.19.6
        path    test
        mod     test    (devel)
        build   -compiler=gc
        build   -trimpath=true
        build   CGO_ENABLED=0
        build   GOARCH=arm64
        build   GOOS=linux
        build   vcs=git
        build   vcs.revision=043649dd3ee451e187991c8ce7d54934b2d47cda
        build   vcs.time=2023-03-16T03:13:43Z
        build   vcs.modified=false
OK

Bare Git repository with worktree
out: go1.19.6
        path    test
        mod     test    (devel)
        build   -compiler=gc
        build   -trimpath=true
        build   CGO_ENABLED=0
        build   GOARCH=arm64
        build   GOOS=linux
        build   vcs=git
        build   vcs.revision=043649dd3ee451e187991c8ce7d54934b2d47cda
        build   vcs.time=2023-03-16T03:13:43Z
        build   vcs.modified=false
OK
Go 1.20
$ nix shell nixpkgs#go_1_20 -c sh go20-buildvcs-issue.sh 
go version go1.20.2 linux/arm64

Git repository
out: go1.20.2
        path    test
        mod     test    (devel)
        build   -buildmode=exe
        build   -compiler=gc
        build   -trimpath=true
        build   CGO_ENABLED=0
        build   GOARCH=arm64
        build   GOOS=linux
        build   vcs=git
        build   vcs.revision=fc4846bf2f91ae1065294ddb0d1696e58a9cf850
        build   vcs.time=2023-03-16T03:17:37Z
        build   vcs.modified=false
OK

Git repository with nested worktree
out: go1.20.2
        path    test
        mod     test    (devel)
        build   -buildmode=exe
        build   -compiler=gc
        build   -trimpath=true
        build   CGO_ENABLED=0
        build   GOARCH=arm64
        build   GOOS=linux
        build   vcs=git
        build   vcs.revision=fc4846bf2f91ae1065294ddb0d1696e58a9cf850
        build   vcs.time=2023-03-16T03:17:37Z
        build   vcs.modified=true
OK

Bare Git repository with worktree
error obtaining VCS status: exit status 128
        Use -buildvcs=false to disable VCS stamping.

Notice that Go 1.19 works fine with this setup.

A shorter reproducer for this bug:

go20-buildvcs-issue.sh
#!/bin/sh
set -eu

temp=$(mktemp -d)
cleanup() {
        rm -r -f -- "$temp"
}
trap cleanup EXIT

cd "$temp"
git init --quiet
echo -n 'module test' >go.mod
echo -n 'package main;func main(){}' >main.go
git add go.mod main.go
git commit --quiet --message 'initial commit'
git config core.bare true && rm go.mod main.go
git worktree add --quiet main && cd main
go build -o out
go version -m out

Also note that this is not an issue with Go version in Nixpkgs, the examples above use nix just to avoid installing different Go versions.

What did you expect to see?

All builds succeed.

What did you see instead?

Go 1.20 runs git status --porcelain outside of the Git work tree, the command fails with fatal: this operation must be run in a work tree error.

@tie
Copy link
Contributor Author

tie commented Mar 16, 2023

Seems to be introduced in bb39656 that added checks for file mode when searching for repository root.

@tie
Copy link
Contributor Author

tie commented Mar 16, 2023

For reference, in Git work trees, .git is a file containing gitdir: <path-to-root>/.git/worktrees/<name> (although the path is absolute by default, Git works with relative paths too).

https://github.com/git/git/blob/73876f4861cd3d187a4682290ab75c9dccadbc56/setup.c#L843-L866

@tie
Copy link
Contributor Author

tie commented Mar 16, 2023

I’m not really sure if bb39656 was the right way to fix the case in #53640, which had a broken Git repository in the first place (since only the submodule was copied to the Docker container without the Git directory).

Before this change, VCS stamping worked in perfectly valid Git repositories with gitdir link but did not in “broken” (i.e. where gitdir points to a non-existent Git directory). Now it just doesn’t work.

@seankhliao
Copy link
Member

I still think the fix for #58218 will do what you want
CL 463849

@tie
Copy link
Contributor Author

tie commented Mar 16, 2023

Oh, right, sorry for not looking up existing issues! I known that work trees are somewhat an advanced Git feature and are likely used by a minority of users, and since this wasn’t fixed yet I’ve assumed that nobody reported this issue 😅

Will the fix be eventually backported to 1.20 release?

@seankhliao
Copy link
Member

cc @bcmills @mvdan

@mvdan
Copy link
Member

mvdan commented Mar 16, 2023

Yes, this is a duplicate. And I would say we would backport the revert, given that it's a regression and the revert should be relatively harmless.

@mvdan mvdan closed this as not planned Won't fix, can't repro, duplicate, stale Mar 16, 2023
@golang golang locked and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants