Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change commit message for specific commit

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:

  1. The function rewrite-commit-message accepts two parameters: the commit_id, and the new_commit_message
  2. There is no need to know the old commit message: having the commit_id is enough to know which commit to change
  3. No git commit --amend, since this is related to old commits (not necessarily to the most recent commit)
  4. No worries about rewriting history and the master repo: I am working in a feature branch, and I am allowed to do git push -f
  5. I would like to use filter-branch for this, but I am not sure how to:
    • apply the change to a specific commit: the 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.
    • how to force a commit message? The --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:

  1. Do not apply the change to a range of commits, but to a specific commit
  2. I do not care about the original commit message, since I want to completely overwrite it
like image 552
blueFast Avatar asked Aug 11 '16 09:08

blueFast


People also ask

How do you change commit message of a specific commit?

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.

How do I reference a specific commit?

To reference a commit, simply write its SHA-hash, and it'll automatically get turned into a link.

Can I checkout a specific commit?

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.


1 Answers

This little script works given the following caveats:

  1. 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.

  2. 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

}

Demo

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
like image 111
Jeff Puckett Avatar answered Sep 30 '22 06:09

Jeff Puckett