Hacker News new | comments | ask | show | jobs | submit login
Unofficial guide to dotfiles on GitHub (dotfiles.github.io)
151 points by Perados on Dec 12, 2015 | hide | past | web | favorite | 51 comments

If anyone is interested in setting up multiple platform dotfiles or more complicated setup, GNU stow [1] is just pure genius. It's a very simple approach which works very well for me. It's described in this blog post: http://brandon.invergo.net/news/2012-05-26-using-gnu-stow-to...

[1]: https://www.gnu.org/software/stow/

Yes. I don't understand why everyone keeps reinventing this tiny, full-featured symlink manager.

It can also unstow and restow, ignore patterns, etc. Highly recommended.

reinventing the wheel != creating a universal standard

With this stow solution, I wonder what happens when some program makes modifications directly to its own configuration files, without being aware that they're not directly under your home directory but symlinked under dotfiles somewhere. Will the symlinked file get modified? Or will the symlink be removed completely and a new file be put in its place, directly under your home directory and not under your stow directory at all.

One program which I'm thinking of that can make modifications of its own config files is znc. weechat is another. There might be some other random program that does this too. I'm concerned that using stow for them might lead to disaster.

Any advice from someone who's tried it with apps like that?

Why wouldn't it work? You can write to a symlink.

    $ touch file
    $ ln -s file symlink
    $ echo text > symlink
    $ cat file

Some applications write to a temp file and then move that over the old file.

One way to work around this is to symlink the entire directory.

That blog post suggests putting the top-level "dotfiles" directory under version control. But doesn't it make more sense, at least with git, to put each individual subdirectory under dotfiles under in its own separate repo?

With the blog post's solution, when you want to revert to an older revision of, say, your .vim or .emacs.d dotfiles you're also going to be automatially reverting your .bash and whatever other random dotfiles you have. With the latter solution, when you revert your dotfiles/vim or dotfiles/emacs subdirectory, you only get an older revision of your vim or your emacs files.

Does that make sense?

You can revert changes to individual files or subtrees in git.

I've occasionally ran into bugs where symlinks have caused problems. At the very least this is something to be aware of.

That looks really cool! The only minor problem I would have is you have to install stow before bootstrapping your dotfiles on a new machine, but that's obviously not a huge deal. I guess I could replace my bootstrap.sh script with a line to install stow, then a line to run stow.

They buried the lede[1]:

> Once you have pushed a commit to GitHub, you should consider any data it contains to be compromised.

I've never understood why people want to dump their config files on a public server. The "reasons" given are unconvincing:

* "Backup, restore, and sync" -- I don't keep the rest of my backups out in the open.

* "Learn" -- Maybe, but I prefer learning from stuff people have taken the time to deliberately share.

* "Share" -- I'd rather explicitly choose what I share.

[1] https://help.github.com/articles/remove-sensitive-data/

In principle your dotfiles shouldn't contain any sensitive data. It's not burying the lede, it's just that you read the article and decided that some important warning was so important that it was the purpose of the whole piece.

The reasons they offer might not be the most convincing, but they're something, which is better than nothing. Suppose you have a bunch of configuration that you're sure contains no sensitive information and you've decided to sync it between machines somehow. Why not use github, assuming you're already a github user.

I agree with you in principle, but in practice putting your config on GitHub is asking to be pwned. If you put your personal config on a public server, the odds are good that you'll eventually leak some information you shouldn't have. If you're lucky, Amazon's bot will find the API key and disable it, and you'll waste a bit of time getting a new one. If you're less lucky, you'll pay for someone's bitcoin miner. If you're unlucky, someone will quietly pwn you bit by bit, it will take you months or years to discover it, and you may never figure how how they did it.

When "scp" and "rsync" exist, and git is a distributed version control system, it's hard to justify unnecessarily exposing data on the web.

The solution I use to this issue, which I think is fairly straightforward, is to put any sensitive information such as credentials, or things that others don't care about such as aliases to company directories or running company-specific scripts, in a private repo. Then I put that repo as a submodule in my public repo. Anyone can look at or clone my public repo, but only I'll be able to initialize the submodule.

What do you mean by "the open"?

Mine are on Github, but in a private repo. They're nothing special at all - there are better examples for others to learn from.

