7 Git tips for managing your home directory

Here is how I set up Git to manage my home directory.
70 readers like this.
Houses in a row

27707 via Pixabay, CC0. Modified by Jen Wike Huger.

I have several computers. I've got a laptop at work, a workstation at home, a Raspberry Pi (or four), a Pocket CHIP, a Chromebook running various forms of Linux, and so on. I used to set up my user environment on each computer by more or less following the same steps, and I often told myself that I enjoyed that each one was slightly unique. For instance, I use Bash aliases more often at work than at home, and the helper scripts I use at home might not be useful at work.

Over the years, my expectations across devices began to merge, and I'd forget that a feature I'd built up on my home machine wasn't ported over to my work machine, and so on. I needed a way to standardize my customized toolkit. The answer, to my surprise, was Git.

Git is version-tracker software. It's famously used by the biggest and smallest open source projects and even by the largest proprietary software companies. But it was designed for source code—not a home directory filled with music and video files, games, photos, and so on. I'd heard of people managing their home directory with Git, but I assumed that it was a fringe experiment done by coders, not real-life users like me.

Managing my home directory with Git has been an evolving process. I've learned and adapted along the way. Here are the things you might want to keep in mind should you decide to manage your home directory with Git.

1. Text and binary locations

When managed by Git, your home directory becomes something of a no-man 's-land for everything but configuration files. That means when you open your home directory, you should see nothing but a list of predictable directories. There shouldn't be any stray photos or LibreOffice documents, and no "I'll put this here for just a minute" files.

The reason for this is simple: when you manage your home directory with Git, everything in your home directory that's not being committed becomes noise. Every time you do a git status, you'll have to scroll past any file that Git isn't tracking, so it's vital that you keep those files in subdirectories (which you add to your .gitignore file).

Many Linux distributions provide a set of default directories:

  • Documents
  • Downloads
  • Music
  • Photos
  • Templates
  • Videos

You can create more if you need them. For instance, I differentiate between the music I create (Music) and the music I purchase to listen to (Albums). Likewise, my Cinema directory contains movies by other people, while Videos contains video files I need for editing. In other words, my default directory structure has more granularity than the default set provided by most Linux distributions, but I think there's a benefit to that. Without a directory structure that works for you, you'll be more likely to just stash stuff in your home directory, for lack of a better place for it, so think ahead and plan out directories that work for you. You can always add more later, but it's best to start strong.

2. Setting up your very best .gitignore

Once you've cleaned up your home directory, you can instantiate it as a Git repository as usual:

$ cd
$ git init .

Your Git repository contains nothing yet, so everything in your home directory is untracked. Your first job is to sift through the list of untracked files and determine what you want to remain untracked. To see untracked files:

$ git status
  .AndroidStudio3.2/
  .FBReader/
  .ICEauthority
  .Xauthority
  .Xdefaults
  .android/
  .arduino15/
  .ash_history
[...]

Depending on how long you've been using your home directory, this list may be long. The easy ones are the directories you decided on in the first step. By adding these to a hidden file called .gitignore, you tell Git to stop listing them as untracked files and never to track them:

$ \ls -lg | grep ^d | awk '{print $8}' >> ~/.gitignore

With that done, go through the remaining untracked files shown by git status and determine whether any other files warrant exclusion. This process helped me discover several stale old configuration files and directories, which I ended up trashing altogether, but also some that were very specific to one computer. I was fairly strict here because many configuration files do better when they're auto-generated. For instance, I never commit my KDE configuration files because many contain information like recent documents and other elements that don't exist on another machine.

I track my personalized configuration files, scripts and utilities, profile and Bash configs, and cheat sheets and other snippets of text that I refer to frequently. If the software is mostly responsible for maintaining a file, I ignore it. And when in doubt about a file, I ignore it. You can always un-ignore it later (by removing it from your .gitignore file).

3. Get to know your data

I'm on KDE, so I use the open source scanner Filelight to get an overview of my data. Filelight gives you a chart that lets you see the size of each directory. You can navigate through each directory to see what's taking up all the space and then backtrack to investigate elsewhere. It's a fascinating view of your system, and it lets you see your files in a completely new light.

Use Filelight or a similar utility to find unexpected caches of data you don't need to commit. For instance, the KDE file indexer (Baloo) generates quite a lot of data specific to its host that I definitely wouldn't want to transport to another computer.

4. Don't ignore your .gitignore file

