Add checkout command with co alias

This commit is contained in:
Chris Wanstrath 2026-02-25 20:23:35 -08:00
parent 9b5b0bc1b6
commit 156e4d9590
2 changed files with 49 additions and 0 deletions

View File

@ -10,6 +10,7 @@ import { action as openAction } from "./commands/open.ts"
import { action as reviewAction } from "./commands/review.ts"
import { action as shellAction } from "./commands/shell.ts"
import { action as closeAction } from "./commands/close.ts"
import { action as checkoutAction } from "./commands/checkout.ts"
import { action as mergeAction } from "./commands/merge.ts"
import { action as squashAction } from "./commands/squash.ts"
import { action as rebaseAction } from "./commands/rebase.ts"
@ -81,6 +82,19 @@ program
.description("Remove a session (alias for close)")
.action((branch: string, opts: { force?: boolean }) => closeAction(branch, opts))
program
.command("checkout")
.argument("<branch>", "branch name")
.option("-f, --force", "checkout even if there are unsaved changes")
.description("Close the session and check out the branch locally")
.action((branch: string, opts: { force?: boolean }) => checkoutAction(branch, opts))
program
.command("co", { hidden: true })
.argument("<branch>", "branch name")
.option("-f, --force", "checkout even if there are unsaved changes")
.action((branch: string, opts: { force?: boolean }) => checkoutAction(branch, opts))
// ── Branch ──────────────────────────────────────────────────────────
program.commandsGroup("Branch Commands:")

35
src/commands/checkout.ts Normal file
View File

@ -0,0 +1,35 @@
import { join } from "path"
import { unlink } from "fs/promises"
import * as git from "../git.ts"
import * as vm from "../vm.ts"
import * as state from "../state.ts"
import { die } from "../fmt.ts"
export async function action(branch: string, opts: { force?: boolean } = {}) {
const root = await git.repoRoot()
const session = await state.getSession(root, branch)
if (!session) {
die(`No session found for branch "${branch}"`)
}
const worktreeAbs = session.worktree
if (!opts.force && await git.isDirty(worktreeAbs)) {
die(`Branch "${branch}" has unsaved changes. Run "sandlot save ${branch}" first, or use -f to force.`)
}
await vm.clearActivity(worktreeAbs, branch)
await git.removeWorktree(worktreeAbs, root)
.catch((e) => console.warn(`⚠ Failed to remove worktree: ${e.message}`))
await unlink(join(root, '.sandlot', branch))
.catch(() => {}) // symlink may not exist
await state.removeSession(root, branch)
await git.checkout(branch, root)
console.log(`✔ Checked out ${branch}`)
}