Задайте значения конфигурации git для всех дочерних папок

Я знаю, что можно установить конфигурации per-repo, которые переопределяют конфигурацию пользовательского уровня (т.е. /path/to/my/repo/.gitconfig переопределяет ~/.gitconfig). Можно ли установить git configs, которые переопределяют настройки уровня пользователя для всех дочерних папок данной папки? I.e., я

|--topLevelFolder1
|--\
|   ---.gitconfig_override
|--\
|   ---childFolder1
|       \---[...]
|--\
|   ---childFolder2
|       \---[...]

И я хочу, чтобы настройки, определенные в .gitconfig_override, применялись в childFolder1 и childFolder2.

Моя мотивация для этого заключается в следующем: у меня есть рабочий ноутбук, который я также использую в свое свободное время для личных проектов. Весь мой рабочий код вложен в одну папку. Когда я нажимаю на работу с репозиториями git, мне нужно сделать это с моей личной работой, вместо имени, и работать с электронной почтой. Когда я нажимаю на свои личные (github) репозитории, я хочу сделать это с моим настоящим именем и личной электронной почтой.

Другие возможные решения, о которых я думал (и проблемы):

  • Создайте отдельных пользователей для "работы" и "воспроизведения", соответствующим образом настройте их параметры на уровне пользователя и войдите в систему как подходящий пользователь, когда я переключаю контекст (хлопот, плюс я мог бы легко забыть переключиться).
  • Создайте script, который ищет git repos внутри "workFolder" и добавляет/обновляет свои файлы .gitconfig, чтобы удержать соответствующие данные (если я создаю репо и забудьте запустить script перед нажатием, Я буду толкать как не того человека)
  • "hack" git, так что каждый раз, когда он создает репо, он проверяет путь к файлу и, при необходимости, обновляет файл .gitconfig(сложный, грязный и почти наверняка The Wrong Way To Do It - plus, я не будет первой подсказки, как это сделать!)

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

Ответ 1

EDIT: Git 2.13 введено условное включает, которые предназначены для решения этой точной проблемы.

Мой оригинальный ответ сохранен ниже, ради истории (и пользователи застряли в более старых версиях git).

====================================

Точное поведение, которое вы желаете, не поддерживается, на основе чтения man-страницы gitconfig.

Однако, с git 1.7.12, Git считывает данные конфигурации из четыре разных источника, два из которых зависят от пользователя:

$XDG_CONFIG_HOME/git/config и ~/.gitconfig. Записи в ~/.gitconfig переопределяют записи в $XDG_CONFIG_HOME/git/config.

Это означает, что вы можете сохранить свой личный gitconfig в $XDG_CONFIG_HOME/git/config и поместить переопределения для машины в ~/.gitconfig. Что-то вроде

[user]
    email = [email protected]

в ~/.gitconfig должен охватывать ваш почтовый ящик.

Обратите внимание, что если $XDG_CONFIG_HOME не установлен, то Git будет искать ~/.config/git/config.

Это хорошо работает для меня, так как у меня только два личных репозитория на рабочих машинах (мой emacs config и мои dotfiles). Если вы часто добавляете личные репозиции на свои рабочие машины, это может быть недостаточно для вас.

В этом случае ваши собственные обертки вокруг git init и git clone будут наилучшим выбором.

Любой двоичный файл вашего $PATH, имя которого соответствует 'git - *', может быть вызван как команда Git, поэтому вам просто потребуется пара скриптов оболочки, которые вызывают исходную команду со всеми переданными аргументами, затем скопируйте правильный файл конфигурации в .git/config.

Ответ 2

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

Прочитайте базовую страницу direnv http://direnv.net/, чтобы настроить ее для своей оболочки. Для zsh было так же просто, как придерживать эту строку в нижней части моего .zshrc и перезапустить оболочку.

eval "$(direnv hook zsh)"

Убедитесь, что параметр git, который вы хотите, может управляться переменной окружения. Кажется, вы хотите управлять author.email для определенного дерева каталогов, управление которым осуществляется установкой GIT_AUTHOR_EMAIL. Переменные среды имеют приоритет над конфигурацией. Полный список переменных среды git читается здесь: https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables

Как указано на странице direnv, создайте файл .envrc в корне иерархии, в вашем случае topLevelFolder1

Например:

echo export [email protected] > .envrc

"Разрешить" envrc: direnv allow . Что это!

Каждый раз, когда вы переходите в иерархию, direnv найдет указанный .envrc файл и загрузит его.

$ cd ~/topLevelFolder1/childFolder1/project_name
direnv: loading ../../../.envrc
direnv: export +GIT_AUTHOR_EMAIL

$ echo ${GIT_AUTHOR_EMAIL}
[email protected]

Выскочите из dir-структуры и direnv выгрузите эти переменные

cd ~
direnv: unloading

Ответ 3

Раздел [include] в git config (.git/config, ~/.gitconfig...) - это то, что вы ищете.

[include]
    path = /path/to/foo.inc ; include by absolute path
    path = foo ; expand "foo" relative to the current file
    path = ~/foo ; expand "foo" in your $HOME directory

См. подробный ответ на вопрос: Можно ли включить файл в ваш .gitconfig

См. git -config Документация: http://git-scm.com/docs/git-config#_includes

ИЗМЕНИТЬ

Добавьте childFolder1/.git/config и childFolder2/.git/config:

[include]
    path = ../.gitconfig_override

Ответ 4

Как упоминалось NateEag edit, git Условные Включает идеальны для этого. Так как этот ответ для людей на git < 2.13, здесь для тех, у кого есть более новые версии.

Сначала создайте новый конфигурационный файл где-нибудь с настройками, которые вы хотите задействовать в подпапках, - используя исходные папки вопросов, скажем, на ~/topLevelFolder1/.gitconfig_override

В ~/.git/config добавьте:

[includeIf "gitdir:~/toplevelFolder1/"]
    path = ~/topLevelFolder1/.gitconfig_override

Любая подпапка ~/topLevelFolder1 теперь будет включать конфигурацию в ~/topLevelFolder1/.gitconfig_override - нет необходимости вручную изменять .git/config в каждом репозитории подпапки. (Это не переопределяет все настройки вложенной папки - это просто добавляет к нему, как предполагает "include".)