Excelente estratégia para "dotfiles"
Recentemente estive pesquisando sobre "dotfiles" para migrar facilmente minhas configurações entre diferentes máquinas e sistemas e acabei esbarrando numa estratégia que considerei excelente, mas que não vi uma alta divulgação, principalmente em português.
Isso me motivou a criar esse 1º post meu aqui no TabNews, pois achei que realmente agregaria valor.
TL; DR;
- "dotfiles" são arquivos de configuração do sistema
- Uma estratégia muito comum para sincroniza-los é o uso de links simbólicos para os arquivos de um repositório Git. Porém, isso pode ser inviável em algumas situações
- Nesse post procuro divulgar uma estratégia alternativa que cria um alias para um comando
git
com 2 argumentos específicos
Descrevendo rapidamente o que são "dotfiles"
São arquivos de configuração que normalmente tem o nome começando com "ponto" ("." ou "dot") e que são usados comumente para configurar a execução de ambientes ou ferramentas.
Exemplos de arquivos "dotfiles" comumente conhecidos: .gitconfig
, .profile
, .bashrc
, .zshrc
, .condarc
, etc . . .
Geralmente também se localizam nas pasta home
do usuário (o que não é obrigatório) e comumente são pré-definidos como arquivos ocultos, que é uma convenção comum para arquivos ou pastas cujo nome começam com ponto "." (eu particularmente prefiro nunca ocultar esses arquivos).
Estratégia comum para "dotfiles": usando "links simbólicos"
Nas minhas pesquisas percebi que uma estratégia muito comum para definir dotfiles passa por armazená-los em um subdiretório da sua escolha, tornando-o um repositório Git versionado, e depois criar links simbólicos dos dotfiles da sua máquina que apontam para os arquivos deste diretório.
Essa estratégia está inclusive mencionada em outro post aqui do TabNews e popularizada em português por esse vídeo do Mario Souto.
A minha dificuldade com essa estratégia foi exatamente na criação dos links simbólicos, pois sou usuário de Windows e acho que a criação desses links não é tão trivial no Windows quando você não tem privilégios de administrador do sistema.
Estratégia alternativa excelente para dotfiles: usar um "alias" para um comando git
customizado que passa 2 argumentos específicos
Essa estratégia busca usar sua pasta home
de usuário (a qual contém os dotfiles) como o "árvore de trabalho" do Git, porém sem inicializá-la diretamente como um repositório Git, pois isso poderia gerar algumas confusões, principalmente quando você possuir algum repositório interno a ela.
Essa estratégia tem o benefício de rastrear dotfiles diretamente com o Git e requer apenas Git e não envolve links simbólicos.
Ideia da estratégia
Toda a estratégia se baseia em passar 2 argumentos específicos para o comando git
: --git-dir
e --work-tree
.
--work-tree
: esse argumento é usado para definir um diretório fixo como a "árvore de trabalho" do Git, que será apontada para a pastahome
do usuário. Normalmente (quando não usamos esse argumento) a árvore de trabalho do Git é a própria pasta onde o comandogit
está sendo chamado.--git-dir
: esse argumento é usado para definir um diretório fixo como o "banco de dados" do repositório, que pode ser apontado para qualquer outra pasta da sua preferência. Normalmente (quando não usamos esse argumento) o diretório do "banco de dados" do repositório é uma pasta (comumente oculta) nomeada.git
que se localiza no mesmo diretório da arvore de trabalho, criada no instante da inicialização do repositório.
Execução da estratégia
Uma vez definida a pasta onde você quer manter o "banco de dados" do seu dotfiles, basta definir um alias da sua preferência no shell da sua preferência.
Por exemplo, caso o banco de dados do repositório dotfiles seja a pasta $HOME/Repos/dotfiles/.git
(pode ser qualquer outro) podemos usar o alias config
(que também pode ser outro nome):
- bash/zsh:
alias config='git --git-dir=$HOME/Repos/dotfiles/.git --work-tree=$HOME'
- PowerShell:
No PowerShell é mais fácil definir um alias com uma função
A variável@Args
serve para passar outros argumentos adicionais para o comandogit
.
function config() {git --git-dir=$HOME/Repos/dotfiles/.git --work-tree=$HOME @Args}
- cmd:
Pode-se tentar usar odoskey
para criar um alias no CMD, mas há muita limitação. Talvez seja mais fácil criar um script.bat
para utilizar o comando. Eu particularmente não uso mais o CMD, mas coloquei esse shell aqui para caso alguém tenha uma solução para utilizá-lo nos comentários.
Exemplo de uso da estratégia
config add .bashrc
config commit -m "Adicionando arquivo .bashrc"
config log
config push
Ignorando arquivos da pasta home
Você pode adicionar alguns arquivos da pasta home
usando o comando config add
(como mostrado acima) e ignorar todos os outros arquivos não adicionados da sua pasta home
por padrão, para evitar mostrar todos eles quando executar um config status
.
Você pode fazer isso com um simples arquivo .gitignore
contendo um único *
. Porém isso tem duas desvantagens:
- Vai obrigá-lo a adicionar novos arquivos com o comando
config add -f
para forçar adição dos arquivos não adicionados antes. - Vai ignorar todos os outros arquivos não adicionados, mesmo aqueles que você queria que fossem rastreados.
Para evitar isso, ao invés de ignorar tudo com apenas um único *
no .gitignore
, você poder escolher uma pasta que você não quer que seja ignorada e definir um padrão que adicione essa pasta para o Git rastrear. Por exemplo:
Escolhendo $HOME/minhasConfigs
como uma pasta que não deve ser ignorada, defina seu .gitignore
da seguinte forma:
/*
!minhasConfigs/
Caso escolha alguma outra subpasta para rastrear, pesquise a forma de excluí-la do .gitignore
. Isso pode ser um pouco não trivial e mereça um post separado pois foge do tema aqui, mas esse tópico do Stack Overflow discute algumas formas simples de trabalhar com o .gitignore
.
Uma outra estratégia para evitar usar o -f
em config add -f
é não usar o .gitignore
e evitar que os arquivos não adicionados sejam mostrados com a seguinte configuração:
config config status.showUntrackedFiles no
Porém, essa estratégia mantém a 2ª desvantagem: vai ignorar todos os outros arquivos não adicionados.
Usando repositório bare
Eu particularmente prefiro definir o banco de dados do repositório dotfiles apontando-o para uma pasta .git
comum, vinda de outro repositório interno da minha máquina, como feito no exemplo acima.
Isso permite que eu utilize ferramentas de visualização de histórico, como o Git Graph ou o SourceTree, que pressupõem a existência dessa pasta padrão .git
.
Porém, você pode definir o banco de dados como qualquer outra pasta do computador, inicializando-a como um repositório do tipo bare, passando o argumento --bare
para o comando git init
.
Por exemplo: caso eu queira que o banco de dados do repositório dotfiles seja simplesmente a pasta $HOME/Repos/dotfiles
(pode ser qualquer outra), eu deveria inicializá-la da seguinte forma:
git init --bare $HOME/Repos/dotfiles