Что произойдет, если я попытаюсь переустановить фиксацию, которая уже отправлена в ветку разработки
Пример использования следующий
Я беру из ветки разработки, вношу некоторые изменения в код и нажимаю затем
Через несколько дней я возвращаюсь и перехожу к статусу git, это показывает, что я опережаю основную ветку на 1 коммит, очевидно, я не получал от мастера пару дней
Теперь, прежде чем я внесу свои изменения, я решаю сделать git pull с rebase, git pull --rebase origin master
Возникает вопрос: будет ли коммит, который у меня был в моей локальной ветке репо, выполняться поверх мастера, или, поскольку я уже нажал его, я просто перейду к вершине глобальной ветки master/remote?
Я новичок в концепции перебазирования, поэтому, пожалуйста, помогите объяснить это.
2 ответа
Рассмотрим следующее.
D---E---F origin/master
/
A---B---C---X master
^
origin/master in your repository
Несколько дней назад ваш локальный мастер и origin/master были синхронизированы, и у каждого из них были коммиты A
, B
а также C
. В какой-то момент вы совершилиX
в вашем местном мастере. И одновременно другие нажимали коммитыD
, E
а также F
к происхождению / мастеру.
На этом этапе, если вы запустите git pull --rebase originmaster
, будет извлекать все коммиты из источника / мастера как есть, а фиксация X
будет воспроизводиться поверх F
и будет сгенерирован новый идентификатор фиксации X'
.
Новый график фиксации будет выглядеть так:
origin/master
/
A---B---C---D---E---F---X' master
^
origin/master in your repository
Так что да, старый коммит X
будет перебазирован в верхней части вашего локального мастера как фиксация X'
.
РЕДАКТИРОВАТЬ:
вопрос в этом варианте использования: что, если бы я нажал X, а затем были созданы D, E, F, как будет выглядеть моя локальная ветвь после того, как я выполню вытягивание с rebase сейчас?
В этом случае после нажатия вашего коммита X ваш локальный репозиторий и origin/master будут синхронизированы.
origin/master
/
A---B---C---X master
^
origin/master in your repository
Через несколько дней коммиты D
, E
а также F
подталкиваются другими к источнику / мастеру. График фиксации будет выглядеть так:
D---E---F origin/master
/
A---B---C---X master
^
origin/master in your repository
Теперь, если ты бежишь git pull --rebase originmaster
он даст идентичные результаты git pull originmaster
команда, потому что не из чего делать перебаз. У вас нет никаких коммитов перед origin/master. В конце этой команды ваш график будет выглядеть так:
origin/master
/
A---B---C---X---D---E---F master
^
origin/master in your repository
Поскольку ваша фиксация X
уже был в origin/master, он не будет воспроизводиться поверх D
, E
а также F
.
Возникает вопрос: будет ли коммит, который у меня был в моей локальной ветке репо, выполняться поверх мастера, или, поскольку я уже нажал его, я просто перейду к вершине глобальной ветки master/remote?
Если под "глобальным" вы имеете в виду "удаленный", то да, ваша локальная ветка будет перебазирована поверх origin/master
. См. Ниже более подробное объяснение.
Исходя из вашего вопроса, ваш репозиторий начинал выглядеть так:
o---o--------------o
^ ^
master development
origin/master origin/development
Ваш местный master
ветка была синхронизирована с удаленным origin/master
ветвь; Кроме того, у вас был местныйdevelopment
ветка с 1 фиксацией, которую вы отправили в удаленный репозиторий, создав таким образом origin/development
.
Теперь, если ваша текущая ветка development
, если ты бежишь
git pull --rebaseoriginmaster
Git будет извлекать любые новые объекты из origin
удаленный и обновите свою ветку удаленного отслеживания origin/master
:
origin/master
⌄
o---o---o
/
o---o--------------o
^ ^
master development
origin/development
Затем он перебазирует вашу текущую ветку (в данном случаеdevelopment
) поверх обновленного origin/master
филиал:
origin/master development
⌄ ⌄
o---o---o--------------o'
/
o---o--------------o
^ ^
master origin/development
Обратите внимание, что ваш местный master
ветка по-прежнему указывает на ту же фиксацию, что и раньше - это потому, что вторая часть git pull
(слияние или перебазирование) всегда работает с текущей веткой, в вашем случаеdevelopment
.
Теперь, если бы вы подтолкнули свой местный development
ветвь после завершения операции извлечения, вы должны обновить origin/development
ветка удаленного отслеживания, указывающая на фиксацию перебазирования:
origin/development
origin/master development
⌄ ⌄
o---o---o--------------o'
/
o---o
^
master
Опять же, ваш местный master
не изменяется, пока вы не сделаете:
git checkout master && git merge origin/master
В git pull
Команда - сложный зверь, поскольку она делает совершенно разные вещи в зависимости от того, в какой ветке вы ее вызываете и какие аргументы вы ей передаете.
Вот что говорится в документации о форме с тремя аргументами:
Слить с текущей веткой удаленную ветку следующим образом:
$ git pull origin next
Это оставляет копию следующего временно в
FETCH_HEAD
, и обновляет ветку удаленного отслеживанияorigin/next
.
Я также предлагаю прочитать этот ответ для более подробного объяснения того, какgit pull
ведет себя в разных сценариях.