Skip to content

Commit 8dc2599

Browse files
committed
- update_commit_dates.sh"
1 parent 756e381 commit 8dc2599

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

update_commit_dates.sh

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
#!/bin/bash
2+
3+
# Script to update author and commit dates for Git commits
4+
# Sets dates to N days ago with random times from two periods: 5:00 AM - 8:00 AM or 10:00 PM - midnight
5+
# Each commit randomly chooses one of these two time periods
6+
#
7+
# Usage: ./update_commit_dates.sh [number_of_commits] [days_ago] [time_period]
8+
#
9+
# Examples:
10+
# ./update_commit_dates.sh # Uses defaults (3 commits, 1 day ago, evening period)
11+
# ./update_commit_dates.sh 30 # Changes the last 30 commits to 1 day ago, evening period
12+
# ./update_commit_dates.sh 10 7 # Changes the last 10 commits to 7 days ago, evening period
13+
# ./update_commit_dates.sh 10 7 morning # Uses morning period (5h-8h)
14+
# ./update_commit_dates.sh 10 7 evening # Uses evening period (22h-midnight)
15+
# ./update_commit_dates.sh 10 7 both # Randomly chooses between both periods
16+
17+
# Default values
18+
DEFAULT_NUM_COMMITS=3
19+
DEFAULT_DAYS_AGO=1
20+
DEFAULT_TIME_PERIOD="evening"
21+
22+
# Check for unstaged changes
23+
if [[ -n $(git status --porcelain) ]]; then
24+
echo "Error: You have unstaged changes in your working directory."
25+
echo "Please commit or stash your changes before running this script."
26+
exit 1
27+
fi
28+
29+
# Parse command line arguments
30+
if [ $# -eq 0 ]; then
31+
NUM_COMMITS=$DEFAULT_NUM_COMMITS
32+
DAYS_AGO=$DEFAULT_DAYS_AGO
33+
TIME_PERIOD=$DEFAULT_TIME_PERIOD
34+
echo "No arguments provided. Using defaults: $NUM_COMMITS commits, $DAYS_AGO day(s) ago, $TIME_PERIOD period."
35+
elif [ $# -eq 1 ]; then
36+
# Validate that the argument is a positive integer
37+
if [[ $1 =~ ^[0-9]+$ ]] && [ $1 -gt 0 ]; then
38+
NUM_COMMITS=$1
39+
DAYS_AGO=$DEFAULT_DAYS_AGO
40+
TIME_PERIOD=$DEFAULT_TIME_PERIOD
41+
echo "Will modify the last $NUM_COMMITS commits to $DAYS_AGO day(s) ago using $TIME_PERIOD period."
42+
else
43+
echo "Error: First argument must be a positive integer."
44+
echo "Usage: $0 [number_of_commits] [days_ago] [time_period]"
45+
exit 1
46+
fi
47+
elif [ $# -eq 2 ]; then
48+
# Validate both arguments are positive integers
49+
if [[ $1 =~ ^[0-9]+$ ]] && [ $1 -gt 0 ] && [[ $2 =~ ^[0-9]+$ ]] && [ $2 -gt 0 ]; then
50+
NUM_COMMITS=$1
51+
DAYS_AGO=$2
52+
TIME_PERIOD=$DEFAULT_TIME_PERIOD
53+
echo "Will modify the last $NUM_COMMITS commits to $DAYS_AGO day(s) ago using $TIME_PERIOD period."
54+
else
55+
echo "Error: Both arguments must be positive integers."
56+
echo "Usage: $0 [number_of_commits] [days_ago] [time_period]"
57+
exit 1
58+
fi
59+
elif [ $# -eq 3 ]; then
60+
# Validate first two arguments are positive integers and third is valid time period
61+
if [[ $1 =~ ^[0-9]+$ ]] && [ $1 -gt 0 ] && [[ $2 =~ ^[0-9]+$ ]] && [ $2 -gt 0 ]; then
62+
if [[ $3 == "morning" || $3 == "evening" || $3 == "both" ]]; then
63+
NUM_COMMITS=$1
64+
DAYS_AGO=$2
65+
TIME_PERIOD=$3
66+
echo "Will modify the last $NUM_COMMITS commits to $DAYS_AGO day(s) ago using $TIME_PERIOD period."
67+
else
68+
echo "Error: Third argument must be 'morning', 'evening', or 'both'."
69+
echo "Usage: $0 [number_of_commits] [days_ago] [time_period]"
70+
exit 1
71+
fi
72+
else
73+
echo "Error: First two arguments must be positive integers."
74+
echo "Usage: $0 [number_of_commits] [days_ago] [time_period]"
75+
exit 1
76+
fi
77+
else
78+
echo "Error: Too many arguments."
79+
echo "Usage: $0 [number_of_commits] [days_ago] [time_period]"
80+
exit 1
81+
fi
82+
83+
# Get the target date in YYYY-MM-DD format
84+
# Check if we're on macOS or Linux
85+
if [[ "$(uname)" == "Darwin" ]]; then
86+
# macOS date command
87+
TARGET_DATE=$(date -v-${DAYS_AGO}d "+%Y-%m-%d")
88+
else
89+
# Linux date command
90+
TARGET_DATE=$(date -d "${DAYS_AGO} days ago" "+%Y-%m-%d")
91+
fi
92+
93+
# Get current branch name
94+
CURRENT_BRANCH=$(git symbolic-ref --short HEAD)
95+
BACKUP_BRANCH="${CURRENT_BRANCH}_backup_$(date +%Y%m%d%H%M%S)"
96+
97+
echo "Setting commit dates to $DAYS_AGO day(s) ago ($TARGET_DATE) with random times:"
98+
if [ "$TIME_PERIOD" == "morning" ]; then
99+
echo " - Between 5:00 AM and 8:00 AM"
100+
elif [ "$TIME_PERIOD" == "evening" ]; then
101+
echo " - Between 10:00 PM and midnight"
102+
else
103+
echo " - Between 5:00 AM and 8:00 AM"
104+
echo " - Between 10:00 PM and midnight"
105+
echo "Each commit will randomly choose one of these two time periods"
106+
fi
107+
echo "This will modify the last $NUM_COMMITS commits."
108+
echo "WARNING: This operation rewrites Git history and is destructive."
109+
echo "If you've already pushed these commits, you'll need to force push after this operation."
110+
echo "This may cause problems for other collaborators who have pulled these commits."
111+
echo "A backup branch named '$BACKUP_BRANCH' will be created."
112+
echo "Press Ctrl+C to cancel or Enter to continue..."
113+
read
114+
115+
# Create backup branch
116+
echo "Creating backup branch '$BACKUP_BRANCH'..."
117+
git branch $BACKUP_BRANCH
118+
119+
# Get the SHA of the commit before our target range
120+
LAST_COMMIT=$(git rev-parse HEAD~$NUM_COMMITS)
121+
122+
# Get the list of commits to modify in reverse order (oldest first)
123+
COMMITS=$(git rev-list --reverse $LAST_COMMIT..HEAD)
124+
125+
# Create a temporary file to store the filter script
126+
FILTER_SCRIPT=$(mktemp)
127+
128+
129+
# Start building the filter script
130+
echo '#!/bin/bash' > $FILTER_SCRIPT
131+
echo '' >> $FILTER_SCRIPT
132+
133+
# Process each commit
134+
for COMMIT in $COMMITS; do
135+
# Generate random time based on selected time period
136+
if [ "$TIME_PERIOD" == "morning" ]; then
137+
# Morning period: 5:00 AM - 8:00 AM (hours 5-7)
138+
RANDOM_HOUR=$((RANDOM % 3 + 5)) # Hours 5, 6, 7
139+
elif [ "$TIME_PERIOD" == "evening" ]; then
140+
# Evening period: 10:00 PM - midnight (hours 22-23)
141+
RANDOM_HOUR=$((RANDOM % 2 + 22)) # Hours 22, 23
142+
else
143+
# Both periods: randomly choose between morning and evening
144+
if [ $((RANDOM % 2)) -eq 0 ]; then
145+
# Morning period: 5:00 AM - 8:00 AM
146+
RANDOM_HOUR=$((RANDOM % 3 + 5)) # Hours 5, 6, 7
147+
else
148+
# Evening period: 10:00 PM - midnight
149+
RANDOM_HOUR=$((RANDOM % 2 + 22)) # Hours 22, 23
150+
fi
151+
fi
152+
153+
# Generate random minutes and seconds
154+
RANDOM_MINUTE=$((RANDOM % 60))
155+
RANDOM_SECOND=$((RANDOM % 60))
156+
157+
# Format the random time as HH:MM:SS
158+
RANDOM_TIME=$(printf "%02d:%02d:%02d" $RANDOM_HOUR $RANDOM_MINUTE $RANDOM_SECOND)
159+
COMMIT_DATE="${TARGET_DATE}T${RANDOM_TIME}"
160+
161+
# Add this commit to the filter script
162+
echo "if [ \$GIT_COMMIT = '$COMMIT' ]; then" >> $FILTER_SCRIPT
163+
echo " export GIT_AUTHOR_DATE=\"$COMMIT_DATE\"" >> $FILTER_SCRIPT
164+
echo " export GIT_COMMITTER_DATE=\"$COMMIT_DATE\"" >> $FILTER_SCRIPT
165+
echo "fi" >> $FILTER_SCRIPT
166+
echo "" >> $FILTER_SCRIPT
167+
168+
echo "Will set commit $COMMIT to $COMMIT_DATE"
169+
done
170+
171+
# Make the filter script executable
172+
chmod +x $FILTER_SCRIPT
173+
174+
# Run git filter-branch with the filter script
175+
echo "Rewriting commit dates..."
176+
git filter-branch -f --env-filter "source $FILTER_SCRIPT" $LAST_COMMIT..HEAD
177+
178+
# Remove the temporary filter script
179+
rm $FILTER_SCRIPT
180+
181+
echo -n "Done! The last $NUM_COMMITS commits now have their dates set to $DAYS_AGO day(s) ago with random times "
182+
if [ "$TIME_PERIOD" == "morning" ]; then
183+
echo "between 5:00 AM - 8:00 AM."
184+
elif [ "$TIME_PERIOD" == "evening" ]; then
185+
echo "between 10:00 PM - midnight."
186+
else
187+
echo "from two periods: 5:00 AM - 8:00 AM or 10:00 PM - midnight."
188+
fi
189+
echo "A backup of the original state was created in branch: $BACKUP_BRANCH"
190+
echo ""
191+
echo "To push these changes to the remote repository, use: git push --force"
192+
echo "To restore the original state, use: git reset --hard $BACKUP_BRANCH"

0 commit comments

Comments
 (0)