Каков наилучший (и самый безопасный) способ объединить ветку Git с master? - PullRequest
1880 голосов
/ 09 апреля 2011

Создается новая ветвь из master, мы называем ее test.

Есть несколько разработчиков, которые либо обязуются master, либо создают другие ветви, а затем объединяются в master.

Допустим, работа над test занимает несколько дней, и вы хотите постоянно обновлять test с коммитами внутри master.

Я бы сделал git pull origin master из test.

Вопрос 1: Это правильный подход?Другие разработчики могли бы легко работать с теми же файлами, что и я.


Моя работа над test завершена, и я готов объединить ее с master.Вот два способа, о которых я могу думать:

A:

git checkout test
git pull origin master
git push origin test
git checkout master
git pull origin test 

B:

git checkout test
git pull origin master
git checkout master
git merge test

Я не использую --rebase, потому что, насколько я понимаю, rebase получит изменения от master и поставит их поверх этого, следовательно, это может перезаписать изменения, сделанные другими людьми.

Вопрос 2: Какой из этих двух методов является правильным?В чем разница?

Цель всего этого состоит в том, чтобы обновлять мою ветку test в соответствии с событиями, происходящими в master, и позже я мог бы объединить их в master в надежде сохранитьграфик как можно более линейный.

Ответы [ 8 ]

2738 голосов
/ 09 апреля 2011

Как бы я это сделал

git checkout master
git pull origin master
git merge test
git push origin master

Если у меня есть локальная ветвь с удаленной, я не чувствую себя комфортно при объединении других ветвей, кроме этой, с удаленной.Кроме того, я не буду продвигать свои изменения, пока я не буду доволен тем, что я хочу подтолкнуть, а также я вообще не буду продвигать вещи, которые предназначены только для меня и моего локального хранилища.В твоем описании кажется, что test только для тебя?Так что нет причин публиковать его.

git всегда старается уважать ваши и другие изменения, как и --rebase.Я не думаю, что могу объяснить это должным образом, поэтому взгляните на книгу Git - Перебазирование или git-ready: введение в перебазирование для небольшого описания.Это довольно крутая функция

346 голосов
/ 14 марта 2015

Это очень практичный вопрос, но все ответы выше не практичны.

Как и

git checkout master
git pull origin master
git merge test
git push origin master

Этот подход имеет два вопроса :

  1. Это небезопасно, потому что мы не знаем, есть ли какие-либо конфликты между тестовой ветвью и главной ветвью.

  2. Это "сжало бы" все коммиты тестав одно слияние совершить на мастере;то есть в основной ветке, мы не можем видеть все журналы изменений тестовой ветви.

Итак, когда мы подозреваем, что будут некоторые конфликты, у нас могут быть следующие операции git:

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

Тест merge до commit, избегайте ускоренной фиксации на --no-ff,

Если возник конфликт, мы можем запустить git status, чтобы проверить подробности оконфликты и попытаться разрешить

git status

После того, как мы разрешим конфликты или если конфликта не будет, мы commit и push их

git commit -m 'merge test branch'
git push

Но так будетпотеря истории изменений, зарегистрированных в тестовой ветке, и другим разработчикам будет трудно понять историю проекта.

Так что лучший способ - использовать rebase вместо merge (предположим, когда в это время мы разрешили конфликты ветвей).

Ниже приведен один простой пример, для продвинутых операций, пожалуйста, обратитесь к http://git -scm.com / book /ru / v2 / Git-Branching-Rebasing

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

Да, когдаЕсли вы сделали верх, все коммиты тестовой ветки будут перенесены в заголовок ветки Master.Основным преимуществом перебазирования является то, что вы получаете линейную и намного более чистую историю проекта.

Единственное, чего вам следует избегать: никогда не используйте rebase в публичной ветке, например, в основной ветке.

Никогда не выполняйте операции , например:

git checkout master
git rebase -i test

Подробная информация о https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasing

приложении:

85 голосов
/ 10 апреля 2011

Ни перебазировка, ни слияние не должны перезаписывать чьи-либо изменения (если вы не решите сделать это при разрешении конфликта).

Обычный подход при разработке -

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge origin/test # to update your local test from the fetch in the pull earlier

Когда вы будете готовы объединиться с мастером,

