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
4 changes: 2 additions & 2 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ func (c *Cache) EnsureCommit(ctx context.Context, url, commit string) error {
return nil
}
out, err := doPinnedURL(ctx, policy, url, Command{
Args: []string{"fetch", "--unshallow", "--quiet", "origin"}, //nolint:goconst // Git argv is clearer with literal subcommands and flags.
Label: "fetch", //nolint:goconst // Retry notices use the literal Git subcommand.
Args: longPathArgs("fetch", "--unshallow", "--quiet", "origin"), //nolint:goconst // Git argv is clearer with literal subcommands and flags.
Label: "fetch", //nolint:goconst // Retry notices use the literal Git subcommand.
Dir: cacheSrc,
Env: remoteEnv(),
})
Expand Down
35 changes: 35 additions & 0 deletions cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"os"
"path/filepath"
"slices"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -191,6 +192,40 @@ func TestCacheEnsureCommitRetriesUnshallowFetch(t *testing.T) {
}
}

func TestCacheEnsureCommitConfiguresLongPathsForFetch(t *testing.T) {
cache := Cache{Root: t.TempDir()}
url := "https://example.invalid/repo"
cacheSrc := filepath.Join(cache.Dir(url), "src")
if err := os.MkdirAll(filepath.Join(cacheSrc, ".git"), 0o755); err != nil {
t.Fatal(err)
}

var fetchArgs []string
cache.Retry = Retry{
Run: func(_ context.Context, _ string, _ []string, args ...string) (string, error) {
switch subcommand(args) {
case "cat-file":
return "", errors.New("missing object")
case "rev-parse":
return "true\n", nil
case "fetch":
fetchArgs = append([]string(nil), args...)
return "", nil
default:
return "", errors.New("unexpected Git command")
}
},
}

if err := cache.EnsureCommit(context.Background(), url, "deadbeef"); err != nil {
t.Fatalf("EnsureCommit: %v", err)
}
want := []string{"-c", "core.longpaths=true"}
if len(fetchArgs) < len(want) || !slices.Equal(fetchArgs[:len(want)], want) {
t.Errorf("fetch args = %v, want prefix %v", fetchArgs, want)
}
}

func TestCacheEnsureCommitSkipsUnreachableCommitInFullClone(t *testing.T) {
cache := Cache{Root: t.TempDir()}
url := "https://example.invalid/repo"
Expand Down
4 changes: 2 additions & 2 deletions ensure.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func ensure(ctx context.Context, retry Retry, url, dst, ref string, options Ensu
out, err := doPinnedURL(ctx, retry, url, Command{
Label: "clone",
Env: remoteEnv(),
Args: args,
Args: longPathArgs(args...),
Reset: DestReset(dst),
})
if err != nil {
Expand Down Expand Up @@ -141,7 +141,7 @@ func fetchRef(ctx context.Context, retry Retry, url, dst, ref string, full bool)
out, err := doPinnedURL(ctx, policy, url, Command{
Label: "fetch", //nolint:goconst // Retry notices use the literal Git subcommand.
Env: remoteEnv(),
Args: args,
Args: longPathArgs(args...),
})
if err != nil {
return fmt.Errorf("%s: %w", strings.TrimSpace(out), err)
Expand Down
23 changes: 23 additions & 0 deletions ensure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,29 @@ func TestEnsureRetriesCloneAndResetsPartialDestination(t *testing.T) {
}
}

func TestEnsureConfiguresLongPathsForCloneAndFetch(t *testing.T) {
dst := filepath.Join(t.TempDir(), "checkout")
commands := make(map[string][]string)
retry := Retry{
Run: func(_ context.Context, _ string, _ []string, args ...string) (string, error) {
commands[subcommand(args)] = append([]string(nil), args...)
return "", nil
},
}

err := Ensure(context.Background(), retry, "https://example.invalid/repo", dst, "main", false)
if err != nil {
t.Fatalf("Ensure: %v", err)
}
for _, command := range []string{"clone", "fetch"} {
args := commands[command]
want := []string{"-c", "core.longpaths=true"}
if len(args) < len(want) || !slices.Equal(args[:len(want)], want) {
t.Errorf("%s args = %v, want prefix %v", command, args, want)
}
}
}

func TestEnsureUnknownRefReturnsUnreachableError(t *testing.T) {
origin := newOriginFixture(t)
dst := filepath.Join(t.TempDir(), "checkout")
Expand Down
4 changes: 4 additions & 0 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ func remoteEnv() []string {
return env
}

func longPathArgs(args ...string) []string {
return append([]string{"-c", "core.longpaths=true"}, args...)
}

// Runner runs one Git invocation and returns its combined output.
type Runner func(ctx context.Context, dir string, env []string, args ...string) (string, error)

Expand Down