在网络共享文件夹中的GIT仓库中的并发性

52
我希望在一个(Windows)网络共享上存储裸的Git存储库。我使用Linux,并已将该网络共享与CIFS挂载。我的同事使用Windows XP,并已将网络共享自动挂载为网络驱动器(从ActiveDirectory中,不知何故)。我想知道是否可以在两台计算机上同时使用该存储库,而不会出现并发问题。我已经进行了测试,在我的端上可以正常克隆,但是我担心如果我们同时访问同一存储库(push / pull),会发生什么。在git FAQ中有关于使用网络文件系统(以及一些SMBFS问题)的参考资料,但我不确定网络/服务器/Windows/Linux是否有任何文件锁定-我相当确定没有。因此,有没有人在没有服务器和问题的情况下在网络共享上使用过Git存储库?谢谢,Alex。PS:我想避免使用http服务器(或git-daemon),因为我无法访问具有共享的服务器。此外,我知道我们可以从一个推/拉到另一个,但出于备份原因,我们需要将代码/存储库放在共享上。

更新:

我的担忧并不是网络故障的可能性。即使如此,我们也会在本地拥有所需的分支,并且能够编译我们的源代码。但是,我们通常经常提交,并且需要经常进行rebase / merge。在我看来,最好的选择是在共享上拥有一个中央存储库(以确保备份),然后我们都从那个存储库克隆,并用它进行rebase。但是,由于我们经常这样做,我担心如果我们同时push / pull,会发生文件/存储库损坏。通常,我们可以每次访问远程存储库时相互大喊大叫 :), 但最好通过计算机/网络来确保安全。

而且,GIT可能有内部机制来处理这个问题(因为某人可以在你工作的时候向你的一个仓库推送内容),但我还没有找到任何确定的信息。

更新2:

共享驱动器上的仓库将是一个空白仓库,不包含工作副本。


4
谢谢您的问题,Alex。我面临着类似的情况,这对我很有帮助。需要补充的一些要点是:你需要确保你们两个正在使用相同版本的Git,因为Windows和Linux的可执行文件将在网络共享的同一个裸库上工作,在理论上有可能存在某些版本之间的差异。可能性不大,但这是一个需要注意的标志。 - Nik Todorov
参见:https://dev59.com/6UnSa4cB1Zd3GeqPO43I - Mechanical snail
通过进入文件夹的高级共享选项,将同时用户数量限制为1可能会很有用。 - Carlos Blanco
3个回答

48
Git需要最少的文件锁定,我相信这是在使用网络文件系统上共享此类资源时出现问题的主要原因。它能够做到这一点的原因是Git库中的大多数文件——构成对象数据库的所有文件——都被命名为其内容的摘要,并且一旦创建就是不可变的。因此,在两个客户端尝试为不同内容使用相同文件的问题不会出现。
对象数据库的另一部分更加棘手,即引用存储在“refs”目录下的文件中(或者在“packed-refs”中),这些文件会发生改变:虽然refs/*文件很小并且总是被重写而不是被编辑。在这种情况下,Git会将新的引用写入一个临时的".lock"文件,然后将其重命名为目标文件。如果文件系统遵循O_EXCL语义,那么就是安全的。即使不是这样,最糟糕的情况也只是竞争覆盖引用文件。虽然遇到这种情况可能会很烦人,但它不应该导致损坏:这只是可能的情况是,您将推送到共享库,并且该推送看起来成功了,而实际上是别人的推送成功了。但是,这可以通过拉取(合并其他人的提交)并再次推送来解决。
总之,我认为在这里,库损坏不是太大的问题——虽然由于锁定问题可能会出现一些问题,但Git仓库的设计将最小化损害。
(免责声明:这在理论上听起来很好,但我没有对库进行任何并发测试,只在NFS而不是CIFS上共享它们)

1
谢谢!我一直在寻找这样的解释。我会尝试一下,看看是否会出现任何问题,并更新这个问题。祝你有愉快的一天! - Alex
1
你能提供一个更深入介绍此内容的网址或其他东西吗?这很有趣。 - knocte

7
为什么要麻烦呢?Git旨在分布式使用。只需在每台机器上有一个存储库,并使用发布和拉取机制在它们之间传播更改即可。
为了备份,每晚运行任务将您的存储库复制到共享文件夹中。
或者,在共享文件夹上创建一个存储库,并从中进行工作,但将其用作分布式存储库,从中可以相互拉取变更集。如果使用此方法,则执行构建等操作的性能将降低,因为您将不断通过网络访问。
或者,在自己的计算机上拥有分布式存储库,并定期运行任务将提交推送到共享文件夹上的存储库中。

我认为Alexandrei真正关心的问题不是分布式性质,而是如果由于CIFS/Windows共享失败(挂载问题、断开连接等),推送将会发生什么情况。 - Marcin Gil
我理解你的意思,但我的观点是,为什么要担心呢?如果你按照git的设计使用它,就不必担心了。 - 1800 INFORMATION
我认为这里的最后一点非常优雅地回答了问题。只需在不同的时间自动将每台计算机的存储库推送到共享中即可。 - supercheetah
谢谢大家的评论 - 这有助于我了解其他人对此问题的解决方案的想法。担心的不是网络故障(它是分布式的),而是没有服务器,就没有访问队列到存储库的内部文件,这可能导致信息损坏。 - Alex
在这里要记住的主要观点是,您绝不能共享工作副本。这会引入某人对工作副本所做更改被其他人覆盖的可能性。 - 1800 INFORMATION
这里介绍了这样一个概率,即某人在工作副本中的更改可能会被其他人覆盖。啊,这正是我在这里担心的问题,但我考虑的不是工作副本,而是“裸”存储库。 - Alex

-1

听起来你更喜欢使用集中式版本控制系统,这样备份的问题就得到了解决。 也许你可以在本地使用 xxx2git。


这就是我们目前正在做的事情,使用 SVN 作为中间层 - 但问题是一样的,没有服务器,我们是基于文件使用它。这是转向 GIT 的原因之一(以及它更好地匹配我们的工作,可以在同一工作副本中切换不同的分支)。 - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接