Skip to content

Instantly share code, notes, and snippets.

@matta
Forked from MarkLodato/git-snapshot.sh
Last active January 4, 2022 22:20
Show Gist options
  • Save matta/ea003ee4674093ca986bb75d18e53619 to your computer and use it in GitHub Desktop.
Save matta/ea003ee4674093ca986bb75d18e53619 to your computer and use it in GitHub Desktop.
git-snapshot-sh - a script to save junk code
#!/usr/bin/env bash
#
# git-snapshot - save junk code to a snapshots branch
#
# USAGE: git-snapshot.sh [-m message] [files...]
#
# Run `git add files` and then create a new commit on branch 'snapshot'
# with two parents, the previous snapshot and HEAD.
#
# If -m is given, the 'message' is used as the commit message; otherwise
# "snapshot" is used. This option must be given as the first argument.
#
# The 'files' argument can be any argument for git add; it defaults to "-a".
set -e
set -u
# Configuration:
BRANCH=refs/heads/snapshot # full refname of branch to update
MESSAGE=snapshot # default commit message
EXT=.snapshot # extension for temporary index file
TOPLEVEL="$(git rev-parse --show-toplevel)"
cd "$TOPLEVEL"
ORIG_INDEX_FILE="$(git rev-parse --git-path index)"
GIT_INDEX_FILE="$(mktemp -p '' index.XXXX)"
trap "rm -f $GIT_INDEX_FILE" EXIT
cp "${ORIG_INDEX_FILE}" "${GIT_INDEX_FILE}"
export GIT_INDEX_FILE
# Save the commit ID of where we currently are.
HEAD_ID="$(git rev-parse HEAD)"
# Get the current commit ID of the snapshots branch.
SNAPSHOT_ID="$(git rev-parse -q --verify "$BRANCH^{commit}")" || true
# Add all files to the index.
git add --all
# Create a tree object in the current index.
TREE_ID="$(git write-tree)"
# Exit if the new tree is no different from the current snapshot head.
# Namely, it has no diff against the previous one and the prior snapshot
# has the same HEAD_ID.
if [[ ! -z "$SNAPSHOT_ID" ]] && \
git diff-tree --quiet "$SNAPSHOT_ID" "$TREE_ID" && \
git rev-parse "${SNAPSHOT_ID}^@" | fgrep -wq "$HEAD_ID"; then
exit
fi
# Create a new commit with the tree we just created, the message given,
# and two parents: the previous snapshot and the current HEAD.
# Save the ID of this new commit.
ARGS=(-m"snapshot at $(date)" -p "$HEAD_ID")
if [[ ! -z "$SNAPSHOT_ID" ]]; then
ARGS+=(-p "$SNAPSHOT_ID")
fi
ARGS+=("$TREE_ID")
COMMIT_ID="$(git commit-tree "${ARGS[@]}")"
# Refer to this new commit from the snapshot branch.
git update-ref $BRANCH $COMMIT_ID
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment