Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 8 additions & 36 deletions internal/gitclone/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ func (m *Manager) GetOrCreate(_ context.Context, upstreamURL string) (*Repositor
credentialProvider: m.credentialProvider,
}

gitDir := filepath.Join(clonePath, ".git")
if _, err := os.Stat(gitDir); err == nil {
headFile := filepath.Join(clonePath, "HEAD")
if _, err := os.Stat(headFile); err == nil {
repo.state = StateReady
}

Expand All @@ -192,14 +192,7 @@ func (m *Manager) DiscoverExisting(_ context.Context) ([]*Repository, error) {
return nil
}

gitDir := filepath.Join(path, ".git")
headPath := filepath.Join(path, ".git", "HEAD")
if _, statErr := os.Stat(gitDir); statErr != nil {
if errors.Is(statErr, os.ErrNotExist) {
return nil
}
return errors.Wrap(statErr, "stat .git directory")
}
headPath := filepath.Join(path, "HEAD")
if _, statErr := os.Stat(headPath); statErr != nil {
if errors.Is(statErr, os.ErrNotExist) {
return nil
Expand Down Expand Up @@ -329,7 +322,7 @@ func (r *Repository) executeClone(ctx context.Context) error {
config := DefaultGitTuningConfig()
// #nosec G204 - r.upstreamURL and r.path are controlled by us
args := []string{
"clone",
"clone", "--mirror",
"-c", "http.postBuffer=" + strconv.Itoa(config.PostBuffer),
"-c", "http.lowSpeedLimit=" + strconv.Itoa(config.LowSpeedLimit),
"-c", "http.lowSpeedTime=" + strconv.Itoa(int(config.LowSpeedTime.Seconds())),
Expand All @@ -342,27 +335,7 @@ func (r *Repository) executeClone(ctx context.Context) error {
}
output, err := cmd.CombinedOutput()
if err != nil {
return errors.Wrapf(err, "git clone: %s", string(output))
}

// #nosec G204 - r.path is controlled by us
cmd = exec.CommandContext(ctx, "git", "-C", r.path, "config", "remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*")
output, err = cmd.CombinedOutput()
if err != nil {
return errors.Wrapf(err, "configure fetch refspec: %s", string(output))
}

cmd, err = r.gitCommand(ctx, "-C", r.path,
"-c", "http.postBuffer="+strconv.Itoa(config.PostBuffer),
"-c", "http.lowSpeedLimit="+strconv.Itoa(config.LowSpeedLimit),
"-c", "http.lowSpeedTime="+strconv.Itoa(int(config.LowSpeedTime.Seconds())),
"fetch", "--all")
if err != nil {
return errors.Wrap(err, "create git command for fetch")
}
output, err = cmd.CombinedOutput()
if err != nil {
return errors.Wrapf(err, "fetch all branches: %s", string(output))
return errors.Wrapf(err, "git clone --mirror: %s", string(output))
}

// Enable partial clone support (e.g. --filter=blob:none) when serving via git http-backend.
Expand Down Expand Up @@ -403,13 +376,13 @@ func (r *Repository) Fetch(ctx context.Context) error {
"-c", "http.postBuffer="+strconv.Itoa(config.PostBuffer),
"-c", "http.lowSpeedLimit="+strconv.Itoa(config.LowSpeedLimit),
"-c", "http.lowSpeedTime="+strconv.Itoa(int(config.LowSpeedTime.Seconds())),
"remote", "update", "--prune")
"fetch", "--prune", "--prune-tags")
if err != nil {
return errors.Wrap(err, "create git command")
}
output, err := cmd.CombinedOutput()
if err != nil {
return errors.Wrapf(err, "git remote update: %s", string(output))
return errors.Wrapf(err, "git fetch: %s", string(output))
}

r.lastFetch = time.Now()
Expand Down Expand Up @@ -444,8 +417,7 @@ func (r *Repository) EnsureRefsUpToDate(ctx context.Context) error {
if !strings.HasPrefix(ref, "refs/heads/") {
continue
}
localRef := "refs/remotes/origin/" + strings.TrimPrefix(ref, "refs/heads/")
localSHA, exists := localRefs[localRef]
localSHA, exists := localRefs[ref]
if !exists || localSHA != upstreamSHA {
needsFetch = true
break
Expand Down
10 changes: 4 additions & 6 deletions internal/gitclone/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,8 @@ func TestManager_GetOrCreate_ExistingClone(t *testing.T) {
assert.NoError(t, err)

repoPath := filepath.Join(tmpDir, "github.com", "user", "repo")
gitDir := filepath.Join(repoPath, ".git")
assert.NoError(t, os.MkdirAll(gitDir, 0o755))
assert.NoError(t, os.WriteFile(filepath.Join(gitDir, "HEAD"), []byte("ref: refs/heads/main\n"), 0o644))
assert.NoError(t, os.MkdirAll(repoPath, 0o755))
assert.NoError(t, os.WriteFile(filepath.Join(repoPath, "HEAD"), []byte("ref: refs/heads/main\n"), 0o644))

upstreamURL := "https://github.com/user/repo"
repo, err := manager.GetOrCreate(context.Background(), upstreamURL)
Expand Down Expand Up @@ -138,9 +137,8 @@ func TestManager_DiscoverExisting(t *testing.T) {
}

for _, repoPath := range repos {
gitDir := filepath.Join(repoPath, ".git")
assert.NoError(t, os.MkdirAll(gitDir, 0o755))
assert.NoError(t, os.WriteFile(filepath.Join(gitDir, "HEAD"), []byte("ref: refs/heads/main\n"), 0o644))
assert.NoError(t, os.MkdirAll(repoPath, 0o755))
assert.NoError(t, os.WriteFile(filepath.Join(repoPath, "HEAD"), []byte("ref: refs/heads/main\n"), 0o644))
}

discovered, err := manager.DiscoverExisting(context.Background())
Expand Down
3 changes: 1 addition & 2 deletions internal/strategy/git/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ func (s *Strategy) serveFromBackend(w http.ResponseWriter, r *http.Request, repo
host := r.PathValue("host")
pathValue := r.PathValue("path")

// Insert /.git before the git protocol paths to match the filesystem layout
var gitOperation string
var repoPathWithSuffix string

Expand All @@ -51,7 +50,7 @@ func (s *Strategy) serveFromBackend(w http.ResponseWriter, r *http.Request, repo
}

repoPath := strings.TrimSuffix(repoPathWithSuffix, ".git")
backendPath := "/" + host + "/" + repoPath + "/.git" + gitOperation
backendPath := "/" + host + "/" + repoPath + gitOperation

logger.DebugContext(r.Context(), "Serving with git http-backend",
slog.String("original_path", r.URL.Path),
Expand Down
10 changes: 4 additions & 6 deletions internal/strategy/git/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,13 @@ func TestNewWithExistingCloneOnDisk(t *testing.T) {
_, ctx := logging.Configure(context.Background(), logging.Config{})
tmpDir := t.TempDir()

// Create a fake clone directory on disk before initializing strategy
// For regular clones, we need a .git subdirectory with HEAD file
// Create a fake bare clone directory on disk before initializing strategy
clonePath := filepath.Join(tmpDir, "github.com", "org", "repo")
gitDir := filepath.Join(clonePath, ".git")
err := os.MkdirAll(gitDir, 0o750)
err := os.MkdirAll(clonePath, 0o750)
assert.NoError(t, err)

// Create HEAD file to make it look like a valid git repo
headPath := filepath.Join(gitDir, "HEAD")
// Create HEAD file to make it look like a valid bare git repo
headPath := filepath.Join(clonePath, "HEAD")
err = os.WriteFile(headPath, []byte("ref: refs/heads/main\n"), 0o640)
assert.NoError(t, err)

Expand Down
7 changes: 3 additions & 4 deletions internal/strategy/git/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,10 @@ func TestIntegrationGitCloneViaProxy(t *testing.T) {
assert.NoError(t, err)
assert.True(t, info.IsDir())

// Verify it has a .git directory (regular clone)
gitDir := filepath.Join(clonePath, ".git")
gitInfo, err := os.Stat(gitDir)
// Verify it has a HEAD file (bare mirror clone)
headFile := filepath.Join(clonePath, "HEAD")
_, err = os.Stat(headFile)
assert.NoError(t, err)
assert.True(t, gitInfo.IsDir())
}

// TestIntegrationGitFetchViaProxy tests fetching updates through the proxy.
Expand Down