Last active
August 18, 2021 05:01
-
-
Save matthieuprat/c11b27b0eec6c5e58f1e to your computer and use it in GitHub Desktop.
Sync a local Git work tree with a remote one
This file contains hidden or 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/sh | |
# | |
# Author: Matthieu Prat <[email protected]> | |
# Date: 01/22/2015 | |
# | |
# Sync a local work tree with a remote one. | |
# It's rsync on steroids within large Git repositories. | |
USAGE='<repository>' | |
LONG_USAGE='Sync a local work tree with a remote one.' | |
SUBDIRECTORY_OK=No | |
OPTIONS_SPEC= | |
. "$(git --exec-path)/git-sh-setup" | |
require_work_tree | |
cd_to_toplevel | |
[ $# -eq 0 ] || [ $# -gt 1 ] && { | |
usage | |
} | |
head=$(git rev-parse HEAD) | |
remote=$(git ls-remote --get-url $1) # e.g. git.example.org:path/to/repository | |
remote_host=${remote%:*} # git.example.org | |
remote_repo=${remote##*:} # path/to/repository | |
remote_exec () { | |
ssh -T -A $remote_host "cd $remote_repo && $*" | |
} | |
{ | |
# Push the local HEAD to the remote (if need be). | |
if ! remote_exec git rev-parse --verify --quiet $head^{commit} | |
then | |
git push --quiet --force $remote $head:refs/heads/rsync/HEAD && | |
remote_exec rm '$(git rev-parse --git-dir)'/refs/heads/rsync/HEAD | |
fi || die "Failed to push local HEAD to the remote." && | |
# Checkout the local HEAD on the remote end and clean untracked files. | |
remote_exec " | |
git checkout --quiet -f $head && | |
git clean -df | |
" || die "Unable to checkout local HEAD on the remote." && | |
# Apply local changes (if any) to the remote work tree. | |
if ! git diff-index --quiet --ignore-submodules HEAD | |
then | |
git diff-index --unified=0 --binary --ignore-submodules $head | | |
remote_exec git apply --unidiff-zero --whitespace=nowarn - | |
fi || die "Could not apply local changes on the remote." && | |
# Fallback to rsync for untracked files. | |
git ls-files --others --exclude-standard -z | | |
rsync --files-from=- -0 --no-dirs --whole-file . dev:dailymotion \ | |
|| die "Failed to push untracked files." | |
} > /dev/null && echo "Success." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this! You still have
dev:dailymotion
hardcoded as the remote in the rsync step. Replacing it with$remote
fixes it.