Встановіть значення конфігурації git для всіх дочірніх папок


80

Я знаю, що можна встановити конфігурації для кожного репо, які замінюють конфігурацію на рівні користувача (тобто /path/to/my/repo/.gitconfigзамінює ~/.gitconfig). Чи можна встановити налаштування git, які замінюють налаштування на рівні користувача для всіх дочірніх папок даної папки? Тобто я маю

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

І я хочу, щоб налаштування, визначені в, .gitconfig_overrideзастосовувались в childFolder1і childFolder2.

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

Інші можливі рішення, про які я думав (і проблеми):

  • Створіть окремих користувачів для "роботи" та "відтворення", встановіть належним чином їхні параметри на рівні користувача та ввійдіть як відповідний користувач, коли я переключаю контекст (клопоти, плюс я міг легко забути перейти)
  • Створіть скрипт, який шукає git repos всередині "workFolder", і додає / оновлює їхні файли .gitconfig, щоб зберігати відповідні деталі (якщо я створив репо і забув запустити сценарій перед натисканням, я буду натискати як неправильну особу)
  • "зламати" git таким чином, що кожного разу, коли він створює репо, він перевіряє шлях до файлу і, за необхідності, оновлює файл .gitconfig (складний, безладний і майже напевно Неправильний спосіб зробити - плюс, я б не мав перший підказка, як це зробити!)

Я перевірив це питання , яке, схоже, містить рішення лише для одного репозиторію, а не для кількох. Сподіваємось, хтось побачить це питання, хто його пропустив!


Чи будете ви працювати над тим самим сховищем, що і "працюйте на вас", і "на вас особисто"? Якщо ні, запитання, на яке ви зв’язали, містить відповідь, яку я дав би. Ваші --globalналаштування користувача повинні містити будь-яку особу, яку ви більше використовуєте. Кожне сховище, яке повинно використовувати іншу ідентифікацію, повинно мати user.nameта user.emailвстановлювати відповідно.
Кріс

Я ніколи не буду працювати в одному репо з двома різними користувачами - кожне репо буде або "робочим", або "домашнім", - але проблема випливає з того, що (принаймні для роботи) у мене є щось на зразок 35 репозиторіїв, і додаю регулярніше. Я міг би додати параметри user.nameта user.emailналаштування у кожному з існуючих репозиторіїв та встановити cron-скрипт, щоб додати їх до будь-яких нещодавно доданих репозиторіїв, але було б набагато простіше, якби я міг встановити їх в одному місці, яке "фільтрується" до будь-якого репозиторії в дочірніх папках.
scubbo

Відповіді:


32

РЕДАГУВАТИ: Git 2.13 представлений умовно включає , які призначені для вирішення саме цієї проблеми.

Моя оригінальна відповідь збережена нижче, заради історії (і користувачі застрягли на старих версіях git).

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

Точна поведінка, яку ви бажаєте, не підтримується, засноване на прочитанні сторінки 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 = username@example.com

in ~/.gitconfigповинен охоплювати вашу справу електронної пошти.

Зверніть увагу, що якщо $ XDG_CONFIG_HOME не встановлено, git буде шукати ~/.config/git/config .

Це добре працює для мене, оскільки я маю лише два особисті репозиторії на робочих машинах (моя конфігурація emacs і мої файли точок). Якщо ви часто додаєте персональні репозиторії до своїх робочих машин, це може бути недостатньо для вас.

В такому випадку, найкращі обгортки навколо git initі git cloneбудуть найкращим вибором.

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


Деякими налаштуваннями git можна керувати, встановлюючи змінні середовища. Вони замінюють значення з конфігураційного файлу. Дуже хороша утиліта для встановлення / зняття змінних змінних env для ієрархії каталогів - direnv. Для деталей див. Мою відповідь нижче.
Ajay M

90

Як зазначив редагувати NateEag в , Git і Умовний Включає ідеально підходять для цього. Оскільки ця відповідь відповідає людям на git <2.13, ось і відповідь для тих, хто має новіші версії.

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

