41

I want to backup and sync my dotfiles using github. Since all the dotfiles resides in $home by default, should I just git init in my $home folder, or is that a bad idea?

Having performed git init in $home, my idea is then to .gitignore all non-dotfiles and non-dotfolders.

4
  • 22
    Be careful what you sync to github, e.g. .ssh, .gnupg, etc. Feb 14 at 15:24
  • I used to have a $HOME/.git, and I found it very cumbersome. A particular problem was cloning on other machines with populated home directories - I had no confidence that my existing files would not be clobbered. I am of the opinion that this is a strong argument in favour of the XDG Directory Spec, but many popular packages choose not to support it. Alas! Feb 15 at 19:28
  • 2
    I'm appalled that several (most) of the responses do not answer the question of whether it is a good practice. Feb 19 at 14:19
  • 1
    I have a repository in ~/skel with the relevant files in it, and the corresponding files in ~ are symlinks to that. For directories like .ssh, I have a symlink to ~/skel/dotssh and track the directory, with the appropriate .gitignore rules. This has served me well since around 2003 (back then using CVS).
    – nafmo
    Feb 19 at 14:39
58

Create a "bare" git repository:

cd $HOME
git init --bare .dotfiles

The --bare flag creates a repository that doesn’t have a working directory, making it impossible to edit files and commit changes in that repository.

Create an alias to manage the repository we just created:

alias dotfiles="/usr/bin/git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME"

Ignore the files that are not being tracked from being shown up in git status:

dotfiles config --local status.showUntrackedFiles no

Add your desired files:

dotfiles add .bash_aliases

Commit.

dotfiles commit -m 'Add .bash_aliases'

Now with the use of a bare repository, there is no .git directory in your $HOME directory; so it does not introduce any surprises while working with git.

That's how I manage my dotfiles. I first read about it here years ago.

4
  • 7
    Source: "Conventionally, repositories initialized with the --bare flag end in .git." In the light of that convention, I think it would be better to do git init --bare .dotfiles.git as opposed to git init --bare .dotfiles. Feb 13 at 22:43
  • 1
    +1, after trying several other approaches, I settled on using this, and it works very well for me. I even have the custom "dotfiles" command, just like you :D (for me it's a script, because it does some extra housekeeping)
    – marcelm
    Feb 14 at 9:16
  • 1
    @SebastianNielsen It's not a requirement. You can call them whatever you like.
    – user253751
    Feb 15 at 15:02
  • @SebastianNielsen Suffixing with .git is for when you want to use your bare repository as a remote centeral repository to "push" in or "pull" from. Though it might be a good practice it's not really necessary. I'll rather to keep it as .dotfiles for simplicity.
    – Ravexina
    Feb 16 at 0:17
14

It is a good practice, but you should ignore all files by default and just add the files you need. Here is an example of a .gitignore:

# ignore all
*
# include dot files (including .gitignore)
!.*

You can also exclude other files putting other lines at the end of your .gitignore:

# ignore all
*
# include dot files (including .gitignore)
!.*
.ssh 
4
  • 3
    will this not include : . (current dir) ? .ssh (ssh directory, containing potentially private keys) ? Feb 15 at 4:56
  • Yes, It will include. You shouldn't push to a public repository. Other option is to exclude specific files in a line below the one with the exclamation
    – neves
    Feb 15 at 15:35
  • Thx for the answer. Maybe add an edit to show how to do that, as it may save many people stumbling on the solution Feb 15 at 23:16
  • @neves it could be useful to demonstrate how to ignore then ~/.ssh, because to some it may not seem so trivial to switch back and forth between includes and excludes kind of rules.
    – Levente
    Feb 16 at 9:39
10

If you're slightly uneasy about having a git repository in your home folder (which I would be), you might consider this idea:

  • Create a git repository somewhere else, e.g. ~/src/configuration or ~/etc or wherever you like.
  • Put all your configuration files in there.
  • Replace your configuration files (at the normal paths) with symlinks into this repository.
  • Perhaps write a simple shell script which checks that the symlinks point where you expect them to, and run it e.g. daily in a cron job.

Every problem in computing can be solved with an additional layer of indirection ;-)

7

You could look at yadm, it does mainly this but I guess it is more secure and the setup may be easier. I think it is just a wrapper of git at first (it does have more features though), meaning that you can just use usual git commands replacing git by yadm (like yadm add/clone/status etc.)

I am not affiliated to yadm, just a happy user.

1
  • Nice! I've been using homesick but looking to drop the ruby dependency. Feb 15 at 0:37
7

I'd say it is a bad practice, indeed. None of the tutorials at https://dotfiles.github.io/tutorials/ or https://github.com/webpro/awesome-dotfiles will have you track the home folder directly into a home-level git repository. Most will manually copy or symlink the files.

While git tracking your dotfiles is a great idea, having a git repo at home level makes it easy to accidentally run commands to that repo when you actually mean to run it in a more specific directory repository.

For example:

mkdir ~/Projects/my-awesome-web-app
cd ~/Projects/my-awesome-web-app
npm init # initializes node projects, creates package.json
git add package.json # would not fail, since it's actually inside a git repo
git commit -m "starts work" # actually commits to the home repo, not locally

Also, Anish Athalye chooses not to track home folder directly under git:

  • There is no possibility of accidentally deleting your files. With your entire home directory under version control, running something like a git clean could wipe out everything in your home directory that is not tracked by your VCS.
  • It is possible to track configuration files that belong somewhere other than $HOME.
  • Installing dotfiles on new machines is easier. All that is required is cloning your dotfiles followed by copying or linking files. Keeping the entire home directory under version complicates installation.
1
  • That's not to say @ravexina's approach is wrong, but she has to go to some length to ensure it doesn't conflict with regular git usage. Feb 15 at 0:47
1

My solution for over 10 years has been a repository with public configuration and code. It includes a Makefile which does some basic checks and has an install target to create symbolic links in the home directory. This makes it harder to accidentally commit something which shouldn't be in there.

2
  • it seems like you don't actually run git init in the home folder, which is what OP asked about. Feb 19 at 14:21
  • They asked whether that was a good idea. I've answered that.
    – l0b0
    Feb 19 at 18:32
1

I do this, but have a whitelist of dotfiles, instead of including them all or having a blacklist. That is, my .gitignore ignores everything and then un-ignores only those files and directories I want to include.

Example "whitelisting" .gitignore:

*
!.vimrc
!.gitignore
!.otherdotfile

etc

There are many dotfiles it doesn't make much sense to keep versioned, like things that are cached files, things that are updated dynamically by graphical apps, and so on.

Also consider that your repository will contain private information in areas you don't expect, even if you exclude things like your SSH keys. Sharing this repository publicly is probably not a good idea.

Note also that if you have other git working trees in your home directory, you'll want the parent directories of those to be excluded from this repository so git doesn't start thinking they are sub-repositories or something.

0

Instead of using git, you may consider symlinking your dot files to a shared storage provider

  • dropbox
  • google drive
  • keybase

There is a tool called mackup that will automatically create these symlinks and has support for a wide variety of other applications. Works on Linux and Mac

https://github.com/lra/mackup

1
  • you can symlink to a git repo as well.
    – qwr
    Feb 17 at 4:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.