
Using GNU Stow to manage your dotfiles - dpeck
http://brandon.invergo.net/news/2012-05-26-using-gnu-stow-to-manage-your-dotfiles.html
======
e40
_but many /most dotfiles reside at the top-level of your home directory, where
it wouldn't be a good idea to initialize a VCS repository_

I totally disagree. I love having much of my home directory in git. I have a
.gitiignore for the stuff I don't want in there, but the rest. Ahhhhh, so nice
to be able to clone somewhere else and use.

~~~
cespare
I also keep my whole homedir in git, and it's great. My approach isn't to
.gitignore, because I want to ignore almost everything -- I just add and
commit things when I want to track them. One of my many git aliases[1] is 'git
sn' for showing status without untracked files; this helps when dealing with
my homedir:

    
    
      status --short --branch --untracked=no
    

[1]
[https://github.com/cespare/dotfiles/blob/master/.gitconfig#L...](https://github.com/cespare/dotfiles/blob/master/.gitconfig#L14)

~~~
oops
I have my homedir in git too and also ignore just about everything. I ended up
using gitignore as a whitelist instead of a blacklist, e.g.:

    
    
        /*
        !/.gitignore
        !/.gitmodules
        !/.gitconfig
        !/.zshrc
        !/.zshenv
        !/.zsh
        !/.tmux.conf
        !/.vimrc
        !/.vim

~~~
dgellow
I have a close setup. It just needs a little trick to add subdirectories :

    
    
      /*
      !/.emacs
      !/.emacs.d/
      /.emacs.d/*
      !/.emacs.d/themes/
      !/.emacs.d/functions/
    

You can check my .gitignore here [0].

[0]
[https://raw.github.com/dgellow/home/master/.gitignore](https://raw.github.com/dgellow/home/master/.gitignore)

------
akkartik
I'm very proud of my server's top-level[1] for the past fifteen years:

    
    
      $ ls -A
      .gitconfig@  .hushlogin  .local/  .notes/  .ssh/  www@  .zshrc@
    

All other dotfiles are configured to be picked up from somewhere inside .local
either using environment variables or aliases.

[1] On the other hand, the laptop -- where I run X and gnome -- is a disaster.

------
dnr
If I may, a small plug for my solution to this problem:

[https://bitbucket.org/davidn/dotstuff](https://bitbucket.org/davidn/dotstuff)

I settled on copying rather than symlinking, which has the benefit that the
source files can be passed through a simple preprocessor to do some
customization for different systems. Also you can get a diff between your
current files and the state that you just synced.

------
philips
The primary complaint of the article is tools that manage the files in git and
symlink things into place have lots of dependencies.

ghar, a project I wrote, is a single standalone python file:
[https://github.com/philips/ghar](https://github.com/philips/ghar)

~~~
Arelius
Python is still a pretty large dependency in itself.

~~~
keeblus
Not really. I've yet to see a distro in the past 10 years without it.

~~~
taylorlapeyre
Arch Linux, for one.

~~~
Arelius
Also Mac, Windows.

~~~
navs
OS X has python preinstalled. Not bleeding edge though.

------
staticshock
I use a similar method, but structured around a single Makefile:
[https://github.com/staticshock/seashell](https://github.com/staticshock/seashell)

This lets me perform any necessary initialization (e.g. cloning submodules)
via `make` and installing the actual symlinks into $HOME via `make install`.

------
rsaarelm
I use the homegit alias trick to manage my top level home directory stuff in a
Git repo that doesn't reside at ~/:
[http://chneukirchen.org/blog/archive/2013/01/a-grab-bag-
of-g...](http://chneukirchen.org/blog/archive/2013/01/a-grab-bag-of-git-
tricks.html)

------
nandhp
I would really like to have a dotfile strategy. But I have another goal beyond
synchronization: I would like to be able to organize my dotfiles in a modular
fashion.

For example, I would like to construct my bashrc using something like run-
parts. This system would take bash/★.bashrc, this-machine/local-env.bashrc,
and special-app/proxy-env.bashrc and compile them into a single ~/.bashrc. I
would also like to be able to build a ~/.nanorc that only includes features
supported by the installed version of nano. Some dotfiles include both public
and private data -- I'd like to publish my git aliases, but not my GitHub
authentication token.

So I basically want a dotfile manager that's a combination of PHP, run-parts,
and stow: dotfiles constructed through in-line Perl code (in my nanorc or
ssh_config) with assembly of multiple pieces (in my bashrc or gitconfig) and
installed into the right place in my home directory.

As far as I can tell there's nothing out there that can do this. (Although I
also insist it be written in something classic that I can find anywhere, like
Python 2.4 or Perl or something like that. So I didn't look at any of the many
dotfile managers written in Ruby or Node.)

    
    
        <? @NANO_VER = `nano -V` =~ m/version (\d+)\.(\d+)/ ?>
        set const
        set cut
        <? if ( $NANO_VER[0] > 2 || $NANO_VER[1] >= 1 ) { # Assume nano 1.x isn't still an issue
        ?>
        bind M-f nextword main
        bind M-b prevword main
        <? }
        print "include \"$_\"\n" foreach </usr/share/nano/*.nanorc>;
        # Maybe I'll have to write this myself....
        ?>

~~~
dnr
Hi,

My dotstuff script can do most of that, with a little bit of work. With the
current features, you'd put all your bashrc content into a single
~/dotstuff/bashrc file, marked off with preprocessor directives that turned on
and off certain sections depending on the content of the "environment" (a
simple key-value file).

Adding the ability to query the version of installed software would be easy to
add. Adding the ability to concatenate multiple files would be fairly easy
too. Although I think an "include" directive might make more sense than run-
parts style, since many dotfiles have hierarchical structure.

It's written in 2.4-compatible Python and I'm happy to accept contributions.

[https://bitbucket.org/davidn/dotstuff](https://bitbucket.org/davidn/dotstuff)

------
platz
also see GitMinutes #13: Richard Hartmann on Managing Your Homedir with vcsh:

[http://episodes.gitminutes.com/2013/06/gitminutes-13-richard...](http://episodes.gitminutes.com/2013/06/gitminutes-13-richard-
hartmann-on.html)

[https://github.com/RichiH/vcsh](https://github.com/RichiH/vcsh)

------
Toenex
I've taken a different approach and store all my dotfiles on Dropbox and then
symlinked them the local system. I get synchronisation between machine almost
instantaneously and can move between around half a dozen boxes Including
Linux, OSX and cygwin with little problem. Dropbox provide some version
control which is useful If I really break something and I have a single script
which can bootstrap a new machine. A few things don't liked to be symlinked
(namely ssh keys) but other than that this had worked great for several years.

------
jhh
I wasn't clear to me from the article alone how GNU Stow decides where to put
the files. Looking it up in the manfile stow uses the parent directory of the
"stow directory" by default.

You can change this behaviour using the --target and --dir options, where
setting --dir will set the target dir to the parent of what you set for --dir.

I don't think it's possible to configure a target in the package itself, as
far as I can see from reading the man page.

------
brini
Does anyone else use RCS [1] for this?

[1] [https://www.gnu.org/software/rcs/](https://www.gnu.org/software/rcs/)

~~~
saidajigumi
WAT. Are you trolling us, or are you that uninformed about VCS history? Giving
you the benefit of the doubt, just learn and use git[1]. Yes, there are things
about the UI that suck. But the underlying machinery and power it provides is
unparalleled.

RCS, in short, is that horrible feet-killing pair of boots that made you think
you _hated_ <insert sport here>, when in fact it was just frustration with
sub-par equipment.

[1] If you need to learn git, check out Scott Chacon's excellent Pro Git,
available for free online at: [http://www.git-scm.com/book](http://www.git-
scm.com/book)

~~~
brini
Ha! Fair enough. No, I didn't intend to troll. I've found RCS useful for ad
hoc versioning of configuration files on systems without git or other version
control systems. Wondering whether anyone still finds it useful. I reckon not!

~~~
throwaway2048
RCS is a lot less complexity and remembering commands than a full-on VCS for a
few stray config files.

------
Aaronneyer
I've made my own similar solution. I have all mine on Github, so I git clone
the repo, and run my bootstrap script, which initializes the submodules,
Vundle's all my vim plugins, and symlinks all the files.

[https://github.com/Aaronneyer/dotfiles](https://github.com/Aaronneyer/dotfiles)

~~~
atmosx
isn't that sort of info kinda _sensitive_
[https://github.com/Aaronneyer/dotfiles/blob/master/sshconfig](https://github.com/Aaronneyer/dotfiles/blob/master/sshconfig)
? I can see hosts and usernames...

~~~
Aaronneyer
Ya, that's actually something I've been meaning to pull out, although I don't
think it really matters all that much if people know what hosts/usernames I
have.

------
muuck
I use Vcsh. It allows for more than one repository. It's a Shell script, uses
Git and it doesn't symlink.

------
4ad
> I've come across various programs which aim to manage this for you by
> keeping all the files in a subdirectory and then installing or linking them
> into their appropriate places. None of those programs ever really appealed
> to me. They would require a ton of dependencies (like Ruby and a ton of
> libraries for it) or they would require me to remember how to use them,
> which is difficult when really for such a task you rarely use the program.

Ever heard of shell scripts? This is what I use:
[https://code.google.com/p/aram-
dotfiles/source/browse/make.u...](https://code.google.com/p/aram-
dotfiles/source/browse/make.unix)

------
fps
I keep all my dotfiles in a directory called "~/dotfiles" and symlink just my
.bashrc. everything else gets reconfigured via aliases.

eg.

    
    
         alias vim='vim -u /home/derf/dotfiles/vim/vimrc'
         alias tmux='tmux -f /home/derf/dotfiles/tmux/tmux.conf'
         

[http://github.com/fredsmith/dotfiles](http://github.com/fredsmith/dotfiles)

~~~
transfire
Isn't that a lot of work? And I doubt it will work for everything. Some
programs don't give you an option to get configuration from non-standard
location.

------
wincent
The article says the author doesn't want to depend on something like Ruby.
Ruby (or Python) seem a lot more likely to be on a base install than GNU Stow,
though.

~~~
jamestomasino
Or just write a shell script. This is a pretty trivial task in Bash, let alone
zsh

------
chris_wot
I gotta ask - what's with the tiny columns on this website? I'm reading on an
iPhone and there's more white space than area that displays actual text!

------
dragonfax
Back to the old "dotfiles with git Best Practices".

My favorite is just to alias it all to a different name.

    
    
        alias dg='git --git-dir=/Users/dragonfax/.dotfiles --work-tree=/Users/dragonfax'
    

now regular git doesn't overlap with my dotfiles git, and I never have to
worry about mis-executing the wrong git

------
bigbossman
I use the thoughtbot/dotfiles setup.
[https://github.com/thoughtbot/dotfiles](https://github.com/thoughtbot/dotfiles)

Pretty good customizations by default with an elegant approach for adding
local settings. The install.sh script automatically symlinks appropriate files
as well as downloads vim bundles.

------
antihero
Can Stow do hardlinks? The reason I ask is that IIRC systemd shits a brick if
your service files are symlinks.

Conversely, I have a script that does this:

[https://github.com/radiosilence/dotfiles/blob/master/relink](https://github.com/radiosilence/dotfiles/blob/master/relink)

All I have to do is maintain a MANIFEST file.

~~~
replax
uAs I ubderstood, systemd only uses symlinks. Any time you enable a service,
systemd executes ln -s ..systemd.. ...service ...

~~~
antihero
Yeah but the services systemd links to cannot be symlinks.

~~~
SEJeff
On Fedora 18 it most certainly can. I did it yesterday with some service files
under /usr/lib/systemd/system for some service files I created

~~~
antihero
Neat! Perhaps it's been updated then.

------
davexunit
I did not know about GNU Stow. I want to try to use this for my dotfiles along
with a simple Makefile to automate calling stow on all of the directories.
This will also be a nice way to manage the differences between my home
configuration and work configuration. One make rule per environment. Thanks
for sharing.

~~~
e12e
You might also enjoy xstow, a reimplementation in c++ -- in case you might
want to use stow without having perl:

[http://xstow.sourceforge.net/](http://xstow.sourceforge.net/)

edit: I use xstow for managing ~/opt -- putting stuff like ~/opt/xstow/golang-
git, with symlinks to ~/opt/{bin,lib,man} -- making it easy to add the
relevant folders to PATH, MANPATH etc in .bashrc.

------
phormat
I don't see dfm mentioned, curious if anyone has used that? I haven't, but may
be interested in trying it out.
[https://github.com/justone/dfm](https://github.com/justone/dfm)

------
qznc
I use a shell script [0]. It also includes some gconf configuration etc.

[0]
[https://github.com/qznc/dot/blob/master/install.sh](https://github.com/qznc/dot/blob/master/install.sh)

------
transfire
Pretty neat. I may try it. I just wish there were a way for the dot files
themselves to not be actual dot files while in the dofiles directory, but then
become dot files when symlinked by stow.

------
est
If you add more features, like store the settings in a sqlite, universal
config r/w interface, and live config change notification to apps, you'll come
up with a system like Registry.

~~~
staticshock
The difference is that dotfiles are simple, text based, and human readable.

When you re-install a Windows system, do you overwrite the registery with a
backup you had? I doubt it.

------
schabernakk
just for completeness sake and because no one mentioned it yet:
[https://github.com/technicalpickles/homesick](https://github.com/technicalpickles/homesick)

yes, you need ruby for it but I dont really see that as a problem. Its a bit
confusing at first (could be just me, but I still dont get why you have
basically 2 repos, one managed by homesick and the one you checked out
yourself) but it works fairly well. Takes care of symlinking, updating and
whatever you want.

------
auvrw
some files i symlink, some i copy, but i prefer to use the language's
import/include/source/load command if the dot file is actually a program
rather than a conf file. that way, i can add machine-specific configuration.
to anyone who makes tools like gnu stow or those mentioned in the comments:

consider adding support to modify existing dot files as well as replace them.

------
kul_
ln -s ~/dotfiles/.bashrc ~/.bashrc

~~~
sneak
I keep the dotfiles in my dotfiles directory without the dots, as there's no
need for them to be hidden.

------
seletskiy
I'm using a bash script [0] too, it is bit complicated because of I've have
three different workplaces and some conf files that have account information
(such as email passwords) should be hidden.

[0]
[https://github.com/seletskiy/dotfiles/blob/master/dotfiles.s...](https://github.com/seletskiy/dotfiles/blob/master/dotfiles.sh)

~~~
stevekemp
I "solved" that problem by having two repositories: dotfiles & dotfiles-
private.

The public repository has .bashrc, etc in it. The private repository has
~/.mutt/work-muttrc, etc in it.

