lazy.nvimでvimdoc-jaが更新できない:doc/tags-jaのlocal changes

Fix lazy.nvim local changes on vimdoc-ja by discarding doc/tags-ja

* 本ページはプロモーションが含まれています

Neovim の設定は init.vimからinit.luaへ移行 したときに、プラグイン管理を lazy.nvim へ寄せた。
そのうえで、:help を日本語で読むために vimdoc-jalazy.nvim のプラグインとして入れている。

Neovim を起動すると、時折 lazy.nvim が vimdoc-ja の更新に失敗することがあった。 エラーは「local changes」で、対象は doc/tags-ja だけだった。


症状

起動時に出てきたメッセージは次のとおり。

Failed (1)
  ● vimdoc-ja  0.46ms  start
      You have local changes in `~/.local/share/nvim/lazy/vimdoc-ja`:
        * doc/tags-ja
      Please remove them to update.
      You can also press `x` to remove the plugin and then `I` to install it again.

プラグイン本体ではなく、ヘルプタグの生成物だけが「ローカル変更」扱いになっている。
lazy.nvim は git の作業ツリーが汚れていると判断すると、更新を拒否する。


原因は tags-ja を git 管理していること

vimdoc-ja は、生成済みの doc/tags-ja(helptags ファイル)をリポジトリにコミットしている。
一方 lazy.nvim は、プラグインのインストールや更新のたびに :helptags を実行して、doc/tags-ja をローカルで再生成する。

この再生成結果がリポジトリのコミット内容と 1 バイトでもズレると、lazy.nvim は「git リポジトリにローカル変更がある」と判断して更新を止める。

開発元(folke 氏)は、「lazy.nvim 側でこの種の例外処理を入れる予定はない」と明言している。
根本は、vimdoc-ja が生成物を git 管理下に置いている構造の問題だ。

過去には、helptags 生成に使う Vim のバージョン差も一因だった。
Vim 9.0.0110 で、ヘルプ内コード例中の疑似タグの扱いが変わったため、生成結果がズレやすかった。
vimdoc-ja-working#1434 (2024-02-07 マージ)で生成用 Vim を 9.1.0065 に更新してから、発生頻度は下がっている。
それでも :helptags を毎回走らせる限り、ズレ自体は再発しうる。

経緯は vim-jp/vimdoc-ja#279 にまとまっている。


その場しのぎ:今出ているエラーを消す

更新を通したいだけなら、対象ファイルの差分を捨てればよい。

cd ~/.local/share/nvim/lazy/vimdoc-ja
git checkout -- doc/tags-ja

:Lazy の画面で x(削除)→ I(再インストール)でも同じ状態に戻せる。
ただし、次に :helptags が走って doc/tags-ja がまたズレれば、同じエラーが再発する。


恒久対策:更新前に tags-ja を捨てる

毎回手で checkout するのは面倒なので、lazy.nvim が更新を始める直前に差分を捨てることにした。
~/dotfiles/nvim/lua/plugins.luarequire('lazy').setup(...) 呼び出し直前に、LazyUpdatePre イベントの autocmd を足した。

-- vimdoc-ja は doc/tags-ja を生成物ごと git 管理しており、:helptags による
-- ローカル再生成でズレると lazy.nvim が「local changes」で更新を拒否する
-- (https://github.com/vim-jp/vimdoc-ja/issues/279)。更新前に破棄しておく。
vim.api.nvim_create_autocmd('User', {
  pattern = 'LazyUpdatePre',
  group = vim.api.nvim_create_augroup('lazy_vimdoc_ja_fix', { clear = true }),
  callback = function()
    local dir = vim.fn.stdpath('data') .. '/lazy/vimdoc-ja'
    if vim.fn.isdirectory(dir) == 1 then
      vim.system({ 'git', 'checkout', '--', 'doc/tags-ja' }, { cwd = dir }):wait()
    end
  end,
})

stdpath('data') 経由なので、プラグインの実体パスをハードコードしなくて済む。
コミュニティで実際に使われている回避策(mimikun/dotfiles )を参考に、自分の設定へ簡略化して入れた。


まとめ

やり方内容再発
git checkout -- doc/tags-ja今出ている差分を捨てるする
:LazyxIプラグインごと入れ直すする
LazyUpdatePre で checkout更新前に自動で捨てるしない

原因は lazy.nvim のバグではなく、vimdoc-ja が doc/tags-ja を生成物ごと git 管理していることと、lazy.nvim が毎回 :helptags を走らせることの組み合わせだった。
同じエラーで更新が止まっている人の参考になれば幸いだ。

カテゴリー: editor 
Tags: neovim lua vimdoc-ja Vim 

関連項目