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.

  • 24
    Be careful what you sync to github, e.g. .ssh, .gnupg, etc. Feb 14, 2021 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, 2021 at 19:28
  • 4
    I'm appalled that several (most) of the responses do not answer the question of whether it is a good practice. Feb 19, 2021 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, 2021 at 14:39

9 Answers 9


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


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.

  • 9
    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, 2021 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, 2021 at 9:16
  • 1
    @SebastianNielsen It's not a requirement. You can call them whatever you like.
    – user253751
    Feb 15, 2021 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, 2021 at 0:17
  • A related answer on SO. There, I note that this technique won't work with many git UI/porcelain. Dec 19, 2021 at 19:13

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)
  • 3
    will this not include : . (current dir) ? .ssh (ssh directory, containing potentially private keys) ? Feb 15, 2021 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, 2021 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, 2021 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, 2021 at 9:39

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 ;-)

  • 2
    chezmoi does all of the above if you set your config to mode = "symlink". You can also configure it to use plain files and not symlinks. (You will need to set up a cronjob, but "checking" comes for free.) Dec 19, 2021 at 16:47

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.
  • 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, 2021 at 0:47

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.

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

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.

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

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:



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.


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


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

I don't like to have the home directory git repository, simply because you run into weirdness with sub-directories of home also being git repos.

After playing with this idea I now selectively sync what I want sync'd into a project directory and use that as a place to make backups and restore from. That way there isn't a .git in the home directory.

Make a working directory wherever, and then place a backup.sh in it that looks something like this with any modifications you want (i.e. you may want to add your documents folder or whatnot)


# = rsync stuff =
# ===============
# -a, --archive
# This is equivalent to -rlptgoD. 
# It is a quick way of saying you want recursion and want to preserve almost everything (with -H being a notable omission).

rsync --mkpath -a ~/.icons ./home_archive
rsync --mkpath -a ~/.themes ./home_archive

rsync --mkpath -a ~/Pictures/1079333.png ./home_archive/Pictures/
rsync --mkpath -a ~/.config/xfce4 ./home_archive/config

rsync --mkpath -a ~/bin ./home_archive

rsync --mkpath -a ~/.profile ./home_archive
rsync --mkpath -a ~/.Xmodmap ./home_archive
rsync --mkpath -a ~/.zshrc ./home_archive

This will then sync what you want syncing into home_archive. To restore, from the parent directory of home_archive, use the command

rsync --mkpath -a home_archive/* ~

Downside is that you need enough disc space to make the clone, but it keeps things much cleaner.

If you want to use a more carpet bombing approach and then exclude things like with a gitignore, then rsync can be used like that also . .

rsync -a --exclude '*.txt' --exclude 'dir3' --exclude 'dir4' sourcedir/ destinationdir/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .