Emacs使用Git-Rebase将缓冲区恢复为奇怪的以前的状态 [英] Emacs Reverts Buffer to Weird Previous State with Git-Rebase
问题描述
我在OS X上使用Emacs(23.3.1)。我从终端发出git命令,而不是使用任何Emacs的VC功能。
(自定义)我的Emacs设置为在修改文件时进行刷新,这是通过我的.emacs文件的这些行启用的。 - 设置变量
...
'(自动恢复间隔1)
...
)
(全局自动恢复模式1)
这一直符合我的预期;如果我拉,我的Emacs缓冲区将更新与合并或冲突,就好像我已经退出缓冲区,并新加载每一个。
最近,我开始rebasing(调用git-取,然后git-rebase),而不是简单地拉(用git-pull),我不知道这个问题是否真的与git-rebase有关,但我当然没有注意到这个问题,现在就做。
所以问题在于:我更新了一个文件,使用 git commit -am...$ c $运行
git fetch origin
,然后运行 git rebase origin / master
(有时压扁在交互模式下一起提交) 。现在我已经引入了远程更新,我继续编辑文件,发现它看起来像我失去了所有最近的更改。第一次发生时,我非常生气,并且诅咒了rebase算法,以某种方式失去了我的修改,直到我意识到该文件完全完好无损,这只是Emacs在修改之前以某种方式恢复了文件的版本我刚刚承诺。我总是可以通过关闭缓冲区并重新加载文件来解决问题,但每次都会很痛苦。
有没有人知道问题是什么是
我是 autorevert
的原作者,但是,我不得不深入到我的记忆中,因为我还没有使用过它一段时间。
我相信这可以归结为Emacs核心的一个问题函数 verify-visited-file-modtime
,它自动恢复用来检查是否需要刷新缓冲区。
<这可能是由于以下原因造成的:
-
这可能是一种竞争条件,Emacs在此之前读取文件它被完全写入,但将缓冲区modtime设置为结束时间。 (当发生这种情况时,Emacs会自动恢复缓冲区的一半,但新的自动恢复不会触发恢复文件的最终版本。)
如果文件的两个变体具有相同的时间戳,那么Emacs将不会看到区别。 >我不认为你可以在Lisp方面做很少的事情来正确地工作(不用解决暴力解决方案)。 Emacs确实需要原子地获取已打开并读入缓冲区的文件的指纹,并且这只能从内核(这是我的区域外)完成。此外,某些文件系统的时间戳分辨率不会超过一秒,因此很难使用时间戳来检测文件是否已更改。
I'm using Emacs (23.3.1) on OS X. I'm issuing git commands from a terminal, not using any of Emacs' VC functionality. I have Emacs set up to refresh when files are modified, which is enabled by these lines of my .emacs file:
(custom-set-variables
...
'(auto-revert-interval 1)
...
)
(global-auto-revert-mode 1)
This has always worked as I expected; if I pulled, my Emacs buffers would update with the merges or conflicts as if I had quit the buffers and freshly loaded each one.
Recently I started rebasing (calling git-fetch and then git-rebase) instead of simply pulling (with git-pull), and I don't know if the issue actually has to do with git-rebase, but I certainly didn't notice the problem before then and do now.
So here's the problem: I update a file, commit the changes with git commit -am "..."
, run git fetch origin
, then run git rebase origin/master
(sometimes squashing commits together in interactive mode). Now that I've pulled in the remote updates, I go to edit the file some more, and find that it looks like I've lost all my recent changes. The first time it happened, I got very mad and cursed the rebase algorithm for somehow losing my changes, until I realized that the file was completely intact and it was just that Emacs had somehow reverted to the version of the file prior to the changes I'd just committed. I can always solve the problem by closing the buffer and loading the file again, but this is quite a pain to do every time.
Does anyone have any idea what the problem is?
I'm the original author of autorevert
, however, I have to dig quite deep into my memory as I haven't worked with it for quite some time.
I believe this boils down to a problem with the Emacs core function verify-visited-file-modtime
, which auto-revert use to check if a buffers needs to be refreshed.
This could be caused by a number of reasons:
This could be a race condition, where Emacs reads a file before it was completely written, but sets the buffer modtime to the end time. (When this occurs, Emacs has auto-reverted the buffer half-way, but a new auto-revert does not trigger to revert the final version of the file.)
If the two variants of the file have the same time stamp, then Emacs will not see the difference.
I don't think that there is little you can do on the lisp side to get this working properly (without resolving to brute-force solutions). Emacs really need to atomically get a fingerprint of the file that has been opened and read into a buffer, and this can only be done from the core (which is something outside my area). Also, some file systems don't have a higher timestap resolution than one second, making it inherently difficult to use the timestamp to detect if a file has been changed.
这篇关于Emacs使用Git-Rebase将缓冲区恢复为奇怪的以前的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!