Изменить сообщение фиксации для конкретной фиксации


Примечание: аналогичный вопрос, как и Этот, но с некоторыми важными изменениями.

У меня есть следующая функция, чтобы переписать дату фиксации, учитывая идентификатор фиксации:

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/"
}

Я пытаюсь реализовать аналогичную функцию rewrite-commit-message для изменения сообщения фиксации. Чего я хочу, так это:

  1. функция rewrite-commit-message принимает два параметра: commit_id и new_commit_message
  2. нет необходимости знать старое сообщение фиксации: достаточно иметь commit_id, чтобы знать, что совершить изменение
  3. Нет git commit --amend, так как это связано со старыми коммитами (не обязательно с самым последним коммитом)
  4. Не беспокойтесь о переписывании истории и мастер-РЕПО: я работаю в филиале функций, и мне разрешено это делать git push -f
  5. я хотел бы использовать filter-branch для этого, но я не уверен, как это сделать.:
    • примените изменение к конкретному коммиту: test, используемый в функции rewrite-commit-date, используется в функции env-filter, но я не собираюсь делать env-filter здесь, так как я делаю не хочу менять ничего, что связано со средой фиксации, но сообщение фиксации.
    • Как заставить сообщение о фиксации? --msg-filter требуется исходное сообщение фиксации. Меня не волнует исходное сообщение о фиксации. Есть ли --force-msg-filter или подобный?

То, что я ищу, похоже на это , но с некоторыми оговорками:

  1. не применяйте изменение к диапазону коммитов, а к конкретному коммиту
  2. я не забочусь о оригинальное сообщение фиксации, так как я хочу полностью перезаписать его
1 10

1 ответ:

Этот маленький скрипт работает со следующими оговорками:

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

  2. Ваша фиксация содержится в ветви master. Вы можете легко изменить это, передав имя ветви в качестве другого параметра, но этот commit лучше находиться в ветви. Вероятно, вам следует встроить некоторую проверку для этого, возможно, используя 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