使用git版本控制系统锁定二进制文件


76

一年半以来,我一直在关注git社区,希望从SVN转向。使我退缩的一个特殊问题是无法锁定二进制文件。在过去的一年中,我尚未看到有关此问题的进展。我知道锁定文件违反了分布式源代码管理的基本原理,但是当二进制文件存在潜在冲突时,我看不到Web开发公司如何利用git来跟踪源代码和图像文件更改。

为了实现锁定的效果,必须标识“中央”存储库。无论git的分布式性质如何,大多数公司都将为软件项目提供“中央”存储库。我们应该能够将文件标记为需要来自指定地址的git仓库的锁定。也许由于git跟踪文件内容而不是文件而使这变得困难吗?

你们中的任何人都具有处理git和二进制文件的经验,这些文件应在修改前锁定?

注意:看起来Source Gear的新开源分布式版本控制项目Veracity已将锁定作为其目标之一。

Answers:


9

Git LFS 2.0增加了对文件锁定的支持。

使用Git LFS 2.0.0,您现在可以锁定正在处理的文件,从而防止其他人将文件推送到Git LFS服务器,直到再次解锁文件为止。

这将防止合并冲突以及文件系统级别上不可合并文件上的工作丢失。尽管文件锁定似乎与Git的分布式和并行性相矛盾,但文件锁定是许多软件开发工作流程的重要组成部分,尤其是对于使用二进制资产的大型团队而言。


74

Subversion有锁,而不仅仅是咨询。可以使用svn:needs-lock属性强制执行这些操作(但也可以在必要时故意将其破坏)。这是管理不可合并文件的正确解决方案。我工作的公司几乎存储了Subversion中的所有内容,并svn:needs-lock用于所有不可合并的文件。

我不同意“锁只是一种通信方法”。与电话或电子邮件之类的推送通知相比,它们是一种更为有效的方法。Subversion锁是自记录的(拥有锁)。另一方面,如果您必须通过其他传统的推送通知渠道(例如电子邮件)进行通信,则将通知发送给谁?除非您有整个开发团队的完整列​​表,否则您不会事先知道谁可能要编辑文件,尤其是在开源项目中。因此,这些传统的交流方法几乎没有效果。

违反DVCS原理的中央锁服务器是不可合并文件的唯一可行方法。只要DVCS没有中央锁功能,我认为它将保持我使用Subversion的公司的地位。

更好的解决方案是为所有二进制文件格式制作一个合并工具,但这是一个长期而持续的目标,永远不会“完成”。

这是关于该主题的有趣读物。


9
非常正确。DVCS并非旨在进行集中控制。但是,在DVCS之上构建集中控制系统可能是可行的,这将为您提供大多数DVCS可以提供​​的功能以及某些情况下所需的中央控制。
迈克尔·约翰逊

我意识到这个问题有点复杂,但由于在DVCS下锁定基本上没有意义,因此投票赞成。相反,您应该查看“独裁者和中尉”工作流,如git-scm.com/book/en/Distributed-Git-Distributed-Workflows
Aaron Newton

10

我同意锁定二进制文件对于某些环境是必需的功能。我只是想到了如何实现这一点:

  • 有一种将文件标记为“需要锁定”的方法(例如“ svn:needs-lock”属性)。
  • 签出时,git会将此类文件标记为只读。
  • 一条新命令git-lock将联系运行在某处的中央锁定服务器,以请求锁定权限。
  • 如果锁服务器授予许可,请将该文件标记为可读写。
  • git-add 会通知锁定服务器锁定文件的内容哈希。
  • 锁定服务器将监视该内容哈希是否显示在主存储库中的提交中。
  • 出现哈希后,释放锁。

这是一个半生半熟的想法,到处都有潜在的漏洞。它也违背了git的精神,但是在某些情况下肯定是有用的。

在特定组织内,可以使用脚本包装程序和提交钩子的适当组合来构建这种东西。


7
我看到的最大问题是git完全旨在脱机工作。虽然,正如您所说,您可以使用构建自定义脚本来实现此目的。除此之外,我很想拥有一个“锁定”分支,该分支会从遥控器上被推拉。它所拥有的只是锁表,取代了锁服务器。
Michael Johnson

1
@MichaelJohnson:您还可以在主分支中只有.lock- <filename>文件。这样,您可以一次提交进行编辑和解锁。
thejh

10

