Disclaimer: de titel is lichtelijk hyperbolisch, er zijn andere bewezen oplossingen voor het probleem. Ik vind onderstaande techniek echter wel erg elegant.

Recentelijk las ik over deze verbazingwekkende techniek in een Hacker News thread over oplossingen van mensen om hun dotfiles op te slaan. Gebruiker StreakyCobra toonde zijn elegante setup en … Het maakte zo veel zin! Ik ben bezig om mijn eigen systeem om te schakelen naar dezelfde techniek. De enige voorwaarde is om Git te installeren.

In zijn woorden vereist de onderstaande techniek:

Geen extra tooling, geen symlinks, bestanden worden bijgehouden op een versie controle systeem, je kunt verschillende takken gebruiken voor verschillende computers, je kunt je configuratie eenvoudig repliceren op een nieuwe installatie.

De techniek bestaat uit het opslaan van een Git kale repository in een “side” folder (zoals $HOME/.cfg of $HOME/.myconfig) met een speciaal gemaakte alias, zodat commando’s tegen die repository worden uitgevoerd en niet tegen de gebruikelijke .git lokale folder, die zou interfereren met andere Git repositories in de buurt.

Beginnen vanaf nul

Als je nog niet eerder je configuraties in een Git repository gevolgd hebt, kun je deze techniek eenvoudig beginnen te gebruiken met deze regels:

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
  • De eerste regel maakt een map ~/.cfg aan die een Git kale repository is die onze bestanden zal volgen.
  • Dan maken we een alias config die we zullen gebruiken in plaats van de gewone git als we willen communiceren met onze configuratie repository.
  • We zetten een vlag – lokaal in de repository – om bestanden te verbergen die we nog niet expliciet volgen. Dit is zodat wanneer u later config status en andere commando’s typt, de bestanden die u niet wilt volgen niet zullen verschijnen als untracked.
  • Ook kunt u de alias-definitie met de hand toevoegen aan uw .bashrc of de vierde regel gebruiken die voor het gemak wordt meegeleverd.

Ik heb de bovenstaande regels verpakt in een snippet op Bitbucket en deze gelinkt via een short-url. Zodat u de dingen kunt instellen met:

curl -Lks http://bit.do/cfg-init | /bin/bash

Nadat u de setup heeft uitgevoerd kan elk bestand in de $HOME map worden geversioneerd met normale commando’s, door git te vervangen door uw nieuw aangemaakte config alias, zoals:

config status
config add .vimrc
config commit -m "Add vimrc"
config add .bashrc
config commit -m "Add bashrc"
config push

Installeer uw dotfiles op een nieuw systeem (of migreer naar deze setup)

Als u uw configuratie/dotfiles al in een Git repository opslaat, kunt u op een nieuw systeem naar deze setup migreren met de volgende stappen:

  • Voor de installatie moet u ervoor zorgen dat u de alias heeft vastgelegd in uw .bashrc of .zsh:
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
  • En dat je bron repository de map negeert waar je het gaat klonen, zodat je geen rare recursie problemen krijgt:
echo ".cfg" >> .gitignore
  • Kloon nu je dotfiles naar een kale repository in een “dot” map van je $HOME:
git clone --bare <git-repo-url> $HOME/.cfg
  • Definieer de alias in de huidige shell scope:
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
  • Checkout de daadwerkelijke inhoud van de kale repository naar je $HOME:
config checkout
  • De bovenstaande stap zou kunnen mislukken met een bericht als:
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

Dit komt omdat uw $HOME map misschien al een aantal standaard configuratiebestanden bevat die door Git overschreven zouden worden. De oplossing is simpel: maak een backup van de bestanden als je er om geeft, verwijder ze als je er niet om geeft. Ik geef je een mogelijke ruwe snelkoppeling om alle beledigende bestanden automatisch naar een backup map te verplaatsen:

mkdir -p .config-backup && \
config checkout 2>&1 | egrep "\s+\." | awk {'print '} | \
xargs -I{} mv {} .config-backup/{}
  • Voer de check out opnieuw uit als je problemen had:
config checkout
  • Zet de vlag showUntrackedFiles op no op deze specifieke (lokale) repository:
config config --local status.showUntrackedFiles no
  • Je bent klaar, vanaf nu kun je config commando’s typen om je dotfiles toe te voegen en te updaten:
config status
config add .vimrc
config commit -m "Add vimrc"
config add .bashrc
config commit -m "Add bashrc"
config push

Ook als een snelkoppeling om niet al deze stappen te hoeven onthouden op elke nieuwe machine die u wilt instellen, kunt u een eenvoudig script maken, sla het op als Bitbucket-snippet zoals ik heb gedaan, maak er een korte url voor en roep het als volgt aan:

curl -Lks http://bit.do/cfg-install | /bin/bash

Voor de volledigheid is dit waar ik mee ben geëindigd (getest op vele vers geslagen Alpine Linux containers om het uit te testen):

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

Ik hoop dat u deze techniek nuttig vindt om uw configuratie bij te houden. Als je nieuwsgierig bent, mijn dotfiles staan hier. Blijf ook verbonden door @durdn te volgen of mijn geweldige team bij @atlassiandev.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.