Как объединить подмодули и всегда оставить «наши»? - PullRequest
3 голосов
/ 19 сентября 2019

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

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

проблема возникает, когда я объединяю ветвь A в B для родительского репо после обновления подмодуля A.Я хочу игнорировать эти обновления (т.е. я всегда хочу отменить обновления подмодуля во время слияний, в противном случае родительская ветвь B может закончиться веткой подмодуля A, что неверно).

Я нашел инструкции о том, как всегда использовать «наши» при объединении файлов , но это кажется неэффективным для подмодулей.Вот как воспроизвести проблему с подмодулем:

# first command will update your ~/.gitconfig, you may want to undo it later
git config --global merge.ours.driver true

mkdir -p tmp/sub
cd tmp
git init
git commit --allow-empty -m "chore: Initial commit"
echo 'sub merge=ours' >> .gitattributes
git add .gitattributes
git commit -m 'chore: Preserve sub during merges'

mkdir sub
pushd sub
git init
git commit --allow-empty -m "sub: init"
popd
git submodule add ./sub
git commit -m 'add submodule'

git checkout -b demo-prod
pushd sub
echo prod > readme
git add readme
git commit -m 'add prod readme'
popd
git commit sub -m 'sub: add prod readme'

git checkout -
git submodule update
pushd sub
echo master > log
git add log
git commit -m 'add master log'
popd
git commit sub -m 'sub: add master log'

git checkout demo-prod
git merge -

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

Как мне добиться легкого слияния в такой ситуации?

Ответы [ 2 ]

0 голосов
/ 21 сентября 2019

Проблема возникает, когда я объединяю ветвь A в B для родительского репо после обновления подмодуля A.Я хочу игнорировать обновления [любого подмодуля ветви A] (т.е. я всегда хочу отменить обновления подмодуля во время слияний, в противном случае родительская ветвь B может закончиться веткой подмодуля A, что неправильно).

Когда вы объединяетесь, если путь был изменен в другой ветке и вообще не затрагивался в локальной ветке, Git не видит шансов конфликта, поэтому он «тривиально» принимает версию другой ветки.Это так далеко под радаром, что Git даже не видит его как automerge, он вообще не запускает драйвер слияния, насколько я могу судить, что отключить нечего, вы не можете его остановить,…

... которая может показаться плоской "не может быть сделано", но это Git.Все, что Git делает автоматически, вы можете легко исправить впоследствии, если хотите.Либо выполните слияние --no-commit и git checkout @ path/to/submodule перед фиксацией, либо, если вы забыли, выполните git checkout @~ path/to/submodule и git commit --amend.Множество пользовательских рабочих процессов могут быть автоматизированы с помощью настроек конфигурации или хуков, но я думаю, что этот достаточно странный, и вам придется его написать, если вам нужна автоматизация.

0 голосов
/ 21 сентября 2019

Слияние с подмодулями протестировано в t7405-submodule-merge.sh, и оно всегда включает merge -s ours, которое должно делать то, что вы хотите.
(тест добавлен в commit f37ae35 , Apr. 2009, Git v1.6.2.4)

Фактическое слияние для субмодуля обсуждалось в ноябре 2017 года , для этого патча , в commit 6c8647d , январь 2018, v2.17.0-rc0, но вам здесь это не нужно.

Использование стратегии слияния "-s ours" может быть слишком много (тем, что он игнорирует все коммиты из другой ветви), но может помочь опция рекурсивной стратегии слияния: git merge -X ours.

...