为了回应马里奥(Mario)对二进制文件中多个地方发生的更改的额外关注。因此,场景就是Alice和Bob都同时对同一二进制资源进行更改。他们每个人都有自己的本地存储库,这些存储库是从一个中央远程站点克隆的。

这确实是一个潜在的问题。因此,爱丽丝首先完成并推进到中心alice/update分支。通常,发生这种情况时,Alice会宣布应对其进行审查。鲍勃看到了,并对其进行了审查。他可以(1)自己将这些更改合并到他的版本中(从该版本分支alice/update并对其进行更改),或者(2)将自己的更改发布到bob/update。他再次宣布。

现在,如果爱丽丝(Alice)改master而推,鲍勃(Bob)在master尝试合并到其本地分支机构时将陷入困境。他与爱丽丝的冲突。但是同样,相同的过程可以应用于不同的分支。即使Bob忽略了所有警告并提交了有关Alice的警告,也总是有可能撤出Alice的提交以修复问题。这仅仅是一个沟通问题。

由于(AFAIK)Subversion锁只是建议性的,因此电子邮件或即时消息可以达到相同的目的。但是,即使您不这样做,Git也会让您对其进行修复。

不,本身没有锁定机制。但是锁定机制往往只是良好通信的替代品。我相信这就是Git开发人员未添加锁定机制的原因。


103
任何源代码控制系统都是结构化的,因此是开发人员之间进行通信的更好方式。电子邮件,聊天或电话不是很结构化,因此情况更糟。因此,当人们说他们将通过电子邮件,聊天或电话而不是使用scm进行通信时,这是错误的。保留源代码和组织开发人员之间的通信是任何SCM的2部分,而git仅解决svn的两个问题。
羊驼

7
我认为重要的一点是,锁定文件在磁盘上是只读的,而未锁定文件是RW。这意味着当某人尝试编辑锁定的文件时,其编辑器至少会警告他们该文件为RO。此时,系统会提示他们与锁定文件的任何人进行通信,以查明其更改是否是冗余的,互补的或不兼容的。如果不使用VCS更改文件权限,则不会自动提示用户进行通信,而这取决于他们容易出错的内存和过程。
KeyserSoze 2010年

52
典型的git响应“这是一个通信问题,因此与git无关”并没有意识到“锁定”是有效传达了一个人的意图,即在给定时间仅是一个人在工作,这很可能是因为一个复杂的二进制文件,很难(不可能)合并。对于从事二元资产的大型团队来说,这是完全有效和合理的要求。至少能够在命名分支上锁定文件将非常有用。该消息可能会传播到原产地,原产地的原产地等等……
Matt Connolly 2010年

20
-1这不能回答问题。问题中的(隐式)想法是在文件编辑之前锁定文件,以使其他人知道您正在处理文件。您所描述的是标准的git冲突解决方案,尽管它非常有用,但仅冲突发生后才起作用。
sleske 2012年

6
那么...在一个有100个用户的DVCS项目中,我不一定要与其中的大多数人共事,当我想独占访问二进制文件时应该向谁发送电子邮件?
iheanyi 2014年

8

我们最近才刚开始使用Git(以前使用Subversion),我发现工作流发生了变化,可以帮助您解决问题,而无需锁定。它利用了git的设计方式以及分支的简易性。

基本上,它归结为推送到非主分支,对该分支进行检查,然后合并到主分支(或目标分支中的任意一个)。

git是“预期”使用的方式,每个开发人员都会发布自己的公共存储库,并要求其他人从中获取。我发现Subversion用户对此有麻烦。因此,我们改为在中央存储库中推送分支树,每个用户都有自己的分支树。例如,这样的层次结构可能会起作用:

users/a/feature1
users/a/feature2
users/b/feature3
teams/d/featurey

随意使用您自己的结构。注意,我还显示了主题分支,另一个常见的git成语。

然后在本地回购中为用户a:

feature1
feature2

并将其发送到中央服务器(来源):

git push origin feature1:users/a/feature1

(这可以通过更改配置来简化)

无论如何,一旦对feature1进行了审核(无论是谁负责)(在我们的情况下,是功能的开发者,您可能只有一个用户负责合并到母版),然后执行以下操作:

git checkout master
git pull
git merge users/name/feature1
git push

提取将进行提取(将任何新的主更改功能分支拉出),并将更新主更新为中央存储库所具有的内容。如果用户a做好了工作并正确跟踪了母版,则合并应该没有问题。

所有这一切意味着,即使用户或远程团队对二进制资源进行了更改,也要先对其进行审核,然后再将其合并到master分支中。并且有明确的描述(基于过程)是什么时候进入master分支的。

您还可以使用git hooks以编程方式强制执行此方面的操作,但是同样,我还没有使用过它们,因此无法对其进行说明。


1
微波中的技术并非旨在用于加热食物。您是在告诉我,因为git最初不是为我的工作流程(以及很多人的工作流程)设计的,所以我不应该将git用作DVCS吗?您确实意识到“拉动请求”是创建对项目具有不同级别权限/信任的开发人员层。对于我们中的许多人来说,我们从事的项目大多数工程师都具有相同的权限,工程师相对较少,因此每个人所做的工作对整体至关重要,不能无限期地待决。
iheanyi 2014年

@iheanyi拉取请求工作流程可以很好地适用于您描述的团队类型(通常允许任何开发人员合并其他人的拉取请求)。
Marnen Laibow-Koser

@ MarnenLaibow-Koser一点也不。您所描述的内容颠倒了工作流程。现在,我合并了别人的更改,而不是每个人都对自己的合并负责。
iheanyi

@iheanyi,这是一个好处。这样做的想法是,没有人将自己的更改合并到母版中,以确保其他人知道并批准它们。而且它并不会颠倒工作流程:您仍将合并请求合并到master中,而不是在自己的分支中。•但是无论如何,也没有必要这样做才能与Git一起使用。您绝对可以在Git中执行功能分支工作流程,每个人都可以合并自己的更改,因此没有拉取请求。我不建议这样做,但是Git支持它很好。
Marnen Laibow-Koser

@ MarnenLaibow-Koser为某些人(而不是其他人)带来好处。我开始重复自己。
iheanyi

5

值得检查您当前的工作流程,以查看是否确实需要锁定图像。两个人独立编辑图像是相对不寻常的,需要一点沟通才能走得很远。


5

当我使用Subversion时,我svn:needs-lock认真地设置了所有二进制文件甚至是难以编辑的文本文件的属性。我从未真正经历过任何冲突。

现在,在Git中,我不必担心这些事情。请记住:Subversion中的锁实际上并不是强制性锁,它们只是通信工具。猜猜是什么:我不需要Subversion进行通信,我可以使用电子邮件,电话和IM进行管理。

我要做的另一件事是用纯文本格式替换了许多二进制格式。我用新结构化或LaΤ Ε Χ而不是字,CSV,而不是Excel中,ASCII艺术,而不是Visio中,YAML而不是数据库,SVG的,而不是面向对象的绘制,而不是ABC的MIDI等。


5
我一直以为你是认真的,直到我读了《 Visio的ASCII艺术》:/(也许你是。您用什么工具替代Visio而不是优秀的Vi?)
kizzx2 2010年

9
@ kizzx2:我使用的主要工具是一种良好的编程语言,其易读性足以使我不需要详尽的图表即可了解WTF的运行情况。更重要的是,我尝试编写可读的代码。一个好的IDE可以从代码中推断出图表,而无需我手动维护它们。对于简单的UML图,我可以使用诸如yUML之类的东西,它支持类,活动和用例图。对于简单图形,我使用Diagrammr从简单句子构建图形,而GraphViz用于复杂图形。
约尔格W¯¯米塔格

1
Diagrammr似乎真的很有趣!谢谢!
kizzx2 2010年

1
实际替换为文本格式并不能解决问题。某些二进制文件(例如纯位图)可以顺利合并。关键是内部结构和依赖性。如果您有任何XML文件依赖于其他内部节点的链接,并且在该链接上需要完整性,则无法合并。通常,大多数复杂的数据格式都使用这种内部链接,例如图形数据库。
2011年

yUML的开源等效项是Plant UML
Mystic

4

我已经在git讨论组上讨论了这个问题,并得出结论,目前,尚无关于git的集中式文件锁定方法的共识。


3

这不是解决方案,而是关于为什么需要锁定机制的评论。在某些领域中使用了一些工具,这些工具仅使用二进制格式,这些格式对任务至关重要,因此“使用更好/不同的工具”不是一个选择。没有可行的替代工具。即使您以ascii格式存储了相同的信息,我熟悉的信息实际上也不适合合并。我听到的一个反对意见是您希望能够脱机工作。我正在考虑使用的特定工具确实确实不能脱机工作,因为需要拉取许可证,因此,如果我在笔记本电脑上拥有数据,那无论如何我都无法在火车上运行该工具。也就是说,如果我的连接速度较慢,git会提供什么,我可以获得许可证,还可以进行更改,但是拥有快速的本地副本,可以查看不同的版本。即使在这种情况下,DVCS也会给您带来好处。

