Всегда игнорируйте определенный коммит при слиянии в git - PullRequest
5 голосов
/ 15 июня 2011

Я работаю над своим первым проектом с использованием git и столкнулся с проблемой.

В репозитории есть приложение клиент / сервер.У меня есть ветки 'master' и 'test', с намерением, чтобы master всегда был таким же, как развернутый.

Моя проблема - в базе кода 3-4 места, где хранится URL-адрес сервера.Я хочу изменить это в ветке 'test', но не в ветке 'master'.Проблема, конечно, в том, что всякий раз, когда я хочу объединиться с «master», git хочет поместить это изменение в «master».

Я могу сделать выборочное объединение и объединить все коммиты, кроме одногопод вопросом, но это кажется утомительным для каждого слияния.Какой лучший способ сделать это?

У меня никогда не было этой проблемы в любой SCM, так что, возможно, я просто ошибаюсь.

Ответы [ 2 ]

1 голос
/ 15 июня 2011

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

Есть несколько способов сделать это. Одним из них является

git checkout master
git merge -s ours --no-ff testing
git checkout testing
git merge -s ours --no-ff master

или

git checkout master
git merge testing --no-commit --no-ff
git checkout HEAD -- .
git submodule update # this is optional and only needed if you have submodules
git add -A
git commit
git checkout testing
git merge master --no-commit --no-ff
git checkout HEAD -- .
git submodule update # this is optional and only needed if you have submodules
git add -A
git commmit

Теперь у вас есть 2 ветки с разными конфигами, но эти коммиты до важного merge-base.

Теперь вам нужно написать что-то вроде этого, чтобы выполнить специальное слияние, которое на самом деле является перебазировкой внизу - это единственный способ игнорировать то, что произошло раньше:

git checkout master
git merge --no-ff -s ours testing
git checkout -b temp testing
git rebase -s recursive -Xtheirs master # these are the conflicts we care about
git reset --soft HEAD@{2}
git add -A
git submodule update
git commit --amend -C HEAD@{2}
git push . +HEAD:master
git checkout master
git branch -d temp

Это просто перебрасывает то, чего у вас нет на master в тестировании ветки, и делает его похожим на слияние. Поскольку он сохраняет его как объединение, вы можете впоследствии запустить его для других веток, которые вы хотите опубликовать в master. Таким образом, вы можете разделить все эти команды с помощью && s, заменить тестирование аргументом, master - переменными второго аргумента и присвоить ему псевдоним:

git config alias.smart-merge '...'

чтобы вы могли публиковать изменения следующим образом:

git smart-merge testing master
git smart-merge feature2 master

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

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

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

- ИЛИ -

Нетривиально чистые сценарии. Взгляните на главу git attribute в progit.org/book.

.

Надеюсь, это помогло.

0 голосов
/ 15 июня 2011

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

Другой способ заключается в том, что вы можете git revert коммит (ы), которые изменили URL, объединиться с master и затем вернуть его обратно в вашу основную ветку.

Еще один другой способ - сделать git commit --no-commit, затем изменить файл, git add перед его фиксацией.

Еще один метод, который, возможно, не позволит «забыть», состоит в том, чтобы поместить такую ​​конфигурацию (URL-адреса и т. Д.) В отдельный файл и добавить этот файл в .gitignore ...

Я не думаю, что что-то из этого действительно элегантно, но это сработало бы ...

...