当使用git进行fork时,是否有一种方法可以锁定单个文件或目录?

81
我们是一个由60多名开发人员组成的团队,致力于同一产品的开发工作,并且正在从SVN迁移至Git和GitHub。我们在SVN中拥有一种锁定单个文件的流程,每当开发人员想提交代码时,必须得到文件所有者的解锁。总共有三个人是150多个文件的所有者。解锁之前需要进行代码审查。
在Github中,我们计划使用Fork-Clone模型 - 每个项目工作组都会进行分叉(fork),每个开发人员都会克隆该分叉(clone),编写代码并提交到origin,功能的负责人将向上游(upstream)发起拉取请求。
尽管这似乎很好,但问题在于当交付一个大型项目时,需要进行大量的变更审核,这增加了文件所有者的负担。此外,这可能会发生在开发的后期阶段,因此可能会危及项目。
我们想到的一个解决方案是,在git推送到源(fork)时设置钩子。最后可以进行一次审查 git pull 到上游(upstream)。
然而,我们找不到任何适用于此的GitHub扩展或推送钩子。是否有一种快速方法(即现有的扩展程序)可以在GitHub中完成此操作,或者我们应该使用与git相同的钩子?

10
我认为Git并不需要文件锁定(在SVN中这很烦人)。大多数情况下,拉取请求和分支是您前进的方式。您甚至可以使用子模块将项目的不同部分分别保存在不同的仓库中,从而在团队之间获得更清晰的分离(文件保护)。因此,文件所有者只需成为主要子模块所有者,并审核他的团队在主分支上提出的每个拉取请求。然后,每个用户都有自己的派生版本。 - Simon Boudrias
http://programmers.stackexchange.com/questions/184435/workflow-using-binary-document-formats-in-git-without-locks-moving-from-subver - Steen
5
@SimonBoudrias,如果使用git来处理任何没有合并工具的文档类型(这几乎总是这种情况),那么您提出的想法就不可行了。虽然使用TortiseSVN/WebSVN可以避免使用MS Exchange,但是在使用git时我们无法这样做。我认为这是git的一个非常不幸的缺陷。 - peterh
使用Git版本控制系统锁定二进制文件 - phuclv
2
这不是技术问题,而是流程问题。为什么需要60名开发人员来处理150个文件?看起来问题就从那里开始了。你们使用的是哪种编程语言?你们的150个文件应该变成1500个文件,然后再将其分成模块。然后将你们的开发“团队”(60人的规模已经不是团队了,而是一个小村庄)分成7人左右的小组,这些小组可以真正作为一个团队运作,并让他们拥有一个模块的所有权。这样你和你的两个同事就不会再成为瓶颈,每个人都会更加快乐。而且你们也不需要锁定文件了。 - Frans
这个问题的理由可以在这个链接中找到:SSIS solution on GIT?。有时在单一仓库中,我们可能需要锁定某些文件。锁定会强制进行显式通信。 - Rajesh Swarnkar
8个回答

101

如果文件不可合并且您需要锁定它,那么请使用集中式解决方案而不是GIT,例如SVN或ClearCase。


8
这是正确答案,而非目前被接受的答案。点赞。甚至不需要二进制文件也可能需要锁定。以其他问题中关于iOS故事板的评论为例。 - Harindaka
我相信@Harindaka的意思是“其他答案”,而不是“其他问题”。所指的评论是:https://dev59.com/rWYr5IYBdhLWcg3wdp4C#v63lnYgBc1ULPQZFl9qW - Billy Jo
正确。应该是“参考其他答案中关于iOS故事板的评论...”。 - Harindaka
2
我们的一个使用案例是一个高度规范化的XML文件。例如,我们有一个字符串表。如果有人修改了文件中的某个字符串,那么表格就必须更改,并且假设它是按字母顺序排列的,那么在它之后的每个字符串引用都必须增加一个。总的来说,这对文件差异的影响很小,但是合并会变成噩梦。因此,我们进行锁定。尽管如此,差异的存储是以UTF-8文件差异的形式进行的,与存储整个文件相比,这种方法相对较小。SVN非常适合这种用例,而非锁定系统将会有严重问题。 - Bill - K5WL
1
听起来像是应该自动生成而不是提交到代码库的东西。或者我们都手动完成这些更改? - Dan M.
显示剩余3条评论

46

如果您正在使用 git LFS (这是一些git托管提供商(如GitHub)支持的),您可以使用文件锁定

通过编辑.gitattributes文件将文件类型标记为可锁定:

*.docx lockable
# Make MS Word files lockable

并使用以下方式锁定:

$ git lfs lock example.docx

您可以使用git lfs unlock example.docx解锁您的文件,如果想解锁其他人的文件,则需要添加--force参数。


6

