Skip to content

Instantly share code, notes, and snippets.

@jagipson
Created May 31, 2012 15:54
Show Gist options
  • Save jagipson/2844358 to your computer and use it in GitHub Desktop.
Save jagipson/2844358 to your computer and use it in GitHub Desktop.
Git repo prepare for backups and restore
#!/bin/bash
# 05/26/2012 jag
# COMPONENT_NAME: backup_prep.sh
#
# ORIGIN: Jeffrey Gipson
#
# Personal Proprietary
# (C) COPYRIGHT 2012 Jeffrey Gipson
# Unpublished work - All Rights Reserved
#
# DESCRIPTION:
#
# This script prepares the system for backup.
#
# EXAMPLE:
#
#
function warn () { echo "$@" 1>&2; }
function die ()
{
local code=1
local message="Unknown error in ${FUNCNAME[1]}"
if [[ "$1" =~ ^[0-9]+$ ]]; then
code=$1
shift
fi
message="$0"
if [[ -n "$message" ]]; then
warn "$message"
fi
exit $code
}
function find_git_repos ()
{
find "${@:-/home}" -type d \
-path */.gvfs -prune ! -name .gvfs \
-o -name .git \
-exec /usr/bin/dirname {} \;
}
function reset_git_repo ()
{
if [[ $# -ne 1 ]]; then
die "${FUNCNAME}() usage error, no argument, expected path to repo"
fi
if [[ ! -d "$1/.git" ]]; then
warn "$1 does not appear to be a non-bare git repo; skipping..."
return
fi
pushd "$1" &>/dev/null
if [[ ! -f "README.backup" ]]; then
warn "$1 wasn't prepared for backup... skipping"
return
else
rm -f README.backup
fi
if git reset --hard; then
if [[ "$(git stash list -1 --format=%s)" == "On working: backup" ]]; then
if ! git stash pop; then
die "SERIOUS: unable to pop stash for $1"
fi
fi
warn "$1 reset complete"
else
die "SERIOUS: unable to reset --hard for $1"
fi
}
function prepare_git_repo ()
{
if [[ $# -ne 1 ]]; then
die "${FUNCNAME}() usage error, no argument, expected path to repo"
fi
if [[ ! -d "$1/.git" ]]; then
warn "$1 does not appear to be a non-bare git repo; skipping..."
return
fi
pushd "$1" &>/dev/null
if git stash save backup && git ls-files -z | xargs -0 rm; then
cat>>README.backup<<EOT
This folder has been prepped for backup. It should only be in this state
during the backup. If something has gone wrong, attempt to run:
backup_prep.sh reset
If you need to reset it manually, then run:
git reset --hard
git stash list
If the top of the stash stack is "On working: backup" then pop the stash:
git stash pop
Finally delete this file:
command rm README.backup
EOT
warn "$1 preparation completed"
else
warn "An error occurred, attempting to reset..."
if reset_git_repo "$1"; then
die 2 "reset successful for $1"
else
die "SERIOUS: unable to recover state for $1"
fi
fi
popd &>/dev/null
}
function belt
{
echo "belt and suspenders: making extra backup in /tmp/gitrepobaks/tar"
find_git_repos | tar cf /tmp/gitrepobaks.tar -T -
}
case "$1" in
prep)
belt || die "belt broke!"
while read repo; do
prepare_git_repo "$repo"
done < <(find_git_repos)
;;
reset)
while read repo; do
reset_git_repo "$repo"
done < <(find_git_repos)
;;
belt)
belt
;;
list)
find_git_repos
;;
test)
belt
rm -rf /tmp/before /tmp/after
mkdir /tmp/before /tmp/after
pushd /tmp/before
tar xf /tmp/gitrepobaks.tar
cd ../after
tar xf /tmp/gitrepobaks.tar
while read repo; do
prepare_git_repo "$repo"
done < <(find_git_repos /tmp/after)
while read repo; do
reset_git_repo "$repo"
done < <(find_git_repos /tmp/after)
popd
exec diff -ur /tmp/before /tmp/after | less
;;
*)
die 1 "Usage: $BASH_SOURCE (prep|reset)"
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment