58

When working on a feature branch in git, I frequently need to stash my changes to commit a bug fix to the main branch. When I'm done working on the changes, I git stash pop, which updates the timestamps on the files.

Even though the files are identical, the next time I try to save, I get:

WARNING: The file has been changed since reading it!!!

Do you really want to write to it (y/n)?

I don't want to automatically reload the file every time it changes on disk, only when I git stash pop.

Right now, I manually reload each buffer individually (:e). Is there any way I can do this in one command?

3 Answers 3

73

See :help bufdo for what you want to do. It will execute a command in each buffer in the buffer list. For example:

:bufdo e

You may also want to look at :help noconfirm to disable the confirmation dialog before issueing the bufdo command

:set noconfirm

and reenabling it after the bufdo command.

:set confirm
2
  • 5
    To force, try: :bufdo! e.
    – kenorb
    Apr 18, 2015 at 21:22
  • 3
    and without printing messages on screen :silent! bufdo e
    – Werner
    Aug 12, 2015 at 20:26
21

You can do this with the :checktime command. From the docs:

:checkt[ime]        Check if any buffers were changed outside of Vim.
                    This checks and warns you if you would end up with two
                    versions of a file.

The command will ask you what to do for each buffer the file of which has a changed timestamp. To disable this for files that haven't changed you can do :set autoread to force vim to just reload them. vim will ask you if the contents between the buffer and the file on disk have changed.

You can setup a map like the following for ease of use:

nnoremap <F5> :checktime<CR>
4
  • Here is some bonus information that is not really part of the answer: For me, on OpenSUSE, gvim (the GTK GUI for vim) does this automatically when it gains focus. I don't really know why it does it and I haven't checked on other systems but I thought it might be useful as an extra. Maybe someelse can confirm?
    – tokoyami
    Feb 5, 2015 at 22:05
  • This is really helpful! What I did on my end was to integrate this command as part of my tab switching shortcuts. i.e. nnoremap tl :tabnext<CR>:checktime<CR> Mar 6, 2019 at 11:39
  • 1
    @tokoyami, the feature you have in gvim may be related to FocusGained event in vim. You can find some related info here - unix.stackexchange.com/a/383044/99801. Dec 10, 2019 at 15:24
  • :checktime will not check hidden buffers, which sometimes might matter.
    – x-yuri
    Jan 17 at 20:42
0

A point that I think is relevant here. Which basically comes down to, "Why would one bother?" And helps to decide which solution to choose.

Let me start with terminology. There are active buffers (buffers which are open in some window, even if the window is not visible at the moment, e.g. on a different tab). When you abandon a buffer b (switch to some other buffer, or close some window, and b is no longer displayed in any window, including the non-visible ones), b becomes hidden if &hidden and unloaded otherwise.

From what I can see after executing a shell command (!:) vim does checktime. That is, it checks every active buffer and asks if the user wants to reload it (:bufdo executes a command in every buffer, including hidden and unloaded).

vim also checks if a buffer needs to be reloaded when the user switches to it. If the buffer was unloaded, it simply loads it (which makes sense). If the user switches to a hidden buffer, vim asks if the buffer should be reloaded.

When you do :lvim vim uses:

  • content in the buffers (possibly stale) in case of active and hidden buffers
  • content on the disk if case of unloaded buffers

Now let's say you're working on a project, have an active buffer b and switch to some other commit (:!git checkout ...). In this case vim asks you if you want to reload b if it was changed.

Let's say b was hidden, and before the switch a variable someName was mentioned in the file. But after the switch the variable is named someOtherName. vim will not ask you if you want to reload b. Then you do :lvim someOtherName **/*, and in this case vim will not find matches in b.

This is no argument against hidden buffers, but something to be aware of.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.