function check_if_unchanged {
unset -v LATEST_DIFF
for file in "${PATSH_REPO}/${1}"-*.diff; do
[[ "$file" -nt "${LATEST_DIFF}" ]] && LATEST_DIFF="$file"
done
if [ "$LATEST_DIFF" != "" ]; then
patch -i "${LATEST_DIFF}" -o - "${PATSH_REPO}/${1}" 2> /dev/null | cmp - "${1}" > /dev/null
else
cmp "${PATSH_REPO}/${1}" "${1}" > /dev/null
fi
}
function showhelp {
cat <<EOF
${PATSH_NAME} -- dead simple patch/version control system
Usage:
patsh [options] command [files...]
Options:
-h show this help
-f enforce commit if no changes
Commands:
init initialize stash area
add start tracking file changes
save store changes done to file
restore undo changes and rewind to last version
diff show changes between working copy and last version
list show stored versions
EOF
exit 0
}
while [[ "$1" == -* ]]; do
case "$1" in
-f|--force)
printf "${PATSH_NAME}: not implemented yet\n"
;;
-h|--help)
showhelp
;;
esac
shift
done
case "$1" in
init)
mkdir "${PATSH_REPO}" && \
printf "${PATSH_NAME}: stash initialized\n"
;;
add|a)
while [ -e "$2" ]; do
if [ ! -e "${PATSH_REPO}/$2" ]; then
cp "$2" "${PATSH_REPO}/" && \
printf "${PATSH_NAME}: tracked file: ${2}\n"
else
printf "${PATSH_NAME}: file already tracked\npat.sh: use ${0} save ${2} to commit changes\n"
fi
shift
done
;;
list|ls)
while [ -e "$2" ]; do
if [ ! -e "${PATSH_REPO}/$2" ]; then
printf "${PATSH_NAME}: file not tracked\npat.sh: use ${0} add ${2} to track file\n"
exit 0
fi
printf "${PATSH_NAME}: ${2}: saved patches\n"
for file in "${PATSH_REPO}/${2}"-*.diff ; do
basename "${file}"
done | sort
shift
done
;;
save|ci)
while [ -e "$2" ]; do
if [ ! -e "${PATSH_REPO}/$2" ]; then
printf "${PATSH_NAME}: file ${2} not tracked\n"
elif check_if_unchanged "$2"; then
printf "${PATSH_NAME}: file ${2} not changed\n"
else
LATEST_DIFF="${PATSH_REPO}/$2-$(date +%s).diff"
diff -u "${PATSH_REPO}/$2" "$2" > "${LATEST_DIFF}"
printf "${PATSH_NAME}: changes written to %s\n" "${LATEST_DIFF}"
fi
shift
done
;;
restore|co)
while [ -e "$2" ]; do
unset -v LATEST_DIFF
if [ ! -e "${PATSH_REPO}/$2" ]; then
printf "${PATSH_NAME}: file ${2} not tracked\n"
exit 0
fi
cp "${PATSH_REPO}/${2}" "${2}"
for file in "${PATSH_REPO}/${2}"-*.diff; do
[[ "$file" -nt "${LATEST_DIFF}" ]] && LATEST_DIFF="$file"
done
if [ "$LATEST_DIFF" != "" ]; then
patch "${2}" < "${LATEST_DIFF}" > /dev/null
printf "${PATSH_NAME}: reset to ${LATEST_DIFF}\n"
else
printf "${PATSH_NAME}: reset to original version\n"
fi
shift
done
;;
diff)
while [ -e "$2" ]; do
unset -v LATEST_DIFF
printf "${PATSH_NAME}: ${2} working copy changes\n"
for file in "${PATSH_REPO}/${2}"-*.diff; do
[[ "$file" -nt "${LATEST_DIFF}" ]] && LATEST_DIFF="$file"
done
if [ "$LATEST_DIFF" != "" ]; then
patch -i "${LATEST_DIFF}" -o - "${PATSH_REPO}/${2}" 2> /dev/null | diff --color=always - "${2}"
else
diff --color=always "${PATSH_REPO}/${2}" "${2}"
fi
shift
done
;;
*)
if [ "$1" == "" ]; then showhelp; fi
printf "${PATSH_NAME}: unknown operation: ${1}\n"
;;
esac