Как я могу просмотреть старую версию файла с помощью Git?

Есть ли в Git команда для просмотра (выгруженная в стандартный вывод, либо в $PAGER или $EDITOR) конкретную версию определенного файла?

Если вы пришли к этому вопросу, потому что хотите проверить старую версию двоичного файла (например, изображение), то лучше выполнить проверку старой фиксации, посмотреть, что вам нужно увидеть, а затем вернуться к HEAD. Для этого сделайте git checkout <sha1-of-the-commit-you-need>, потом git checkout HEAD

Homero Esmeraldo 04.01.2020 05:48
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Принципы ООП в JavaScript
Принципы ООП в JavaScript
Парадигма объектно-ориентированного программирования имеет 4 основных принципа,
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Можете ли вы объяснить разницу между ngOnInit и конструктором в Angular?
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
1 616
2
462 112
10

Ответы 10

Вы можете использовать git show с путем из корня репозитория (./ или ../ для относительного пути):

$ git show REVISION:path/to/file

Замените REVISION вашей фактической версией (может быть SHA фиксации Git, имя тега, имя ветки, относительное имя фиксации или любой другой способ идентификации фиксации в Git)

Например, чтобы просмотреть версию файла <repository-root>/src/main.c от 4 коммитов назад, используйте:

$ git show HEAD~4:src/main.c

Git для Windows требует косая черта даже в путях относительно текущего каталога. Для получения дополнительной информации посетите страницу руководства для git-show.

На самом деле это не работает - вы пробовали? Для "git show HEAD: path / to / file.c" я получаю ошибку "неоднозначный аргумент".

mike 03.12.2008 23:06

И если я просто сделаю «git-show path / to / file.c», команда завершится успешно без вывода.

mike 03.12.2008 23:12

С какой версией git? Другой способ сделать это - использовать git cat-file с указанием идентификатора blob-объекта (который вы можете найти с помощью ls-tree, но это трудный путь).

Dustin 04.12.2008 01:17

Должен быть полный путь, начиная с репозитория git

richq 04.12.2008 11:25

Если вы работаете в Windows, это может быть разделитель путей; если я сделаю git show HEAD: dir \ subdir \ file, я получу неоднозначный аргумент. Если я сделаю git show HEAD: dir / subdir / file, он будет работать, как ожидалось.

Matt McMinn 21.07.2010 18:56

Путь, который вы должны указать после:, находится в корне репозитория git. (это было дано ниже в качестве ответа, но я думаю, что это было задумано как комментарий к этому ответу)

MatrixFrog 28.02.2011 22:21

Если вы хотите увидеть его в разделе Vim, чтобы они прокручивались вместе, я написал короткий Сообщение блога, показывающий, как это сделать.

Flaviu 25.12.2011 10:18

Mercurial может обновить все репо до предыдущей версии ... с помощью команды обновления. любой аналогичный способ в git временно переключиться на предыдущую ревизию ??

ashishsony 03.01.2012 13:13

@ashishsony: Да, вы можете использовать git checkout <revision>.

mipadi 03.01.2012 18:52

Что происходит с изменениями, которые я делаю в рабочем каталоге ?? есть ли способ сохранить их нетронутыми и вернуть их, как только я вернусь к исправлению? Спасибо.

ashishsony 04.01.2012 08:22

Спасибо! Какая полезная команда. Я мучительно и неэффективно пытался скопировать, вставить и переформатировать мой старый исходный код из файла diff.

ratsimihah 24.07.2012 03:00

Вы можете использовать git log - [имя_файла] для просмотра исправлений

Michael Dausmann 17.02.2014 03:32

Вы также можете перенаправить git show в vim с помощью (commit):(path to file) | vim -. Я считаю это намного лучше, чем использовать меньше / больше, которое используется по умолчанию.

laughing_man 06.03.2014 07:57

По какой-то причине у меня работает Только - git show <commit>:file. Все остальное просто дает самую последнюю версию.

Bobby Jack 24.11.2014 14:45

Вы сказали «показать 4-ю последнюю фиксацию файла», но действительно ли вы имели в виду «показать файл таким, каким он был в 4-й последней фиксации»?

Craig McQueen 15.04.2015 09:19

Эти инструкции не работают в моем случае. Он может найти файл на диске, но сообщает, что его нет в предоставленном коммите; однако я получил sha коммита от git blame, поэтому он должен быть в коммите.

weberc2 10.06.2016 17:08

Синтаксис HEAD: ~ <n> НЕ работает должным образом. Не отображается n-я предыдущая ревизия файла src / main.c. Он показывает содержимое этого файла на n-й предыдущей фиксации текущей ветки. Если файл src / main.c не изменялся при каждой фиксации в истории ветки, это не даст ожидаемого результата.

