Можно ли исключить определенные коммиты при слиянии git?

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

Моя стратегия до сих пор заключается в следующем (в мастере):

git merge --no-commit release-branch
# Resolve conflicts and apply reverse patch of the commits that I don't want included
git commit # Edit commit message so that it lists the commits that have been reverse-patched

Есть лучший способ сделать это?

Возможный дубликат git - пропуск определенных коммитов при слиянии - знаю, что моложе, но его принятый ответ ИМХО лучше

Tobias Kienzler 11.08.2017 11:53
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Принципы ООП в JavaScript
Принципы ООП в JavaScript
Парадигма объектно-ориентированного программирования имеет 4 основных принципа,
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Можете ли вы объяснить разницу между ngOnInit и конструктором в Angular?
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
73
1
59 751
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

Создайте новую ветку, переустановите ветку в интерактивном режиме и удалите ненужные коммиты, а затем объедините их.

Вы не можете удалить изменения из середины ветки без повторного хеширования, но правильно будет, когда он увидит те же изменения при более позднем слиянии (например, из-за выбора вишни и т. д.).

Но что произойдет, если вы снова попытаетесь объединить эту ветку?

Evgeny 22.09.2010 10:18

Какими точными командами это нужно сделать? Я не вижу способа "отбросить" нежелательные коммиты

Henning 08.06.2011 15:37

@Henning, когда вы git rebase -i other-branch, он дает вам текстовый редактор с кучей коммитов в нем. Удалите ненужные строки.

Dustin 09.06.2011 04:14

Причина, по которой это нельзя сделать напрямую, заключается в том, что каждая фиксация содержит ссылки на родительские коммиты (обычно только одну, а несколько для слияний). Таким образом, если у вас есть один коммит (по его сумме SHA1), вся история также фиксируется, поскольку родители также содержат ссылки на своих родителей и так далее. Так что единственный способ оставить патчи в истории - это написать новый. git rebase -i во вновь созданной ветке, вероятно, самый простой способ добиться этого.

Я нашел решение, которое мне подходит в книге Pro Git.

Допустим, вы хотите исключить файл config.php.

На ветке А:

  1. Создайте файл с именем .gitattributes в том же каталоге со следующей строкой: config.php merge=ours. Это говорит git, какую стратегию использовать при слиянии файла. В этом случае он всегда сохраняет вашу версию, т.е. версия в ветке, в которую вы выполняете слияние.

  2. Добавьте файл .gitattributes и зафиксируйте

На ветке B: повторить шаги 1-2.

Попробуйте объединиться сейчас. Ваш файл следует оставить нетронутым.

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

charliepark 13.05.2011 16:08

У меня это почему-то не работает. Я создал новую ветку с фиксацией, изменяющей файл, и добавил файл .gitattributes в обе ветки. Когда я снова сливаюсь с исходной веткой, кажется, что она полностью игнорирует строку в .gitattributes и в любом случае извлекает измененный файл. Есть какие-то настройки, которые мне не хватает?

robbles 01.10.2012 03:59

У меня не работает. Я тоже выполнил инструкции в вопросе, указанном VonC. Я на винде. Файл, который я пытаюсь избежать слияния, представляет собой точечный файл (.core.config). Мне нужно заключить это имя в кавычки или что-то в этом роде?

Sean 09.05.2013 01:27

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

Caumons 28.09.2013 19:57

@robbles Каумонс прав. По сути, этот атрибут срабатывает только в случае конфликта слияния. В вашем случае у вас есть слияние FF. Git просто делает это без проверки стратегии слияния

Johnny Z 09.06.2015 23:23

Если вы хотите исключить только некоторые коммиты, которые находятся в конце, вы можете просто зафиксировать конкретный номер фиксации:

git checkout partlyMergedFrom
git whatchanged
--> find the commit hash up to where you want to merge
git checkout partlyMergedInto
git merge e40a0e384f58409fe3c864c655a8d252b6422bfc
git whatchanged
--> check that you really got all the changes you want to have

Также можно изменить файл .git / info / attributes и сохранить его в папке .git вместо того, чтобы добавлять файлы .gitattribute повсюду, что в конечном итоге потребует их добавления в систему управления версиями.

