vim plugged snapshot ==================== A few of my friends and I all just borked our neovim configs during a plug update, and because none of us were using it was painful to recover from. Date: May 13, 2022 A few of my friends and I all just borked our neovim configs during a plug update, and because none of us were using `:PlugSnapshot` it was painful to recover from. https://twitter.com/pypeaday/status/1524882893914398732 > Lucky for me I did it on a home machine that I only occasionally edit from, > so I could still take the snapshot from a working machine before taking the > plunge into fixing everying. ## Why snapshot Snapshotting ensures that you install the same git sha on every single plugin. This way when you have multiple machines running your same vim config, they are all on the same sha of each plugin, and you dont end up with weird things happening on one machine. And then you get to decide when you are ready to update, rather than when it breaks. * same config everywhere * you control the update * in case of a borked update you have a good working place to rever to ## Let's snapshot Running `:PlugSnapshot` will generate the following content in a buffer that you can save. I chose to save mine in `~/.config/nvim/snapshot.vim`. ``` vim " Generated by vim-plug " Fri 13 May 2022 08:01:39 PM CDT " :source this file in vim to restore the snapshot " or execute: vim -S snapshot.vim silent! let g:plugs['Telegraph.nvim'].commit = '92e472f4e83acd60eb3766168e66d02718bfefe0' silent! let g:plugs['black'].commit = '8ed3e3d07ea3e6d62e3e533e69f96a0ff148cd5d' silent! let g:plugs['bufutils.vim'].commit = '4634feb1312fd73fab66cfaa860e7af3abde935b' silent! let g:plugs['cmp-buffer'].commit = 'd66c4c2d376e5be99db68d2362cd94d250987525' silent! let g:plugs['cmp-calc'].commit = '970fd5f97b4bd363260365b217f694dd6a1182cb' silent! let g:plugs['cmp-nvim-lsp'].commit = 'ebdfc204afb87f15ce3d3d3f5df0b8181443b5ba' silent! let g:plugs['cmp-path'].commit = '466b6b8270f7ba89abd59f402c73f63c7331ff6e' silent! let g:plugs['cmp-rg'].commit = 'fd92d70ff36b30924401b0cf7d4ce7344c8235f7' silent! let g:plugs['cmp-vsnip'].commit = '0abfa1860f5e095a07c477da940cfcb0d273b700' silent! let g:plugs['colorbuddy.nvim'].commit = 'cdb5b0654d3cafe61d2a845e15b2b4b0e78e752a' silent! let g:plugs['compe-tmux'].commit = '3c16f7e73abee43b3ea3e919e8b34c24427d9530' silent! let g:plugs['coverage-highlight.vim'].commit = '864e03679ea4168661501246147893cc82020917' silent! let g:plugs['diffurcate.vim'].commit = 'b804675072220ff7c7ebcd24a028aa4aa35f09cc' silent! let g:plugs['friendly-snippets'].commit = '5fd8b920a3497dec9a3ef939595186b362d041b4' silent! let g:plugs['fzf'].commit = 'a91a67668e0830a8cf9a792c4949e03b4189f097' silent! let g:plugs['fzf.vim'].commit = 'd5f1f8641b24c0fd5b10a299824362a2a1b20ae0' silent! let g:plugs['gitsigns.nvim'].commit = 'ead0d48df801431b990d6b91fa210f7efa30ac38' silent! let g:plugs['gruvbox-flat.nvim'].commit = '756dbdd3dfd3ed84acb2f9649724df19ae41f904' silent! let g:plugs['harpoon'].commit = '28762aa04d6395538e26e1efff5213b26720e68f' silent! let g:plugs['impatient.nvim'].commit = '2337df7d778e17a58d8709f651653b9039946d8d' silent! let g:plugs['instant.nvim'].commit = 'c02d72267b12130609b7ad39b76cf7f4a3bc9554' silent! let g:plugs['lsp_extensions.nvim'].commit = '4011f4aec61ba59c734f5dbf52e91f258b99d985' silent! let g:plugs['lsp_signature.nvim'].commit = 'a351509512687293fd659ba4ee7e34412c3a8f70' silent! let g:plugs['lspsaga.nvim'].commit = 'cb0e35d2e594ff7a9c408d2e382945d56336c040' silent! let g:plugs['lualine.nvim'].commit = '18a07f790ed7ed1f11d1b130c02782e9dfd8dd7d' silent! let g:plugs['nvim-cmp'].commit = '433af3dffce64cbd3f99bdac9734768a6cc41951' silent! let g:plugs['nvim-compe'].commit = 'd186d739c54823e0b010feb205c6f97792322c08' silent! let g:plugs['nvim-dap'].commit = 'd6d8317ce9e096029150bc5844916347a9af6f45' silent! let g:plugs['nvim-dap-python'].commit = '4c7ea25f8ff6de6fa00bf5625d2e76753cced70f' silent! let g:plugs['nvim-lspconfig'].commit = 'ad9903c66bac88f344890acb6532f63f1cd4dac3' silent! let g:plugs['nvim-lspinstall'].commit = '79ec2425d6b39cdcb69d379f3e56847f49be73eb' silent! let g:plugs['nvim-lsputils'].commit = 'ae1a4a62449863ad82c70713d5b6108f3a07917c' silent! let g:plugs['nvim-spectre'].commit = '345e5dd57773e2b4b425a2515c831108b9808a0f' silent! let g:plugs['nvim-tree.lua'].commit = 'ce463a53ae269544697c3dedd3d5beae05937405' silent! let g:plugs['nvim-treesitter'].commit = '3c50297eca950b4b1a7c07b28e586b0576c0a796' silent! let g:plugs['nvim-web-devicons'].commit = '4febe73506268a02ff15a240abcd7bf3eb9234da' silent! let g:plugs['onebuddy'].commit = '7e16006e7dde15e3cb72889f736c49409db6ff42' silent! let g:plugs['onedark.nvim'].commit = 'e520a0c81a5a1997ecffd846ccd9c6e63b7859c6' silent! let g:plugs['playground'].commit = '13e2d2d63ce7bc5d875e8bdf89cb070bc8cc7a00' silent! let g:plugs['plenary.nvim'].commit = '9069d14a120cadb4f6825f76821533f2babcab92' silent! let g:plugs['popfix'].commit = 'ea262861ce3905b90c2c203b74a7be2539f1aba4' silent! let g:plugs['popup.nvim'].commit = 'b7404d35d5d3548a82149238289fa71f7f6de4ac' silent! let g:plugs['refactoring.nvim'].commit = '94eaa199ad892f26d2c8594dbbc5656314cf5bdb' silent! let g:plugs['stylua-nvim'].commit = '8bd7fa127367178dddb9ee06fdce1d7c622d2feb' silent! let g:plugs['targets.vim'].commit = '8d6ff2984cdfaebe5b7a6eee8f226a6dd1226f2d' silent! let g:plugs['telescope-dap.nvim'].commit = 'b4134fff5cbaf3b876e6011212ed60646e56f060' silent! let g:plugs['telescope.nvim'].commit = '8b02088743c07c2f82aec2772fbd2b3774195448' silent! let g:plugs['termopen.vim'].commit = '3194a991a18a9be2fd9fcf8c4c55fe990c04b2bd' silent! let g:plugs['undotree'].commit = '08e259be24d4476c1ee745dc735eefd44f90efdc' silent! let g:plugs['vim-be-good'].commit = 'bc499a06c14c729b22a6cc7e730a9fbc44d4e737' silent! let g:plugs['vim-commentary'].commit = '3654775824337f466109f00eaf6759760f65be34' silent! let g:plugs['vim-dispatch'].commit = '00e77d90452e3c710014b26dc61ea919bc895e92' silent! let g:plugs['vim-doge'].commit = '88d8dfacc3a5f3dfce82ef5221e5e6943e627d85' silent! let g:plugs['vim-floaterm'].commit = '6244d1739aad6682c6c1d5db18c846c342af6e3e' silent! let g:plugs['vim-fugitive'].commit = 'b5bbd0d181ebc3cea5c42bdaed13141850432ba1' silent! let g:plugs['vim-indent-object'].commit = '5c5b24c959478929b54a9e831a8e2e651a465965' silent! let g:plugs['vim-ipython-cell'].commit = 'f0548d9a8d5e31d5c7f73e8729b55e8eb402852f' silent! let g:plugs['vim-log-highlighting'].commit = '1037e26f3120e6a6a2c0c33b14a84336dee2a78f' silent! let g:plugs['vim-quicklink'].commit = '021167741588555501594e1fc31f130b16acefa0' silent! let g:plugs['vim-repeat'].commit = '24afe922e6a05891756ecf331f39a1f6743d3d5a' silent! let g:plugs['vim-signify'].commit = '69498f6d49f3eeac06870012416dd9bf867b84f3' silent! let g:plugs['vim-slime'].commit = '0ea9b35882155996171fd15a5227e673ce2d2c60' silent! let g:plugs['vim-sneak'].commit = '94c2de47ab301d476a2baec9ffda07367046bec9' silent! let g:plugs['vim-surround'].commit = '81fc0ec460dd8b25a76346e09aecdbca2677f1a7' silent! let g:plugs['vim-test'].commit = '2240d7a4b868cb594b7d83544e1b6db4df806e5e' silent! let g:plugs['vim-tmux-runner'].commit = '54767911fd5e6e2d8e493847149e315ac2e6531a' silent! let g:plugs['vim-ultest'].commit = 'a99eb0bdf7d901d538b5dd724e2ab3a958c1799c' silent! let g:plugs['vim-visualstar'].commit = 'a18cd0e7a03311ac709595c1d261ed44b45c9098' silent! let g:plugs['vim-vsnip'].commit = '8f199ef690ed26dcbb8973d9a6760d1332449ac9' PlugUpdate! ``` > NOTE! the `PlugUpdate!` at the end. I did not catch this at first, if you > are like me and automatically source `*.vim` files on save, this will > immediately run the update when you save it. If you just took the snapshot > though I don't think it will actually do anything. ## Let's Update Now without the snapshot sourced, I will not have any of my plugins pinned. When I run `:PlugUpdate` it will update all of my plugins to the latest versions. Then I can `:PlugSnapshot` again, and this will kick out an updated list of sha's. I will yank this file `yyG` and paste it into my snapshot.vim file `vGp`. ## Look at these updates We can see these updates with a little `:G diff %` on the file. ```diff diff --git a/nvim/.config/nvim/snapshot.vim b/nvim/.config/nvim/snapshot.vim index 88db2b0..837c8e4 100644 --- a/nvim/.config/nvim/snapshot.vim +++ b/nvim/.config/nvim/snapshot.vim @@ -1,14 +1,14 @@ " Generated by vim-plug -" Fri 13 May 2022 08:01:39 PM CDT +" Fri 13 May 2022 08:22:17 PM CDT " :source this file in vim to restore the snapshot " or execute: vim -S snapshot.vim silent! let g:plugs['Telegraph.nvim'].commit = '92e472f4e83acd60eb3766168e66d02718bfefe0' -silent! let g:plugs['black'].commit = '8ed3e3d07ea3e6d62e3e533e69f96a0ff148cd5d' +silent! let g:plugs['black'].commit = '7f033136ac5e0e5bf6cf322dd60b4a92050eedc4' silent! let g:plugs['bufutils.vim'].commit = '4634feb1312fd73fab66cfaa860e7af3abde935b' -silent! let g:plugs['cmp-buffer'].commit = 'd66c4c2d376e5be99db68d2362cd94d250987525' -silent! let g:plugs['cmp-calc'].commit = '970fd5f97b4bd363260365b217f694dd6a1182cb' -silent! let g:plugs['cmp-nvim-lsp'].commit = 'ebdfc204afb87f15ce3d3d3f5df0b8181443b5ba' +silent! let g:plugs['cmp-buffer'].commit = '12463cfcd9b14052f9effccbf1d84caa7a2d57f0' +silent! let g:plugs['cmp-calc'].commit = 'f7efc20768603bd9f9ae0ed073b1c129f63eb312' +silent! let g:plugs['cmp-nvim-lsp'].commit = 'e6b5feb2e6560b61f31c756fb9231a0d7b10c73d' silent! let g:plugs['cmp-path'].commit = '466b6b8270f7ba89abd59f402c73f63c7331ff6e' silent! let g:plugs['cmp-rg'].commit = 'fd92d70ff36b30924401b0cf7d4ce7344c8235f7' silent! let g:plugs['cmp-vsnip'].commit = '0abfa1860f5e095a07c477da940cfcb0d273b700' @@ -16,60 +16,60 @@ silent! let g:plugs['colorbuddy.nvim'].commit = 'cdb5b0654d3cafe61d2a845e15b2b4b silent! let g:plugs['compe-tmux'].commit = '3c16f7e73abee43b3ea3e919e8b34c24427d9530' silent! let g:plugs['coverage-highlight.vim'].commit = '864e03679ea4168661501246147893cc82020917' silent! let g:plugs['diffurcate.vim'].commit = 'b804675072220ff7c7ebcd24a028aa4aa35f09cc' -silent! let g:plugs['friendly-snippets'].commit = '5fd8b920a3497dec9a3ef939595186b362d041b4' -silent! let g:plugs['fzf'].commit = 'a91a67668e0830a8cf9a792c4949e03b4189f097' +silent! let g:plugs['friendly-snippets'].commit = '627dea2ff1ee8d8a7e6ad365acb3e335c8b25574' +silent! let g:plugs['fzf'].commit = '6dcf5c3d7d6c321b17e6a5673f1533d6e8350462' silent! let g:plugs['fzf.vim'].commit = 'd5f1f8641b24c0fd5b10a299824362a2a1b20ae0' -silent! let g:plugs['gitsigns.nvim'].commit = 'ead0d48df801431b990d6b91fa210f7efa30ac38' +silent! let g:plugs['gitsigns.nvim'].commit = 'ffd06e36f6067935d8cb9793905dd2e84e291310' silent! let g:plugs['gruvbox-flat.nvim'].commit = '756dbdd3dfd3ed84acb2f9649724df19ae41f904' -silent! let g:plugs['harpoon'].commit = '28762aa04d6395538e26e1efff5213b26720e68f' +silent! let g:plugs['harpoon'].commit = 'd3d3d22b6207f46f8ca64946f4d781e975aec0fc' silent! let g:plugs['impatient.nvim'].commit = '2337df7d778e17a58d8709f651653b9039946d8d' silent! let g:plugs['instant.nvim'].commit = 'c02d72267b12130609b7ad39b76cf7f4a3bc9554' silent! let g:plugs['lsp_extensions.nvim'].commit = '4011f4aec61ba59c734f5dbf52e91f258b99d985' -silent! let g:plugs['lsp_signature.nvim'].commit = 'a351509512687293fd659ba4ee7e34412c3a8f70' +silent! let g:plugs['lsp_signature.nvim'].commit = 'db324e2ada5bb795d0016ec0ef2b4ae7f11d8904' silent! let g:plugs['lspsaga.nvim'].commit = 'cb0e35d2e594ff7a9c408d2e382945d56336c040' -silent! let g:plugs['lualine.nvim'].commit = '18a07f790ed7ed1f11d1b130c02782e9dfd8dd7d' -silent! let g:plugs['nvim-cmp'].commit = '433af3dffce64cbd3f99bdac9734768a6cc41951' +silent! let g:plugs['lualine.nvim'].commit = 'a4e4517ac32441dd92ba869944741f0b5f468531' +silent! let g:plugs['nvim-cmp'].commit = '9a0c639ac2324e6e9ecc54dc22b1d32bb6c42ab9' silent! let g:plugs['nvim-compe'].commit = 'd186d739c54823e0b010feb205c6f97792322c08' -silent! let g:plugs['nvim-dap'].commit = 'd6d8317ce9e096029150bc5844916347a9af6f45' -silent! let g:plugs['nvim-dap-python'].commit = '4c7ea25f8ff6de6fa00bf5625d2e76753cced70f' -silent! let g:plugs['nvim-lspconfig'].commit = 'ad9903c66bac88f344890acb6532f63f1cd4dac3' +silent! let g:plugs['nvim-dap'].commit = '2249fcfd09cdc27c08e9d2f3be5268ba81db3378' +silent! let g:plugs['nvim-dap-python'].commit = 'd96bcbf3803283456c900cf25ab0995e8d2f00c0' +silent! let g:plugs['nvim-lspconfig'].commit = '9ff2a06cebd4c8c3af5259d713959ab310125bec' silent! let g:plugs['nvim-lspinstall'].commit = '79ec2425d6b39cdcb69d379f3e56847f49be73eb' silent! let g:plugs['nvim-lsputils'].commit = 'ae1a4a62449863ad82c70713d5b6108f3a07917c' silent! let g:plugs['nvim-spectre'].commit = '345e5dd57773e2b4b425a2515c831108b9808a0f' -silent! let g:plugs['nvim-tree.lua'].commit = 'ce463a53ae269544697c3dedd3d5beae05937405' -silent! let g:plugs['nvim-treesitter'].commit = '3c50297eca950b4b1a7c07b28e586b0576c0a796' -silent! let g:plugs['nvim-web-devicons'].commit = '4febe73506268a02ff15a240abcd7bf3eb9234da' +silent! let g:plugs['nvim-tree.lua'].commit = '82ec79aac5557c05728d88195fb0d008cacbf565' +silent! let g:plugs['nvim-treesitter'].commit = 'f1373051e554cc4642cda719c8023e4e8508eb2d' +silent! let g:plugs['nvim-web-devicons'].commit = 'bdd43421437f2ef037e0dafeaaaa62b31d35ef2f' silent! let g:plugs['onebuddy'].commit = '7e16006e7dde15e3cb72889f736c49409db6ff42' -silent! let g:plugs['onedark.nvim'].commit = 'e520a0c81a5a1997ecffd846ccd9c6e63b7859c6' -silent! let g:plugs['playground'].commit = '13e2d2d63ce7bc5d875e8bdf89cb070bc8cc7a00' -silent! let g:plugs['plenary.nvim'].commit = '9069d14a120cadb4f6825f76821533f2babcab92' +silent! let g:plugs['onedark.nvim'].commit = '08cde8acf181b3278dafb9c8284726104a11cc0f' +silent! let g:plugs['playground'].commit = '71b00a3c665298e5155ad64a9020135808d4e3e8' +silent! let g:plugs['plenary.nvim'].commit = '0a907364b5cd6e3438e230df7add8b9bb5ef6fd3' silent! let g:plugs['popfix'].commit = 'ea262861ce3905b90c2c203b74a7be2539f1aba4' silent! let g:plugs['popup.nvim'].commit = 'b7404d35d5d3548a82149238289fa71f7f6de4ac' -silent! let g:plugs['refactoring.nvim'].commit = '94eaa199ad892f26d2c8594dbbc5656314cf5bdb' -silent! let g:plugs['stylua-nvim'].commit = '8bd7fa127367178dddb9ee06fdce1d7c622d2feb' +silent! let g:plugs['refactoring.nvim'].commit = '33ac6f3bcfe97447037ded20291d40de34d8912c' +silent! let g:plugs['stylua-nvim'].commit = 'ce59a353f02938cba3e0285e662fcd3901cd270f' silent! let g:plugs['targets.vim'].commit = '8d6ff2984cdfaebe5b7a6eee8f226a6dd1226f2d' silent! let g:plugs['telescope-dap.nvim'].commit = 'b4134fff5cbaf3b876e6011212ed60646e56f060' -silent! let g:plugs['telescope.nvim'].commit = '8b02088743c07c2f82aec2772fbd2b3774195448' +silent! let g:plugs['telescope.nvim'].commit = '39b12d84e86f5054e2ed98829b367598ae53ab41' silent! let g:plugs['termopen.vim'].commit = '3194a991a18a9be2fd9fcf8c4c55fe990c04b2bd' silent! let g:plugs['undotree'].commit = '08e259be24d4476c1ee745dc735eefd44f90efdc' silent! let g:plugs['vim-be-good'].commit = 'bc499a06c14c729b22a6cc7e730a9fbc44d4e737' silent! let g:plugs['vim-commentary'].commit = '3654775824337f466109f00eaf6759760f65be34' silent! let g:plugs['vim-dispatch'].commit = '00e77d90452e3c710014b26dc61ea919bc895e92' -silent! let g:plugs['vim-doge'].commit = '88d8dfacc3a5f3dfce82ef5221e5e6943e627d85' -silent! let g:plugs['vim-floaterm'].commit = '6244d1739aad6682c6c1d5db18c846c342af6e3e' -silent! let g:plugs['vim-fugitive'].commit = 'b5bbd0d181ebc3cea5c42bdaed13141850432ba1' +silent! let g:plugs['vim-doge'].commit = 'd5b08d01f64396557d9912b3830717d45671764b' +silent! let g:plugs['vim-floaterm'].commit = 'ab7876f86c05c1935eb23a193f4f276132902ac1' +silent! let g:plugs['vim-fugitive'].commit = 'a8139d37b242c5bc5ceeddc4fcd7dddf2b2c2650' silent! let g:plugs['vim-indent-object'].commit = '5c5b24c959478929b54a9e831a8e2e651a465965' silent! let g:plugs['vim-ipython-cell'].commit = 'f0548d9a8d5e31d5c7f73e8729b55e8eb402852f' silent! let g:plugs['vim-log-highlighting'].commit = '1037e26f3120e6a6a2c0c33b14a84336dee2a78f' silent! let g:plugs['vim-quicklink'].commit = '021167741588555501594e1fc31f130b16acefa0' silent! let g:plugs['vim-repeat'].commit = '24afe922e6a05891756ecf331f39a1f6743d3d5a' silent! let g:plugs['vim-signify'].commit = '69498f6d49f3eeac06870012416dd9bf867b84f3' -silent! let g:plugs['vim-slime'].commit = '0ea9b35882155996171fd15a5227e673ce2d2c60' +silent! let g:plugs['vim-slime'].commit = '6e4b81303968f37346925d6907b96ef07788cc82' silent! let g:plugs['vim-sneak'].commit = '94c2de47ab301d476a2baec9ffda07367046bec9' -silent! let g:plugs['vim-surround'].commit = '81fc0ec460dd8b25a76346e09aecdbca2677f1a7' +silent! let g:plugs['vim-surround'].commit = 'bf3480dc9ae7bea34c78fbba4c65b4548b5b1fea' silent! let g:plugs['vim-test'].commit = '2240d7a4b868cb594b7d83544e1b6db4df806e5e' silent! let g:plugs['vim-tmux-runner'].commit = '54767911fd5e6e2d8e493847149e315ac2e6531a' -silent! let g:plugs['vim-ultest'].commit = 'a99eb0bdf7d901d538b5dd724e2ab3a958c1799c' +silent! let g:plugs['vim-ultest'].commit = '6978fd32e3ca2c1c5591884eea0d57a7ee43d212' silent! let g:plugs['vim-visualstar'].commit = 'a18cd0e7a03311ac709595c1d261ed44b45c9098' silent! let g:plugs['vim-vsnip'].commit = '8f199ef690ed26dcbb8973d9a6760d1332449ac9' ``` ## Commits Now I can look through all the versions of my `snapshot.vim` by opening it, running `:0Gclog` and navigating the quickfix list with `:cnext` and `:cprev`. If I want to install one of the old versions while its open in a buffer, all I need to do is run `:source %`. ## Log Now the log of my `snapshots.vim` looks like this. I saved the working version, and successfully updated to the latest versions of all plugins, with a save point I can revert back to. ``` log commit 20e901196b0d9633a42176f1fe1757e45f709fd3 Author: Waylon S. Walker Date: Fri May 13 20:37:03 2022 -0500 plugupdate commit f9d76368697b4c4427c0fa8ccd5e2449b6e5a9ff Author: Waylon S. Walker Date: Fri May 13 20:16:11 2022 -0500 commit my plugin snapshot ```