一种观点认为,git根本不是要使用的工具,但是它对于所有使用该工具管理的文本文件也很好,并且烦人的是需要针对不同文件的不同版本控制工具。

那种通过邮件锁定建议的方式真的很臭。我已经看到了这一点,并且厌倦了无休止的“我正在编辑”,“我已经完成编辑”的电子邮件流,并看到更改因此而丢失。我正在考虑的一种特殊情况是,一个较小的ascii文件集合会好得多,但这是一个问题。


1

我不希望文件锁定能够成为git中的功能。您主要对哪种二进制文件感兴趣?您实际上对锁定文件感兴趣,还是只是防止由于无法合并而引起的冲突?

我似乎记得有人在谈论(甚至实施)在git中合并OpenOffice文档的支持。


1

cad文件呢?如果文件没有被锁定(也保持只读),大多数cad程序将以任意更改的方式打开它们,任何vc都将其视为新文件。因此,在我看来,锁定是传达您打算更改某些particalur文件的理想方法。同样,它首先会阻止某些软件获得写访问权限。这样就可以更新本地文件,而无需完全关闭软件或至少完全关闭所有文件。


只是打开文件会改变一些任意位?听起来像是个严重的错误!
Stein G. Strindhaug


0

我不建议在我的公司使用git来解决相同的问题。我们使用EA进行所有设计,使用Microsoft Word进行文档编制,我们不预先知道谁可以编辑特定文件,因此独占锁定是我们唯一的选择。


3
我认为更好的长期解决方案是使用更好的工具。一个好的Wiki将会走很长一段路,或者仅仅使用不存储二进制文件的东西(HTML,TeX等)。锁定很不错,但是似乎大多数人只想使用锁定,因为二进制差异比较难处理,但是对于大多数使用而言,没有理由存储二进制文件。您将源代码保存在git中,而不是dll / sos和可执行文件中,因此为什么要存储文档的编译版本?

0

git将在非团队环境中很好地工作,在该环境中,每个开发人员仅负责一段代码或文件,因为在这种情况下,不需要有关锁的通信。

如果您的组织需要团队环境(通常是为了剥夺开发人员的工作安全性),请使用svn,而不适合git。Svn同时提供源代码控制和开发人员之间有关锁的通信。


2
许多git是专门为团队设计的,这是git比SVN领先几英里的一个区域。在这种情况下,锁定不像SVN那样容易,但是有一些功能会有所帮助,例如合并驱动程序。
shmish111 2014年

@ shmish111:开发人员之间的锁通信是团队环境的重要组成部分,为什么您认为“这种情况”不需要涵盖?Svn允许开发人员进行锁定/解锁通信,而Git则不允许。Git应该使它成为可选的但可用的功能。
alpav 2014年

1
就像我说的那样,git在锁定方面比SVN弱。我只遇到过一次这项要求,结果证明我们最终不需要这样做。我建议经常(并非总是)需要锁定文件时,这很好地表明您可以更好地组织项目。Git专为团队合作而设计,因此说它不是为团队环境而疯狂的。说团队环境剥夺了开发人员的工作安全性真是太疯狂了!
shmish111 2014年

@alpav“开发人员之间的锁通信是团队环境的重要组成部分”仅在首先需要锁的情况下。通常,它们不是。(我很开心地工作了20年没有锁定。我不明白为什么要这么做。)
Marnen Laibow-Koser


0

确实,重组项目可以帮助避免锁定,但是:

  • 团队还按其他优先级(位置,客户等)进行组织
  • 其他目标也选择工具(兼容性,价格,大多数员工的易用性)
  • 某些工具(因此有二进制文件)是不可避免的,因为没有替代工具可以完成相同的工作,并且以相同的价格满足公司的需求。

要求,整个公司可能会重组其工作流程并替换其所有生成二进制文件的工具,但由于缺少锁,才能够使用git听起来效率很低。

锁不适合git的哲学(从来没有为二进制编写过),但是在不可忽视的情况下,锁是解决此类问题的最有效方法。


-1

Git没有提供任何锁定文件的命令,但是我资助了一种使用git hooks实现该功能的方法。需要一个辅助服务器来存储锁信息。我们可以使用预提交钩子来检查是否有任何已提交的文件被锁定。并且,如果有人锁定了文件,则程序应将存储柜和锁定文件的信息告知辅助服务器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.