是否可以连贯地管理多个存储库?

时间:2012-02-03 21:58:17

标签: git multiple-repositories

我有一组git存储库,这些存储库是独立版本的,但彼此相关。例如,在添加功能时,我可能必须向共享库添加功能,然后扩展应用程序或服务以利用该功能。

目前,我必须在处理该功能时触摸的每个存储库上创建一个分支。然而,我想要做的是通过一次分支和合并这些多个存储库来简化过程(以减少忘记分支,或在一个存储库中提交/合并而不是另一个存储库)的可能性。

是否有一种简单的方法可以同时分支和合并多个存储库,或者这是一个更适合帮助程序脚本集合的任务?如果是后者,是否有任何已经完成此操作的脚本?

6 个答案:

答案 0 :(得分:7)

没有一种内置的方法可以同时处理多个存储库,如果你考虑git的分布式特性,除了可以定义的社交约定之外别无他法那。 (考虑一下,如果某人在一个存储库中从你那里撤走,而另一个存储库中的另一个遥控器,你会有这种连贯性吗?)

您可能会找到像mr这样的工具,它同时适用于多个存储库,非常有用。

如果你真的有紧密相关的东西,我建议你把它们放到一个存储库中。这样你就不会忘记任何步骤,因为它们发生在一个原子操作中。

如果你的代码实际上并没有紧密联系在一起,那么放弃“必须在同一时间分支”这个概念,你就会更快乐。

答案 1 :(得分:5)

您可以使用repo工具:https://gerrit.googlesource.com/git-repo/

  • 在多个项目上设置相同的分支
  • 使用一个命令查看多个存储库(分支,未合并提交)的状态
  • 使用清单文件管理一组存储库(克隆,同步等)
  • 很多其他很酷的东西

答案 2 :(得分:3)

另外,请看一下:http://fabioz.github.io/mu-repo/ - 它是一个像mr和repo这样的工具,因为我无法按照我的需要使它们工作:)

一些注意事项:

  • 它是用Python完成的(因此,适用于运行Python的任何操作系统:Linux,Win,Mac ......)

  • 除了同时针对多个repos运行常见的git操作外,还提供了工作流程:

    • 克隆多个存储库
    • 从repos打开网址(因此,可以立即为多个存储库创建拉取请求)。
    • 使用winmerge或meld ,
    • diff会立即更改多个repos
    • 执行非git命令

答案 3 :(得分:2)

没有内置的方法可以同时处理多个存储库

但是会有。

Git 2.27(2020年第2季度)以“ git update-ref --stdin”铺平了道路,后者学习了一些新的动词,以使用户控件ref可以更明确地更新交易。

这有助于在多个存储库中实现两阶段提交样式的原子引用更新

请参见commit e48cf33commit 94fd491commit de0e0d6commit 804dba5commit 5ae6c5acommit a65b8ac(2020年4月2日)和{{3} },commit bd021f3commit faa35ee(2020年3月30日)由commit edc3069
(由Patrick Steinhardt (pks-t)Junio C Hamano -- gitster --中合并,2020年4月29日)

commit d2ea03d:实现交互式事务处理

签名人:Patrick Steinhardt

update-ref命令现在只能通过其“ --stdin”参数处理排队事务,但是用户无法以更明确的方式处理事务本身。

例如在一个复制的场景中,可以想象一个协调器为多个存储库生成git-update-ref,并且只有当所有人都同意可以进行更新时,协调器才会发送一次提交。

这样的事务会话看起来像

> start
< start: ok
> update refs/heads/master $OLD $NEW
> prepare
< prepare: ok
# All nodes have returned "ok"
> commit
< commit: ok

或:

> start
< start: ok
> create refs/heads/master $OLD $NEW
> prepare
< fatal: cannot lock ref 'refs/heads/master': reference already exists
# On all other nodes:
> abort
< abort: ok

为了允许进行此类事务性会话,此提交为git-update-ref引入了四个新命令,这些命令与我们内部已经存在的命令相匹配,但“ start”除外:

  • start :开始新的交易
  • prepare :准备交易,即尝试锁定所有引用并验证其当前值是否与预期值相符
  • commit :显式提交会话,即更新引用以匹配其新的预期状态
  • abort :中止会话并回滚所有更改

