Hacker News new | past | comments | ask | show | jobs | submit login
Dotfiles.github.com - A guide to dotfiles on GitHub (dotfiles.github.com)
122 points by netherland on April 23, 2012 | hide | past | favorite | 37 comments



(Obvious) disclaimer: this is a user-hosted subdomain on GitHub. It is not an official GitHub page (even if the logo is two octocats snuggling together).


Which means, of course, it's also a repository if anyone is interested:

https://github.com/dotfiles/dotfiles.github.com/


I've meant to finally put my dotfiles into a repository but the one thing keeping me from it is that I haven't yet stumbled upon a script to symlink everything into it's place that I'm totally satisfied with.

I don't use ruby and don't want to install rake on each machine for something that should be possible with a simple shell script, and didn't like the scripts I saw so far. Everything had a medium or large aspect that kept me from using it.

Maybe I just need to write my own thing.


I highly recommend not symlinking things at all; just have the repository itself as your home directory.

Whenever I set up a new machine, I always do this:

    git clone git://joshtriplett.org/git/home
    mv home/.git .
    rm -rf home
    git checkout -f
(There probably exists a simpler way to do that, but I haven't found it yet.)

I can always check out my repository via git:// even on a machine where I want to push to it, because my repository includes a ~/.gitconfig containing:

    [url "ssh://joshtriplett.org/"]
            pushInsteadOf = "git://joshtriplett.org/"
So, I can automatically push as long as I have SSH access to my server. (I wrote the support for pushInsteadOf in upstream git, specifically to enable this use case.)


I don't know if it's any simpler, but I tend to do:

    git init .
    git remote add origin git://github.com/eentzel/dotfiles.git
    git checkout -t origin master


Your script can be pretty simple. E.G. Create symlinks when they don't exist and report errors if creating them would clobber something else:

    DOTFILES=$HOME/where/the/dotfiles/live/in/git
    for T in $DOTFILES/*; do
        TARGET=$(readlink -e $T)
        LINK_NAME=$($HOME/.$(basename $TARGET))
        # test if a file, working symlink, or broken symlink already exists
        if [ -e $LINK_NAME -o -L $LING_NAME ]; then
            CURRENT_TARGET=$(readlink -m $LINK_NAME)
            if [ $CURRENT_TARGET != $TARGET ]; then
                    echo "$LINK_NAME already exists and is really $CURRENT_TARGET"
            fi
        fi
        ln -s $TARGET $LINK_NAME
    done
Remove stale dotfile symlinks:

    for L in $(find $HOME -maxdepth 1 -type l -name '.*'); do
        if [ ! -e $L ]; then rm $L; fi
    done
This assumes you'll use git excludes to keep files you don't want out of your repository. E.G. if you don't want $HOME/.ssh/id_rsa in git then you'd have $DOTFILES/ssh/.gitignore with 'id_rsa' in it. If you try to manage your excludes through the linking you'll end up with a very ugly script like what I have at https://github.com/sciurus/dotfile_management


I would recommend it. I'm not fully happy yet with my setup, but it's all in bash, and fairly simple really. Plus, when you do it yourself you will understand everything you do, and be less likely to screw up something you didn't actually want changed.


I've been using justone's dfm (dotfile manager) script[1]. The only requirement is PERL 5.8, which is just about everywhere, I think. Seems good enough so far, but I'm not sure how I'll integrate Oh-My-Zsh 2.0[2] yet. Maybe someone can compare it to homesick or do a PERL port...

[1] https://github.com/justone/dotfiles [2] https://github.com/sorin-ionescu/oh-my-zsh


I just use a bash script that I add a line to symlink each config to the correct location. I really like this as I know exactly what's happening.


I use the dircombine perl script that has been used by Joey Hess since his first SVN home directory article was written. You can also look at the fixups scripts that uses dircombine to setup everything. It's simple and to the point.

http://git.kitenet.net/?p=joey/home.git;a=blob_plain;f=bin/d...


I use homesick (which is written in Ruby) and I think I agree with you. I like the premise of having the repo in a subdirectory and symlinking the files in - I don't like to have the whole homedir in git - I only want certain things in the repo in the first place, not everything. Seems like the rest could be done in a shell script for maximum portability.


With respect, a guide to dotfiles should explain what dotfiles are.


If someone needs to ask what dotfiles are, they aren't in the target audience of this project.


I have to disagree - I had never heard the term before, but now that I see the power/convenience of a symlinked configuration, I'm interested in learning more.

I'm sure many others like myself would appreciate a more thorough, introductory walkthrough. I'll be asking my more hard-core friends for guidance in the meantime.


I highly recommend using symlinks to synchronize dotfiles with a locally cloned repo. That way, you can make changes to the dotfiles sitting in your home directory and it'll be reflected in your repo should you want to commit those changes.


I just track ~/ directly and add appropriate .gitignore entries to those files which are ephemeral or not part of my local configuration:

https://github.com/uggedal/dotfiles/blob/master/.gitignore


Wait, I've done it the other way around. I have a repo directory, and I created symlinks in ~/ pointing to the dotfiles in the repo. I have a simple install script to symlink the files.

Would you suggest having the physical files in ~/ and adding their symlinks to a repo?


I would think he meant what you said.... symlinks in the repo doesn't sound a good idea.


While we're on the subject - has anyone found a good way to separate environments while keeping your setup fairly DRY? e.g. I have slight variations in my aliases for work/home, different git config email etc.

You can find mine here: http://github.com/adamgibbins/dotfiles


Towards that end, (and for keeping certain sensitive things from repos...) I made this:

https://github.com/sophacles/dotfuse

It is a fuse filesystem that allows for modularization of some "single file" style dotfiles. Combined with git branche or modules (or both) it can get a lot of this (i hope). Warning though, it is still a bit of a toy, and I haven't played with it for a while, but I'm open to suggestions and pull requests!

As for dry with sourceable stuff, like bash/zsh configs, you can just keep the environment specific stuff in a separate repo, and use git modules, that is if your environ specific stuff needs to be confidential (or some of it) and kept in separate private repos.


this is clever, thanks for sharing


I see you have a zshrc.local; that's the same approach I use. Unfortunately not everything supports "includes" but many, many things do.

If you want to see more, https://github.com/apinstein/dotfiles

I suppose another alternative might be having a private ".local" repo as a submodule, and having a rake task to concatenate and install the shared & local files. It is a tricky problem.


My zshrc.local setup is rather poor and I need to find time to sort it out correctly - currently its effectively a clone of the standard grml setup (http://grml.org/zsh/).


I haven't done this yet, but I'm guessing you could just branch off of master, and create a "home" or "work" branch.

To me that might be better than using setup scripts for the various environments, and keeping it all in one branch (like I've seen other people do).

I'd prefer to see the differences by doing things like:

    git diff master work
or

    git diff home work
etc


You should take a look at http://vcs-home.branchable.com/ They have a mailing list and a bunch of resources to do similar things.

Right now I use movein[1] to maintain my dot files. Each dotfile is held in it's own repo which is checked out to $HOME via GIT_DIR and GIT_WORK_TREE environment variables. The mr[2] command ties the git repos together as it if was one repo. I use additional repos or branches to handle variations within dotfiles. For work, I try to keep things confined to the relevent directory eg. using local.vimrc[3]

[1] http://stew.vireo.org/movein [2] http://kitenet.net/~joey/code/mr/ [3] https://github.com/embear/vim-localvimrc


Here's my solution: https://bitbucket.org/davidn/dotstuff

Briefly: ~/dotstuff is a hg/git/whatever repo that contains your dotfiles, which can optionally use simple preprocessor directives to turn on or off different sections on different systems, or contain macro substitutions. You run 'dot' and it shows you a diff between what's in the repo and what's in your filesystem. Then run 'dot -g' to make the changes (with optional backups). Also manages crontabs.

I wrote it about four years ago and have been using it happily since then to manage dotfiles on 2-4 different systems. (I wrote the README today before posting this, which is why it has today's date.)


I have a "~/.hostclass" file on all systems, created manually, which contains some string identifying which confiv variant to use on that machine. EG, "home", "work".

Then, my config files are "make"'d by concatting three files: cat "$1.first" "$1.`cat ~/.hostclass`" "$1.end" > ~/.$1

This lets me split out specific parts into a hostclass-specific file.

Generally, I set variables in these files that gets used in the $1.end file.

It works pretty well for me, since my hosts are generally pretty close to each other.


I haven't done it yet, but I've been meaning to set up a very simple solution to this using a preprocessor (probably m4). I think wrapping a few blocks in if-statements based on the host name will go pretty far.

edit: might as well link my repo, which doesn't yet include that functionality: https://github.com/drewfrank/dotfiles


I've got a preprocessor (ruby) in my zsh dotfiles:

https://github.com/halostatue/dotfiles

I've been slowly moving toward a 'detect-and-configure' plug-in system that I'm quite happy with.


I found vcsh to be very effective. Files live directly in $HOME but the .git repository is in a special directory.

https://github.com/RichiH/vcsh


I use something relatively similar, but I do it with Chef.

(shameless plug) Kindness: A nice way to bootstrap your box (with chef) http://joshtoft.com/kindness/

It takes advantage of site-cookbooks with Chef, letting you bring in your own site-cookbooks and also takes your chef-solo.json (if it exists).

I made it to get away from the rake dotfile sillyness.


A workaround to the "symlink farm" method is making use of "--config=PATH" options for most apps and setting up aliases.

Conforming to the XDG base dir standard as much as possible makes sense but can get painful sometimes (e.g. vim: http://tlvince.com/2011/02/03/vim-respect-xdg/).


@github - Please make a font a bit darker.


It's a user page, so not by github


A Rakefile for dotfiles? Seriously?


Why not? I've been using it without any problems. It's just easier to manage.


Because not everyone has a Ruby development environment available. It would be a lot better idea to stick with Makefiles or other more commonly available Unix tools.

A lot of Ruby people seem to add a Rakefile or a Ruby script to do some simple task like installing a few dotfiles. That makes them a lot less useful to me (for example), as I don't have a Ruby env available on all machines I use.

Same goes for Node.js, Python and Perl people. If a "standard unix" tool can do something almost as easily as a Rakefile/whatever, you should probably stick to the standard tools. I don't know what you should do with Windows, though.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: