Перегляньте історію змін файлу за допомогою версії Git


3088

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

Я досяг:

git log -- [filename]

яка показує мені історію фіксації файлу, але як я можу отримати вміст кожного з змін файлу?

Я намагаюся зробити перехід від MS SourceSafe, який раніше був простим right-clickshow history.


41
Наведене вище посилання вже не дійсне. Це посилання працює сьогодні: Git Community Book
chris

1
Посилання вище (розміщене Крісом) більше не дійсне. Це посилання працює сьогодні: git-scm.com/book/uk/v2
Cog

Відповіді:


2370

Для цього я б використав:

gitk [filename]

або слідкувати за попередніми іменами файлів

gitk --follow [filename]

28
Але у мене навіть є інструмент, який поєднав вищезгадане із "git blatu", що дозволяє мені переглядати джерело файлу, коли він змінюється в часі ...
Egon Willighagen

26
На жаль, це не відповідає історії попередніх перейменовань файлу.
Дан Ліплення

146
Я також шукав історію файлів, які раніше були перейменовані, і знайшов цю тему спочатку. Рішення полягає у використанні "git log - follow <ім'я файлу>", як тут зазначив Філ .
Флоріан Гутманн

115
Автор шукав інструмент командного рядка. Хоча gitk постачається з GIT, це не додаток командного рядка, ані особливо хороший графічний інтерфейс.
mikemaccana

72
Він шукав інструмент командного рядка? "клацнути правою кнопкою миші -> показати історію", безумовно, це не означає.
hdgarrood

2234

Можна використовувати

git log -p filename

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

Подивитися

git help log

для додаткових варіантів - це насправді може зробити багато приємних речей :) Отримати різницю для конкретного зобов’язання ви можете

git show HEAD 

або будь-яка інша редакція за ідентифікатором. Або використовувати

gitk

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


8
git show HEAD показує всі файли, чи знаєте ви, як відстежувати окремий файл (як просив Річард)?
Jonas Byström

5
ви використовуєте: git show <revision> - ім'я файлу, яке буде показувати відмінності для цієї версії, якщо вона існує.
Маркос Олівейра

4
--stat також корисний. Ви можете використовувати його разом з -p.
Раффі Хатчадурян

5
Це чудово. gitk не веде себе добре, коли вказує шляхи, які вже не існують. Я використовував git log -p - path.
Пауло Касаретто

6
Плюс гітк виглядає так, що його збудувало монстр Бугі. Це чудова відповідь і найкраще підходить до оригінального питання.
ghayes

1495

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це має значення лише в тому випадку, якщо у вас є назва шляху, який починається з тире . Скажіть, ви хотіли дізнатися історію файлу, який має нещасне ім’я "- наступний":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 install tig
  • Домашня мова (OS X) :$ brew install tig

Використовуйте його для перегляду історії в одному файлі: tig [filename]
Або перегляньте детальну історію репо:tig

Схожий на gitkтекст, але на основі тексту. Підтримує кольори в терміналі!


23
Відмінний текстовий інструмент, чудова відповідь. Я злякався, коли побачив залежності від встановлення gitk на моєму безголовому сервері. Знову підтримає A +++
Том Маккензі

Ви також можете подивитися на певні файли з tig -- path/to/specific/file
тигом

109

git whatchanged -p filenameтакож еквівалентно git log -p filenameв цьому випадку.

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


4
+1, але filenameв команді не є обов'язковимgit blame filename .
rockXrock

7
"Новим користувачам рекомендується замість цього використовувати git-log. (...) Команда зберігається в основному з історичних причин;"
ciastek

104

Користувачі SourceTree

Якщо ви використовуєте SourceTree для візуалізації вашого сховища (він безкоштовний і досить непоганий), ви можете клацнути правою кнопкою миші файл і вибрати журнал вибрано

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

Дисплей (внизу) набагато привітніший ніж gitk та більшість інших перерахованих варіантів. На жаль (на даний момент) немає простого способу запустити цей вид з командного рядка - CLI SourceTree в даний час просто відкриває репост.

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


1
Особливо мені подобається опція "Дотримуватися перейменованих файлів", яка дозволяє вам побачити, чи файл перейменований чи переміщений.
Кріс

