Обновление веток Git от мастера


676

Я новичок в Git, и теперь я в этой ситуации:

  • У меня есть четыре ветви (мастер, b1, b2 и b3).
  • После того, как я поработал на b1-b3, я понял, что мне нужно что-то изменить на ветке master, которая должна быть во всех других ветках.
  • Я изменил то, что мне было нужно, masterи ... вот моя проблема:

Как мне обновить все остальные ветви с помощью masterкода филиала?



59
Еще одна простая задача, затрудненная Git. Разработчики Git должны использовать переполнение стека в качестве обратной связи в своем цикле SDLC. 300 000 человек должны указать, что что-то не так с рабочим процессом Git. Им нужно нанять эксперта по UX, потому что они явно не могут сделать это самостоятельно.
августа

Ответы:


621

У вас есть два варианта:

Первый - это слияние, но это создает дополнительный коммит для слияния.

Оформить заказ каждой ветви:

git checkout b1

Затем объедините:

git merge origin/master

Затем нажмите:

git push origin b1

Кроме того, вы можете сделать ребаз:

git fetch
git rebase origin/master

15
Я обеспокоен этим подходом. Когда я запускаю git log --graph, график показывает, что мастер фактически объединен с веткой темы. Это вызовет какие-либо проблемы в долгосрочной перспективе? Я думал, что лучшая практика - это всегда объединять ветку темы с мастером. Прокомментируйте, пожалуйста.
Патрик

2
Обращайте внимание на эту проблему, если вы собираетесь использовать рабочий процесс слияния: randyfay.com/node/89
Hampus Ahlgren

22
Вы объединяете мастера в b1. Почему ты got push origin master... не имеет смысла. Вы не меняете основную ветку. Я думаю, что это ошибка с 119 upvote: /
Ив Ланге

22
Не используйте метод слияния, используя git rebase masterправильный ответ
Уэстон Гангер

6
Для тех из нас, кто читает позже - беспокойство @Kursion по поводу опечатки было решено редактором автора. Кроме того, второй ответ с наивысшим рейтингом ниже говорит в основном то же самое, что и этот ответ, но с диаграммой структуры ветвей и предупреждением о том, почему вы не хотите перебазировать.
beyondtheteal

496

У вас есть в основном два варианта:

  1. Вы сливаетесь. На самом деле это довольно простая и совершенно локальная операция:

    git checkout b1
    git merge master
    # repeat for b2 and b3
    

    Это оставляет историю в точности так, как это произошло: вы разветвились от мастера, вы внесли изменения во все ветви и, наконец, включили изменения от мастера во все три ветви.

    gitможет справиться с этой ситуацией действительно хорошо, он предназначен для слияния, происходящего во всех направлениях, в то же время. Вы можете доверять этому, чтобы быть в состоянии собрать все нити вместе правильно. Ему просто не важно, b1сливается ветвь masterили masterсливается b1, коммит слияния выглядит все равно для git. Разница лишь в том, какая ветвь в конечном итоге указывает на этот коммит слияния.

  2. Вы перебазируете. Люди с SVN или подобным опытом считают это более интуитивным. Команды аналогичны регистру слияния:

    git checkout b1
    git rebase master
    # repeat for b2 and b3
    

    Людям нравится такой подход, потому что он сохраняет линейную историю во всех отраслях. Однако эта линейная история - ложь, и вы должны знать, что это так. Рассмотрим этот граф коммитов:

    A --- B --- C --- D <-- master
     \
      \-- E --- F --- G <-- b1
    

    Результатом слияния становится реальная история:

    A --- B --- C --- D <-- master
     \                 \
      \-- E --- F --- G +-- H <-- b1
    

    Ребаз, однако, дает вам эту историю:

    A --- B --- C --- D <-- master
                       \
                        \-- E' --- F' --- G' <-- b1
    

    Дело в том, что коммиты E', F'и G'никогда по- настоящему существует, и никогда , вероятно , не были испытаны. Они могут даже не скомпилироваться. На самом деле довольно легко создавать бессмысленные коммиты через ребаз, особенно когда изменения masterважны для разработки в b1.

    Следствием этого может быть, что вы не можете определить , какой из трех коммитов E, Fи Gфактически ввел регрессию, уменьшая значение git bisect.

    Я не говорю, что вы не должны использовать git rebase. Это имеет свое применение. Но всякий раз, когда вы используете его, вы должны осознавать тот факт, что вы лжете об истории. И вы должны по крайней мере скомпилировать тест новых коммитов.


Я сливалась другой источник ветви (не мастер) и дополнительные шаги , чтобы добавить к этому хорошему ответу был , чтобы обновить его на моем локальном репо до слияния (иметь последнюю версию коды локально) git checkout <source branch> git pull. Тогда продолжаем с выше: git checkout b1...
Род

