Skip to content

My dotfiles for consistent behaviour across devices

Notifications You must be signed in to change notification settings

justinnais/.dotfiles

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dotfiles

Based on jesuswasrasta's dotfile config

Quick Install

Run this script on new machine to setup dotfiles

curl -Lks https://gist.githubusercontent.com/justinnais/11e49896a4632d294a30283de5465e19/raw/a5a26fefc3c8eee03d5911f87da61f96ef55218e/dotfiles_setup.sh | /bin/bash

How it works

The technique consists in storing dotfiles in a Git bare repository, but in a customized $HOME/.dotfiles folder instead of the usual .git folder.
Then, using a special Git alias command, I'm able to add and commit files I want to track in the repo, and pushing them to a remote repo.

Repository structure

I use a different Git branch for every machine; on main branch there are only common file I use as a template.

Main branch

Contains:

  • common ignore file
  • common shell aliases I always use
  • other common files and configurations I like to have on all my machines

Machine branches

Contains:

  • .gitconfig

Starting from scratch

If you haven't been tracking your configurations in a Git repository before, you can start using this technique easily with these lines:

1) git init --bare $HOME/.dotfiles
2) alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'
3) dotfiles config --local status.showUntrackedFiles no
4) dotfiles config --local core.excludesFile=.dotfilesignore
5) echo ". ~/.zsh_aliases" >> $HOME/.zshrc
6) echo "alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'" >> $HOME/.zsh_aliases
7) echo "alias dfg=dotfiles" >> $HOME/.zsh_aliases
  1. The first line creates a folder ~/.dotfiles which is a Git bare repository that will track your files.
  2. Then we create a new command dotfiles that is nothing else than a customized alias to git command, configured to work only with your .dotfiles repo. We will use it instead of the regular git command when we want to interact with our configuration repository.
  3. We set the flag status.showUntrackedFiles no - local to the repository - to hide files we are not explicitly tracking yet. This is so that when you type dotfiles status and other commands later, files you are not interested in tracking will not show up as untracked.
  4. To make things more coherent, I use a custom .dotfilesignore as Git ignore file instead of the common .gitignore one. This way it's easier to remember where to write your exclusions.
  5. I usually store my aliases in a separate file, like .zsh_aliases, then I include it in my .zshrc appending this line to it: . ~/.zsh_aliases.
  6. Add the dotfiles alias definition by hand or use the the command provided for convenience.
  7. I usually create even another alias to my newly created command called dfg; I would call it df but, you know, there's already a df command on Unix boxes :)
    So I opted for dot files git acronym, dfg, that is (at least for me) easy to remember and convenient, as in QWERTY keyboards the three letters are adjacent.

As a Zsh user, in these example I worked with .zshrc and .zsh_aliases files; feel free to substitute them with .bashrc and .bash_aliases if you plan to use Bash as your preferred shell: they works the same way.

After you've executed the setup, any file within the $HOME folder can be versioned with normal Git commands, replacing git with your newly created dotfiles alias:

dotfiles status
dotfiles add .vimrc
dotfiles commit -m "Add vimrc"
dotfiles add .bashrc
dotfiles commit -m "Add bashrc"
dotfiles push

Install your dotfiles onto a new system

Prior to the installation make certain you have committed the dotfiles alias as in steps 5), 6) and 7).

Then be sure your repository ignores the folder where you'll clone it, so that you don't create weird recursion problems:

echo ".dotfiles" >> .dotfilesignore

Now clone your Dotfiles repository into a bare repository in the .dotfiles dot folder of your $HOME:

git clone --bare --recurse-submodules <git-repo-url> $HOME/.dotfiles

Define the alias in the current shell scope:

alias dotfiles='/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME'

Checkout the actual content from the bare repository to your $HOME:

dotfiles checkout master

The step above might fail with a message like this:

error: The following untracked working tree files would be overwritten by checkout:
    .zshrc

