Просмотр истории изменений файла с помощью Git-версий

3092

Как я могу просмотреть историю изменений отдельного файла в Git, полную информацию о том, что изменилось?

Я дошел до:

git log -- [filename]

которая показывает мне историю коммитов файла, но как мне узнать содержание каждого файла?

Я пытаюсь сделать переход от MS SourceSafe, и это было просто right-clickshow history.

Ричард
источник
41
Приведенная выше ссылка больше не действительна. Эта ссылка работает сегодня: Git Community Book
Крис
1
Ссылка выше (размещенная Крисом) больше не действительна. Эта ссылка работает сегодня: git-scm.com/book/en/v2
Cog

Ответы:

2370

Для этого я бы использовал:

gitk [filename]

или следовать имени файла после переименования

gitk --follow [filename]
Клаудио Аччарези
источник
28
Но у меня даже есть инструмент, который сочетает в себе все вышеперечисленное с «мерзавцем», позволяющим мне просматривать источник файла по мере его изменения во времени ...
Egon Willighagen,
26
К сожалению, это не соответствует истории файла после переименования.
Дэн Молдинг
146
Я также искал историю файлов, которые были ранее переименованы и нашел эту тему первым. Решение состоит в том, чтобы использовать «Git журнал --follow <имя файла>» , как Фил указал здесь .
Флориан Гутман
115
Автор искал инструмент командной строки. Хотя gitk поставляется с GIT, он не является ни приложением командной строки, ни особенно хорошим графическим интерфейсом.
mikemaccana
72
Он искал инструмент командной строки? «правый клик -> показать историю», конечно, не подразумевает этого.
hdgarrood
2236

Ты можешь использовать

git log -p filename

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

Видеть

git help log

для большего количества опций - это может действительно сделать много хороших вещей :) Чтобы получить только diff для определенного коммита, вы можете

git show HEAD 

или любая другая ревизия по идентификатору. Или использовать

gitk

просматривать изменения визуально.

Волька
источник
8
git show HEAD показывает все файлы, знаете ли вы, как отслеживать отдельный файл (как просил Ричард)?
Йонас Быстрем
5
вы используете: git show <revision> - имя файла, которое будет отображать различия для этой ревизии, если она существует.
Маркос Оливейра
4
--stat также полезно. Вы можете использовать его вместе с -p.
Раффи Хачадурян
5
Это замечательно. Гитк не ведет себя хорошо при указании путей, которые больше не существуют. Я использовал git log -p - путь.
Пауло Касаретто
6
Плюс гитк выглядит так, как будто его создал монстр буги. Это отличный ответ и лучше всего приспособлен к исходному вопросу.
Гэйс
1499

git log --follow -p -- path-to-file

Это покажет всю историю файла (включая историю за переименованием и различия для каждого изменения).

Другими словами, если названный файл barбыл когда-то назван foo, тогда git log -p bar(без --followопции) будет отображаться только история файла до того момента, когда он был переименован - он не будет отображать историю файла, когда он был известен как foo. Использование git log --follow -p barпокажет всю историю файла, включая любые изменения в файле, когда он был известен как foo. -pОпция гарантирует , что дифференциалы включены для каждого изменения.

Дэн Молдинг
источник
18
--stat также полезно. Вы можете использовать его вместе с -p.
Раффи Хачадурян
23
Я согласен, что это РЕАЛЬНЫЙ ответ. (1.) --followгарантирует, что вы видите файл переименовывает (2.) -pгарантирует, что вы видите, как файл изменяется (3.) это только командная строка.
Тревор Бойд Смит
3
@NHDaly Я заметил, что --был добавлен, но я не знаю, почему это делает это лучше? Что это делает?
Бенджон
40
@Benjohn --Опция сообщает Git, что она достигла конца опций и что все последующее --следует рассматривать как аргумент. Для git logэтого имеет значение только если у вас есть путь, который начинается с тире . Скажем, вы хотели узнать историю файла с неудачным именем "--follow":git log --follow -p -- --follow
Дэн Молдинг
10
@Benjohn: как правило, --это полезно, потому что оно также может защитить от любых revisionимен, которые соответствуют введенному вами имени файла, что на самом деле может быть страшно. Например: если у вас есть и ветвь, и файл с именем foo, git log -p fooбудет отображаться история журнала git foo, а не история файла foo . Но @DanMoulding прав в том, что поскольку --followкоманда принимает в качестве аргумента только одно имя файла, это менее необходимо, поскольку она не может быть a revision. Я только что узнал это. Может быть, вы были правы, оставив это без ответа; Я не уверен.
NHDaly
172

