Published on

Tutorial 1: How to manage dotfiles

Authors
  • avatar
    Name
    Shibi Suriya
    Twitter

This is a dead simple tutorial on how to manage dotfiles meant for absolute beginners, we won't be exploring any fancy tools (like GNU stow, dotbot, chezmoi, etc.) that abstracts away the basics & makes our work easier, instead we will be using simple shell commands to set everything up from scratch to understand what most of these tools actually do under the hood.

What are dotfiles?

Dotfiles are hidden files that are used to configure computer programs.

For example,

  1. The dotfile .zshrc (located at /Users/<username>/) is used to configure the user's zsh shell.

  2. The dotfile keybindings.json (located at /Users/<username>/Library/Application Support/Code/User) is used to add, remove and modify keyboard shortcuts for vscode.

Computers hide files and directories whose name starts with a ., so dotfiles are typically hidden.

Why should I care about dotfiles?

Owning multiple computers

Let's say, recently at work your task involves frequently making small change to the codebase and pushing it to Github. After scambling through the clunky GUI of vscode to press the "Push commit" button multiple times, you feel that you will highly benefit from adding a keyboard shortcut to push commits to Github. So you add the keyboard shortcut and it feels very ergonomic, within hours/days your mind/nervous system gets used to the keyboard shortcut & you start to take it for granted. When you hop onto your personal computer after work hours or in the weekend you will badly miss this keyboard shortcut (trust me bro 😀)! You now have to manually copy all the keyboard shortcuts & settings that you changed in your work computer to your personal computer typically by pressing buttons on a GUI (Graphical User Interface).

This might sound silly, but I think this small inconvenience of manually syncing the configurations between multiple computers makes using multiple computers impractical... You might start feeling that one of your computer is better or more ergonomic than others (even though it might not be true, its just "Familarity Bias") and you would end up spending most of your time on this "one" computer because you feel the most productive in it.

Using multiple computers become very practical when you get the same experience across your computers with very little effort.

Virtual machines & Docker containers can also be considered "computers", if you are someone who spends a lot of time in virtual machines or docker containers, consistent experience (think system settings, installed programs, keyboard shortcuts, appearance, etc.) across your hosts, virtual machines & containers could be extremely valuable.

What if you were able to sync your settings & keyboard shortcuts across computers using a single (obiviously familiar) command,

git pull origin main

We will discuss how to set this up in this blog post.

New computers

Typically, most computer users tend to configure their computers for better ergonomics or to increase their productivity (to finish their work faster). Configurations might range from switching on the Dark theme, installing/uninstalling programs, modifying/adding keyboard shortcuts, tweaking performance, changing a program's appearance, etc.

Letting go of a computer and setting up everything from scratch on a new computer could be daunting especially for users who have invested a lot of time & energy into configuring their computer the way they like.

People who work with virtual machines or Docker containers a lot might even change their "computers" in hours or days! Setting up new "computers" frequently by clicking buttons in a GUI or by typing/pasting tons of commands in a shell is not practical.

Version control

We must be able to track what changes we made to our dotfiles, when and for what purpose... This allows us to revert changes we didn't like, also we would be able to debug and fix issues confidently without second guessing what worked and what didn't. For example, if you added a keyboard shortcut in vscode and didn't like it after a week of usage, you can easily go through the Git commit history and remove it.

Tutorial

  1. Create a directory named dotfiles at /User/<username>/ and initailize a git repository in it.

    mkdir ~/dotfiles
    cd ~/dotfiles
    git init
    
  2. Move your dotfiles files into the directory.

    Let's start by moving vscode's keybindings.json (a file that stores keyboard shortcuts of vscode) into ~/dotfiles.

    mkdir vscode
    mv "~/Library/Application Support/Code/User/keybindings.json" ~/dotfiles/vscode/keybindings.json
    
  3. Commit the changes.

    git add .
    git commit -m 'added vscode/keybindings.json'
    

    If you open vscode now, all of the keyboard shortcuts must have went back to their default values because vscode looks for keybindings.json file at ~/Library/Application Support/Code/User/keybindings.json but we have moved it to ~/dotfiles!

    To get all of your keyboard shortcuts back, you can either,

    1. Request vscode to look for keybindings.json at ~/dotfiles/vscode. This is usually impractical because most programs won't have provision for it.

    2. Symlink keybindings.json to ~/Library/Application Support/Code/User/.

    A symlink is a file that points to another file or directory, think of them as "shortcut files" (in Windows OS), they aren't copies of files or directories they just point to them. So when we delete a symlink, the file or directory that it points to is not deleted.

  4. Symlink ~/dotfiles/vscode/keybindings.json to ~/Library/Application Support/Code/User/.

    Create a shell script for creating symlinks,

    touch symlink.zsh
    chmod +x symlink.sh
    

    Paste these lines inside symlink.zsh,

    #!/bin/zsh
    ln -s ~/dotfiles/vscode/keybindings.json "~/Library/Application Support/Code/User/keybindings.json"
    # Add commands for creating symlinks for the rest of your dotfiles...
    

    Execute symlink.zsh

    ./symlink.zsh
    
  5. Move the rest of your dotfiles into ~/dotfiles and add commands in symlink.zsh for creating symlinks for them.

  6. Add remote & push your commits to it.

    git remote add origin <remote-url>
    git push origin main
    
  7. Clone this repo in another computer & execute symlink.zsh,

    git clone <repo-url>
    cd <repo-name>
    ./symlink.zsh
    

    You can now use basic git commands & github to keep your dotfiles in sync across your computers!

    Add/modify a keyboard shortcut in vscode & run,

    git add vscode/keybindings.json
    git commit -m 'added a new keyboard shortcut'
    git push origin main
    

    Get the newly added/modified keyboard shortcuts on your other computers by running,

    git pull
    

    Warning

    If you have decided to maintain your dotfiles repo publically make sure to not commit and push sensitive information (could include personal email addresses, JWT tokens, passwords, etc.) to the remote! If you have pushed sensitive information to the remote accidentally, make sure to clean up the commit history.

Where to go next?

Now that you know what dotfiles are, why you should manage them? & how to manage them by manually creating symlinks, you can further explore,

  • Managing dotfiles using GNU Stow

  • Managing dotfiles using a 'bare Git repository'

  • You can use Nix (the package manager) or Ansible playbook to setup new computers in minutes,

    • You will able to install all of the software applications you need (Chrome, Firefox, Neovim, Obsidian, etc.) on a new computer by running a couple of commands.

    • You will be able to configure your computer the way you want (dark mode enabled, point & click enabled, etc.) by editing text files & then running a couple of commands.

  • Using Docker or QEMU to test your dotfiles installation process

If you are looking for neat tools or technics for managing your dotfiles then peep my dotfiles repo & read my blog post 'How I manage my dotfiles?' where I explain my setup.

Happy hacking.