I have wrote already about this, now for an improved version some years later.
Nothing new under the sun: you have your /etc
under git (I
recommend doing that with etckeeper)
and you want to be reminded about uncommited changes if you leave the root
shell. This is handy for example when co-maintaining a server and everybody is
required to leave a trace after changing a file.
So you put something like this in your favourite root shell initialization file
(e.g. ~root/.bashrc
) and make sure the shell is invoked as
interactive/login (e.g. alias su='su -l'
)
git_functions="/usr/local/sbin/git-etc-common" # export GIT_* variables if [ -r "$git_functions" ]; then . "$git_functions" git_export_env fi case $- in *i*) # interactive shell check_uncommitted(){ ttyuser=$(ttyuser) logoutfile="$HOME/.logout-$ttyuser" # ttyuser is empty if the shell is not connected to a terminal # IOW, avoid forkbombing if the terminal has been closed if ! git_etc_status && [ ! -e "$logoutfile" ] && [ ! -z "$ttyuser" ]; then echo "Uncommitted changes to /etc. touch $logoutfile to force logout." # TODO show a list of files to commit? $SHELL -$- fi rm -f $logoutfile } trap check_uncommitted EXIT ;; esac
And git-etc-common
looks like this:
# source this file ttyuser() { cur_tty=$(tty) && echo $(stat -c "%U" $cur_tty) } # detect who's currently at the console git_export_env() { # TODO ask for name if GIT_AUTHOR_{NAME,EMAIL} is not set? ttyuser=$(ttyuser || echo "") if [ -n "$ttyuser" ]; then ttyuserhome=$(getent passwd "$ttyuser" | cut -d: -f6) conf=$ttyuserhome/.gitconfig fi if [ -z "$GIT_AUTHOR_NAME" ] && [ -z "$GIT_AUTHOR_EMAIL" ]; then if [ ! -z "$GIT_CONFIG_LOCAL" ] || [ ! -z "$GIT_CONFIG" ]; then export GIT_AUTHOR_NAME=$(git config --get user.name) export GIT_AUTHOR_EMAIL=$(git config --get user.email) elif [ -n "$conf" ] && [ -r "$conf" ]; then export GIT_AUTHOR_NAME=$(git config --file $conf --get user.name) export GIT_AUTHOR_EMAIL=$(git config --file $conf --get user.email) fi fi } git_etc_status() { changed=$(cd /etc && git ls-files --modified --deleted --others \ --exclude-per-directory=.gitignore \ --exclude-from=.git/info/exclude) ret=$? [ -z "$changed" ] && [ "$ret" -eq 0 ] return $? }
Exercise: generalise the functions above so you can have warnings about uncommited changes in generic repositories.