Unofficial guide to dotfiles on GitHub(dotfiles.github.io)
dotfiles.github.io
Unofficial guide to dotfiles on GitHub
https://dotfiles.github.io/
64 comments
I still want the versioning of host-specific stuff though, as well as the backup (by having the repo on GitHub too), and easy reference to other hosts' config that I might want on my current one after all (or setting it up for the first time).
I do this by having ~/.config/tool/blah.conf as you'd expect; but also ~/.config/by-host/$hostname/tool/blah.conf
I agree 'classes of hosts' is way overkill for probably anyone's personal machines though. Only thing close to that I do is with aconfmgr for more system-oriented stuff - but that's all simply on the basis 'if SSD enable TRIM' type 'classes', no manual specification.
I do this by having ~/.config/tool/blah.conf as you'd expect; but also ~/.config/by-host/$hostname/tool/blah.conf
I agree 'classes of hosts' is way overkill for probably anyone's personal machines though. Only thing close to that I do is with aconfmgr for more system-oriented stuff - but that's all simply on the basis 'if SSD enable TRIM' type 'classes', no manual specification.
I do something similar, though I use the "defaults" as the starting point and add overrides in local files which aren't checked in. Something like this:
# .dotfiles/.bashrc
# shared baseline config...
if [ -f ~/.bashrc.local ]; then
. ~/.bashrc.local
fiJust wanted to mention Stow[1] here, which I use to symlink my dotfiles on a new machine on a per app basis for many years now. My set up script just installs basic compiler toolchain and runs a bunch of stow commands based on Linux/Mac OS. I also adhere to XDG base spec[2] so I can keep my ~/ clean.
1: https://www.gnu.org/software/stow/ 2: https://wiki.archlinux.org/title/XDG_Base_Directory
1: https://www.gnu.org/software/stow/ 2: https://wiki.archlinux.org/title/XDG_Base_Directory
Also, the latest version (>= 2.3.0, released June '19) has a new flag specific to managing dotfiles. When passing `--dotfiles`, stow replaces `dot-` at the beginning of filenames with `.` in the symlinks. The online help does not mention it, but the release notes and man pages do.
Stow is the answer as far as I'm concerned. It's been around forever, it's standard, available in every package manager, the defaults just work.
I use it in combination with a make to automate the setup of a new install.
I use it in combination with a make to automate the setup of a new install.
Yeah, I don't understand why people like reinventing the wheel, Stow works, Make works, both are available everywhere, you don't need 30 layers of JS to manage dotfiles, I'm not against progress, but at least make something better than what's already around.
I really like stow. It handles almost everything for me.
One thing, I didn't split things by apps per se. I split them based on task. In some machines, I do Python work, so I created a 'python' package. In some I do PHP, so I created a 'php' one. I have a 'base' one where it has my .bashrc, .profile, .bash_profile, fish configs and other things.
Everything in the .bashrc. .profile, etc is loaded around conditionals. So, while the files are long, the section only activates if the other package is available. I thought about splitting it onto files, but most editors have a way of collapsing sections, so I decided to keep it on one so it's easy to edit in one place.
One thing, I didn't split things by apps per se. I split them based on task. In some machines, I do Python work, so I created a 'python' package. In some I do PHP, so I created a 'php' one. I have a 'base' one where it has my .bashrc, .profile, .bash_profile, fish configs and other things.
Everything in the .bashrc. .profile, etc is loaded around conditionals. So, while the files are long, the section only activates if the other package is available. I thought about splitting it onto files, but most editors have a way of collapsing sections, so I decided to keep it on one so it's easy to edit in one place.
How do you manage dotfiles of apps that overwrite symlinks? Eg: Xfce frequently does it.
I do not like comments, which are basically upvotes, but yes, Stow is the answer and this should be the top comment.
After fiddling around with lot of options, I have finally homed in on a nix / home-manager[1] based setup. There are a few minor annoyances on Mac OS that I haven't sorted out yet (most of them are symlink/permissions related), but so far it's been working great for everything including support for VSCode dev container dotfiles setup[2].
[1]: https://github.com/nix-community/home-manager [2]: https://code.visualstudio.com/docs/remote/containers#_person...
[1]: https://github.com/nix-community/home-manager [2]: https://code.visualstudio.com/docs/remote/containers#_person...
[This] way (linked from the tutorials section of the page) is a great way to version your dotfiles without symlinks or installer scripts.
[This]: https://www.atlassian.com/git/tutorials/dotfiles
[This]: https://www.atlassian.com/git/tutorials/dotfiles
I use this method, it's great. WAY superior to and WAY easier than using symlinks and having to constantly copy/move and symlink things to a git repo.
I use this script (which I modified a bit from the Atlassian one) to bootstrap it on a new $HOME dir (replace "***YOUR_GIT_REPO_ADDRESS***" with your address; also, you need to copy the function ,cfg into your .*rc file for command-line use):
I use this script (which I modified a bit from the Atlassian one) to bootstrap it on a new $HOME dir (replace "***YOUR_GIT_REPO_ADDRESS***" with your address; also, you need to copy the function ,cfg into your .*rc file for command-line use):
#!/bin/bash
set -euo pipefail # the usual stuff
# TODO: copy the below function into your .*rc file
function ,cfg {
/usr/bin/git --git-dir="$HOME/.cfg/" --work-tree="$HOME" "$@"
}
# TODO: replace '***YOUR_GIT_REPO_ADDRESS***' below
git clone --bare git@***YOUR_GIT_REPO_ADDRESS***/.cfg "$HOME/.cfg"
,cfg config status.showUntrackedFiles no
if ,cfg checkout; then
# worked fine, we're done
echo "Checked out config."
else
# it failed, so assume we need to move some files out of the way
echo "Backing up pre-existing dot files."
mkdir -p "$HOME/.config-backup"
,cfg checkout 2>&1 | grep -e "\s+\." | awk "{'print $1'}" | xargs -I{} mv {} "$HOME/.config-backup"/{}
,cfg checkout || (echo "Still cannot checkout configs; see messages and fix." && exit 1)
echo "Checked out config."
fi
I also have a git alias to commit files that are tracked with a message: ctm = commit -a -u -m #commit all tracked files with message
So you can do like this to commit changes and push them: ,cfg ctm "I modified my .zshrc"
,cfg push*What issue do symlinks have that makes them worth listing as a negative? Asking as someone who wrote an installer script to make symlinks a decade ago, and has used it whenever setting up a new computer ever since.
I use them and have no issues, but some editors don’t respect symlinks when making backups when you’ve opened the symlink (Rename existing file, make new file with the old name, and now the symlink is renamed and subsequent updates are unlinked as well). I seem to recall I had to set an emacs var to avoid this behavior.
Flatpaks can be an issue depending on the sandboxing. The application may be restricted from accessing the target. Using a hardlinks works, so it isn't that big of an issue to have a couple hardlinks, but it is still something to keep in mind.
Enabling/disabling systemd services is done via managing symlinks. Unfortunately, when disabling a service in systemd, it follows and remove symlinks which can remove your symlinked service files.
Which was inspired by this HN thread https://news.ycombinator.com/item?id=11070797
I love the atlassian method for dotfiles. I have been using for a few years now and currently stored on my private gitea server. I also create a branch for each variation, linux, macOS, macOS arm, windows. Basically they’re the same but they all have slightly different things I cannot use universally.
I had different branches for different machines too in the past but it felt very inefficient to me. The configuration was the same for 99% and for the last 1% I had to manually copy stuff back and forth. At the moment, I just try to use tools that allow me to have different configurations for different hostnames or OSs but maybe I should look into one of the fancier dotfile managers…
FWIW, that isn't the "atlassian method" for dotfiles. People have been doing bare repos for a while.
Also, pretty sure they even say at the start of the post they got the original alias from a HN commenter.
Also, pretty sure they even say at the start of the post they got the original alias from a HN commenter.
A few years ago I spent some time developing my own solution to this, which I published on GitHub. I drew inspiration from the best dotfiles managers at the time, but I found deficiencies in all of them which is why I made my own. Basically: no configuration file, uses symlinks and not copies or templates, and can clean up files after you remove them. The result is dfm [0]. I talk more about the differences from other high-quality projects in the README. If you like DFM, I’d appreciate a star on GitHub so that I can hit 100 to qualify to be listed on the dotfiles.github.io list :)
[0] https://github.com/cgamesplay/dfm
[0] https://github.com/cgamesplay/dfm
This is fascinating to me. I have been a unix user since 1994 and I have carried my dotfiles around with me. I almost never edit them. Things like "oh-my-zsh" just look to me like supply chain attacks as a service. What is the benefit of these dotfile schemes?
> What is the benefit of these dotfile schemes?
Not everyone has the time to create their own custom dotfiles.
Some just want sane and beautiful terminal defaults.
Not everyone has the time to create their own custom dotfiles.
Some just want sane and beautiful terminal defaults.
I certainly hope I did not give the impression that I spent a great deal of time editing these files. My zshrc is three lines, the last of which was added in the 90s.
Folks have been storing their home directories in VCS for ages, some older resources:
https://vcs-home.branchable.com/
https://vcs-home.branchable.com/
My pick is yadm - clean way to setup working environment on any host any *nix-like OS and bootstrap it in seconds. password-store (plus yubikey) organically complements it with simple and effective way to access secrets on any host. However I'm using private gitea instance to store repos for both. Just because. :)
after trying a few different ways i've settled on chezmoi which they also mention on their utilites page. it supports quite a lot of things that many other solutions miss like templates so that you can use the same repo across different operating systems and being able to run scripts just once, in order and so on.
It's somewhat involved to set up but now across windows/linux/macos my entire setup is literally just a one-liner.
It's somewhat involved to set up but now across windows/linux/macos my entire setup is literally just a one-liner.
I started using Chezmoi as well a year or so ago. Its the only one I've managed to stick with and not end up with a mess of different setups across machines.
I really like chezmoi. It is powerful enough to setup an entire organizations dot files.
I create my .vimrc and .tmux.conf when I set up my machine or when I get annoyed at the defaults.
I find the problem with "set and forget" kind of jobs is that you forget how to do something because someone else already did it for you, so you don't learn anything. It's similar to joining a complicated project where everything has been set up for you and all problems were solved and if you were to join a new project from day 1 you would have to learn everything again. (See setting up CI/CD, the structure of a java project, a gradle file, a maven POM, Dockerfiles, git, Kubernetes manifests and other devops tasks)
You still need to learn how to do things. I want to be fluent in the tools I use, so I would rather do things from memory.
I find the problem with "set and forget" kind of jobs is that you forget how to do something because someone else already did it for you, so you don't learn anything. It's similar to joining a complicated project where everything has been set up for you and all problems were solved and if you were to join a new project from day 1 you would have to learn everything again. (See setting up CI/CD, the structure of a java project, a gradle file, a maven POM, Dockerfiles, git, Kubernetes manifests and other devops tasks)
You still need to learn how to do things. I want to be fluent in the tools I use, so I would rather do things from memory.
I have my home directory as a git repo: works great, simple, no symlinking
I have this as well. Easy to push and pull changes. I push to a private git server.
I keep a second copy repo on a thumb drive so I can start my home directory on an offline computer.
I keep a second copy repo on a thumb drive so I can start my home directory on an offline computer.
Interesting. But I guess there must be files that you don't check in because of size?
You can .gitignore everything. I used to have my homedir as git repo, but abadoned that because it interfered with other git repos inside my home. Nowadays i have ~/.config as git root, with some symlinks supporting the programs that don't look there on their own.
Also, codespaces has an option to deploy (your) dotfiles by selecting a repo that will be used. It runs install or similarly named file to do so.
https://docs.github.com/en/codespaces/customizing-your-codes...
https://docs.github.com/en/codespaces/customizing-your-codes...
Their Vim-specific recommendations are woefully out of date.
Can you provide a link to more current recommendations for Vim? I've used this article so I'd like to know what it got wrong.
I used vim years ago, and the list looks like it was written then.
e.g. the package management. vim-plug seems fine, it seems odd to me to mention the others. (Pathogen's readme now mentions that it recommends vim's built-in package management. Vundle and neoplug haven't had a commit in years).
In terms of vim distributions, https://github.com/SpaceVim/SpaceVim probably deserves a mention, as inspired by the popular Spacemacs.
It'd probably be worth mentioning NeoVim.
e.g. the package management. vim-plug seems fine, it seems odd to me to mention the others. (Pathogen's readme now mentions that it recommends vim's built-in package management. Vundle and neoplug haven't had a commit in years).
In terms of vim distributions, https://github.com/SpaceVim/SpaceVim probably deserves a mention, as inspired by the popular Spacemacs.
It'd probably be worth mentioning NeoVim.
[deleted]
I’ve written a bit. Maybe it’s helpful.
https://statico.link/vim3 https://statico.link/dotfiles
https://statico.link/vim3 https://statico.link/dotfiles
I've used my custom bash script for managing dotfiles for ages and also have tried all other tools, but just couldn't get it right because I work on multiple OS. Then I found https://github.com/rhysd/dotfiles. It is the only tool I know of that can support multiple OS (Linux, mac, windows). I have to work with multiple OS and having a single dotfiles repo has been great, especially its ability to set different config on different OS, well as a unified Unix-like config setting.
In 2015, GitHub sent me a DMCA takedown notice for a repository of dotfiles. When I tried to convince them how ridiculous that is, their only suggestion was to file a DMCA counter notice.
Glad they've come a long way since then.
Glad they've come a long way since then.
Not much work ou-of-the-box.
In the home directory (~) run:
In the home directory (~) run:
git init
git remote add origin https://github.com/username/dotfiles
echo '/**' >> .gitignore;
git add -f .gitignore
git add -f .gitconfig
git add -f .bash_profile
# etc and push
On the second machine: git clone https://github.com/username/dotfiles tmp --no-checkout
mv tmp/.git .
rmdir tmp
git reset --mixedtl;dr: Create a .gitignore in your ~ with an asterisk on the first line and `!.dotfilename` on subsequent lines; the asterisk means Git will ignore everything, and the ! means Git will un-ignore that specific file or directory. (Be sure to include the .gitignore file itself.) Use Git as normal and push. To deploy on another machine/account, the easiest method is to check out as normal into a temporary directory, then move the .git directory from that temporary directory into your ~ and run `git revert`. Git will see all of the missing dotfiles as changes to be reverted and revert them into existence.
One potential drawback of doing that is that every directory under ~/ that is not itself part of another git repository becomes part of that git repository, which could make some programs act weird, particularly project auto-detectors in IDEs and such.
To avoid that, one can rename the `.git` folder, effectively disabling auto-discovery, and run git with the option `--git-dir=<newname>`.
To avoid that, one can rename the `.git` folder, effectively disabling auto-discovery, and run git with the option `--git-dir=<newname>`.
So the IDE or whatever would basically traverse up the filesystem looking for the first directory with a .git subdirectory? I've never encountered something like that but I suppose it's possible. Do you know of any IDEs specifically that do that?
At any rate, I didn't know renaming the .git directory was possible. Do you have to add the --git-dir option to every subsequent git command? Sounds like a pain but my dotfiles change rarely enough that I guess I could live with it if I had to.
At any rate, I didn't know renaming the .git directory was possible. Do you have to add the --git-dir option to every subsequent git command? Sounds like a pain but my dotfiles change rarely enough that I guess I could live with it if I had to.
you can also create a .git file with the path for the git-dir folder (git-dir: /path-to-git-folder/) but that is kind of like having the .git folder with the exception that some programs don't seem to support it.
Yeah, the git command traverses up the filesystem until it finds a ./.git/HEAD file or until it reaches /, whatever happens first. The problem comes when a 3rd program uses git to find the root of a project that doesn't exist and instead of failing finds ~/.git and naively decides to index everything under ~/. I don't know of any specific IDEs that do that, although I vaguely remember running into a similar issue in the past, maybe not with an IDE, which is probably why I do it that way.
In `~/.git/config` do:
[status]
showUntrackedFiles = no
That solves most of those problems, as git will only consider files already in the repository and ignore everything else in your home directory.Don't track your home directory with Git if you have a habit of using git clean -xdf. Speaking from a bad experience.
This is what I do. It's simple enough and doesn't require any external dependencies. Highly recommend this approach.
The only issue I've had with this approach is that new files which I'd like to commit to the repository are ignored by default. One could use the .gitignore negation strategy like OP mentions to first unignore the file and then add it to the repository. I just end up using git add -f foo to force the addition even though foo is ignored.
The only issue I've had with this approach is that new files which I'd like to commit to the repository are ignored by default. One could use the .gitignore negation strategy like OP mentions to first unignore the file and then add it to the repository. I just end up using git add -f foo to force the addition even though foo is ignored.
Wow, thank you! This is pretty easy and without all the acrobatics you usually see people do when dealing with dotfiles.
git config status.showUntrackedFiles no
Shameless plug for "yet another" dotfile manager I'm writing.
It doesn't get in the way, and allows you to manage them in quite a flexible way.
Templating, conditional linking, copying, custom code execution... You name it!
https://github.com/cquintana92/dotfilers
https://github.com/cquintana92/dotfilers
I highly recommend Mathias Bynens's dotfiles under the Inspirations section. Have been using it for many years now and it makes it so much faster for me to work in terminal.
Literally was just looking at doing this an hour ago. After deciding it’d be too much work I come to hn for my pre-sleep reading and find this, lol.
[deleted]
weirdly, nobody mentioned vcsh[1] yet. it's a git-based tool that gives all git goodies. I use it and a couple of bash micro scripts to pull/push the latest changes upon logging in/out into shell (again bash, but seeking for POSIX or fish-based version)
[1] https://github.com/RichiH/vcsh
[1] https://github.com/RichiH/vcsh
There are so many utilities. Why not just use ansible? It can manage your dotfiles and much more (you can configure your whole machine).
Ansible is wonderful. I'd strongly consider it if I wasn't against the idea of having interesting enough dotfiles to version.
What I do with RasPi servers is I make a pull and a push playbook that live in a repo, which let me deploy what I have onto a new server, and pull any changes made in server web GUIs into the repo where I can commit them.
Then of course any other random periodic task also becomes an Ansible task.
If I had a use case for lots of random little scripts on my main machine, I think I'd choose Ansible over bash where practical, you get so many tools premade, and you can run local or remote all the same.
What I do with RasPi servers is I make a pull and a push playbook that live in a repo, which let me deploy what I have onto a new server, and pull any changes made in server web GUIs into the repo where I can commit them.
Then of course any other random periodic task also becomes an Ansible task.
If I had a use case for lots of random little scripts on my main machine, I think I'd choose Ansible over bash where practical, you get so many tools premade, and you can run local or remote all the same.
I used to manage my dotfiles with stow (xstow actually) and do some simple links. Now I run an Ansible playbook that creates links or copy depending on the files and also install tools on different OSes.
The big benefit is that it can be organized in a modular way with roles and tags, and sensitives files (like my gpg keys...) can be encrypted with the vault.
The big benefit is that it can be organized in a modular way with roles and tags, and sensitives files (like my gpg keys...) can be encrypted with the vault.
I’m slowly trying to make ansible playbook that pulls in my dot files and installs everything I need (node, rust, go, all my CLTs, etc).
What I didn’t need at all, after all, was anything that installed different things on different hosts or classes of hosts.
Luckily, every tool I want to configure has a config file option to include another file, so I have a working copy of my version controlled defaults here:
…and a one time installation script that makes various tool’s config files look like this:
I am quite happy managing the local bits by editing files on local machines. All my configuration stuff splits into either “used everywhere” or “used just on this one host”, so that makes it easier.
As soon as I figured this out I had to pinch myself as to why it had taken so long to come up with this idea.