Слияние ветки разработки с мастером

764

У меня есть две ветви, а именно masterи developmentв репозитории GitHub. Я делаю все свои разработки в ветке разработки, как показано на рисунке.

git branch development
git add *
git commit -m "My initial commit message"
git push -u origin development

Теперь я хочу объединить все изменения на developmentветке в master. Мой текущий подход:

git checkout master 
git merge development
git push -u origin master 

Пожалуйста, дайте мне знать, если процедура, которой я следую, является правильной.

Паван
источник
7
git pull -uустанавливает отслеживание в восходящем направлении для ветви (или всех ветвей, если нажать более одной). Как только он установлен, отслеживание продолжается. Нет причин использовать его постоянно.
Дэвид Калп

Ответы:

1166

Как правило, мне нравится объединяться masterс developmentпервым, чтобы в случае возникновения каких-либо конфликтов я мог разрешить проблему в самой developmentветке, и мои данные masterостаются чистыми.

(on branch development)$ git merge master
(resolve any merge conflicts if there are any)
git checkout master
git merge development (there won't be any conflicts now)

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

РЕДАКТИРОВАТЬ: Из комментариев

Если вы хотите отслеживать, кто и когда произвел слияние, вы можете использовать --no-ffфлаг для слияния, чтобы сделать это. Обычно это полезно только при слиянии developmentс master(последний шаг), потому что вам может потребоваться слиться masterс development(первым шагом) несколько раз в вашем рабочем процессе, и создание узла фиксации для них может быть не очень полезным.

git merge --no-ff development
Sailesh
источник
71
У этого подхода есть небольшой недостаток: фактическое слияние с мастером, скорее всего, является слиянием в ускоренном режиме и, следовательно, не создает никакого узла фиксации. Это не проблема с реальным кодом в ветке, но затрудняет выяснение позже, кто сделал фактическое слияние с мастером и в какое время. Явное --no-ffслияние с мастером необходимо исправить это.
Михас
11
Да, именно --no-ffдля этого. :)
Михас
19
Это git merge --no-ff developmentпросто для исправления использования @ elect.
jewbix.cube
2
@sailesh Можете ли вы обновить свой ответ, чтобы включить флаг git merge, если вы согласны с комментариями?
Веб-пользователь
2
@Mars, объединение переопределит файл, если старое изменение было прямым происхождением коммита. Например, пусть A->B->Cбудет хозяином, и A->X->Yэто ваша ветка разработчика. Если вы измените часть файла, в Xкоторой могли возникнуть конфликты с изменением A, это не будет конфликтом, поскольку Aявляется предком X. Что касается потерянных изменений, обратитесь к stackoverflow.com/questions/7147680/…, чтобы восстановить любые изменения.
Сайлэш
103

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

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

git fetch origin master

git merge master

git push origin development:master

Первая строка гарантирует, что он имеет какие-либо восходящие коммиты, которые были сделаны мастеру с момента последнего обновления его локального репозитория.

Второй тянет эти изменения (если они есть) из мастера в разработку

Третий подталкивает ветку разработки (теперь полностью объединенную с master) до origin / master.

Я могу немного ошибиться в его базовом рабочем процессе, но в этом его основная суть.

Дэвид Калп
источник
Спасибо! Это для меня более интуитивный смысл.
Джейми Николл-Шелли
2
Да - за 6 с лишним лет, с тех пор как я написал это, я тоже принял его - хотя с rebaseобновлением devветки вместо merge.
Дэвид Калп
32

Объяснение снизу для тех, кто пришел сюда без каких-либо знаний о ветвях.

Основная логика разработки основной ветки такова: вы работаете только с другими ветками и используете master только для объединения других ветвей.

Вы начинаете создавать новую ветку следующим образом:

1) Клонируйте репозиторий в вашем локальном каталоге (или создайте новый репозиторий):

$ cd /var/www
$ git clone git@bitbucket.org:user_name/repository_name.git

2) Создать новую ветку. Он будет содержать последние файлы вашего основного филиала хранилища

$ git branch new_branch

3) Измените вашу текущую ветку git на new_branch

$ git checkout new_branch

4) Заниматься кодированием, фиксирует, как обычно…

$ git add .
$ git commit -m “Initial commit”
$ git push (pushes commits only to “new_branch”)

5) Когда работа в этой ветке завершится, объедините с веткой «master»:

$ git merge master
$ git checkout master (goes to master branch)
$ git merge development (merges files in localhost. Master shouldn’t have any  commits ahead, otherwise there will be a need for pull and merging code by hands!)
$ git push (pushes all “new_branch” commits to both branches - “master” and “new_branch”)

Обновление: я настоятельно рекомендую использовать GitKraken для этого, чтобы видеть визуальное дерево изменений и лучше видеть всю логику и коммиты.

Гедиминас
источник
Мне понравился твой подход не работать на мастера. но сегодня, когда я играл с gitflow, я создал releaseветку нашего develop. Затем добавили файл заметки о выпуске и зафиксировали. Затем закончил релиз, который сливается с обоими master/develop. но в моей основной ветке только что было добавлено примечание к выпуску. никакие другие файлы во время предыдущих коммитов разработки не были обновлены в нем.
Амит Шах
если вы работаете с веткой, отличной от master, убедитесь, что вы зафиксировали и передали изменения в эту ветку. Чем вы можете посмотреть, как файлы выглядят в графическом интерфейсе github.com или bitbucket.com, и попытаться нажать Merge там, на веб-сайте. Следует обновить все от вашей ветки до мастера. Если мастер имеет более новые файлы, это должно быть конфликтом, и вы получите сообщение об ошибке. Не уверен, что я ответил достаточно хорошо, пожалуйста, дайте мне сообщение, если нет :)
Гедиминас
Я использую sourcetree в качестве графического интерфейса и репозитория github. Я пробовал 2 раза с тестом релиза. мастер никогда не обновлялся с последней веткой разработки.
Амит Шах
попробуйте использовать на веб-сайте live github.com файлы вашей ветки, над которой вы работаете. Они выдвинуты? Если да, попробуйте нажать на ту же ветку - объединить, и вы увидите, что происходит. Мой личный опыт работы с sourcetree довольно плохой - я не смог полностью понять, что происходит в моих ветках
Гедиминас
Спасибо @Gediminas за подробное объяснение. Я был смущен в git ключевых словах, прежде чем читать ваш ответ .. :)
Динеш Сутар
21

Было бы здорово, если бы вы могли использовать рабочий процесс Git Flow . Он может легко объединить развивающуюся ветку в мастерскую

То, что вы хотите сделать, это просто следовать инструкции git-flow, упомянутой здесь:

ШАГИ:

  • настроить проект git-flow
  • создавать филиалы и объединять все для развития
  • запустить команду git flow release start <version_number>
  • затем предоставить содержательное сообщение для релиза
  • запустить команду git flow release finish <version_number>
  • он объединит все в master и изменит ветку на master .
  • выполните команду, git pushчтобы опубликовать изменения на удаленном мастере .

Для получения дополнительной информации посетите страницу - http://danielkummer.github.io/git-flow-cheatsheet/

Harsha
источник
1
Решение, если кто-то использует git flow!
Чаба Тот
21
1. //pull the latest changes of current development branch if any        
git pull (current development branch)

2. //switch to master branch
git checkout master 

3. //pull all the changes if any
git pull

4. //Now merge development into master    
git merge development

5. //push the master branch
git push origin master
Ризван Сиддик
источник
9

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

Серджиу Думитриу
источник
6

Если вы используете Mac или Ubuntu, перейдите в рабочую папку ветки. В терминале

Предположим, что Харисдев является отчеством.

git checkout master

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

git merge harisdev 

git push origin master

Последняя команда для удаления ветки.

$ git branch -d harisdev
Харис Нп
источник
Что здесь характерно для Mac или Ubuntu?
talonx
Сожалею. Ни в одном из других ответов не упоминалось, что команды должны быть заданы в Терминале и команда для удаления ветки. На самом деле я просто хотел добавить команду для удаления ветки, чтобы разработчик не связывался с той же веткой в ​​будущем. Я использую Mac, поэтому я упомянул об этом. Ваш вопрос верен, и ни одна из этих команд не относится к Mac или Ubuntu.
Харис Np
Спасибо за разъяснение.
talonx
5

Шаг 1

Создайте и переключитесь на новую ветку «dev», где ваши локальные git-файлы синхронизируются с удаленной, но ветка «dev» еще не существует.

git branch dev # create
git checkout dev # switch
# No need to git add or git commit, the current
# branch's files will be cloned to the new branch by-default.
git push --set-upstream origin dev # push the "dev" branch to the remote.

Шаг 2

Внесите изменения в ветку «dev» (текущую, если вы выполните шаг 1), зафиксируйте и отправьте их в удаленную ветку «dev».

git add .
git commit -S -m "my first commit to the dev branch" # remove the -S if you're not "secure", secure = when you already setup crypto private and public keys (i.e "verified" green sign in github)
git push -u origin dev # push the changes to the remote, -u origin dev is optional but good to use.

Шаг 3

Объедините свою ветку «dev» в «master».

git checkout dev # switch to "dev" branch if you're not already.
git merge master # optionally, this command is being used to resolve any conflicts if you pushed any changes to your "master" but "dev" doesn't have that commit.
git checkout master # switch to "master", which is the branch you want to be merged.
git merge --no-ff dev # merge the "dev" branch into the "master" one.
kataras
источник
4

Вот как я обычно это делаю. Во-первых, убедитесь, что вы готовы объединить свои изменения в мастер.

  1. Проверьте, соответствует ли разработка последним изменениям на удаленном сервере с git fetch
  2. Как только выборка завершена git checkout master.
  3. Убедитесь, что главная ветвь имеет последние обновления, выполнив git pull
  4. Как только подготовка завершена, вы можете начать слияние с git merge development
  5. Нажмите изменения, git push -u origin masterи все готово.

