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 gewonegit
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 alsuntracked
. - 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
opno
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.