Created
December 11, 2025 19:28
-
-
Save algal/dce3e1c22aae080788a1bf90349167d2 to your computer and use it in GitHub Desktop.
Saves and Checkpoints
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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