5 ms·
> 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. Right. Which is why I
by AceJohnny2 12y ago
> 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.
Right. Which is why I use git with a workspace detached from the git directory. The git directory is in ~/dotfiles/.git, with "git config core.worktree ~", and I set an alias "dgit=git --git-dir ~/dotfiles/.git". The advantage of this method is that there are no symlinks to maintain, however initial clone is a bit painful, since you have to move the files and set the config.
It's not perfectly straightforward, but it's as close to it as I could get it.
- emillon 12y agoThat's exactly how vcsh works too.
- zorbo 12y agoThis is great! It fixes the only problem I have with maintaining my dotfiles as a git repo: the .git dir in ~. That interferes with so many things such as the CtrlP vim plugin, the integration of git with the bash prompt and many other things. Thank you for this.
- AceJohnny2 12y agoYeah, the git in the bash prompt thing was the most annoying thing to me, honestly :) Since there is interest, I'll elaborate on the understated "a bit painful" part of moving the files after an initial clone which leaves the files in the ~/dotfiles dir. The problem is that I didn't find an easy "move and overwrite recursively" command in Linux. Here's the magic command from my script: git ls-files --cached -z | rsync -av --from0 --remove-source-files --files-from - ${dir} ~/ && find . -type d -empty -delete To spell it out, it's having git list all the files in the repo (so skipping any unversioned files such as the .git dir itself), using the NUL byte as file termination to avoid any (most?) special character issues in file names, and using rsync to move the files over thanks to --remove-source-files. However rsync doesn't remove empty directories (durr), so have the find do that. Also, you probably want to set "git config status.showUntrackedFiles no" ;)
- mbudde 12y agoI have very similar setup to yours, but my solution is to use a bare repository. To set up dotfiles on a new computer is just $ git clone --bare git@github.com:mbudde/homedir.git .homegit $ git --git-dir=.homegit --work-tree=~ checkout -f # Overwrite existing files $ echo '*' >> .homegit/info/exclude And then I have a simple git wrapper script [1]. I moved from using an alias to a script for some reason I can't remember (and of cause I didn't write it in the commit message -_-). [1] https://github.com/mbudde/homedir/blob/master/usr/bin/hgit https://github.com/mbudde/homedir/blob/master/usr/bin/hgit
- AceJohnny2 12y agoThis definitely looks like a better alternative!
- 4ad 12y ago> I didn't find an easy "move and overwrite recursively" command in Linux. You don't need recursiveness into commands, just use find (maybe with xargs) to generate the list of files to overwrite (or commands to execute).
- AceJohnny2 12y agoThat's what I did in my first iteration, except find is hell. No wait, I mean find is a really powerful and sophisticated tool, but it takes time and effort to get it to do precisely what you want. It turned out rsync did what I wanted more easily.
- 4ad 12y agoFind has an atrocious syntax. Nowadays, I seldom use any other feature of find rather than just enumerating files. Rather, I enumerate files, create commands on them (with things like xargs and sed), and pipe the output into sh. Generating code is a very flexible technique, and it's actually easier (and safer) that trying to muck with find options.
- stormbrew 12y agoThis is exactly what I do and I think it works fantastically. I also have the same problem with initial clone and I keep meaning to write a script to automate it (especially in a push sort of way where I just specify the host that I want to convert and it does it over ssh with git push). I also make an effort to push my config files into .config wherever possible. I really hate the ~ dotfile clutter.
- burke 12y agoI just made ~/.git and ignore everything with .gitignore, whitelisting files I want to commit: https://github.com/burke/dotfiles/blob/master/.gitignore https://github.com/burke/dotfiles/blob/master/.gitignore It works really well for me.
- dietrichepp 12y agoI remember giving advice once, to someone who did that and then git clean -dfx
- zokier 12y agoThat is especially problematic with gits directory traversal behavior. If you are in a wrong directory inside your home, you might accidentally nuke your homedir instead of the intended repo.
- burke 12y agoThat is terrifying. I just added this to my zshrc: git() { local toplevel=$(command git rev-parse --show-toplevel 2>/dev/null) if [[ "${toplevel}" == "${HOME}" ]] && [[ "$1" == "clean" ]]; then >&2 echo "Do NOT run git clean in this repository." return fi command git "$@" }
- rkowalick 12y agoThe one thing I like about stow is that I can choose to only add configurations that make sense for the machine I am using. If don't have a certain application, I don't 'stow' the configuration for that application in my home directory.
- 4ad 12y agoI used to have complex configuration files that worked in all scenarios using conditionals and detecting available features, but now I just generate the configuration files, or rather specialise the parametric versions of them, and push them with chef/cfengine/ansible or even rsync.
- stormbrew 12y agoA sibling post mentions a thing called vcsh (with no additional details) that appears to allow you to do just that with the same premise by overlapping multiple repositories onto your homedir.
- marbu 12y agoYou can have multiple git repositories, each for different application. Or you can use git submodules when suitable (eg. vim plugins, directories in ~/.config).
- yawaramin 12y agoYou could have a separate git branch for each machine :-)
- tvon 12y agoSince we're all talking about it... I keep my dotfiles in a sub-directory (doesn't matter where) and use the following Rakefile to manage it: https://github.com/tvon/dotfiles/blob/master/Rakefile https://github.com/tvon/dotfiles/blob/master/Rakefile Then it's just `rake status` or `rake link` to symlink everything. I've only been using this for a few years but I haven't run into any problems yet.
- marbu 12y agoI'm using the same scheme for some time and it works nice. It started with simple alias as well, but then it expanded into bigger wrapper script over time. You can check it here https://github.com/marbu/dogit/blob/master/README.md https://github.com/marbu/dogit/blob/master/README.md That said, I'm not sure if it would be direclty usable for anyone other that me in it's current state. It's tailored to my use case and there are few not so well solved use cases. Few additional advantages of this approach in general: You can use local branch which is private to the machine and a public branch, Whatewer you commit ends up in the local private branch and if you would like to share it, you need to cherry pick particular commit and rebase (so that you I don't end up sharing private ssh key on github). You can use any git tool directly on your dotfiles. One can directly add vim submodules into the dotfiles repo.
- akavel 12y agoI've once thought of something similar for hg, but a bit bigger, in that: 1. There could be many "hg-dirs" for a one regular "workdir" (e.g. .hg_foo, .hg_bar, .hg_baz, ...) 2. There'd be a wrapper tool, that on any hg command would autodetect to which hg-dir any given affected file belongs, if already committed earlier (with ability to override the autodetection by hand, including for adding brand new files to the repo). However, didn't care enough to try implementing this yet. Also, not quite sure how/whether it could work with git, given the existence of staging area. (full story: http://stackoverflow.com/a/5789827/98528 http://stackoverflow.com/a/5789827/98528)