Git Checkpoints

Pretty regularly as I’m writing code, I want to save the current state of my work, but I don’t want the overhead of a full commit. Usually when I find myself in this situation, I’ll really like what I’ve written, but the code isn’t quite yet compilable (I prefer all my commits to at least build and run, so I can safely check them out later). In these situations, I want to be able to safely experiment with changing code without having to worry about losing my place, so I created a set of git aliases that allow me to do just that.

Usage

Here’s a quick example of how I use these git checkpoints:

$ git status
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   file1.txt
        modified:   file2.txt
        modified:   file3.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git checkpoint
[main b2f15ab] SAVEPOINT - CHECKPOINT
 3 files changed, 43 insertions(+), 2 deletions(-)
$ git listCheckpoints
checkpoint/2021_09_17_13_25_55
# After making new changes that you decide you no longer want
$ git status
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   file1.txt
        modified:   file2.txt
        modified:   file3.txt
        modified:   file4.txt
        modified:   file5.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git loadCheckpoint 2021_09_17_13_25_55
HEAD is now at b2f15ab SAVEPOINT - CHECKPOINT
$ git status
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   file1.txt
        modified:   file2.txt
        modified:   file3.txt
$ git deleteCheckpoint 2021_09_17_13_25_55
Deleted tag 'checkpoint/2021_09_17_13_25_55' (was b2f15ab)

Get the Code

Just copy this to your .gitconfig to start using git checkpoints:

  # Checkpoints allow you to get a commit hash for a WIP.
  # It's intended for when you'd like to mark progress to return to later, but don't yet want a full commit.
  # See https://nathanorick.com/git-checkpoints/ for more details.
  save = "!f() { git add -A && git commit --no-verify -m "\"SAVEPOINT - $@\""; }; f"
  undo = reset HEAD~1 --mixed
  checkpoint = "!f() { git save ${1-CHECKPOINT}; git tag "\"checkpoint/${1-`date +%Y_%m_%d_%H_%M_%S`}\""; git undo; }; f"
  listCheckpoints = tag -l "checkpoint/*"
  deleteCheckpoint = "!f() { git tag -d checkpoint/$1; }; f"
  loadCheckpoint = "!f() { git reset --hard checkpoint/$1 && git undo; }; f"
  cp = checkpoint
  cpls = listCheckpoints
  cpd = deleteCheckpoint
  cpld = loadCheckpoint