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.
I take a similar approach. I have a dotfiles git repo in ~/dotfiles/ and have a Makefile which creates symlinks in my home directory. For example, ~/.bashrc is a symlink to ~/dotfiles/bashrc. That way, I can have a whitelist (whatever's in the Makefile) instead of a blacklist (like a .gitignore).
My main problem with this is it leads to accidentally executing git commands on your dotfiles repo.
Like, say you thought ~/src/xulrunner was a git repo, but it was actually managed with hg or maybe was extracted from a tarball. Whereas normally executing some git command would complain that this is not a repo, if your ~ is a git repo then git will happily execute whatever you told it to on your dotfiles repo.
For git repositories that are not touched very often, you can move the .git directory to something that isn't picket up automatically. Use it like this:
mv .git dot_git
git --git-dir="dot_git" add ...
Thats also a nice trick if you need a git repos in a git repos, e.g. for integration test for libraries interacting with git.
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:
I wondered about this, but I pose this question to you: what happens if you have a merge problem with, say, a libreoffice doc or something. How do you handle that? I use hg, but I imagine my plight would be similar. TIA.
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.
This lets me perform any necessary initialization (e.g. cloning submodules) via `make` and installing the actual symlinks into $HOME via `make install`.
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....
?>
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.
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.
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.
I know of a guy who used to use rcs back in 2001 and he probably is today. He is one of those old-school UNIX guys who know literally everything about a UNIX system.
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
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!
I've recently installed RCS on a Windows host for versioning my .emacs file, and I rely on Emacs VC to drive the tool.
On Solaris hosts, including locked-down "production", I use SCCS to version my dot-files because it's available by default. For development I use SVN (old too by today's standards).
I don't advocate using these old tools over modern alternatives; however I find their simplicity in the above cases to be beneficial.
I used to use RCS, but these days I use mercurial. Pretty much any DVCS is going to be a "better RCS" than RCS (bzr, mercurial, git, fossil, monotone...). Even if you never need to pull/push.
rcs doesn't have .gitignore files and accidentally running commands on your top-level repo, so I could see why one would consider it. You don't really need atomic commits for this use case, so rcs is barely worse than the alternatives.
I can't say that I've ever had a problem with accidentally running commands in my top-level repo despite many years of running it under git and other VCS'es.
That said, using tools mentioned in this thread (esp. vcsh[1] and mr[2]) it's possible to have one's cake and eat it too w.r.t. using git for homedir version control without the worries of accidentally running VCS commands on your homedir. They also allow some real benefits, like the ability to use and deploy subsets of your rcfiles. For example, you could easily create profiles like: "server-side minimal core", "main personal system", "work box with employer-specific stuff".
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.
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.
> 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.