Die in Sente 07.07.2016 20:51
REVISION может быть хешем фиксации. Смотрите мой ответ: stackoverflow.com/a/40400259/759452
Adrien Be 03.11.2016 14:57
git-show отличный. Могу ли я переключать номера строк при использовании в командной строке?
KFL 11.01.2017 10:18

Чтобы добавить к ответу, git-show не дает вам номеров строк. Если вам нужны номера строк, попробуйте git show <commit>:<file> | less -N

KFL 11.01.2017 10:20

Вместо того, чтобы указывать путь из корня репо, вы можете использовать относительный путь, если вы запустите его с ., например: git show HEAD:./subdir/main.c > foo. Это работает в последних версиях git (проверено в git 2.8.3 на CentOS 7)

Eponymous 06.09.2017 18:53

@MichaelDausmann, я добавил серию патчей в файл с помощью git add -p. Есть ли способ увидеть весь файл в том виде, в каком он находится в индексе, прежде чем я его зафиксирую?

alpha_989 30.04.2018 21:08

Не работает, получаю fatal: Invalid object name 'REVISION'.

Black 14.07.2018 19:10

@Black: замените REVISION своей фактической ревизией (может быть SHA фиксации Git, имя тега, имя ветки, относительное имя фиксации или любой другой способ идентификации фиксации в Git).

mipadi 17.07.2018 01:24

@mipadi, не работает Я пробовал: "git show 717fe60db378e7052247fa5de33e50bce59e2e85:" app \ Models \ Seleniu‌ m.php "Но вывода нет

Black 17.07.2018 11:27

@Black: Это путь в вашем репозитории? Здесь много чего может пойти не так.

mipadi 18.07.2018 23:06

Не хотел голосовать за этот ответ, так как теперь у него 1337 голосов. Все равно сделал это :)

Michel 10.08.2018 12:12

У меня это работает. Я получаю вывод в терминале. Есть ли способ отправить это в текстовый файл?

Diego 23.10.2019 17:00

@Diego: перенаправить вывод в файл: git show REVISION:path/to/file > path/to/file.

mipadi 24.10.2019 07:06

Если вам нравятся графические интерфейсы, вы можете использовать gitk:

  1. Запустите gitk с:

    gitk /path/to/file
    
  2. Выберите версию в верхней части экрана, например по описанию или дате. По умолчанию в нижней части экрана отображается разница для этой ревизии (соответствует переключателю «патч»).

  3. Чтобы увидеть файл выбранной ревизии:

    • Щелкните переключатель "дерево". Это покажет корень файлового дерева этой ревизии.
    • Перейдите к своему файлу.

Это также работает с тигр, который является программой просмотра репозитория curses git.

Matthew G 13.05.2013 09:01

@Paul Slocum: Может быть, потому, что эта команда не является стандартной командой, а не встроенной в git. Я думаю, что эта команда работает только для Windows.

Envil 04.12.2013 06:46

Обратите внимание, что это работает, только если вы начинаете с корня репозитория git.

Marc 23.03.2016 19:43

Если вы хотите проверить определенную ревизию с помощью gitk, вы также можете использовать этот ярлык: gitk REVISION /path/to/file. Это может пригодиться, например, когда вы хотите проверить определенную версию.

Christian.D 06.07.2016 10:42

Выполнение этого по дате выглядит так: если фиксация произошла в течение последних 90 дней:

git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt

Обратите внимание, что HEAD@{2013-02-25} означает «где HEAD был 25 февраля 2013 г.» в этом репозитории (с использованием рефлог), а не «последний коммит перед 25 февраля 2013 г. в этой ветке в истории».

Это важно! Это означает, что по умолчанию этот метод работает только для истории за последние 90 дней. В противном случае нужно сделать так:

git show $(git rev-list -1 --before = "2013-02-26" HEAD):./fileInCurrentDirectory.txt

Эта команда полезна с master вместо HEAD@{2013-02-25}, если вы находитесь в ветке

funroll 09.11.2015 16:56

Можете включить время а-ля git log --since='2016-04-28 23:59:59 +0100'?

dumbledad 03.05.2016 15:55

Тот факт, что этот синтаксис использует reflog, важен и должен быть особо выделен, потому что рефлог не содержит всех коммитов. См. blog.endpoint.com/2014/05/git-checkout-at-specific-date.html

Alice Heaton 30.12.2016 07:21

То, что я пропустил: там не могу будет пробел после двоеточия : и перед именем файла.

Abhishek Divekar 11.01.2018 12:19

@AliceHeaton Это невозможно переоценить. (Спасибо !)

Skippy le Grand Gourou 25.01.2021 12:37

@AliceHeaton - обновлено (4 года спустя, ха-ха!)

Jim Hunziker 25.01.2021 16:53

В дополнение к ответу Джим Ханзикер,

Вы можете экспортировать файл из ревизии как,

git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt > old_fileInCurrentDirectory.txt

Надеюсь это поможет :)

