我有一个脚本test.sh
#!/bin/bash
echo start old file
sleep 20
echo end old file在我确实执行的存储库中,同时,我的git merge other-branch更改如下
#!/bin/bash
echo start new file
sleep 20
echo end new file进入当前的分支。
看来在Unix (?)不直接覆盖现有的文件节点(?)然后执行rm test.sh操作并创建新文件。这样,它保证脚本执行始终读取初始文件test.sh并以echo end old file终止。
备注:在我的系统(Ubuntu20.04)上执行脚本和在编辑器中直接处理内容时,会导致执行新代码,这是不好的.
这是正确的,它也是正确的Windows与git-for-windows?
发布于 2020-06-05 16:09:57
我不能回答关于Windows的问题,但是在Ubuntu18.04上,我可以确认git checkout或git merge会删除和重新创建一个修改过的文件,而不是在适当的地方编辑它。这可以在strace输出中看到,例如:
unlink("test.sh") = 0紧随其后
openat(AT_FDCWD, "test.sh", O_WRONLY|O_CREAT|O_EXCL, 0666) = 4如果在git命令之前创建一个指向文件的硬链接,然后再看一遍,您将看到有两个不同的inode,它们的内容不同。这是预期后删除和娱乐,而就地编辑将保留硬链接。
$ ls -l test.sh
-rw-r--r-- 1 myuser mygroup 59 Jun 5 17:04 test.sh
$ ln test.sh test.sh.bak
$ ls -li test.sh*
262203 -rw-r--r-- 2 myuser mygroup 59 Jun 5 17:04 test.sh
262203 -rw-r--r-- 2 myuser mygroup 59 Jun 5 17:04 test.sh.bak
$ git merge mybranch
Updating 009b964..d57f33a
Fast-forward
test.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
$ ls -li test.sh*
262219 -rw-r--r-- 1 myuser mygroup 70 Jun 5 17:05 test.sh
262203 -rw-r--r-- 1 myuser mygroup 59 Jun 5 17:04 test.sh.bak您在附在问题后面的评论中提到,它与Overwrite executing bash script files有关。虽然运行影响当前仍在执行的脚本的git命令似乎不是最好的主意,但实际上,删除和重新创建行为应该意味着现有的执行不会受到影响。即使bash解释器尚未将整个文件读入内存,它仍将在现有inode上具有一个打开的文件句柄,并且可以继续访问其内容,即使inode不再可以通过它所拥有的文件名访问。参见例如What happens to an open file handle on Linux if the pointed file gets moved or deleted
发布于 2020-06-05 16:30:58
在带有git-for-windows的Windows上,我看到了相同的行为:
$ mklink /H test.sh.bak
$ fsutil hardlink list test.sh.bak
test.sh.bak
test.sh
$ git merge test
$ fsutil hardlink list test.sh.bak
test.sh.bak这意味着硬链接没有被保留,意味着一个新的文件已经创建。
https://stackoverflow.com/questions/62218749
复制相似问题