我需要将
hostA
上托管的多个 git 存储库“镜像”到 hostB
上的存储库中。我对 hostA
上的存储库具有只读访问权限,并拥有 hostB
上的存储库,但我没有 hostB
上的管理权限。
我在引号中写了“镜像”,因为我只需要跟踪主分支及其上的标签。唯一的要求是,在主分支上的每个标记提交中,代码都基于
hostA
和 hostB
匹配。
通过中间跳转(我的计算机)执行此操作的一种简单方法是:
git clone hostA:repo1.git
cd repo1
git remote add hostB:repo1.git
然后每次我想同步时:
git pull hostA main
git push hostB main
git push --tags hostB main
这在大多数情况下都可以正常工作,除了一些存储库中包含大型二进制文件,并且
hostB
有最大文件大小限制,而 hostA
没有。 hostB
确实有 git LFS,而 hostA
没有。因此,如果不采取一些措施排除大文件,我就无法将这些存储库推送到 hostB
。
我已经确定的一些可能的解决方案路径:
hostA
上的大文件:这显然是正确的事情(TM),但由于超出本问题范围的各种原因,这不会发生。hostB
之前进行本地更改,之后我不再在没有冲突的情况下从 hostA
拉取。hostA
(我想 - 我可能做错了......)。我目前正在使用选项(2),每次我想要同步时,我都会克隆一个新副本,对其进行过滤,然后强制推送到
hostB
,但这远非理想。
理想情况下,我正在寻找一种方法将二进制文件截断为零字节大小,并让 git 在从
hostA
拉取(即 git 没有看到冲突)并将空文件推送到 hostB
时忽略该文件
无怨无悔。
我不确定这是否可能,所以我也对其他解决方案持开放态度。同步大约每月一次,因此解决方案可能有点复杂。
在我看来这是不可能的,因为您无法即时更改要推送的内容(镜像)。
您只能避免推送大于指定大小的文件,例如使用 git hook,如下所示:
#!/bin/bash
# Located in .git/hooks/pre-push
MAX_SIZE=1024
human_size() {
awk -v sum=$1 'BEGIN {
hum[1024^3]="GB";hum[1024^2]="MB";hum[1024]="KB";
for (x=1024^3; x>=1024; x/=1024) {
if (sum>=x) { printf "%.2f %s\n", sum/x, hum[x]; break }
}
}'
}
files_to_push=$(git diff --cached --name-only --diff-filter=ACM)
for file in $files_to_push; do
if [ ! -e "$file" ]; then
continue
fi
size=$(du -k "$file" | cut -f1)
if [ $size -gt $MAX_SIZE ]; then
echo "Error: File $file is larger than the allowed size of $(human_size $((MAX_SIZE * 1024)))."
exit 1
fi
done
# If we're here, all files are of an allowed size
exit 0
我认为唯一真正的解决方案是通过 BFG Repo-Cleaner 过滤和清理你的源代码库。