Если вы предпочитаете оставаться текстовым, вы можете использовать tig .

Быстрая установка:

  • apt-get :# apt-get install tig
  • Доморощенный (OS X) :$ brew install tig

Используйте его для просмотра истории одного файла. tig [filename]
Или просмотрите подробную историю репо:tig

Похоже, gitkно на основе текста. Поддерживает цвета в терминале!

Falken
источник
23
Отличный текстовый инструмент, отличный ответ. Я испугался, когда увидел зависимости для установки gitk на моем безголовом сервере. Снова проголосую за A +++
Том МакКензи
Вы также можете посмотреть определенные файлы с помощью tig, то естьtig -- path/to/specific/file
gloriphobia
110

git whatchanged -p filenameтакже эквивалентно git log -p filenameв этом случае.

Вы также можете увидеть, когда была изменена конкретная строка кода внутри файла git blame filename. Это выведет короткий идентификатор фиксации, автора, метку времени и полную строку кода для каждой строки в файле. Это очень полезно после того, как вы нашли ошибку и хотите узнать, когда она была обнаружена (или кто виноват в ней).

farktronix
источник
4
+1, но filenameне является обязательным в команде git blame filename.
RockXrock
7
«Новым пользователям рекомендуется использовать вместо этого git-log. (...) Команда сохраняется в основном по историческим причинам;»
Ciastek
105

Пользователи SourceTree

Если вы используете SourceTree для визуализации своего хранилища (это бесплатно и довольно неплохо), вы можете щелкнуть правой кнопкой мыши файл и выбрать Log Selected

введите описание изображения здесь

Дисплей (ниже) намного удобнее, чем GITK и большинство других перечисленных опций. К сожалению (в настоящее время) нет простого способа запустить это представление из командной строки - в настоящее время CLI SourceTree просто открывает репозитории.

введите описание изображения здесь

Марк Фокс
источник
1
Мне особенно нравится опция «Отслеживать переименованные файлы», которая позволяет вам видеть, был ли файл переименован или перемещен.
Крис
но если я не ошибаюсь (пожалуйста, дайте мне знать!), можно сравнить только две версии одновременно в графическом интерфейсе? Есть ли клиенты, которые имеют элегантный интерфейс для показа нескольких разных версий одновременно? Возможно, с уменьшенным изображением, как в Sublime Text? Это было бы действительно полезно, я думаю.
Сэм Льюоллен
@ SamLewallen Если я правильно понимаю, вы хотите сравнить три разных коммита? Это похоже на трехстороннее слияние (мое, ваше, базовое) - обычно эта стратегия используется для разрешения конфликтов слияния, не обязательно сравнивающих три произвольных фиксации. Есть много инструментов , которые поддерживают три путь слияние stackoverflow.com/questions/10998728/... но трюк кормление этих инструментов конкретных изменений gitready.com/intermediate/2009/02/27/...
Mark Fox
Спасибо Марк Фокс, вот что я имею в виду. Вы знаете какие-либо приложения, которые будут делать это?
Сэм Льюоллен
1
@ MarnenLaibow-Koser Я не могу вспомнить, зачем мне нужен SHA в то время. Ахаха.
AechoLiu
63

Чтобы показать, какая ревизия и автор в последний раз изменили каждую строку файла:

git blame filename

или если вы хотите использовать мощный графический интерфейс:

git gui blame filename
yllohy
источник
49

Резюме других ответов после их прочтения и небольшой игры:

Обычная команда командной строки будет

git log --follow --all -p dir/file.c

Но вы также можете использовать либо gitk (gui), либо tig (text-ui), чтобы дать гораздо более понятные человеку способы просмотра.

gitk --follow --all -p dir/file.c

tig --follow --all -p dir/file.c

В Debian / Ubuntu, команда install для этих замечательных инструментов выглядит так:

sudo apt-get install gitk tig

И я в настоящее время использую:

alias gdf='gitk --follow --all -p'

так что я могу просто напечатать, gdf dirчтобы получить целевую историю всего в подкаталоге dir.

Джон Лоуренс Аспден
источник
2
Я думаю, что это отличный ответ. Может быть, вас тоже не голосуют, потому что вы отвечаете другими способами (ИМХО лучше), чтобы увидеть изменения, например, через gitk и tig в дополнение к git.
PopcornKing
Просто чтобы добавить, чтобы ответить. Найдите путь (в git-пространстве, до которого до сих пор существует в хранилище). Затем используйте указанную выше команду "git log --follow --all -p <folder_path / file_path>". Может случиться так, что папка / файл была бы удалена за историю, поэтому найдите максимальный путь, который все еще существует, и попытайтесь извлечь его историю. работает !
parasrish
2
--allдля всех ветвей, остальное объясняется в ответе @ Дана
cregox
1
О, чувак, после столь долгого времени поиска хорошего решения для отслеживания файлов за пределами переименований, наконец, я нашел его здесь. Работает как шарм! Спасибо!
xZero
25

