migrate-checkpoints: address review (silent cancel, disabled push, --remote, parent validation) · Entire
migrate-checkpoints: address review (silent cancel, disabled push, --remote, parent validation)
96537c1→main·
Soph·2w ago·2 files·+27 added/-10 removed
- Map context.Canceled to NewSilentError so Ctrl-C exits quietly instead of printing a noisy Cobra error (matches the clean.go convention).
- When the user confirms push but checkpoint pushing is disabled in settings, report that the refs stay queued instead of "Pushed 0 checkpoint ref(s)".
- Add a --remote flag (default origin) instead of hardcoding "origin", so repos that push to a different remote work.
- MigrateBranchToRefs now only uses an existing ref as the new commit's parent when it resolves to a real commit; a ref at an unreadable/non-commit object is treated as absent (orphan) rather than parenting on a bad hash, which would corrupt the commit graph for fetch+replay.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
5d352fa1b1bbView transcript
Changes
2
cmd/entire/cli
checkpoint
- Mmigrate.go+10/-5
- Mdoctor_migrate.go+17/-5
73 unmodified lines
74
75
76
77
77
78
79
80
81
82
80
81
82
83
83
84
85
86
87
88
89
90
91
73 unmodified lines
}
// Resolve the existing ref once: it drives both the idempotency check and
// the parent of the new commit.
// the parent of the new commit. Only a ref that resolves to a real commit
// becomes the parent — a ref pointing at an unreadable/non-commit object
// is treated as absent (orphan) rather than parenting the new commit on a
// bad hash, which would corrupt the commit graph for fetch+replay.
parent := plumbing.ZeroHash
if existing, err := repo.Reference(refName, true); err == nil {
parent = existing.Hash()
if commit, cerr := repo.CommitObject(parent); cerr == nil && commit.TreeHash == cpTreeHash {
result.Skipped++
return nil
}
if commit, cerr := repo.CommitObject(existing.Hash()); cerr == nil {
if commit.TreeHash == cpTreeHash {
result.Skipped++
return nil
}
parent = existing.Hash()
}
}
Mcmd/entire/cli/checkpoint/migrate.go+10/-5
1
2
3
4
5
6
7
8
3 unmodified lines
12
13
14
13
14
15
16
15
16
17
18
19
20
23 unmodified lines
44
45
46
47
48
49
50
51
52
28 unmodified lines
81
82
83
82
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package cli
import (
"context"
"errors"
"fmt"
"github.com/spf13/cobra"
3 unmodified lines
"github.com/entireio/cli/cmd/entire/cli/strategy"
)
// migrateCheckpointsPushRemote is the remote the opt-in "push now" targets; the
// actual push URL is resolved from checkpoint-remote settings when configured.
const migrateCheckpointsPushRemote = "origin"
func newDoctorMigrateCheckpointsCmd() *cobra.Command {
var dryRun bool
var remote string
cmd := &cobra.Command{
Use: "migrate-checkpoints",
23 unmodified lines
result, err := checkpoint.MigrateBranchToRefs(ctx, repo, dryRun)
if err != nil {
if errors.Is(err, context.Canceled) {
return NewSilentError(err)
}
return fmt.Errorf("migrate checkpoints: %w", err)
}
28 unmodified lines
return nil
}
pushed, err := strategy.PushMigratedCheckpointRefs(ctx, repo, migrateCheckpointsPushRemote)
pushed, err := strategy.PushMigratedCheckpointRefs(ctx, repo, remote)
if err != nil {
if errors.Is(err, context.Canceled) {
return NewSilentError(err)
}
return fmt.Errorf("push migrated refs: %w", err)
}
if pushed == 0 {
// Confirmed, but nothing went to the remote — checkpoint pushing
// is disabled in settings. The refs stay queued locally.
fmt.Fprintln(out, "Checkpoint pushing is disabled in settings; refs stay queued for the next push.")
return nil
}
fmt.Fprintf(out, "Pushed %d checkpoint ref(s).\n", pushed)
return nil
},
}
cmd.Flags().BoolVar(&dryRun, "dry-run", false, "Report what would be migrated without writing refs")
cmd.Flags().StringVar(&remote, "remote", "origin", "Remote to push migrated refs to when confirmed")
return cmd
}
Mcmd/entire/cli/doctor_migrate.go+17/-5