Если у вас есть ветка поддержки, где вы исправляете ошибки и создаете новые версии. На master у вас есть следующая версия, в которой вы также часто создаете новые версии.

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

Если файл, содержащий информацию о версии Только, содержит информацию о версии, вы можете использовать ответ fcurella. Но если он действительно может содержать объединяемую информацию (pom.xml, gradle.properties, MANIFEST.MF, ...), вы должны выполнить некоторые дополнительные действия.

Давайте использовать следующий пример

      C---D*---E---F* support
     /
A---B---G---H*---I master

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

Чтобы объединить служба поддержки в мастер без конфликтов слияния из-за сборок версий, вы можете выполнить одно из следующих действий:

Множественные коммиты слияния

git checkout master
git merge C
git merge D -s ours
git merge E
git merge F -s ours

Аргументом -s ours мы говорим git записывать только слияние без изменения рабочей области. Это сопоставимо с к опции svn --record-only.

Вышеупомянутое приведет к следующему макету

      -------------C---D*---E---F* support
     /              \   \    \   \
A---B---G---H*---I---J---K----L---M master

Один коммит слияния с использованием Cherry-Pick

git checkout master
git merge support -s ours --no-commit
git cherry-pick C E --no-commit
git commit -m 'merged support into master'

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

Вышеупомянутое приведет к следующему макету

      C---D*---E---F* support
     /              \
A---B---G---H*---I---J master

Можно даже автоматизировать сбор вишен.

git checkout master
git merge support -s ours --no-commit
for id in `git log support --reverse --not HEAD --format = "%H [%an] %s" |
  grep -v "bump version" |
  sed "s/\(\w*\)\s.*/\1/g"`
do
  git cherry-pick --no-commit $id
done
git commit -m 'merged support into master'

Любой пример автоматизации множественных коммитов слияния?

Santos 21.12.2016 20:07

Решение, которое дает одну фиксацию слияния с использованием Cherry Pick, просто фантастическое! Спасибо! Это именно то, что мне было нужно. У нас есть два проекта, разветвленных из одного источника. Нам нужно сохранить несколько различий между ними, но в целом нам нужно, чтобы большая часть изменений была объединена взад и вперед. Отличный пост!

Brent K. 20.03.2020 23:57

Главный вопрос: как вы хотите представить коммиты, которые хотите пропустить?

  1. украдкой спрячьте их (не мой любимый)
  2. явно пропустить их
  3. явно отменить их

К сожалению нет. 2 невозможно выразить в графике истории.

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

Но сюрприз, сюрприз, вы можете изменить всю кодовую базу и представить ее как слияние. Эффект слияния двоякий: оно объединяет дерево истории и, оно должно объединять две базы кода. Первое - это точно (иначе никто не называет это слиянием), второе - может потерпеть неудачу, например. когда возник конфликт слияния и он был разрешен ошибочно (значит, кодовые базы слились некорректно).

Некоторые другие ответы предполагают это сокрытие. Я рекомендую явный способ: слияние плюс откат коммитов.

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

Ron Wertlen 01.07.2016 16:44

@RonWertlen Вы правы в утверждении, что мастер не может быть снова объединен с этой «рабочей веткой» / веткой выпуска без введения эффекта возврата. - Но это верно не только для предложенной мной стратегии 3 моего ответа, но и для стратегии 1. - Это также одна из причин, по которой я лично не буду следовать рабочему процессу из вопроса ОП.

Robert Siemer 01.07.2016 16:56

Я тоже с тобой согласен. 1 и 2 - это антирабочие процессы. Если у вас есть долгоживущие ветки и вы хотите постоянно сохранять коммиты вне одной и другой, пора подумать о реструктуризации вашего проекта и использовании подмодулей (с node.js у вас также есть node_modules в качестве параллельный механизм для достижения того же самого).

Ron Wertlen 06.07.2016 15:29

Кроме того, № 2. не выражается в графике истории, это утверждение не на 100% ясно. Практически можно «солгать» себе историю, сбросив или переустановив и переписав индекс удаленного репо с помощью «--force». Это, конечно, очень плохая идея.

Ron Wertlen 06.07.2016 15:31

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

Robert Siemer 07.07.2016 14:52

Другие вопросы по теме