创建一个Git Hook,以便在每次推送远程存储库时从另一个文件夹中提取数据



我目前正在为我的项目创建一个更好的结构Github存储库。我希望我的项目被其他人通过链接查看(因为他们没有github),但我没有找到解决方案。所以我试图在OneDrive中传输我的项目文件,我已经成功了:我在OneDrive中有git init我的文件夹,我有git pull我的github仓库。这个OneDrive文件夹只接收新文件,我正在用我电脑上的另一个文件夹更新我的项目。现在,我希望这个过程在每次将更新推送到远程存储库时都是自动的。我试着创建代码(但我不确定他是否ok):

cd "D:/Ewan/OneDrive/MyFolder" // Once I git push, I go to the folder to update it
git pull <github-repo> <my-branch>

我想实现它到一个git钩子文件,但我现在已经知道在哪里,在代码已经写…

你能帮我一下吗?谢谢!PS:有些钩子,比如post-receive,不在我的。git文件夹中。

首先,让我指出,结合两个不同的"跟踪系统"(Git和OneDrive在这里)对于同一个文件夹是容易出错的,并可能导致不一致(例如)。

所以,我建议你在一个Git存储库中工作,存储在OneDrive文件夹之外。;这个仓库可以随时与GitHub或其他远程同步,然后可以确保每次你拉或合并本地master分支中的内容时,Git钩子也可靠地将分支内容复制到你的OneDrive文件夹,然后可以自动同步。

关于钩子,请注意,给定"自动部署钩子",这个用例可以被视为有点非标准的用例;通常在服务器端裸存储库中使用,使用在接收到Push后触发的post-receive钩子。然而,似乎从本地端(在非裸存储库中),post-merge钩子可以提供解决这个特定用例的解决方案!

在续集中,我假设您的存储库存储在$HOME/git/project中,并且您希望每次在中执行git pull或任何git merge时,在$HOME/OneDrive/MyFolder中自动部署其内容。(即,特性分支中的git pull不会使钩子运行)。

这个想法的一个全面的概念证明

#!/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

安装说明

你只需要运行:

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 &

免责声明:这个Git钩子依赖于bashrsync(你可能需要提前安装);我只在GNU/Linux上测试了它…

作为题外话,如果您需要扩展或重构建议的shell代码,我建议在生产环境中使用之前,始终在脚本上运行shellcheck检查器。