Change commit message for specific commit

Refresh

November 2018

Views

3k time

11

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

1 answers

6

Этот небольшой скрипт работает с учетом следующих предостережений:

  1. Это будет переписать свою историю от фиксации на наконечнике ветви. Потому что вы заявили в вопросе, что это не является проблемой, то это квалифицируется.

  2. Ваше обязательство содержится в masterотрасли. Вы можете легко изменить, передав имя ветви в качестве другого параметра, но фиксации лучше быть в отрасли. Вы , вероятно , следует построить в какой - то проверки для этого, возможно , с помощью git rev-parse --abbrev-ref HEADили , может быть ,git branch --all --contains <commit>

Без дальнейших церемоний:

#!/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