镜像一个 git 非裸仓库

Mirroring a git non-bare repository

我需要一个 "robot user" 通过一些脚本与 git 裸远程存储库交互。这个裸仓库被称为中央仓库。

这次,这个机器人用户有自己的本地存储库,这不是一个裸存储库(他必须检查分支、合并分支……)。但是每天晚上,当他醒来工作时,他需要在本地有一个中央仓库的完美镜像(除了 master 之外的每个分支都可以进化,一些新的分支可以被创建,...)。

最好的方法是什么?

这非常简单(如果您所说的完美镜像是指 all branches, but not other refs)。

在没有 --bare 的情况下克隆裸仓库会导致正常的仓库。这样做一次后,您的机器人只需

git pull

他上班的时候。

不幸的是,这并不像前面的答案所建议的那样简单,因为 git pull 仅将更改合并到当前分支中。

你的机器人需要做的第一件事是 git fetch - 虽然 git pull 确实会(默认情况下)导致这种情况发生,但我建议做 fetch 直接避免潜在的混淆副作用。

当您执行 fetch 时,您得到的结果取决于 remote.central.fetch 配置选项(对于您指定的名为 central 的远程)。 clone 之后的默认设置(假设您没有指定 mirrorsingle-branchdepth 之类的东西,而没有 no-single-branchclone命令...) 将获取所有分支的历史记录,并更新远程分支引用(例如 refs/origin/central/master 以指示 central 上的 master 分支的条件)。

如果你坚持这样做,那么你的本地引用仍然与远程不同步。这是否是一个问题取决于你的机器人在做什么。这里有很多排列......您的机器人可能在 fetch 之前进行了本地更改,如果是这样,您想对它们做什么?您的机器人会在 fetch 之后进行更改,并最终推送这些更改吗?加上任意数量的 "if you want the history to come out looking like X, do Y" 考虑因素。

我会说,如果你的意图是移动所有本地分支以反映 central 上的相应分支,有两种基本方法:

1) 将 refspec 保留为默认设置,然后遍历分支更新本地 ref 以匹配远程。这使您有机会处理任何本地更改(通过将它们合并或变基到分支历史记录中),但这需要大量的脚本编写。

2) 将 refspec 更改为看起来像在镜像克隆上的样子。 (我觉得这就是你要表达的意思,以及你如何措辞这个问题。)这可能是有风险的,因为本地更改可能会被破坏,而且你仍然必须识别在 [=17 上删除的任何分支=].这里的设置类似于

git config remote.central.fetch +refs/*:refs/*