Skip to content

Instantly share code, notes, and snippets.

@laggardkernel
Created July 7, 2020 06:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laggardkernel/67ccf6bfba59fdcd902fab5b7eb16d91 to your computer and use it in GitHub Desktop.
Save laggardkernel/67ccf6bfba59fdcd902fab5b7eb16d91 to your computer and use it in GitHub Desktop.
rsync CWD to remote server #bash #zsh
function rsync-up {
  if ! (($#)); then
    echo "No host is provided" >/dev/stderr
    return 1
  fi
  local host="$1"
  local local_dir remote_dir cmd git_conf ignore_conf

  # https://git-scm.com/docs/gitignore
  # gitignore syntax is not compatible with rsync --exclude, use --filter instead
  if [[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/git/config ]]; then
    git_conf="${XDG_CONFIG_HOME:-$HOME/.config}/git/config"
  else
    git_conf="$HOME/.gitconfig"
  fi
  ignore_conf=$(command awk -F "[ \t]*=[ \t]*" '/excludesfile/ {print $2}' "$git_conf")
  if [[ -z $ignore_conf ]]; then
    if [[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/git/ignore ]]; then
      ignore_conf="${XDG_CONFIG_HOME:-$HOME/.config}/git/ignore"
    else
      ignore_conf="$HOME/.gitignore"
    fi
  else
    # the --filter file is always referenced from local
    ignore_conf="${ignore_conf/\~/$HOME}"
  fi

  local_dir="$PWD/"
  if [[ "$local_dir" == "$HOME"* ]]; then
    remote_dir="~${local_dir#$HOME}"
  else
    remote_dir="$local_dir"
  fi
  cmd=(rsync --archive --verbose --compress --delete -e ssh --stats)
  # ~ won't be evaluated after added into an array like cmd+=('~')
  # cmd+=("$local_dir")
  # cmd+=(\'"${host}:${remote_dir}"\')

  # print with additional single quote
  echo "${cmd[@]} --filter='".- $ignore_conf"' ${local_dir} '${host}:${remote_dir}'" >/dev/stderr
  # TODO: use --dry-run instead of env
  if ! (($+DEBUG)); then
    ${cmd[@]} --filter=".- $ignore_conf" "${local_dir}" "${host}:${remote_dir}"
  fi
}

function rsync-down {
  if ! (($#)); then
    echo "No host is provided" >/dev/stderr
    return 1
  fi
  local host="$1"
  local local_dir remote_dir cmd git_conf ignore_conf

  if [[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/git/config ]]; then
    git_conf="${XDG_CONFIG_HOME:-$HOME/.config}/git/config"
  else
    git_conf="$HOME/.gitconfig"
  fi
  ignore_conf=$(command awk -F "[ \t]*=[ \t]*" '/excludesfile/ {print $2}' "$git_conf")
  if [[ -z $ignore_conf ]]; then
    if [[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/git/ignore ]]; then
      ignore_conf="${XDG_CONFIG_HOME:-$HOME/.config}/git/ignore"
    else
      ignore_conf="$HOME/.gitignore"
    fi
  else
    # the --filter file is always referenced from local
    ignore_conf="${ignore_conf/\~/$HOME}"
  fi

  local_dir="$PWD/"
  if [[ "$local_dir" == "$HOME"* ]]; then
    remote_dir="~${local_dir#$HOME}"
  else
    remote_dir="$local_dir"
  fi
  cmd=(rsync --archive --verbose --compress --delete -e ssh --stats)

  echo "${cmd[@]} --filter='".- $ignore_conf"' '"${host}:${remote_dir}"' ${local_dir}" >/dev/stderr
  if ! (($+DEBUG)); then
    ${cmd[@]} --filter=".- $ignore_conf" "${host}:${remote_dir}" "${local_dir}"
  fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment