This might be useful if you keep your settings (.bashrc, .subversion/config, etc.) outside the home directory, like in a Subversion repository. Just copy the following script to the repository directory corresponding to $HOME and run
/path/to/make-links.sh
to create symlinks from ~ to each file in the repository, recursively.

If you don't want to use meld to see differences, just change the diff variable near the top of the code.

Edit 2: Now actually does something useful if the target file already exists or the target directory does not exist.

make-links.sh

 #!/bin/sh # # $Id: make-links.sh 1870 2009-11-10 08:56:35Z
vengmark $ # # NAME # make-links.sh - Make symlinks to all user settings in
repository # # SYNOPSIS # make-links.sh [options] # # OPTIONS # -v,--verbose
Verbose output # -d Specify the source and target directories for the symlinks #
# EXAMPLE # /path/to/make-links.sh -d ~/settings/user ~ # # Create links in the
home directory based on files in ~/settings/user # # /path/to/make-links.sh -v #
# Create links in / based on files in the directory of make-links.sh # #
DESCRIPTION # If the file in the source directory doesn't exist in the target
directory, # a symlink is created directly. # If the file exists, or the target
directory does not exist, the user is # given options to continue. # # BUGS #
Email bugs to victor dot engmark at gmail dot com. Please include the # output
of running this script in verbose mode (-v). # # COPYRIGHT AND LICENSE #
Copyright (C) 2008-2009 Victor Engmark # # This program is free software: you
can redistribute it and/or modify # it under the terms of the GNU General Public
License as published by # the Free Software Foundation, either version 3 of the
License, or # (at your option) any later version. # # This program is
distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY;
without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the # GNU General Public License for more details. # #
You should have received a copy of the GNU General Public License # along with
this program. If not, see <http://www.gnu.org/licenses/>. #
################################################################################
# Output error message with optional error code error() { if [ -z "$2" ] then
error_code=$EX_UNKNOWN else error_code=$2 fi echo "$1" >&2 exit $error_code }
usage() { error "Usage: ${cmdname} [-v|--verbose] [-d source target]" $EX_USAGE
} verbose_echo() { if [ $verbose ] then echo "$*" fi } # Use for mandatory
directory checks # $1 is the directory path # $2 is the (optional) error message
directory_exists() { if [ ! -d $1 ] then error "No such directory '${1}' $2"
$EX_NO_SUCH_DIR fi } # Make sure an executable is available # $1 is the path to
the executable # $2 is the (optional) error message executable_exists() { if [ !
-x $1 ] then error "No such executable '${1}' $2" $EX_NO_SUCH_EXEC fi }
ifs_original="$IFS" # Reset when done IFS=" " # Make sure paths with spaces
don't make any trouble when looping PATH="/usr/bin:/bin" cmdname=`basename $0`
directory=$(dirname $(readlink -f $0)) diff=/usr/bin/meld
source_base="${directory}/home/$(whoami)/" target_base="$HOME" # Exit codes from
/usr/include/sysexits.h, as recommended by #
http://www.faqs.org/docs/abs/HTML/exitcodes.html EX_OK=0 # successful
termination EX_USAGE=64 # command line usage error EX_DATAERR=65 # data format
error EX_NOINPUT=66 # cannot open input EX_NOUSER=67 # addressee unknown
EX_NOHOST=68 # host name unknown EX_UNAVAILABLE=69 # service unavailable
EX_SOFTWARE=70 # internal software error EX_OSERR=71 # system error (e.g., can't
fork) EX_OSFILE=72 # critical OS file missing EX_CANTCREAT=73 # can't create
(user) output file EX_IOERR=74 # input/output error EX_TEMPFAIL=75 # temp
failure; user is invited to retry EX_PROTOCOL=76 # remote error in protocol
EX_NOPERM=77 # permission denied EX_CONFIG=78 # configuration error # Custom
errors EX_UNKNOWN=1 EX_NO_SUCH_DIR=91 EX_NO_SUCH_EXEC=92 # Process parameters
until [ $# -eq 0 ] do case $1 in -v|--verbose) verbose=1 shift ;; -d) if [ -z
"$2" ] || [ -z "$3" ] then usage_error fi source_base=$2 target_base=$3 shift 3
;; *) # Unknown parameter usage ;; esac done verbose_echo "Running $cmdname at
`date`." # Make sure the directory paths don't end with a slash
source_base="${source_base%\/}" target_base="${target_base%\/}" # Preliminary
checks directory_exists "$source_base" directory_exists "$target_base"
verbose_echo "Source directory: '${source_base}'" verbose_echo "Target
directory: '${target_base}'" # Find files excluding .svn directories for
source_path in `find "$source_base" -mindepth 1 -type f | grep -v "/.svn/"` do
target_path="${target_base}${source_path#${source_base}}" target_dir="$(dirname
"${target_path}")" unset replace_file unset create_dir verbose_echo ""
verbose_echo "Source file: \"${source_path}\"." verbose_echo "Target file:
\"${target_path}\"." # Trivial case if [ -L "$target_path" ] then verbose_echo
"\"${target_path}\" is already a symlink; skipping." continue fi # File exists
if [ -f "$target_path" ] then # Make sure we skip or replace in the end while !
expr "$replace_file" : "^[SsRr]$" > /dev/null do echo "\"${target_path}\" is a
proper file. What do you want to do?" read -p "[S]kip, [D]iff, [R]eplace: "
replace_file if expr "$replace_file" : "^[Dd]$" > /dev/null then verbose_echo
"Diffing \"${source_path}\" and \"${target_path}\"" $diff "$source_path"
"$target_path" fi done if expr "$replace_file" : "^[Rr]$" then verbose_echo
"Removing ${target_path}" rm "$target_path" else continue fi fi # Not a proper
file if [ -e "$target_path" ] then echo "\"${target_path}\" exists but is not a
file; skipping." continue fi # Directory missing; might have to create it if [ !
-e "$target_dir" ] then while ! expr "$create_dir" : "^[SsCc]$" > /dev/null do
echo "\"${target_dir}\" doesn't exist. What do you want to do?" read -p "[S]kip
or [C]reate: " create_dir done if expr "$create_dir" : "^[Cc]$" > /dev/null then
mkdir -p "$target_dir" else continue fi fi echo "Creating symlink at
\"${target_path}\"." ln -s "$source_path" "$target_path" done verbose_echo
"Cleaning up." IFS="$ifs_original" verbose_echo "${cmdname} completed at
`date`." exit $EX_OK