Важно понимать, что в Git, ветвях в некоторой степени является иллюзия. Git - это не про ветки . Git - это примерно коммиты .
Когда вы используете git merge
- или щелкающие кнопки GitHub для достижения слияния - вы получаете, как правило, новый коммит . Этот новый коммит не меняет - и буквально не может - изменять какие-либо существующие коммиты вообще. 1 Это новый коммит, поэтому он имеет новый, невиданный ранее ha sh ID.
Между тем, имена веток сами по себе просто фиксируют объект ha sh ID. Точнее говоря, каждое имя содержит один га sh ID. Эта фиксация - последняя фиксация, которая считается «на ветке». Другие, более ранние коммиты также могут быть в этой же ветке, и любая одна фиксация может быть - а многие из них - на многих ветвях одновременно .
Процесс создания нового фиксация в Git выполняется либо «в ветке» - в ситуации, когда специальное имя HEAD
содержит имя ветки, - либо в «режиме отсоединенной HEAD», где специальное имя HEAD
содержит необработанное га sh ID. Если это сделано «в ветке», последним шагом создания новой фиксации является запись Git идентификатора ha sh новой фиксации в имя текущей ветки, так что теперь это имя ветки идентифицирует новую фиксацию. Поскольку в настоящее время никакое другое имя ветки не обновляется, новая фиксация только в этой ветке.
Это относится и к git merge
тоже. 2 Итак, если вы находятся в ветке B
и запускают git merge A
, новый коммит ha sh ID записывается в имя B
. Это означает, что ветка B
имеет новую фиксацию в качестве последней фиксации. Новая фиксация, однако, имеет не только один обычный родительский элемент, но вместо этого имеет два: первый родительский элемент является обычным первым родительским элементом, а второй родительский элемент - это фиксация конца ветки A
. Итак, все коммиты, которые раньше были только в ветке A
, теперь находятся в обеих ветвях. Но имя A
не обновляется, поэтому новый коммит слияния (пока) не присутствует в ветке A
.
Теперь можно переместить имя A
таким образом, чтобы слияние происходило в обеих ветвях, но вы должны сделать это как отдельный шаг, если хотите это сделать.
1 Это связано с фундаментальным свойством всех Git объектов: идентификатор объекта Git является криптографией c ha sh его содержимого. Если вы возьмете контент из некоторого существующего объекта, измените его и поместите обратно в Git, то вы получите новый и другой объект с новым и другим ha sh ID . Старый объект все еще существует под своим старым идентификатором ha sh ID, без изменений.
2 В этом абзаце описываются истинные слияния, выполняемые git merge --no-ff
или git merge
, для которых требуется истинное слияние. С командной строкой Git, git merge --ff-only
или git merge
, которая в противном случае разрешает операцию быстрой перемотки вперед, в конце концов не создает новую фиксацию.
При использовании GitHub для слияния (но не для «перебазирования и слияния "или" squa sh and merge ") интерфейс GitHub выполняет истинное слияние, даже если возможна операция быстрой перемотки вперед.