git - как исключить файлы из слияния - PullRequest
12 голосов
/ 09 июня 2011

Я пытаюсь сохранить 2 проекта сайта в одном хранилище.Эти веб-сайты в основном одинаковы, за исключением файлов шаблонов (html, css) и нескольких файлов конфигурации.Основной сайт (который, скажем, Supersite) находится в ветке master.Второй сайт находится в ветке secondSite.Каждый раз, когда я разрабатываю какую-то новую функцию в основной ветке, я хочу объединить ее с secondSite, но я хочу исключить файлы шаблонов из слияния.

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

Как я могу сказать git всегда оставить указанные локальные файлы без изменений, даже если нет конфликта.

Или, может быть, я использую совершенно неверный подход к проблеме?

Заранее спасибо за любую помощь.

Ответы [ 5 ]

7 голосов
/ 22 ноября 2012

Как уже упоминалось в моем ответе о драйверах слияния , они полезны только в случае конфликта.
Это относится к merge=ours в .gitattributes файле : см. Стратегии слияния .

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

Эта недавняя ветка (2012) подтверждает это:

Есть ли способ слияния из филиала A в филиал B и из филиала B в branchA при полном игнорировании изменений в отслеживаемом файле и существует в обеих ветках?

Нет. По сути, объект коммита в git состоит из состояния содержимого (т. Е. Указателя на объект дерева) и указателя на всю предыдущую историю (т. Е. Ноль или более «родительского») указатели для фиксации объектов).
Семантику объекта коммита можно представить как «Я просмотрел всю историю всех родительских коммитов, и состояние, содержащееся в указателе моего дерева, заменяет их все».

Таким образом, вы можете объединить 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 
3 голосов
/ 09 июня 2011

Вы пробовали использовать .gitignore? Подробности доступны в документации git здесь

2 голосов
/ 28 сентября 2015

Или, может быть, я использую совершенно неверный подход к проблеме?

Вы используете совершенно неверный подход к этой проблеме:)

Проблема в том, что ветви и инструменты вокруг них предназначены для поддержки разных версий одной и той же базовой вещи .

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

Ваши вменяемые параметры:

  1. заставит ваше репо представлять вселенную всех (хорошо, оба) сайтов . Таким образом, они оба видны в одной структуре каталогов и используют разные пути. Они могут иметь отдельные ветки dev и release, но это необязательно. Если два сайта имеют некоторую общность, это может быть просто в форме общих файлов.

    например.

    repo/supersite
    repo/secondsite
    repo/common
    
  2. сделать отдельное репо для каждого сайта и продублировать общие файлы. Вы можете просто скопировать изменения

  3. создайте отдельное репо для каждого сайта и третье репо для общих вещей и используйте субмодули для объединения суперсайта + общего в одном месте и секундного + общего в другом.

    например.

    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
    

    Обратите внимание, что подмодули относятся к одному и тому же репо, но каждый экземпляр может в настоящее время находиться в другой ветви или коммите

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

2 голосов
/ 28 сентября 2015

Здесь git-update-index - Зарегистрировать содержимое файла в рабочем дереве для индекса.

git update-index --assume-unchanged <PATH_OF_THE_FILE>

Пример: - * +1004 *

git update-index --assume-unchanged somelocation/pom.xml

или

Добавить пути к файлам в .gitignore

1 голос
/ 02 октября 2017

В каждой из ваших веток добавьте файл .gitattributes в корень.

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

filename merge=ours

и не забывайтечтобы активировать драйвер для этого:

git config --global merge.ours.driver true

Попробуйте выполнить слияние, вы увидите, что файлы, указанные в .gitattributes в каждой ветви, не будут затронуты во время слияния.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...