Git(LFS):什么是锁定支持?我应该启用吗?

Mik*_*son 21 git git-lfs

"新"Git评论:

就在今天,我第一次遇到Git的以下评论(至少第一次看到它):

Mikes-Mac$ git push
Locking support detected on remote "origin". Consider enabling it with:
  $ git config 'lfs.https://github.com/<my_repo>.git/info/lfs.locksverify' true
Everything up-to-date
Mikes-Mac$ 
Run Code Online (Sandbox Code Playgroud)

这是什么Locking support?这是LFS(大文件存储)的某种互斥锁定吗?如果是这样,在git上工作是不是绝对必要?(最低限度,如何建立日志历史记录的"排序"?更糟糕的是,我不能通过同时写入来破坏二进制文件吗?)

我的行动

我最近没有对这个存储库做任何不同的事情,与我用LFS建立的任何其他存储库相比,我也没有做过任何不同的事情.

因此,我假设这是向"世界"提供的新评论,让我们了解新功能.

没有明显的文档

但是,无论是谷歌搜索还是通过他们的文档快速搜索,我都无法解释这一点.所以,我想知道:

  • 什么是锁定?
    • 是互斥吗?如果是这样,我的回购怎么能在没有它的情况下运作?
    • 这只限于LFS吗?它与普通的git文件锁定有什么不同?
  • 为LFS添加锁定支持的优缺点是什么?

ken*_*ytm 28

这里记录了对Git LFS的锁定支持https://github.com/git-lfs/git-lfs/wiki/File-Locking.

Git LFS v2.0.0包含File Locking的早期版本.文件锁定允许开发人员锁定他们正在更新的文件,以防止其他用户同时更新它们.Git存储库中的并发编辑将导致合并冲突,这在大型二进制文件中很难解决.

一旦文件模式.gitattributes可锁定,Git LFS将自动在本地文件系统上使它们只读.这可以防止用户在不先锁定文件的情况下意外编辑文件.

Git LFS将在推送时验证您是否未修改其他用户锁定的文件.由于文件锁定是早期版本,并且很少有LFS服务器实现API,因此如果Git LFS无法验证锁定文件,则不会停止推送.你会看到这样的消息:

$ git lfs push origin master --all
Remote "origin" does not support the LFS locking API. Consider disabling it with:
  $ git config 'lfs.http://git-server.com/user/test.locksverify' false
Git LFS: (0 of 0 files, 7 skipped) 0 B / 0 B, 879.11 KB skipped
Run Code Online (Sandbox Code Playgroud)
$ git lfs push origin master --all
Locking support detected on remote "origin". Consider enabling it with:
  $ git config 'lfs.http://git-server.com/user/repo.locksverify' true
Git LFS: (0 of 0 files, 7 skipped) 0 B / 0 B, 879.11 KB skipped
Run Code Online (Sandbox Code Playgroud)

因此在某种意义上,您可能会认为它是一个咨询互斥,因为:

  • 如果您没有"锁定"该文件,则无法对其进行编辑
  • 一旦用"锁定"文件git lfs lock,就可以对其进行编辑,存储库服务器将识别出您正在编辑它
  • 服务器不接受提交更改您已被其他人锁定的文件.

它主要用于帮助团队管理大型文件以防止合并冲突.

  • @GandalfSaxe 从程序员的角度来看这是有意义的,因为您需要“锁定”(获取)互斥体才能访问受互斥体保护的变量。 (5认同)
  • 嗨,`git config'lfs.http://git-server.com/user/repo.locksverify'true之后,**如何恢复**到“正常状态”?我只需要执行`git push -f origin 99157a1b1b27820dfba48c5e9d3c4f075670670c:master`即可恢复正常生活。 (3认同)
  • 听起来他们应该在编辑之前使用术语“解锁”文件。 (2认同)
  • @PeterKrauss我想你只是做 `git config 'lfs.http://git-server.com/user/repo.locksverify' false` ,对吧?“正常状态”是什么意思?它只能意味着禁用锁定验证,不是吗? (2认同)

Bob*_*rns 17

接受的答案未能回答问题的次要方面,特别是:

如果是这样,那么让 git 上的任何东西都能工作不是绝对必要的吗?(至少,如何才能建立日志历史记录的“顺序”?更糟糕的情况是,我不能让二进制文件因同时写入而损坏吗?)

因此,我将只讨论这些部分。

git 中没有同时写入,历史记录的顺序是原因的一部分答案!

当您将提交推送到远程 git 存储库时,它会验证您正在推送的提交是否是存储库已作为该分支头的提交的后代。

如果不是,则提交被拒绝。

如果是,那么 git 将发送一组 blob(文件数据)、树对象和提交。

然后它更新分支头以指向您的新提交。

除非头部发生变化,否则它将再次拒绝您的新提交。

如果被拒绝,您必须从远程存储库中提取较新的更改,并将它们与您的更改合并,或者在新更改的基础上重新调整您的更改(例如 git pull -r)。

无论哪种方式,您都会创建一个新的本地提交,它是存储库所拥有的内容的后代。

然后,您可以将此新提交推送到存储库。这个新提交可能会被拒绝,迫使您重复该过程。

文件永远不会被覆盖。git 的文件“mybigfile.mpg”只是一个具有基于文件内容的 SHA-256 哈希值的唯一 ID 的 blob。如果更改文件,则会生成一个具有新 ID 的新 blob。

文件名,只是树对象中的一个条目。它们也有基于其内容散列的 ID。

如果您重命名一个文件(或添加、删除等),那么它就是一个新的树对象,具有自己的 ID。

因为这些是历史记录的一部分(提交包括正在提交的顶级树的 ID 以及其父级的 ID),所以这些对象(blob、树、提交、签名标签)仅添加到存储库中,并且从未修改过。

Git 历史记录始终是有序的,因为它是一个链表,其中的链接指向父级。初始提交为零次提交,合并提交为两次或多次提交,否则为一次提交。

而且它们不需要任何显式锁定,因为 git 在进行更改之前会检查冲突。

仅需要锁定包含分支上头提交 ID 的文件,并且仅在检查更改和更新它之间的短暂时间内锁定。

git-lfs 中的锁解决了一个非常不同的问题。二进制资产通常无法合并,并且通常需要大量的工作来更改它们。

对于大型资产尤其如此。

如果两个开发人员开始对同一个文件进行更改,则必须放弃一组更改,然后以另一组更改为基础重新创建。

git-lfs 锁定可以防止这种情况意外发生。如果遇到锁,您要么等到稍后再进行更改,要么去与拥有该锁的人交谈。

他们要么可以进行所请求的更改,要么可以释放锁定并允许您在他们迄今为止的更改之上进行更改。然后,完成后,您可以推送更改并释放锁定,允许他们继续进行更改。

因此,它允许序列化特定文件的更改(整个开发过程,而不是文件写入),而不是用于文本源文件的并行然后合并范例。