On some projects, I tell Git to ignore my .gitignore file because what I want to ignore is sometimes specific to my working directory, and I don't presume other developers on the same project need me to tell them what their .gitignore file ought to look like. Because my home directory is for my use only, I do not ignore my home's .gitignore file. I commit it along with other important files, so it's inherited across all of my systems. And of course, all of my systems are identical from the home directory's viewpoint: they have the same set of default folders and many of the same hidden configuration files.

5. Don't fear the binary

I put my system through weeks and weeks of rigorous testing, convinced that it was never wise to commit binary files to Git. I tried GPG encrypted password files, I tried LibreOffice documents, JPEGs, PNGs, and more. I even had a script that unarchived LibreOffice files before adding them to Git, extracted the XML inside so I could commit just the XML, and then rebuilt the LibreOffice file so that I could work on it within LibreOffice. My theory was that committing XML would render a smaller Git repository than a ZIP file (which is all a LibreOffice document really is).

To my great surprise, I found that committing a few binary files every now and then did not substantially increase the size of my Git repository. I've worked with Git long enough to know that if I were to commit gigabytes of binary data, my repository would suffer, but the occasional binary file isn't an emergency to avoid at all costs.

Armed with this new confidence, I add font OTF and TTF files to my standard home repo, my .face file for GDM, and other incidental minor binary blobs. Don't overthink it, don't waste time trying to avoid it; just commit it.

6. Use a private repo

Don't commit your home directory to a public Git repository, even if the host offers private accounts. If you're like me, you have SSH keys and GPG keychains and GPG-encrypted files that ought not end up on anybody's server but my own.

I run a local Git server on a Raspberry Pi (it's easier than you think), so I can update any computer any time I'm home. I'm a remote worker, so that's usually good enough, but I can also reach the computer when traveling over my VPN.

7. Remember to push

The thing about Git is that it only pushes changes to your server when you tell it to. If you're a longtime Git user, this process is probably natural to you. For new users who might be accustomed to the automatic synchronization in Nextcloud or Syncthing, this may take some getting used to.

Git at home

Managing my common files with Git hasn't just made life more convenient across devices. Knowing that I have a full history for all my configurations and utility scripts encourages me to try out new ideas because it's always easy to roll back my changes if they turn out to be bad ideas. Git has rescued me from an ill-advised umask setting in .bashrc, a poorly executed late-night addition to my package management script, and an it-seemed-like-a-cool-idea-at-the-time change of my rxvt color scheme—and probably a few other mistakes in my past. Try Git in your home because a home that commits together merges together.

What to read next
Tags
Seth Kenlon
Seth Kenlon is a UNIX geek, free culture advocate, independent multimedia artist, and D&D nerd. He has worked in the film and computing industry, often at the same time.

6 Comments

For me, personally, the best way of managing files (mainly configuration files) in my home directory is using git bare repository and an alias in the shell. This way way I do not need to worry about writing an extensive '.gitignore' file - I just 'git add' all the files I want.
Good points of reference are this article by Atlassian - https://www.atlassian.com/git/tutorials/dotfiles

If you want to ignore files specific to your set up, then use .git/info/exclude

I like this idea, but actually don't get the benefits of it.

Personally, I'm using rsnapshot for backups. To find out possible differences in particular files I can use Meld/KDiff3/BeyondCompare 3 on the different snapshot directories. In this case GIT would be more helpful to check a "history" of a file.

You could "split" up your GIT repository in different folders, if you want. I assume on some folders you are working far more often then on others. In which time cycle you would otherwise commit all your changes?

I use this as a way to keep my laptop and desktop more or less in sync, with the additional benefit that I can quickly "image" a Pi or any given test system. There are other ways to do this, and in fact for years I quite happily used nothing. For now, though, I find myself doing similar activities on a variety of systems, and so I find it useful to be able to do a Git pull and inherit all the latest config changes I made on another system.

In reply to by Armakuni

Your command to list directories to .gitignore ignores directories with spaces. Something like this might be better `\ls -1d ~/*/` but haven't experimented with the result in .gitignore. Obviously not a huge issue :)

I like the concept, and for your setup (one desktop and one laptop) this might make it worthwhile.

I have been toying with using a similar approach for keeping .bashrc, .bash_profile, ~/.bashrc.d/, in sync though. And use a script to hardlink or symlink those files/dirs into $HOME. Some good ideas here though, thanks for the article.

Nice article. Another approach which seems to have gained some popularity over the last few years is to keep your dotfiles in one or more git repositories which are isolated from $HOME, and then symlink them into $HOME using GNU Stow. You can find more details linked from the Stow homepage. I've been doing this for many years and it works great for me. Full disclaimer: I maintain GNU Stow so I'm probably biased towards this approach.

Creative Commons LicenseThis work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.