3
Как давний пользователь SVN, я предпочитаю вариант слияния перебазированию: при любом контроле версий очень и очень важно вести точный учет внесенных вами изменений и почему. Я вижу привлекательность перебазирования для упрощения кажущейся истории, но затем вам следует вернуться и добавить к коммиту комментарии E ', F', G '- и желательно, чтобы ребаз автоматически добавлялся к этим комментариям. В противном случае, если процесс build / test / test-deploy обрывается на G ', вам нужно выяснить, почему изменения были сделаны без полной информации.
WillC

13
История ложь
piratemurray

Спасибо, я использую "git merge any-branch-name", чтобы объединить один код ветви с другим. Локально я могу проверить код ветви 1 в то время как я нахожусь на ветви 2
Прити

1
@blamb Конфликты слияния случаются с обоими git mergeи git rebase. Там не избежать этого. git rebaseобладает тем преимуществом, что позволяет скрывать несколько этапов перебазировки (т.е. перебазировать одну и ту же ветку на несколько разных коммитов последовательно, чтобы уменьшить количество конфликтов на каждом этапе). Тем не менее, сам факт того, что ребаз лжет об истории, намного проще испортить добро в таком многоступенчатом ребазе ... Вот почему я всегда предпочитаю слияние, даже когда это означает, что мне нужно загромождать историю несколькими коммитами слияния ,
cmaster - восстановить

238

git rebase masterэто правильный способ сделать это. Слияние будет означать, что для слияния будет создан коммит, а перебазирование - нет.


52
Как насчет того, когда вы уже выдвинули к исходной точке, если вы перебазируете, вы будете переписывать историю коммитов, и это будет конфликтовать с вашей удаленной веткой. Я думаю, что rebase должен использоваться только при извлечении или когда вы не выдвинули удаленную ветку.
Мэтт Смит

6
Если вы единственный, кто работает с удаленной веткой, вы можете использовать функцию git push --force origin, чтобы обновить удаленную ветку перебазированной локальной веткой. stackoverflow.com/questions/8939977/…
stormwild

7
rebase и объединить обе работы, rebase лучше всего подходит для частных филиалов, потому что он дает более чистый график истории. этот ответ самый лучший
Junchen Liu

5
Необходимо прояснить компромисс между ясностью (отлично подходит для одного пользователя или небольшой команды) или грязной правдой (для веток кода с несколькими участниками - требуется для удобства обслуживания (по моему опыту - YMMV)).
WillC


53

Если вы работали над веткой время от времени или в других ветвях происходило много всего, когда вы работали над чем-то, лучше перенести вашу ветку на master. Это поддерживает историю в чистоте и делает вещи намного легче следовать.

git checkout master
git pull
git checkout local_branch_name
git rebase master
git push --force # force required if you've already pushed

Ноты:

  • Не рекламируйте ветки, с которыми вы сотрудничали.
  • Вы должны перебазировать ветку, с которой вы будете объединяться, которая не всегда может быть главной.

На сайте http://git-scm.com/book/ch3-6.html есть глава о перебазировании и множество других ресурсов в Интернете.


Спасибо за простое решение
другой Высокий парень

18

@cmaster сделал лучший подробный ответ. Вкратце:

git checkout master #
git pull # update local master from remote master
git checkout <your_branch>
git merge master # solve merge conflicts if you have`

Вы не должны переписывать историю ветвей, а сохранять их в актуальном состоянии для будущих ссылок. При слиянии с мастером создается один дополнительный коммит, но это дешево. Коммитов не стоит.


13

Для обновления других веток, таких как (резервная копия), с вашей копией главной ветки Вы можете следовать в любом случае (перебазировать или объединить) ...

  1. Сделайте ребаз (не будет никакого дополнительного коммита, сделанного в резервную ветку).
  2. Слияние веток (будет дополнительная фиксация автоматически в резервную ветку).

    Примечание: Rebase - это не что иное, как создание новой базы (новой копии)

git checkout backup
git merge master
git push

(Повторите для других веток, если они есть, например, backup2 и т. Д.,)

git checkout backup
git rebase master
git push

(Повторите для других веток, если они есть, например, backup2 и т. Д.,)



1

Есть два варианта этой проблемы.

1) git rebase

2) git merge

Только в случае слияния с обоими выше в случае слияния, будет иметь дополнительный коммит в истории

1) ветка git checkout (b1, b2, b3)

2) git rebase origin / master (в случае конфликтов разрешите локально, выполнив git rebase --continue)

3) git push

Альтернативно, опция git merge аналогична

1) git checkout "your_branch" (b1, b2, b3)

2) мастер слияния

3) git push


1

обновить ветку от мастера:

  git checkout master
  git pull
  git checkout your_branch
  git merge master
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.