根据设计,git-update-ref将在关闭标准输入后立即提交。
虽然在非交易世界中很好,但在交易世界中绝对是出乎意料的。
因此,一旦使用任何新的事务性命令,默认值将更改为中止而没有显式的“ commit”。
为了避免在排队更新和开始事务的第一个“ prepare”之间发生竞争,已添加“ start”命令以开始显式事务。

添加一些测试以行使此新功能。


Git 2.28(2020年第3季度)和新的钩子延续了一次内置处理多个存储库的方式。

请参见git-update-refcommit 6754159(2020年6月19日)。
(由Patrick Steinhardt (pks-t)Junio C Hamano -- gitster --中合并,2020年7月6日)

commit 33a22c1:实现参考交易挂钩

签名人:Patrick Steinhardt

用于更新引用的低级引用事务当前对于用户是完全不透明的。
尽管在大多数用例中肯定是合乎需要的,但有些人可能希望挂接到事务中以观察所有排队的参考更新以及观察中止或提交已准备好的事务

一个这样的用例是拥有给定Git存储库的一组副本,我们在其中对所有存储库立即执行Git操作,并期望结果在所有存储库中都相同。

虽然已经存在用于某些Git命令子集的钩子,这些钩子可用于为此实现投票机制,但许多其他工具目前对此还没有任何机制。

以上情况是新的“参考交易”挂钩直接进入Git的参考交易机制的动机。

该挂钩接收交易已移至的当前状态作为参数(“ prepared ”,“ committed ”或“ aborted ”),并通过其标准输入获取所有排队的参考更新。

虽然退出代码在“ committed”和“ aborted”状态下被忽略,但是处于“ prepared”状态的非零退出代码将导致事务过早中止。

鉴于上述用例,现在可以通过此钩子实现投票机制:一旦调用它,它将使用所有stdin并将其用于对中央服务进行投票。
当存储库的所有副本都同意时,该挂钩将以零退出,否则它将通过返回非零来中止事务。
最重要的好处是,这将捕获 all 一次编写引用的命令,从而允许通过单一机制为引用更新实现强大的一致性。

为了测试对存储库中未安装任何“ reference-transaction”挂钩的情况的影响,此提交针对refs引入了两个新的性能测试。
针对空的存储库运行,将产生以下结果:

Test                         origin/master     HEAD
--------------------------------------------------------------------
1400.2: update-ref           2.70(2.10+0.71)   2.71(2.10+0.73) +0.4%
1400.3: update-ref --stdin   0.21(0.09+0.11)   0.21(0.07+0.14) +0.0%  

性能测试p1400.2创建,更新和删除分支1000次,因此平均git-update-refs的运行时间超过3000次调用。
p1400.3会调用git-update-refs --stdin三次,分别排队一千次创建,更新和删除。

正如预期的那样,p1400.3始终没有显示出明显的影响,因为对于每一批更新,都有一个对否定钩子查找的access(3P)调用。
另一方面,对于p1400.2,可以看到由该补丁集引起的影响。但是,进行五次性能测试,每项测试均使用GIT_PERF_REPEAT_COUNT=10,进行运行,则开销在-1.5%到+ 1.1%之间。这些不一致的性能数字可以由产生3000个进程的开销来解释。这表明,组装挂钩路径并执行一次access(3P)来检查它是否存在的开销在大多数情况下都超过了操作系统的开销。


在Git 2.29(2020年第4季度)中,通过消除无效的优化来简化钩子。

请参见git-update-refscommit 0a0fbbe(2020年8月25日)。
(由Patrick Steinhardt (pks-t)Junio C Hamano -- gitster --中合并,2020年8月31日)

commit 6ddd76f:删除reference-transaction钩子的查找缓存

签名人:Patrick Steinhardt

