checkpoint resume: harden auto-detection and clash message · Entire
checkpoint resume: harden auto-detection and clash message
a9d4ce9→main·
pfleidi·1w ago·2 files·+96 added/-12 removed
Auto-detection now only treats local branches as branch targets, so revision syntax like HEAD and remote-only branch names fall through to commit resolution instead of misrouting via branchCommit's origin/
fallback; the local-branch check also runs before the remote checkpoint fetch, sparing hex-named branches a network round-trip. The worktree-clash message points at 'entire checkpoint resume
Sessions
01KX43N6X1W5H2P290WEM1F45EView transcript
[?
Implement Checkpoint Resume CommandClaude Code·2 steps](/content/gh/entireio/cli/session/ba137a72-eaf9-443b-b868-49da78b39915#timeline-01KX43N6X1W5H2P290WEM1F45E/index.html)
Changes
2
cmd/entire/cli
Mcheckpoint_resume.go+29/-12
Mcheckpoint_resume_test.go+67
41 unmodified lines
The target can be a checkpoint ID (or prefix), a commit SHA (or ref) whose message carries an Entire-Checkpoint trailer, or a branch name. Auto-detection tries checkpoint ID first, then branch, then commit; use the flags to force one interpretation.
For a checkpoint or commit target, the branch containing the checkpoint's commit is checked out at its current tip before the session logs are.
```go
func resumeAutoTarget(ctx context.Context, cmd *cobra.Command, lookup *explainCheckpointLookup, target string, force bool) (*explainCheckpointLookup, error) {
if checkpointPrefixShape.MatchString(target) {
shapedLikeCheckpoint := checkpointPrefixShape.MatchString(target)
if shapedLikeCheckpoint {
if matches := matchCheckpointPrefix(lookup, target); len(matches) > 0 {
return lookup, resumeMatchedCheckpoints(ctx, cmd, lookup, target, matches, force)
}
}
if branchExistsLocally(lookup.repo, target) {
return lookup, runResume(ctx, cmd, target, force)
}
if shapedLikeCheckpoint {
var matches []id.CheckpointID
matches, lookup = matchCheckpointPrefixWithRemoteFallback(ctx, cmd.ErrOrStderr(), lookup, target)
if len(matches) > 0 {
}
}
if _, err := branchCommit(lookup.repo, target); err == nil {
return lookup, runResume(ctx, cmd, target, force)
}
err := resumeCommitTarget(ctx, cmd, lookup, target, force)
if errors.Is(err, errNoResumeCommit) {
return lookup, fmt.Errorf("nothing matched %q as a checkpoint ID, branch, or commit\nHint: run 'entire checkpoint list' to see available checkpoints", target)
}
}
}
func TestCheckpointResumeAuto_HeadResolvesAsCommit(t *testing.T) {
tmpDir := t.TempDir()
t.Chdir(tmpDir)
claudeDir := filepath.Join(tmpDir, "claude-projects")
t.Setenv("ENTIRE_TEST_CLAUDE_PROJECT_DIR", claudeDir)
repo, w, head := setupResumeTestRepo(t, tmpDir, false)
cpID := id.MustCheckpointID("abc123def456")
writeCommittedResumeCheckpoint(t, repo, cpID, "session-head", time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC))
if _, err := w.Commit("work\n\nEntire-Checkpoint: " + cpID.String(), &git.CommitOptions{
AllowEmptyCommits: true,
Author: &object.Signature{Name: "Test User", Email: "test@example.com"},
}); err != nil {
t.Fatalf("commit: %v", err)
}
// Seed origin/HEAD like a real clone has: auto-detection must not classify
// "HEAD" as a branch via branchCommit's origin/<name> fallback.
if err := repo.Storer.SetReference(plumbing.NewHashReference(plumbing.NewRemoteReferenceName("origin", "master"), head)); err != nil {
t.Fatalf("create origin/master: %v", err)
}
if err := repo.Storer.SetReference(plumbing.NewSymbolicReference(plumbing.NewRemoteHEADReferenceName("origin"), plumbing.NewRemoteReferenceName("origin", "master"))); err != nil {
t.Fatalf("create origin/HEAD: %v", err)
}
cmd, out := newCheckpointResumeTestCmd(t)
cmd.SetArgs([]string{"HEAD"})
if err := cmd.Execute(); err != nil {
t.Fatalf("Execute() error = %v\noutput: %s", err, out.String())
}
if !strings.Contains(out.String(), "session-head") {
t.Errorf("output should mention restored session ID, got: %s", out.String())
}
}
Conclusion
This documentation details changes and enhancements to the checkpoint resume command in the CLI, highlighting detection improvements and relevant code changes.