views:

1045

answers:

9

I commonly work on multiple computers. I have various configuration files, eg, .bashrc, .gitconfig, .irbrc, .vimrc and configuration folders, eg, .vim/ that contain valuable customizations. Sometimes I want small variations in configuration between the different computers.

I want to use version control to manage these different files.

  • do others use version control to manage their configuration files?
  • what are some hints that might make this easier?
  • what's the most elegant way of dealing with variations between the computers?
  • I'm comfortable with git; any other suggestions?
A: 

git with branches for custom computers, with automated sync at login seems like a good solutions to me.

I've used etckeeper for versioning configurations, but I've never actually expanded to user configurations.

Ben S
+2  A: 

If you use git, you could define an "origin" repo to be the master; and then do a clone on each computer you work. you could use a branch for every computer to have your set of config files.

fablife
+2  A: 

With CfEngine you can manage config files across machines and do also many more things! The learning curve is maybe a bit high but worth it if you have to manage/update/maintain a pool of computers running linux regularly.

jdehaan
+1 for this as well http://en.wikipedia.org/wiki/Cfengine
Phill Pafford
+4  A: 

At the moment, I use a cloned git repo. To keep things simple, the only file that needs to vary between the different machines is .bashrc. It's nice if there can be just one version of this file that responds differently on different machines. Thus, in my .bashrc:

if [ $(hostname) == 'host1' ]; then
     # things to do differently on host1.
elif [ $(hostname) == 'host2' ]; then
     # things to do differently on host2.
fi

This obviously has some limitations (such as that a different technique would be required for .vimrc or other config files needing customization), but it works fairly well.

Peter
A: 

This kind of question comes up occasionally, and I've never seen a tool to handle this common use case, so I wrote a script that uses git and symlinks to manage these files.

See http://github.com/bstpierre/dotfiles

It is not perfect. There is currently a bug related to handling directories, and there is no support yet for variations across computers.

Before using any tool of this nature, make sure you have good backups!

bstpierre
please explain in comments when you downvote
+3  A: 

I keep a folder at ~/config/ which is a bzr repository. I push/pull the repository between my various computers to sync it up. I have an install script which I use to make symlinks to my home directory:

#! /bin/sh
# link all files to the home directory, asking about overwrites
cd `dirname $0`
SCRIPT_DIR=`pwd`
SCRIPT_NAME=`basename $0`
FILES=`bzr ls --versioned --non-recursive`

cd $HOME
for FILE in $FILES; do
    ln --symbolic --interactive $SCRIPT_DIR/$FILE
done
rm $TARGET_DIR/$SCRIPT_NAME

If you want to use git instead of bzr, you can instead use:

FILES=`git ls-tree --name-only HEAD`

(I had to ask SO to figure that out)

Christian Oudard
+1 pretty much the same thing I do
Xiong Chiamiov
+2  A: 

Easy. Use DropBox for that: http://www.nixtutor.com/linux/sync-config-files-across-multiple-computers-with-dropbox/

FractalizeR
+1. I use Dropbox too. I also move across multiple operating systems, so most of the config files in Dropbox have an extension to denote the OS on which they were created. If both environments are the same, I can link to the same file regardless of the extension. For example, I have a .profile symlink that points to ~/Dropbox/config/bash/profile.osx. On my linux box, it points to ~/Dropbox/config/bash/profile.lin.
Rob Wilkerson
+1  A: 

I use slack for a similar situation. slack allows definition of roles/subroles so you can manage files with small variation either through a cloned file or patch. The slack directory is then managed by git in my deployment.

phsiao
I use slack a lot. It is lightweight and fast and does not get in the wayand. Works very reliable here.
A: 

I think what you want could be similar to what I've been doing...

Make a directory in home called .host_configs/ . This is version controlled. Or in my case it lives in a special folder on a central computer, I scp it down on any new machine. Inside it make a folder for every host that you want different configurations for. The folder for each host should be named after the short hostname for that machine. So in your git repo you have:

.host_configs/
           homecomp1/
           girlfriendcomp1/
           workcomp1/
           workcomp2/

In each host specific folder, put the .vimrc, .irbrc, etc., configuration files for that specific box. And also, in each host folder make a file called .[SHORT_HOST]_rc. For instance, if your machine is name "sane" have a file named .sane_rc ... This file will contain the lines that would normally be in .bashrc that are unique to that host. For instance, if it's a mac and it needs alias ls='ls -GF' instead of alias ls='ls --color=auto' which works for most nix machines for ls with colors, put that line in the .[SHORT_HOST]_rc for that machine, along with whatever special functions, declarations, etc, that would normally go into the .bashrc or .profile etc. (or .zshrc, .tschrc, as the case may be). So the version controlled ~/.host_configs/ folder looks like:

.host_configs/
           homecomp1/
                    .homecomp1_rc        #special shell configs for this hostname
                    .vimrc               #you know the rest
                    .irbrc
                    .Xresources
           girlfriendcomp1/
                    .girlfriendcomp1_rc
                    .vimrc
                    .bubblebathrc
           workcomp1/
                    .workcomp1_rc
                    .bashrc
                    .vimrc
           workcomp2/
                    .workcomp2_rc
                    .bashrc
                    .vimrc

I use all the same barebones $HOME/.bashrc (or ~/.tshrc etc) on all of my machines. I just take the basic one that comes with the distro in question and move all of the host-specific configuration into the .host-configs/[SHORT_HOST]/.[SHORT_HOST]_rc file.

Put this at the bottom (of $HOME/.bashrc):

export SHORT_HOST="sane"
for file in `find ~/.host_configs/$SHORT_HOST -name ".*"`
do
ln -s $file `ls -la $file |awk -F/ '{print $6}'`; #note this requires your .host_configs/ folder to be in your home directory; with this, the filename is the 6th split on '/'
done
source ~/`.$SHORT_HOST`_rc

(Finds all of the dot-files for the host and makes a symlink in home to the~/.host_configs/foo_host folder). Your dot files are in their normal location but they are symlinked to version control. The above also sources all of the lines in your [$SHORT_HOST]_rc file into .bashrc

You can commit back to git from the ~/.host_configs/ folder whenever you have changes.

That's what it looks like in shell, which is probably all you need, but if you need other features, I would write something that uses the same principles (sourcing an external .rc file into .bashrc and symlinking all the config files to the structured version control folder) in something more versatile/less ugly than shell. So instead of the above in your .bashrc, there could be:

export SHORT_HOST="sane"
ruby ~/import_conf.rb $SHORT_HOST

...and write your import_conf.rb to do more complex conf management, like placing a specific configuration file in some directory besides home, or handling a config folder like .ssh/, .subversion/ etc. That's what I do, it's pretty elegant for me, but there may be better solutions. Dropbox with some creative symlinks is also an excellent idea, though you're relying on a third party, and you need to be in a graphical environment. Also note there are inconsistencies between what you can do with symlinks + dropbox in Linux and shortcuts + dropbox in Windows if you implement something that wants to play with Windows.

perrierism