2009-04-07 2 views
158

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

У меня есть две ветви, называемые say master10 (для v1) и master20 (для v2). Я делаю исправления ошибок в v1 на master-сервере branch10 и разрабатываю новый материал master20. Всякий раз, когда я делаю исправление ошибки, я объединяю его в v2, проверяя master20 и делая git merge master10. Все идет нормально.

Теперь, однако, я внес изменения в v1, который не нужен в v2, но я хочу продолжить слияние других исправлений ошибок. Как сообщить Git о пропуске этого конкретного коммита (или диапазона коммитов), но в будущем я все же хочу объединить другие исправления ошибок.

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

Я думаю, что я хочу что-то вроде команды «git sync», которая сообщает git, что две ветви теперь синхронизированы и в будущем только сливают коммиты с этой точки синхронизации.

Любая помощь приветствуется.

ответ

234

Если вы хотите объединить большинство, но не все коммиты на ветке «maint» на «master», вы можете это сделать. Это требует некоторой работы ----, как упоминалось выше, обычным вариантом использования является объединение всего из ветки --- но иногда бывает так, что вы внесли изменения в версию выпуска, которая не должна быть интегрирована обратно (возможно, этот код теперь уже завершен в мастерстве), так как вы это представляете? Вот так ...

Итак, предположим, что у maint было применено 5 изменений, и один из них (maint ~ 3) не должен быть объединен обратно в master, хотя все остальные должны быть. Вы делаете это в три этапа: на самом деле объедините все до этого, скажите git, чтобы отметить maint ~ 3 как слияние, даже когда это не так, а затем объединить остальные. Магия:

bash <master>$ git merge maint~4 
bash <master>$ git merge -s ours maint~3 
bash <master>$ git merge maint 

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

Вторая команда объединяет сложную транзакцию maint ~ 3, но опция «-s ours» сообщает git использовать специальную «стратегию слияния», которая, по сути, работает, просто удерживая дерево, в которое вы сливаетесь и игнорируете commit (s), который вы полностью объединяете. Но он все еще делает новое слияние с HEAD и maint ~ 3 в качестве родителей, поэтому в графе пересмотра теперь говорится, что maint ~ 3 сливается. Поэтому на самом деле вы, вероятно, хотите использовать параметр -m для 'git merge', чтобы объяснить, что это maint ~ 3 commit фактически игнорируется!

Последняя команда просто объединяет остальную часть maint (maint ~ 2..maint) в master, чтобы вы все синхронизировались снова.

+0

Интересно, однако, если это не немного опасно: что такое мачта ~ 3, нельзя игнорировать, а просто отложить? С вашим решением любой последующий git merge maint не объединит мачту ~ 3. – VonC

+1

Для отложенного фиксации я создал «суб-ветвь», сделаю именно то, что вы описали (в том числе git merge -s ours maint ~ 3), а затем слейте все из суб-ветви в master. Я считаю, что будущий «git merge maint» на этот раз сменил бы «mast ~ 3» – VonC

+2

Я думаю, что если вам нужно отложить слияние этого фиксажа, у вас мало выбора, кроме как пропустить его (merge-our ours), а затем применить его, используя команда вишневого пика. Как только фиксация достижима с помощью мастера, ее нельзя снова объединить - избегая слияния одного и того же изменения дважды, это одна из главных целей git. – araqnid

0

Создайте третью ветку для изменений, которые вы хотите в master10, но не в master20. Всегда считайте master10 своим «хозяином», самой стабильной ветвью всех. Филиал всех других филиалов хочет постоянно синхронизироваться.

+0

Я думаю, это может сработать, но я уже попал в это состояние, и третья ветвь, вероятно, смутила бы меня еще больше. :) –

15

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

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

+1

Спасибо, вишневый забор сделает эту работу. Не так хорошо, как я надеялся, но это сработает. –

26

IMHO, самое логичное, что нужно сделать: слить все, а затем использовать git revert (commit_you_dont_want), чтобы удалить его.

Пример:

git merge master 
git revert 12345678 

Если у вас есть несколько "игнорируемые" совершает или хотел бы изменить вернуться сообщение:

git merge master 
git revert -n 123456 
git revert -n abcdef 
git commit -m "... Except commits 123456 and abcdef" 

Тогда ваша история может выглядеть следующим образом:

| ... Except 123456 and abcdef 
|\ Merge branch 'master' into 'your_branch' 

Если у вас есть конфликты, в которых участвуют ТОЛЬКО, эти «игнорируемые» коммиты, вы можете использовать:

git merge master -X ours 

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

Если у вас возникли конфликты, то НЕ ТОЛЬКО ЗАПРЕЩАЕТСЯ «игнорировать», вы должны разрешить их вручную, и вам, вероятно, придется снова их разрешать во время реверсии.

+1

Если вы захотите позже объединить эти возвращенные коммиты в ответ на вопрос, будет ли Git игнорировать их? –

+0

@ AnriëtteMyburgh Вы можете вернуть завершение реверсии, чтобы позже объединить их, что вы действительно не можете сделать так легко с помощью стратегии «merge -s ours». – ikdc

2

Вид рекламы на мой project, который в основном обертывает процесс, описанный @araqnid.

Это своего рода помощник, который вводит следующий GIT поток:

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

Цитата со страницы проекта:

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

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

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

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

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

Смежные вопросы