Managing your dotfiles .*
So you are finally tired of manually syncing your dotfiles? 😬
I’ve had the same personal computer for 6 years (Thanks Steve 😉 🍏) but this year I finally upgraded. I keep all my dotfile configs in Github repo so it’s pretty easy to just clone them to my new computer and it’s ready to go. But then I also use them at my work laptop now, and I end up modifying them more often, so I started looking for a better way to sync them all together 🤔
This is not a new problem and if you google there’re hundreds of blogposts and comments out there. I basically did that. And this is the solution that I liked the most: the idea is to link a cloned git repo of your dotfiles with the ones you have in `~/$HOME` using git worktrees.
The reason I liked it is because you can easily commit any changes using the alias and it will actually commit them into your git repo and then push to Github — amazing! 🎉
This is mainly based on this blog post I stumbled upon in my search journey for a perfect solution. So I took that as the base, tweaked a little to my needs and wrote a bash script for that will just do all of that for me whenever I’m setting up a new machine!
SO LET’S WALK THROUGH THE STEPS
Ok back up a sec… what exactly is a git worktree
You can skip this if you already know.
Worktree is essentially like a copy of your main git repository. You can have multiple worktrees associated with your main git repository. The best thing about them is that because those are linked it’s easy to sync up changes between your worktrees and main directory, as we will see later. You can read more about them here.
Let’s go through the setup steps
- What we are going to do is clone your GitHub repo with your dotfiles in the folder of your choice:
"> git clone —-bare <GITHUB_REFERENCE> $HOME/dotfiles
This clones my dotfiles repo in $HOME/dotfiles. It’s important to note that we want a bare repository here. Since the repo will not be edited directly but rather through its worktree.
2. Now we want to create an alias that will be like new command, allowing us to manipulate the changes of our dotfiles in the home repo and commit them to the main repository as well as push to github.
You can name it whatever you want, I was choosing between config and dotfiles and chose the latter to see if it sticks.
alias dotfiles = '/usr/bin/git --git-dir=$HOME/dotfiles/ --work-tree=$HOME'
Now every time you do dotfiles command in the terminal it would know that you refer to that folder.
If you do dotfiles checkout in your home directory that will checkout all your dotfiles from the cloned repo to ~/.. That easy! No copy over commands.
3. Now, you probably have a lot of other files in your home directory, so we want to make sure that only the once we checked out are getting traced by git. So let’s set the appropriate flag:
dotfiles config --local status.showUntrackedFiles no
Now, if you do dotfiles status it shows you any uncommited changes, if any.
4. 🛑 ✋ Before you go and try all the git commands, we need to add the alias to your .bashrc file so you don’t have to set it every single time.
echo "alias dotfiles='/usr/bin/git --git-dir=$HOME/dotfiles/ --work-tree=$HOME'" >> $HOME/.bashrc
That’s it! Now you cad do
dotfiles add <file>
dotfiles commit
aand
dotfiles push to make sure your changes are sync with github!
…aand any other git command really 😀
Now, let’s see how we can put this into a simple script to do the work for us.
All I did here was copying the commands described above. The only condition added is to checked whether you have already cloned the repository so that the script can be idempotent. Of course you can go further and add other checks, or backup your dotfiles before you run the script if you want to save those. For my purposes this will be used on clean new laptop so that’s all I need. But feel free to share your versions! 🎉
# /bin/bash
# Change this variable to customize your script
#
REPO_NAME=’dotfiles’
GITHUB_LINK=’<your_repo_url>’
ALIAS_NAME=’dotfiles’
GIT=`/usr/bin/git`if [ ! -d “$HOME/$REPO_NAME” ]; then
echo “Cloning your github repo …”
`git clone --bare $GITHUB_LINK $HOME/$REPO_NAME`
cd ~/
echo “Adding your dotfiles directory to .gitignore”
echo “$REPO_NAME” >> .gitignore
alias dotfiles=’$GIT --git-dir=$HOME/dotfiles/ — work-tree=$HOME’
echo “Copying your dotfile to your home directory..”
`dotfiles checkout`
echo “Adding your alias to your bash config”
echo “alias dotfiles=’$GIT --git-dir=$HOME/dotfiles/ --work-tree=$HOME’” >> $HOME/.bashrc
source $HOME/.bashrc
echo “Configuring tracking of files..”
`dotfiles config --local status.showUntrackedFiles no`
echo “All done!”
else
echo “You already have $HOME/$REPO_NAME directoty”
fi
I just started using this setup and it looks very promising! If you have another way of solving the same problem you like, let me know in the comment! 😃