cmd/gitmirror: explicitly specify GIT_DIR

Gitmirror uses mirror (bare) local repositories as part of its work.
Its tests use one non-bare test repository, so that they can commit
to it and check that mirroring works.

Explicitly track and specify GIT_DIR for all git operations for the
same reasons as in CL 489915 and CL 605937 - it makes them slightly
faster and able to run in safe.bareRepository=explicit environments.

Fixes golang/go#66202.

Change-Id: I9a08938777e9108f940a791bab65180f8297d0a8
Reviewed-on: https://go-review.googlesource.com/c/build/+/605976
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
Dmitri Shuralyov 2024-04-04 17:43:11 -04:00 коммит произвёл Gopher Robot
Родитель 5b502e190a
Коммит 21347def97
2 изменённых файлов: 34 добавлений и 19 удалений

Просмотреть файл

@ -329,7 +329,7 @@ type remote struct {
type repo struct { type repo struct {
name string name string
url string url string
root string // on-disk location of the git repo, *cacheDir/name root string // on-disk location of the bare git repo, *cacheDir/name
meta *repospkg.Repo meta *repospkg.Repo
changed chan bool // sent to when a change comes in changed chan bool // sent to when a change comes in
status statusRing status statusRing
@ -344,7 +344,8 @@ type repo struct {
lastGood time.Time lastGood time.Time
} }
// init sets up the repo, cloning the repository to the local root. // init sets up the repo, cloning the remote repository from r.url
// to a local --mirror (which implies --bare) repository at r.root.
func (r *repo) init() error { func (r *repo) init() error {
canReuse := true canReuse := true
if _, err := os.Stat(filepath.Join(r.root, "FETCH_HEAD")); err != nil { if _, err := os.Stat(filepath.Join(r.root, "FETCH_HEAD")); err != nil {
@ -394,6 +395,7 @@ func (r *repo) runGitQuiet(args ...string) ([]byte, []byte, error) {
envutil.SetDir(cmd, "/") envutil.SetDir(cmd, "/")
} else { } else {
envutil.SetDir(cmd, r.root) envutil.SetDir(cmd, r.root)
envutil.SetEnv(cmd, "GIT_DIR="+r.root)
} }
envutil.SetEnv(cmd, "HOME="+r.mirror.homeDir) envutil.SetEnv(cmd, "HOME="+r.mirror.homeDir)
cmd.Stdout, cmd.Stderr = stdout, stderr cmd.Stdout, cmd.Stderr = stdout, stderr

Просмотреть файл

@ -96,13 +96,23 @@ func TestMirrorInitiallyEmpty(t *testing.T) {
type testMirror struct { type testMirror struct {
// Local paths to the copies of the build repo. // Local paths to the copies of the build repo.
gerrit, github, csr string gerrit, github, csr explicitRepo
m *gitMirror m *gitMirror
server *httptest.Server server *httptest.Server
buildRepo *repo buildRepo *repo
t *testing.T t *testing.T
} }
// explicitRepo is a Git repository
// whose GIT_DIR and worktree paths
// are explicitly tracked.
type explicitRepo struct {
gitDir string // GIT_DIR.
dir string // Worktree directory if non-bare repo, equal to gitDir if bare.
}
func (r explicitRepo) bare() bool { return r.gitDir == r.dir }
// newTestMirror returns a mirror configured to watch the "build" repository // newTestMirror returns a mirror configured to watch the "build" repository
// and mirror it to GitHub and CSR. All repositories are faked out with local // and mirror it to GitHub and CSR. All repositories are faked out with local
// versions created hermetically. The mirror is idle and must be pumped with // versions created hermetically. The mirror is idle and must be pumped with
@ -119,9 +129,6 @@ func newTestMirror(t *testing.T) *testMirror {
} }
tm := &testMirror{ tm := &testMirror{
gerrit: gerrit,
github: t.TempDir(),
csr: t.TempDir(),
m: &gitMirror{ m: &gitMirror{
mux: http.NewServeMux(), mux: http.NewServeMux(),
cacheDir: t.TempDir(), cacheDir: t.TempDir(),
@ -143,12 +150,10 @@ func newTestMirror(t *testing.T) *testMirror {
tm.server = httptest.NewServer(tm.m.mux) tm.server = httptest.NewServer(tm.m.mux)
t.Cleanup(tm.server.Close) t.Cleanup(tm.server.Close)
// The origin is non-bare so we can commit to it; the destinations are initRepo := func(dir string, bare bool) explicitRepo {
// bare so we can push to them. gitDir, initArgs := filepath.Join(dir, ".git"), []string{"init"}
initRepo := func(dir string, bare bool) {
initArgs := []string{"init"}
if bare { if bare {
initArgs = append(initArgs, "--bare") gitDir, initArgs = dir, append(initArgs, "--bare")
} }
for _, args := range [][]string{ for _, args := range [][]string{
initArgs, initArgs,
@ -157,14 +162,18 @@ func newTestMirror(t *testing.T) *testMirror {
} { } {
cmd := exec.Command("git", args...) cmd := exec.Command("git", args...)
envutil.SetDir(cmd, dir) envutil.SetDir(cmd, dir)
envutil.SetEnv(cmd, "GIT_DIR="+gitDir)
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out) t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out)
} }
} }
return explicitRepo{gitDir, dir}
} }
initRepo(tm.gerrit, false) // The origin is non-bare so we can commit to it; the destinations are
initRepo(tm.github, true) // bare so we can push to them.
initRepo(tm.csr, true) tm.gerrit = initRepo(gerrit, false)
tm.github = initRepo(t.TempDir(), true)
tm.csr = initRepo(t.TempDir(), true)
tm.buildRepo = tm.m.addRepo(&repospkg.Repo{ tm.buildRepo = tm.m.addRepo(&repospkg.Repo{
GoGerritProject: "build", GoGerritProject: "build",
@ -180,8 +189,8 @@ func newTestMirror(t *testing.T) *testMirror {
// Manually add mirror repos. We can't use tm.m.addMirrors, as they // Manually add mirror repos. We can't use tm.m.addMirrors, as they
// hard-codes the real remotes, but we need to use local test // hard-codes the real remotes, but we need to use local test
// directories. // directories.
tm.buildRepo.addRemote("github", tm.github, "") tm.buildRepo.addRemote("github", tm.github.gitDir, "")
tm.buildRepo.addRemote("csr", tm.csr, "") tm.buildRepo.addRemote("csr", tm.csr.gitDir, "")
return tm return tm
} }
@ -195,17 +204,21 @@ func (tm *testMirror) loopOnce() {
func (tm *testMirror) commit(content string) { func (tm *testMirror) commit(content string) {
tm.t.Helper() tm.t.Helper()
if err := os.WriteFile(filepath.Join(tm.gerrit, "README"), []byte(content), 0777); err != nil { if err := os.WriteFile(filepath.Join(tm.gerrit.dir, "README"), []byte(content), 0777); err != nil {
tm.t.Fatal(err) tm.t.Fatal(err)
} }
tm.git(tm.gerrit, "add", ".") tm.git(tm.gerrit, "add", ".")
tm.git(tm.gerrit, "commit", "-m", content) tm.git(tm.gerrit, "commit", "-m", content)
} }
func (tm *testMirror) git(dir string, args ...string) string { func (tm *testMirror) git(r explicitRepo, args ...string) string {
tm.t.Helper() tm.t.Helper()
cmd := exec.Command("git", args...) cmd := exec.Command("git", args...)
envutil.SetDir(cmd, dir) envutil.SetDir(cmd, r.dir)
envutil.SetEnv(cmd, "GIT_DIR="+r.gitDir)
if !r.bare() {
envutil.SetEnv(cmd, "GIT_WORK_TREE="+r.dir)
}
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
tm.t.Fatalf("git: %v, %s", err, out) tm.t.Fatalf("git: %v, %s", err, out)