Automated Git Repository Monitoring: Cron Job Solution to Detect Uncommitted Changes


2 views

When managing server configurations in Git repositories, we need to ensure no unauthorized local modifications exist. While git status shows changes, we need an automated way to detect and alert about any modifications.

The simplest approach checks git status --porcelain output. The --porcelain flag provides parseable output:


#!/bin/bash
REPO_PATH="/path/to/your/repo"
cd $REPO_PATH

if [[ $(git status --porcelain) ]]; then
    echo "Changes detected in $REPO_PATH at $(date)" | mail -s "Git Changes Alert" admin@example.com
    git status # Include full status in logs
fi

For multiple repositories, create a script like this:


#!/bin/bash
REPOS=(
    "/etc/apache2"
    "/var/www/configs"
    "/opt/application/config"
)

for repo in "${REPOS[@]}"; do
    cd "$repo" || continue
    if [[ $(git status --porcelain) ]]; then
        SUBJECT="Unauthorized changes in $repo"
        BODY=$(git status)
        echo "$BODY" | mail -s "$SUBJECT" sysadmin-team@example.com
        logger -t git-monitor "$SUBJECT"
    fi
done

Add this to crontab (run every 15 minutes):


*/15 * * * * /usr/local/bin/git-change-monitor.sh >/dev/null 2>&1

For files that should be ignored (like local config overrides), ensure they're properly listed in .gitignore:


# Example .gitignore entries
/local-settings.ini
/temp/
*.swp

For more detailed tracking, use git diff:


#!/bin/bash
REPO="/path/to/repo"
DIFF_FILE="/tmp/git-diff-$(date +%Y%m%d).log"

cd $REPO
git diff > $DIFF_FILE

if [ -s $DIFF_FILE ]; then
    mail -s "Git Diff Report for $REPO" admin@example.com < $DIFF_FILE
fi

For Nagios/Icinga integration:


#!/bin/bash
REPO=$1
WARNING=1
CRITICAL=2

cd $REPO || exit $CRITICAL
CHANGES=$(git status --porcelain | wc -l)

if [ $CHANGES -ge $CRITICAL ]; then
    echo "CRITICAL: $CHANGES uncommitted changes"
    exit 2
elif [ $CHANGES -ge $WARNING ]; then
    echo "WARNING: $CHANGES uncommitted changes"
    exit 1
else
    echo "OK: No uncommitted changes"
    exit 0
fi

For better logging:


LOG_FILE="/var/log/git-monitor.log"
exec >> $LOG_FILE 2>&1

echo "=== Git Change Check $(date) ==="
git status --porcelain
echo "==============================="

Ensure the cron job runs with appropriate permissions and consider:

  • Using a dedicated monitoring account
  • Setting proper umask (0027 recommended)
  • Storing logs securely
  • Using GPG for email alerts containing sensitive data

When managing server configurations via Git repositories, unexpected local modifications can introduce configuration drift and deployment inconsistencies. The fundamental requirement is ensuring that no uncommitted changes exist in any repository directory, whether they're server configs, static websites, or web applications.


#!/bin/bash
REPO_PATH="/path/to/your/repo"
cd $REPO_PATH || exit 1

# Check for uncommitted changes
if ! git diff-index --quiet HEAD --; then
    echo "Uncommitted changes detected in $REPO_PATH"
    git status --porcelain
    exit 1
fi

# Check for untracked files (excluding .gitignore patterns)
if [ -n "$(git status --porcelain)" ]; then
    echo "Untracked files found in $REPO_PATH"
    git status --porcelain
    exit 1
fi

For environments with multiple repositories, we can create a wrapper script:


#!/bin/bash
REPO_LIST=(
    "/etc/apache2"
    "/var/www/html/config"
    "/opt/wordpress/wp-content"
)

for repo in "${REPO_LIST[@]}"; do
    if [ -d "$repo/.git" ]; then
        output=$(git -C "$repo" status --porcelain)
        if [ -n "$output" ]; then
            echo "ALERT: Changes detected in $repo"
            echo "$output"
            # Additional notification logic here
        fi
    fi
done

To run this check hourly, add to crontab:


0 * * * * /usr/local/bin/git_repo_monitor.sh >> /var/log/git_monitor.log 2>&1

For immediate alerts, integrate with common notification systems:


# Slack notification example
if [ -n "$output" ]; then
    curl -X POST -H 'Content-type: application/json' \
    --data "{\"text\":\"Git changes detected in $repo:\n$output\"}" \
    https://hooks.slack.com/services/TOKEN
fi
  • Add timestamp logging for audit trails
  • Implement lock files to prevent concurrent execution
  • Include proper error handling for non-Git directories
  • Add whitelist capability for intentional local changes

For Puppet environments, consider complementing this solution with:


# Puppet snippet to ensure no manual changes
file { '/etc/apache2':
  ensure  => 'directory',
  recurse => true,
  source  => 'puppet:///modules/apache/config',
  replace => true,
  force   => true,
}