Is it bad practice to git init in the $home directory to keep track of dot files?

6,288

Solution 1

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.

Solution 2

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 

Solution 3

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

Solution 4

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.

Solution 5

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.

Share:
6,288

Related videos on Youtube

Sebastian Nielsen
Author by

Sebastian Nielsen

Updated on September 18, 2022

Comments

  • Sebastian Nielsen
    Sebastian Nielsen over 1 year

    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.

    • Olaf Dietsche
      Olaf Dietsche about 3 years
      Be careful what you sync to github, e.g. .ssh, .gnupg, etc.
    • preferred_anon
      preferred_anon about 3 years
      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!
    • Capi Etheriel
      Capi Etheriel about 3 years
      I'm appalled that several (most) of the responses do not answer the question of whether it is a good practice.
    • nafmo
      nafmo about 3 years
      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).
  • Sebastian Nielsen
    Sebastian Nielsen about 3 years
    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.
  • marcelm
    marcelm about 3 years
    +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)
  • Capi Etheriel
    Capi Etheriel about 3 years
    Nice! I've been using homesick but looking to drop the ruby dependency.
  • Capi Etheriel
    Capi Etheriel about 3 years
    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.
  • ShadowRunner
    ShadowRunner about 3 years
    will this not include : . (current dir) ? .ssh (ssh directory, containing potentially private keys) ?
  • user253751
    user253751 about 3 years
    @SebastianNielsen It's not a requirement. You can call them whatever you like.
  • neves
    neves about 3 years
    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
  • ShadowRunner
    ShadowRunner about 3 years
    Thx for the answer. Maybe add an edit to show how to do that, as it may save many people stumbling on the solution
  • Ravexina
    Ravexina about 3 years
    @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.
  • Levente
    Levente about 3 years
    @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.
  • qwr
    qwr about 3 years
    you can symlink to a git repo as well.
  • Capi Etheriel
    Capi Etheriel about 3 years
    it seems like you don't actually run git init in the home folder, which is what OP asked about.
  • l0b0
    l0b0 about 3 years
    They asked whether that was a good idea. I've answered that.
  • DharmaTurtle
    DharmaTurtle over 2 years
    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.)
  • DharmaTurtle
    DharmaTurtle over 2 years
    A related answer on SO. There, I note that this technique won't work with many git UI/porcelain.