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