Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
- 2.43.1 → 2.51.0 no changes
-
2.43.0
2023-11-20
- 2.39.1 → 2.42.4 no changes
-
2.39.0
2022-12-12
- 2.24.1 → 2.38.5 no changes
-
2.24.0
2019-11-04
- 2.23.1 → 2.23.4 no changes
-
2.23.0
2019-08-16
- 2.19.3 → 2.22.5 no changes
-
2.19.2
2018-11-21
- 2.16.6 → 2.19.1 no changes
-
2.15.4
2019-12-06
- 2.11.4 → 2.14.6 no changes
-
2.10.5
2017-09-22
- 2.1.4 → 2.9.5 no changes
-
2.0.5
2014-12-17
СИНОПСИС
git merge-base [-a | --all] <commit> <commit>… git merge-base [-a | --all] --octopus <commit>… git merge-base --is-ancestor <commit> <commit> git merge-base --independent <commit>… git merge-base --fork-point <ref> [<commit>]
ОПИС
«git merge-base» знаходить найкращого спільного предка (або спільних предків) між двома комітами для використання у тристоронньому злитті. Один спільний предок є «кращим» за іншого спільного предка, якщо останній є предком першого. Спільний предок, який не має жодного кращого спільного предка, є «найкращим спільним предком», тобто «базою злиття». Зверніть увагу, що для пари комітів може бути більше однієї бази злиття.
РЕЖИМИ РОБОТИ
У найпоширенішому окремому випадку, зазначення лише двох комітів у командному рядку означає обчислення бази злиття між двома заданими комітами.
У більш загальному випадку, серед двох комітів, з яких обчислюється база злиття, один визначається першим аргументом коміта в командному рядку; інший коміт є (можливо, гіпотетичним) комітом, який є злиттям усіх решти комітів у командному рядку.
Як наслідок, «база злиття» не обов’язково міститься в кожному з аргументів комітів, якщо вказано більше двох комітів. Це відрізняється від git-show-branch[1], коли використовується з опцією --merge-base
.
- --octopus
-
Обчисліть найкращих спільних предків усіх наданих комітів, готуючись до n-стороннього злиття. Це імітує поведінку git show-branch --merge-base.
- --independent
-
Замість виведення баз злиття, виведіть мінімальну підмножину наданих комітів з тими ж предками. Іншими словами, серед наданих комітів перелічіть ті, до яких неможливо дістатися з жодного іншого. Це імітує поведінку git show-branch --independent.
- --is-ancestor
-
Перевірити, чи перший <commit> є предком другого <commit>, та завершити роботу зі статусом 0, якщо це правда, або зі статусом 1, якщо ні. Помилки сигналізуються ненульовим статусом, який не дорівнює 1.
- --fork-point
-
Знайти точку, в якій гілка (або будь-яка історія, що веде до <commit>) відгалужується від іншої гілки (або будь-якого посилання) <ref>. Це не лише шукає спільного предка двох комітів, але й враховує рефлог <ref>, щоб побачити, чи історія, що веде до <commit>, відгалужується від попередньої версії гілки <ref> (див. обговорення цього режиму нижче).
ОБГОВОРЕННЯ
Враховуючи два коміти A та B, git
merge-base
A
B
виведе коміт, який доступний як з A, так і з B через батьківське відношення.
Наприклад, з такою топологією:
o---o---o---B / ---o---1---o---o---o---A
База злиття між A та B дорівнює 1.
Враховуючи три коміти A, B та C, git
merge-base
A
B
C
обчислить базу злиття між A та гіпотетичним комітом M, який є злиттям між B та C. Наприклад, з такою топологією:
o---o---o---o---C / / o---o---o---B / / ---2---1---o---o---o---A
Результат git
merge-base
A
B
C
дорівнює 1. Це тому, що еквівалентна топологія зі злиттям M між B та C така:
o---o---o---o---o / \ / o---o---o---o---M / / ---2---1---o---o---o---A
а результатом git
merge-base
A
M
є 1. Commit 2 також є спільним предком між A та M, але 1 є кращим спільним предком, оскільки 2 є предком 1. Отже, 2 не є базою злиття.
Результатом виконання git
merge-base
--octopus
A
B
C
буде 2, оскільки 2 є найкращим спільним предком усіх комітів.
Коли історія включає перехресні злиття, може бути більше одного «найкращого» спільного предка для двох комітів. Наприклад, з такою топологією:
---1---o---A \ / X / \ ---2---o---o---B
Як 1, так і 2 є базами злиття A та B. Жодна з них не краща за іншу (обидві є «найкращими» базами злиття). Якщо опція --all
не вказана, не вказано, яка з них найкраща виводиться.
Поширеною ідіомою для перевірки "швидкого перемотування" між двома комітами A та B є (або принаймні раніше використовувалася) обчислення бази злиття між A та B та перевірка, чи вона така ж, як A, і в цьому випадку A є предком B. Ви часто побачите цю ідіому у старіших скриптах.
A=$(git rev-parse --verify A) if test "$A" = "$(git merge-base A B)" then ... A is an ancestor of B ... fi
У сучасному git це можна сказати більш прямо:
if git merge-base --is-ancestor A B then ... A is an ancestor of B ... fi
замість цього.
Обговорення режиму розгалуження
Після роботи над гілкою topic
, створеною за допомогою git
switch
-c
topic
origin/master
, історія гілки віддаленого відстеження origin/master
могла бути перемотана та перебудована, що призвело до історії такої форми:
o---B2 / ---o---o---B1--o---o---o---B (origin/master) \ B0 \ D0---D1---D (topic)
де origin/master
раніше вказував на коміти B0, B1, B2, а тепер вказує на B, і ваша гілка topic
була запущена поверх неї, коли origin/master
була в B0, і ви створили три коміти, D0, D1 та D, поверх неї. Уявіть, що тепер ви хочете перебазувати роботу, яку ви виконали над темою, поверх оновленого origin/master.
У такому випадку, git
merge-base
origin/master
topic
поверне батьківський елемент B0 на зображенні вище, але B0^..D не є діапазоном комітів, які ви хочете відтворити поверх B (він включає B0, що не те, що ви написали; це коміт, який інша сторона відкинула, коли перемістила свою кінчику з B0 до B1).
Команда git
merge-base
--fork-point
origin/master
topic
розроблена для допомоги в такому випадку. Вона враховує не лише B, але й B0, B1 та B2 (тобто старі підказки гілок віддаленого відстеження, про які знає reflog вашого репозиторію), щоб побачити, на якому коміті була зібрана ваша тематична гілка, та знаходить B0, що дозволяє вам відтворити лише коміти у вашій темі, виключаючи коміти, які інша сторона пізніше відкинула.
Отже
$ fork_point=$(git merge-base --fork-point origin/master topic)
знайде B0, і
$ git rebase --onto origin/master $fork_point topic
відтворить D0, D1 та D поверх B, щоб створити нову історію цієї фігури:
o---B2 / ---o---o---B1--o---o---o---B (origin/master) \ \ B0 D0'--D1'--D' (topic - updated) \ D0---D1---D (topic - old)
Застереження полягає в тому, що старіші записи reflog у вашому репозиторії можуть бути застарілі за допомогою git
gc
. Якщо B0 більше не відображається в reflog гілки віддаленого відстеження origin/master
, режим --fork-point
очевидно не може його знайти та завершує роботу, уникаючи видачі випадкового та непотрібного результату (наприклад, батьківського елемента B0, як це дає та сама команда без опції --fork-point
).
Також, гілка віддаленого відстеження, з якою ви використовуєте режим --fork-point
, має бути тією, з якої ваша тема відгалужується від її кінчика. Якщо ви відгалужувалися від коміту, старішого за кінчик, цей режим не знайде точку відгалуження (уявіть, що у наведеному вище прикладі історії B0 не існує, origin/master починався з B1, перемістився до B2, а потім до B, і ви відгалужували свою тему в origin/master^, коли origin/master був B1; форма історії була б такою ж, як і вище, без B0, а батьківська гілка B1 - це те, що git
merge-base
origin/master
topic
правильно знаходить, але режим --fork-point
не знайде цього, оскільки це не один з комітів, які раніше були на кінчику origin/master).
GIT
Частина набору git[1]