GIT-Home > tutorial
FAQ

GIT-Home tutorial

Abstract

The basic aim of git-home is to automate task when keeping a whole home directory in git repositories. The first motivation for git-home comes from Joey Hess' svnhome (formerly cvshome) and the second one from Jean-François Richard's git-home-history.

Warning

This is a very young project thus do not try to use it in a real environment unless you know what you are doing. You'd been warned. Then even if the git that wrote git(1) lauds the no-backup way of life, DO BACKUPS, or maybe you do not need backups then you shouldn't read this and use that tool.

Organization

I use several repositories to store my data. Some are common to all hosts, other are very specific to one (or more) host(s). Each repository's structure is exactly the same as if files were in my home directory. Then symlinks are made for easy access to them. Each repository is one sub-module of the super-project.

An example is better than so many words. Let's assume we only use bash(1). Both .bashrc and .bash_profile are common to all hosts. Both .bash_history and .bash_logout are specific to all hosts.

We need 2 repositories:

  • home-common: that contains .bashrc and .bash_profile
  • home-my.host: that contains .bash_history and .bash_logout

Replace my.host by your FQDN. This is not mandatory but clearer.

home-my.host is the super-project and refers home-common as a sub-module.

Preparation

I assume you wish to work in a sandbox ($HOME/g-h-test):

$ mkdir $HOME/g-h-test
$ cd $HOME/g-h-test

git-home would assume you are in your home directory. If not, you are assumed to work in a sandbox. Technically home directory and sandbox are exactly the same thing, except the sandbox is not you live home).

You need an other source of repositories located somewhere out of your home directory (/backup/git for example).

Let's create the 2 repositories:

$ git-home add-module -h /backup/git home-$(hostname --fqdn)
$ git-home add-module -t .gh  /backup/git home-common

Note

  • In a secure environment you want to store repositories to a fully secured host using by replacing /backup/git by user@securehost:/path/to/git in the URL switch.
  • if your module has already been initialized on an other host and you just want to add it in your home directory use the -g switch.
  • if you want to add a remote (external) git repository in your home (for example you want to participate to a project), then use the -e switch.

If you have a glance in /backup/git you would find the repositories:

$ ls /backup/git
home-common.git  home-my.host.git

In the sandbox, you can find some basic files used by git-home:

$ ls -a
.  ..  .gh  .git  .git-home  .gitignore  .gitstats
$ ls -a .gh
.  ..  home-common  .placeholder
$ ls -a .gh/home-common/
.  ..  .git  .gitignore  .gitstats

The .git-home file contains all informations useful for git-home modules:

$ cat .git-home
[git-home "__home__"]
    path = .
    url = /backup/git/home-my.host.git
    fix = 0
    push = 1
    commit-all = 0
    update = 1
    external = 0

[git-home "home-common"]
    path = .gh/home-common
    url = /backup/git/home-common.git
    fix = 1
    push = 1
    commit-all = 0
    update = 1
    external = 0

Note

  • I do store modules in the .gh directory just to only have a single entry point. Anyway it's up to you to change this location in the path variable.
  • The url is local to the host in this example but should be located somewhere else such as: user@host:/path/repositories/home-common/.git.
  • If fix value is different than 0 all files (by files you should understand not a directory) are linked to the sandbox directory within the same structure as in the module.
  • If push is set to 0 then the module would not be pushed when committing. This option is useful if you track remote git repositories and cannot write to them (the kernel source for example).
  • if commit-all is set to 1, everything would be committed regardless modification status. This option is useful for maildir.
  • if update is set to 0, the repository would not be updated with the update command. Source repositories are a good example of such needs.
  • if external is set to 1, files would not appear in ls-files command. Use this when participating to a project.
  • .placeholder files are a workaround to track modification done in directories where modules are stored. If a file foobar is created in .gh, then the status would say that .gh/foobar is untracked, instead of saying .gh had been modified.
  • .gitstats are permission information saved and restored through git hooks. Please note that gawk(1) must be present.

You can check tracked files:

$ git-home ls-files
__home__ : .gh/.placeholder
__home__ : .git-home
__home__ : .gitignore
__home__ : .gitstats
home-common : .gitignore
home-common : .gitstats

Usage

Let's take bash(1) configuration in example. Let's say you have:

  • .bashrc
  • .bash_profile
  • .bash_logout
  • .bash_history

You can add these files:

$ cp -L ~/.bashrc ~/.bash_profile ~/.bash_logout ~/.bash_history .

Now the files are in the sandbox but not tracked by git:

$ ls -a
.   .bash_history  .bash_profile  .gh   .git-home   .gitstats
..  .bash_logout   .bashrc        .git  .gitignore

$ git-home status

in submodule __home__:
        untracked: .bash_history
        untracked: .bash_logout
        untracked: .bash_profile
        untracked: .bashrc

Add them:

$ git add .bashrc .bash_profile .bash_logout .bash_history
$ git-home commit --message "Add bash configuration files"

Ok nice, but both .bash_profile and .bash_history is specific to each host, and other files are common to all hosts. So move them to home-common:

$ git-home move --to home-common .bash_profile .bashrc .bash_logout

If you list files in your directory you will notice that the 4 configuration move are now symlinked to home-common module's directory and ignored by git:

$ cat .gitignore
/.gh/home-common
/.bash_logout
/.bash_profile
/.bashrc
$ git-home ls-files
__home__ : .bash_history
__home__ : .bash_logout
__home__ : .bash_profile
__home__ : .bashrc
__home__ : .gh/.placeholder
__home__ : .git-home
__home__ : .gitignore
__home__ : .gitstats
home-common : .bash_logout
home-common : .bash_profile
home-common : .bashrc
home-common : .gitignore
home-common : .gitstats

Recovery

Imagine you have a fresh new home directory (host crash or any):

$ cd $HOME/g-h-test
$ rm -rf .??* *
$ ls -a
.  ..
$ git-home pull --url /backup/git/home-my.host
$ ls -a
.   .bash_history  .bash_profile  .git        .gitmodules
..  .bash_logout   .bashrc        .gitignore  .gh

As you can see sub-modules are automatically recovered and fixed.

See also

  • the GIT-Home FAQ.
  • all git man pages.