Использование условных файлов конфигурации с Git

Я часто обнаруживаю, что меняю одну переменную в своем проекте в Git для подключения к другому серверу в ветке разработки (в JavaScript, поэтому я не могу использовать препроцессоры).

Есть ли какой-либо способ в Git, который я могу условно использовать в одном файле в зависимости от того, в какой ветке я работаю?

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

Ответ 1

Нет, нет, но это хорошо разрешенная проблема.

У вас есть несколько вариантов:

Версия управляет примером конфигурационного файла

  • Не хранить данные, зависящие от среды, в управлении версиями
  • Создайте файл config.example, в котором перечислены все параметры конфигурации, которые необходимо указать, и предоставит нормальные значения по умолчанию для разработки.
  • Пользователи, которые клонируют ваше репо, должны скопировать config.example в реальное имя файла конфигурации и добавить реальные значения
  • Добавьте настоящее имя файла конфигурации в .gitignore.
  • Сохраните ваши учетные данные за пределами git, но резервное копирование,
  • В качестве бонуса вы можете добавить setup.sh script, который копирует config.example в реальное местоположение конфигурации и заполняет его переменными для локальной среды

В качестве примера у вас может быть приложение JavaScript, которое должно знать, где находится его база данных, и читает эту информацию с config/database.json. Вы можете использовать что-то вроде этого:

// config/database.example.json
DATABASE = {
  "host": "localhost",
  "user": "#TODO",
  "pass": "#TODO",
}

Чтобы выполнить запуск в разработке, вы должны скопировать этот файл в config/database.json и заполнить значения, соответствующие вашей среде разработки.

В процессе производства у вас будет config/database.json, который содержит производственные значения, но не контролируется версией.

Репо было бы config/database.json в своем .gitignore.

Версия для управления конфигурационными файлами, зависящими от среды

  • Храните X разных файлов конфигурации, по одному для каждой среды, вызывайте их config.development и config.production и т.д.
  • Symlink правильный для вашей среды.
  • добавить символическую ссылку в .gitignore

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

Ответ 2

Обратите внимание, что условие включает конфигурацию, начиная с Git 2.13 (Q2 2017).
Единственное условие, поддерживаемое на данный момент, - это имя проекта, а не имя хоста.

В вашем случае это будет работать, если каждая ветвь будет выгружена в ее собственной папке (с git worktree: см. "Несколько рабочих каталогов с Git" ).

См. commit 86f9515, зафиксировать 4aad2f1 ( 05 апреля 2017 г.) Nguyễn Thái Ngọc Duy (pclouds).
(слияние Junio ​​C Hamano - gitster - в совершить a2e2c04, 24 апреля 2017 г.

config: добавить условное включение

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

Настройка $GIT_DIR/.config работает, но если наказание за обновление $GIT_DIR/.config велико (особенно когда вы заканчиваете клонирование часто), это может быть не лучший способ. Наличие настроек в ~/.gitconfig, которые будут работать только для одного набора репозиториев, не будет в такой ситуации.
Наличие отдельного ${HOME}s может добавить больше проблем, чем оно решает.

Расширьте механизм include.path, который позволяет конфигурационному файлу включать другой файл конфигурации, так что включение может быть выполнено только при выполнении некоторых условий.
Тогда ~/.gitconfig может сказать: включить config-project-Aтолько при работе над project-A "для каждого project A, на котором работает пользователь.

В этом патче единственная поддерживаемая группировка основана на $GIT_DIR (в абсолютный путь), поэтому вам нужно будет группировать репозитории по каталогам или что-то подобное, чтобы воспользоваться им.

У нас уже есть include.path для безусловных включений. Этот патч имеет значение includeIf.<condition>.path, чтобы было ясно, что требуется условие.
Новая конфигурация имеет тот же подход обратной совместимости, что и include.path: более старые версии Git, которые не понимают includeIf, будут просто игнорируйте их.


Git 2.14 (Q3 2017) уточняет документацию.

См. commit ce933eb, совершить a076df2, commit 994cd6c, commit 9d71d94 (11 мая 2017 г.) Джефф Кинг (peff).
(Слияние с Junio ​​C Hamano - gitster - в commit ed98060, 29 мая 2017 года)

Документация теперь читает и включает в себя:

Включает

Секции include и includeIf позволяют включать конфигурацию директивы из другого источника. Эти разделы ведут себя одинаково друг за другом, за исключением того, что разделы includeIf могут игнорироваться если их состояние не оценивается как истинное; см. "Условные включения" ниже.

Тот же Git 2.14 усиливает эту функцию.
См. commit 0624c63 (16 мая 2017 г.) Ævar Arnfjörð Bjarmason (avar).
(слияние Junio ​​C Hamano - gitster - в commit b784d0b, 30 мая 2017 года)

Недавно введенный механизм "[includeIf "gitdir:$dir"] path=..." был дополнительно учтен с учетом символических ссылок.

Каталог "$dir", указанный в "gitdir:$dir", может быть символической ссылкой на реальное местоположение, а не то, что $(getcwd) может вернуться.
В этом случае реальная траектория "$dir" сравнивается с реальным путем текущий репозиторий, чтобы определить, содержит ли содержимое из именованного пути должны быть включены.

Ответ 3

Похоже, вас может заинтересовать hook; в частности, посмотрите на крюк после проверки. В принципе, вы должны написать небольшой script, который изменяет файл после проверки на основе значения $(git branch). Вы точно не укажете, что должно произойти, но скорее всего это будет связано с sed.

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