# Git home config

By [bobuk.eth](https://paragraph.com/@bobuk) · 2024-12-13

---

Когда-то очень давно я сделал для себя систему хранения конфигов в git. Потом оказалось что я изобрел велосипед, который неплохо описан вот тут, [у атласианов](https://www.atlassian.com/git/tutorials/dotfiles)

Итак, давайте начнем с того, для чего вообще нужно держать конфиги в гите. Представьте себе ситуацию: вы настроили свою рабочую среду идеально, все конфигурационные файлы, все алиасы, все работает как часы. Но вот беда, ваш компьютер ломается, или вы решаете перейти на новый. В такой ситуации, если у вас нет бэкапа конфигов, вам придется все настраивать заново. Это может занять часы, а то и дни. Хранение конфигов в гите решает эту проблему. Вы всегда можете клонировать репозиторий с конфигами на новый компьютер и быстро восстановить свою рабочую среду.

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

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

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

Суть моего решения в одном алиасе для шелла:
--------------------------------------------

    alias home='git --work-tree=$HOME --git-dir=$HOME/.cfg'
    

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

Обратите внимание, я тут привожу синтаксис для Bash, хотя на деле у меня самого Fish, там между названием алиаса и его содержимым надо вставить пробел вместо `=`.

> Почему важно держать отдельную папку .cfg вместо обычной .git: мне так спокойнее, я уверен что не закоммичу ничего случайно.

Инициализация репозитория
-------------------------

    git init --bare $HOME/.cfg
    

В прицнипе всё, уже всё работает хотя этого конечно недостаточно, так гит (а точнее команда `home` которую я использую из алиаса) будет пытаться отслеживать **все** файлы, а это не имеет смысла. Я добавляю файлы в репозиторий выборочно. В конфиге репозитория следует произвести следующие изменения руками:

    [status]
        showUntrackedFiles = no
    

Эти изменения в файле `$HOME/.cfg/config` указывают гиту не показывать неотслеживаемые файлы при выполнении команды home status. Таким образом, гит будет учитывать изменения только в тех файлах, которые были явно добавлены через home add.

Добавление файлов и работа с изменениями
----------------------------------------

Понятно что команда `home add .bashrc` добавит файл `.bashrc` в репозиторий. Теперь `home commit -m 'add .bashrc' -a && home push` и всё, файл в репозитории и можно с ним делать всё что захочешь. Обычно я добавляю все нужные мне конфиги и коммичу их буквально в момент ДО первого их редактирования, так я точно не забуду оригинальное содержимое файла.

Синхронизация на разных девайсах
--------------------------------

Для начала надо создать пустой репозиторий где-то где вы будете хранить конфиги. В моем случае это github. Создаем пустой репо а потом добавляем его в конфиг нашего домашнего репозитория:

    home remote add origin <git-repo-url>
    

Теперь можно делать `home push` и `home pull` и все изменения будут синхронизированы между вашими устройствами.

Добавляем тот же алиас в шелл. Клониурем репозиторий

    alias home='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
    git clone --bare <git-repo-url> $HOME/.cfg
    

Теперь можно работать с конфигами на другом устройстве так же как и на первом. Начните с `home checkout` и все файлы из репозитория будут скопированы в ваш домашний каталог. Если какие-то файлы уже существуют, git выдаст ошибку, и вам придется их удалить или переименовать, чтобы продолжить операцию. Я обычно просто удаляю такие файлы, потому что лучше знаю какие конфиги это мой _source of truth_. В случе когда мне нужны какие-то чисто локальные вещи (например только на десктопном маке), я делаю инклюды. Например в `.bashrc`:

    if [ -f ~/.bashrc_local ]; then
        . ~/.bashrc_local
    fi
    

и все локальные для хоста настройки я храню в файле `.bashrc_local` который не добавляю в репозиторий.

Вывод
-----

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

---

*Originally published on [bobuk.eth](https://paragraph.com/@bobuk/git-home-config)*
