我如何制作一个 git 挂钩来修改然后镜像一个 git 存储库?
How do I make a git hook for modifying then mirroring a git repository?
我的点文件 here 有一个 GitHub 存储库。
它包含一个 installdotfiles.sh 脚本,用于从 GitHub 安装点文件。我想在 GitLab 上有另一个 git 存储库用于备份(以及非常酷的自定义语法高亮 :P),镜像此存储库,除了 运行 宁 shell 存储库上的命令:
grep -rl raw.githubusercontent . |
xargs sed -i ''
's/raw.githubusercontent/gitlab/g'; grep -rl 'dotfiles/master' . |
xargs sed -i '' 's/dotfiles\/master/dotfiles\/raw\/master/g'
将指向 Github 的链接替换为指向 GitLab 的相应链接。
基本上,如果我推送到我的 GitHub 点文件存储库,我会自动更新我的 GitLab 存储库,除了 运行 存储库中的脚本首先,所以我让我的 GitLab 存储库包含 GitLab 链接。
我将如何实现这样的钩子?
我听说这可以使用 Git Hooks 来实现,但是我不熟悉它们,并且阅读它们,我不完全理解这样的事情是如何完成的。
P.S 如果它可以双向工作就更好了 - 所以当我推送到 GitLab 时,GitHub 将 运行 一个不同的脚本来替换 GitLab 链接与 GitHub 链接,因此每当我推送到其中一个时,两者都会相应更新。
How would I implement such a hook?
您可以选择任何您喜欢的挂钩并检查文件中的链接。
例如,您可以使用类似这样的东西,并在 if 条件之后添加您的脚本行。
pre-receive hook
#!/bin/sh
# Check to see if this is the first commit in the repository or not
if git rev-parse --verify HEAD >/dev/null 2>&1
then
# We compare our changes against the previous commit
against=HEAD^
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Redirect output to screen.
exec 1>&2
# Get the list of files which were commits
# assuming the other files are already contains the right values and does not need to be updated
files = $(git diff-tree -r --name-only $against )
# ... do whatever you want to do with the files
P.S it would be nice if it works both ways - so when I push to GitLab, GitHub will run a different script that replaces GitLab links with GitHub links, so that whenever I push to one, both update accordingly.
设置 2 个挂钩,我在每个存储库上设置正确的链接,每个存储库上都有正确的值。
另一种不使用钩子的方法:
如果您可以在客户端使用本地代码,则可以在 git:
中使用此功能
It turns out that you can write your own filters for doing substitutions in files on commit/checkout.
These are called clean
and smudge
filters.
在这里阅读所有相关内容:
https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Keyword-Expansion
最简单的方法是让您的脚本 installdotfiles.sh
使用一个变量,该变量是您根据要获取文件的存储库设置的(在调用脚本之前)。
例如:
origin=github curl https://raw.githubusercontent.com/thepiercingarrow2/dotfiles/master/installdotfiles.sh | sh
# or
origin=gitlab curl https://gitlab.com/thepiercingarrow2/dotfiles/raw/master/.bash_profile | sh
这意味着您的脚本包含一个简单的测试:
remote="raw.githubusercontent.com/thepiercingarrow2/dotfiles"
if [[ "${origin}" == "gitlab" ]]; then
remote="gitlab.com/thepiercingarrow2/dotfiles/raw"
fi
#bash_profile
curl -# https://${remote}/master/.bash_profile > ~/.bash_profile
换句话说,你真的不需要git钩子。任何一种。
我的点文件 here 有一个 GitHub 存储库。
它包含一个 installdotfiles.sh 脚本,用于从 GitHub 安装点文件。我想在 GitLab 上有另一个 git 存储库用于备份(以及非常酷的自定义语法高亮 :P),镜像此存储库,除了 运行 宁 shell 存储库上的命令:
grep -rl raw.githubusercontent . |
xargs sed -i ''
's/raw.githubusercontent/gitlab/g'; grep -rl 'dotfiles/master' . |
xargs sed -i '' 's/dotfiles\/master/dotfiles\/raw\/master/g'
将指向 Github 的链接替换为指向 GitLab 的相应链接。
基本上,如果我推送到我的 GitHub 点文件存储库,我会自动更新我的 GitLab 存储库,除了 运行 存储库中的脚本首先,所以我让我的 GitLab 存储库包含 GitLab 链接。
我将如何实现这样的钩子?
我听说这可以使用 Git Hooks 来实现,但是我不熟悉它们,并且阅读它们,我不完全理解这样的事情是如何完成的。
P.S 如果它可以双向工作就更好了 - 所以当我推送到 GitLab 时,GitHub 将 运行 一个不同的脚本来替换 GitLab 链接与 GitHub 链接,因此每当我推送到其中一个时,两者都会相应更新。
How would I implement such a hook?
您可以选择任何您喜欢的挂钩并检查文件中的链接。
例如,您可以使用类似这样的东西,并在 if 条件之后添加您的脚本行。
pre-receive hook
#!/bin/sh
# Check to see if this is the first commit in the repository or not
if git rev-parse --verify HEAD >/dev/null 2>&1
then
# We compare our changes against the previous commit
against=HEAD^
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Redirect output to screen.
exec 1>&2
# Get the list of files which were commits
# assuming the other files are already contains the right values and does not need to be updated
files = $(git diff-tree -r --name-only $against )
# ... do whatever you want to do with the files
P.S it would be nice if it works both ways - so when I push to GitLab, GitHub will run a different script that replaces GitLab links with GitHub links, so that whenever I push to one, both update accordingly.
设置 2 个挂钩,我在每个存储库上设置正确的链接,每个存储库上都有正确的值。
另一种不使用钩子的方法:
如果您可以在客户端使用本地代码,则可以在 git:
中使用此功能It turns out that you can write your own filters for doing substitutions in files on commit/checkout. These are called
clean
andsmudge
filters.
在这里阅读所有相关内容:
https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Keyword-Expansion
最简单的方法是让您的脚本 installdotfiles.sh
使用一个变量,该变量是您根据要获取文件的存储库设置的(在调用脚本之前)。
例如:
origin=github curl https://raw.githubusercontent.com/thepiercingarrow2/dotfiles/master/installdotfiles.sh | sh
# or
origin=gitlab curl https://gitlab.com/thepiercingarrow2/dotfiles/raw/master/.bash_profile | sh
这意味着您的脚本包含一个简单的测试:
remote="raw.githubusercontent.com/thepiercingarrow2/dotfiles"
if [[ "${origin}" == "gitlab" ]]; then
remote="gitlab.com/thepiercingarrow2/dotfiles/raw"
fi
#bash_profile
curl -# https://${remote}/master/.bash_profile > ~/.bash_profile
换句话说,你真的不需要git钩子。任何一种。