.gitattributes и индивидуальная стратегия слияния для файла

У меня есть мастер и тестовая ветвь моего (веб-приложения). Эти проекты практически одинаковы, за исключением одного файла, который устанавливает приложение, например "setup".

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

Я следил за инструкцией из книги Pro git и создал файл .gitattributes с линией "setup merge = ours", Однако это не сработает - ни с быстрым переходом не сливается, если я ввожу конфликты.

(Если быть точным:

$: mkdir gitest
$: cd gittest
$: git init
$: echo "setup merge=ours" >> .gitattributes 
$: echo "master" >> setup
$: git add setup .gitattributes
$: git commit -a -m ...
$: git branch test
$: git checkout test
$: echo "test" >> setup
$: git commit -a -m ...
$: git checkout master
$: git merge test

Ожидаемый результат: настройка содержит слово "master", вместо этого git выполняет слияние ff, а настройка - "test".)

Ответ 1

У меня была такая же ошибка, и ее можно решить, просто определяя драйвер слияния "наш" в .git/config:

[merge "ours"]
    name = "Keep ours merge"
    driver = true

Так как true всегда возвращает 0, временный файл, содержащий текущее состояние, не будет изменен и останется в качестве окончательной версии.

Подробнее о слиянии можно прочитать здесь: http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html#_defining_a_custom_merge_driver

Приложение:

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

Ответ 2

Я обнаружил, что если бы я изменил файлы на обеих ветвях и внес изменения в каждую ветку, а затем попытался слияние, он вывел бы драйвер слияния и прослушал мой .gitattributes, который указывает merge=ours. После этого два файла всегда отличаются друг от друга на двух ветвях, поэтому драйвер слияния всегда будет вызываться, поэтому мне не нужно иметь настраиваемый драйвер слияния, который касается файла. Нужно было сначала изменить оба варианта.

Ответ 3

Драйвер слияния вызывается только в нетривиальных случаях, т.е. если мастер и тест коснулись настройки (и вам сначала нужно определить драйвер слияния ours):

git init
git config merge.ours.name '"always keep ours" merge driver'
git config merge.ours.driver 'touch %A'
echo "setup merge=ours" >> .gitattributes 
echo "master" >> setup
git add setup .gitattributes
git commit -a -m ...
git branch test
git checkout test
echo "test" >> setup
git commit -a -m ...
git checkout master
echo "more content" >> setup
git commit -a -m ...
git merge test

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

Ответ 4

Сделайте пятно чистой script вместо отдельных ветвей. script может отличаться в зависимости от того, на какой машине вы находитесь.