[Guide] How I git my dotfiles - GNU/Linux

Users browsing this thread: 3 Guest(s)
crshd
Registered
Another guide brought to you courtesy of [crshd.github.io](http://crshd.github.io/2013/09/05/How_I_..._dotfiles/)

---

Dotfiles are every developer's and geek's pride and joy. Hours of work have been spent on them, and most important of all, they are constantly evolving. If you are like me, hardly a day goes by where you don't add a cool new piece of functionality that you just came up with, or found by looking through somebody else's configs.

Now, having a byte-tuned system is great for workflow. But unfortunately, there are some side effects. If you lose your files, you are seriously crippled. Moving to a new system involves a lot of searching for files, copying and pasting them from one computer to another. And you're likely to be constantly bombarded with questions about how you did what.

## The Solution

One possible solution to these problems: every developer's best friend, Github!

Config files are all backed up, even if all of your hardware falls victim to a kraken, you'll still be able to clone your repository from Github once you have aquired new electron pushers. Moving to a new system is easy, just clone the repository, and you are good to go. And best of all, you can show off in front of your friends! The next time somebody asks you for some config file, just give them the link to the repository. No more uploading single files on some random pastebin, forgetting the link, uploading again, loosing track of what where and when, and having people find old, possibly broken, versions and yelling at you. What a relief...

## How I did it. AKA: the strategy

Have I convinced you yet? Great, read on.

If you want to post your configuration files on the Hub, there are some things to keep in mind:

- **Location**
Unfortunately, developers still have not managed to decide on a single location to keep configuration files. Most of them are still dumped into hidden directories in your $HOME, some actually obey $XDG_CONFIG_DIR (which defaults to ~/.config), and other only act like they do, but their location is hardcoded to ~/.config, instead of reading the environment variable.
- **Passwords**
If you are putting your configuration files online for the world to see, you should **really** make sure to remove all your passwords, api keys and other sensitive data before pushing it to github. Ideally, they should be encrypted and stored somewhere else, but sometimes you just cannot get around saving them as plaintext in some file somewhere.
- **Clutter**
Please, for the love of God, make sure you keep your files organized. No useless files in your repo!

Below I will show you how I got around these things.

## Location

So, you want to git your configs, but they are scattered all over the place. You can't just stuff your entire $HOME into a repository - this is not going to work out. I like to keep files organized anyways, so this was the perfect excuse for me to go all OCD on my file system.

### XDG Base Directory Specification

freedesktop.org came up with a beautiful solution to this mess: the [XDG Base Directory Specification](http://standards.freedesktop.org/basedir...atest.html). Every piece of software that follows this specification will put it's config file wherever the environment variable $XDG_CONFIG_HOME points to. I've set mine to ~/etc (because /etc), but it's really up to you. So make sure to set it in your shell configuration. And put that shell config in $XDG_CONFIG_HOME. Configception.

### Command Line Flags

Unfortunately, a lot of software still does not follow the specifications, in which case you'll have to do some manual work. Luckily, _most_ software allows you to specify an alternative configuration file via command-line options, or sometimes even environment variables. So go RTFM and modify your shell rc accordingly (just set aliases).

### Symlinks

Some (very few, though) programs do not allow you to change the location of their configuration file. At least not without modifying the source (I'm looking at you, Emacs and Xmonad). In this case, you have three options: patch the source and recompile, bug the developers, or use symlinks. While it clutters my $HOME again, I decided to go for the latter solution. I do have subdirectories for both Emacs and Xmonad in my ~/etc, which I just symlinked to ~/.emacs.d and ~/.xmonad respectively.

## Sensitive Data

So yeah, them passwords. Again, I have three different methods how you can avoid giving people the account details of your online banking account.

### Git Filters

Git has filters that can be applied to your code before it gets commited. [Marc-Antoine Perennou did a nice write-up about this](http://www.imagination-land.org/posts/20...h-git.html), so I'm not going to go into too much detail here, but you can clean your passwords with

Code:
$ git config filter.password.clean "sed -e 's/mypassword/@PASSWORD@/' -e 's/anotherpassword/@PASSWORD2@/'"
$ git config filter.password.smudge "sed -e 's/@PASSWORD@/mypassword/' -e 's/@PASSWORD2@/anotherpassword/'"
$ cat > .git/info/attributes << EOF
myconf.conf filter=password
EOF

This is obviously a very simple example, and will only work if you use the same password everywhere. So you'd need to add a filter for every different password you use. But since it's just calling sed, you have the possibility to go completely crazy with regexes, if you're one of those people.

### .gitignore

Another possibitly would be to use .gitignore, and ignore all the files that contain sensitive data. For example, I'm ignoring ~/etc/fb-client/apikey, which basically contains nothing more than my API key for [paste.xinu.at](http://paste.xinu.at). Not much more to say about that.

### External Files

Depending on the type of configuration, you might be able to read your passwords from an external file, which you could keep outside your repo. Or which is .gitignored. Since the methods differ for each application, there's no example here. Go cry about it.

## Clutter

There's really not a lot to write about this. Please make sure you keep your stuff organized. Everything in its subdirectory, don't include useless files, like auto-generated stuff or editor backups. Just double-check everything before calling git add on it, and set your ignores accordingly.

-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCA/IT d-(---)@ s+: a-- C+++(++++)$ UBL*+++ P+++>++++ L++ E W+++$ !N !o K !w !O M+>++ !V PS+++ PE !Y PGP+ !t-- !5 !X R@ tv- b+ DI D+ G e h r++ y+
------END GEEK CODE BLOCK------

shtols
Long time nixers
Sidenote for beginners: A common 'mistake' is to clone your repository via HTTPS, when trying to push your changes later it will ask for a password rather than the public key (you've hopefully set up). The simplest method to change this is:
Code:
git remote set-url origin git@github.com:username/repo.git

@NeoTerra: Pro Git is a pretty cool book, just in case you'd like a good git-related read.
Hans Hackett
Members
"Wow" nothing more. This is the first time I know that the git provide a filter feature.
z3bra
Grey Hair Nixers
That's a great tutorial!

If I can help, here is a script from my ~/etc/ It will list all the files in its directory, dump them in a file on /tmp/, ask you to edit the file, and create a symlink for each file.

~/etc/copy.sh :
Code:
#!/bin/sh

TMPFILE=/tmp/dotfiles.list

OK="[$(tput setaf 3)OK$(tput sgr0)]"
NOPE="[$(tput setaf 1)FAIL$(tput sgr0)]"

cat <<EOF > $TMPFILE
##
## Here is an auto-generated file for linking
## config file to your $home directory
##
## The $0 script will read filenames from that
## file in order to create ONLY the links you
## want.
##
## The following list lists every. single. file
## or directory. Just remove the line that you
## don't want to be linked.
## Then, save that file, and watch the magic happen...
##
EOF

echo "listing the whole directory"
ls $PWD >> $TMPFILE

$EDITOR $TMPFILE

echo "simulating..."
for f in $(grep -v '^#' $TMPFILE); do
  echo "$f -> ~/.$f"
done

echo "attempting to link config file to ~ ..."
read -p "Hit <Enter> to continue, <Ctrl-C> to abort..."
for f in $(grep -v '^#' $TMPFILE); do
  ln -s $PWD/$f ~/.$f
  if [ -L ~/.$f ] ; then
    echo "$OK   -> $f"
  else
    echo "$NOPE -> $f"
  fi
done

echo "removing temporary files"
rm $TMPFILE

echo "finished."

File list comment/delete de files you dont want to see)
Code:
##
## Here is an auto-generated file for linking
## config file to your  directory
##
## The ./copy.sh script will read filenames from that
## file in order to create ONLY the links you
## want.
##
## The following list lists every. single. file
## or directory. Just remove the line that you
## don't want to be linked.
## Then, save that file, and watch the magic happen...
##
bashrc
#copy.sh
cwmrc
elinks
#evilwmrc
#irssi
mutt
#ncmpcpp
#openbox
#ratpoisonrc
#rtorrent.rc
#screenrc
#tint2
tmux.conf
vim
vimrc
xbindkeysrc
xinitrc
Xresources
#zshrc
This will create a symlink for every uncommented line, by appending a '~/.' before the filename (bashrc -> ~/.bashrc).

Once you're done editing the list, it will simulate the linking, so that you can check that it does it the way you want. Presse <Enter> to proceed, <Ctrl-C> to abort. Finally, watch the linking going!

It has saved me a lot of pain seting up new machines :)
BANGARANG, MOTHERFUCKER