I'm in the middle of developing a solution to the same kind of problem.
Basically, my objective is a system allowing undo and redo with file-level granularity.
Starting with your question and working backwards...
- In order to compare to the default configuration, we have to store the originals of all those files somewhere first. Then we can produce what you want with something like...
DIFFDIR= ......
ARCDIR=./.archives # see below
function getlastarchive() {
... code to return last archived version ...
}
for FILE in /etc/*
do
ARCFILE="$(getlastarchive $FILE)"
diff $ARCDIR/$ARCFILE /etc/$FILE >$DIFFDIR/$FILE.diff
done
- To store the originals, I've chosen to adopt the convention of having a single
.archives subdirectory in any directory with an altered file. It's created as necessary by a file-archive script.
- If you only want one level of undo, you only need copy the unaltered file to the
.archives directory before it is changed.
- For unlimited-undo, we need a versioning scheme. An obvious choice is a datetime stamp appended to the name of the archived version. Something like...
Files: /etc/hosts
/etc/resolv.conf
Archived Versions: /etc/.archives/hosts.20121219015459
/etc/.archives/resolv.conf.20121219015459
- Instead, I'm using just an auto-calculated incremental version#, as in...
Files: /etc/hosts
/etc/resolv.conf
Archived Versions: /etc/.archives/hosts.00
/etc/.archives/resolv.00.conf
- The version# is before the extension since I also use this for edited versions of images which need their extensions (.jpg, .png, etc) intact in order to be detected properly by a lot of software. If a file has no extension, the version# is just appended to the end. The code to do this is more complex, but runs instantly so no problem. A case can be made for a number of other schemes but this works for me.
Hope this helps!