але якщо я не помиляюсь (будь ласка, дайте мені знати!), можна порівнювати одночасно дві версії в gui? Чи є клієнти, які мають елегантний інтерфейс для розробки декількох різних версій одночасно? Можливо, із поданням масштабу, як у Sublime Text? Думаю, це було б дуже корисно.
Сем Леваллен

@SamLewallen Якщо я правильно зрозумів, ви хочете порівняти три різні коміти? Це схоже на тристороннє злиття (моє, ваше, базове) - зазвичай ця стратегія використовується для вирішення конфліктів злиття, не обов'язково порівнюючи три довільні коміти. Існує багато інструментів, які підтримують тристоронній злиття stackoverflow.com/questions/10998728/…, але хитрість полягає в подачі цих інструментів конкретними версіями gitready.com/intermediate/2009/02/27/…
Марк Фокс

Дякую Марку Фоксу, саме так я і маю на увазі. Чи трапляється вам знати про будь-які програми, які це роблять?
Сем Леваллен

1
@ MarnenLaibow-Koser Я не можу пригадати, для чого мені потрібен SHA в той час. Ахаха.
AechoLiu

63

Щоб показати, яка редакція та автор востаннє змінили кожен рядок файлу:

git blame filename

або якщо ви хочете використовувати GUI з потужною виною:

git gui blame filename

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 команда встановлення цих чудових інструментів як очікується:

sudo apt-get install gitk tig

І я зараз використовую:

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

так що я можу просто набрати, gdf dirщоб отримати сфокусовану історію всього в підкаталозі dir.


2
Я думаю, що це чудова відповідь. Можливо, ви також не отримуєте голосування, тому що ви відповідаєте на інші способи (краще IMHO), щоб побачити зміни, тобто за допомогою gitk та tig на додаток до git.
PopcornKing

Просто для додання відповіді. Знайдіть шлях (у git space, до якого все ще існує сховище). Потім скористайтеся командою, зазначеною вище, "git log --follow --all -p <folder_path / file_path>". Може статися так, що filde / папка була б видалена за всю історію, отже знайдіть максимальний шлях, який існує досі, і спробуйте отримати її історію. працює!
парасити

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. Насолоджуйтесь.


Після того, як я запустив цю ярликову ярлик, я сказав (і цитую) "Красиво!". Однак зауважте, що "\ n" після "--graph" є помилкою.
jmbeck

3
Також можна використовувати git lg -p filename- він повертає гарний розріз шуканого файлу.
Егель

22

Останнім часом я виявив tig і знайшов це дуже корисним. Я б хотів, щоб це було A або B, але більшість часу це досить акуратно.

У вашому випадку tig <filename>може бути те, що ви шукаєте.

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


on centos yum install tig
zzapper

17

Ви можете використовувати vscode з GitLens , це дуже потужний інструмент. Після встановлення GitLens перейдіть на вкладку GitLens, виберіть, FILE HISTORYі ви можете переглядати її.

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


15

Я написав git-відтворення саме для цієї мети

pip install git-playback
git playback [filename]

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



9

Якщо ви хочете переглянути всю історію файлу, в тому числі і для всіх інших гілок, використовуйте:

gitk --all <filename>

9

Ви також можете спробувати це, у якому перераховано коміти, які змінили певну частину файлу (реалізовано в Git 1.8.4).

Результатом повернення буде список комітетів, які змінили цю конкретну частину. Команда:

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

де upperLimit - це початковий_лінійний номер, а нижнійLimit - кінцевий_лінійний номер файлу.

Детальніше на https://www.techpurohit.com/list-some-useful-git-commands


7

З відмінним розширенням Git ви переходите до пункту історії, де файл все ще існував (якщо він був видалений, інакше просто перейдіть до HEAD), переходите на File treeвкладку, клацніть правою кнопкою миші на файлі та вибираєте File history.

За замовчуванням слід за файлом через перейменування та Blame вкладка дозволяє побачити ім'я в заданій редакції.

У неї є деякі незначні добутки, як-от показ fatal: Not a valid object nameна Viewвкладці при натисканні на редакцію видалення, але я можу з цим жити. :-)


Варто зазначити, що це лише Windows.
Еван Хан

