add checkpoint policy command · Entire
add checkpoint policy command
c0e6ffe·
pfleidi·3w ago·12 files·+448 added/-18 removed
Expose repo-wide checkpoint policy inspection and updates through entire policy checkpoint.
The update path fetches the remote policy before validation, rejects downgrades unless forced, and pushes only the checkpoint policy ref.
Sessions
5578a456290cView transcript
Changes
12
cmd/entire/cli
- checkpoint
Mopen.go+1/-1
checkpointpolicy
Mformat_test.go+1/-2
Mpolicy_test.go-1
Mremote.go+16/-9
Mstore.go+3/-3
Aupdate.go+110
Aupdate_test.go+64
Apolicy_checkpoint.go+76
Apolicy_checkpoint_test.go+151
Apolicy_group.go+23
Mroot.go+1
strategy
Mmanual_commit.go+2/-2
54 unmodified lines
55
56
57
58
58
59
60
61
54 unmodified lines
}
// Temporary returns the git-backed temporary shadow-branch store.
func (s *Stores) Temporary() TemporaryStore { return s.temporary } //nolint:ireturn // temporary store capability is the abstraction boundary
func (s *Stores) Temporary() TemporaryStore { return s.temporary }
// Refs returns the resolved committed-ref topology.
func (s *Stores) Refs() CommittedRefs { return s.refs }
Mcmd/entire/cli/checkpoint/open.go+1/-1
23 unmodified lines
24
25
26
27
27
28
29
23 unmodified lines
53
54
55
57
56
57
23 unmodified lines
{name: "non numeric major", input: "branch-vx", wantErr: "invalid checkpoint major"},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got, err := checkpointpolicy.ParseFormat(tt.input)
23 unmodified lines
require.True(t, checkpointpolicy.KnowsFormat(refsV1))
require.False(t, checkpointpolicy.CanRead(refsV1))
require.False(t, checkpointpolicy.CanWrite(refsV1))
require.Less(t, checkpointpolicy.Compare(branchV1, refsV1), 0)
require.Negative(t, checkpointpolicy.Compare(branchV1, refsV1))
}
Mcmd/entire/cli/checkpointpolicy/format_test.go+1/-2
27 unmodified lines
28
29
30
31
31
32
33
27 unmodified lines
{name: "unsupported minimum", policy: checkpointpolicy.Policy{CheckpointVersion: "branch-v1", CheckpointMinVersion: "refs-v1"}, wantErr: "not read-supported"},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := checkpointpolicy.ValidatePolicy(tt.policy)
Mcmd/entire/cli/checkpointpolicy/policy_test.go-1
35 unmodified lines
36
37
38
39
39
40
41
42
43
43
44
45
46
5 unmodified lines
52
53
54
55
55
56
57
58
29 unmodified lines
88
89
90
91
92
93
91
92
93
94
35 unmodified lines
130
131
132
135
133
134
135
136
137
138
139
140
141
142
143
144
145
146
6 unmodified lines
153
154
155
152
156
157
154
158
159
160
161
1 unmodified line
163
164
165
166
167
168
169
170
35 unmodified lines
}
dir, err := paths.WorktreeRoot(ctx)
if err != nil {
return Target{}, err
return Target{}, fmt.Errorf("resolve worktree root: %w", err)
}
target, dedicated, err := remote.PushURL(ctx, baseRemote)
if err != nil {
return Target{}, err
return Target{}, fmt.Errorf("resolve checkpoint push URL: %w", err)
}
label := baseRemote
if dedicated {
5 unmodified lines
func CheckRemote(ctx context.Context, target Target) (RemoteState, error) {
output, err := remote.LsRemoteInDir(ctx, target.Dir, target.Remote, RefName.String())
if err != nil {
return RemoteState{}, err
return RemoteState{}, fmt.Errorf("check remote checkpoint policy ref: %w", err)
}
fields := strings.Fields(string(output))
if len(fields) == 0 {
29 unmodified lines
return State{}, err
}
fetched.RemoteHash = remoteState.Hash
defer func() {
_ = repo.Storer.RemoveReference(fetchRefName)
}
defer removeFetchRef(repo)
if local.Hash.IsZero() || isAncestorOf(ctx, repo, local.Hash, fetched.Hash) {
if err := SetRef(repo, RefName, fetched.Hash); err != nil {
35 unmodified lines
NoFilter: true,
Dir: target.Dir,
}); err != nil {
return State{}, err
return State{}, fmt.Errorf("fetch checkpoint policy ref: %w", err)
}
return ReadFromRef(ctx, repo, fetchRefName, SourceRemote)
}
func removeFetchRef(repo *git.Repository) {
if err := repo.Storer.RemoveReference(fetchRefName); err != nil {
return
}
}
func isAncestorOf(ctx context.Context, repo *git.Repository, ancestor, target plumbing.Hash) bool {
if ancestor == target {
return true
6 unmodified lines
defer iter.Close()
found := false
_ = iter.ForEach(func(commit *object.Commit) error {
err = iter.ForEach(func(commit *object.Commit) error {
if err := ctx.Err(); err != nil {
return err
return fmt.Errorf("traverse checkpoint policy ancestry: %w", err)
}
if commit.Hash == ancestor {
found = true
1 unmodified line
}
return nil
})
if err != nil && !errors.Is(err, errStopTraversal) {
return false
}
return found
}
}
Mcmd/entire/cli/checkpointpolicy/remote.go+16/-9
61 unmodified lines
62
63
64
65
65
66
67
68
4 unmodified lines
73
74
75
76
76
77
78
79
10 unmodified lines
90
91
92
93
93
94
95
96
61 unmodified lines
}
blobHash, err := checkpoint.CreateBlobFromContent(repo, data)
if err != nil {
return plumbing.ZeroHash, err
return plumbing.ZeroHash, fmt.Errorf("create checkpoint policy blob: %w", err)
}
treeHash, err := checkpoint.BuildTreeFromEntries(ctx, repo, map[string]object.TreeEntry{
PolicyFileName: {Name: PolicyFileName, Mode: filemode.Regular, Hash: blobHash},
4 unmodified lines
authorName, authorEmail := checkpoint.GetGitAuthorFromRepo(repo)
commitHash, err := checkpoint.CreateCommit(ctx, repo, treeHash, parent, "Update checkpoint policy", authorName, authorEmail)
if err != nil {
return plumbing.ZeroHash, err
return plumbing.ZeroHash, fmt.Errorf("create checkpoint policy commit: %w", err)
}
if err := SetRef(repo, RefName, commitHash); err != nil {
return plumbing.ZeroHash, err
10 unmodified lines
}
func readFromHash(ctx context.Context, repo *git.Repository, hash plumbing.Hash, source Source) (State, error) {
if err := ctx.Err(); err != nil {
return State{}, err
return State{}, fmt.Errorf("read checkpoint policy: %w", err)
}
commit, err := repo.CommitObject(hash)
if err != nil {
Mcmd/entire/cli/checkpointpolicy/store.go+3/-3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package checkpointpolicy
import (
"context"
"fmt"
"github.com/go-git/go-git/v6"
)
type UpdateOptions struct {
CheckpointVersion string
CheckpointMinVersion string
Force bool
}
func Update(ctx context.Context, repo *git.Repository, target Target, opts UpdateOptions) (State, error) {
baseline, err := updateBaseline(ctx, repo, target)
if err != nil {
return State{}, err
}
policy := baseline.Policy
if opts.CheckpointVersion != "" {
policy.CheckpointVersion = opts.CheckpointVersion
}
if opts.CheckpointMinVersion != "" {
policy.CheckpointMinVersion = opts.CheckpointMinVersion
}
if err := rejectDowngrades(baseline.Policy, policy, opts); err != nil {
return State{}, err
}
if err := ValidatePolicy(policy); err != nil {
return State{}, err
}
hash, err := WriteLocal(ctx, repo, baseline.Hash, policy)
if err != nil {
return State{}, err
}
return State{
Policy: Normalize(policy),
Source: SourceLocal,
Hash: hash,
RemoteHash: baseline.RemoteHash,
}, nil
}
func updateBaseline(ctx context.Context, repo *git.Repository, target Target) (State, error) {
local, err := ReadLocal(ctx, repo)
if err != nil {
return State{}, err
}
remoteState, err := CheckRemote(ctx, target)
if err != nil {
return State{}, err
}
if !remoteState.Exists {
return local, nil
}
if local.Hash == remoteState.Hash {
local.Source = SourceRemote
local.RemoteHash = remoteState.Hash
return local, nil
}
fetched, err := fetchRemotePolicy(ctx, repo, target)
if err != nil {
return State{}, err
}
fetched.RemoteHash = remoteState.Hash
defer removeFetchRef(repo)
return fetched, nil
}
func rejectDowngrades(before, after Policy, opts UpdateOptions) error {
before = Normalize(before)
after = Normalize(after)
if opts.Force {
return nil
}
if opts.CheckpointVersion != "" {
if err := rejectFieldDowngrade("checkpoint_version", before.CheckpointVersion, after.CheckpointVersion); err != nil {
return err
}
}
if opts.CheckpointMinVersion != "" {
if err := rejectFieldDowngrade("checkpoint_min_version", before.CheckpointMinVersion, after.CheckpointMinVersion); err != nil {
return err
}
}
return nil
}
func rejectFieldDowngrade(field, beforeRaw, afterRaw string) error {
before, err := ParseFormat(beforeRaw)
if err != nil {
return fmt.Errorf("%s existing value %q: %w", field, beforeRaw, err)
}
after, err := ParseFormat(afterRaw)
if err != nil {
return fmt.Errorf("%s: %w", field, err)
}
if Compare(after, before) < 0 {
return fmt.Errorf("would downgrade %s from %q to %q; pass --force to allow this", field, beforeRaw, afterRaw)
}
return nil
}
Acmd/entire/cli/checkpointpolicy/update.go+110
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package checkpointpolicy_test
import (
"testing"
"github.com/entireio/cli/cmd/entire/cli/checkpoint"
"github.com/entireio/cli/cmd/entire/cli/checkpointpolicy"
"github.com/go-git/go-git/v6/plumbing"
"github.com/stretchr/testify/require"
)
func TestUpdateRejectsDowngradeFromRemoteWithoutForce(t *testing.T) {
t.Parallel()
remoteDir, remoteRepo, bareDir := initPolicyRemoteFixture(t)
remoteHash, err := checkpointpolicy.WriteLocal(t.Context(), remoteRepo, plumbing.ZeroHash, checkpointpolicy.Policy{
CheckpointVersion: "refs-v1",
CheckpointMinVersion: "refs-v1",
})
require.NoError(t, err)
pushPolicyRefWithGit(t, remoteDir, bareDir)
localDir, localRepo := initPolicyRepoWithDir(t)
localHash, err := checkpointpolicy.WriteLocal(t.Context(), localRepo, plumbing.ZeroHash, checkpointpolicy.DefaultPolicy())
require.NoError(t, err)
_, err = checkpointpolicy.Update(t.Context(), localRepo, checkpointpolicy.Target{Remote: bareDir, Dir: localDir}, checkpointpolicy.UpdateOptions{
CheckpointVersion: checkpoint.CheckpointVersionBranchV1,
CheckpointMinVersion: checkpoint.CheckpointVersionBranchV1,
})
require.ErrorContains(t, err, "would downgrade checkpoint_version")
localState, err := checkpointpolicy.ReadLocal(t.Context(), localRepo)
require.NoError(t, err)
require.Equal(t, localHash, localState.Hash)
require.NotEqual(t, remoteHash, localState.Hash)
}
func TestUpdateAllowsDowngradeWithForce(t *testing.T) {
t.Parallel()
remoteDir, remoteRepo, bareDir := initPolicyRemoteFixture(t)
remoteHash, err := checkpointpolicy.WriteLocal(t.Context(), remoteRepo, plumbing.ZeroHash, checkpointpolicy.Policy{
CheckpointVersion: "refs-v1",
CheckpointMinVersion: "refs-v1",
})
require.NoError(t, err)
pushPolicyRefWithGit(t, remoteDir, bareDir)
localDir, localRepo := initPolicyRepoWithDir(t)
got, err := checkpointpolicy.Update(t.Context(), localRepo, checkpointpolicy.Target{Remote: bareDir, Dir: localDir}, checkpointpolicy.UpdateOptions{
CheckpointVersion: checkpoint.CheckpointVersionBranchV1,
CheckpointMinVersion: checkpoint.CheckpointVersionBranchV1,
Force: true,
})
require.NoError(t, err)
require.Equal(t, checkpointpolicy.SourceLocal, got.Source)
require.Equal(t, checkpointpolicy.Policy{
CheckpointVersion: checkpoint.CheckpointVersionBranchV1,
CheckpointMinVersion: checkpoint.CheckpointVersionBranchV1,
}, got.Policy)
commit, err := localRepo.CommitObject(got.Hash)
require.NoError(t, err)
require.Equal(t, []plumbing.Hash{remoteHash}, commit.ParentHashes)
}
Acmd/entire/cli/checkpointpolicy/update_test.go+64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package cli
import (
"fmt"
"github.com/entireio/cli/cmd/entire/cli/checkpointpolicy"
"github.com/entireio/cli/cmd/entire/cli/gitrepo"
"github.com/spf13/cobra"
)
type policyCheckpointOptions struct {
version string
minVersion string
force bool
}
func newPolicyCheckpointCmd() *cobra.Command {
var opts policyCheckpointOptions
cmd := &cobra.Command{
Use: "checkpoint",
Short: "Inspect and update checkpoint policy",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
return runPolicyCheckpoint(cmd, opts)
},
}
cmd.Flags().StringVar(&opts.version, "checkpoint-version", "", "Set the checkpoint version written by this repository")
cmd.Flags().StringVar(&opts.minVersion, "checkpoint-min-version", "", "Set the minimum checkpoint version required by this repository")
cmd.Flags().BoolVar(&opts.force, "force", false, "Allow checkpoint policy version downgrades")
return cmd
}
func runPolicyCheckpoint(cmd *cobra.Command, opts policyCheckpointOptions) error {
ctx := cmd.Context()
repo, err := gitrepo.OpenCurrent(ctx)
if err != nil {
return fmt.Errorf("open repository: %w", err)
}
defer repo.Close()
target, err := checkpointpolicy.ResolveTarget(ctx, "origin")
if err != nil {
return fmt.Errorf("resolve checkpoint policy remote: %w", err)
}
var state checkpointpolicy.State
if hasPolicyCheckpointUpdate(opts) {
state, err = checkpointpolicy.Update(ctx, repo, target, checkpointpolicy.UpdateOptions{
CheckpointVersion: opts.version,
CheckpointMinVersion: opts.minVersion,
Force: opts.force,
})
if err != nil {
return fmt.Errorf("update checkpoint policy: %w", err)
}
if err := checkpointpolicy.Push(ctx, target); err != nil {
return fmt.Errorf("push checkpoint policy: %w", err)
}
state.Source = checkpointpolicy.SourceRemote
} else {
state, err = checkpointpolicy.Sync(ctx, repo, target)
if err != nil {
return fmt.Errorf("sync checkpoint policy: %w", err)
}
}
fmt.Fprintf(cmd.OutOrStdout(), "checkpoint_version: %s\n", state.Policy.CheckpointVersion)
fmt.Fprintf(cmd.OutOrStdout(), "checkpoint_min_version: %s\n", state.Policy.CheckpointMinVersion)
fmt.Fprintf(cmd.OutOrStdout(), "source: %s\n", state.Source)
return nil
}
func hasPolicyCheckpointUpdate(opts policyCheckpointOptions) bool {
return opts.version != "" || opts.minVersion != ""
}
Acmd/entire/cli/policy_checkpoint.go+76
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package cli
import (
"bytes"
"context"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/entireio/cli/cmd/entire/cli/checkpointpolicy"
"github.com/entireio/cli/cmd/entire/cli/testutil"
"github.com/go-git/go-git/v6"
"github.com/go-git/go-git/v6/plumbing"
"github.com/stretchr/testify/require"
)
func TestPolicyCheckpointCmd_PrintsDefaults(t *testing.T) {
_, _ = setupPolicyCheckpointRepo(t)
stdout, err := executePolicyCheckpointCmd(t)
require.NoError(t, err)
require.Contains(t, stdout, "checkpoint_version: branch-v1")
require.Contains(t, stdout, "checkpoint_min_version: branch-v1")
require.Contains(t, stdout, "source: defaults")
}
func TestPolicyCheckpointCmd_RejectsUnsupportedVersion(t *testing.T) {
tests := []struct {
name string
args []string
wantErr string
}{
{name: "checkpoint version", args: []string{"--checkpoint-version", "refs-v1"}, wantErr: "not write-supported"},
{name: "minimum version", args: []string{"--checkpoint-min-version", "refs-v1"}, wantErr: "not read-supported"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, _ = setupPolicyCheckpointRepo(t)
_, err := executePolicyCheckpointCmd(t, tt.args...)
require.ErrorContains(t, err, tt.wantErr)
})
}
}
func TestPolicyCheckpointCmd_RejectsDowngradeWithoutForce(t *testing.T) {
dir, bareDir := setupPolicyCheckpointRepo(t)
seedPolicyForCheckpointCommand(t, dir, checkpointpolicy.Policy{
CheckpointVersion: "refs-v1",
CheckpointMinVersion: "refs-v1",
})
pushCheckpointPolicyRefForCommandTest(t, dir, bareDir)
_, err := executePolicyCheckpointCmd(t, "--checkpoint-version", "branch-v1", "--checkpoint-min-version", "branch-v1")
require.ErrorContains(t, err, "would downgrade checkpoint_version")
}
func TestPolicyCheckpointCmd_UpdatesAndPushesOnlyPolicyRef(t *testing.T) {
dir, bareDir := setupPolicyCheckpointRepo(t)
testutil.WriteFile(t, dir, "README.md", "hello\n")
testutil.GitAdd(t, dir, "README.md")
testutil.GitCommit(t, dir, "init")
stdout, err := executePolicyCheckpointCmd(t, "--checkpoint-version", "branch-v1", "--checkpoint-min-version", "branch-v1")
require.NoError(t, err)
require.Contains(t, stdout, "checkpoint_version: branch-v1")
require.Contains(t, stdout, "checkpoint_min_version: branch-v1")
require.Contains(t, stdout, "source: remote")
remoteHash := checkpointPolicyRemoteHashForCommandTest(t, dir, bareDir)
require.False(t, remoteHash.IsZero())
repo := openPolicyCheckpointRepoForCommandTest(t, dir)
localState, err := checkpointpolicy.ReadLocal(t.Context(), repo)
require.NoError(t, err)
require.Equal(t, remoteHash, localState.Hash)
branches := runPolicyCheckpointGit(t, dir, "ls-remote", bareDir, "refs/heads/*")
require.Empty(t, strings.TrimSpace(branches))
}
func setupPolicyCheckpointRepo(t *testing.T) (string, string) {
t.Helper()
testutil.IsolateGitConfigEnv(t)
dir := setupTestDir(t)
testutil.InitRepo(t, dir)
bareDir := filepath.Join(t.TempDir(), "remote.git")
_, err := git.PlainInit(bareDir, true)
require.NoError(t, err)
runPolicyCheckpointGit(t, dir, "remote", "add", "origin", bareDir)
return dir, bareDir
}
func executePolicyCheckpointCmd(t *testing.T, args ...string) (string, error) {
t.Helper()
cmd := newPolicyCmd()
var stdout, stderr bytes.Buffer
cmd.SetOut(&stdout)
cmd.SetErr(&stderr)
cmd.SetArgs(append([]string{"checkpoint"}, args...))
cmd.SetContext(t.Context())
cmd.SilenceErrors = true
cmd.SilenceUsage = true
err := cmd.Execute()
return stdout.String(), err
}
func seedPolicyForCheckpointCommand(t *testing.T, dir string, policy checkpointpolicy.Policy) plumbing.Hash {
t.Helper()
repo := openPolicyCheckpointRepoForCommandTest(t, dir)
hash, err := checkpointpolicy.WriteLocal(t.Context(), repo, plumbing.ZeroHash, policy)
require.NoError(t, err)
return hash
}
func openPolicyCheckpointRepoForCommandTest(t *testing.T, dir string) *git.Repository {
t.Helper()
repo, err := git.PlainOpen(dir)
require.NoError(t, err)
return repo
}
func pushCheckpointPolicyRefForCommandTest(t *testing.T, dir, remote string) {
t.Helper()
refspec := checkpointpolicy.RefName.String() + ":" + checkpointpolicy.RefName.String()
runPolicyCheckpointGit(t, dir, "push", remote, refspec)
}
func checkpointPolicyRemoteHashForCommandTest(t *testing.T, dir, remote string) plumbing.Hash {
t.Helper()
output := runPolicyCheckpointGit(t, dir, "ls-remote", remote, checkpointpolicy.RefName.String())
fields := strings.Fields(output)
require.NotEmpty(t, fields, "missing remote checkpoint policy ref")
return plumbing.NewHash(fields[0])
}
func runPolicyCheckpointGit(t *testing.T, dir string, args ...string) string {
t.Helper()
cmd := exec.CommandContext(context.Background(), "git", args...)
cmd.Dir = dir
cmd.Env = testutil.GitIsolatedEnv()
output, err := cmd.CombinedOutput()
require.NoError(t, err, string(output))
return string(output)
}
Acmd/entire/cli/policy_checkpoint_test.go+151
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package cli
import (
"errors"
"github.com/entireio/cli/cmd/entire/cli/paths"
"github.com/spf13/cobra"
)
func newPolicyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "policy",
Short: "Manage repo-wide Entire policies",
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
if _, err := paths.WorktreeRoot(cmd.Context()); err != nil {
return errors.New("not a git repository")
}
return nil
},
}
cmd.AddCommand(newPolicyCheckpointCmd())
return cmd
}
Acmd/entire/cli/policy_group.go+23
83 unmodified lines
84
85
86
87
88
89
90
83 unmodified lines
// Noun groups (canonical homes for subcommands).
cmd.AddCommand(newSessionsCmd()) // 'session' (with 'sessions' as Cobra alias)
cmd.AddCommand(newCheckpointGroupCmd()) // 'checkpoint' / 'cp' / 'checkpoints'
cmd.AddCommand(newPolicyCmd()) // 'policy'
cmd.AddCommand(newAgentGroupCmd()) // 'agent'
cmd.AddCommand(newAuthCmd()) // 'auth'
cmd.AddCommand(newDoctorCmd()) // 'doctor' (group: trace/logs/bundle)
Mcmd/entire/cli/root.go+1
51 unmodified lines
52
53
54
55
55
56
57
58
3 unmodified lines
62
63
64
65
65
66
67
68
51 unmodified lines
// topology. Writes target refs.Primary; reads target refs.Read. The strategy's
// blob fetcher is wired in so reads can fetch blobs on demand after a treeless
// fetch.
func (s *ManualCommitStrategy) getCheckpointStore(ctx context.Context, repo *git.Repository) (checkpoint.CommittedStore, error) { //nolint:ireturn // committed store capability is the abstraction boundary
func (s *ManualCommitStrategy) getCheckpointStore(ctx context.Context, repo *git.Repository) (checkpoint.CommittedStore, error) {
stores, err := s.getCheckpointStores(ctx, repo)
if err != nil {
return nil, err
3 unmodified lines
// getTemporaryStore returns the git-backed shadow-branch store with the
// strategy's blob fetcher wired in.
func (s *ManualCommitStrategy) getTemporaryStore(ctx context.Context, repo *git.Repository) (checkpoint.TemporaryStore, error) { //nolint:ireturn // temporary store capability is the abstraction boundary
func (s *ManualCommitStrategy) getTemporaryStore(ctx context.Context, repo *git.Repository) (checkpoint.TemporaryStore, error) {
stores, err := s.getCheckpointStores(ctx, repo)
if err != nil {
return nil, err