在添加 reference-transaction 挂钩时,担心它可能会对根本不使用新挂钩的设置产生性能影响。
毕竟,每次准备,提交或中止reftx时,它都会执行,这与每个会话中创建的参考交易的数量成线性比例。
并且由于存在诸如refs git push之类的代码路径,它们为要更新的每个引用创建了一个新事务,因此这可能会转化为调用find_hook()很多。

为解决此问题,添加了缓存,以免重复执行负钩子查找。
原来,此缓存导致了回归,该回归已通过man(“ refs:使用reference-transaction hook修复交织的钩子调用”进行了修复,2020-08-07,Git v2.29.0-{{ 3}}在e5256c82e5中列出。)

在讨论此修复程序的过程中,我们意识到,即使在否定查找的情况下,缓存也无济于事。
虽然性能测试已添加到基准测试中,但确实在1%的范围内有所改善,但这实际上并不能保证拥有缓存。
此外,它也很易碎。例如。连续运行两次会产生以下结果:

Test                         master            pks-reftx-hook-remove-cache
--------------------------------------------------------------------------
1400.2: update-ref           2.79(2.16+0.74)   2.73(2.12+0.71) -2.2%
1400.3: update-ref --stdin   0.22(0.08+0.14)   0.21(0.08+0.12) -4.5%

Test                         master            pks-reftx-hook-remove-cache
--------------------------------------------------------------------------
1400.2: update-ref           2.70(2.09+0.72)   2.74(2.13+0.71) +1.5%
1400.3: update-ref --stdin   0.21(0.10+0.10)   0.21(0.08+0.13) +0.0%

这些基准测试中明显没有的一种情况是单个可执行文件搜索该挂钩数百次,这恰好是添加负缓存的情况。
p1400.2将为每个事务生成一个新的update-ref,而p1400.3仅对所有参考更新具有单个reference-transaction。
因此,此提交添加了第三个基准,该基准执行了数千个引用的非原子推送。这将为每个参考创建一个新的参考交易。但是即使在这种情况下,负缓存也无法持续提高性能:

Test                         master            pks-reftx-hook-remove-cache
--------------------------------------------------------------------------
1400.4: nonatomic push       6.63(6.50+0.13)   6.81(6.67+0.14) +2.7%
1400.4: nonatomic push       6.35(6.21+0.14)   6.39(6.23+0.16) +0.6%
1400.4: nonatomic push       6.43(6.31+0.13)   6.42(6.28+0.15) -0.2%

因此,我们完全删除缓存以简化代码。


在Git 2.30(2021年第一季度)中,“ merge batch #8”学会了在单个会话中进行多个事务。

请参见git update-ref --stdinmancommit 8c4417fcommit 2102043commit 262a4d2(2020年11月13日)。
(由commit c0e1726Patrick Steinhardt (pks-t)中合并,2020年12月8日)

Junio C Hamano -- gitster --:允许创建多个交易

签名人:Patrick Steinhardt
评论人:杰夫·金

尽管git-update-ref最近增长了一些命令,这些命令允许对commit 1bc550e中的事务进行交互式控制(“ update-ref:实现交互式事务处理”,2020-04-02,Git v2.27.0- rc0-update-ref中列出的e48cf33b61),尚无法在单个会话中创建多个事务。为此,当前仍然需要多次调用可执行文件。

此提交通过允许“开始”命令创建一个新事务(如果当前事务已提交或中止)来解决此缺点。

git update-ref现在包含在其merge中:

显式提交。此命令可能会在以下情况下创建一个新的空事务 当前的已提交或已中止。

答案 4 :(得分:0)

就像一个想法。我自己没有试过这个,但是我前段时间遇到过这个问题。 尝试将所有想要的存储库作为子模块添加到新的“根”存储库并使用以下命令

git submodule foreach --recursive <command>

您可以参考相关帮助以及如何处理子模块。您可以使用任何您想要的命令。 git和non-git命令。

答案 5 :(得分:0)

Android repo tool管理跨多个存储库创建功能分支。但是repo upload命令只能发布到Gerrit代码审查。

如果您使用像GitHub或GitLab这样的普通Git存储库管理器,repo upload将无效;你需要不存在的repo push命令。我在the Wave Computing fork of repo中实施了repo push。我们在生产中使用它。