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

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

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

Homero Esmeraldo 04.01.2020 05:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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

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