Please move or remove them before you can switch branches.

Aborting

This is because your $HOME folder might already have some stock configuration files which would be overwritten by Git (like .zshrc in my case). The solution is simple: back up the files if you care about them, remove them if you don't care. Nicola provided us with a possible rough shortcut to move all the offending files automatically to a backup folder:

mkdir -p .dotfiles-backup && \
dotfiles checkout 2>&1 | egrep "\s+\." | awk {'print $1'} | \
xargs -I{} mv {} .dotfiles-backup/{}

Re-run the check out if you had problems:

dotfiles checkout master

Set the flag showUntrackedFiles to no on this specific (local) repository:

dotfiles config --local status.showUntrackedFiles no

Set the flag core.excludesFile to .dotfilesignore on this specific (local) repository:

dotfiles config --local core.excludesFile=.dotfilesignore

Now you have two options: create a new branch for the brand new machine you are installing, or checkout an existing branch and use it.

Create a new branch

dotfiles checkout -b <my-new-machine-branch-name>

At this point you can start customizing your dotfiles and the commit them to this new branch. You can also diff your files form other branches and cherry-pick stuff you like form other branches.

Checkout an existing branch

In the previous steps we checked out master branch, that in my personal dotfiles repo contains only shared file and configurations I like to have on all my machines (my machines are not all 100% equal).
But you can commit all the dotfiles you like in master branch and always use it, or checkout an existing (other machine) into the new one if you like: simply switch branch like this:

dotfiles checkout <existing-machine-branch-name>

Of course, you will have some conflicts like we mentioned before: handle them with the provided script or delete current dotfiles you planned to override.

Summary

You're done, from now on you can now type dotfiles or dfg commands to add and update your dotfiles:

dotfiles status
dotfiles add .vimrc
dotfiles commit -m "Add vimrc"
dotfiles add .bashrc
dotfiles commit -m "Add bashrc"
dotfiles push

Install script

As a shortcut not to have to remember all these steps on any new machine you want to setup, you can create a simple script like this:

git clone --bare <url-of-your-repo> $HOME/.dotfiles
function dotfiles {
   /usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME $@
}
mkdir -p .dotfiles-backup
dotfiles checkout
if [ $? = 0 ]; then
  echo "Checked out dotfiles repository.";
  else
    echo "Backing up pre-existing dot files.";
    dotfiles checkout 2>&1 | egrep "\s+\." | awk {'print $1'} | xargs -I{} mv {} .dotfiles-backup/{}
fi;
dotfiles checkout
dotfiles config --local status.showUntrackedFiles no
dotfiles config --local core.excludesFile=.dotfilesignore

I stored it as a BitBucket snippet, so now I can call it like this:

curl -Lks https://bitbucket.org/snippets/fsantacroce/qedGpx | /bin/bash

Appendixes

Some other things you would know.

Which dotfiles are worth to be versioned?

There's not a unique answer, it depends

These are some of the files I always include:

  • .dotfilesignore, of course
  • Shell config file: .zshrc
  • Aliases file: .zshrc_aliases
  • oh-my-zsh: .oh-my-zsh/ folder
  • my common Git config and aliases: .gitconfig
  • ... to be continued ...

Which dotfiles needs to be ignored?

Yes, there are many cache, temp and machine related files there's no need to include (or that can be dangerous to include), like:

Zsh temp and cache files:

  • .zsh_history
  • .zsh_save

Bash temp and cache files:

  • .bash_history
  • .bash_logout

And others, like these:

  • .config/chromium/*
  • .config/session/*
  • .config/pulse/*
  • .m2/*, Maven repository cache
  • .IntelliJ*/*, IntelliJ settings: I have a repo apart for those :)
  • ... to be continued ...

I add new folders and files every time I discover something useless to track.

About

My dotfiles for consistent behaviour across devices

Topics

Resources

Stars

Watchers

Forks

Languages