Что произойдет, если я попытаюсь переустановить фиксацию, которая уже отправлена ​​в ветку разработки

Пример использования следующий

Я беру из ветки разработки, вношу некоторые изменения в код и нажимаю затем

Через несколько дней я возвращаюсь и перехожу к статусу 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 ведет себя в разных сценариях.

Другие вопросы по тегам