Skip to content

Instantly share code, notes, and snippets.

@ofou
Last active January 18, 2025 21:00
Show Gist options
  • Save ofou/783034a293b68c5391da88def7cfb15d to your computer and use it in GitHub Desktop.
Save ofou/783034a293b68c5391da88def7cfb15d to your computer and use it in GitHub Desktop.
Fill your GitHub calendar with fake commits to confuse recruiters
#!/bin/bash
set -euo pipefail
# Validate we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo "Error: Not in a git repository"
exit 1
fi
# Function to validate date format
validate_date() {
local date="$1"
if [[ "$OSTYPE" == "darwin"* ]]; then
if ! date -j -f "%Y-%m-%d" "$date" >/dev/null 2>&1; then
echo "Error: Invalid date format for '$date'. Please use YYYY-MM-DD"
exit 1
fi
else
if ! date -d "$date" >/dev/null 2>&1; then
echo "Error: Invalid date format for '$date'. Please use YYYY-MM-DD"
exit 1
fi
fi
}
# Function to get current timezone offset for Chile
get_chile_timezone() {
# Use system's timezone information to determine current offset
TZ="America/Santiago" date +%z
}
# Function to generate random time between 8:00 and 20:00 (Chilean work hours)
generate_random_time() {
# Use /dev/urandom for better randomness
hour=$((8 + $(od -An -N2 -i /dev/urandom) % 13))
minute=$(($(od -An -N2 -i /dev/urandom) % 60))
second=$(($(od -An -N2 -i /dev/urandom) % 60))
tz_offset=$(get_chile_timezone)
printf "%02d:%02d:%02d %s" $hour $minute $second "$tz_offset"
}
# Function to increment date (macOS compatible)
increment_date() {
local date="$1"
if [[ "$OSTYPE" == "darwin"* ]]; then
date -v+1d -j -f "%Y-%m-%d" "$date" "+%Y-%m-%d"
else
date -d "$date + 1 day" "+%Y-%m-%d"
fi
}
# Function to compare dates (returns 0 if date1 <= date2)
compare_dates() {
local date1="$1"
local date2="$2"
if [[ "$OSTYPE" == "darwin"* ]]; then
local ts1=$(date -j -f "%Y-%m-%d" "$date1" +%s)
local ts2=$(date -j -f "%Y-%m-%d" "$date2" +%s)
else
local ts1=$(date -d "$date1" +%s)
local ts2=$(date -d "$date2" +%s)
fi
[[ $ts1 -le $ts2 ]] && return 0 || return 1
}
# Function to make commits for a specific date
make_commits() {
local date="$1"
# Use modulo on a larger random number for better distribution
local commits_to_make=$((1 + $(od -An -N2 -i /dev/urandom) % 5))
echo "Making $commits_to_make commits for $date"
for ((i = 1; i <= commits_to_make; i++)); do
commit_time=$(generate_random_time)
commit_message="Commit $i of $commits_to_make on $date at $commit_time"
if ! GIT_AUTHOR_DATE="$date $commit_time" \
GIT_COMMITTER_DATE="$date $commit_time" \
git commit --allow-empty -m "$commit_message"; then
echo "Error: Failed to create commit for $date"
exit 1
fi
done
}
# Main script
start_date="2017-12-01"
end_date=$(date +"%Y-%m-%d")
# Validate dates
validate_date "$start_date"
validate_date "$end_date"
# Check if end_date is after start_date
if ! compare_dates "$start_date" "$end_date"; then
echo "Error: End date must be after start date"
exit 1
fi
# Ensure we're in the right branch and not in detached HEAD
current_branch=$(git rev-parse --abbrev-ref HEAD || echo "HEAD")
if [ "$current_branch" = "HEAD" ]; then
echo "Error: In detached HEAD state"
exit 1
elif [ "$current_branch" != "main" ]; then
echo "Warning: Not on main branch. Currently on: $current_branch"
read -p "Continue anyway? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
# Print script configuration
echo "Configuration:"
echo "- Time range: 8:00 AM to 8:00 PM (Chile Time)"
echo "- Date range: $start_date to $end_date"
echo "- Commits per day: 1-5 (at least 1)"
echo "- Timezone: Chile Time (auto-adjusted for DST)"
echo
# Create a temporary file with restricted permissions to store dates with commits
temp_file=$(mktemp)
chmod 600 "$temp_file"
trap 'rm -f "$temp_file"' EXIT # Ensure temp file is removed on script exit
# Get existing commit dates
if ! git log --since="$start_date" --until="$end_date" --date=short --pretty=format:"%ad" | sort -u > "$temp_file"; then
echo "Error: Failed to retrieve git log"
exit 1
fi
# Find and process dates without commits
echo "Finding dates without commits..."
missing_dates=()
current_date="$start_date"
while compare_dates "$current_date" "$end_date"; do
if ! grep -q "^$current_date$" "$temp_file"; then
missing_dates+=("$current_date")
fi
current_date=$(increment_date "$current_date")
done
# Report the number of dates that need commits
total_missing="${#missing_dates[@]}"
if [ "$total_missing" -eq 0 ]; then
echo "No missing dates found. All days have commits."
exit 0
fi
echo "Found $total_missing days without commits. Starting to add commits..."
# Process each missing date
for date in "${missing_dates[@]}"; do
make_commits "$date"
done
# Push changes with error handling
echo "Pushing changes to origin..."
if ! git push origin "$current_branch"; then
echo "Error: Failed to push changes to origin"
exit 1
fi
echo "Successfully completed all operations!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment