Git - пропустить определенные коммиты при слиянии

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

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

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

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

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

Любая помощь была оценена.

Ответ 1

Если вы хотите объединить большинство, но не все коммиты на ветке "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 совершит на master. Сообщение о слиянии по умолчанию объяснит, что вы объединяете "ветвь" maint "(ранняя часть)".

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

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

Ответ 2

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

Пример:

git merge master
git revert 12345678

Если у вас есть несколько "to-ignore", или вы хотите отредактировать сообщение revert:

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

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

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

Ответ 3

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

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

Ответ 5

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

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

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

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

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

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

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

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

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

Ответ 6

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

Ответ 7

Вместо того, чтобы 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 будет считать вашу ветку более новой, чем эта фиксация, поскольку вы уже имели дело с ней (решив сохранить ВАШИ версии вещей).