39

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?
Peter
  • 127,331
  • 53
  • 180
  • 211
  • 6
    By golly, yes, people most certainly use revision control for config files. I see it especially for window manager config files, but just do a search on GitHub for "config" and see what you get. – Xiong Chiamiov Sep 17 '09 at 21:47

12 Answers12

18

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)

EDIT: I don't actually do this anymore, now I have a dotfiles repo on github, with a nice rake install script that someone else wrote.

Community
  • 1
  • 1
Christian Oudard
  • 48,140
  • 25
  • 66
  • 69
  • Thank you. the dotfiles repo is very helpful! – Shuo May 17 '13 at 00:57
  • What's the benefit of the rake install script versus your old bash script? And is there a difference between you having a bzr repository versus a dotfiles repo on github? It sounds like the same solution except you're just using git vs bzr, and a different install script now? – meder omuraliev Jan 10 '14 at 07:30
  • Like meder, I wonder what the benefits are, I tried your rake script in a fresh user install, and apparently it does not know how to update, only install..? – yPhil Nov 06 '14 at 13:34
15

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
  • 127,331
  • 53
  • 180
  • 211
  • 4
    You can have .bashrc.local file on each machine and you can source that .bashrc.local through common .bashrc file. .bashrc.local will have customization specific to that machine (like color). – vaichidrewar Oct 06 '13 at 02:07
3

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.

transient_loop
  • 5,984
  • 15
  • 58
  • 117
3

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
  • 19,700
  • 6
  • 57
  • 97
  • Or puppet, chef, bcfg2 and [others](http://en.wikipedia.org/wiki/Comparison_of_open_source_configuration_management_software). – Bash Dec 12 '11 at 02:57
2

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

Vladislav Rastrusny
  • 29,378
  • 23
  • 95
  • 156
  • 1
    +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 Sep 21 '09 at 18:16
2

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
  • 1,557
  • 10
  • 7
  • I use slack a lot. It is lightweight and fast and does not get in the wayand. Works very reliable here. – user89021 Jan 02 '10 at 15:56
2

Here are some dotfile managers:

  • homesick: Based on Ruby
  • homeshick: Same as first one, but without ruby dependency
  • dfm: Written in Perl
Khashayar
  • 1,321
  • 10
  • 9
1

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
  • 68,394
  • 30
  • 171
  • 212
1

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
  • 30,042
  • 15
  • 70
  • 103
1

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 `basename $file`
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.

Community
  • 1
  • 1
Purrell
  • 12,461
  • 16
  • 58
  • 70
0

Now there is also vcsh

From the README:

vcsh - manage config files in $HOME via fake bare git repositories

[...]

vcsh allows you to have several git repositories, all maintaining their working trees in $HOME without clobbering each other. That, in turn, means you can have one repository per config set (zsh, vim, ssh, etc), picking and choosing which configs you want to use on which machine.

Works perfectly, but may be a bit daunting if you are not an experienced git user.

sleepyMonad
  • 989
  • 8
  • 13
0

Most of these answer address sync, but not how to tailor the files for the specific device. filetailor is an open-source Python program for this exact issue. Based on a YAML configuration file, it can make small changes to the files using device-specific variables or using device-specific comments in the files. Then, use another program such as Syncthing or Git to transfer the files.

For example, the following line would be commented out on every device except the one with hostname device1.

alias MYHOME='/home/dev1home/' #{filetailor device1}

Disclaimer: I had this same issue and made filetailor to solve it.

Kyle
  • 127
  • 1
  • 9