As a backup, or for a refresh/new machine - what easier way than to clone my own repo? I guess I could them on another disk, a USB drive say, but will I really remember to plug it in to push changes? It would certainly be easier just to use Github.

> Mine are on Github, but in a private repo.

The fact that Amazon has paid engineers to write a bot that scans for API keys suggests that most people aren't that careful, or willing to spend $7/mo so they can use private repos. It sounds like you're doing it right, but most people seem to be doing it wrong.

> The fact that Amazon has paid engineers to write a bot that scans for API keys suggests that most people aren't that careful

The fact that GitHub has not paid engineers to write a bot that scans for API keys, RSA keys, and other common credentials mistakenly committed and dropping the files from UI view / search indices without notification and explicit permission surprises me a lot more. The company seems to be full of great engineers and UI people; doing something like this would vastly improve the UX of developers beginning to use the platform, and would likely not get in the way of seasoned ones.

The fact no one muss mentioned that Bitbucket provides Free Private Repos eliminating the "can't be bothered paying" aspect is amazing and it makes the question "why would you not just put them in a private git/hg repo, it's practically free backups!"

    > most people aren't ... willing to spend $7/mo so they
    > can use private repos
Ah. I'm a student, I forgot there was a fee normally.

Still, there's Bitbucket and others, or self-hosted if so inclined.

Just recommending "closed configuration"? Same disadvantages as closed source.

I'm a fan of Thoughtbot's rcm[1], a dotfile manager. I just `git clone` my dotfiles down to a new machine, install rcm and run `rcup -d ~/.dotfiles` to symlink them into $HOME.

Used this to get a new laptop up and running immediately; the only step beyond that was a quick `brew list` to install packages that those dotfiles might lean on.

[1]: https://robots.thoughtbot.com/rcm-for-rc-files-in-dotfiles-r...

One thing that I love about rcm is how well it handles the case of host-specific dotfiles. Between my laptop, school servers, personal servers, etc., I access a lot of servers running different software that need to be configured differently. However, there are a lot of things, like aliases for example, that work regardless of the platform.

Rcm lets you specify which files should always be linked, and which should only be linked on a specific host, which means I factor out my dotfiles into "modules" and load exactly the right ones.

[1]: https://github.com/jez/dotfiles/tree/master/util [2]: https://github.com/jez/dotfiles/blob/master/zshrc

I highlighted this in a Show HN a few weeks back but I figured I'd link it here:

"dit" is a dotfile tool that isn't concerned with being fancy. It uses git hooks so all that's required of you to update your dotfiles is "git commit." It's written in Ruby, and is entirely open source.

I created it as a much easier, much simpler alternative to rcm or homesick. It doesn't have nearly the same amount of features (it's around 200 lines of Ruby), and it is only concerned with syncing dotfiles to the home directory.

I'd love to get feedback on the program, my programming, etc.


Looks really nice! I'll probably switch to this. I'm always annoyed that homesick doesn't automatically sync my local dotfiles repo with the home directory and I have to push to GitHub and then pull with homesick.

I have my own home-rolled "solution" to managing dotfiles, I'm a little uncomfortable checking them into Github though, as there's a slight risk some security credentials or something could leak without me realising.

Unless you have private repos I guess.

My solution is to use Dropbox to store all my configuration files, then use symlinks to the default locations.

If you don't already use it, you should check out GNU Stow as a tool to manage those symlinks. You just make a directory (or directories) which mirrors your home folder, but with only the files you want to store in dropbox, and Stow will generate symlinks in the appropriate places.


Just put your passwords in a separate `.environment` file and source it in your main file. Make sure the `.environment` file is in `.gitignore` (although there should be no reason to put it in your repo to begin with).

source $HOME/.environment


Mackup is a good tool for this -https://github.com/lra/mackup/blob/master/README.md

BitBucket has free private repos

