Объяснение Git: Диапазоны коммитов

Источник: «Git explained: Commit ranges»
Команды Git log и diff полезны для проверки изменений вашего репозитория. Обе команды принимают диапазоны коммитов в разных форматах, что может сбивать с толку. В этой статье я пролью свет на различия между диапазонами коммитов a b, a..b, a...b.

Скачайте репозиторий который я буду использовать в качестве примера.

Это вторая часть из серии Объяснение Git:

git log

Команда 'git log' выводит список всех коммитов, доступных из определённого коммита.

git log feature
git log origin/feature

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

git log main feature
git log main feature

Возможно вы захотите исключить некоторые коммиты из git log. Следующие команды эквивалентны и перечисляют все коммиты доступные из feature, но не из main:

git log main..feature
git log ^main feature
git log feature --not main
git log main..feature

Ещё одно специальное обозначение - ... три точки, исключающее общего предка двух коммитов. В следующем примере, команда отобразит все коммиты, которые доступны либо из feature, либо из main, но не из обоих вместе:

git log main...feature
git log main...feature

git diff

git diff покажет различия (изменения) между коммитами.

Разделение двух коммитов пробелом или двумя точками покажет полную разницу между этими коммитами:

git diff main feature
git diff main..feature
-D
-E
-F
+G
+H
git diff main..feature

Другой способ подумать об этом: какие изменения нужно применить, что бы перейти от main к feature? В предыдущем примере, нужно сначала "отменить" коммиты F, E, и D, а затем применить коммиты G и H.

Использование троеточия ... удобно для отображения изменений только определённой ветви:

git diff main...feature
+G
+H
git diff main...feature

В этом примере показаны только различия в feature по сравнению с main.

Примеры

Далее приведены несколько распространённых случаев использования команд log и diff.

Предварительный просмотр запроса на пулл

Просмотр запроса на пулл в GitHub, под капотом, использует git log и git diff. Например, во вкладке "Commits" отображаются все коммиты из feature, которые будут объединены с main:

GitHub Commits

Если вы хотите посмотреть коммиты перед созданием запроса на пулл, вот команда:

git log main..feature --reverse
* 11dcc47 - G
* b8434e1 - H

Во вкладке "Files changed" отображены фактические изменения, которые необходимо применить:

GitHub Files changed

Вот как это воспроизводится локально:

git diff main...feature
+ G
+ H

Amend

Если вы привыкли переписывать историю, amend - один из ваших лучших друзей. В следующем примере, в коммите 5c7a82 отсутствуют некоторые изменения. Что бы история Git оставалась чистой, мы внесли эти изменения (2b049ea):

* 2b049ea - (HEAD -> feature) Fix defect 47
| * 5c7a782 - (origin/feature) Fix defect 47
|/
* fb2546f - Add checkout page

Мы могли бы захотеть проверить, что мы исправили, прежде чем пушить наши правки:

git diff origin/feature feature
- Hello
+ Hello world

Правки выглядят хорошо, поэтому мы хоти запушить их. Исходный коммит 5c7a782 публичный, но он находится в нашей собственной ветке, поэтому мы решили "принудительно запушить" с помощью git push --force-with-lease.

Но что, если в этой же ветке работает кто-то ещё? После получения feature, они увидят инвертированный граф:

* 2b049ea - (origin/feature) Fix defect 47
| * 5c7a782 - (HEAD -> feature) Fix defect 47
|/
* fb2546f - Add checkout page

Теперь они заинтересовались изменениями в origin/feature по сравнению с их локальным коммитом (т.е. тем который был до нашей поправки). Другими словами, какое изменение необходимо применить, что бы перейти от feature к origin/feature:

git diff feature origin/feature
- Hello
+ Hello world

Обратите внимание, что diff выглядит так же, как и раньше, но на этот раз команда выглядит иначе из-за порядка коммитов:

Шпаргалки

Если вы используете эту статью в качестве руководства, вот вся информация в одном месте:

Git log cheatsheetGit diff cheatsheet

Дополнительные материалы

Предыдущая Статья

Объяснение Git: Переписывание истории

Следующая Статья

Прилипающие CSS Grid элементы