Объяснение Git: Диапазоны коммитов
log
и diff
полезны для проверки изменений вашего репозитория. Обе команды принимают диапазоны коммитов в разных форматах, что может сбивать с толку. В этой статье я пролью свет на различия между диапазонами коммитов a b
, a..b
, a...b
.Скачайте репозиторий который я буду использовать в качестве примера.
Это вторая часть из серии Объяснение Git:
- Часть 1: Переписывание истории
- Часть 2: Диапазоны коммитов
git log
Команда 'git log' выводит список всех коммитов, доступных из определённого коммита.
git log feature
![git log origin/feature](images/log-feature.png)
Вы так же можете указать несколько коммитов, разделённых пробелом, мы получим список всех коммитов которые доступные из любого из них:
git log main feature
![git log main feature](images/log-main-feature.png)
Возможно вы захотите исключить некоторые коммиты из git log
. Следующие команды эквивалентны и перечисляют все коммиты доступные из feature
, но не из main
:
git log main..feature
git log ^main feature
git log feature --not main
![git log main..feature](images/log-main-dd-feature.png)
Ещё одно специальное обозначение - ...
три точки, исключающее общего предка двух коммитов. В следующем примере, команда отобразит все коммиты, которые доступны либо из feature
, либо из main
, но не из обоих вместе:
git log main...feature
![git log main...feature](images/log-main-ddd-feature.png)
git diff
git diff
покажет различия (изменения) между коммитами.
Разделение двух коммитов пробелом или двумя точками покажет полную разницу между этими коммитами:
git diff main feature
git diff main..feature
-D
-E
-F
+G
+H
![git diff main..feature](images/diff-main-dd-feature.png)
Другой способ подумать об этом: какие изменения нужно применить, что бы перейти от main
к feature
? В предыдущем примере, нужно сначала "отменить" коммиты F
, E
, и D
, а затем применить коммиты G
и H
.
Использование троеточия ...
удобно для отображения изменений только определённой ветви:
git diff main...feature
+G
+H
![git diff main...feature](images/diff-main-ddd-feature.png)
В этом примере показаны только различия в feature
по сравнению с main
.
Примеры
Далее приведены несколько распространённых случаев использования команд log
и diff
.
Предварительный просмотр запроса на пулл
Просмотр запроса на пулл в GitHub, под капотом, использует git log
и git diff
. Например, во вкладке "Commits" отображаются все коммиты из feature
, которые будут объединены с main
:
![GitHub Commits](images/pr-commits.png)
Если вы хотите посмотреть коммиты перед созданием запроса на пулл, вот команда:
git log main..feature --reverse
* 11dcc47 - G
* b8434e1 - H
Во вкладке "Files changed" отображены фактические изменения, которые необходимо применить:
![GitHub Files changed](images/pr-changes.png)
Вот как это воспроизводится локально:
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 cheatsheet](images/git-log.png)
![Git diff cheatsheet](images/git-diff.png)