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:

  • The function rewrite-commit-message accepts two parameters: the commit_id , and the new_commit_message
  • There is no need to know the old commit message: having the commit_id is enough to know which commit to change
  • No git commit --amend , since this is related to old commits (not necessarily to the most recent commit)
  • 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
  • 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:

  • Do not apply the change to a range of commits, but to a specific commit
  • I do not care about the original commit message, since I want to completely overwrite it

  • 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
    
    }
    

    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
    
    链接地址: http://www.djcxy.com/p/19514.html

    上一篇: Javascript原生等同于jQuery event.preventDefault

    下一篇: 更改特定提交的提交消息