4
并非完全的锁定,但Github引入了一个名为“代码所有者”的概念。 它允许您将代码库的一部分限制为仅在代码所有者审查后才允许提交。

3

请在此处编写答案的相关部分,因为链接可能会随时间变化而改变。 - Harsh Wardhan

3
Git不提供任何锁定功能,因为它是分散的。但是,如果您将代码托管在GitLab Enterprise Edition Premium上,您可以{{link2:使用Web界面锁定单个文件或文件夹},从而实现您想要做的事情。
如果您不想将项目托管在其他人的服务器上(他们的网站),您也可以下载GitLab并将其托管在自己的Web服务器上。

5
这与GitLab无关,使用Git LFS也可以实现。 Git LFS 2.0引入了锁定文件的功能:https://github.com/git-lfs/git-lfs/wiki/File-Locking。 TFS 2017.2支持此功能:https://learn.microsoft.com/en-us/vsts/release-notes/。 - erradi mourad

0

参考:

Git 是一种分布式版本控制工具,因此将文件集中锁定是违背其开发哲学的,因此不可能实现。

但是,我们可以通过其他方式实现相同的结果。

其中一种方法是使用 git-lfs,它用于大型文件系统。但这需要您迁移 git 存储库,安装 git-lfs 会更改 git 存储库,并且卸载需要再次迁移到 git 存储库。如其文档所述。这在其他答案中已经更清楚地解释了。

另一种解决方案是以某种方式使用git来实现相同的结果。例如,使用git pullupload-pack来触发服务器上的命令,该命令将在服务器上手动编写的方式处理文件锁定,并在推送时放置(pre|post)-recieve钩子以防止其他人更改已被锁定的文件。您还可以修改git-upload-pack命令,在拉取请求或存储库更新时触发警告,如果您愿意,但我不建议这样做,因为这会使git更新/升级变得困难。请查看我的this git repo,我在这里使用git-pull的upload-pack实现了相同的效果。

背景是,在我们的项目中,我们有导入/导出功能,可以在导出时生成XML文件。当多个人推送多个XML文件时,手动合并XML文件变得非常困难,因为其结构在每次导出时都会发生变化。因此,即使两个XML文件在技术上相同,但从文件和git的角度来看,它们始终是非常不同的文件。因此,我们使用聊天组协调,以便在某人已经在处理一个XML文件时停止工作。现在,我们使用git-pull的upload-pack来协调团队,只是为了提醒,并且有时候不需要提醒,通过我的脚本处理锁定,因此即使某人没有收到提醒,也可以放心地继续工作。


-28

这个用例是Git比SVN更好的原因之一--> rebase!如果你遵循良好的git工作流,在提交拉取请求之前,你会从上游进行变基。你不需要担心文件锁定、覆盖其他人的提交和合并冲突等问题... 变基将你的工作放在一边,应用远程提交,然后将你的工作应用在其上。

我认为这只需要重新思考你的流程,并依靠git的优势,而不是强行将Subversion工作流嵌入到git中。你的“分叉-克隆”模型可能也需要再看一眼。通常每个开发者都有自己的分支,如果你想,可以通过远程共享存储库来在团队之间共享。但是,共享同一个起点的贡献者会培养一些不好的习惯。

Gitflow是一个非常流行的git工作流,Github本身也有一些不错的提示并分享他们的工作流程


96
只要您有可合并的文件,这个方法就会起作用。如果您有二进制文件(例如Word文档),则无法使用该方法。 - schoetbi
11
Git和SVN并没有太大区别。对于使用非二进制文件的开发人员来说,Git更加适合。但在我们公司的情况下,由于需要处理大小为20MB+、版本数达到100+的大型二进制文件,我们选择了SVN,因为它比Git更擅长处理这些文件(根据我们测试时的场景)。顺便说一句,我喜欢Git。 - thclpr
51
被踩是因为你没有提供解决方案,而是说服人们不需要他们想做的事情,因为 Git 有其他东西。如果你在别人的更改之上重新派生你的更改,这是否意味着不会有任何冲突(即对同一行的编辑),并且你肯定不会覆盖其他人的工作。我真的不这么认为。 - xorcus
3
@pan40 你做不到。句号。 - usr-local-ΕΨΗΕΛΩΝ
5
我不同意这个答案,因为变基并不是处理冲突的万能方法,甚至更糟! SVN锁定的目的(除非有人欺骗工作副本或滥用强制窃取锁)是警告其他人某人正在对文件进行大量修改。在Git变基中,如果一个人将多个提交应用于其他人修改过的同一文件,则他将不得不解决每个提交的冲突才能重播。在这种情况下合并会更便宜,因为您只需解决一次冲突,但这并不是锁定的目的。当然,良好的项目管理和协调是有帮助的。 - usr-local-ΕΨΗΕΛΩΝ
显示剩余8条评论

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