首页 > 解决方案 > 每次我推入远程存储库时,创建一个 Git Hook 以在另一个文件夹中提取数据

问题描述

我目前正在创建一个 Github 存储库,以获得更好的项目结构。我希望其他人通过仅链接查看我的项目(因为他们没有 github),但我没有找到解决方案。所以我试图在 OneDrive 中传输我的项目文件并且我成功了:我在 OneDrive 中有 git init 我的文件夹,我有 git pull 我的 github 存储库。此 OneDrive 文件夹将仅接收新文件,我正在使用计算机中的其他文件夹更新我的项目。现在,我希望每次将更新推送到远程存储库时,此过程都是自动的。我试图创建该代码(但我不确定他是否还好):

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

我想将它实现到一个 git hook 文件中,但我现在已经知道已经编写的代码的位置和位置......

你能帮我吗 ?谢谢 !

PS:像 post-receive 这样的钩子不在我的 .git 文件夹中。

标签: bashgitgithubhookgithooks

解决方案


首先,让我注意,为同一个文件夹组合两个不同的“跟踪系统”(此处为 Git 和 OneDrive)很容易出错,并且可能导致不一致(例如)。

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

关于钩子,请注意,这个用例可以看作是一个有点不标准的用例,因为“自动部署钩子”通常用于服务器端的存储库,使用post-receive在接收到推送后触发的钩子。但是,似乎从本地方面(在非裸存储库中),post-merge钩子也可以提供解决此特定用例的解决方案!

在续集中,我假设您的存储库存储在其中,$HOME/git/project并且您希望$HOME/OneDrive/MyFolder每次在mastergit pull分支中执行 a或 any时自动部署其内容(即,在功能分支中不会使挂钩运行)。git mergegit 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 钩子依赖于bashand rsync(你可能需要预先安装);而且我只在 GNU/Linux 上测试过……</p>

顺便说一句,如果你需要扩展或重构这个建议的 shell 代码,我建议在生产中使用它之前,总是在你的脚本上运行shellcheck linter 。


推荐阅读