Manage dotfiles with git
       ========================================================================
       
       I'm managing my dotfiles with git. My method serves me well for a few
       years already and so I think it's time to write it down.
       
       If you think git, you might think of a dotfile repository and dozens of
       symlinks into the home directory. This is precisely what kept me from
       using git until I discovered bare repositories.
       
       Create your dotfile repository with the --bare parameter
       
           $ git init --bare $HOME/.cfg
       
       This creates only a folder for git control files, which normally reside
       inside the .git folder within the repository.
       
       You can now tell git to use $HOME as your work-tree directory. This
       makes git handle your home directory like all the files would be within
       the git repository. Now you can:
       
           $ git --git-dir=$HOME/.cfg/ --work-tree=$HOME add .vimrc
           $ git --git-dir=$HOME/.cfg/ --work-tree=$HOME commit -m "my .vimrc"
       
       If course it is silly to type out such a long command every time you
       want to interract with your dotfiles. So why not create an alias?
       
           $ alias config='git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
       
       Put this in your .bashrc or .kshrc and you can now use the command
       "config" in the same way you usually use git.
       
           $ config add .vimrc
           $ config commit -m "my vimrc"
       
       Maybe you were brave and typed "config status" already. This will list
       the content of your whole home directory as "untracked files". This is
       not what we want. We can run "git config" and tell it to stop doing
       this. But of course we must run our git, which is called "config".
       
           $ config config --local status.showUntrackedFiles no
       
       Now git status will only check what's being tracked. So if you add your
       vimrc file and later change it, "config status" will show it, "config
       diff" will diff it...
       
       You can now use the power of git with your new "config" command.
       
       The solution is not perfect, so I'm using a few workarounds.
       
       1. Passwords
           Try to keep your passwords out of your dotfiles. In many
           cases, this can be done with gpg (or password-store
           https://www.passwordstore.org).
       Examples:
       
           - .msmtprc:
               passwordeval "gpg2 -d $HOME/.msmtp-pw.gpg"
           - .offlineimaprc:
               pythonfile=~/.offlineimap.py
               remotepasseval=get_pass("mail","user","993")
           - .muttrc:
               source "gpg2 -d $HOME/.mutt-pw.gpg |"
       
           Actually, I use "password store" and prefer to use it to retrieve
           passwords. In mutt this would be something like:
               source "pass Accouts/private-mutt |"
       
           Another method I use is that I keep the origin of some files gpg
           encrypted. For example my .ssh/config file, as I don't want to leak
           hostnames user and ports.
       
           My vim has the vim-gpg plugin loaded and can therefore edit .gpg
           files directoy (decrypt, edit, encrypt). So I create a simple shell
           alias for convenience:
       
           $ sshconfig() {
           $   vim ~/.ssh/config.gpg && \
           $   gpg2 -qd ~/.ssh/config.gpg > ~/.ssh/config
           $ }
         
           With this I run "sshconfig", update my file, save, done.
           of course I added only config.gpg to my git. On a new
           system I have to run sshconfig once to create the config file.
       
       2. Stuff outside $HOME
           I wanted to add a few files that reside in /etc. Here I took the
           lazy route and created $HOME/.etc and copied the files there. On a
           new machine I have the files, but need to copy them manually. Works
           fine for me.
       
       3. Host specific files
           I try to keep my dotfiles compatible to all computers I use. But
           sometimes this is not possible and there are a few methods to battle
           this.
       
           If your configuration allows code evaluation, you may do something
           like ". myconfig.$(hostname -s)" and just check in individual files
           per host.
       
           If this does not work or you have a file that needs to have a
           password in it, you could copy the file, remove the password and
           check it in as template or sample file.
       
       The methods above served me very well over the past years and I'm not
       seeing why I would want to change it. It's easy and simple and I don't
       need to remember anything beside a few git commands.
       
       Well okay, because I'm lazy and don't want to think about git commit
       messages, I'm using this to push my changes:
       
           $ dotfiles_autoupdate() {
           $     MSG="Update $(date +"%Y-%m-%d %H:%M") $(uname -s)/$(uname -m)"
           $     config add -u && \
           $     config commit -m "$MSG" && \
           $     config push
           $ }
       
       This command takes all changed files and commits them with the date and
       some machine information. Not creative, but I don't care. YMMV.
       
       # Changelog:
       # * 2019-04-27: Created
       # * 2019-04-28: Added password evaluation examples
       # * 2020-05-17: Added password-store and sshconfig examples