今天在使用 package-vc-upgrade
更新一个包时,意外出现了 File is not under version control
的报错,但是这个包是使用 package-vc-install
直接从 github 链接安装的,而且之前调用这个函数也没有出现过问题。当我在 list-packages
得到的 buffer 中调用该命令时能够正常拉取,但是在 current-buffer
为我的 init.el
时调用该命令会报错。
用 edebug 调试了一下,发现虽然 package-vc-install
在调用 vc-pull
时将 default-directory
设置为了包所在的目录,但是 vc-pull
内部使用的 vc-deduce-fileset
会通过 with-current-buffer
设置当前 buffer 为当前 buffer (草):
;;vc.el line 1125
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(setq res
(vc-deduce-fileset-1 not-state-changing
allow-unregistered
state-model-only-files))
(setq new-buf (current-buffer)))
...)
然后问题就出在了这个 vc-deduce-fileset-1
上,它在获取版本管理后端时使用 buffer-file-name
作为判断依据先于 default-directory
,因此我们调用 package-vc-upgrade
时所在的 buffer 将会提供这个 buffer-file-name
,从而导致可能的版本管理后端获取失败。
好玩的是如果我们所在的当前 buffer 是某个 git 仓库下的文件,那么 package-vc-upgrade
也能够正常工作,因为能够从当前文件获取到 Git 后端。这也大概是我之前没有碰到这个问题的原因,之前我在使用 git 管理配置文件,每次执行 package-vc-upgrade
都是在配置文件作为 current-buffer
时。
以下是一个复现过程:
- 在 Emacs 中随意打开一个文件,该文件没有位于任何的版本管理中
- 调用
package-vc-install
随便安装一个包,比如(package-vc-install "https://github.com/SqrtMinusOne/micromamba.el")
- 在先前打开的文件 buffer 作为当前 buffer 的情况下,调用
package-vc-upgrade
命令,并选择安装的包:micromamba
- 观察是否出现错误
要解决这个问题,比较简单的办法是加一个 around advice,使用 temp buffer 作为当前 buffer:
(defun yy/package-vc-upgrade-advice (upfun pkg-desc)
(with-temp-buffer
(funcall upfun pkg-desc)))
(advice-add 'package-vc-upgrade :around 'yy/package-vc-upgrade-advice)
如果你能够复现这个问题,可以回个帖告诉我,我会考虑提个 issue 给 bug-gnu-emacs。
顺带,使用的 Emacs 是 “GNU Emacs 29.2 (build 2, x86_64-w64-mingw32) of 2024-01-19”