Dotfiles: a melhor maneira de armazenar em um repositório do Git simples
Isenção de responsabilidade: o título é um pouco hiperbólico, existem outras soluções comprovadas para o problema. Eu acho que a técnica abaixo é muito elegante.
Há pouco tempo, li sobre essa técnica incrível em um tópico do Hacker News sobre as soluções das pessoas para armazenar seus dotfiles. O usuário StreakyCobra mostrou sua configuração elegante e... fazia muito sentido! Estou mudando meu próprio sistema para a mesma técnica. O único pré-requisito é instalar o Git.
Em suas palavras, a técnica abaixo requer:
Ausência de ferramentas extras, sem links simbólicos, os arquivos são rastreados em um sistema de controle de versão, você pode usar branches diferentes para computadores diferentes, pode replicar sua configuração com facilidade em uma nova instalação.
A técnica consiste em armazenar um repositório simples do Git em uma pasta "secundária" (como $HOME/.cfg ou $HOME/.myconfig) usando um alias especialmente criado para que os comandos sejam executados nesse repositório e não na pasta local .git usual, o que interferiria com quaisquer outros repositórios Git ao redor.
Começando do zero
Se você não estava rastreando suas configurações em um Repositório do Git antes, você pode começar a usar essa técnica facilmente com estas linhas:
1git init --bare $HOME/.cfg
2alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
3config config --local status.showUntrackedFiles no
4echo "alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'" >> $HOME/.bashrcA primeira linha cria uma pasta
~/.cfgque é um repositório simples do Git que vai rastrear nossos arquivos.Em seguida, criamos uma
configuraçãode alias que vamos usar em vez dogitnormal quando quisermos interagir com nosso repositório de configuração.Definimos uma marcação — local para o repositório — para ocultar arquivos que ainda não estamos rastreando explicitamente. Essa marcação ocorre para que, quando você digitar
config statuse outros comandos posteriormente, os arquivos que você não está interessado em rastrear não apareçam comonão rastreados.Além disso, você pode adicionar a definição de alias manualmente ao seu
.bashrcou usar a quarta linha mostrada para sua conveniência.
Agrupei as linhas acima em um snippet no Bitbucket e o vinculei a partir de uma URL curta. Para que você possa configurar as coisas com:
1curl -Lks http://bit.do/cfg-init | /bin/bashDepois de executar a configuração, qualquer arquivo dentro da pasta $HOME pode usar o controle de versões com comandos normais, substituindo o git pelo seu alias de configuração recém-criado, como:
1config status
2config add .vimrc
3config commit -m "Add vimrc"
4config add .bashrc
5config commit -m "Add bashrc"
6config pushInstalar dotfiles em um novo sistema (ou migrar para essa configuração)
Se você já armazena suas configurações/dotfiles em um repositório do Git, em um novo sistema, você pode migrar para essa configuração com as seguintes etapas:
Antes da instalação, garanta que tenha feito o commit do alias no
.bashrcou.zsh:
1alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'E que seu repositório de origem ignora a pasta onde você vai cloná-lo, para que você não crie problemas estranhos de recursão:
1echo ".cfg" >> .gitignoreAgora clone seus dotfiles em um repositório vazio em uma pasta "dot" de
$HOME:
1git clone --bare <git-repo-url> $HOME/.cfgDefina o alias no escopo atual do shell:
1alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'Faça o checkout do conteúdo real do repositório vazio para sua
$HOME:
1config checkoutA etapa acima pode falhar com uma mensagem como:
1error: The following untracked working tree files would be overwritten by checkout:
2 .bashrc
3 .gitignore
4Please move or remove them before you can switch branches.
5AbortingO erro ocorre porque sua pasta $HOME pode já ter alguns arquivos de configuração de estoque que seriam substituídos pelo Git. A solução é simples: faça backup dos arquivos se você se importa com eles, remova-os se não se importar. Eu forneço a você um possível atalho aproximado para mover todos os arquivos ofensivos automaticamente para uma pasta de backup:
1mkdir -p .config-backup && \
2config checkout 2>&1 | egrep "\s+\." | awk {'print $1'} | \
3xargs -I{} mv {} .config-backup/{}Execute o checkout de novo se você tiver problemas:
1config checkoutDefina a marcação
showUntrackedFilescomononeste repositório (local) específico:
1config config --local status.showUntrackedFiles noVocê está pronto, a partir de agora você pode digitar comandos de
configuraçãopara adicionar e atualizar seus dotfiles:
1config status
2config add .vimrc
3config commit -m "Add vimrc"
4config add .bashrc
5config commit -m "Add bashrc"
6config pushDe novo, como um atalho para não ter que lembrar todas essas etapas em qualquer nova máquina que você quer configurar, você pode criar um script simples, armazená-lo como snippet do Bitbucket como eu fiz, criar uma URL curta para ele e chamá-lo assim:
1curl -Lks http://bit.do/cfg-install | /bin/bashPara concluir, foi assim que terminei (testado em muitos contêineres Alpine Linux recém-criados para testá-lo):
1git clone --bare https://bitbucket.org/durdn/cfg.git $HOME/.cfg
2function config {
3 /usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME $@
4}
5mkdir -p .config-backup
6config checkout
7if [ $? = 0 ]; then
8 echo "Checked out config.";
9 else
10 echo "Backing up pre-existing dot files.";
11 config checkout 2>&1 | egrep "\s+\." | awk {'print $1'} | xargs -I{} mv {} .config-backup/{}
12fi;
13config checkout
14config config status.showUntrackedFiles noEncerrando
Espero que você ache essa técnica útil para rastrear sua configuração. Se está curioso, meus dotfiles estão aqui. Além disso, fique conectado seguindo @durdn ou minha equipe incrível em @atlassiandev.