Git - как исключить файлы из слияния
Я пытаюсь сохранить 2 проекта веб-сайта в одном хранилище. Эти веб-сайты в основном такие же, кроме файлов шаблонов (html, css) и нескольких файлов конфигурации.
Основной сайт (который, по моему мнению, Supersite) находится в главном сервере. Второй сайт находится в филиале secondarySite. Каждый раз, когда я разрабатываю новую функцию в основной ветке, я хочу объединить ее с secondarySite, но я хочу исключить слияние файлов шаблонов.
Я нашел частичное решение здесь Как сообщить git, чтобы всегда выбирать локальную версию для конфликтующих слияний в определенном файле?, но она работает только тогда, когда я меняю файл шаблона в обеих ветвях и возникает конфликт. Когда нет конфликта git просто используйте более новую удаленную версию файла.
Как я могу сообщить git всегда оставить указанные локальные файлы неизменными, даже если конфликт отсутствует.
Или, может быть, я использую совершенно неправильный подход к проблеме?
Заранее благодарим за помощь.
Ответы
Ответ 1
Как упоминается в моем ответе о драйверах слияния, они полезны только в случае конфликта.
Это относится к merge=ours
в файле .gitattributes
: см. Стратегии объединения.
Один очень полезный вариант - сообщить Git не пытаться объединить определенные файлы , когда у них есть конфликты, а скорее использовать вашу сторону слияния над кем-то elses.
Этот недавний поток (2012) подтверждает это:
Есть ли способ слияния из branchA в branchB и от ветки B до branchA, полностью игнорируя изменения в файле, который отслеживается и существует в обеих ветвях?
Нет. По существу объект фиксации в Git состоит из состояния содержимого (то есть указателя на объект дерева) и указателя на всю предыдущую историю (то есть, ноль или более "родительские" указатели для совершения объектов).
Семантику объекта фиксации можно рассматривать как "Я просмотрел всю историю во всех родительских коммитах, а состояние, содержащееся в моем указателе на дерево, заменяет их всех".
Итак, вы можете сделать merge B
в A
, но сохраните A
копию файла (например, используя стратегию "ours
" ). Но это говорит о том, что вы считали состояние как A, так и B, и решили, что версия A
заменяет то, что произошло в B
. Если позже вы захотите объединиться с A
на B
, версия файла B
даже не будет считаться результатом слияния.
Существует не очень умный способ обойти это с помощью другой стратегии слияния; это фундаментальный аспект структуры данных Git для хранения истории.
Если эти шаблоны находятся в подкаталоге, лучше выделить их в репозитории Git, чтобы включить это репо в качестве подмодуля.
Если нет, то вам необходимо вернуть файлы, которые были неправильно объединены перед фиксацией (как в этот поток):
git merge --no-commit other
git checkout HEAD XYZ # or 'git rm XYZ' if XYZ does not exist on master
git commit
Ответ 2
Пробовали ли вы использовать .gitignore? Подробности, доступные в документации git здесь
Ответ 3
Здесь git -update-index - записывать содержимое файла в рабочем дереве в индекс.
git update-index --assume-unchanged <PATH_OF_THE_FILE>
Пример: -
git update-index --assume-unchanged somelocation/pom.xml
или
Добавить пути к файлам в .gitignore
Ответ 4
Или, может быть, я использую совершенно неправильный подход к проблеме?
Вы используете совершенно неправильный подход к этой проблеме:)
Проблема заключается в том, что ветки и инструменты вокруг них предназначены для поддержки разных версий одной и той же базовой вещи.
Но ваши два веб-сайта на самом деле не являются одним и тем же основным, они - две разные вещи с некоторой общности, и вам приходится злоупотреблять git, потому что вы лжете ему об их отношениях.
Ваши разумные варианты:
-
сделайте свое репо представителем юниверса всех (нормально, обоих) сайтов. Таким образом, они оба видны в одной структуре каталогов и используют разные пути. У них могут быть отдельные ветки dev и release, но это необязательно. Если два сайта имеют некоторую общность, это может быть просто в виде общих файлов.
например.
repo/supersite
repo/secondsite
repo/common
-
сделать отдельное репо для каждого сайта и дублировать общие файлы. Вы можете просто скопировать изменения
-
сделать отдельное репо для каждого сайта и третье репо для обычных вещей и использовать подмодули для объединения суперсайта + общего в одном месте, а второй - с общим в другом.
например.
super-repo/site # super site content
super-repo/common # common repo as submodule
second-repo/site # second site content
second-repo/common # same common repo as submodule
Обратите внимание, что подмодули относятся к одному и тому же репо, но каждый экземпляр может находиться в настоящее время на другой ветке или фиксировать
В какой-то степени правильный выбор зависит от того, насколько два сайта меняются независимо друг от друга, и как часто изменяются общие биты, и можно ли заставить оба сайта использовать одну и ту же версию разделяемых битов и какую часть общий контент является общим и уникальным, и т.д. и т.д.
Ответ 5
В каждом из ваших ветвей добавьте файл .gitattributes
в корневой каталог.
Для каждой ветки указаны файлы, которые следует игнорировать при слиянии следующим образом:
filename merge=ours
и не забудьте активировать драйвер для этого:
git config --global merge.ours.driver true
Попробуйте слить, вы увидите, что файлы, указанные в .gitattributes
в каждой ветки, будут нетронутыми, пока произойдет слияние.