В ~/.gitconfig, додайте:

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

Будь-яка підпапка ~/topLevelFolder1тепер включатиме конфігурацію ~/toplevelFolder1/.gitconfig_include- немає необхідності вручну змінювати .git/configрепо кожної підпапки. (Це не замінює все, що є в конфігурації підпапки - воно просто додає до нього, як випливає з "include".)


10
Кінцева скісна риска ( /) в gitdirумові важлива.
stefanct

2
Це слід позначити як правильну відповідь на це запитання. Завдяки згадці про includeIf(і трохи спроб і помилок), я зараз сконфігурував одне конкретне дерево папок на моєму робочому ПК, в якому кожна дія Git ідентифікує мене як мій особистий кабінет і використовує мій особистий ключ SSH, а також схожу папку для робочих матеріалів на моєму персональному ПК Тим часом решта кожної системи використовує відповідну електронну адресу, ім'я та ключ SSH на обох машинах. Я бажаю лише більше разів проголосувати цю відповідь .. (:

Чи ifсправді частина потрібна? Якщо посилання pathне існує, запис, схоже, ігнорується.
Олівер Пірмен

Якби тільки git просто зробив логічну справу і ходив по дереву, шукаючи .gitкаталоги у кожному батьківському каталозі ...
Ian Kemp 02

@OliverPearmain Мета не включати файл, якщо він існує, а включити файл, якщо ви перебуваєте в репо за вказаним шляхом.
phemmer

14

Ви можете використовувати direnvкоманду для встановлення змінних середовища, які застосовуються до всіх дочірніх папок. Ви можете бути де завгодно в цій ієрархії каталогів. Якщо параметром git, який ви намагаєтесь встановити, можна керувати змінною середовища, то вам пощастило.

Прочитайте direnvосновну сторінку http://direnv.net/, щоб налаштувати її для вашої оболонки. Для zsh це було так просто, як приклеїти цей рядок унизу мого .zshrcі перезапустити оболонку.

eval "$(direnv hook zsh)"

Перевірте, чи можна налаштування git, яким ви хочете, керувати змінною середовища. Здається , що ви хочете контролювати author.emailдля конкретного дерева директорій, який управляється змінної оточення, GIT_AUTHOR_EMAIL. Зверніть увагу, що змінні середовища мають перевагу над config. Повний перелік змінних середовища, які підтримує git, знаходиться тут: https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables

Як direnvвказує сторінка ', створіть файл з іменем .envrcу корені ієрархії; у вашому випадку,topLevelFolder1

Наприклад:

echo export GIT_AUTHOR_EMAIL=myotheremail@esp.com > .envrc

"Дозволити" envrc: direnv allow .Ось і все!

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

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

$ echo ${GIT_AUTHOR_EMAIL}
myotheremail@esp.com

Вискакує зі структури каталогу і direnvвивантажує ці змінні

cd ~
direnv: unloading

7

[include]Розділ в мерзотникові конфігурації ( .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

2
Добре - отже, це вирішує проблему лише визначення user.nameі user.emailв одному місці (в ../.gitconfig_override), але я не думаю, що це насправді відповідає на вихідне питання? Якщо childFolder1і childFolder2є дітьми parentFolder, я шукав спосіб встановити значення конфігурації, parentFolderякі б фільтрувались до будь-яких репозиторіїв, корінених у дочірніх папках.
scubbo

1
Як зазначив NateEag , це було представлено лише в Git 2.13. (Git 2.13.0 датується 9 травня 2017 р.) Отже, якщо хтось, хто читає цю відповідь, задається питанням, чому це не працює для них, можливо, він використовує стару версію Git.

ПРИМІТКА. Нещодавно я зіткнувся з проблемою, де ці умовні включення, здається, не дотримувались. Проблема полягала в тому, що git (принаймні, моя установка - 2.17.0 на MacOSX), схоже, вимагає кінцевої косої риски на шляхах каталогів.
scubbo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.