Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чим HEAD~2 відрізняється від HEAD^2 і що означають діапазони A..B та A...B?

~ і ^ рухаються по батьках коміту, але по-різному:

  • ~n - n кроків назад по першому батькові: HEAD~1 - батько, HEAD~3 - прапрадід;
  • ^n - n-й батько коміту. Має сенс для merge-комітів, у яких батьків два: HEAD^1 - гілка, у яку зливали, HEAD^2 - гілка, яку зливали.
        D---E  (feature)
       /     \
  A---B---C---M  (main, HEAD)

HEAD~1 = HEAD^ = HEAD^1 = C
HEAD^2 = E
HEAD~2 = B
HEAD^2~1 = D

Для звичайного коміту з одним батьком HEAD~1 і HEAD^ однакові - різниця видна лише на merge-комітах.

Інші способи назвати коміт:

main@{yesterday}       # де була main вчора (за reflog)
@{-1}                  # попередня гілка
@{u}                   # upstream поточної гілки
HEAD^{tree}            # дерево коміту
:/fix invoice          # останній коміт з таким текстом у повідомленні
v2.4.0^{commit}        # коміт, на який вказує тег

Діапазони:

Запис Що означає
A..B коміти, досяжні з B, але не з A
A...B коміти, досяжні з A або B, але не з обох (симетрична різниця)
^A B те саме, що A..B
git log main..feature          # що є у feature і ще не злито в main
git log feature..main          # що з'явилося в main, поки ви працювали
git log --left-right --oneline main...feature   # обидві сторони з позначками < і >
git log origin/main..HEAD      # що ви ще не запушили

Пастка: .. і ... у git diff означають інше:

  • git diff A..B - те саме, що git diff A B: порівняння двох знімків;
  • git diff A...B - зміни в B від спільного предка з A. Саме так GitHub показує diff pull request-у: лише зміни гілки, без того, що за цей час з'явилося в main.

Тому git diff main...feature - правильний спосіб побачити «що змінює моя гілка», а git diff main feature покаже ще й чужі зміни в main з протилежним знаком.

Докладніше в документації: gitrevisions

Схожі питання