skip to content
Архитектура в курилке

Как синкать dotfile-ы

/ чтиво на 3 минуты

Содержание

TLDR

Terminal window
# Первая инициализация
git init --bare $HOME/.dotfiles
alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
dotfiles remote add origin <git repo url>
dotfiles config status.showUntrackedFiles no
# Работа с новыми файлами
dotfiles status
dotfiles add <file>
dotfiles commit -m "Added <file>"
dotfiles push
# Инициализация на новом компе без файлов
git clone --separate-git-dir=$HOME/.dotfiles <git repo url> $HOME/.dotfiles-tmp
mv ~/.dotfiles-tmp ~/.dotfiles

Зачем

Предположим такую гипотетическую ситуацию: Вы поставили себе на компьютер Linux и стали “обживаться”. Поставили Ghostty, решили поменять шрифт, его размер, кастомную тему… Всего пара простых mkdir -p ~/.config/ghostty && nvim ~/.config/ghostty/config и вот он, терминал мечты. И новый файлик в .config

~
└── .config
└── ghostty
└── config

Потом решили, что надо бы перейти с bash на zsh, поставили, даже настроили пару биндов, подсветку, автокомплит:

~
├── .zshrc
└── .config
└── ghostty
└── config

Насмотрелись в r/UnixPorn на то, как люди упарываются в терминалы, настроили starship:

~
├── .zshrc
└── .config
├── ghostty
│ └── config
└── starship.toml

Всего пару дней такого баловства и файлов станет безбожно много.

И вдруг Вам дарят новый ноут, а хочется, чтобы все было по-старому, но быстрее, да и в целом как-то круче будет.

Всегда можно переносить руками, можно разово закинуть в git и оттуда вытащить.

А если у Вас несколько тачек (одна дома, вторая для работы)? А если хочется выпендриться на том же r/UnixPorn?

Если у Вас есть подобная “First World Problem”, то этот гайд для Вас.

Подробно

В целом это адаптированный перевод поста с Hacker News

Рассмотрим каждый из моментов отдельно.

Инициализация

При первом запуске достаточно инициализировать новую git репу в корне с флагом --bare.

Для удобства стоит обзавестись алиасом для работы с данными файлами. В моем случае я его просто добавляю в файл .aliases, который подсасывается .zshrc.

Далее по классике указываем remote для текущей репы.

При этом обязательно стоит указать в локальном конфиге для этой репы status.showUntrackedFiles no, в противном случае при вызове dotfile status ВСЕ файлы в домашнем каталоге будут отображаться как недобавленные в репу.

Команды

Все как в обычной git репе:

  • делаем правки в необходимых нам файлах

  • дальше вместое типичного git add делаем dotfiles add <путь до файла>

  • делаем коммит и пишем для него сообщение

  • dotfiles push

  • PROFIT!

Клонирование

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

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

Интеграция с starship

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

[custom.dotfiles]
format = "[-](white)[](green)[󰥵 ](bold crust bg:green)[](green bg:surface2)[ +$output](bold text bg:surface2)[](surface2)"
command = "/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME status -s | wc -l"
when = """test "$HOME" = "$PWD" && test $(/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME status -s | wc -l) -gt 0"""
description = "Shows number of dotfiles that are not synced"

В целом это просто небольшое напоминание для того, чтобы закоммитить изменения dotfile-ов. Если изменения есть, но они не закоммичены, то в домашней (~) папке будет выводиться количество таких файлов.

Выглядит страшно, но в целом ничего сложного здесь нет.

Параметр format - это просто форматирование вывода, здесь важна только переменная $output, которую формирует параметр command.

Параметр command вызывает git status -s, чтобы получить список измененных файлов. Даьше это пайпится в wc -l, чтобы получить просто их количество. Эта команда вызывается только тогда, когда параметр when возвращает не ошибку.

Параметр when сначала проверяет, что мы находимся в домашней директории test "$HOME" = "$PWD". Если это та, то мы считаем количество измененых файлов и проверяем, что их количество больше нуля.

desription - просто штука для strship explain.

А на деле это работает так:

starship

Заключение

Вы великолепны! Все работает, синкается с git-ом, этим можно хвалиться и синхронизировать устройства. Далее можно настраивать пуши в репу по крону, синхронизации в .**rc файлах при старте новой сессии. Как Вам угодно. Как говорится Sky is the limit