Merge pull request #914 from sdowell/git-lock-files

fix: recover when there is unreleased lock file
This commit is contained in:
Kubernetes Prow Robot 2024-08-12 11:09:47 -07:00 committed by GitHub
commit a5a965f08b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 64 additions and 0 deletions

24
main.go
View File

@ -1227,6 +1227,20 @@ func (git *repoSync) removeStaleWorktrees() (int, error) {
return count, nil return count, nil
} }
func hasGitLockFile(gitRoot absPath) (string, error) {
gitLockFiles := []string{"shallow.lock"}
for _, lockFile := range gitLockFiles {
lockFilePath := gitRoot.Join(".git", lockFile).String()
_, err := os.Stat(lockFilePath)
if err == nil {
return lockFilePath, nil
} else if !errors.Is(err, os.ErrNotExist) {
return lockFilePath, err
}
}
return "", nil
}
// sanityCheckRepo tries to make sure that the repo dir is a valid git repository. // sanityCheckRepo tries to make sure that the repo dir is a valid git repository.
func (git *repoSync) sanityCheckRepo(ctx context.Context) bool { func (git *repoSync) sanityCheckRepo(ctx context.Context) bool {
git.log.V(3).Info("sanity-checking git repo", "repo", git.root) git.log.V(3).Info("sanity-checking git repo", "repo", git.root)
@ -1258,6 +1272,16 @@ func (git *repoSync) sanityCheckRepo(ctx context.Context) bool {
return false return false
} }
// Check if the repository contains an unreleased lock file. This can happen if
// a previous git invocation crashed.
if lockFile, err := hasGitLockFile(git.root); err != nil {
git.log.Error(err, "error calling stat on file", "path", lockFile)
return false
} else if len(lockFile) > 0 {
git.log.Error(nil, "repo contains lock file", "path", lockFile)
return false
}
return true return true
} }

View File

@ -424,3 +424,43 @@ func TestTouch(t *testing.T) {
t.Errorf("touch(newfile) mtime %v is not after %v", newfileInfo.ModTime(), stamp) t.Errorf("touch(newfile) mtime %v is not after %v", newfileInfo.ModTime(), stamp)
} }
} }
func TestHasGitLockFile(t *testing.T) {
testCases := map[string]struct {
inputFilePath []string
expectLockFile bool
}{
"missing .git directory": {
expectLockFile: false,
},
"has git directory but no lock files": {
inputFilePath: []string{".git", "HEAD"},
expectLockFile: false,
},
"shallow.lock file": {
inputFilePath: []string{".git", "shallow.lock"},
expectLockFile: true,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
root := absPath(t.TempDir())
if len(tc.inputFilePath) > 0 {
if err := touch(root.Join(tc.inputFilePath...)); err != nil {
t.Fatal(err)
}
}
lockFile, err := hasGitLockFile(root)
if err != nil {
t.Fatal(err)
}
hasLock := len(lockFile) > 0
if hasLock != tc.expectLockFile {
t.Fatalf("expected hasGitLockFile to return %v, but got %v", tc.expectLockFile, hasLock)
}
})
}
}