Есть ли быстрая команда Git, чтобы увидеть старую версию файла?
Есть ли команда в Git, чтобы увидеть (либо сбрасывается в стандартный вывод, или в $PAGER
или же $EDITOR
) конкретная версия конкретного файла?
11 ответов
Ты можешь использовать git show
:
$ git show REVISION:path/to/file
Замените REVISION вашей фактической ревизией (это может быть SHA коммита Git, имя тега, имя ветки, относительное имя коммита или любой другой способ идентификации коммита в Git)
Например, для просмотра версии файла src/main.c
из 4 коммитов назад используйте:
$ git show HEAD~4:src/main.c
Обратите внимание, что путь идет от корня хранилища, если только он не начинается с./ или../ для указания относительного пути. Git для Windows требует прямой косой черты даже в путях относительно текущего каталога. Для получения дополнительной информации, обратитесь к справочной странице для git-show
,
Делать это по дате выглядит так:
git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt
Обратите внимание, что HEAD@{2013-02-25}
означает "где HEAD был 2013-02-25" в этом репозитории (с использованием reflog), а не "последний коммит до 2013-02-25 в этой ветви в истории".
Если вам нравятся графические интерфейсы, вы можете использовать gitk:
начать гитк с:
gitk /path/to/file
Выберите редакцию в верхней части экрана, например, по описанию или дате. По умолчанию в нижней части экрана отображается разница для этой ревизии (в соответствии с переключателем "patch").
Чтобы просмотреть файл для выбранной ревизии:
- Нажмите на кнопку "дерево". Это покажет корень дерева файлов в этой ревизии.
- Разверните файл.
Вы также можете указать commit hash
(часто также называется commit ID
) с git show
командование
В двух словах
git show <commitHash>:/path/to/file
Шаг за шагом
- Показать журнал всех изменений для данного файла с
git log /path/to/file
- В показанном списке изменений показаны
commit hash
такие какcommit 06c98...
(06c98... хеш коммита) - Скопируйте
commit hash
- Запустите команду
git show <commitHash>:/path/to/file
с использованиемcommit hash
шага 3 иpath/to/file
шага 1.
Примечание: добавление ./
когда указание относительного пути кажется важным, т.е. git show b2f8be577166577c59b55e11cfff1404baf63a84:./flight-simulation/src/main/components/nav-horiz.html
,
Чтобы быстро увидеть различия со старыми ревизиями файла:
git show -1 filename.txt
> сравнить с последней ревизией файла
git show -2 filename.txt
> сравнить со 2-ой последней ревизией
git show -3 fielname.txt
> сравнить с последней 3-ей последней ревизией
В дополнение к ответу Джима Хунцикера,
Вы можете экспортировать файл из ревизии как,
git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt > old_fileInCurrentDirectory.txt
Надеюсь это поможет:)
git log -p
покажет вам не только логи коммитов, но и различия каждого коммита (кроме коммитов слияния). Тогда вы можете нажать /
введите имя файла и нажмите enter
, Нажмите n
или же p
перейти к следующему / предыдущему вхождению. Таким образом, вы увидите не только изменения в файле, но и информацию о фиксации.
СПОСОБ 1: (Я предпочитаю этот способ)
Найдите идентификатор фиксации с помощью:
git reflog
Список файлов из коммита
git diff-tree --no-commit-id --name-only -r <commitHash>
Пример:
git diff-tree --no-commit-id --name-only -r d2f9ba4
d2f9ba4
это идентификатор фиксации из шага 1.Откройте нужный файл с помощью следующей команды:
git show <commitHash>:/path/to/file
Пример:
git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift
Src/...
путь к файлу из шага 2.
СПОСОБ 2:
Найдите идентификатор фиксации с помощью:
git reflog
Сделайте полный сброс этого коммита:
git reset --hard %commit ID%
Пример:
git reset --hard c14809fa
Внесите необходимые изменения и сделайте новый коммит в нужную ветку
Вы можете использовать скрипт, подобный этому, чтобы записать все версии файла в отдельные файлы:
например
git_dump_all_versions_of_a_file.sh path/to/somefile.txt
Получите скрипт здесь как ответ на другой похожий вопрос
Помощник для извлечения нескольких файлов из данной ревизии
При попытке разрешить конфликты слияния этот помощник очень полезен:
#!/usr/bin/env python3
import argparse
import os
import subprocess
parser = argparse.ArgumentParser()
parser.add_argument('revision')
parser.add_argument('files', nargs='+')
args = parser.parse_args()
toplevel = subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).rstrip().decode()
for path in args.files:
file_relative = os.path.relpath(os.path.abspath(path), toplevel)
base, ext = os.path.splitext(path)
new_path = base + '.old' + ext
with open(new_path, 'w') as f:
subprocess.call(['git', 'show', '{}:./{}'.format(args.revision, path)], stdout=f)
Использование:
git-show-save other-branch file1.c path/to/file2.cpp
Результат: следующие содержат альтернативные версии файлов:
file1.old.c
path/to/file2.old.cpp
Таким образом, вы сохраняете расширение файла, чтобы ваш редактор не жаловался и мог легко найти старый файл рядом с новым.
Ни один из предыдущих ответов не касался второй возможности, упомянутой ФП, а именно, как открыть результаты в$EDITOR
.
Большинство редакторов на терминале примут чтение, если вы передадите одно тире-
в качестве имени файла, что позволяет передать вывод команды команде, которую вы будете использовать для открытия редактора.
Как пользователь Vim, я буду использовать его в качестве примера для пояснения. Вы можете сделать следующее:
# The reference to a commit, branch, tag, etc
$ REVISION='...'
$ git show "$REVISION":path/to/file | vim -
Одним из недостатков этого является то, что редактор не имеет четкого представления о типе файла, с которым вы имеете дело, и у него могут возникнуть проблемы, например, с подсветкой синтаксиса. Это происходит потому, что нет расширения файла, на которое можно было бы обратить внимание. С точки зрения редактора, он просто получает блок байтов отstdin
.
В Vim эту проблему можно легко решить, явно задав параметрfiletype
:
$ git show "$REVISION":path/to/file.py | vim -c 'set filetype=python' -
Очень полезно объединитьgit show
с заменой процесса для сравнения двух исторических версий файла напрямую с помощью утилиты сравнения (diff
,vimdiff
, и т. д). Возможно, положение файла сильно изменилось внутри репозитория Git или, возможно, он был удален на некоторое время, а затем создан заново. В таких ситуациях Git сложно отобразить нужные вам различия, но следующая команда помогает:
$ vimdiff <(git show "$REV_0":path/to/file) <(git show "$REV_1":another/path/to/file)
Приятно найти что-то добавить к почти 15-летнему вопросу!