loading . . . version control of /etc with git and git-store-meta This blog post describes how to use git together with git-store-meta to version control config files in unix/linux `/etc` directories
## Intro and backstory
I have used version control on the config files in my unix/linux home directories, since the early 90-ies, and used version control on config files in the `/etc` directory tree of my linux boxes, since I first started setting up linux boxes in the mid-late ninties.
Initially I used RCS both for home directory version control.
But while dotfile version control in my home directories transitioned from RCS controlled files in home directories on various computers, to a shared CVS repository used in all home directories, which was later transformed from CVS to SVN, until it was finally converted from SVN to git in May 2011, I continued to use RCS versioning for files in `/etc` directories on various computers.
The reason for staying with RCS version control for files in `/etc` directories was git’s lack of metadata storage, in particular user and group membership and user and group access to files, as well as limiting public access to files.
To some extent this was handled by RCS (e.g. by giving the version control file the same owner and group membership as the target file), but it always required a bit of manual fiddeling when things broke.
This blog post explains how to version control `/etc` directories by combining git with git-store-meta to preserve user and group membership of the versioned files as well as access privileges to the files and even preserve the time of the last change to the files.
## How to set up version control of /etc directories
The first thing to do is to install the prerequisites. On a debian (or ubuntu) system that could be done by doing the following commands as root:
__
apt update
apt install git perl
Clone the git-store-meta git repository (this can be done by any user. Doesn’t need root privileges):
__
cd /tmp
git clone https://github.com/danny0838/git-store-meta.git
Then create an empty git repository in the /etc directory. Do the following commands as root
__
cd /etc
git --init
Rename the default branch (typically `master` or `main`) to a branch name reflecting the hostname of the machine containing the `/etc` directory being versioned, e.g. if the host is named `doohan`, the branch should be named something like `etc-doohan`:
__
git branch -M master etc-doohan
Add an `/etc/.gitignore` file ignoring everything (which means that version control of new files has to be done by forcibly adding the files with “`git add -f`“):
__
cd /etc
echo "*" >.gitignore
git add -f .gitignore
git commit -m "Ignore all unknown files found in /etc and subdirectories"
Copy git-store-meta into the git repository of `/etc/.git` and create an initial metadata file with the necessary fields for controlling and versioning ownership and access of files in `/etc`
__
cd /etc
cp /tmp/git-store-meta/git-store-meta.pl .git/hooks/
.git/hooks/git-store-meta.pl --store -f user,group,mode,mtime,atime
git add -f .git_store_meta
git commit -m "Add git-store-meta metadata file"
Set up the git-store-metadata hooks which will update `.git_store_meta` on commits and add `.git_store_meta` to the commit and will set metadata values on files when updating a branch:
__
cd /etc
.git/hooks/git-store-meta.pl --install
Add a remote (make sure it is not a public repository) and push the branch:
__
git remote add origin [email protected]:~exampleuser/etc-config
git push -u origin HEAD
## Using git version control of /etc for a new file
In the future, when doing changes to a new config file, do the following:
1. Add the current version of the file to git (the “-f” flag is necessary because of the .gitignore file excluding all files by default)
__
cd /etc
git add -f dnsmasq.conf
git commit -m "Add version of dnsmasq.con distributed by debian 13 trixie"
2. Make local modifications to the configuration files and commit the changes and push the branch to the remote for safekeeping
__
cd /etc
git add dnsmasq.conf
git commit -m "Adapt dnsmasq to home network"
git push
(note that the “-f” flag isn’t necessary on “git add” here)
## Preserving history from RCS files
When adding git versioning to `/etc` I preserved the history from existing the RCS version control files on the various computers, by
1. Creating a CVS repository based on RCS files from `/etc`
__
mkdir /tmp/etc-cvs
cd /etc
find . -name RCS | xargs tar cf - | (cd /tmp/etc-cvs; tar xf -)
2. installed cvs-fast-export on the computer where the conversion was run (must be done by root or sudo)
__
apt install cvs-fast-export
3. exported the cvs repo to a fast-import file and then imported that file into an empty git repository
__
cd /tmp/etc-cvs/
find -type f | cvs-fast-export >/tmp/etc.dump
mkdir /tmp/etc-config
git init
git fast-import </tmp/etc.dump
git branch -m master etc-doohan
git config user.name "root doohan"
4. moved the new .git directory to `/etc`
__
cd /etc
mv /tmp/etc-config/.git .
5. then added git-store-meta metadata versioning and pushed the branch to a remote, as outlined in the previous section
## Closing words
I also added git-store-meta metadata versionining to git versioning of my various home directories, which removed the need to manually do “`chmod go-rwx`” on files that should be unaccessible to others after switching branches or merging branches.
When I first looked into using git for `/etc` version control, back in 2018, I had planned to use a tool named metastore to store the metadata of `/etc` directory.
However, metastore proved to be unsatisfactory for adding metadata support to git:
1. metastore added metadata for all files in the `/etc` directories and subdirectories, not just the files version controlled by git, which caused git updates and commits to become very slow
2. metastore metadata files were binary, which isn’t optimal for git versioning of the files or visual inspection of commits
3. the last commit was from February 1 2023, which isn’t too long ago, but the last release of metastore was version 1.1.2 on January 6 2018, which _is_ a long time ago
In contrast git-store-meta has can be used from its main HEAD, rather than a specific release, was easy to install, only tracked metadata for files in git in a human readable CSV file, and worked well (i.e. does what it is supposed to do without breaking anything in the process).
### Share this:
* Click to share on X (Opens in new window) X
* Click to share on Facebook (Opens in new window) Facebook
* Click to share on LinkedIn (Opens in new window) LinkedIn
*
Like Loading...
### _Related_ https://steinar.bang.priv.no/2025/09/16/version-control-of-etc-with-git-and-git-store-meta/