Добавьте этот псевдоним в ваш .gitconfig:

[alias]
    lg = log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\n--abbrev-commit --date=relative

И используйте команду так:

> git lg
> git lg -- filename

Вывод будет выглядеть почти так же, как вывод gitk. Наслаждаться.

Palesz
источник
После того, как я запустил этот ярлык LG, я сказал (и я цитирую) «Прекрасно!». Однако обратите внимание, что «\ n» после «--graph» является ошибкой.
jmbeck
3
Также может быть использован git lg -p filename- он возвращает красивую разность искомого файла.
Эгель
22

В последнее время я обнаружил tigи нашел это очень полезным. В некоторых случаях я хотел бы, чтобы это делалось A или B, но в большинстве случаев это довольно аккуратно.

Для вашего случая, tig <filename>может быть, то, что вы ищете.

http://jonas.nitro.dk/tig/

lang2
источник
на
Centos Yum
18

Вы можете использовать vscode с GitLens , это очень мощный инструмент. После установки GitLens, перейдите на вкладку GitLens, выберите FILE HISTORYи вы можете просмотреть его.

введите описание изображения здесь

foxiris
источник
15

Я написал Git-воспроизведения для этой конкретной цели

pip install git-playback
git playback [filename]

Это дает преимущество как в отображении результатов в командной строке (например git log -p), так и в том случае, когда вы можете проходить каждый коммит с помощью клавиш со стрелками (например gitk).

Цзянь
источник
13

Или:

gitx -- <path/to/filename>

если вы используете GITX

Джордж Андерсон
источник
1
По какой-то причине мой gitx открывается пустым.
Игорь Ганапольский
@IgorGanapolsky вы должны убедиться, что вы находитесь в корне своего репозитория git
zdsbs
10

Вы также можете попробовать это, в котором перечислены коммиты, которые изменили определенную часть файла (реализовано в Git 1.8.4).

Возвращенным результатом будет список коммитов, которые изменили эту конкретную часть. Команда:

git log --pretty=short -u -L <upperLimit>,<lowerLimit>:<path_to_filename>

где upperLimit - это start_line_number, а lowerLimit - это конечный_лайн-номер файла.

Более подробная информация на https://www.techpurohit.com/list-some-useful-git-commands

jitendrapurohit
источник
9

Если вы хотите просмотреть всю историю файла, в том числе и во всех других ветках, используйте:

gitk --all <filename>
Ади Шавит
источник
7

С отличными Git Extensions вы переходите к точке в истории, где файл еще существовал (если он был удален, в противном случае просто перейдите в HEAD), переключитесь на File treeвкладку, щелкните правой кнопкой мыши на файле и выберите File history.

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

У него есть несколько мелких ошибок, например, показ fatal: Not a valid object nameна Viewвкладке при нажатии на ревизию удаления, но я могу с этим смириться. :-)

PhiLho
источник
Стоит отметить, что это только для Windows.
Эван Хан
3
@EvanHahn не точный, через моно можно использовать GitExtension также и в Linux, мы используем его в Ubuntu и очень довольны этим. см. git-extensions-documentation.readthedocs.org/en/latest/…
Шмиль Кот
7

Если вы используете графический интерфейс пользователя git (в Windows) в меню «Репозиторий», вы можете использовать «Визуализация истории мастера». Выделите коммит в верхней панели и файл в правом нижнем углу, и вы увидите diff для этого коммита в левом нижнем углу.

кори
источник
Как это отвечает на вопрос?
jmbeck
3
Что ж, OP не указывал командную строку, и, переходя от SourceSafe (который является GUI), казалось уместным указать, что вы можете делать почти то же самое, что вы можете делать в VSS в Git GUI на Windows.
Кори
6

SmartGit :

  1. В меню включите отображение неизмененных файлов: Просмотр / Показать неизмененные файлы
  2. Щелкните правой кнопкой мыши файл и выберите «Журнал» или нажмите «Ctrl-L»
Антонин Слейшка
источник
4

Ответ, который я искал, которого не было в этой теме, - увидеть изменения в файлах, которые я подготовил для фиксации. т.е.

