golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.89k stars 17.52k forks source link

cmd/go: binary does not contain VCS information when compiled in git worktree dir #58218

Open rogpeppe opened 1 year ago

rogpeppe commented 1 year ago

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

$ go version
go version go1.20rc3 linux/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
$ go env
GO111MODULE="auto"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/rogpeppe/.cache/go-build"
GOENV="/home/rogpeppe/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/rogpeppe/src/go/pkg/mod"
GONOPROXY="github.com/influxdata/idpe"
GONOSUMDB="github.com/influxdata/idpe"
GOOS="linux"
GOPATH="/home/rogpeppe/src/go"
GOPRIVATE="github.com/influxdata/idpe"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/rogpeppe/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/rogpeppe/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.20rc3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/rogpeppe/src/cuelabs/cue2/go.mod"
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 -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3009011258=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Run testscript on the following file:

# set up git repository and build first binary
cd d1
exec git init
exec git add .
exec git commit -m 'initial commit'
exec go build -o $TMPDIR/prog1 .

# set up worktree and build second binary
exec git worktree add -b main1 ../d2 HEAD
cd ../d2
exec go build -o $TMPDIR/prog2 .

# ensure first binary has VCS info
exec go version -m $TMPDIR/prog1
stdout 'vcs.revision='

# ensure second binary has VCS info
exec go version -m $TMPDIR/prog2
stdout 'vcs.revision='

-- d1/go.mod --
module example

-- d1/main.go --
package main

func main() {}

What did you expect to see?

A successful test.

What did you see instead?

The binary built in a git worktree directory does not contain VCS information. I suspect the logic doesn't understand that .git can be a file was well as a directory.

# set up git repository and build first binary (0.096s)
# set up worktree and build second binary (0.088s)
# ensure first binary has VCS info (0.002s)
# ensure second binary has VCS info (0.002s)
> exec go version -m $TMPDIR/prog2
[stdout]
$WORK/.tmp/prog2: go1.20rc3
    path    example
    mod example (devel) 
    build   -buildmode=exe
    build   -compiler=gc
    build   CGO_ENABLED=1
    build   CGO_CFLAGS=
    build   CGO_CPPFLAGS=
    build   CGO_CXXFLAGS=
    build   CGO_LDFLAGS=
    build   GOARCH=amd64
    build   GOOS=linux
    build   GOAMD64=v1
> stdout 'vcs.revision='
FAIL: /tmp/testscript498691614/x.txtar/script.txtar:19: no match for `vcs.revision=` found in stdout
error running /tmp/x.txtar in /tmp/testscript498691614/x.txtar
mknyszek commented 1 year ago

CC @bcmills @matloob

mknyszek commented 1 year ago

Does this reproduce with earlier releases?

mvdan commented 1 year ago

It does; I have a fix ready. It's a rather simple one, we were just assuming that .git was always a directory in -buildvcs=auto.

gopherbot commented 1 year ago

Change https://go.dev/cl/463849 mentions this issue: cmd/go: support git worktree checkouts in -buildvcs=auto

tie commented 1 year ago

As mentioned in #58978 and #59068, this issue also affects work trees inside bare Git repositories where running git status --porcelain fails since it must be run in a work tree. That is, go build with VCS stamping (including auto mode) fails in such setup.

  1. Go looks for .git, which is currently only allowed to be a directory.
  2. Finds .git directory from the bare repository (see also git config core.bare).
  3. Runs git status there, outside of the work tree.
gopherbot commented 1 year ago

Change https://go.dev/cl/480635 mentions this issue: cmd/gomote: don't push .git even if it is a file

cehoffman commented 6 months ago

Thanks for the start of the patch process @mvdan. I looked at the thread there, and I'm not sure what the remaining work is. Is the ask for a revert of the original logic change that broke worktrees with a regression test?

tie commented 6 months ago

@cehoffman, hi, I don’t think there is any work to do here aside from getting CL 463849 rebased, reviewed and merged, ideally also backported to stable release.

I’ve also added comments with regression test suggestions for my particular use case (i.e. bare Git repository with work trees), but that shouldn’t be that different from the regression test already present in the CL.

I’ve been using Go toolchain with GOFLAGS=-buildvcs=false because of this issue, so I’d appreciate if it finally gets resolved 😅

CodingMinds commented 2 weeks ago

The discussion in https://go.dev/cl/463849 seems to be stalled. Does anyone know what's the state of this?

matloob commented 1 week ago

@mvdan Do you have context on this? Did you send out a fix with regression test?

mvdan commented 1 week ago

I didn't do anything beyond https://go-review.googlesource.com/c/go/+/463849; writing the git worktree test and doing the revert is somewhere on my TODO list. I honestly don't use git worktrees at the moment so it's not my top priority. I'm happy for someone else to do this and I'll close my CL.