Я работаю в операционной системе «Windows 10». Использую программу «Git» (дистрибутив «Git for Windows») версии 2.35.1 (и программу-оболочку «Git Bash» из ее дистрибутива). С программой «Git», которая является системой управления версиями, обычно работаю из командной строки с помощью программы-оболочки «PowerShell» версии 7, запускаемой из программы-«эмулятора терминала» «Windows Terminal» версии 1.16.
Разные способы организации работы над проектом
Погружаясь в мир совместной разработки программ, я узнал, как выполнять вклад в проект, работая с удалёнными репозиториями (по-английски «remote repository» или просто «remote»), которые могут находиться на других компьютерах в компьютерной сети, в том числе — в интернете. При этом для отправки вклада в проект, файлы которого хранятся в удалённом репозитории (хранилище), в программе «Git» используется команда «git push», для применения которой требуется обладать правом записи в удалённый репозиторий.
На сайте «GitHub» я познакомился с другим способом отправки вклада в проект: с помощью создания «форка» (копии исходного репозитория проекта; это слово является калькой с английского «fork») под своей учетной записью, внесения в форк изменений и последующей отправки запроса на принятие изменений (по-английски «pull request», сокращенно «PR») в исходный репозиторий. При этом не требуется обладать правом записи в исходный репозиторий. Получается, что вы передаете предлагаемые вами изменения в проект (вклад) на рассмотрение людям, которые имеют право записи в исходный репозиторий. Они рассмотрят ваш запрос на принятие изменений и, возможно, примут его (выполнят слияние ваших изменений с исходным проектом), если изменение будет признано ими полезным и не будет содержать ошибок. То есть в данном случае мы действуем через посредника.
Только после этого я узнал про существование «патчей» (файлов с вашими изменениями в проект). Сразу мне было непонятно, зачем нужны эти патчи, если существуют вышеописанные способы внесения вклада в проект. Как оказалось, существует еще множество других способов организации работы над проектом, в том числе способ с помощью патчей. При этом способе вы получаете копию файлов проекта из исходного репозитория, вносите в них свои изменения, формируете файл (патч) с изменениями и передаете этот файл каким-либо способом (загрузив патч на сайт проекта, переслав его по электронной почте или еще как-либо) людям, у которых есть право записи в исходный репозиторий.
Таким образом, способ работы над проектом с помощью патчей немного похож на вышеописанный способ работы с помощью запросов на принятие изменений на сайте «GitHub»: здесь тоже работа идет через посредника, который рассмотрит ваш патч и, возможно, сделает его слияние с файлами проекта в исходном репозитории.
Откуда взялось слово «патч», инструменты «diff» и «patch»
Вообще, способ работы над проектом с помощью патчей возник намного раньше, чем появилась программа «Git» (2005 год). Да, в общем-то, и намного раньше, чем появились системы управления версиями (начало 1960-х). Слово «патч» — это калька с английского слова «patch», которое дословно означает «заплатка» или «наложить заплатку». Уже в 1940-х годах «патчи» реально могли представлять собой физически существующие заплатки в виде кусочков бумаги, которыми заклеивали некоторые места на бумажных перфолентах или перфокартах, таким образом исправляя ошибки в программах, хранящихся на этих перфолентах и перфокартах.
В Unix-подобных операционных системах существуют команды (программы-инструменты) «diff» и «patch». С помощью инструмента «diff» можно найти разницу между файлами, которую после этого можно выгрузить в отдельный файл. Полученный файл с изменениями тоже называют «diff», а еще этот же файл могут называть «patch», так как его можно передать другим разработчикам, которые применят этот файл с изменениями к своей копии файлов проекта с помощью инструмента «patch», таким образом внеся предлагаемые изменения в проект. Название инструмента «diff» получено сокращением от английского слова «difference» (по-русски «разница»).
Следует иметь в виду, что программа-инструмент «diff» может выдавать разницу между файлами в разных форматах, например, в «контекстном формате» или в «унифицированном формате» (по-английски «unified format» или «unidiff»).
В программе «Git» для получения разницы между файлами, коммитами, версиями проекта используется команда «git diff», после чего полученная разница может быть выгружена в отдельный файл (патч). После передачи файла-патча человеку, имеющему право записи в исходный проект, этот человек может применить полученный файл-патч к файлам исходного проекта с помощью команды «git apply». Насколько я понимаю, при этом используется формат вывода разниц «unidiff» (унифицированный формат).
Работа с патчем в программе «Git» на тестовом проекте
Подготовка тестового проекта
Сначала подготовим тестовый проект, он у меня находится в папке «C:\Users\Илья\source\repos\test\». Проект состоит из одного текстового файла «shalandy.txt», в который записан текст в кодировке UTF-8 с окончаниями строк вида CRLF, как принято в операционных системах «Windows» (окончания строк я буду показывать, хотя в редакторах кода они обычно скрыты):
shalandy.txt (185 байтов, кодировка UTF-8)
Шаланды, полные кефали,CRLF
В Одессу Костя приводил.CRLF
И все биндюжники вставали,CRLF
Когда в пивную он входил.
Шаг 1. Создание пустого Git-репозитория для проекта:
PS C:\Users\Илья\source\repos\test> git init
Initialized empty Git repository in C:/Users/Илья/source/repos/test/.git/
Шаг 2. Проверка настройки режима работы с окончаниями строк для проекта:
PS C:\Users\Илья\source\repos\test> git config core.autocrlf
true
Про эту настройку у меня есть отдельная статья, там же показано на примере, как ее можно изменить. У меня для этой настройки прописано значение true
на уровне текущего пользователя (global) операционной системы, поэтому нет необходимости задавать ей значение отдельно на уровне проекта. Напомню, при этой настройке со значением true
предполагается, что в рабочей папке в файлах мы имеем дело с окончаниями строк вида CRLF, а в Git-репозитории версии файлов хранятся с окончаниями строк вида LF.
Шаг 3. Добавление исходной версии файла «shalandy.txt» в индекс (stage):
PS C:\Users\Илья\source\repos\test> git add "shalandy.txt"
Для демонстрации создания файла-патча нам достаточно помещения версии файла «shalandy.txt» в индекс (далее в статье будет показано и помещение версии файла в коммит). Команда «git diff» может быть использована как для получения разницы между версией файла в индексе и версией файла в рабочей папке, так и для получения разницы между версией файла в определенном коммите и версией файла в рабочей папке (а также для многих других разных сравнений).
Шаг 4. Внесение изменений в файл «shalandy.txt» (то есть создание его новой версии) в рабочей папке:
shalandy.txt (217 байтов, кодировка UTF-8)
Шаланды, полные кефали,CRLF
В Одессу Гена приводил.CRLF
И все биндюжники вставали,CRLF
Когда в пивную он входил.CRLF
(поёт Марк Бернес)
Создание файла разниц (файла-патча)
У нас есть две версии файла «shalandy.txt» из тестового проекта. Исходная версия содержится в индексе Git-репозитория, новая версия — в рабочей папке проекта. Разницы между ними можно просмотреть в окне консоли (терминала) с помощью следующей команды:
PS C:\Users\Илья\source\repos\test> git diff
Вот как выглядит результат работы этой команды у меня в программе-оболочке «PowerShell» версии 7, запущенной в программе-«эмуляторе терминала» «Windows Terminal» версии 1.16:
Далее я опишу два сценария получения файла-патча и некоторые тонкости работы программ, на которые при этом стоит обратить внимание. Начнем с более простого сценария, а потом перейдем к более сложному.
Сценарий 1. Получение файла-патча «my.patch» из программы-оболочки «Git Bash», которую я получил в составе дистрибутива «Git for Windows». По умолчанию программа-оболочка «Git Bash» у меня настроена для работы в традиционной для операционных систем «Windows» программе-«эмуляторе терминала» «Windows Console»:
Илья@IlyaComp MINGW64 ~/source/repos/test (master)
$ git diff > my.patch
my.patch (493 байта, кодировка UTF-8)
diff --git a/shalandy.txt b/shalandy.txtLF
index 8591ff8..fd3ff04 100644LF
--- a/shalandy.txtLF
+++ b/shalandy.txtLF
@@ -1,4 +1,5 @@LF
Шаланды, полные кефали,LF
-В Одессу Костя приводил.LF
+В Одессу Гена приводил.LF
И все биндюжники вставали,LF
-Когда в пивную он входил.LF
\ No newline at end of fileLF
+Когда в пивную он входил.LF
+(поёт Марк Бернес)LF
\ No newline at end of fileLF
Следует иметь в виду, что в команде git diff > my.patch
только часть git diff
относится к программе «Git», а часть > my.patch
обрабатывается программой-оболочкой (в данном случае «Git Bash»), из которой запущена эта команда. Символ >
означает перенаправление вывода (в данном случае вывод команды git diff
вместо окна консоли отправляется в указанный файл). В разных программах-оболочках часть > my.patch
команды может быть обработана по-разному, из-за чего файл «my.patch» может быть сформирован с ошибками (это будет показано далее).
В вышеприведенном блоке кода видно, что в полученном файле-патче созданы окончания строк вида LF. Следует иметь в виду, что программа «Git» в данном случае возвращает строки исходной версии файла «shalandy.txt» в том виде, в котором они хранятся в Git-репозитории. Если в Git-репозиторий случайно попадут строки с окончаниями вида, к примеру, CRLF, то в файл «my.patch» они будут выгружены тоже с окончаниями вида CRLF.
Сценарий 2. Получение файла-патча «my.patch» из программы-оболочки «PowerShell» версии 7, запущенной в программе-«эмуляторе терминала» «Windows Terminal» версии 1.16.
Сначала следует проверить значения некоторых настроек:
PS C:\Users\Илья\source\repos\test> (Get-WinSystemLocale).Name
ru-RU
PS C:\Users\Илья\source\repos\test> ([System.Console]::OutputEncoding).CodePage
866
PS C:\Users\Илья\source\repos\test> $OutputEncoding.CodePage
65001
Выше, на иллюстрации 1, было показано, что вывод команды git diff
, запущенной из программы-оболочки «PowerShell», в окно терминала у меня происходит без проблем с настройками по умолчанию. Перенаправление вывода этой команды в файл происходит по-другому, русские буквы трансформируются в кракозябры (по-английски «mojibake»).
Это происходит потому, что при перенаправлении вывода в файл в вышеописанном сценарии в процесс вмешивается объект класса System.Console
, в свойстве которого OutputEncoding
у меня по умолчанию записан объект, представляющий кодировку «CP866» (устаревшая 8-битная кодировка, входящая в группу устаревших кодировок «OEM» операционных систем «Windows»). Значение по умолчанию для свойства OutputEncoding
объекта класса System.Console
зависит от языка системы (по-английски «system locale»; не путать с «языком интерфейса», по-английски «display language» или «interface language»). Для языка системы «ru-RU» («Русский (Россия)») кодировкой по умолчанию в группе кодировок «OEM» является кодировка (кодовая страница) «CP866», так как в нее включен русский алфавит.
Текущее значение языка системы я получил в блоке кода выше с помощью командлета Get-WinSystemLocale
.
Свойство OutputEncoding
объекта класса System.Console
не следует путать с предопределенной переменной $OutputEncoding
, это разные вещи. Как видно из блока кода выше, по умолчанию в программе-оболочке «PowerShell» версии 7 эта переменная содержит объект, представляющий кодировку UTF-8 (кодовая страница 65001).
В результате настроек по умолчанию, показанных в блоке кода выше, при применении команды git diff > my.patch
байты текста в кодировке UTF-8 сначала интерпретируются побайтно по кодовой странице «CP866», а затем полученные символы конвертируются в байты по правилам кодировки UTF-8. Вот как это происходит на примере буквы «Ш» слова «Шаланды» (кому интересно, у меня есть более подробный разбор):
D0 A8 -----------------> D0 A8 --------------> ╨ и
Ш интерпретация ╨ и конвертация E2 95 A8 D0 B8
UTF-8 как CP866 в UTF-8
Как видно из блока кода выше, мало того, что в результате получаются кракозябры, так еще размер полученного текста в байтах может вырасти в 2-3 раза (в примере выше из двух изначальных байт D0 A8
получено пять байт E2 95 A8 D0 B8
). Понятно, что всё это не касается символов из таблицы ASCII (в том числе символов латиницы), так как эти символы в кодировках «CP866» и «UTF-8» отображаются одинаково (одними и теми же кодами, и занимают по одному байту).
Конечно, результат можно конвертировать обратно. Например, в редакторе «VS Code» есть нужные для этого инструменты. Но правильнее будет перед выгрузкой файла-патча просто изменить соответствующую настройку:
PS C:\> [System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8
PS C:\> ([System.Console]::OutputEncoding).CodePage
65001
PS C:\Users\Илья\source\repos\test> git diff > my.patch
Теперь команда git diff > my.patch
создаст файл «my.patch» в корректном, то есть читаемом, виде, в кодировке UTF-8, размером 507 байтов. От файла, полученного при сценарии 1, который имел размер в 493 байта, файл, полученный при сценарии 2, отличается только видом окончаний строк. При первом сценарии окончания строк были вида LF, при втором сценарии получились окончания строк вида CRLF (отсюда разница в 14 байтов, так как в файле-патче содержится 14 строк).
Следует иметь в виду, что в программе-оболочке «PowerShell» перенаправление вывода >
делает то же самое, что и передача вывода по конвейеру |
командлету Out-File
(с указанием пути к файлу-результату, но без дополнительных параметров).
В отличие от команды git diff > my.patch
в первом сценарии, в данном случае строки от команды git diff
передаются на конвейер |
в виде 14 объектов (как уже было сказано выше, в файле-патче получилось 14 строк) класса System.String
. Однако, эти строки-объекты не содержат окончаний строк, это касается и тех строк, которые получены из Git-репозитория (это поведение отличается от описанного в сценарии 1). Программа-оболочка «PowerShell» версии 7 записывает полученные строки в файл с окончаниями вида CRLF.
Что делать, если мы хотим получить в этом сценарии файл-патч с окончаниями строк вида LF? Способ попроще: открыть полученный файл в редакторе кода и преобразовать окончания строк в окончания нужного вида. Инструменты для этого есть, например, в редакторе «Notepad++». Способ посложнее, из командной строки: вместо команды git diff > my.patch
в блоке кода выше можно ввести, к примеру, такую команду:
PS C:\Users\Илья\source\repos\test> git diff |
>> Join-String -Separator "`n" -OutputSuffix "`n" |
>> Out-File -FilePath "my.patch" -NoNewline
Суть тут в том, что мы получаем от команды git diff
14 объектов-строк, склеиваем их в один объект-строку с помощью командлета Join-String
, вставляя между ними (параметр -Separator
) символ LF и в конце (параметр -OutputSuffix
) символ LF. После этого передаем полученный один объект-строку командлету Out-File
, запрещая ему с помощью параметра -NoNewline
вставку умолчательного окончания строки CRLF после нашего одного итогового объекта-строки (у меня есть подробный разбор этой команды).
Применение файла-патча с помощью команды «git apply»
Думаю, понятно, что применять созданный нами файл-патч будут другие люди на их копии нашего проекта (или на оригинале проекта, если наш проект является копией оригинала). Чтобы смоделировать эту ситуацию, создадим копию нашего проекта, на которой будем пытаться применить файл-патч. Вернее, мы будем создавать копию Git-репозитория с помощью команды «git clone».
Ранее, в рамках подготовки тестового проекта, я создал Git-репозиторий, но ничего в него не поместил, поэтому Git-репозиторий пока что остался пустым. Я поместил только исходную версию файла «shalandy.txt» в индекс, а в рабочей папке создал измененную версию исходного файла «shalandy.txt», после чего из разниц между этими версиями с помощью команды «git diff» создал файл-патч «my.patch». Напомню, индекс — это отдельный служебный файл, он не входит в состав базы данных «Git», поэтому Git-репозиторий всё еще считается пустым.
Шаг 5. Поместим в базу данных «Git» первый коммит, сформировав его из содержимого индекса:
PS C:\Users\Илья\source\repos\test> git commit -m "Первый коммит"
[master (root-commit) 3834f65] Первый коммит
1 file changed, 4 insertions(+)
create mode 100644 shalandy.txt
Шаг 6. Создание копии (клона) исходного Git-репозитория:
PS C:\Users\Илья\source\repos\test> cd ..
PS C:\Users\Илья\source\repos> git clone test test2
Cloning into 'test2'...
done.
Команда cd
в программе-оболочке «PowerShell» — это псевдоним (alias) командлета «Set-Location». А вообще это известная команда в разных операционных системах. Параметр ..
означает родительскую папку для текущей папки. То есть команда cd ..
выполняет переход на ближайший верхний уровень от текущего местоположения в дереве папок. В результате мы перешли в местоположение «C:\Users\Илья\source\repos\».
Этот переход не обязателен для применения команды «git clone», но он делает ввод параметров для этой команды более удобным: после перехода нам достаточно набрать название исходной папки (наш проект) и название новой папки (новый проект, копия нашего), без набора полного пути к этим папкам. (Вообще, команду «git clone» можно применить несколькими способами, об этом можно прочитать в документации.)
Итак, первый параметр test
команды «git clone» в данном случае — название исходной папки нашего проекта. Папки test2
до ввода вышеприведенной команды «git clone» в местоположении «C:\Users\Илья\source\repos\» у меня не существовало. Команда «git clone» у меня создала папку с таким названием, после чего создала внутри вложенную папку «.git» (скрытую) и скопировала в нее базу данных «Git» моего оригинального проекта «test».
Если бы в данном случае папка «test2» (папка назначения) существовала бы в указанном местоположении, команда «git clone» выполнила бы клонирование, если б папка «test2» была бы пуста. Иначе, если бы в папке «test2» были бы какие-то файлы, то команда «git clone» не выполнила бы клонирование и выдала бы соответствующее предупреждающее сообщение.
После того, как команда «git clone» у меня успешно отработала и создала новую папку «test2» с вложенной в нее скрытой папкой «.git» (скопированная из оригинального проекта база данных «Git»), в рабочей папке «test2» появился и файл «shalandy.txt». Тут следует понимать, что этот файл не был скопирован из рабочей папки оригинального проекта «test», а был восстановлен из коммита в скопированной базе данных «Git». Таким образом, эта версия файла «shalandy.txt» — это первоначальная версия этого файла из оригинального проекта. То есть на данный момент файлы «shalandy.txt» в папке «test» и в папке «test2» отличаются друг от друга на разницу в файле-патче «my.patch», полученном в предыдущих постах. Всё готово для тестирования применения файла-патча с помощью команды «git apply».
Шаг 7. Применение файла-патча «my.patch» к файлу «shalandy.txt» в папке «test2»:
PS C:\Users\Илья\source\repos> cd test2
PS C:\Users\Илья\source\repos\test2> git apply "..\test\my.patch"
Первая команда из двух в блоке кода выше была уже объяснена ранее. Здесь мы с помощью этой команды cd test2
переходим в только что созданную папку с копией (клоном) нашего исходного проекта (вернее, с копией Git-репозитория нашего исходного проекта). Это нужно потому, что команда «git apply» применяет указанный файл-патч к текущей рабочей папке, так что в эту папку сначала следует перейти.
Далее запускаем команду «git apply», которая и применяет файл-патч к файлам в текущей рабочей папке текущего проекта. В данном случае я указал относительный путь "..\test\my.patch"
, который означает, что файл-патч «my.patch» находится в соседней для папки «test2» папке «test» (в рабочей папке исходного проекта).
В итоге у меня команда «git apply» выполнилась успешно, то есть исходная версия файла «shalandy.txt» в рабочей папке проекта «test2» преобразовалась в измененную версию (217 байтов, кодировка UTF-8, окончания строк вида CRLF).
Важно отметить, что всё работает успешно, если в файле-патче «my.patch» окончания строк вида LF. Если там окончания строк вида CRLF, то у меня выдаются сообщения об ошибке следующего вида:
PS C:\Users\Илья\source\repos\test2> git apply "..\test\my.patch"
error: patch failed: shalandy.txt:1
error: shalandy.txt: patch does not apply
В итоге всё это работает не слишком интуитивно: в файле-патче окончания строк вида LF, а в файле, к которому применяется файл-патч, окончания строк оказываются вида CRLF.
Работа с патчем на примере веб-приложения «WordPress»
Существует такое довольно известное веб-приложение «WordPress», которое представляет собой систему управления содержимым сайта. Это проект с открытым исходным кодом. Вы можете внести вклад в код этого проекта разными способами, в частности, предложив файл-патч. Вообще, исходный код веб-приложения «WordPress» находится под управлением программы (системы управления версиями) «Subversion» или сокращенно «SVN», но эта программа принимает патчи, сформированные и из программы «Git».
В принципе, когда разработчик хочет поработать с исходным кодом какого-либо проекта, находящегося под управлением программы «Git», он клонирует Git-репозиторий этого проекта к себе на компьютер и дальше уже работает с этим клоном (существуют зеркала репозитория с исходным кодом для программы «Git»). Но мне удобнее показать создание файла-патча на уже развернутом у меня локально экземпляре веб-приложения «WordPress».
Я установил это веб-приложение (дистрибутив можно загрузить с сайта проекта) к себе на компьютер в папку «C:\inetpub\wwwroot\wp\» (эта папка будет корневой папкой нашего проекта). Я решил предложить небольшое изменение в код одного из файлов проекта: «wp-includes\class-requests.php» (путь к файлу указан относительно корневой папки проекта).
Шаг 1. Создание пустого Git-репозитория для проекта:
PS C:\inetpub\wwwroot\wp> git init
Initialized empty Git repository in C:/inetpub/wwwroot/wp/.git/
Шаг 2. Настройка режима работы с окончаниями строк для проекта:
PS C:\inetpub\wwwroot\wp> git config core.autocrlf
true
PS C:\inetpub\wwwroot\wp> git config --local core.autocrlf input
PS C:\inetpub\wwwroot\wp> git config core.autocrlf
input
Из блока кода выше видно, что я переключил настройку «core.autocrlf» для проекта со значения «true» на значение «input». Этот шаг делать не обязательно. Дело в том, что файлы веб-приложения «WordPress» из его дистрибутива написаны с окончаниями строк вида LF. Настройкой «core.autocrlf=input» я хочу сохранить окончания строк в файлах проекта (в рабочей папке) в исходном виде при извлечении (checkout) версий файлов из Git-репозитория. При настройке «core.autocrlf=true» исходные окончания строк в файлах проекта (в рабочей папке) будут в такой ситуации затерты окончаниями строк вида CRLF.
Шаг 3. Запишем оригинальную версию файла «wp-includes\class-requests.php» в индекс:
PS C:\inetpub\wwwroot\wp> git add "wp-includes\class-requests.php"
Шаг 4. Внесем изменение в файл «wp-includes\class-requests.php» в рабочей папке проекта. Суть изменения в рамках данной статьи неважна, но кому интересно, можно прочитать подробный разбор по следующей ссылке.
Шаг 5. Создание файла-патча из программы-оболочки «Git Bash» и помещение этого файла на рабочий стол (кавычки, обособляющие путь к файлу-результату, в данном случае обязательны):
Илья@IlyaComp MINGW64 /c/inetpub/wwwroot/wp (master)
$ git diff > "C:\Users\Илья\Desktop\57325.diff"
После этого на моем рабочем столе появился файл-патч «57325.diff» размером 444 байта в кодировке UTF-8 с окончаниями строк вида LF. В проекте «WordPress» принимают файлы-патчи с расширением либо «.diff», либо «.patch».
Предварительно вы должны создать в системе управления проектом (это можно сделать через сайт wordpress.org проекта, для этого требуется регистрация на сайте) сообщение об ошибке (по-английски его называют «ticket») с подробным описанием ошибки. После чего к этому сообщению об ошибке можно приложить файл-патч с предлагаемым исправлением ошибки. Название файла-патча должно совпадать с номером сообщения об ошибке. То есть в моем случае я приложу полученный выше файл-патч «57325.diff» к предварительно созданному сообщению об ошибке с номером 57325.
Вот что у меня получилось в результате в системе управления проектом «WordPress» на сайте wordpress.org:
-
Сообщение об ошибке (ticket) номер 57325;
-
Файл-патч, приложенный к сообщению об ошибке номер 57325.
-
-p
-
-u
-
--patch
-
Сгенерировать патч (см. Создание патчей с помощью -p).
Это действие по умолчанию. -
-s
-
--no-patch
-
Подавлять весь вывод от утилиты сравнения (включая в частности собственно список изменений). Полезно для команд, вроде
git show
, чтобы подавить вывод патча, который иначе показывается по умолчанию; или чтобы отменить эффект таких параметров, как--patch
, или--stat
, указанных ранее в командной строке (например для команды сокращения (alias)). -
-U<n>
-
--unified=<n>
-
Генерировать списки изменений с <n> строками контекста вместо обычных трёх.
Подразумевает--patch
. -
--output=<файл>
-
Выводить в указанный файл вместо стандартного вывода.
-
--output-indicator-new=<символ>
-
--output-indicator-old=<символ>
-
--output-indicator-context=<символ>
-
Задаёт символ, используемый для обозначения новых, старых или контекстных строк в сгенерированном патче. Обычно это
+
,-
и ` ` соответственно. -
--raw
-
Сгенерировать список изменений в сыром формате.
-
--patch-with-raw
-
Синоним для
-p --raw
. -
--indent-heuristic
-
Применять эвристику, которая сдвигает границы блоков списков изменений, дабы сделать патчи более удобными для чтения. Это поведение включено по умолчанию.
-
--no-indent-heuristic
-
Не применять эвристику сдвига границ блоков.
-
--minimal
-
Потратить дополнительное время, чтобы гарантировать, что будет сгенерирован минимально возможный список изменений.
-
--patience
-
Генерировать списки изменений с помощью «терпеливого» алгоритма (patience diff).
-
--histogram
-
Генерировать списки изменений с помощью «гистограммного» алгоритма (histogram diff).
-
--anchored=<текст>
-
Генерировать списки изменений с помощью алгоритма поиска различий «с якорем» (anchored diff).
Этот параметр может быть указана несколько раз.
Если строка существует как в источнике, так и в назначении, встречается только один раз и начинается с <текста>, этот алгоритм пытается не допустить, чтобы эта строка была обозначена в выводе как удаляемая или добавляемая. Для собственно поиска отличий используется «терпеливый» алгоритм.
-
--diff-algorithm=(patience|minimal|histogram|myers)
-
Выберите алгоритм для получения списка изменений. Доступны следующие варианты:
-
default
-
myers
-
Базовый жадный алгоритм, используемый в стандартной утилите сравнения (
diff
). В настоящее время это значение по умолчанию. -
minimal
-
Потратить дополнительное время, чтобы гарантировать, что будет сгенерирован минимально возможный список изменений.
-
patience
-
Используйте «терпеливый» алгоритм сравнения (patience diff) для генерации патчей.
-
histogram
-
Этот алгоритм расширяет «терпеливый» алгоритм так, что он «поддерживает общие элементы с низкой частотой встречаемости».
В частности, если вы настроили переменную
diff.algorithm
на нестандартное значение и хотите использовать стандартный алгоритм, то следует задать параметр--diff-algorithm=default
. -
-
--stat[=<ширина>[,<ширина-имени>[,<число>]]]
-
Генерировать статистику изменений diffstat. По умолчанию для имени файла используется столько места, сколько необходимо, а остаток — для графика. Максимальная <ширина> по умолчанию равна ширине терминала или 80 столбцам, если вывод производится не на терминал. Ширину части, отводящейся под имя файла, можно ограничить, указав <ширину-имени> после запятой или установив переменную конфигурации
diff.statNameWidth=<ширина-имени>
. Ширина части, отводящейся под график также можно ограничить с помощью--stat-graph-width=<ширина-графика>
или переменной конфигурацииdiff.statGraphWidth=<ширина-графика>
. Все команды, генерирующие статистические графики принимают параметры--stat
или--stat-graph-width
, а установка переменныхdiff.statNameWidth
илиdiff.statGraphWidth
влияет на все команды кромеgit format-patch
. При указании третьей части аргумента вывод ограничивается указанным <числом> строк, а при его превышении вместо оставшихся строк будет выведено...
.Эти параметры также могут быть установлены в индивидуальном порядке с помощью
--stat-width=<ширина>
,--stat-name-width=<ширина-имени>
и--stat-count=<число>
. -
--compact-summary
-
Выводить в статистике diffstat краткую выжимку информации, содержащейся в расширенном заголовке, в частности, был ли файл создан или удалён («new» или «gone», и возможно с «
+l
», если это символическая ссылка) и был ли изменён режим доступа к нему (+x
или-x
для добавления или удаления исполняемого бита соответственно). Эта информация помещается между имени файла и графиком. Подразумевает--stat
. -
--numstat
-
Аналогичен
--stat
, но показывает количество добавленных и удалённых строк в десятичном формате и полный путь к файлу без сокращения, что делает его более удобным для машинной обработки. Для бинарных файлов выводит две чёрточки-
вместо0 0
. -
--shortstat
-
Выводить только последнюю строку, выводимую
--stat
, содержащую общее количество изменённых файлов, а также количество добавленных и удалённых строк. -
-X [<аргумент>,...]
-
--dirstat[=<аргумент>,...]
-
Вывести распределение относительного количества изменений для каждого подкаталога (т.е. какой процент от общего числа изменений приходится на каждый конкретный каталог). Поведение
--dirstat
можно модифицировать, передавая ему список аргументов, разделённых запятыми. Аргументы по умолчанию контролируются переменной конфигурации diff.dirstat (см. git-config[1]). Доступные аргументы:-
changes
-
Подсчитывать количество строк, которые были удалены или добавлены. Этот алгоритм игнорирует чистые перемещения кода внутри файла. Другими словами, строки перемещённые внутри файла без изменений не учитываются в отличии от других правок. Это поведение по умолчанию, когда аргумент не указан.
-
lines
-
Подсчитывает количество строк с использованием обычного алгоритма поиска изменений, основываясь на строках и суммируя количество удалённых/добавленных строк. (Для бинарных файлов подсчитываются 64-байтовые блоки, так как у них нет естественного понятия «строк»). Это более затратный алгоритм работы
--dirstat
, чемchanges
, но он учитывает переставленные строки внутри файла так же, как и другие изменения. Вывод с этим алгоритмом лучше согласуется с теми данными, которые вы получаете от других параметров--*stat
. -
files
-
Подсчитывает количество изменённых файлов. При анализе каждый изменённый файл учитывается в равной степени. Это наиболее экономичный алгоритм
--dirstat
, так как он не требует просмотра содержимого файлов. -
cumulative
-
Для родительского каталога также учитывает изменения в дочерних подкаталогах. Обратите внимание, что при использовании
cumulative
сумма процентов может превышать 100%. Поведение по умолчанию (некумулятивное) можно задать с помощью аргументаnoncumulative
. - <число>
-
При использовании целочисленного значения в качестве аргумента, оно задаёт пороговое значение (по умолчанию 3%). Каталоги, изменения в которых составляют меньшую часть от общего числа изменений, чем указанный процент, не отображаются в выводе.
Пример: Следующая команда будет подсчитывать какую долю составляют файлы, которые были изменены в каждом конкретном каталоге, при этом игнорируя каталоги, на которые приходится менее 10% изменённых файлов и считая изменения в дочерних каталогов, как часть изменений в родительских:
--dirstat=files,10,cumulative
. -
-
--cumulative
-
Синоним для
--dirstat=cumulative
. -
--dirstat-by-file[=<аргумент>,...]
-
Синоним для
--dirstat=files,<аргумент>,...
. -
--summary
-
Вывести краткую сводку из информации, содержащейся в расширенных заголовках списков изменений. В частности, информацию о создании, переименовании и изменении режима доступа к файлу.
-
--patch-with-stat
-
Синоним для
-p --stat
. -
-z
-
Когда заданы параметры
--raw
,--numstat
,--name-only
или--name-status
, не вносить ни
какие изменения в пути файлов и использовать NUL-символ в качестве разделителя полей вывода.Без данного параметра пути с «необычными» символами берутся в кавычки, как это описано для переменной конфигурации
core.quotePath
(см. git-config[1]). -
--name-only
-
Выводить только имена изменённых файлов в результирующем дереве. Имена файлов обычно используют кодировку UTF-8. Для более подробной информации о кодировках см. обсуждение на справочной странице git-log[1].
-
--name-status
-
Показывать только имя/имена и статус каждого изменённого файла. См., что означают буквы статуса, в описании параметра
--diff-filter
. Как и для--name-only
, имена файлов обычно используют кодировку UTF-8. -
--submodule[=<формат>]
-
Задаёт, как должны отображаться различия в подмодулях. При указании
--submodule=short
, используется форматshort
. Этот формат показывает только имена коммитов в начале и конце диапазона. При указании--submodule
или--submodule=log
используется форматlog
. Этот формат перечисляет все коммиты в диапазоне, как это делает git-submodule[1]summary
. При указании--submodule=diff
используется форматdiff
. Этот формат показывает различия в содержимом подмодуля между началом и концом диапазона в виде списка изменений, встроенного в основной. По умолчанию используется формат указанный в переменной конфигурацииdiff.submodule
илиshort
, если переменная не установлена. -
--color[=<когда>]
-
Выводить список изменений в цвете.
--color
(т.е. без аргумента=<когда>
) эквивалентно--color=always
. <когда> может быть одним из:always
,never
илиauto
.
Это значение также можно изменить с помощью
переменных конфигурацииcolor.ui
иcolor.diff
. -
--no-color
-
Выключить выделение цветом при выводе списка изменений.
Этот параметр можно использовать для переопределения значений, заданных в переменных конфигурации.
Эквивалентно--color=never
. -
--color-moved[=<режим>]
-
Перемещённые строки кода выделяются другим цветом.
Это значение можно также изменить с помощью переменной конфигурацииdiff.colorMoved
.
Если параметр не задан, то <режим> по умолчанию:no
; если
задан, но без явного указания <режима> — тоzebra
.
Значение <режима> может быть одним из:-
no
-
Перемещённые строки ни как не выделяются.
-
default
-
Синоним для
zebra
. В будущем это может измениться, если появится режим получше. -
plain
-
Любая строка, добавленная в одном месте и удалённая в другом, будет окрашена с помощью
color.diff.newMoved
. Аналогичноcolor.diff.oldMoved
будет использоваться для удалённых строк, которые добавлены в каком-то другом месте. Этот режим подсвечивает все перемещённые строки, но при рецензировании кода знать был ли блок перемещён и при этом без какой-либо информации о перестановках не так уж и полезно. -
blocks
-
Для поиска блоков перемещённого текста (из не мене чем 20-и алфавитно-цифровых символов) используется жадный алгоритм. Найденные блоки окрашиваются с помощью
color.diff.(old|new)Moved
. Возможности различить смежные блоки нет. -
zebra
-
Поиск блоков перемещённого текста происходит так же, как и в режиме
blocks
. Блоки окрашиваются с помощьюcolor.diff.(old|new)Moved
илиcolor.diff.(old|new)MovedAlternative
. Изменение цвета с одного на другой указывает на то, что был найден новый блок. -
dimmed-zebra
-
Аналогично
zebra
, но также выполняется дополнительное затемнение «неинтересных» частей перемещённого кода. Интересными считаются пограничные строки двух соседних блоков, остальное — неинтересным.dimmed_zebra
— устаревший синоним.
-
-
--no-color-moved
-
Отключить поиск перемещений. Этот параметр можно использовать для переопределения настроек, заданных переменными конфигурации. Эквивалентно
--color-moved=no
. -
--color-moved-ws=<режим>,...
-
Задаёт должны ли игнорироваться пробелы при поиске перемещений для
--color-moved
.
Это можно также задать с помощью переменной конфигурацииdiff.colorMovedWS
.
Следующие режимы могут быть указаны через запятую:-
no
-
Не игнорировать пробелы при поиске перемещений.
-
ignore-space-at-eol
-
Игнорировать изменения пробелов на концах строк.
-
ignore-space-change
-
Игнорировать изменения количества пробелов. Этот режим игнорирует пробелы на концах строк и считает все остальные последовательности одного или более пробельных символов эквивалентными.
-
ignore-all-space
-
Игнорировать все пробелы при сравнении строк. Это игнорирует различия даже если в одной строке пробелы есть там, где в другой их нет.
-
allow-indentation-change
-
Сначала игнорировать любые пробелы при обнаружении перемещений, а затем группировать перемещённые блоки кода в один только, если изменение пробелов одинаково для каждой строки блока. Этот режим несовместим с остальными.
-
-
--no-color-moved-ws
-
Не игнорировать пробелы при поиске перемещений. Этот параметр можно использовать для переопределения настроек, заданных переменными конфигурации. Эквивалентно
--color-moved-ws=no
. -
--word-diff[=<режим>]
-
По умолчанию слова разделены пробелами; см.
--word-diff-regex
ниже. Аргумент <режим> по умолчанию равенplain
, и должен быть одним из:-
color
-
Выделять изменённые слова только цветом. Подразумевает
--color
. -
plain
-
Отображать слова как
[-удалено-]
и{
. Этот нежим не пытается экранировать разделители, если они появляются во входных данных, поэтому вывод может быть неоднозначным.добавлено
} -
porcelain
-
Использовать специальный построчный формат, предназначенный для программной обработки сценариями. Добавленные/удалённые/неизменённые участки строк исходных документах выводятся в виде обычного унифицированного списка изменений: каждый участок записывается на отдельной строке, начинающейся, соответственно, с символов
+
/-
/` ` и продолжается до конца строки. А собственно переводы строк во входных данных представляются в виде тильды~
на отдельной строке. -
none
-
Отключить сравнение слов; снова.
Обратите внимание, что несмотря на название первого режима, цвет используется для выделения изменённых частей во всех режимах, если он включён.
-
-
--word-diff-regex=<регулярное-выражение>
-
Использовать <регулярное_выражение> для определения того, что является словом, вместо того, чтобы считать словом любую последовательность непробельных символов. Также подразумевает параметр
--word-diff
, если он не было указан до этого.Каждая подстрока, не перекрывающаяся с другими и сопоставленная <регулярному_выражению> считается словом. Всё, что находится между ними, считается пробелами и игнорируется(!) при поиске различий. Возможно, вам понадобиться добавить
|[^[:space:]]
к вашему регулярному выражению, чтобы быть уверенным, что оно будет сопоставлено с любой непробельным символом. Сопоставленная подстрока, содержащая перевод строки, по-тихому обрезается(!) на символе перевода строки.Например,
--word-diff-regex=.
будет обращаться с каждым символом как со словом и, соответственно, показывать различия символ к символу.Это регулярное выражение также можно задать через драйвер пользовательской утилиты сравнения или переменные конфигурации; см. gitattributes[5] или git-config[1]. Явное указание этого параметра переопределяет любое значение, заданное в драйвере или переменной конфигурации. Кроме того, драйверы переопределяют значения, заданные в переменных конфигурации.
-
--color-words[=<регулярное-выражение>]
-
Эквивалентно
--word-diff=color
плюс (если указано регулярное выражение)--word-diff-regex=<регулярное_выражение>
. -
--no-renames
-
Отключить обнаружение переименований, даже если в файле конфигурации оно включено по умолчанию.
-
--[no-]rename-empty
-
Определяет, рассматривать ли пустые бинарные объекты, как возможные источники переименований.
-
--check
-
Предупреждать, если изменения включают маркеры конфликтов или ошибки расстановки пробелов. Что именно считается ошибками расстановки пробелов, настраивается с помощью переменной конфигурации
core.whitespace
. По умолчанию такими ошибками считаются пробелы в конце строк (включая строки, состоящие только из пробелов), а также пробел внутри начального отступа строки, непосредственно за котором следует табуляция. Программа завершится с ненулевым статусом, если такие проблемы будут обнаружены. Не совместимо с--exit-code
. -
--ws-error-highlight=<тип>
-
Выделять цветом ошибки расстановки пробелов в строках
context
(контекстных),old
(старых) илиnew
(новых) в списке изменений. Допустимо несколько значений, разделённых запятой;none
сбрасывает предыдущие значения,default
сбрасывает список доnew
, аall
— это сокращение дляold,new,context
. Если этот параметр не указан, и переменная конфигурацииdiff.wsErrorHighlight
не установлена, то ошибки расстановки пробелов будут выделятся только в новых строках. Для выделения используется цвет, указанный в переменной конфигурацииcolor.diff.whitespace
. -
--full-index
-
Вместо первых нескольких символов показывать полные имена blob-объектов в строке «index» при выводе патча.
-
--binary
-
Выводить список изменений в бинарных файлах, который может быть применён с помощью
git-apply
. Также подразумевает--full-index
.
Подразумевает--patch
. -
--abbrev[=<n>]
-
Вместо вывода полных 40-байтовых шестнадцатеричных имён объектов в списках изменений в сыром формате, а также в строках заголовков diff-tree, выводить их минимальный префикс, который имеет как минимум <n> шестнадцатеричных цифр и уникально идентифицирует объект. Однако, при выводе списка изменений в виде патча параметр
--full-index
имеет приоритет, т.е. если задан параметр--full-index
, будут выведены полные имена блоков, независимо от того, задан ли--abbrev
. Количество выводимых цифр отличное от значения по умолчанию можно задать с помощью--abbrev=<n>
. -
-B[<n>][/<m>]
-
--break-rewrites[=[<n>][/<m>]]
-
Разбивать изменения, которые полностью переписывают файл на пары удаления и создания. Этот параметр служит двум целям:
Влияет на то, как правка, которая по сути представляет собой полное переписывание файла, отображается в списке изменений не как серия удалений и вставок, смешанных с несколькими строками «контекста», которые оказались таковыми лишь по случайному стечению обстоятельств, а как одно единое удаление старого файла целиком, за которым следует создание нового файла. Число <m>(по умолчанию 60%) в аргументе параметра
-B
задаёт, какая часть файла должна быть изменена, чтобы он считался полностью переписанным. Например,-B/70%
указывает, что, чтобы Git считал файл полностью переписанным, в нём должно оставаться нетронутым менее 30% исходного содержимого (т.е. в случае, если нетронутыми будут больше 30% объёма файла, полученный патч будет серией удалений и вставок, смешанных с контекстными строками, как при обычном выводе).При использовании совместно с
-M
, полностью переписанный файл также рассматривается как возможный источник переименований (обычно-M
рассматривает в качестве таковых только файлы, которые были удалены). Число <n>(по умолчанию 50%) в аргументе параметра-B
задаёт, какая часть файла должна быть изменена, чтобы он рассматривался как возможный источник переименований. Например, при указании-B20%
для того, чтобы файл рассматривался в качестве такового, изменения в нём (включая добавления и удаления строк) должны составлять более 20% файла. -
-M[<n>]
-
--find-renames[=<n>]
-
Обнаруживать переименования.
Если указан аргумент <n>, то это значение является пороговым коэффициентом
сходства (т.е. количеством добавлений/удалений по отношению к размеру файла).
Например,-M90%
означает, что Git должен считать пару файлов
удалённый/добавленый переименованием, если более 90% файла не изменилось. Без
знака процента%
это число рассматривается как дробная часть десятичной
дроби (т.е. с нулём и десятичной точкой перед числом). Так например,-M5
рассматривается «0.5» и таким образом эквивалентно-M50%
. Аналогично,-M05
эквивалентно-M5%
. Чтобы ограничиться обнаружением только переименований без
изменений, используйте-M100%
. По умолчанию коэффициент сходства равен 50%. -
-C[<n>]
-
--find-copies[=<n>]
-
Обнаруживать копии наряду с переименованиями. См. также
--find-copies-harder
. Аргумент <n>, если указан, имеет то же значение, что и в-M<n>
. -
--find-copies-harder
-
По соображениям производительности, по умолчанию параметр
-C
рассматривает в качестве исходных файлов копий только те файлы, которые были изменены в том же наборе изменений. Этот флаг заставляет команду рассматривать в качестве кандидатов на роль источника копии также и неизмененные файлы. Для больших проектов это очень дорогая операция, поэтому используйте её с осторожностью. Передача параметра-C
более одного раза имеет тот же эффект. -
-D
-
--irreversible-delete
-
Опускать исходное содержимое файла при его удалении, т.е. выводить только заголовок, но не «различия» между удаляемым файлом и
/dev/null
. Полученный патч не предназначен для применения с помощьюpatch
илиgit apply
, а исключительно для тех людей, кто хочет сосредоточиться на рецензировании или просмотре различий после внесения изменений. Кроме того, с таким патчем, очевидно, не будет возможности обратить изменения, даже вручную; отсюда и название параметра: «irreversible» — необратимый.При использовании совместно с
-B
, опускается также и содержимое удаляемой части в паре «удаление/создание». -
-l<число>
-
Выполнение поиска для параметров
-M
и-C
происходит в два этапа: сначала производится некоторый предварительные шаги, которые позволяют дёшево обнаружить лишь часть переименований/копирований, а затем следует исчерпывающая часть поиска, на которой все оставшиеся назначения для которых не было найдено пары сравниваются со всеми подходящими для них источниками. (Для переименований подходящими считаются только те источники, которым ещё не были найдены пары; для копирований — все исходные источники.) Для N возможных файлов источников и назначений эта исчерпывающая проверка имеет сложность O(N^2). Данный параметр предотвращает запуск исчерпывающей части поиск переименований/копирований, если количество файлов источников/назначений превышает указанное <число> (по умолчанию:diff.renameLimit
). Обратите внимание, что значение0
означает, что это количество файлов неограниченно. -
--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]
-
Выбирать только файлы, которые были добавлены (
A
, Added), скопированы (C
, Copied), удалены (D
, Deleted), изменены (M
, Modified), переименованы (R
, Renamed), чей тип (т.е. обычный файл, символическая ссылка, подмодуль, …) был изменён (T
, Type), не слиты (U
, Unmerged), неизвестны (X
) или имеют сломанную связь (B
, Broken). Может быть задано любое подмножество символов фильтра (включая пустое). При добавлении*
(всё или ничего) к аргументам, то или выбираются все пути, если существует хотя бы один файл, соответствующий остальным критериям, или ничего, если такого файла нет.Также если вместо этих прописных букв задать их строчные версии, то соответствующие этому критерию файлы будут наоборот исключены. Например,
--diff-filter=ad
исключает добавленные и удалённые пути.Обратите внимание, что не все списки изменений могут обеспечить доступ ко всем типам изменений. В частности, записи о переименованиях и копированиях не будут доступны, если обнаружение для этих типов не было включено.
-
-S<строка>
-
Искать различия, которые изменяют количество вхождений указанной <строки> в файле (т.е. её добавления/удаления, но не изменения/перемещения). Предназначено для использования в скриптах.
Это полезно, если вы ищете точный блок кода (например, структуру), и хотите знать историю этого блока с момента его появления: вызывайте эту функцию последовательно несколько раз, передавая полученный на очередном шаге интересующий вас блок обратно в
-S
, и продолжайте так до тех пор, пока не получите самую первую версию этого блока.Поиск происходит также и в бинарных файлах.
-
-G<регулярное-выражение>
-
Искать списки изменений, текст патча которых содержит добавление/удаление строк, соответствующих <регулярному_выражению>.
Чтобы проиллюстрировать разницу между
-S<регулярное_выражение>
--pickaxe-regex
и-G<регулярное_выражение>
, рассмотрим коммит со следующими различиями в одном и том же файле:+ return frotz(nitfol, two->ptr, 1, 0); ... - hit = frotz(nitfol, mf2.ptr, 1, 0);
В то время как команда
git log -G"frotznitfol"` выведет этот коммит, `git log -S"frotznitfol" --pickaxe-regex
— не выведет (потому что количество вхождений этой строки не изменилось).Если не указан параметр
--text
и для данного типа файлов нет фильтра textconv, изменения вносимые патчами в бинарные файлы будут проигнорированы.См. раздел pickaxe в gitdiffcore[7] для более подробной информации.
-
--find-object=<id-объекта>
-
Искать различия, которые меняют количество вхождений указанного объекта. Аналогично
-S
, но в качестве аргумента вместо конкретной строки для поиска передаётся идентификатор конкретного объекта.Объект может быть blob-объектом или коммитом в подмодуле. Этот параметр также подразумевает
-t
вgit-log
, для поиска деревьев. -
--pickaxe-all
-
Когда поиске с помощью параметров
-S
или-G
находит изменения, показывать все изменения в данном наборе, а не только в тех файлах, которые содержат изменения в заданной <строке>. -
--pickaxe-regex
-
Обрабатывать <строку>, переданную в
-S
, как расширенное регулярное выражение POSIX с котором должно производится сопоставление. -
-O<файл-порядка>
-
Контролирует порядок, в котором файлы появляются в выводе. Этот параметр переопределяет значение указанное в переменной конфигурации
diff.orderFile
(см. git-config[1]). Чтобы отменить использование файла указанного вdiff.orderFile
, используйте-O/dev/null
.Порядок вывода определяется порядком glob-шаблонов в <файле-порядка>. Первыми выводятся все файлы, пути которых соответствуют первому шаблону, затем файлы, соответствующие второму шаблону (но не первому), и так далее. Все файлы, которые не соответствуют ни одному из шаблонов, выводятся в конце, как если бы в конце файла был неявно задан шаблон, который сопоставляется всем путям. Пути одного ранка (которые соответствуют какому-либо одному шаблону, но не одному из предыдущих) относительно друг друга выводятся в нормальном порядке.
Синтаксис <файла-порядка> следующий:
-
Пустые строки игнорируются, так что их можно использовать для улучшения читаемости.
-
Строки, начинающиеся с символа решётки («
#
»), игнорируются, их можно использовать для комментариев. Если шаблон начинается с решётки, добавьте обратный слэш («\
») перед ней. -
Все остальные строки являются шаблонами; по одному на строку.
Синтаксис и семантика у этих шаблонов те же, что и у шаблонов, используемых для
fnmatch
(3) без флагаFNM_PATHNAME
, за исключением того, что путь к файлу также сопоставляются шаблону; при этом в качестве пути к файлу сопоставляется путь к его родительскому каталогу любого уровня. Например, шаблону «foo*bar
» будет соответствовать какfooasdfbar
, так и «foo/bar/baz/asdf
», но не «foobarx
». -
-
--skip-to=<файл>
-
--rotate-to=<файл>
-
Пропускать в выводе файлы до указанного <файла> (со
--skip-to
), или вывести их в конец (с--rotate-to
). Эти параметры были добавлены в первую очередь для использования в командеgit difftool
и, вероятно, от них будет не так много пользы в других командах. -
-R
-
Поменять местами два входных файла; т.е. показывать, какие изменения произошли бы при переходя от версии файла в индексе или на диске к той, что содержится в дереве коммита.
-
--relative[=<путь>]
-
--no-relative
-
При запуске из одного из подкаталогов проекта этот параметр позволяет исключить изменения за пределами этого каталога и отображать пути относительно него. Если вы не находитесь в каком-либо подкаталоге (например, в голом репозитории), можно указать подкаталог, относительно которого будет производиться вывод, передав <путь> в качестве аргумента. Параметр
--no-relative
можно использовать как для отмены эффекта от переменной конфигурацииdiff.relative
, так и предшествующего параметра--relative
. -
-a
-
--text
-
Обрабатывать все файлы как текстовые.
-
--ignore-cr-at-eol
-
Игнорировать символы возврата каретки в конце строк при сравнении.
-
--ignore-space-at-eol
-
Игнорировать изменения пробелов на концах строк.
-
-b
-
--ignore-space-change
-
Игнорировать изменения количества пробелов. Этот режим игнорирует пробелы на концах строк и считает все остальные последовательности одного или более пробельных символов эквивалентными.
-
-w
-
--ignore-all-space
-
Игнорировать все пробелы при сравнении строк. Это игнорирует различия даже если в одной строке пробелы есть там, где в другой их нет.
-
--ignore-blank-lines
-
Игнорировать изменения, в которых все строки пустые.
-
-I<регулярное-выражение>
-
--ignore-matching-lines=<регулярное-выражение>
-
Игнорировать изменения, в которых все строки сопоставляются <регулярному-выражению>. Этот параметр может быть указан несколько раз.
-
--inter-hunk-context=<число>
-
Выводить в качестве контекста между блоками изменений до указанного <числа> строк, тем самым объединяя близкие блоки изменений. По умолчанию равно значению переменной конфигурации
diff.interHunkContext
или 0, если оно не установлено. -
-W
-
--function-context
-
Показывать всю функцию в качестве контекста для каждого изменения. Для определения имён функций используется тот же механизм, что и для определения заголовков блоков изменений командой
git diff
(см. «Определение пользовательского заголовка блока» в gitattributes[5]). -
--exit-code
-
Сделать так, чтобы программа завершалась с определённым кодом, аналогично тому, как это делает команда
diff
(1). То есть при наличии различий она будет завершаться с кодом 1, а при отсутствии — с кодом 0. -
--quiet
-
Отключить весь вывод у данной программы. Подразумевает
--exit-code
. Также отключает выполнение вспомогательных сторонних утилит сравнения, коду завершения которых нельзя доверять, т.е. если для них не установлена переменная конфигурацииdiff.trustExitCode
илиdiff.
<драйвер>.trustExitCode
, а также если переменная окруженияGIT_EXTERNAL_DIFF_TRUST_EXIT_CODE
ложна. -
--ext-diff
-
Разрешить выполнение вспомогательных сторонних утилит сравнения. Если вы настроили драйвер сторонней утилиты сравнения с помощью gitattributes[5], то вам нужно будет использовать этот параметр с командой git-log[1] и другими подобными.
-
--no-ext-diff
-
Запретить драйверы сторонних утилит сравнения.
-
--textconv
-
--no-textconv
-
Разрешить (или запретить) преобразование бинарных файлов в текст с помощью внешних фильтров при их сравнении. См. подробности в gitattributes[5]. Полученный вывод подходит для восприятия человеком, но поскольку фильтры
textconv
обычно представляют из себя одностороннее преобразование, полученный патч нельзя будет применить. По этой причине фильтрыtextconv
по умолчанию включены только для git-diff[1] и git-log[1], но не для git-format-patch[1] или низкоуровневых команд сравнения. -
--ignore-submodules[=(none|untracked|dirty|all)]
-
Игнорировать изменения в подмодулях при создании вывода. Значением по умолчанию является
all
. При использовании значенияnone
будет считаться, что подмодуль изменён, если он содержит неотслеживаемые или изменённые файлы или если егоHEAD
отличается от коммита, зафиксированного в надпроекте и может быть использовано для переопределения любых переменных конфигурации сignore
в git-config[1] или gitmodules[5]. При использованииuntracked
подмодули не считаются грязными только из-за того, что они содержат неотслеживаемые файлы (но они всё равно проверяются на наличие изменений в содержимом). При использованииdirty
игнорируются все изменения в рабочих каталогах подмодулей и показываются только изменения коммитов, хранящихся в надпроекте (таким было поведение до версии 1.7.0). При использованииall
все изменения в подмодулях скрываются. -
--src-prefix=<префикс>
-
Использовать указанный <префикс> для источника вместо «a/».
-
--dst-prefix=<префикс>
-
Использовать указанный <префикс> для назначения вместо «b/».
-
--no-prefix
-
Не выводить ни префикс источника, ни назначения.
-
--default-prefix
-
Использовать стандартные префиксы источника и назначения («a/» и «b/»). Это переопределяет такие переменные конфигурации, как
diff.noprefix
,diff.srcPrefix
,diff.dstPrefix
, иdiff.mnemonicPrefix
(см. git-config[1]). -
--line-prefix=<префикс>
-
Добавить дополнительный <префикс> к каждой строке вывода.
-
--ita-invisible-in-index
-
По умолчанию записи, добавленные командой
git add -N
, отображаются в выводеgit diff
как существующий пустой файл, а в выводе git diff —cached` — как новый файл. Этот параметр делает так, что такие записи отображаются как новый файл в выводеgit diff
и отсутствовать в выводеgit diff --cached
. Этот параметр может быть переопределён с помощью--ita-visible-in-index
. Оба эти параметра являются экспериментальными и могут быть удалены в будущем.
-
-1
-
--base
-
-2
-
--ours
-
-3
-
--theirs
-
Сравнение рабочего каталога с:
-
«базовой» версией (индекс №1) при использовании
-1
или--base
, -
«нашей веткой» (индекс №2) при использовании
-2
или--ours
, или -
«их веткой» (индекс №3) при использовании
-3
или--theirs
.
Все эти три индекса существуют только для не слитых записей, т.е. при разрешении конфликтов. См. подробности в git-read-tree[1] в разделе «Трёхходовое слияние».
-
-
-0
-
Опускать вывод списка изменений для не слитых записей и вместо этого просто выводить «Unmerged» («Не слит»). Данный параметр может использоваться только при сравнении рабочего каталога с индексом.
-
<путь>…
-
При указании <путей> в аргументах выводимый список изменений ограничивается изменениями только в указанных путях (можно также указать имена каталогов и получить список изменений для всех файлов внутри этих каталогах).
Diff tools are essential for developers who need to compare and merge files and code. These tools highlight differences between two files or directories and are invaluable in version control, especially in collaborative environments. This guide explores various diff tools, including those available online, Windows, Mac, and within Git environments.
What is a diff tool?
A diff tool, or a difference tool, compares files line by line, helping users to see what has changed between file versions. It’s particularly useful in software development for comparing code files, but can also be used to compare any text-based files.
Types of diff tools
Diff tools can be broadly categorized based on their platform and integration:
- Online diff tools: These are accessible through web browsers and do not require any software installation.
- Desktop diff tools: These include standalone applications for Windows and Mac.
- Integrated diff tools in version control systems: Tools specifically designed to work with systems like Git.
Online diff tools
Online diff tools provide a quick and easy way to compare text without the need for installation. They are particularly useful for quick checks or when working on machines where you do not have the necessary permissions to install software.
1. Diffchecker
Features:
- Text, PDF, and image comparisons: Diffchecker allows users to compare plain text, as well as PDF files and images, highlighting differences in content.
- Privacy: Claims to securely handle your data, ensuring that files and information are kept private.
- Ease of use: Simple interface where users can paste text directly or upload files for comparison.
2. Mergely
Features:
- Rich text editor: Mergely incorporates a rich text editor, making it easier to make edits directly within your browser while comparing texts.
- Real-time visual diffing: Provides a more interactive and visually appealing way to see differences, using color coding in a side-by-side format.
- Embeddable widget: Offers a widget that can be integrated into other web applications, ideal for developers looking to add diff capabilities to their apps.
- Support for code and HTML: Besides plain text, it can compare code and HTML, showing syntax highlighting which is beneficial for developers.
3. Draftable
Features:
- Broad file format support: Draftable supports a wider range of file formats including Word, PowerPoint, Excel, and PDFs, making it versatile for professional environments.
- Side-by-side document viewing: Unlike basic text comparisons, Draftable provides a more robust interface for viewing documents side by side.
- Private and secure: Emphasizes security and privacy, particularly important for sensitive business documents.
- Account-based features: Offers features like saving comparisons for later viewing with an account, which can be useful for ongoing review processes.
Usage
For all three tools, the process of comparing documents or text is straightforward:
- Users navigate to the tool’s website.
- They either paste the text into provided text boxes or upload the files that need to be compared.
- After initiating the comparison, the tool highlights the differences between the two inputs. The highlighting might vary, showing added, deleted, or changed lines, often in different colors to facilitate quick identification.
Desktop diff tools
For Windows:
- WinMerge: An open-source tool that is popular among Windows users for its user-friendliness and feature set. It supports file diffs, directory diffs, and merging.
- Beyond Compare: A more advanced tool that not only compares files and folders but also synchronizes them, supports FTP sites, and more.
For Mac:
- DiffMerge: Offers visual file comparison and merging, as well as folder comparison.
- Kaleidoscope: Is known for its clean user interface and powerful features, including image and text comparison.
Git diff
Git comes with built-in tools for diff viewing, but it can also integrate with third-party tools for more advanced diff and merge functionalities.
- Using Git’s built-in command: You can view diffs directly in the terminal using commands like
git diff
which shows differences between commits, branches, and more. For more details see this in-depth guide on thegit diff
command. - Integrating external tools: Tools like Meld can be configured to work with Git for a more visual diff experience.
Meld
Meld is a visual diff and merge tool available on Linux, Windows, and Mac. It is highly regarded for its clarity and ease of use, making it a favorite in the open-source community.
- Features: Compare two or three files, and directories, and perform three-way merges.
- Usage: You can launch Meld, select the files or folders to compare, and it will display the differences side by side with changes highlighted.
Diff tools enable developers to track changes and ensure consistency across project versions. Whether you choose an online tool for convenience or a powerful desktop application for comprehensive features, the right diff tool can significantly streamline your development workflow.
UPDATE!!! I’m now using an easier way of configuring diff and merge tools. If you don’t mind using KDiff3 then you might want to check that out first. If you want flexibility in which tools you use and how they’re used, then read on. – DT, 26 Mar 2010
I finally got tired of reading diff outputs from git on the command line, and decided to hook up a visual diff and merge tool. After piecing together hints from various posts around ye olde intraweb I’ve now got somethings that works. I am using Git on MSys to get Git working on Windows via a PowerShell command line, but a similar setup might work via Cygwin or via the cmd.exe
command line.
Setting up a diff tool
Update 2009-05-20: This approach stopped working for me when I upgraded to Windows 7 and Git 1.6.3. I had to switch to using git difftool
instead.
The easiest way I found to do this was to create a shell script wrapper for your diff tool of choice. To make things easy on me I put the script, git-diff-wrapper.sh
in C:\Program Files\Git\cmd
, which is in my Path
environment variable. The file contents looks like this:
#!/bin/sh # diff is called by git with 7 parameters: # path old-file old-hex old-mode new-file new-hex new-mode "C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$2" "$5" | cat #"C:/Program Files/WinMerge/WinMergeU.exe" "$2" "$5" | cat #"C:/Program Files/KDiff3/kdiff3.exe" "$2" "$5" | cat
The basic format of this is stolen directly from this post on the Msysgit site. Provided your diff tool can be called from the command line, you’ll be able to set it up to work with Git using this template. In this case I’ve used it to setup a call to Sourcefear’s DiffMerge, a nice free (as in beer) diff and merge tool.
You’ll also see I’ve commented out calls to WinMerge and KDiff3, which are both free as in beer and speech. I ended up settling on DiffMerge because it is purdy (unlike KDiff3 – sorry), and also does 3-way merges (unlike WinMerge, which was my previous diff tool of choice).
The next step is telling Git about your wrapper. In your home directory (C:\Users\(username)
or the corresponding Documents and Settings equivalent) Git will normally have created a .gitconfig
file. If not then go ahead and create one. You’ll need to have the following section in there:
[diff] external = C:/Program Files/git/cmd/git-diff-wrapper.sh
We can now use git diff
and it will fire up our diff tool of choice.
Setting up a merge tool
I had more trouble getting a merge tool working, largely because putting references to paths like C:/Program Files/...
in .gitconfig
seems to bork when used here. Again I ended up using the wrapper approach, creating git-merge-diffmerge-wrapper.sh
at C:\Program Files\Git\cmd
to call DiffMerge. This file ended up looking like this:
#!/bin/sh # Passing the following parameters to mergetool: # local base remote merge_result "C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" "$1" "$2" "$3" --result="$4" --title1="Mine" --title2="Merging to: $4" --title3="Theirs"
I unashamedly stole this from Alexander Groß’s post on getting DiffMerge running on Cygwin-based Git (with slight modifications, any faults are mine :)). We can then wire this up in .gitconfig
again:
[merge] tool = diffmerge [mergetool "diffmerge"] cmd = git-merge-diffmerge-wrapper.sh "$PWD/$LOCAL" "$PWD/$BASE" "$PWD/$REMOTE" "$PWD/$MERGED" trustExitCode = false keepBackup = false [mergetool "kdiff3"] path = C:/Program Files/KDiff3/kdiff3.exe keepBackup = false trustExitCode = false
Now remember that C:\Program Files\Git\cmd
is on my PATH
, so I can set the command to call git-merge-diffmerge-wrapper.sh
without fully qualifying the path. The details on the arguments are available from the git-mergetool(1) man page. I’ve also left in a KDiff3 version that seems to work too (Git has some built in support for KDiff3 I think, which is why you can get away with only specifying the path).
Time for a test drive
Let’s make sure everything’s in working order. I’ll open up a PowerShell window and let’s see how we go (you’ll have to excuse me for using old DOS commands instead of fancy PowerShell ones, I’ve only just switched to PS after running into various issues with the cmd.exe
command line).
PS> mkdir HelloWorld PS> cd HelloWorld PS> git init Initialized empty Git repository in C:/Development/Git/HelloWorld/.git/ PS> echo Hello World! > hello.txt PS> git add hello.txt PS> git commit -m "Initial commit" [master (root-commit)]: created 2a2cf34: "Initial commit" 1 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 hello.txt PS> git checkout -b helloGit Switched to a new branch "helloGit" PS> echo Hello Git! > hello.txt PS> git add hello.txt PS> git commit -m "Update from helloGit branch" [helloGit]: created e71437b: "Update from helloGit branch" 1 files changed, 0 insertions(+), 0 deletions(-) PS> git checkout master Switched to branch "master" PS> echo Hello World! Hello indeed! > hello.txt PS> git add hello.txt PS> git commit -m "Update from master" [master]: created 5dee19d: "Update from master" 1 files changed, 0 insertions(+), 0 deletions(-) PS> git merge helloGit warning: Cannot merge binary files: HEAD:hello.txt vs. helloGit:hello.txt Auto-merging hello.txt CONFLICT (content): Merge conflict in hello.txt Automatic merge failed; fix conflicts and then commit the result.
Because I’ve used echo
to stream data into hello.txt
the files have ended up in binary mode. Let’s ignore that as it is just to get an easy demo going. The important thing is we now have a merge conflict to resolve.
If we now type in git mergetool
Git ask’s us if we’d like to run our merge tool. We can hit enter and up pops DiffMerge. If you wanted KDiff3, we could have called git mergetool -t kdiff3
, or any other merge tool in our .gitconfig
(by default the tool specified in the merge.tool
config option is used).
PS> git mergetool Merging the files: hello.txt Normal merge conflict for 'hello.txt': {local}: modified {remote}: modified Hit return to start merge resolution tool (diffmerge):
Resolve the merge conflict however you like and then try this:
PS> echo Wow, it worked! > hello.txt PS> git diff
Hooray, we have our diff tool working! We can also run commands like git diff HEAD~ HEAD
and git diff helloGit master
and get the output via our diff tool.
Conclusion
This setup earns the coveted Works on My Machine certification, but even if that’s the only place it works then hopefully it still gives you enough information to configure your Windows diff and merge tools for use with Git.
If you hunt down the relevant command line options you should be able to get pretty much any tool working: Beyond Compare, p4merge, TortoiseMerge etc.
Hope this helps.
Overview
Teaching: 30 min
Exercises: 5 minQuestions
How can I see what changed between commits?
How do I go back to a previous version of my project?
Objectives
Be able to view history of changes to a repository
Be able to view differences between commits
Be able to recover a previous version of your project
Understand how and when to use tags to label commits
Looking at differences
We should reference some previous work in the introduction section.
Make the required changes, save both files but do not commit the changes yet.
We can review the changes that we made using:
$ nano paper.md # Cite previous studies in introduction
$ nano refs.txt # Add the reference to the database
$ git diff # View changes
This shows the difference between the latest copy in the repository and the
unstaged changes we have made.
-
means a line was deleted.+
means a line was added.- Note that a line that has been edited is shown as a removal of the old line and an
addition of the updated line.
Looking at differences between commits is one of the most common activities.
The git diff
command itself has a number of useful
options.
There are many GUI-based tools available for looking at differences and editing files,
which can be easier to work with.
For example:
- Diffmerge (Free, cross-platform)
- WinMerge — open source tool available for Windows;
To view differences with a GUI instead of using the command-line diff tool, first configure
git to use your chosen diff tool:$ git config --global diff.tool diffmerge # Set diffmerge as your visual diff tool $ git config --global difftool.prompt false # Suppress confirmation before launching GUI
Note that these config steps are slightly different for Windows.
Then to use the GUI, use the following command instead of
git diff
:
Now commit the change we made by adding the second reference:
$ git add paper.md refs.txt
$ git commit # "Cite previous work in introduction"
Looking at our history
To see the history of changes that we made to our repository (the most recent
changes will be displayed at the top):
commit 8bf67f3862828ec51b3fdad00c5805de934563aa
Author: Your Name <your.name@manchester.ac.uk>
Date: Mon Jun 26 10:22:39 2017 +0100
Cite PCASP paper
commit 4dd7f5c948fdc11814041927e2c419283f5fe84c
Author: Your Name <your.name@manchester.ac.uk>
Date: Mon Jun 26 10:21:48 2017 +0100
Write introduction
commit c38d2243df9ad41eec57678841d462af93a2d4a5
Author: Your Name <your.name@manchester.ac.uk>
Date: Mon Jun 26 10:14:30 2017 +0100
Add author and title
The output shows (on separate lines):
- the commit identifier (also called revision number) which
uniquely identifies the changes made in this commit - author
- date
- your commit message
Git automatically assigns an identifier (e.g. 4dd7f5) to each commit
made to the repository
— we refer to this as COMMITID in the code blocks below.
In order to see the changes made between any earlier commit and our
current version, we can use git diff
followed by the commit identifier of the
earlier commit:
$ git diff COMMITID # View differences between current version and COMMITID
And, to see changes between two commits:
$ git diff OLDER_COMMITID NEWER_COMMITID
Where to create a Git repository?
Avoid creating a Git repository within another Git repository.
Nesting repositories in this way causes the ‘outer’ repository to
track the contents of the ‘inner’ repository — things will get confusing!
Exercise: “bio” Repository
- Create a new Git repository on your computer called “bio”
- Be sure not to create your new repo within the ‘paper’ repo (see above)
- Write a three-line biography for yourself in a file called me.txt
- Commit your changes
- Modify one line, add a fourth line, then save the file
- Display the differences between the updated file and the original
You may wish to use the faded example below as a guide
cd .. # Navigate out of the paper directory # Avoid creating a repo within a repo - confusion will arise! mkdir ___ # Create a new directory called 'bio' cd ___ # Navigate into the new directory git ____ # Initialise a new repository _____ me.txt # Create a file and write your biography git ___ me.txt # Add your biography file to the staging area git ______ # Commit your staged changes _____ me.txt # Edit your file git ____ me.txt # Display differences between your modified file and the last committed version
Solution
cd .. # Navigate out of the paper directory # Avoid creating a repo within a repo - confusion will arise! mkdir bio # Create a new directory cd bio # Navigate into the new directory git init # Initialise a new repository nano me.txt # Create a file and write your biography git add me.txt # Add your biography file to the staging area git commit # Commit your staged changes nano me.txt # Edit your file git diff me.txt # Display differences between your modified file and the last committed version
The HEAD
and master
pointers
Let’s take a look again at the output from git log
.
This time we’ll use the --decorate
option to display the pointers
(your git set up might already display them by default).
commit 8bf67f3862828ec51b3fdad00c5805de934563aa (HEAD -> master)
Author: Your Name <your.name@manchester.ac.uk>
Date: Mon Jun 26 10:22:39 2017 +0100
Cite PCASP paper
commit 4dd7f5c948fdc11814041927e2c419283f5fe84c
Author: Your Name <your.name@manchester.ac.uk>
Date: Mon Jun 26 10:21:48 2017 +0100
Write introduction
commit c38d2243df9ad41eec57678841d462af93a2d4a5
Author: Your Name <your.name@manchester.ac.uk>
Date: Mon Jun 26 10:14:30 2017 +0100
Add author and title
You’ll see there are two pointers, HEAD
and master
which label the most recent commit.
HEAD
points to the commit you’re currently on in the repomaster
points to the tip of the master branch, and moves forward as you make new commitsHEAD
normally points to a branch pointer
Going back in time with git
We can use commit identifiers to set our working directory back to how it was
at any commit.
Doing so will mean the HEAD
pointer no longer points to the branch tip –
this scenario is known as a detached HEAD,
and is for inspection and discardable experiments.
Before we go back to a previous version of our project,
we’ll just visualise our history in the same way as the diagram above.
$ git log --graph --decorate --oneline --all
* 6a48241 (HEAD, master) Cite previous work in introduction
* ed26351 Cite PCASP paper
* 7446b1d Write introduction
* 4f572d5 Add title and author
Notice how HEAD
and master
point to the same commit.
As we’ll find out in episode 6,
the switch command is used to switch between branches,
but if we want to switch to a commit instead of a named branch,
we’ll need to use switch
with the -d
(detach) option.
Let’s go back to the very first commit we made:
$ git switch -d INITIAL_COMMITID
We will get something like this:
HEAD is now at 8bd9133 Add title and author
And if we run
we get a confirmation that we have a detached HEAD:
HEAD detached at 8bd9133
nothing to commit, working tree clean
If we look at paper.md
we’ll see it’s our very first version. And if we
look at our directory,
then we see that our refs.txt
file is gone. But don’t worry, while it’s
gone from our working directory, it’s still in our repository.
Let’s visualise the repo again now we are a ‘detached HEAD’ state:
$ git log --graph --decorate --oneline --all
* 6a48241 (master) Reference second paper in introduction
* ed26351 (HEAD) Reference Allen et al in introduction
* 7446b1d Write introduction
* 4f572d5 Add title and authors
Notice how HEAD
no longer points to the same commit as master
.
Let’s return to the current version of the project by switching back to master
.
See that refs.txt
is back in the working directory,
So we can get any version of our files from any point in time. In other words,
we can set up our working directory back to any stage it was at when we made
a commit.
Using tags as nicknames for commit identifiers
Commit identifiers are long and cryptic. Git allows us to create tags, which
act as easy-to-remember nicknames for commit identifiers.
For example,
We can list tags by doing:
Let’s explain to the reader why this research is important:
$ nano paper.md # Give context for research
$ git add paper.md
$ git commit -m "Explain motivation for research" paper.md
We can switch back to our previous version using our tag instead of a commit
identifier.
$ git switch -d PAPER_STUB
We might want to have a look around while we’re here:
And to return to the latest commit, we use
Top tip: tag significant events
When do you tag? Well, whenever you might want to get back to the exact
version you’ve been working on. For a paper, this might be a version that has
been submitted to an internal review, or has been submitted to a conference.
For code this might be when it’s been submitted to review, or has been
released.
Key Points
git log
shows the commit history
git diff
displays differences between commits
git switch -d
recovers previous states of the repo
HEAD
points to the commit you have checked out
master
points to the tip of themaster
branch
git tag
allows commits to be given a descriptive label
git difftool
shows changes using your configured diff GUI