Created
May 31, 2012 15:54
-
-
Save jagipson/2844358 to your computer and use it in GitHub Desktop.
Git repo prepare for backups and restore
This file contains 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
#!/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