Bup repositories and Git

In last weeks post I quickly when through setting up Bup. Internally Bup stores backup data in a Git repository, this is why bup init references Git:

$ bup -d /var/bup init
Initialized empty Git repository in /var/bup/

One of the nice things about this is you can use Git commands directly on the Bup repo. There are a few caveats to this, if you want to learn more I would recommend having a read of the Bup design readme.

Listing backups

To list the name of available backups, you would normally run bup ls:

$ bup -d /var/bup ls
etc-backup

Internally each name is a branch in the repository, consequently you can also use git branch to get the same output:

$ git --git-dir=/var/bup branch
  etc-backup

Each named backup will have one or more points in time which can be displayed with bup ls:

$ bup -d /var/bup ls etc-backup
2018-08-03-180408@  2018-08-03-182654@  2018-08-03-182852@  latest@

Each point in time is stored as a commit, therefore git log can also be used to list them:

$ git --git-dir=/var/bup log etc-backup --format='%h: %ci'
84f04f8: 2018-08-03 17:28:52 +0000
7ddec50: 2018-08-03 17:26:54 +0000
0e9d160: 2018-08-03 17:04:08 +0000

Comparing backups

Once you can list the commit hashes for each backup, git diff can be used two compare two backups:

$ git --git-dir /var/bup diff --stat 84f04f8 7ddec50
etc/.bupm   | Bin 4005 -> 3955 bytes
etc/example |   1 -
2 files changed, 1 deletion(-)

Restoring files with Git

git show can be used to copy an individual file from a Bup repository:

$ git --git-dir=/var/bup show etc-backup:etc/hostname > /tmp/hostname
$ cat /tmp/hostname
bup.example.com

Note: restoring a file using git show will not restore any of the metadata associated with the file!

As well as restoring individual files, it's also possible to use git clone to restore an entire backup:

$ git clone --branch etc-backup /var/bup /tmp/bup-etc-backup
Cloning into '/tmp/bup-etc-backup'...
done.

The command above will create a working directory in /tmp/bup-etc-backup and checkout the etc-backup branch into the working directory. Like using git show, restoring files by cloning a Bup repo will not restore file metadata, however you will probably notice the .bupm metadata files in the working directory:

$ find /tmp/bup-etc-backup/etc/X11/
/tmp/bup-etc-backup/etc/X11/
/tmp/bup-etc-backup/etc/X11/.bupm
/tmp/bup-etc-backup/etc/X11/xkb
/tmp/bup-etc-backup/etc/X11/xkb/.bupm

It's also worth noting that cloning a Bup repo is not very space efficient. This shouldn't be a problem for small repos, however it's worth keeping in mind if you're working with large Bup repos:

$ du -sh /var/bup/
1016K   /var/bup/
$ du -sh /tmp/bup-etc-backup/
5.1M    /tmp/bup-etc-backup/

Pushing to a remote repository

It's also possible to push backups to a remote Bup repository:

$ ssh remotehost bup -d /var/bup-remote init
Initialized empty Git repository in /var/bup-remote/
$ git --git-dir=/var/bup remote add bup-remote ssh://remotehost/var/bup-remote
$ git --git-dir=/var/bup push bup-remote --all
Counting objects: 1175, done.
Compressing objects: 100% (854/854), done.
Writing objects: 100% (1175/1175), 554.28 KiB | 0 bytes/s, done.
Total 1175 (delta 3), reused 1172 (delta 0)
To ssh://remotehost/var/bup-remote
 * [new branch]      etc-backup -> etc-backup

This is great if you want to copy backups via SSH to a remote host.