2016-08-11 14 views
8

Примечание: аналогичный вопрос, как this one, но с некоторыми важными изменениями.Изменить сообщение фиксации для конкретного фиксации

У меня есть следующие функции, чтобы переписать дату фиксации, учитывая обязательство 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/" 
} 

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

Я ищу похож на this, но с некоторыми оговорками:

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

ответ

3

Этот небольшой скрипт работает, учитывая следующее ca :

  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