29

如果我想看看foo.bar某个提交的样子,<COMMIT_ID>那么我可以调用:

git show <COMMIT_ID>:foo.bar

很好...我该怎么做emacs?使用magit? 使用vc? 假设我正在访问该文件foo.bar,并且我想查看它的外观<COMMIT_ID>

4

4 回答 4

31

在 Emacs 中执行此操作的规范方法是使用 VC:C-x v ~从文件的缓冲区中会要求您进行修订,然后显示该文件在该修订时的样子。它应该适用于 VC 支持的任何控制系统,例如 Git、Bzr、...

于 2014-08-21T18:43:52.217 回答
24
  • C-xvl查看文件的历史记录。
  • np在提交之间移动。
  • f在提交时访问文件。

这是必然的log-view-find-revision,如果我们查看代码,我们会看到关键位是:

(switch-to-buffer (vc-find-revision file revision)))

所以我们可以将它包装在一个自定义函数中,如下所示:

(defun my-vc-visit-file-revision (file revision)
  "Visit FILE as it was at REVISION."
  (interactive
   (list (expand-file-name
          (read-file-name (if (buffer-file-name)
                              (format "File (%s): " (file-name-nondirectory
                                                     (buffer-file-name)))
                            "File: ")))
         (read-string "Revision: ")))
  (require 'vc)
  (switch-to-buffer
   (vc-find-revision file revision)))

编辑:Stefan 提供了更好的答案,但是如果您喜欢能够选择文件和修订版,这里是我的函数的一个版本,它维护交互式文件选择,但使用来自的代码vc-revision-other-window进行修订处理。

我得出的结论是,默认使用 other-window 确实更有意义,所以我在这里做了同样的事情——除非你提供一个前缀参数,在这种情况下它使用当前窗口。

(defun my-vc-visit-file-revision (file rev)
  "Visit revision REV of FILE in another window.
With prefix argument, uses the current window instead.
If the current file is named `F', the revision is named `F.~REV~'.
If `F.~REV~' already exists, use it instead of checking it out again."
  ;; based on `vc-revision-other-window'.
  (interactive
   (let ((file (expand-file-name
                (read-file-name
                 (if (buffer-file-name)
                     (format "File (%s): " (file-name-nondirectory
                                            (buffer-file-name)))
                   "File: ")))))
     (require 'vc)
     (list file (if (vc-backend file)
                    (vc-read-revision
                     "Revision to visit (default is working revision): "
                     (list file))
                  (vc-read-revision "Revision to visit: " t
                                    (or (vc-deduce-backend)
                                        (vc-responsible-backend file)))))))
  (require 'vc)
  (let ((revision (if (string-equal rev "")
                      (if (vc-backend file)
                          (vc-working-revision file)
                        (error "No revision specified for unregistered file %s"
                               file))
                    rev))
        (backend (or (vc-backend file)
                     (vc-deduce-backend)
                     (vc-responsible-backend file)))
        (visit (if current-prefix-arg
                   'switch-to-buffer
                 'switch-to-buffer-other-window)))
    (condition-case err
        (funcall visit (vc-find-revision file revision backend))
      ;; The errors which can result when we request an invalid combination of
      ;; file and revision tend to be opaque side-effects of some unexpected
      ;; failure within the backend; so we simply trap everything and signal a
      ;; replacement error indicting the assumed cause.
      (error (error "File not found at revision %s: %s" revision file)))))

我将此命令绑定到C-xvC-f

于 2014-08-21T07:44:45.383 回答
8

有一个名为的包git-timemachine可以使查看文件以前版本的过程几乎完全无缝;请参阅链接以获取安装说明和演示。(如果您已经在使用 MELPA,就这样做M-x package-install RET git-timemachine RET)。

它的工作方式是,您M-x git-timemachine RET从访问跟踪文件的缓冲区中调用。那么你也能:

  • p访问以前的历史版本
  • n访问下一个历史版本
  • w复制当前历史版本的缩写哈希
  • W复制当前历史版本的完整哈希
  • q退出时光机。

请注意,如果您知道要访问的提交的哈希值,@phils 解决方案中的自定义命令将为您提供更好的特定用例。但是对于在文件的不同版本之间导航,我发现使用git-timemachine比使用 VC 提供的功能更容易。

您当然可以绑定git-timemachine到您选择的键绑定。

于 2014-08-21T10:05:45.707 回答
7

如果您正在查看 magit 中的提交,您只需在文件或您感兴趣的部分文件上按 Enter。

于 2015-09-25T13:59:27.020 回答