git - пропускает определенные коммиты при слиянии - PullRequest
183 голосов
/ 08 апреля 2009

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

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

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

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

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

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

Ответы [ 7 ]

270 голосов
/ 08 апреля 2009

Например, если вы хотите объединить большинство, но не все коммиты на ветке "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' (ранняя часть)".

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

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

32 голосов
/ 10 сентября 2013

ИМХО, самое логичное, что нужно сделать, это объединить все, а затем использовать 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

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

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

16 голосов
/ 08 апреля 2009

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

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

6 голосов
/ 13 апреля 2018

Походит на классический случай для 'мерзавца' https://git -scm.com / документы / ГИТ-вишневого выбор это именно то, что звучит как

2 голосов
/ 21 июля 2015

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

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

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

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

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

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

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

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

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

0 голосов
/ 08 мая 2019

Вместо revert или cherry-pick для этого случая вам нужно получить git, чтобы учесть изменения, которые вы пропускаете, чтобы быть старше, чем те, которые вы сделали.

Итак:

  1. объединить последний коммит до коммитов, которые вы хотите пропустить. Это, конечно, объединит все коммиты ранее. git merge ccc
  2. объединить коммиты, которые вы хотите пропустить. git merge fff --no-commit
  3. ставить любые слияния, отменять все изменения, отменять все изменения. (Возможно, для этого есть надежные команды, но я бы просто выполнил эту часть в пользовательском интерфейсе - как вы знаете, как это сделать)
  4. завершить пустое слияние git merge --continue
  5. объединить коммиты ПОСЛЕ того, который вы хотели пропустить. git merge source-branch-head

После шага 4 git будет считать вашу ветку более новой, чем эта фиксация, поскольку вы уже имели дело с ней (решив сохранить ВАШИ версии вещей).

0 голосов
/ 08 апреля 2009

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

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