Вы можете узнать больше о git merging в статье.

Неша Зорич
источник
3

1) В отделе разработки проверьте статус git с помощью следующей команды:

git status

Там не должно быть незафиксированного кода. Если это так, отправьте ваш код в ветку Разработка:

git add *

git commit -m "My initial commit message"

git push origin Development

2) В ветке разработки выполните следующие две команды:

git branch -f master HEAD

git push -f origin master

Это подтолкнет ваш код ветки разработки в основную ветку.

Химаншу Махаджан
источник
Это также подталкивает все коммиты разработки к мастеру или просто добавляет новый коммит в мастер?
закатывает
1
как это на самом деле работает? В частности, «Git Branch Master», когда вы находитесь в разработке, выглядит как безумие. как вы можете создать новую ветку с именем master, если уже есть ветка с именем master? Документы говорят, что -f делает это: Сброс <branchname> в <startpoint>. Что это значит?
Джон Литтл
Разве эта сила не толкает локального мастера на удаленный мастер? Это кажется плохой идеей, если вы работаете в команде.
Ник
-fне рекомендуется
DawnSong
2

Основано на @Sailesh и @DavidCulp:

(on branch development)
$ git fetch origin master
$ git merge FETCH_HEAD
(resolve any merge conflicts if there are any)
$ git checkout master
$ git merge --no-ff development (there won't be any conflicts now)

Первая команда убедится, что у вас есть все вышестоящие коммиты, сделанные удаленному мастеру, с ответом Sailesh, который не произойдет.

Второй будет выполнять слияние и создавать конфликты, которые вы затем сможете разрешить.

После этого вы можете наконец оформить заказ мастера, чтобы переключиться на мастер.

Затем вы объединяете ветку разработки с локальным мастером. Флаг no-ff создаст узел фиксации в master для отслеживания всего слияния.

После этого вы можете зафиксировать и нажать свое слияние.

Эта процедура позволит убедиться, что существует коммит слияния от разработки к мастеру, который могут видеть люди, а затем, если они пойдут посмотреть ветку разработки, они увидят отдельные коммиты, которые вы сделали с этой веткой во время ее разработки.

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

РЕДАКТИРОВАТЬ: мой оригинальный ответ предложил, git merge masterкоторый ничего не делал, это лучше сделать git merge FETCH_HEADпосле получения оригинала / мастера

Cisco
источник
2

Как только вы «оформили» ветку разработки, вы ...

 git add .
 git commit -m "first commit"
 git push origin dev
 git merge master

 git checkout master 
 git merge dev
 git push origin master 
Тиаго Медичи
источник
1

Если вы используете Gerrit, следующие команды работают отлично.

git checkout master
git merge --no-ff development

Вы можете сохранить с сообщением фиксации по умолчанию. Убедитесь, что идентификатор изменения сгенерирован. Вы можете использовать следующую команду, чтобы убедиться.

git commit --amend

Затем нажмите следующую команду.

git push origin HEAD:refs/for/refs/heads/master

Вы можете столкнуться с сообщением об ошибке, как показано ниже.

! [remote rejected] HEAD -> refs/for/refs/heads/master (you are not allowed to upload merges)

Чтобы решить эту проблему, администратор проекта gerrit должен создать еще одну ссылку в gerrit с именем 'refs / for / refs / head / master' или 'refs / for / refs /head / *' (которая будет охватывать все ветви в будущем). Затем предоставьте разрешение «Push Merge Commit» на эту ссылку и разрешение «Отправить», если требуется отправить GCR.

Теперь попробуйте вышеупомянутую команду push, и она должна работать.

Кредиты:

https://github.com/ReviewAssistant/reviewassistant/wiki/Merging-branches-in-Gerrit

https://stackoverflow.com/a/21199818/3877642

Шанкаран Сринивасан
источник
1

Я думаю, что самое простое решение было бы

git checkout master
git remote update
git merge origin/Develop -X theirs
git commit -m commit -m "New release"
git push --recurse-submodules=check --progress "origin" refs/heads/Master

Это также сохраняет историю всех используемых веток

Вишал
источник
-4
1. //push the latest changes of current development branch if any        
git push (current development branch)

2. //switch to master branch
git checkout master 

3. //pull all the changes if any from (current development branch)
git pull origin (current development branch)

4. //Now merge development into master    
git merge development

5. //push the master branch
git push origin master

Error
To https://github.com/rajputankit22/todos-posts.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/rajputankit22/todos-posts.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Then Use 
5. //push the master branch forcefully
git push -f origin master
Анкит Кумар Раджпут
источник
1
Принудительное нажатие, когда вы видите, что ошибка почти никогда не бывает правильной, если только вы не уверены, что знаете, почему в вашей локальной ветке отсутствуют коммиты из удаленной ветки. В общем, гораздо лучше вернуться к шагу 3 и pullснова. Кроме того, не ясно, какую ценность этот ответ добавляет по сравнению с существующими ответами.
Кайл Стрэнд,