Magit 的行追踪功能不可用

我现在遇到的问题是使用 Magit 的行追踪功能不可用,对应到 Git 的命令行是 git log -L 这个,但实际上我这里得到的结果总是 (empty),有人清楚这是什么原因吗?

额外信息

  • 在我自己的 Mac 上和公司配发的 Mac 上都是一样的问题,公司 Mac 从我自己电脑上全盘 Clone 过去的
  • 在命令行下使用是完全没问题的,可以正常展示结果

提供一个我操作的案例

  • Git 地址: GitHub - Lenic/test-tailwindcss
  • Git 命令行的指令:git log -L 2,5:src/App.vue,可以正常看到关于这几行的 Diff 信息
  • 在 Magit 中执行 M-x magit-log RET -L RET 2,5 RET l 看到的结果是 (empty)

Magit 操作结果如图

总结

希望大神能帮帮忙,为了不脱离 Emacs 环境,我特意按照这里的说明装上了 git-timemachine,虽然很好用但不能解决我行追踪的问题

我克隆了你的仓库,用最小配置 (emacsq.sh) 试了一下,没问题。

步骤:

$ git clone https://github.com/Lenic/test-tailwindcss && cd test-tailwindcss
$ emacsq.sh -P magit -nw src/App.vue
M-x magit-log RET -L RET 2,5 RET l
1 个赞

我这边也是好的,大概率是 magit 版本问题, 建议把 magit 用 commit 固定下来(submodule 或其他方式)。

b68a760c9e7694c687adedec7dffab0a5609ea93 我目前用的是这个 commit 是 OK 的。

用你的办法尝试了,结果仍然是 (empty)

发现一个被我忽略的细节,那就是启动后,如果不首先执行 magit-status 这个命令,直接执行 magit-log,会提示一个错误:

Symbol’s function definition is void: magit-read-file-from-rev

与这个错误有关吗?

最新的 magit-log.el 文件里有这么两行声明:

https://github.com/magit/magit/blob/ea1f626b0adfc25e5beacc6f4c9d8cff6d5cfc35/lisp/magit-log.el#L42-L43

(declare-function magit-read-file-from-rev "magit-files"
                  (rev prompt &optional default))

就是为了避免出现你说的这个错误。

难道你还在使用三年前的旧版本?

并没有,我刚刚更新了最新版本,你贴出来的这两行我这里也是有的,只是仍然存在我说的那个问题:

Symbol’s function definition is void: magit-read-file-from-rev

重新启动 Emacs 不执行 magit-status 直接执行 magit-log,在执行这个流程的过程中:

M-x magit-log RET L RET 2,5 RET l

执行到按大写的 L 按键的时候就报出来这个错

我个人的 Emacs 配置在:https://gitee.com/lenic/emacs-config

1 个赞

切换到 App.vue 文件,执行 M-! git log -L 2,5:App.vue --no-color 应该有输出。

这个是有输出,实际上就是执行命令,也算是一个临时解决方案吧

我的意思是,先确保相同的命令在 Emacs 和终端能得到一致的结果,由于配置导致的 Emacs 内外环境不同而产生的问题并不少见。所以,不仅是要看到输出,而且最好两边输出结果一致。否则也可能导致 magit 解析失败。

然后再考虑是否 magit 的问题。可以把范围缩小到具体的函数,在 App.vue 文件执行:

(magit-log-setup-buffer '("master")
                        '("-L2,5:src/App.vue")
                        '("src/App.vue"))

正常情况下这样就能直接看到如我前面贴图的结果了。

如果还是 empty,就继续拆解这个函数的每一步。

试试Magit稳定版3.0.0。

Magit我用得不多。但恰好这个显示指定范围的功能我经常用。我常用的命令是magit-log-buffer-file,

1 个赞

我在 src/App.vue 文件中直接更改为 lisp-mode,把你的代码 magit-log-setup-buffer 粘贴进去,然后执行 C-x C-e,看到的结果仍然是 (empty)

我还有另外两点发现:

  • 清除所有配置:只配置 emacs-china 的镜像源,只安装 magit 包一样显示 (empty)
  • 使用 Docker 容器:重复上面描述的方式,得到的仍然是 (empty)

所以,我怀疑是不是镜像源有问题?我找了好久,始终不清楚官方的地址是什么,不配置镜像源找不到 magit 这个包,只好作罢

Docker 容器使用这个命令下载镜像:docker pull lenic/node_lts_sshd:14

能提供下怎样把 magit 的 Git 仓库嵌入到自己的 Git 仓库中吗?

注:submodule 的方式我会用,只是不清楚怎么嵌入本地的情况下调用 magit 安装

简单说就是修改 load-path,然后 require 就好了。可以参考我最近的一篇文章:

我后边还说了一句:

范围已经缩很小了,debug 一下就知道究竟了。


但是始终也没说你的 magit 版本号。

首先非常感谢你一直在跟踪我这个问题,非常抱歉没理解你的意思。。。

这里我为自己辩解一下:

  • 我 lisp 水平还不够,debug 还局限在使用 print 指令打印 message 的程度,所以不清楚怎么 debug
  • magit 的版本号我没关注过,我查了下一直使用的最新构建

下面是我使用的配置:

;; 设置 Git 管理快捷键
(use-package magit
  :bind ("C-x m" . magit-status)
  :config
  (setq magit-diff-refine-hunk (quote all))
  :hook ((magit-post-commit-hook) . 'git-gutter:update-all-windows))

我发现自己哪怕是只安装 magit 也是没办法使用行追踪功能,除了自己的 Mac 电脑,在 Docker 容器中也是没办法使用这个功能的,综合来看不是我设置、环境或者硬件的问题。

今天再次尝试了一遍,使用 @jiacai2050 提供的方法,对应到 b68a760 这个提交,在我这里仍然没办法看到行追踪的历史。

无奈了。。。

b68a760 算是比较近的版本了。

我怀疑你可能无意中改了 magit 的 git 命令参数。

magit 所有动作都会转换成 git 命令执行,执行结果放在 buffer 里进行 wash。

所以,存在两种可能:

  1. 命令返回结果为空。
  2. 命令返回结果不为空,但 wash 失败。

可以从 magit-git-insert 切入调试。它执行 git 命令并返回未经处理的结果。处于问题1和2的分界线。

首先通过 advice 把命令参数以及相关信息打印出来看看有无异常:

(define-advice magit-git-insert (:before (&rest args) debug)
  (message "==> (magit-process-environment): %S" (magit-process-environment))
  (message "==> (magit--process-coding-system): %S" (magit--process-coding-system))
  (message "==> magit-git-executable: %s" magit-git-executable)
  (message "==> magit-git-global-arguments: %S" magit-git-global-arguments)
  (message "==> args: %S" args))

再把命令参数 args 带入到 magit-git-insert 执行:

(let ((default-directory "~/Downloads/test-tailwindcss")
      ;; (magit-git-debug t)
      ;; (magit-process-extreme-logging t)
      )
  (magit-git-insert
  ;; 用 advice 得到的 args 参数替换以下内容:
  "log" "--format=%h%x0c%x0c%x0c%aN%x0c%at%x0c%s" "-L2,5:src/App.vue"
  "--use-mailmap" "--no-prefix" "master" "--" "src/App.vue"))

正常情况下应该原地得到未经处理的输出结果。

magit-git-insert 几乎是最末端的函数了,再展开就是 process-file,没有往下探究的必要了:

(let ((default-directory "~/Downloads/test-tailwindcss")
      (process-environment (magit-process-environment))
      (default-process-coding-system (magit--process-coding-system)))
  (apply #'process-file
         magit-git-executable
         nil (list t nil) nil
         (magit-process-git-arguments
          '(;; 用 advice 得到的 args 参数替换以下内容:
            "log" "--format=%h%x0c%x0c%x0c%aN%x0c%at%x0c%s"
            "-L2,5:src/App.vue" "--use-mailmap" "--no-prefix"
            "master" "--" "src/App.vue"))))

再插一句,M-x magit-version 检查下版本是不是你指定的版本,我这边返回的是 Magit v3.0.0-2-gb68a760c, Git 2.20.1 (Apple Git-117), Emacs 27.2, darwin ,然后你再按照 twlz0ne 的方法测试。

反正代码你都 clone 下来了,不用 advice,直接修改相关 el 代码即可。

@jiacai2050 看到你的 Git 版本号,心血来潮用虚拟机试了下不同版本的 Git,发现 Alpine 下 3.12 版本自带的 2.26.3 是可以正常查看行追踪历史记录的,3.13 下就会出现 (empty) 问题。

然后我在 Git 官网下载源码,自己在 Mac 上编译了一个 2.26.3 版本,也是正常显示行追踪历史记录的。使用系统自带的 2.30.2 版本的 Git 就会出现问题。

但是我没完全测试在 (2.26.3, 2.30.2) 范围内的其它版本,我相信是这个范围内的某个 Git 版本更新了默认参数,然后 magit 没有及时跟进导致的异常。

个人感觉:magit 作者也没有及时更新 Git 版本,所以并不会复现这个问题 @twlz0ne

赞,后面提问题,可以把自己相关的环境都贴出来。

感觉可以再跟一下,看看是哪个参数改了,(或者去 GitHub 上提个 issue)方便我们后来要升级的 :smile: