我在文档中找不到任何东西。如果我使用git pull,我能保证合并后的底层文件是原子编写的吗?关于我想实现的目标,还有一些背景:我有一些定期执行git pull的脚本,我需要知道在pull过程中是否可以依赖文件的状态有效。我们基本上使用git作为一个部署工具。我们从来没有合并冲突的设计。在远程端,一个作业不断拉每x秒,和其他作业读取文件。可能发生的是,我们打开一个文件,而它正在被git拉,并且文件的内容不是我们所期望的。除非git足够聪明,在底层操作系统上使用原子交换(RedHat在此)
yruzcnhs1#
简短的回答是“不”。值得注意的是git pull根本不是关于文件的,它是关于 commits 的。文件只是一个副作用。:-)pull操作只是git fetch(获取提交),然后是第二个Git命令,通常是git merge。merge步骤合并 commits。这也有合并文件的副作用,如果操作不是快进而不是合并;然后当合并或快进完成时,Git对结果提交执行git checkout。所以这真的可以归结为:* git checkout在操作系统级别是原子的吗?* 答案是非常响亮的 * 不:* 它在任何方面都不是原子的。工作树中写入的单个文件是一次写入一个,使用操作系统级的write调用,这不是原子的。需要创建或删除的文件是一次完成一个。Git * 确实 * 使用索引,索引Git也会锁定其他 Git 操作,并使Git级别的事务看起来是原子的,但任何在Git之外工作的事务,不与Git的锁定系统合作,将能够看到发生的变化。
git pull
git fetch
git merge
git checkout
write
ewm0tg9j2#
关于git pull的git checkout部分,请参见torek的answer。在git pull的git fetch部分,有一个--atomic标志,Git 2.36(Q2 2022)澄清了它。“git fetch“(man)可以进行两次单独的提取,但来自它们的ref更新在“--atomic“下的两个单独的ref事务中,这已在Git 2.36(Q2 2022)中得到纠正。参见commit 583bc41、commit b3a8046、commit 4f2ba2d、commit 62091b4、commit 2983cec、commit efbade0、commit 2a0cafd(2022年2月17日)by Patrick Steinhardt ( pks-t )。(由Junio C Hamano -- gitster --合并于commit 851d2f0,2022年3月13日)
atomic
--atomic
pks-t
gitster
fetch
签字人:帕特里克斯坦哈特当使用git fetch和--atomic标志时,预期是所有引用都被更新,或者在提取失败的情况下不更新。虽然我们已经有了相关的测试,但是我们还没有任何测试在删除refs或删除tags时执行原子性。测试覆盖率中的这一差距隐藏了我们确实没有正确处理这两种情况下的原子性。添加涵盖这些测试差距的测试用例,以证明破坏行为。警告:在Git 2.36(Q2 2022)中,恢复“删除引用不应单独触发松散和打包引用后端的事务事件”,该行为在引用被打包后未被修改时回归。参见commit 4315986、commit 347cc1b、commit c6da34a(2022年4月13日)by Junio C Hamano ( gitster )。(由Junio C Hamano -- gitster --合并于commit 4027e30,2022年4月14日)
4027e30c53
Revert“fetch:增加fetches的测试覆盖率”还原“合并分支”ps/avoid-unconscious-hook-invocation-with-packed-refs“”“git fetch --atomic”(man)发出了一个不必要的空错误消息,该错误已在Git 2.44(Q1 2024)中得到纠正。参见commit 18ce489,commit 97d82b2(2023年12月17日)by Jiang Xin ( jiangxin )。(由Junio C Hamano -- gitster --合并于commit deb67d1,2023年12月27日)
git fetch --atomic
jiangxin
协助人:帕特里克斯坦哈特签字人:蒋欣确认人:帕特里克斯坦哈特如果在原子提取期间发生错误,则在do_fetch()的末尾会出现冗余错误消息。它是在b3a8046中引入的(“fetch:make --atomic flag cover tags”,2022-02-17,Git v2.36.0-rc 0--merge listed in batch #11)。由于在函数do_fetch()中设置retcode之前会显示失败消息,因此在此函数结束时对err消息调用error()可能会导致显示冗余或空的错误消息。我们可以删除冗余的error()函数,因为我们知道函数ref_transaction_abort()永远不会失败。虽然我们可以通过运行命令“git grep“(man)-A1 ref_transaction_abort",来找到调用ref_transaction_abort()的常见模式,例如:
do_fetch()
ref_transaction_abort()
git grep
ref_transaction_abort",
if (ref_transaction_abort(transaction, &error)) error("abort: %s", error.buf);
字符串按照这种模式,我们可以容忍函数ref_transaction_abort()的返回值在将来被更改。我们还将err消息的输出延迟到do_fetch()的末尾,以减少冗余代码。
2条答案
按热度按时间yruzcnhs1#
简短的回答是“不”。
值得注意的是
git pull
根本不是关于文件的,它是关于 commits 的。文件只是一个副作用。:-)pull操作只是git fetch
(获取提交),然后是第二个Git命令,通常是git merge
。merge步骤合并 commits。这也有合并文件的副作用,如果操作不是快进而不是合并;然后当合并或快进完成时,Git对结果提交执行git checkout
。所以这真的可以归结为:*
git checkout
在操作系统级别是原子的吗?* 答案是非常响亮的 * 不:* 它在任何方面都不是原子的。工作树中写入的单个文件是一次写入一个,使用操作系统级的write
调用,这不是原子的。需要创建或删除的文件是一次完成一个。Git * 确实 * 使用索引,索引Git也会锁定其他 Git 操作,并使Git级别的事务看起来是原子的,但任何在Git之外工作的事务,不与Git的锁定系统合作,将能够看到发生的变化。ewm0tg9j2#
关于
git pull
的git checkout
部分,请参见torek的answer。在
git pull
的git fetch
部分,有一个--atomic
标志,Git 2.36(Q2 2022)澄清了它。“
git fetch
“(man)可以进行两次单独的提取,但来自它们的ref更新在“--atomic
“下的两个单独的ref事务中,这已在Git 2.36(Q2 2022)中得到纠正。参见commit 583bc41、commit b3a8046、commit 4f2ba2d、commit 62091b4、commit 2983cec、commit efbade0、commit 2a0cafd(2022年2月17日)by Patrick Steinhardt (
pks-t
)。(由Junio C Hamano --
gitster
--合并于commit 851d2f0,2022年3月13日)fetch
:增加fetches的测试覆盖率签字人:帕特里克斯坦哈特
当使用
git fetch
和--atomic
标志时,预期是所有引用都被更新,或者在提取失败的情况下不更新。虽然我们已经有了相关的测试,但是我们还没有任何测试在删除refs或删除tags时执行原子性。
测试覆盖率中的这一差距隐藏了我们确实没有正确处理这两种情况下的原子性。
添加涵盖这些测试差距的测试用例,以证明破坏行为。
警告:
在Git 2.36(Q2 2022)中,恢复“删除引用不应单独触发松散和打包引用后端的事务事件”,该行为在引用被打包后未被修改时回归。
参见commit 4315986、commit 347cc1b、commit c6da34a(2022年4月13日)by Junio C Hamano (
gitster
)。(由Junio C Hamano --
gitster
--合并于commit 4027e30,2022年4月14日)4027e30c53
:合并分支'jc/revert-ref-transaction-hook-changes'Revert“fetch:增加fetches的测试覆盖率”
还原“合并分支”ps/avoid-unconscious-hook-invocation-with-packed-refs“”
“
git fetch --atomic
”(man)发出了一个不必要的空错误消息,该错误已在Git 2.44(Q1 2024)中得到纠正。参见commit 18ce489,commit 97d82b2(2023年12月17日)by Jiang Xin (
jiangxin
)。(由Junio C Hamano --
gitster
--合并于commit deb67d1,2023年12月27日)fetch
:原子取数没有多余的错误信息协助人:帕特里克斯坦哈特
签字人:蒋欣
确认人:帕特里克斯坦哈特
如果在原子提取期间发生错误,则在
do_fetch()
的末尾会出现冗余错误消息。它是在b3a8046中引入的(“
fetch
:make--atomic
flag cover tags”,2022-02-17,Git v2.36.0-rc 0--merge listed in batch #11)。由于在函数
do_fetch()
中设置retcode之前会显示失败消息,因此在此函数结束时对err消息调用error()可能会导致显示冗余或空的错误消息。我们可以删除冗余的error()函数,因为我们知道函数
ref_transaction_abort()
永远不会失败。虽然我们可以通过运行命令“
git grep
“(man)-A1ref_transaction_abort",
来找到调用ref_transaction_abort()
的常见模式,例如:字符串
按照这种模式,我们可以容忍函数
ref_transaction_abort()
的返回值在将来被更改。我们还将err消息的输出延迟到
do_fetch()
的末尾,以减少冗余代码。