1

This question already has an answer here:

I opened several files in vim and then switched git branches. I want to save the versions I have open to the new git branch, for all of them, without having to silence the WARNING: The file has changed since reading it!!! for each of them individually. I am specifically interested in doing this for several files at once. Answers here only help for the single file case.

How do I do it?

marked as duplicate by DoYouEvenCodeBro, peterh says reinstate Monica, Herb Wolfe, jamessan, Alex Kroll Jul 4 at 2:13

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 2
    Just in case you didn't know: This is not the way to do this. You can checkout specific files from another branch or commit to the current branch. – muru Jul 2 at 7:03
  • Not a duplicate. I'm asking about the many-files case. – Jacob Kopczynski Jul 20 at 1:46
  • What prevents you from using the answer in the dupe in a loop over all buffers? – muru Aug 7 at 15:46
  • 1
    Loop over all windows in all tabs and you have all visible buffers. – muru Aug 11 at 7:10
4

This answer is a two-parter:

  1. "Tricking" vim into not caring about the fact that files have changed
  2. Using git properly to avoid this in the first place

Vim

Reading :help :wall tells us that

Vim will warn you if you try to overwrite a file that has been changed
elsewhere.  See |timestamp|.

:help timestamp gives

If you do not want to be asked or automatically reload the file, you can use
this: 
        set buftype=nofile

Now, the problem with buftype=nofile is that the file

will not be written (:help 'buftype')

So, the linked QA provides one answer (save and restore). My solution would be to set all buffers to nofile and then use :w filename (which should still work, according to the docs):

argdo set buftype=nofile | execute 'write' bufname('%')

except that, for some reason, the docs don't seem to be correct: the above command errors for each argument, even though :write filename is supposed to work. :write othername works, but you cannot write to the buffer name.

So I would use the linked answer.

Git

I'm not sure how on-topic this part is, but it's an answer to the question, if a bit of a frame challenge.

You want to get (some of) the files in one branch (to_update) to have identical contents to the corresponding files on another branch (stable).

  1. Checkout the to_update branch
  2. Choose a strategy:
    • Merge the branches: git merge stable. You don't have control over which files change, and they won't be identical post-merge, but you do get the contents from the stable branch (integrated with to_update).
    • Checkout the files on another branch: git checkout stable [files...]. This makes files exactly as they are in stable, and lets you pick which files. No vim reloading necessary.

Caveat: if you have already edited the files, then you switch branches, you have a different problem. You wouldn't be allowed to switch branches if there were conflicts, so the vim method should work fine. If there were conflicts, do git stash, the use the second strategy for git, the git stash apply (followed by git stash drop if you're satisfied).

If you wish to edit the files that changed, you can do some parsing to get a list of changed files. I do this with my git-ed script.

  • I virtually always want this in the situation you mention under "Caveat", in which case git can only do it as an awkward kludge. – Jacob Kopczynski Aug 1 at 20:46

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