dotfiles

Dotfiles

Within Linux, we refer to our local user’s custom configurations as our dotfiles, which will come to be some of the most important files on your system as you configure settings between various applications. Recently, I have been configuring an installation of Manjaro i3wm which has given me some good experience in managing dotfiles. Since configuing a system like i3wm can require several files across many different directories, I thought now would be a good time to take a look at a good process to backup and restore these files. The configurations I have decided to backup using stow would (probably) not be easily migrated to other systems, and should only be installed on Manjaro i3wm. Using stow with more general configurations could allow for a more portable, light-weight setup that would be far less dependant on the platform.

Since i3wm is such a broad topic, in my description below I will leave the details on those configurations out. Look to the i3wm documentation for help on using or understanding such configurations. You can also see my personal knoats on i3wm or GitHub dotfiles repository also hosted on GitLab.

For a more general example, if you are using Urxvt as your terminal emulator and wanted to change the font displayed within the terminal, you would look to edit the ~/.Xresources file. After making these changes it’s easy to take the configuration for granted. Should you need to migrate to a new system, you’ll often find yourself digging through old configs, repeating the same steps, or making the same configurations within the same files. To avoid having to do this, we can use stow.

Using Stow

Stow allows us to easily track, backup, and restore our dotfiles within remote repositories using the VCS of your choice. For this example, I’ll be using Git. The stow documentation provides a great online reference for using the tool, giving examples for various scenarios throughout. Generally, stow accomplishes its file management by distributing symbolic links to similiar files or working trees of your parent directory. This can be a bit odd to work with at first, but once you are comfortable using stow you’ll feel much more confident in your system’s configuration.

The Stow Directory

Unless you are careful with how you invoke stow, the location you choose to create your stow directory is very important to how the command will be handled. Given no additional arguments, stow will by default search the parent directory for the configuration files being stowed within the call. You can use this to your advantage by choosing to stow the configs within a relevant directory. Should you be managing your own dotfiles, it would be beneficial to have stow begin its search within the tree of your user’s home directory. So, to ensure this is the case and start stowing configurations, all we need to do is create a new directory within the home directory for the user we want to configure. If you want to track your configurations with a VCS, you’ll also need to make this new directory into a new repository.

For full disclosure, there are many ways to approach using stow to manage your dotfiles. Here, I will cover the two approaches I have found to be the most useful for my needs. The first setup allows you to stow all of your files for a user with a single command, the second setup will allow you to use stow to configure dotfiles for one application at a time. There is no right or wrong approach here, just be careful that you do not symlink to a file you want to keep as you will lose the contents of that file.

More examples can be found on GitHub, and within various documentation sources found online.

General User Configurations

Using stow to backup a user’s dotfiles can allow you to restore your configurations with a single command - stow .. Following the steps below, I use a Git repository to version and restore my own dotfiles.

You can name the stow directory whatever you want, but its location is important. Assuming you have named your directory ~/dot as I did in my repository, we continue by populating this directory with our configurations -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Simplified file tree of a stow repository
~/dot/
├── .bash_aliases
├── .bashrc
├── bg-saved.cfg
├── .config
│   ├── Code - OSS/
│   ├── compton.conf
│   ├── conky/
│   ├── i3/
│   ├── polybar/
│   └── powerline-shell/
├── .dir_colors
├── .git/
├── .gitignore
├── .gitmodules
├── .local
│   └── bin/
├── nitrogen.cfg
├── packages/
├── README.md
├── .tmux/
├── .tmux.conf
├── .tmux.conf.local
├── .tmux-gitbar/
├── .tmux-gitbar.conf
├── .vim/
├── .vimrc
└── .Xresources

Notice how the file structure is identical to how the configurations are stored in the user’s home directory. This is important to how stow will handle creating the symbolic links when invoked. Since we created the file tree above within our user’s home directory, restoring the configurations is easy. From within our new ~/dot directory, we can run the stow command -

1
stow .

You should now notice when running ls -la ~/ that the stowed configs in your home directory are now linked to the files within the ~/dot/ directory, effectively defining your user’s local configurations from a remote repository tracked by Git. For example, one of the files in the tree above is .Xresources. Running ls -la ~/.Xresources will show the symbolic link we created within it’s output -

1
lrwxrwxrwx  1 kapper kapper       15 Oct 22 15:46  .Xresources -> dot/.Xresources

The local system file is pointing to the configuration stored within the ~/dot/ directory and Git repository. Now that stow has been ran, we can make changes to the ~/.Xresources file either by running vim ~/.Xresources or vim ~/dot/.Xresources, both files will reflect any changes made to the other, and in doing so Git will track any changes made.

Application Configurations

Stow can also be used to target specific application configurations, and in doing so gives an organized file structure with directories containing configurations only for the applications they are named after. For example, the file tree below could be created within the home directory as ~/dot/-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
~/dot/
├── README.md
├── tmux
│   ├── .tmux/
│   ├── .tmux.conf
│   ├── .tmux.conf.local
│   ├── .tmux-gitbar/
│   └── .tmux-gitbar.conf
├── urxvt
│   └── .Xresources
├── vim
│   ├── .vim/
│   └── .vimrc
├── bash
│   ├── .bash_aliases
│   └── .bashrc
├── bin
│   └── .local/
└── vscode
└── .config/

The format of the repository above allows us to manage the configurations based on the application instead of installing all of the user’s preferences in a single call to stow .. From within the ~/dot/ directory, we can now run the following commands instead -

1
2
3
stow tmux/
stow vim/
stow bash/

These commands would install the configurations for tmux, vim, and bash. This approach may be favorable, as you can install some configurations while leaving out others. But it’s also important to consider the complexity of your configurations. In an environment where your user configurations are dependent, it may be better to approach linking the configurations as a whole. This can avoid errors or issues when configs have been installed for one application but not another. If configurations are kept general and light, then managing them by application may be an easier approach, especially when only making small changes like vim tab size or adding a keybind to the tmux multiplexer.