60

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

75

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
5
  • 5
    To force, try: :bufdo! e.
    – kenorb
    Commented Apr 18, 2015 at 21:22
  • 3
    and without printing messages on screen :silent! bufdo e
    – Werner
    Commented Aug 12, 2015 at 20:26
  • @kenorb I'm surprised it's not :bufdo e!. Because to edit a different file in a buffer that has unsaved changes, without prompting, we can do e! file. It's the e that needs forcing, not the bufdo iteration.
    – Kaz
    Commented Jan 12 at 22:04
  • There is a problem with :bufdo e. It brings the last buffer visited into the foreground. What if you want to reload buffers without changing which buffer is current? I use a buffer manager with a LRU display: recently viewed buffers closer to top. This :bufdo e messes with it; it visits every buffer and makes it the most recent buffer.
    – Kaz
    Commented Jan 12 at 22:09
  • You also might want to set ei= and check if the buffer is stored on disk (if bufname('%') != '' | e | endif).
    – x-yuri
    Commented Aug 13 at 8:49
22

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>
5
  • 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
    Commented 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> Commented 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. Commented Dec 10, 2019 at 15:24
  • :checktime will not check hidden buffers, which sometimes might matter.
    – x-yuri
    Commented Jan 17, 2023 at 20:42
  • :checktime is not reliable for me. I saw it work, but right now, I have a buffer whose file was externally modified. Vim knows this. If I do :w in that buffer, it produces the warning that the file was modified by another program. Yet :checktime does nothing. I ran it before trying :w. If I abort the :w operation, and try :checktime again, again nothing, and then :w again produces the warning. This is Vim 8.0 on Ubuntu 18; not latest/greatest. The buffer is not hidden. This reproduces when that buffer is current and displayed.
    – Kaz
    Commented Jan 13 at 1:20
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.

3
  • > If the user switches to a hidden buffer, vim asks if the buffer should be reloaded This is false. If a file is externally modified, Vim will switch to that buffer without any fuss. It will let you perform modifications and only when you save with :w will it then say, oh, that had been modified by an outside program, are you sure you want to clobber that ...
    – Kaz
    Commented Jan 13 at 1:23
  • This question is about how to tell Vim that files have been externally modified and just sync all the buffers to the new files, to prevent the above problem.
    – Kaz
    Commented Jan 13 at 1:25
  • @Kaz If you can't reproduce it then your buffer was likely not hidden. Try the following steps (it creates /tmp/a). The last command makes vim ask to reload the file.
    – x-yuri
    Commented Jan 13 at 16:09

Your Answer

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

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