git diff --cached
Malks
источник
1
Если вы хотите включить локальные (немаркированные) изменения, я часто запускаю, git diff origin/masterчтобы показать полные различия между вашей локальной веткой и главной веткой (которую можно обновлять с удаленного компьютера git fetch)
ghayes
4

Если вы используете TortoiseGit, вы сможете щелкнуть правой кнопкой мыши по файлу и сделать TortoiseGit --> Show Log. В появившемся окне убедитесь, что:

  • Show Whole ProjectОпция ' ' не отмечена.

  • All BranchesОпция ' ' отмечена.

user3885927
источник
TortoiseGit (и Eclipse Git также) почему-то пропускает ревизии выбранного файла, не рассчитывайте на это!
Ноам Манос
@ NoamManos, я не сталкивался с этой проблемой, поэтому я не могу проверить правильность вашего утверждения.
user3885927
Моя ошибка, это происходит только в Eclipse, но в TortoiseGit вы можете увидеть все ревизии файла, если снять отметку «показать все проекты» + проверить «все ветви» (в случае, если файл был зафиксирован в другой ветви, прежде чем он был объединен с основной филиал). Я обновлю ваш ответ.
Ноам Манос
3

git diff -U <filename> дать вам унифицированный дифференциал.

Он должен быть окрашен в красный и зеленый. Если это не так, запустите: git config color.ui autoсначала.

Лукаш Червинский
источник
2

Если вы используете eclipse с плагином git, он имеет превосходное представление сравнения с историей. Щелкните правой кнопкой мыши файл и выберите «сравнить с» => «история»

AhHatem
источник
Однако это не позволит вам найти удаленный файл.
Авгвств
Сравнение двух версий файла отличается от просмотра истории изменений файла
golimar
0

Я, вероятно, о том, где был OP, когда это началось, в поисках чего-то простого, что позволило бы мне использовать git difftool с vimdiff для просмотра изменений в файлах в моем репо, начиная с определенного коммита. Я не был слишком доволен ответами, которые нашел, поэтому я собрал этот скрипт git inc remental rep orter (gitincrep), и он мне пригодился:

#!/usr/bin/env bash

STARTWITH="${1:-}"
shift 1

DFILES=( "$@" )

RunDiff()
{
        GIT1=$1
        GIT2=$2
        shift 2

        if [ "$(git diff $GIT1 $GIT2 "$@")" ]
        then
                git log ${GIT1}..${GIT2}
                git difftool --tool=vimdiff $GIT1 $GIT2 "$@"
        fi
}

OLDVERS=""
RUNDIFF=""

for NEWVERS in $(git log --format=format:%h  --reverse)
do
        if [ "$RUNDIFF" ]
        then
                RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
        elif [ "$OLDVERS" ]
        then
                if [ "$NEWVERS" = "${STARTWITH:=${NEWVERS}}" ]
                then
                        RUNDIFF=true
                        RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
                fi
        fi
        OLDVERS=$NEWVERS
done

Вызывается без аргументов, это начнется с начала истории репо, в противном случае оно начнется с любого сокращенного хэша коммита, который вы предоставите, и перейдет к настоящему моменту - вы можете в любое время выйти из ctrl-C. Любые аргументы после первого будут ограничивать отчеты о различиях только теми файлами, которые перечислены среди этих аргументов (что, как мне кажется, и было желательным для ОП, и я бы порекомендовал для всех проектов, кроме небольших). Если вы проверяете изменения в определенных файлах и хотите начать с самого начала, вам нужно предоставить пустую строку для arg1. Если вы не являетесь пользователем vim, вы можете заменить vimdiff своим любимым инструментом diff.

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

Этот подход, вероятно, довольно наивный, но, просматривая множество решений здесь и в соответствующей статье, многие из них включали установку новых инструментов в систему, к которой у меня нет доступа администратора, с интерфейсами, которые имели собственную кривую обучения. Вышеупомянутый скрипт сделал то, что я хотел, не имея дело с этим. Я рассмотрю множество отличных предложений, когда мне нужно что-то более сложное, но я думаю, что это напрямую зависит от ОП.

oracleif
источник
0

Я нашел очень простое решение, чтобы быстро найти историю файла.

  1. Произведите случайное изменение в файле
  2. Это покажет как незафиксированные изменения на вашем исходном дереве
  3. Щелкните правой кнопкой мыши файл и выберите «Журнал выбран»

введите описание изображения здесь

Было бы показать историю всех коммитов.

savvyBrar
источник
Откуда этот GUI?
Колидир
Sourcetree UI. Спасибо
savvyBrar