Descargo de responsabilidad: el título es ligeramente hiperbólico, hay otras soluciones probadas para el problema. Sin embargo, creo que la técnica de abajo es muy elegante.
Recientemente leí sobre esta increíble técnica en un hilo de Hacker News sobre las soluciones de la gente para almacenar sus dotfiles. El usuario StreakyCobra
mostró su elegante configuración y … ¡Tiene mucho sentido! Estoy en el proceso de cambiar mi propio sistema a la misma técnica. El único prerrequisito es instalar Git.
En sus palabras la técnica de abajo requiere:
No hay herramientas extra, no hay enlaces simbólicos, los archivos son rastreados en un sistema de control de versiones, puedes usar diferentes ramas para diferentes ordenadores, puedes replicar tu configuración fácilmente en una nueva instalación.
La técnica consiste en almacenar un repositorio Git desnudo en una carpeta «lateral» (como $HOME/.cfg
o $HOME/.myconfig
) utilizando un alias especialmente diseñado para que los comandos se ejecuten contra ese repositorio y no la carpeta local habitual .git
, que interferiría con cualquier otro repositorio Git alrededor.
Empezando desde cero
Si no has rastreado tus configuraciones en un repositorio Git antes, puedes empezar a usar esta técnica fácilmente con estas líneas:
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 primera línea crea una carpeta
~/.cfg
que es un repositorio Git desnudo que rastreará nuestros archivos. - Luego creamos un alias
config
que usaremos en lugar del habitualgit
cuando queramos interactuar con nuestro repositorio de configuración. - Ponemos una bandera -local al repositorio- para ocultar los archivos que aún no estamos rastreando explícitamente. Esto es para que cuando se escribe
config status
y otros comandos más tarde, los archivos que no están interesados en el seguimiento no se mostrará comountracked
. - También puede agregar la definición de alias a mano a su
.bashrc
o utilizar la cuarta línea proporcionada para la conveniencia.
He empaquetado las líneas anteriores en un fragmento de arriba en Bitbucket y lo vinculó de un corto-url. Así que usted puede configurar las cosas con:
curl -Lks http://bit.do/cfg-init | /bin/bash
Después de haber ejecutado la configuración de cualquier archivo dentro de la carpeta $HOME
puede ser versionado con comandos normales, reemplazando git
con su recién creado config
alias, como:
config status
config add .vimrc
config commit -m "Add vimrc"
config add .bashrc
config commit -m "Add bashrc"
config push
Instale sus dotfiles en un nuevo sistema (o migre a esta configuración)
Si ya almacena su configuración/dotfiles en un repositorio Git, en un nuevo sistema puede migrar a esta configuración con los siguientes pasos:
- Antes de la instalación asegúrese de haber confirmado el alias en su
.bashrc
o.zsh
:
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
- Y que tu repositorio de fuentes ignora la carpeta donde lo clonarás, para no crear problemas de recursión extraños:
echo ".cfg" >> .gitignore
- Ahora clona tus dotfiles en un repositorio vacío en una carpeta «dot» de tu
$HOME
:
git clone --bare <git-repo-url> $HOME/.cfg
- Define el alias en el ámbito actual del shell:
alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
- Revisar el contenido real del repositorio desnudo a su
$HOME
:
config checkout
- El paso anterior podría fallar con un mensaje como:
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
Esto se debe a que su carpeta $HOME
podría tener ya algunos archivos de configuración de stock que serían sobrescritos por Git. La solución es sencilla: haz una copia de seguridad de los archivos si te importan, elimínalos si no te importan. Le proporciono un posible atajo aproximado para mover todos los archivos ofensivos automáticamente a una carpeta de copia de seguridad:
mkdir -p .config-backup && \
config checkout 2>&1 | egrep "\s+\." | awk {'print '} | \
xargs -I{} mv {} .config-backup/{}
- Vuelva a ejecutar la comprobación si tuvo problemas:
config checkout
- Ajuste la bandera
showUntrackedFiles
ano
en este repositorio específico (local):
config config --local status.showUntrackedFiles no
- Ya está, a partir de ahora puede escribir los comandos
config
para añadir y actualizar sus dotfiles:
config status
config add .vimrc
config commit -m "Add vimrc"
config add .bashrc
config commit -m "Add bashrc"
config push
De nuevo como atajo para no tener que recordar todos estos pasos en cualquier máquina nueva que quieras configurar, puedes crear un simple script, almacenarlo como snippet de Bitbucket como hice yo, crear una url corta para él y llamarlo así:
curl -Lks http://bit.do/cfg-install | /bin/bash
Para completar esto es lo que terminé (probado en muchos contenedores Alpine Linux recién acuñados para probarlo):
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
Resumiendo
Espero que encuentres esta técnica útil para seguir tu configuración. Si tienes curiosidad, mis dotfiles viven aquí. También, por favor, mantente conectado siguiendo a @durdn o a mi impresionante equipo en @atlassiandev.