Hacker News new | ask | show | jobs
by ah- 5164 days ago
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.

7 comments

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 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 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 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.