Disclaimer: il titolo è leggermente iperbolico, ci sono altre soluzioni provate al problema. Penso però che la tecnica qui sotto sia molto elegante.
Di recente ho letto di questa tecnica incredibile in un thread di Hacker News sulle soluzioni delle persone per memorizzare i loro dotfiles. L’utente StreakyCobra
ha mostrato la sua elegante configurazione e … Aveva così tanto senso! Sono in procinto di passare il mio sistema alla stessa tecnica. L’unico pre-requisito è installare Git.
Nelle sue parole la tecnica sottostante richiede:
Nessuno strumento extra, nessun symlink, i file sono tracciati su un sistema di controllo della versione, è possibile utilizzare rami diversi per computer diversi, è possibile replicare facilmente la configurazione su una nuova installazione.
La tecnica consiste nel memorizzare un repository Git nudo in una cartella “laterale” (come $HOME/.cfg
o $HOME/.myconfig
) utilizzando un alias appositamente creato in modo che i comandi vengano eseguiti contro quel repository e non nella solita cartella locale .git
, che interferirebbe con qualsiasi altro repository Git in giro.
Partendo da zero
Se non hai mai tracciato le tue configurazioni in un repository Git, puoi iniziare ad usare questa tecnica facilmente con queste linee:
git init --bare $HOME/.cfg
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
config config --local status.showUntrackedFiles no
echo "alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'" >> $HOME/.bashrc
- La prima linea crea una cartella
~/.cfg
che è un repository Git nudo che terrà traccia dei nostri file. - Poi creiamo un alias
config
che useremo al posto del normalegit
quando vogliamo interagire con il nostro repository di configurazione. - Impostare un flag – locale al repository – per nascondere i file che non stiamo ancora esplicitamente monitorando. Questo è così che quando si digita
config status
e altri comandi più tardi, i file che non si è interessati a tracciare non appariranno comeuntracked
. - Inoltre si può aggiungere la definizione dell’alias a mano al proprio
.bashrc
o usare la quarta linea fornita per comodità.
Ho impacchettato le linee precedenti in uno snippet su Bitbucket e l’ho collegato da uno short-url. In modo che tu possa impostare le cose con:
curl -Lks http://bit.do/cfg-init | /bin/bash
Dopo aver eseguito il setup qualsiasi file all’interno della cartella $HOME
può essere versionato con normali comandi, sostituendo git
con il tuo alias config
appena creato, come:
config status
config add .vimrc
config commit -m "Add vimrc"
config add .bashrc
config commit -m "Add bashrc"
config push
Installa i tuoi dotfiles su un nuovo sistema (o migra a questo setup)
Se memorizzi già la tua configurazione/dotfiles in un repository Git, su un nuovo sistema puoi migrare a questo setup con i seguenti passi:
- Prima dell’installazione assicurati di aver impegnato l’alias nel tuo
.bashrc
o.zsh
:
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
- E che il vostro repository sorgente ignori la cartella dove lo clonerete, in modo da non creare strani problemi di ricorsione:
echo ".cfg" >> .gitignore
- Ora clona i tuoi dotfiles in un repository nudo in una cartella “dot” del tuo
$HOME
:
git clone --bare <git-repo-url> $HOME/.cfg
- Definisci l’alias nello scope della shell corrente:
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
- Controlla il contenuto effettivo dal repository nudo al tuo
$HOME
:
config checkout
- Il passo precedente potrebbe fallire con un messaggio come:
error: The following untracked working tree files would be overwritten by checkout:
.bashrc
.gitignore
Please move or remove them before you can switch branches.
Aborting
Questo perché la tua cartella $HOME
potrebbe già avere alcuni file di configurazione di riserva che verrebbero sovrascritti da Git. La soluzione è semplice: fate il backup dei file se vi interessa, rimuoveteli se non vi interessa. Ti fornisco una possibile scorciatoia approssimativa per spostare automaticamente tutti i file incriminati in una cartella di backup:
mkdir -p .config-backup && \
config checkout 2>&1 | egrep "\s+\." | awk {'print '} | \
xargs -I{} mv {} .config-backup/{}
- Riavvia il check out se hai avuto problemi:
config checkout
- Imposta il flag
showUntrackedFiles
ano
su questo specifico repository (locale):
config config --local status.showUntrackedFiles no
- Hai finito, da ora in poi puoi digitare
config
comandi per aggiungere e aggiornare i tuoi dotfiles:
config status
config add .vimrc
config commit -m "Add vimrc"
config add .bashrc
config commit -m "Add bashrc"
config push
Anche come scorciatoia per non dover ricordare tutti questi passaggi su ogni nuova macchina che vuoi impostare, puoi creare un semplice script, memorizzarlo come Bitbucket snippet come ho fatto io, creare un breve url per esso e chiamarlo così:
curl -Lks http://bit.do/cfg-install | /bin/bash
Per completezza questo è ciò che ho ottenuto alla fine (testato su molti container Linux alpini appena coniati per provarlo):
git clone --bare https://bitbucket.org/durdn/cfg.git $HOME/.cfg
function config {
/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME $@
}
mkdir -p .config-backup
config checkout
if ; then
echo "Checked out config.";
else
echo "Backing up pre-existing dot files.";
config checkout 2>&1 | egrep "\s+\." | awk {'print '} | xargs -I{} mv {} .config-backup/{}
fi;
config checkout
config config status.showUntrackedFiles no
Wrapping up
Spero che questa tecnica vi sia utile per tracciare la vostra configurazione. Se siete curiosi, i miei dotfile vivono qui. Inoltre vi prego di rimanere connessi seguendo @durdn o il mio fantastico team a @atlassiandev.