3
@EvanHahn не точний, через моно можна використовувати GitExtension також на Linux, ми використовуємо його на ubuntu і дуже щасливий з ним. дивись git-extensions-documentation.readthedocs.org/en/latest/…
The Cat

7

Якщо ви використовуєте графічний інтерфейс git (у Windows) у меню репозиторію, ви можете скористатись "Візуалізація історії майстра". Виділіть фіксацію у верхній панелі та файл у нижній правій частині, і ви побачите різницю для цього коміту в нижній лівій частині.


Як це відповідає на питання?
jmbeck

3
Ну, OP не вказав командний рядок, і, переходячи від SourceSafe (який є графічним інтерфейсом), здавалося, що це актуально, щоб зазначити, що ви можете зробити майже те ж саме, що ви можете зробити в VSS в Git GUI в Windows.
cori

6

SmartGit :

  1. У меню включити відображення незмінних файлів: Переглянути / Показати незмінні файли
  2. Клацніть правою кнопкою миші файл і виберіть "Журнал" або натисніть "Ctrl-L"

4

Відповідь, яку я шукав, що не була в цій темі, - це побачити зміни у файлах, які я влаштував для введення. тобто

git diff --cached

1
Якщо ви хочете включити локальні (нестандартні) зміни, я часто біжу, git diff origin/masterщоб показати повну різницю між вашою локальною філією та git fetch
основною

4

Якщо ви використовуєте TortoiseGit, ви повинні мати правою кнопкою миші на файл і робити TortoiseGit --> Show Log. У вікні, що спливе, переконайтесь:

  • Show Whole ProjectПараметр ' ' не перевіряється.

  • ' All Branches' варіант встановлений.


TortoiseGit (а також Eclipse Git) якось пропускає редакції вибраного файлу, не розраховуйте на нього!
Ноам Манос

@NoamManos, я не стикався з цією проблемою, тому не можу перевірити, чи правильно є ваше твердження.
користувач3885927

Моя помилка, це відбувається лише в Eclipse, але в TortoiseGit ви можете побачити всі версії файлу, якщо зніміть прапорець "показати весь проект" + перевірити "всі гілки" (у випадку, якщо файл був зроблений на іншій гілці, до того як він був об'єднаний в основний відділення). Я оновлю вашу відповідь.
Ноам Манос

3

git diff -U <filename> дамо вам єдину розл.

Він повинен бути кольоровим на червоний і зелений. Якщо ні, запустіть: git config color.ui autoспочатку.


2

Якщо ви використовуєте eclipse з плагіном git, він має чудовий вигляд порівняння з історією. Клацніть правою кнопкою миші файл і виберіть "порівняти з" => "історія"


Це не дозволить вам знайти видалений файл.
avgvstvs

Порівняння двох версій файлу відрізняється від перегляду історії змін файлу
golimar

0

Я, мабуть, про те, де був ОП, коли це починалося, шукаючи щось просте, яке дозволило б мені використовувати git difftool з vimdiff для перегляду змін у файлах мого репо, починаючи з конкретної комісії. Я був не дуже задоволений відповідями я знаходять, так що я кинув цей мерзотник вкл remental представника 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 поведінка , але воно працює тут).

Такий підхід, мабуть, досить наївний, але, переглядаючи безліч рішень тут і на пов'язаній посаді, багато хто брав участь у встановленні нових інструментів у системі, де я не маю доступу адміністратора, з інтерфейсами, які мали власну криву навчання. Вищеописаний сценарій робив те, що я хотів, не маючи справу ні з чим. Я перегляну тут безліч чудових пропозицій, коли мені потрібно щось більш витончене - але я думаю, що це безпосередньо відповідає ОП.


0

Я знайшов дуже просте рішення, щоб швидко знайти історію файлу.

  1. Зробіть випадкову зміну у файлі
  2. Він відображатиметься як непомітні зміни на вашому вихідному дереві
  3. Клацніть правою кнопкою миші на файл та виберіть "Журнал вибраний"

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

Це показало б історію всіх комітетів.


Звідки цей графічний інтерфейс?
colidyre

Користувацький інтерфейс Sourcetree. Спасибі
savvyBrar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.