First, let me note that combining two different "tracking systems" (Git and OneDrive here) for the same folder is error-prone and can lead to inconsistencies (for instance).
So, I'd suggest you work in one Git repository stored outside of the OneDrive folder; this repository can be synchronized with GitHub or other remotes anytime you want, and it is then possible to ensure that every time you pull or merge something in your local master
branch, a Git hook also reliably copies the branch contents to your OneDrive folder, which can then be synchronized automatically.
Regarding hooks, note that this use case can be viewed as a somewhat non-standard one, given "auto-deploy hooks" are typically used in server-side bare repositories, using a post-receive
hook that is triggered after receiving a Push. However, it appears that from local side as well (in a non-bare repository), the post-merge
hook may provide a solution to address this specific use case!
In the sequel, I assume your repository is stored in $HOME/git/project
and you want to auto-deploy its contents in $HOME/OneDrive/MyFolder
every time you do a git pull
or any git merge
in the master branch (namely, git pull
in feature branches won't make the hook to run).
A comprehensive proof-of-concept of this idea
#!/usr/bin/env bash
# PoC(post-merge); see https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
# Assuming the ambient Git repo is NOT a bare repo (i.e., it has a working dir)
# Get unambiguous branch name; see https://stackoverflow.com/a/61808046/9164010
current_branch=$(git rev-parse --symbolic-full-name HEAD)
target_branch="refs/heads/master"
# TODO: Update this variable accordingly (a trailing slash is optional here):
dest_dir="$HOME/OneDrive/MyFolder"
# Redirect output to stderr
exec 1>&2
if [ "$current_branch" != "$target_branch" ]; then
echo "post-merge: no-op (NOT on $target_branch)"
else
echo "post-merge: on $target_branch (in $PWD)"
# Use mktemp + git-archive to avoid issues with a "dirty working directory"
# as well as with files to be ignored (e.g., the .git subdirectory itself);
# this is just ONE possible approach (which resets timestamps in $dest_dir)
# and other ones might be considered (e.g., using "rsync --exclude-from" …)
temp_dir=$(mktemp -d) || { echo "Failed to create tmp directory"; exit 2; }
set -exo pipefail
git archive --format=tar HEAD -- . | ( cd "$temp_dir/" && tar xf -)
rsync -a --delete-delay "$temp_dir/" "$dest_dir"
# Note that in the param $temp_dir/ above, the trailing slash is mandatory.
rm -fr "$temp_dir"
fi
Installation instructions
You'll just need to run:
touch ~/git/project/.git/hooks/post-merge
chmod a+x ~/git/project/.git/hooks/post-merge
# then edit this file with any text editor of your choice, pasting the code above
gedit ~/git/project/.git/hooks/post-merge &
Disclaimer: this Git hook relies on bash
and rsync
(which you may need to install beforehand); and I only tested it on GNU/Linux…
As an aside, if you need to extend or refactor this suggested shell code, I would recommend to always run the shellcheck linter on your script before using it in production.