After some years of git and hg, nowadays I use RCS to version control my dotfiles. I have a little bunch of them and their history is unrelated to each other, and I do not have to bother with symlinks or other fragile stuff. There's an RCS directory in my $HOME, every time I update a dotfile, I make a tarball of that directory and the checkouts of the files and encrypt the tarball, and put in dropbox. I have written a little command in emacs to help me do that, and emacs vc makes it easy to deal with check-ins and locking. It's just easier and more natural to me. For bigger repos, I resort to git too (though I'm inclined to try darcs some time soon).

I used to have my configuration files on Github, but I decided to remove them, first dotfiles, then recently my emacs config, as I have the idea that they are too personal, and I have to spend some certain effort to keep them publishable, e.g. use files for private data, like api keys, emails, Gnus settings, feed lists. Now I'll be able to check these in too, freely.

Earlier this year I was looking for a good way to sensibly manage my dotfiles across multiple machines (with different setups). The closest project I could find that supported something like this was https://github.com/EvanPurkhiser/dots which had a fairly robust way of extending/overriding configs, but I ended up getting a bit hung up (either with deploying or auto-updating, I forget which). Is there anything else out there that deals well w/ multiple machines/types (and across OS X and Linux ideally?)

You might want to take a look at my solution:


It lets you mix platform-specific bits in the middle of a file, do basic macro substitution, and some other things.

(Now that I'm using a mac occasionally, I use more of the multi-platform features than I claim in that post.)

Thanks, I'll give it a look next time I get the itch. :)

Ansible (http://www.ansible.com) works. As long as your workstation has ssh access to the machine you want to set up, you're good.

Salt or Puppet could work, if you don't mind templating out your dotfiles.

A different approach that i use:

Since i often work on systems i don't directly own or have an own account on, i use

eval "$(wget -O - https://myhost/.bashrc)"

to inject my bashrc into the current bash session to get my prompt, aliases and shortcuts ready without making changes to the fs. The functions defined in .bashrc help with managing pubkeys and loading other dotfiles.

The Zsh dotfiles are all giant frameworks... Allow me to shamelessly plug my zshrc. It's small, fast, single file and documented in the README - it's both a great standalone dotfile, or an excellent starting point for anyone interested in doing their own.


After running into a few bugs do to the use of symlinks I decided to write my own that was really just a wrapper around Git. After installing [gitsick][1] you could add one of your existing repos,

gitsick clone <name> <url>

The files will be deployed directly to your $HOME, without symlinks, and from then on `gitsick <name>` is just a wrapper around Git such that the $GIT_DIR is stored in one place and your $WORK_TREE is $HOME.

[1]: https://github.com/nnutter/gitsick

Do you know about vcsh (also linked in the post)? It seems similar to what you describe...

I'll have to look at that more. My initial scan of it is that is very similar except that it manually implemented each Git subcommand whereas mine does not need to because it just wraps and delegates to `git` (even tab completion).

I found that I don't really care about the commit history for my dotfiles so instead of using git to synchronize them, I use Unison, which is a bidirectional file synchronizer. Its like rsync but it has a graphical interface and its bidirectional so when I am synchronizing files I have the option to skip some files or to sync them in the opposite direction.


I've had my dotfiles on GitHub for some time. I'm planning to have a go at automating setting up my laptop. This post was posted on hn some time ago http://spin.atomicobject.com/2015/09/21/ansible-configuratio...

Anyone got any suggested reading on this topic? More than just dotfiles but actually automating installing software etc.

I built wsup [1] so that I could keep my dotfiles in multiple independent git repos -- some public on github for sharing (e.g. my emacs config [2]), and some private. It works similarly to stow, but is written in bash.

[1] https://github.com/dcreemer/wsup

[2] https://github.com/dcreemer/dotemacs

I've been using a dotfile manager called denv that my friend has been working on. It's still a little rough around the edges but allows me to switch between a golang env and a python env quickly by swapping out the dotfiles.


Could someone pretty please explain what dotfiles are and their uses? Google says they're just hidden files :S

They're configuration files for different *nix programs. For example .vimrc for vim. Or .bashrc for bash. In those dotfiles you can customize how things look or add custom commands etc.

This post is about how you can automated some of that so you can easily replicate the environment you're used to everywhere.

In this context, it's referring to various configuration and settings files, which traditionally on Unix platforms are saved in your home directory, either directly as hidden files or within hidden directories (for when there are multiple files needed).

Some examples would include .bashrc for running commands automatically when bash starts, .vimrc for vim preferences, .ssh/ for storing SSH keys and settings, etc.

myrepos and vcsh

+1 for vcsh.

I've got four separate repos: one for VIM, one for bash, one for SSH keys, and a miscellaneous one (.inputrc and friends).

This is a good idea but a bad choice of font. I can barely read the text even when I enlarge it.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact