Note: similar question as this one, but with some important changes.
I have the following function to rewrite the date of a commit, given the commit id:
rewrite-commit-date () {
local commit="$1"
local newdate="$2"
newdate="$(date -R --date "$newdate")"
echo ">>>> Rewriting commit $commit date: $newdate"
git filter-branch --env-filter \
"if test \$GIT_COMMIT = '$commit'
then
export GIT_AUTHOR_DATE
export GIT_COMMITTER_DATE
GIT_AUTHOR_DATE='$newdate'
GIT_COMMITTER_DATE='$newdate'
fi" &&
rm -fr "$(git rev-parse --git-dir)/refs/original/"
}
I am trying to implement a similar function rewrite-commit-message
to change the commit message. What I want is:
rewrite-commit-message
accepts two parameters: the commit_id
, and the new_commit_message
commit_id
is enough to know which commit to changegit commit --amend
, since this is related to old commits (not necessarily to the most recent commit)git push -f
filter-branch
for this, but I am not sure how to:
test
used in the rewrite-commit-date
function is used in env-filter
, but I am not going to do env-filter
here, since I do not want to change anything related to the commit environment, but the commit message. --msg-filter
needs the original commit message. I do not care about the original commit message. Is there a --force-msg-filter
or similar?What I am looking for is similar to this, but with some caveats:
Use the awesome interactive rebase:Find the commit you want, change pick to e ( edit ), and save and close the file. Git will rewind to that commit, allowing you to either: use git commit --amend to make changes, or.
To reference a commit, simply write its SHA-hash, and it'll automatically get turned into a link.
To pull up a list of your commits and their associated hashes, you can run the git log command. To checkout a previous commit, you will use the Git checkout command followed by the commit hash you retrieved from your Git log.
This little script works given the following caveats:
This will rewrite your history from the commit to the tip of the branch. Because you stated in the question that this isn't a problem, then this qualifies.
Your commit is contained in the master
branch. You can easily change this by passing the branch name as another parameter, but that commit better be in the branch. You should probably build in some validation for this, perhaps using git rev-parse --abbrev-ref HEAD
or maybe git branch --all --contains <commit>
Without further ado:
#!/bin/bash
change-commit-msg(){
commit="$1"
newmsg="$2"
branch="master"
git checkout $commit
git commit --amend -m "$newmsg"
git cherry-pick $commit..$branch
git branch -f $branch
git checkout $branch
}
git init
echo init > a && git add . && git commit -m "init"
echo another > a && git commit -am "another"
echo lastly > a && git commit -am "lastly"
git log --graph --oneline --all --decorate
* bca608c (HEAD -> master) lastly * 4577ab5 another * b3d018c init
change-commit-msg 4577ab5 "something else"
* c7d03bb (HEAD -> master) lastly * 3ec2c3e something else * b3d018c init
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With