Git log -p покажет вам не только журналы фиксации, но и различия каждой фиксации (кроме фиксации слияния). Затем вы можете нажать /, ввести имя файла и нажать enter. Нажмите n или p, чтобы перейти к следующему / предыдущему вхождению. Таким образом, вы увидите не только изменения в файле, но и информацию о фиксации.

Похоже, git log -pm также покажет коммиты слияния.

sanbor 06.05.2016 23:07

Вы также можете запустить git log -p -- filename.txt, чтобы ограничить историю только желаемым файлом.

Jean Paul 21.01.2019 15:25

Вы также можете указать commit hash (часто также называемый commit ID) с помощью git show команда.


В двух словах

Git show <commitHash>:/path/to/file


Шаг за шагом

  1. Показать журнал всех изменений для данного файла с помощью git log /path/to/file
  2. В показанном списке изменений он показывает commit hash, например commit 06c98... (06c98 ... хеш фиксации)
  3. Скопируйте commit hash
  4. Запустите команду 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 <SHA1> --name-only для его получения.

Tiina 11.10.2017 04:03

Эта команда op - даже автоматически завершается из памяти - проверена на удаленном каталоге ... не может получить больше op, чем этот gg

treyBake 10.11.2017 15:55

В debian добавление ./ не имеет значения для пути.

Timo 15.08.2020 15:53

Вы можете использовать такой сценарий, чтобы выгрузить все версии файла в отдельные файлы:

Например

git_dump_all_versions_of_a_file.sh path/to/somefile.txt

Получите сценарий здесь как ответ на другой похожий вопрос

git_root, git_log_short и git_log_message_for_commit отсутствуют.
mogsie 26.01.2018 17:23

Хороший улов! Я дважды разместил этот ответ в двух разных местах, а просто удалил его и связал с другим, где люди рассказывали мне об этом раньше ... спасибо @mogsie!

Brad Parks 26.01.2018 17:32

Этот скрипт очень полезен!

XMAN 22.12.2018 06:33

Помощник для получения нескольких файлов из данной ревизии

Этот помощник очень полезен при попытке разрешить конфликты слияния:

#!/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)

GitHub вверх по течению.

Использование:

git-show-save other-branch file1.c path/to/file2.cpp

Результат: следующие версии файлов содержат альтернативные версии:

file1.old.c
path/to/file2.old.cpp

Таким образом, вы сохраните расширение файла, чтобы ваш редактор не жаловался и мог легко найти старый файл рядом с новым.

@MickeyPerlstein, если вы можете добиться того же интерфейса с лучшей реализацией, я все слышу.

Ciro Santilli新疆棉花TRUMP BAN BAD 24.03.2019 19:38

Возможно, я не понимаю (и если да, то приношу свои извинения), но разве это не просто: "git show version: ./ path> new_path"?

Mickey Perlstein 26.03.2019 14:34

@MickeyPerlstein привет, да, моя команда генерирует этот интерфейс командной строки, но она перебирает несколько файлов и выдает имя вывода из ввода, поэтому вам не нужно набирать слишком много. Ничего революционного конечно, но удобно.

Ciro Santilli新疆棉花TRUMP BAN BAD 27.03.2019 00:16

Чтобы быстро увидеть различия со старыми версиями файла:

git show -1 filename.txt > to compare against the last revision of file git show -2 filename.txt > to compare against the 2nd last revision git show -3 fielname.txt > to compare against the last 3rd last revision

Эти команды показывают мне различия с текущей версией, но не показывают весь файл.

Jean Paul 21.01.2019 14:31

СПОСОБ 1: (я предпочитаю этот способ, без возможности потерять незафиксированные данные)

  1. Найдите идентификатор фиксации с помощью: git reflog

  2. Список файлов из коммита git diff-tree --no-commit-id --name-only -r <commitHash>

    Пример:

    git diff-tree --no-commit-id --name-only -r d2f9ba4 d2f9ba4 is commit id from step 1.
  3. Откройте требуемый файл с помощью следующей команды:

    Git show <commitHash>:/path/to/file

    Пример:

    git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift Src/... is file path from step 2.

СПОСОБ 2: (возможность потерять незафиксированные данные)

  1. Найдите идентификатор фиксации с помощью: git reflog

  2. Сделайте полный сброс этого коммита: git reset --hard %commit ID%

    Пример:

    git reset --hard c14809fa
  3. Внесите необходимые изменения и сделайте новый коммит в нужную ветку.

ВНИМАНИЕ: будьте осторожны со вторым методом, так как вы потеряете все незафиксированные изменения при выполнении аппаратного сброса!

Enn Michael 01.12.2020 19:25

Да, с полным сбросом все в порядке. это из-за того, что сброс бывает «жестким», а не «мягким». Но нужно усердно работать из-за возможности конфликтов.

Andrew 01.12.2020 21:31

Другие вопросы по теме