set -euo pipefail
usage() {
cat <<'EOF'
Usage:
stash-copy user@host
stash-copy user@host:/remote/stash
Copies stash data and attribute files from a remote machine into the local
stash repository.
Behavior:
- local stash root uses STASH_DIR if set, otherwise ~/.stash
- remote stash root uses the explicit path if provided
- otherwise remote stash root uses STASH_DIR if set remotely, otherwise ~/.stash
- only data/ and attr/ are copied
- tmp/ is created locally and is not copied from the remote machine
EOF
}
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi
if [[ $# -ne 1 ]]; then
usage >&2
exit 1
fi
if ! command -v rsync >/dev/null 2>&1; then
echo "error: rsync is required" >&2
exit 1
fi
if ! command -v ssh >/dev/null 2>&1; then
echo "error: ssh is required" >&2
exit 1
fi
src="$1"
remote_host="$src"
remote_root=""
if [[ "$src" == *:* ]]; then
remote_host="${src%%:*}"
remote_root="${src#*:}"
fi
if [[ -z "$remote_host" ]]; then
echo "error: invalid remote spec" >&2
exit 1
fi
local_root="${STASH_DIR:-$HOME/.stash}"
local_data="$local_root/data"
local_attr="$local_root/attr"
mkdir -p "$local_data" "$local_attr" "$local_root/tmp"
if [[ -z "$remote_root" ]]; then
remote_root="$(
ssh "$remote_host" '
set -eu
if [ -n "${STASH_DIR:-}" ]; then
printf "%s\n" "$STASH_DIR"
else
printf "%s/.stash\n" "$HOME"
fi
'
)"
fi
if [[ -z "$remote_root" ]]; then
echo "error: could not determine remote stash path" >&2
exit 1
fi
echo "Copying data from $remote_host:$remote_root/data/ to $local_data/"
rsync -a \
-e ssh \
"$remote_host:$remote_root/data/" \
"$local_data/"
echo "Copying attributes from $remote_host:$remote_root/attr/ to $local_attr/"
rsync -a \
-e ssh \
"$remote_host:$remote_root/attr/" \
"$local_attr/"
echo "Done."