There is a handy trick I use to keeping track of changes made to the configuration of a system, and one which I sometimes neglect in my rush. It has changed a bit over the years, and I never did figure out how to do it on AIX, where unlike other UN*X versions, the configuration was stored in a database called Object Data Manager, or simply ODM. The trick is track the changes using some form of version control. At first, this was Revision Control System, or RCS, and from what I recall from those days, to say that it was "far from ideal" was an understatement. Then, I moved to Concurrent Versions System, or CVS. Again, not the best. But then along came git in 2005, which due to its distributed nature, creates a subdirectory named .git in the directory under control. This greatly simplified things, and my idea began to bloom.
I don't track all my configuration using it, as vast portions of the files under /etc are almost never changed manually from the day I install the system to the day I remove it from service. And then, there is the issue of OS update, where files like /etc/redhat-release are changed, and I am not sure that tracking those changes is even remotely necessary. But then, there are other directories, where such changes do make sense. Examples of these on my systems include places such as /etc/cobbler, /var/named and today's favorite, /etc/httpd (or /etc/nginx for those who use nginx instead of Apache as your web server. When I rebuilt my main bastion host a couple of years ago, one of the first things I did was to go into that directory, and run these commands:
# git init
# git add -A
# git commit -m 'Initial versions'This captured a snapshot of this directory, outside of those places which exist as symlinks, such as the log directory and others. And then, each change I made, I tried to remember to go back to the directory, do a git add to add the changed file for committing, and a git commit to actually track that change. But, I have not been consistent about it, often when rushed while doing something else. But tonight, I am fixing that, and thankfully, I remember these changes, since they are thankfully few and self-explanatory. But I want the date of the commit to reflect the date of the change, and have the commits in order. For this, I am relying on a few tricks, which I figured I would share. The first is the command to list the changed files in chronological order, and just the files, and not the symlinks. For that, the command is this:
# ls --full-time -t $(git ls-files -mo | grep -vE '^(logs|modules|run|state)$')That gets me a nice, in order list of all the modified or untracked files from newest to oldest. From there, I am doing commands like this one:
# export GIT_AUTHOR_DATE="2026-02-19 01:35:02"
# export GIT_COMMITTER_DATE="2026-02-19 01:35:02"
# git commit --date="2026-02-19 01:35:02" some-file-pathNote that the export is necessary, otherwise the date will still show up as today.
Of course, since I have to do this several times, and may need to to it again in the future, I will create a little shell script for it. Since git sees files which start with git- in your path as extensions, I did (as I write this), and called this script git-past-commit. Now, the command is git past-commit some-file-path, and it uses the stat command to get the modification date, sets the variables, and runs the git commit on that file. The file is simple, and looks like this:
#/bin/sh
set -e
export GIT_AUTHOR_DATE=$(stat -c %y $1)
export GIT_COMMITTER_DATE=$(stat -c %y $1)
git add $1
git commit $1The set -e just says that if any of these exit with a non-zero status, stop executing the script. The -c %y to the stat command says to output the modification time in a human readable format, which git accepts when doing the commit. And finally, the git add makes sure that new files as well as old files are handled by the command, instead of being unknown to git. I only wrote this to handle a single file, since multiple files will almost certainly represent multiple changes for different reasons.
Just throw in git gui to allow me to see what the changes were, and setting EDITOR to "emacs", and I am set. Why emacs, you ask? Not to restart the almost religious war of "emacs vs. vim vs. ....", but I like to be able to have multiple windows, potentially for multiple things like the commit message and the actual file, or the ability to pull up a man page. Yes, vim can do it, but gone are the days when I regularly was forced to use multiple editors (I don't miss running ed on a DEC LA-120 DECwriter console, since it was a combination keyboard and printer). And I started using emacs (mumble) years ago, and so... while I loved vi when I got it over editors like ed (thanks to Bill Joy), when emacs became available, I favored it even if it meant compiling it myself. But I digress.
Now, on to getting these changes committed, before I finally double check things which will be a part of my next article, about a problems I have been debugging... I think I finally have that problem figured out.
Comments
A quick comment about the `git ls-files command` I used above.
Even adding the logs, modules, run and state symlinks to a
.gitignorefile does not result in those files being filtered out of the output ofgit ls-files. Instead of just the-moargument, you need to add the argument--exclude-standardto the command line to do away with thegrep. So now, that command line reads:And just in-case it is not clear, the
#is the command line prompt to show I am doing this as root, since it takes administrator privileges to maintain files under/etc. But don't worry...I do my normal work as my non-root user, and just work directly as root, rather than usingsudufor command after command. 😁Oh, and an odd bit of history I just wanted to mention...
I mentioned the LA-120 DECWriter. Few realize that we used such a device on the Big Ear radio telescope at Ohio State Radio Observatory to produce the printouts of what we were seeing, such as the Wow! signal, known by the comment my friend and fellow volunteer Dr. Jerry Ehman when he was reviewing the printouts a few days later back in 1977. The fact that we used such a device is part of what contributed to our not knowing which horn in which the signal was detected, and thus the ambiguity of the exact location of the signal to two separate areas of the sky, a problem we later worked around with the trick of overprinting the characters for one of the horns with another character, a dash (
-) or underscore (_), if I remember correctly, but I cannot remember which after all this time.