Допустим, я хочу выполнить слияние из ветки выпуска в ветку 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
Есть лучший способ сделать это?
Создайте новую ветку, переустановите ветку в интерактивном режиме и удалите ненужные коммиты, а затем объедините их.
Вы не можете удалить изменения из середины ветки без повторного хеширования, но правильно будет, когда он увидит те же изменения при более позднем слиянии (например, из-за выбора вишни и т. д.).
Но что произойдет, если вы снова попытаетесь объединить эту ветку?
Какими точными командами это нужно сделать? Я не вижу способа "отбросить" нежелательные коммиты
@Henning, когда вы git rebase -i other-branch
, он дает вам текстовый редактор с кучей коммитов в нем. Удалите ненужные строки.
Причина, по которой это нельзя сделать напрямую, заключается в том, что каждая фиксация содержит ссылки на родительские коммиты (обычно только одну, а несколько для слияний). Таким образом, если у вас есть один коммит (по его сумме SHA1), вся история также фиксируется, поскольку родители также содержат ссылки на своих родителей и так далее. Так что единственный способ оставить патчи в истории - это написать новый. git rebase -i во вновь созданной ветке, вероятно, самый простой способ добиться этого.
Я нашел решение, которое мне подходит в книге Pro Git.
Допустим, вы хотите исключить файл config.php
.
На ветке А:
Создайте файл с именем .gitattributes
в том же каталоге со следующей строкой: config.php merge=ours
. Это говорит git, какую стратегию использовать при слиянии файла. В этом случае он всегда сохраняет вашу версию, т.е. версия в ветке, в которую вы выполняете слияние.
Добавьте файл .gitattributes
и зафиксируйте
На ветке B: повторить шаги 1-2.
Попробуйте объединиться сейчас. Ваш файл следует оставить нетронутым.
Для будущих читателей это отлично подходит для явного нет, включая определенные файлы. (В моем случае я развертываю разные ветки на разных серверах и хочу, чтобы мой сценарий развертывания Capistrano был уникальным для каждой ветки.)
У меня это почему-то не работает. Я создал новую ветку с фиксацией, изменяющей файл, и добавил файл .gitattributes в обе ветки. Когда я снова сливаюсь с исходной веткой, кажется, что она полностью игнорирует строку в .gitattributes и в любом случае извлекает измененный файл. Есть какие-то настройки, которые мне не хватает?
У меня не работает. Я тоже выполнил инструкции в вопросе, указанном VonC. Я на винде. Файл, который я пытаюсь избежать слияния, представляет собой точечный файл (.core.config). Мне нужно заключить это имя в кавычки или что-то в этом роде?
Это работает только в том случае, если два файла изменены, иначе слияние нашего игнорируется
@robbles Каумонс прав. По сути, этот атрибут срабатывает только в случае конфликта слияния. В вашем случае у вас есть слияние FF. Git просто делает это без проверки стратегии слияния
Если вы хотите исключить только некоторые коммиты, которые находятся в конце, вы можете просто зафиксировать конкретный номер фиксации:
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
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'
Любой пример автоматизации множественных коммитов слияния?
Решение, которое дает одну фиксацию слияния с использованием Cherry Pick, просто фантастическое! Спасибо! Это именно то, что мне было нужно. У нас есть два проекта, разветвленных из одного источника. Нам нужно сохранить несколько различий между ними, но в целом нам нужно, чтобы большая часть изменений была объединена взад и вперед. Отличный пост!
Главный вопрос: как вы хотите представить коммиты, которые хотите пропустить?
К сожалению нет. 2 невозможно выразить в графике истории.
№ 1 возможно, но я бы сделал это никогда: коммит слияния может содержать изменения. - Обычно фиксация слияния указывает на результат слияния еще двух ветвей: все, что разработано в этих ветвях, должно быть в коде после слияния (то есть в коде, на который указывает фиксация слияния). И в этом коммите больше ничего не должно быть.
Но сюрприз, сюрприз, вы можете изменить всю кодовую базу и представить ее как слияние. Эффект слияния двоякий: оно объединяет дерево истории и, оно должно объединять две базы кода. Первое - это точно (иначе никто не называет это слиянием), второе - может потерпеть неудачу, например. когда возник конфликт слияния и он был разрешен ошибочно (значит, кодовые базы слились некорректно).
Некоторые другие ответы предполагают это сокрытие. Я рекомендую явный способ: слияние плюс откат коммитов.
Это отличная стратегия для недолговечных веток. Проблема с этой стратегией заключается в том, что когда вы объединяете свою правильно объединенную ветвь (ту, что с откатом) обратно в рабочую ветвь, рабочая ветвь также получит откат, потому что это обычная, настоящая фиксация. Если у вас есть случай, когда в рабочей ветке действительно не должно быть фиксации, вам придется отменить откат. Это будет продолжаться, пока используется эта конкретная рабочая ветка.
@RonWertlen Вы правы в утверждении, что мастер не может быть снова объединен с этой «рабочей веткой» / веткой выпуска без введения эффекта возврата. - Но это верно не только для предложенной мной стратегии 3 моего ответа, но и для стратегии 1. - Это также одна из причин, по которой я лично не буду следовать рабочему процессу из вопроса ОП.
Я тоже с тобой согласен. 1 и 2 - это антирабочие процессы. Если у вас есть долгоживущие ветки и вы хотите постоянно сохранять коммиты вне одной и другой, пора подумать о реструктуризации вашего проекта и использовании подмодулей (с node.js у вас также есть node_modules в качестве параллельный механизм для достижения того же самого).
Кроме того, № 2. не выражается в графике истории, это утверждение не на 100% ясно. Практически можно «солгать» себе историю, сбросив или переустановив и переписав индекс удаленного репо с помощью «--force». Это, конечно, очень плохая идея.
@RonWertlen Вы только что напомнили мне способ что-то объединить, но пропустив некоторые коммиты. - Но это никак не связано с пультами.
Возможный дубликат git - пропуск определенных коммитов при слиянии - знаю, что моложе, но его принятый ответ ИМХО лучше