I have two machines on which I do most of my writing and development: a 27″ iMac and a 5 year old MacBook Pro. I use both of these computers everyday so I need to keep them in sync. I do that with Git repositories that live on a separate Linux server. One of those repositories contains all my org files. That includes blog posts, todo and task lists from my org agenda, and various other files that I maintain with org-mode. Those, along with all the other archived files means that I have a lot of files to keep up to date.
The first thing I do when I begin a session is a git pull to make sure I have the latest files from the other machine. Of course that means I have to be religious about pushing any changes to Git but that’s pretty much second nature now. The other thing you need to know is that when I’m finished with a session, I just put the machine in sleep mode. That means my Emacs still has all the open files from the last session when I get back to it. I also have desktop-save-mode on so this happens even if I turn the computer off or reboot it.
Here’s the problem. After the Git pull, those buffers and their underlying files are no longer in sync. I could set Emacs to automatically sync them but I don’t want to deal with the overhead. Thus I have to run revert-buffer by hand for each of the updated files. That’s a pain, of course, and cries out for automation so I wrote a quick bit of Elisp to do it for me. Here’s the code
(defun revert-all-buffers () "Revert all non-modified buffers associated with a file. This is to update existing buffers after a Git pull of their underlying files." (interactive) (save-current-buffer (mapc (lambda (b) (set-buffer b) (unless (or (null (buffer-file-name)) (buffer-modified-p)) (revert-buffer t t) (message "Reverted %s\n" (buffer-file-name)))) (buffer-list))))
The code is pretty simple. It goes through the buffer list looking for buffers with an underlying file. If the buffer is not dirty, I call revert-buffer to get the changes from the Git pull into the buffer. If I’ve made changes to the buffer, then I have to fix things up by hand so I don’t want to do the revert.
It seems to me that there’s nothing special about my work flow so others may have the same problem and find revert-all-buffers useful.
If you perform the pull with Magit, it will conservatively revert the associated buffers for you. That’s how I’ve mostly managed the issue.
Really? I didn’t know that. I do use Magit so this is good news for me. Do you have a pointer to the details?
It’s probably in the manual somewhere. All I know is that it just works for me with Magit 1.0.0. I did a little test right now to make sure I wasn’t imagining things, and yes, it’s definitely working. Switch branches and such through Magit and watch the magic.
Wouldn’t (global-auto-revert-mode t) do?
Yes but that’s what I meant when I said that I didn’t want to deal with the overhead. I read somewhere that set
global-auto-revert-modeon can slow things down because it has to keep checking the file status. My use case doesn’t require constant checking for a changed file; I only need to revert after a Git pull.I have the same setting you have and have global-auto-revert-mode on with absolutely no slow down.
+1
(global-auto-revert-mode t) has been in my config for more than 3 yrs. It’s makes an assert about the state of my files and emacs buffers that I find simplifies things. I have lost work a couple of times, but I’m happy with that cost in return for the sane work practices it enforces (stash or commit before pulling; never treat your emacs buffers as storage for valuable work, except when you are writing said work).
See also: http://www.neilvandyke.org/revbufs/
I was totally going to recommend this.
It changed my world :)