Managing your .dotfiles
Dotfiles are files that house your configuration for many unix based software (linux and mac) residing on your vms or your laptops/desktops. Popular ones are -
- Shells - bash(.bashrc), zsh(.zshrc), fish, oh-my-zsh etc
- Text editor - vim(.vimrc)
- Terminal - iterm2
- Shell theme - powerlevel10k
- Development CLI - aws cli, npm, sdkman, pyenv, terraform etc
- IDE - vscode
and a lot more.
I have changed laptops and systems frequently, and I dreaded this process of backing up my data and copying to the new system. All my code is version controlled so I don't need to back them up. All my documents are synced to cloud, so I don't worry about that.
The challenge I faced when setting up new systems is -
- Installing all the software I used in previous systems (Who maintains a list!!)
- Configuring them to me liking
- Maintaining upto date configurations across systems (if you use multiple vms)
And as I had posted earlier I have specific configuration for Mac that I like and end up repeating these steps each time.
This got me thinking, there must be a better way!
Well there is! Dotfiles management tools. This is specially useful for folks who need to provision new vms according to company or personal customisation.
There are a lot of tools and how-to wikis available to manage your dotfiles. I have researched extensively on this and found multiple good options available. I will list the ones I have checked, and what I have employed for my own needs. I will list them in order of smallest learning curve to largest -
NOTE : You can use any cvs like Git to manage your dotfiles.
1) $HOME
This is the most obvious, straightforward way, with zero learning curve
1.1 Vanilla git
As most of your dotfiles reside in your $HOME folder you can potentially version control your entire $HOME. This is dangerous if your repo is public, you may unknowingly share your .ssh keys for example. But you can avoid this by few ways -
1.1.1 Whitelist - create a .gitignore to ignore all dotfiles by default, and add whitelist of ones you want to include. For example, below I am ignoring all .files except .gitignore
.* !.gitignore
1.1.2 Blacklist - Allow all dotfiles to be versioned, except few files. Like below. I like this approach, though I have not adopted it (maybe in future). This allows changes to be shown when I do $git status. But you will need to constantly maintain this list which will increase as you add new content.
.ssh .aws .kube
1.2 Git bare
This allows you to check-in files only certain files. With a normal git repo, you could potentially do $git add * to checkin all files (as it maintains an active worktree) where as git bare does not. So you cannot push files unknowingly. Only drawback is it does not show the changed files on my shell prompt, but you can do $git status as always.
This is what I am using. You can refer to this excellent blog on how to set it up.
2) Outside $HOME
In this approach you will version control a folder which is not $HOME. This is done via symlinking your .dotfiles in your $HOME folder into a separate version controlled folder.
This is the safest approach, but with more setup and learning required. I have explored a few options here.
2.1 GNU Stow
https://www.gnu.org/software/stow/manual/stow.html#Introduction
This is the oldest tool (unknown to most, including me) in this list. This basically creates an alternate clone of the complete directory structure of the application. For example, if you use pyenv you will have following structure in your $HOME
$HOME
|--.pyenv
├── shims
├── version
└── versions
When you do $stow .pyenv it will create an alternate directory tree as below and symlink all your files to $HOME, so your commands work as before.
$HOME
|--stow
|--.pyenv
├── shims
├── version
└── versions
Now you can version you stow folder. On your new system all you need to do is, clone this folder, install stow and run $stow .pyenv which will create the symlinks in your new $HOME. More on this here
2.2 DOTBOT
https://github.com/anishathalye/dotbot
This is a tool to setup your dotfiles similar to GNU stow, but it adds some extra features to conditionally install your dotfiles (based on OS) and have a setup script that can run, and when setting up on your new system, you just run a single command ./install
2.3 YADM
https://github.com/TheLocehiliosan/yadm
This tool builds over DOTBOT and offers encryption, hooks, bootstrap, alternate files for different environments.
Let me know how you are managing your dotfiles in the comments (If not you should consider it!).
if it's Mac -> Mac, a lot of stuff is taken care by the Migration Assistant software on the Macs. In the olden days, there was a software called Norton Ghost using which you could replicate your machine and then 'burn' it on to a new one.