Если мы сделаем sh от локального до удаленного коммита, который представляет собой слияние фиксации ветки X и фиксации функции Y, но в удаленной фиксации Y нет, будет ли это работать? - PullRequest
2 голосов
/ 05 мая 2020

У меня есть такая ситуация, которую я пытаюсь понять.

at T1 Local                         |       at T1 Remote:
------------------------------------------------------------------------
 E--F featureOne                    |        E--F featureOne
/                                   |       /
A--B--C--D branchOne                |       A--B--C--D branchOne
------------------------------------------------------------------------


at T2 Local                         |       at T2 Remote:
------------------------------------------------------------------------
merged branchOne into featureOne:   |
   E------F   featureOne            |    E--F featureOne    
  /        \                        |   /       
 /          G                       |   A--B--C--D branchOne                    
/          /                        |               
A--B--C----D branchOne              |                           
------------------------------------------------------------------------


at T3 Local                         |       at T3 Remote:
------------------------------------------------------------------------
merged featureOne into branchOne    |
after git pull branchOne            |
from Remote:                        |
   E------F                         |    E--F featureOne    
  /        \                        |   /       
 /          G-. featureOne          |   A--B--C--D branchOne                    
/          /   \                    |               
A--B--C----D-----H branchOne        |                           
------------------------------------------------------------------------

H в local - это слияние коммитов между G featureOne и D ветки BranchOne. Поскольку в удаленном режиме у нас нет G, что произойдет, скажем, в T4, если я сделаю sh branchOne с локального на удаленный (origin / branchOne)? Он сольется? К сожалению, я не могу попробовать это, потому что я сначала переместил G из локального featureOne в удаленный featureOne, а затем переместил H из локального branchOne в удаленный BranchOne.

1 Ответ

1 голос
/ 05 мая 2020

Что делает git push, так это отправляет ваши коммиты - некоторые или все (или иногда ни одного) из тех, которые у вас есть, а у некоторых других Git нет - другому Git в вопросе, затем попросите этот другой Git установить некоторые из их имена на какой-то коммит ha sh ID.

Итак, если у вас есть:

 E--F--G____
/       \   \
A--B--C--D--H

в вашем репозитории - независимо от того, где находится какая-либо из ваших веток имена точки - и вы говорите своему Git отправить фиксацию H другому Git, ваш Git вызовет другой Git и предложит совершить H.

(Примечание: здесь я предполагаю, что фиксация G представляет собой слияние F и D. Описание вашего вопроса проясняет, что это так. Я бы сам нарисовал график немного по-другому; см. ниже.)

(Те же рассуждения применимы, если вы попросите свой Git явно отправить им коммит G, но в этом конкретном случае ваш Git должен предложить G после предложения H и их принятия, поэтому мы просто будем беспокоиться бой H здесь. Кроме того, вы спросили о git push branchOne, где ваше имя branchOne указывает на фиксацию H.)

Если у них есть фиксация H, эта часть git push выполнена. В этом случае у них нет фиксации H, поэтому ваш Git будет предлагать фиксации G и D, потому что это родители H. Если у них есть эти коммиты, эта часть git push выполнена: ваш Git отправляет фиксацию H (только). Если им не хватает одного или нескольких коммитов, ваш Git предлагает [оставшимся] родителям G и / или D, то есть F и C. Если у них есть эти коммиты, эта часть git push выполнена: ваш Git отправляет фиксацию H, плюс фиксацию G и / или D по мере необходимости.

Итак, давайте посмотрим на что у них есть:

  E--F   <-- featureOne
 /
A--B--C--D   <-- branchOne

Здесь уже есть коммиты F и D. Итак, ваш Git предлагает H, и они принимают; ваши Git предлагает G, и они принимают; ваш Git предлагает D и они говорят нет, спасибо, у меня уже есть; и ваш Git предлагает совершить F, и они говорят нет, спасибо, у меня уже есть это один . Ваш Git затем отправляет им коммиты G и H, которые они вставляют в свой график. Их существующие имена веток на этом этапе все еще указывают на коммиты F (featureOne) и D (branchOne) соответственно.

