DEV Community

Heiker
Heiker

Posted on

Lazy.nvim: how to revert a plugin back to a previous version

If you've been using Neovim for a while maybe you noticed that plugins receive updates all the time. This isn't always good news, a change can introduce a bug in your config, or maybe it changed the current api. It can be annoying, I know. But today we are going to learn how lazy.nvim can help us recover from bad situations, so we can always have Neovim in a good state.

I'm going to tell you how to rollback a plugin update using lazy.nvim's interface. And also, in case something goes horribly wrong, how you can rollback every plugin installed back to a known previous state.

Revert a plugin

If you know what plugin broke your Neovim config you can execute the command.

:Lazy log some-plugin
Enter fullscreen mode Exit fullscreen mode

Where some-plugin is the name of your plugin. This command will open lazy.nvim's interface and it will show the previous commits.

If I execute the command :Lazy log nvim-lspconfig, this is what I get.

● nvim-lspconfig 371.28ms ⌘ Lsp
  b609127 feat(omnisharp): find root directory for .csx scripts (#2715) (hace 4 días)
  654dd9e fix(rust_analyzer): check active clients is empty (#2734) (hace 5 días)
  6f426c3 docs: update server_configurations.md skip-checks: true (hace 6 días)
  01b25ff docs: make vimdocs consistent with readme (#2732) (hace 6 días)
  dd11ba7 fix(pyright): re-enable single-file mode (#2730) (hace 10 días)
  6c53bf7 fix(pyright): fix root_dir detection (#2727) (hace 10 días)
  443c56a docs: update server_configurations.md skip-checks: true (hace 11 días)
  e7be6d4 feat(v): add `v-analyzer` (#2726) (hace 11 días)
Enter fullscreen mode Exit fullscreen mode

Notice that before each commit message we have the commit hash.

To revert the plugin to any of those commits all I have to do is place the cursor above the commit hash and press r.

The lockfile

If there is no way of knowing which plugin is causing the error then you could use this command

:Lazy restore
Enter fullscreen mode Exit fullscreen mode

With this you will be able to revert all the plugins to the state reflected in the lockfile.

If you don't know, the lockfile is a JSON file that contains the current commit hash of all your plugins. This is located in the same folder as your init.lua or init.vim config. The lockfile is actually called lazy-lock.json.

There is one problem: the lockfile updates with your plugins. If you don't backup your lockfile before an update there is no way to revert to the previous working state.

What to do?

Here are few ideas:

  • Make a copy

Easiest thing will be to create a copy of the lockfile and just keep it around. You would navigate to your Neovim config folder and copy the file lazy-lock.json.

cp lazy-lock.json lazy-lock.backup.json
Enter fullscreen mode Exit fullscreen mode

There you go. lazy-lock.backup.json can have the last working state of all your plugins. When something goes wrong you simply change the name of the backup file to lazy-lock.json. Then in Neovim you can execute the command :Lazy restore.

  • Use git

You would want to add the lockfile to git. Have a commit with a stable version of the lockfile. If something goes wrong you can revert the lockfile using the git cli. And then use :Lazy restore inside Neovim.

If you don't know how to revert to a commit with the git cli, try to use the website of your repo (github/gitlab/whatever). Go to the lockfile and copy it to your system.

  • Automatic backups

What I do is use lua to make a backup of the lockfile. I use the autocommand User LazyUpdatePre, this is executed before lazy.nvim updates the plugins. Here I have a function that creates a copy of the lockfile with a time and date as the name.

Here is the code.

local lazy_cmds = vim.api.nvim_create_augroup('lazy_cmds', {clear = true})
local snapshot_dir = vim.fn.stdpath('data') .. '/plugin-snapshot'
local lockfile = vim.fn.stdpath('config') .. '/lazy-lock.json'

vim.api.nvim_create_user_command(
  'BrowseSnapshots',
  'edit ' .. snapshot_dir,
  {}
)

vim.api.nvim_create_autocmd('User', {
  group = lazy_cmds,
  pattern = 'LazyUpdatePre',
  desc = 'Backup lazy.nvim lockfile',
  callback = function(event)
    vim.fn.mkdir(snapshot_dir, 'p')
    local snapshot = snapshot_dir .. os.date('/%Y-%m-%dT%H:%M:%S.json')

    vim.loop.fs_copyfile(lockfile, snapshot)
  end,
})
Enter fullscreen mode Exit fullscreen mode

If something goes wrong I use the command :BrowseSnapshots to search for the latest lockfile. I usually just grab the commit of the plugin that broke my config, then copy it to the current lockfile. After that, I use the restore command with the name of the plugin.

:Lazy restore some-plugin
Enter fullscreen mode Exit fullscreen mode

If something went really really bad, I would just copy the whole backup and replace the current lockfile.

Conclusion

Is important to be prepared in case a plugin makes our editor unusable. Fortunaly lazy.nvim gives us convenient tools to recover from a bad state. We can use the interface to revert a plugin to a recent version, or we can use the lockfile to revert everything to a previous working state. So there is always a way to have Neovim with a working config.


Thank you for your time. If you find this article useful and want to support my efforts, consider leaving a tip in buy me a coffee ☕.

buy me a coffee

Top comments (0)