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.