Put /etc Under Revision Control (with git)
UPDATE: There is a much easier way now:
sudo aptitude install etckeeper
There, now etc is under revision control and changes are automatically committed with a helpful message after you install new packages. Thanks for the tip, Marcelo! Read on for the original blog entry.
---
I put my /etc directory under revision control. I used git. It's awesome. Not that I think I'm going to wholesale copy my /etc from one machine to another, nor because I'm going to branch my /etc directory and spend weeks developing some cool new feature (whatever that would look like...) and then merge it back into the main branch. No, it's mostly because I like the idea of having the big "undo" option that having things under revision control provides. Having to commit changes and write check-in comments when I make changes helps me stay more organized too. It's never good when I go in willy-nilly to make a "quick change" to some configuration file.
I relied heavily on this blog entry for using git, and this blog entry for using mercurial (hg). I decided to go with git because mercurial quietly ignores symbolic links, and it seems like there are just a few important symbolic links in /etc. It also seems that git handles these just fine. Oh, and I didn't choose bzr or darcs mainly because they are slow, and because I want to get to know git better.
Here's how I did it (on Ubuntu Feisty Fawn, do all this as root):
First, initialize the repository:
cd /etc
git init-db
chmod og-rwx .git
The chmod is so non-root users can't go poking around in your repository. Next, ignore a few files:
cat > .gitignore << EOF
*~
*.dpkg-new
*.dpkg-old
blkid.tab(|.old)
mtab
# add other files if necessary, depends on your setup...
EOF
Do the initial commit:
git add .
git commit -a -m "initial import"
Set up a script to check in any change made when installing new packages. Put this in /etc/apt and call it something like, git-snapshot-script. Here is the script I use (UPDATED: Jul 11, 2007):
#!/bin/bash
set -e
caller=$(ps axww | mawk '/aptitude|apt-get/ {for (i=5; i<=NF ; i++) printf ("%s ",$i); printf ("\n") }' | head -1)
git-add .
# the || true is to make sure we don't error out because of the set -e
# above
STATUS="$(git status)" || true
if echo $STATUS | grep '\(Changed\|Update\)' > /dev/null ; then
echo "git-snapshot-script: found changed files"
echo $STATUS
git-commit -a -m "snapshot after: $caller"
else
echo "git-snapshot-script: no changes"
fi
echo "git-snapshot-script: done"
Then tell apt to run this script after it's invoked:
cat >> /etc/apt/apt.conf << EOF
DPkg {
Post-Invoke {"cd /etc ; ./apt/git-snapshot-script";};
}
EOF
chmod +x /etc/apt/git-snapshot-script
Now, check in the script and the change to apt.conf:
git add .
git commit -a -m "set up apt to track changes with git automatically"
And that should do it.
Comments
http://www.isisetup.ch/
http://huerlisi.wordpress.com/2006/08/26/howto-use-isisetup/
just trying to install the update-script for apt-get.
i made some smaller changes, the most significant should be:
caller=$(ps --no-header -p $PPID -o "%a")
instead of your pipeline.
might be faster, and sure is shorter.
feel free to use it if you like it.
btw: grep -q doesnt produce output -> no need for the i/o-redirection.
jakob
(sometimes i just forget being polite)
jakob
echo $STATUS | grep '\(Changed\|Update\)' > /dev/null
with
git status > /dev/null
as the former didnt work for me,
also the manpage said that the exit status of "git status" would be nonzero only with untracked changes.
jakob
http://www.rpath.com/rbuilder/
Would it have helped to post your changes as a patch!