Skip to content

Instantly share code, notes, and snippets.

@ViBiOh
Last active January 15, 2024 19:26
Show Gist options
  • Select an option

  • Save ViBiOh/d72d01a82c604a37afb7a2165a72ffba to your computer and use it in GitHub Desktop.

Select an option

Save ViBiOh/d72d01a82c604a37afb7a2165a72ffba to your computer and use it in GitHub Desktop.
Git sync
#!/usr/bin/env bash
git_root() {
git rev-parse --is-inside-work-tree > /dev/null 2>&1 && cd $(git rev-parse --show-toplevel)
}
head_sync() {
if [[ "${#}" -ne 2 ]]; then
echo "Usage: head_sync [REMOTE_SERVER] [REMOTE_PATH]"
return 1
fi
local REMOTE_PATH_PREFIX="~/${2}"
if [[ "${2:0:1}" == "/" ]]; then
REMOTE_PATH_PREFIX="${2}"
fi
local branch=$(git symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')
ssh "${1}" "cd ${REMOTE_PATH_PREFIX} && git reset HEAD . && git clean -f && git checkout -- . && git fetch && git checkout ${branch} && git pull"
}
git_sync() {
if [[ "${#}" -lt 2 ]]; then
echo "Usage: git_sync [REMOTE_SERVER] [REMOTE_PATH] [DRY]?"
return 1
fi
local RED='\033[0;31m'
local GREEN='\033[0;32m'
local YELLOW='\033[0;33m'
local BLUE='\033[0;34m'
local RESET='\033[0m'
git_root
isGit=$?
if [[ ${isGit} -ne 0 ]]; then
return ${isGit}
fi
local REMOTE_PATH_PREFIX="~/${2}"
if [[ "${2:0:1}" == "/" ]]; then
REMOTE_PATH_PREFIX="${2}"
fi
local dry=false
if [[ "${3,,}" == "dry" ]]; then
dry=true
fi
if [[ "${dry}" == true ]]; then
echo -e "${BLUE}Dry run of syncing files...${RESET}\n"
else
echo -e "${BLUE}Syncing files...${RESET}\n"
fi
local toSync=()
local toDelete=()
local IFS=$'\n'
for gitFile in $(git status --porcelain); do
local prefix="${gitFile:0:2}"
local trimmedPrefix="${prefix#[[:space:]]}"
case "${trimmedPrefix:0:1}" in
"M" | "A" | "?")
toSync=("${toSync[@]}" "${gitFile:3}")
;;
"D")
toDelete=("${toDelete[@]}" "${REMOTE_PATH_PREFIX}/${gitFile:3}")
;;
"R")
local originFile=$(echo -n "${gitFile}" | awk '{print $2}')
local destinationFile=$(echo -n "${gitFile}" | awk '{print $4}')
toDelete=("${toDelete[@]}" "${REMOTE_PATH_PREFIX}/${originFile}")
toSync=("${toSync[@]}" "${destinationFile}")
;;
*)
echo -e "${BLUE} ¯\_(ツ)_/¯ Don't know how to handle ${gitFile}${RESET}"
esac
done
if ! ${dry}; then
echo -e "${YELLOW}Cleaning remote${RESET}\n"
ssh "${1}" "cd ${REMOTE_PATH_PREFIX} && git clean -f && git checkout -- ."
fi
if [[ "${#toDelete[@]}" -ne 0 ]]; then
! ${dry} && ssh "${1}" "rm -rf ${toDelete[@]}"
echo -e "${RED} - Deleted\n${toDelete[*]}${RESET}\n"
fi
if [[ "${#toSync[@]}" -ne 0 ]]; then
! ${dry} && rsync -raR "${toSync[@]}" "${1}:${REMOTE_PATH_PREFIX}/"
echo -e "${GREEN} + Copied\n${toSync[*]}${RESET}\n"
fi
echo -e "${BLUE}Done!${RESET}"
echo
}
watch_sync() {
if [[ -z "${NO_HEAD_SYNC:-}" ]]; then
head_sync "${@}"
fi
git_sync "${@}"
fswatch -0 -o --exclude=.git/ . | while read -d "" event
do
git_sync "${@}"
done
}
@kuvaldini
Copy link

kuvaldini commented Feb 27, 2019

git_root() {
  git rev-parse --is-inside-work-tree &>/dev/null  &&
  cd $(git rev-parse --show-toplevel) || return 1
}

Look much less verbose

@ViBiOh
Copy link
Author

ViBiOh commented Mar 1, 2019

@kuvaldini Thank you, I just updated it

@fabioperrella
Copy link

thank you for this script, it helped me a lot!

@vs4vijay
Copy link

How to use this script?

@schalla7
Copy link

This is awesome, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment