I found this excellent blog post giving a nice example of incron useage at http://andrew.mcmillan.net.nz/blog/using_incron_to_autoversion_a_directory
Normally when I edit files in /etc, I am focused on achieving something now, and not on being able to undo it later. To this end I have written myself a script which will commit the contents of a directory (including adding new files and removing deleted ones) into a git repository, as follows:
#!/bin/sh
#
# Allow for debugging.
[ -n "$DEBUG" ] && set -o xtrace
cd $1
MESSAGE="Autocommit"
# Initialise the directory if it's not in Git currently
if [ ! -d .git ]; then
git init
MESSAGE="Initial commit"
fi
# Any files that aren't in the directory, but are in the repository can be removed.
for F in `git ls-tree HEAD | cut -f2`; do
[ -e "${F}" -o -L "${F}" ] || git rm "${F}"
done
# Any files that are in the directory, but aren't in the repository can be added
git add .
# And commit...
git commit -m "$MESSAGE"
So this script takes one parameter: the name of the directory where changes have (presumably) occurred, and just blindly commits everything there.
The magic glue, then, is the awesomeness that is ‘incron’ :-)
My first target is the ~/bin directory of all of those useful little scripts that I tend to randomly edit without nearly enough version control:
incrontab -e
home/andrew/bin IN_MODIFY,IN_DELETE,IN_CLOSE_WRITE,IN_MOVE \
/home/andrew/bin/commit-directory /home/andrew/bin 2>&1 | logger -t andrew-bin
With this, it means that whenever a file changes, is deleted from, moved into, or out of the directory we are monitoring, our commit-directory script is run.
Just for testing I delete some ancient files that should have been killed a few computers back. A quick ‘git status’ in the directory shows everything was committed nicely. I edit a file and make some quick changes. Once again, I go into gitk and can see all the history.
I sit back and ratchet my laziness another notch with a nice cup of tea, happy that, for now, at least, changes to my scripts are under revision control at last.
Outstanding Issues
Well, ok: it’s usable as is, but there are a few small things that could be improved:
- When I edit a file, the temporary swap file gets committed, and then deleted as the changes get committed
- If I make a whole lot of changes the script can fire multiple times, or even fire before some changes fully happened
- Maybe I want a shadow folder maintained and committed, rather than just this folder
- Perhaps it would be a good idea to push the repository elsewhere
I’ll keep monitoring in the real world if these are real annoyances, and whatever other annoyances I find, and maybe I’ll tweak that commit script a bit more – add a delay and/or some locking too it. I don’t think that adding some push would be too big a deal either, and I’d love to get suggestions from Git geeks as to how to do this more simply/reliably too.
2 responses to “Using incron to autocommit changes in a folder”
Interesting. Perhaps generating a .gitignore file after init could prevent those swap files from being committed?
Having played around some more, I have realized a MAJOR bug with incron .. its not recursive. This means that if you change /etc/apache/somethingelse it wont register it. It will only register things in /etc/ alone etc.