git checkout master
git log ..test # if you're curious
git merge test
git push

Если вы беспокоитесь о том, чтобы что-то сломать при слиянии, git merge --abort для вас.

Глупо использовать push, а затем pull как средство слияния. Я также не уверен, почему вы отправляете тест на источник.

38 голосов
/ 21 апреля 2016

Я бы сначала сделал объединяемую ветвь максимально чистой. Запустите свои тесты, убедитесь, что состояние соответствует желаемому. Очистите новые коммиты git squash .

Помимо Ответ KingCrunches , я предлагаю использовать

git checkout master
git pull origin master
git merge --squash test
git commit
git push origin master

Возможно, вы сделали много коммитов в другой ветке, что должно быть только одним коммитом в основной ветке. Чтобы сохранить историю коммитов настолько чистой, насколько это возможно, вы можете сжать все свои коммиты из тестовой ветки в один коммит в основной ветке (см. Также: Git: сквошить или не давить? ). Затем вы также можете переписать сообщение коммита в нечто очень выразительное. Что-то, что легко читать и понимать, не копаясь в коде.

edit: Возможно, вас заинтересует

Итак, на GitHub я делаю следующее для ветви функций mybranch:

Получить последнюю версию от происхождения

$ git checkout master
$ git pull origin master

Найдите базовый хеш слияния:

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

Теперь убедитесь, что только первое pick, остальное s:

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

Далее выберите очень хорошее сообщение коммита и нажмите на GitHub. Сделайте запрос на извлечение.

После объединения запроса на удаление вы можете удалить его локально:

$ git branch -d mybranch

и на GitHub

$ git push origin :mybranch
6 голосов
/ 17 марта 2016

Это рабочий процесс, который я использую на работе в команде.Сценарий такой, как вы описали.Во-первых, когда я заканчиваю работу над test, я перезагружаюсь с мастером, чтобы вытянуть то, что было добавлено к мастеру за время, когда я работал над веткой test.1006 *

Это приведет к изменениям мастера, поскольку вы разветвляли ветвь test и применяете их, а затем применяете изменения, которые вы сделали, чтобы проверить "поверх" текущего состояния мастера.Здесь могут возникнуть конфликты, если другие люди внесли изменения в те же файлы, которые вы редактировали в тесте.Если есть, вам придется исправить их вручную и зафиксировать.Как только вы это сделаете, вам будет удобно переключиться на основную ветку и объединить test без проблем.

4 голосов
/ 31 октября 2018

Старая тема, но я не нашел способ сделать это.Это может быть полезно для тех, кто работает с rebase и хочет объединить все коммиты из ветки поверх master.Если есть конфликт, вы можете разрешить его для каждого коммита.

Обновление мастер и ветвь:

git checkout master
git pull --rebase origin master
git checkout <branch_name>
git pull --rebase origin <branch_name>

Слияние ветки поверх Мастера:

git checkout <branch_name>
git rebase master

Если вы столкнетесь с конфликтами во время перебазировки:

Сначала разрешите конфликт в файле.Затем:

git add .
git rebase --continue

Как только перебазирование закончено, перебазировать ветку поверх мастера:

git checkout master
git rebase <branch_name>
3 голосов
/ 13 сентября 2018

Я бы использовал метод rebase. Главным образом потому, что он идеально отражает ваш случай семантически, т.е. то, что вы хотите сделать, это обновить состояние вашей текущей ветви и «притвориться», как будто оно основано на последней версии.

Итак, даже не проверяя master, я бы:

git fetch origin
git rebase -i origin/master
# ...solve possible conflicts here

Конечно, просто выборка из источника не обновляет локальное состояние вашего master (так как оно не выполняет слияние), но это совершенно нормально для нашей цели - мы хотим избежать переключения, ради экономии времени.

3 голосов
/ 07 апреля 2015
git checkout master
git pull origin master
# Merge branch test into master
git merge test

Если после слияния файл был изменен, то при слиянии он возникнет из-за ошибки «Resolve Conflict»

Итак, вам нужно сначала разрешить все ваши конфликты, затем вы должны снова зафиксировать все свои изменения и затем нажать

git push origin master

Это лучше делать тем, кто внес изменения в тестовую ветку, потому что он знал, какие изменения он сделал.

...