This command is provides a snapshotting mechanism for refs/workdirs.
Routinely run git snapshot to save undo points:
% vim quxx.txt % git snapshot # ... % git add . && git commit -am "new commit" % git snapshot
Later, if you need to recall any recorded information:
% git log refs/snapshots/HEAD % git log refs/snapshots/refs/heads/master % git checkout refs/snapshots/refs/heads/master:quxx.txt
Often times I find myself sketching out projects without wanting to actually record a revision history yet.
Even though the history has no organizational value I could run:
git add . && git commit -m "$(date)"
every once in a while in order to record an edit history, sort of like an on-disk undo log.
git snapshot provides something less messy than this ad-hoc approach, and
safer than simply not recording anything at all.
git snapshot will run
git snapshot-ref HEAD, and if
a symbolic ref, also
git snapshot-ref refs/heads/master or whatever HEAD is
git-snapshot-ref starts by running
git snapshot-tree, which reads the
current working tree into a temporary Git index file, uses
git write-tree to
record that data in the object database, and prints the sha1 of the recorded
git-snapshot-ref then checks if the previous snapshot (recorded in
refs/snapshots/refs/heads/master, ...) is up to date. If the tree has changed
or new commits have been made on the ref, then a new commit is recorded into
the snapshots ref.
If you're working on a large patch, you can also snapshot an explicit ref:
git snapshot-ref topic_branch
Once you've created your commits, and then squashed and merged them you can: delete the snapshot log for that branch:
git update-ref -d refs/snapshots/topic_branch
By routinely running
git snapshot (for instance from within a crontab) you
get a fully versioned history that is somewhat similar in usefulness to
git reflog; if you made a mistake in recording your changes, or if you
accidentally modified a file before comitting it, you can recall a previous
version from the snapshot history:
git log refs/snapshots/... git checkout refs/snapshots/...:the/file/i/want.txt
On MacOS X you can use the Finder's Get Info dialogue to add a spotlight comment or a label to project directories.
Then you can use one of the following commands in your crontab to automatically snapshot it:
# snapshot every directory with 'git-snapshot' in its comment mdfind -0 "kMDItemFinderComment == '*git-snapshot*'" | xargs -0 -n 1 git-snapshot # snapshot every directory under ~/code that has the red label mdfind -0 -onlyin ~/code "kMDItemFSLabel == 6" | xargs -0 -n 1 git-snapshot
On Linux, just run
git snapshot-watch in the directory you want to
keep snapshots of. Every time you make a change to your project, it
will automatically be snapshotted. When you don't want this to happen
anymore, just Control-C the process.
git help rev-parsefor specifying time based revisions (e.g.
git commit --amendin conjuction with
git reflogcan provide a similar safety net.