На этом этапе ваш Git входит в последнюю фазу of git push, то есть попросить их установить некоторый набор их имен для некоторых коммитов. Здесь содержится точное написание того, что вы дали команде git push:

git push branchOne

Это неправильное написание, которое должно быть:

git push origin branchOne

Часть origin - это то, как вы сообщаете своему Git, какой еще Git звонить. Часть имени, branchOne, является сокращением от этого альтернативного написания:

git push origin branchOne:branchOne

Левая часть двоеточия : символ - это то, как ваш Git находит начальную фиксацию предлагать. В этом случае ваше имя branchOne указывает на ваш коммит H, так что коммит, который предлагает ваш Git, начинается.

Правая часть двоеточия : символ предоставляет имя ветки вы просите их до установить в их Git репозиторий. Используя здесь branchOne, вы в конечном итоге попросите их указать свое имя branchOne, указывающее на фиксацию H.

Будет ли оно объединено?

Команда git push никогда не вызывает слияния . Он просто отправляет существующие коммиты, которые у вас есть, которых нет , затем просит их установить некоторые имена (обычно имена веток). Их Git может принять или отклонить этот запрос для установки имен веток.

Если вы нажимаете на GitHub, и кто-то включил режим «защищенной ветки» для имени ветки branchOne в репозиторий Git на GitHub, они отклонят эту попытку изменить имя, потому что ветка защищена.

Однако в большинстве случаев они примут этот запрос на изменение имени. В настоящее время у них есть свое имя branchOne, идентифицирующее фиксацию D. Коммит H имеет коммит D в качестве предка - фактически, в качестве непосредственного родителя - поэтому эта операция является быстрой перемоткой вперед (а не быстрым слиянием вперед , просто a перемотка вперед ), что делает запрос приемлемым.

Обратите внимание, что этот не просит их указать свое имя featureOne вообще. Их имя featureOne будет продолжать указывать туда, куда оно указывало раньше, например, на фиксацию F. Например, для целей публикации StackOverflow я бы нарисовал это как:

    E------F   <-- featureOne
   /        \
  /          G-.
 /          /   \
A--B--C----D-----H   <-- branchOne

. (Я переместил G вперед, так как он явно предназначен для слияния D и F, и, как вы его нарисовали, похоже, что D представляет собой слияние C и G.)

Примечания

Если вы используете синтаксис двоеточия:

git push origin <commit-specifier>:<name>

, вы можете использовать здесь любой произвольный спецификатор фиксации слева. Это может быть имя ветки, имя тега, имя HEAD, относительное имя, например master~3, запись в рефлоге, например develop@{yesterday}, или даже необработанный идентификатор ha sh. Если вы используете необработанный идентификатор ha sh слева и хотите, чтобы другой Git создал новое имя ветки , вы должны написать полное имя:

git push origin a123456:refs/heads/new-branch

Сокращение, например:

git push origin a123456:existing-branch

, основано на их Git совпадении имени existing-branch с одним из существующих имён веток.

Если вы используете форму без двоеточия, вы должны использовать имя, так как это имя должно быть отправлено другому Git.

Вы можете git push более одного объекта на a время:

git push origin master dev feature

или:

git push origin master~3:refs/heads/new-temp-branch dev a123456:refs/tags/v1.2

Предполагая, что имя new-temp-branch еще не существует в Git at origin, эта последняя версия использует одно относительное имя (master~3), чтобы создать новую ветку с именем new-temp-branch. Он использует одно выражение без двоеточия для отправки фиксации подсказки локальной ветки dev и запроса создания или обновления имени своей ветки dev соответственно. И он использует необработанный идентификатор ha sh (a123456), чтобы запросить создание или обновление имени тега v1.2. Обновление имени тега обычно запрещено, 1 , поэтому мы ожидаем, что это создаст новое имя тега.


1 В * 1234 произошла ошибка * версии до 1.8.2 или 1.8.4, в которых случайно разрешалось не принудительное обновление имени тега с использованием того же правила, что и для обновления имени ветки.

...