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

Примечание. Вопрос аналогичен этому, но с некоторыми важными изменениями.

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

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. 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.
    • как заставить сообщение коммита? --msg-filter требуется исходное сообщение фиксации. Меня не волнует исходное сообщение коммита. Есть ли --force-msg-filter или аналогичный?

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

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

person blueFast    schedule 11.08.2016    source источник


Ответы (1)


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

  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
person Jeff Puckett    schedule 16.08.2016