Skip to content

Instantly share code, notes, and snippets.

@algal
Created December 11, 2025 19:28
Show Gist options
  • Select an option

  • Save algal/dce3e1c22aae080788a1bf90349167d2 to your computer and use it in GitHub Desktop.

Select an option

Save algal/dce3e1c22aae080788a1bf90349167d2 to your computer and use it in GitHub Desktop.
Saves and Checkpoints
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.9"
# ///
"""Checkpoint: save, then squash consecutive solveit commits into one with given name."""
import subprocess, sys
from datetime import datetime, UTC
def git(*args, check=True):
r = subprocess.run(['git', *args], capture_output=True, text=True, check=check)
return r.stdout.strip()
def save():
if not git('status', '--porcelain'): return
git('add', '-A')
git('commit', '-m', f"solveit commit: {datetime.now(UTC):%b. %d %H:%M:%S UTC}")
def list_squashable():
"""Return [HEAD,...] of consecutive non-merge solveit commits, stopping at branch points."""
log = git('log', '--format=%H|%P|%s')
if not log: return []
candidates = []
for line in log.splitlines():
h, parents, msg = line.split('|', 2)
if msg.startswith("solveit commit:") and len(parents.split()) < 2:
candidates.append(h)
else: break
if not candidates: return []
# Exclude commits reachable from other branches
current = git('rev-parse', '--abbrev-ref', 'HEAD')
branches = [b for b in git('branch', '--format=%(refname:short)').splitlines() if b != current]
commit_idx = {c: i for i, c in enumerate(candidates)}
cutoff = len(candidates)
for b in branches:
mb = git('merge-base', 'HEAD', b, check=False)
if mb in commit_idx: cutoff = min(cutoff, commit_idx[mb])
return candidates[:cutoff]
def squash(commits, msg):
if not commits: return
oldest = commits[-1]
parent = git('rev-parse', f'{oldest}^', check=False)
if parent: git('reset', '--soft', parent)
else: git('update-ref', '-d', 'HEAD')
git('commit', '-m', msg)
def main():
if len(sys.argv) != 2: sys.exit("Usage: sv_checkpoint <checkpoint_name>")
try: git('rev-parse', '--show-toplevel')
except subprocess.CalledProcessError: sys.exit("Not a git repository")
if git('rev-parse', '--abbrev-ref', 'HEAD') == 'HEAD': sys.exit("Cannot checkpoint with detached HEAD")
save()
squash(list_squashable(), sys.argv[1])
if __name__ == '__main__': main()
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.9"
# ///
"""Save: stage all changes and commit with auto-generated message."""
import subprocess, sys
from datetime import datetime, UTC
def git(*args): return subprocess.run(['git', *args], capture_output=True, text=True, check=True).stdout.strip()
def main():
try: git('rev-parse', '--show-toplevel')
except subprocess.CalledProcessError: sys.exit("Not a git repository")
if not git('status', '--porcelain'): return # No changes
git('add', '-A')
git('commit', '-m', f"solveit commit: {datetime.now(UTC):%b. %d %H:%M:%S UTC}")
if __name__ == '__main__': main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment