Reputation: 271
The big picture of my problem:
I want to write a script to change the history of the last n commits to today, for example: ./myscript.sh 5
will change the commit dates of the last 5 commits to today.
From this link, I can either:
Because what I want is to change the history of the last n commits, not only 1, so I have to go with the 3rd technique, which need to invoke git rebase -i
and an editor open. I want to write a script to automate this task.
Here's how the task is done manually (change the commit dates of last 5 commits to today):
git rebase -i HEAD~5
then it opens the editor
pick 81888d1 committed 9 months ago
pick 7363124 committed a month ago
pick eea43f7 committed yesterday
pick 48c3e85 committed yesterday
pick a62cbec commit recently
# change all the `pick` to `edit`
close the editor, repeat the following for 5 times
GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"
git rebase --continue
Done.
Constraints: Because I know ahead of time that the part I do in editor is to replace all pick
keywords with edit
, so I want it to be done silently. Just type ./myscript.sh 5
and the job done, no editors opened. How can I do this (in script)?
With the help of the answers, here's my final script:
#!/bin/bash
# wish design:
#./myscript.sh [number of days]
#./myscript.sh 5 # make the last 5 commits's commit dates to today
declare -r integer_pattern="^[0-9]+$"
if [[ $1 =~ $integer_pattern ]]; then
count=$1
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i "HEAD~$count"
for ((i=0; i<count; i++)); do
GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"
git rebase --continue
done
else
echo "invalid argument [number of days] $1"
fi
Upvotes: 2
Views: 738
Reputation: 12837
As described here.
Interactive rebase opens the default $EDITOR
on the commit list. It can be also overriden by env variable called GIT_SEQUENCE_EDITOR
, so you need to intercept the call and use this variable with some script
Run: GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>
. Your <script>
should accept a single argument: the path to the file containing the standard rebase commit list. It should rewrite it in-place and exit. Usual rebase processing happens after that.
Example:
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i
But you can use also some bash/python/whatever script instead.
Upvotes: 1
Reputation: 30164
Squashing n commits into one can be done without rebase interactive.... or even rebase at all. To squash the last 5 commits you can do this:
git reset --soft HEAD~5
git commit -m "some comment"
And you are done
Upvotes: 2