Использование emacs (и magit?) Для посещения файла в данных commit/branch/etc
Если я хочу посмотреть, как выглядит foo.bar
в некотором определенном commit <COMMIT_ID>
, я могу вызвать:
git show <COMMIT_ID>:foo.bar
Ницца... Как это сделать в emacs
? Используя magit
? Используя vc
? Скажем, я посещаю файл foo.bar
, и я хочу посмотреть, как он выглядел в <COMMIT_ID>
.
Ответы
Ответ 1
Канонический способ сделать это в Emacs - использовать VC: C-x v ~
из файлового буфера попросит вас о пересмотре, а затем покажет этот файл так, как он был при этой ревизии. Он должен работать для любой системы управления, поддерживаемой VC, например, Git, Bzr,...
Ответ 2
- C-x v l, чтобы просмотреть историю файлов.
- n и p для перемещения между коммитами.
- 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
для обработка исправлений.
Я пришел к выводу, что использование другого окна по умолчанию действительно имеет смысл, поэтому я сделал то же самое здесь - если вы не предоставили префиксный аргумент, в этом случае он использует текущее окно.
(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)
(unless (vc-backend file)
(error "File %s is not under version control" file))
(list file (vc-read-revision
"Revision to visit (default is working revision): "
(list file)))))
(require 'vc)
(unless (vc-backend file)
(error "File %s is not under version control" file))
(let ((revision (if (string-equal rev "")
(vc-working-revision file)
rev))
(visit (if current-prefix-arg
'switch-to-buffer
'switch-to-buffer-other-window)))
(funcall visit (vc-find-revision file revision))))
Ответ 3
Там пакет под названием 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
к привязке клавиш по вашему выбору.
Ответ 4
Если вы просматриваете фиксацию в magit, вы можете просто нажать Enter в файле или части интересующего вас файла.