2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Git 全過去コミットの Author と Committer を上書きする(GPG 署名対応)

Last updated at Posted at 2022-04-20

まとまった情報がなさそうだったので。歴史修正していきましょう 🥺

filter-branchrebase のような歴史修正コマンドは危険なので、バックアップを取るなど安全を確保した上で自己責任での作業をお願いします 🙇

環境

Git v2.36.0

共通の準備

git config --global user.name "Alice"
git config --global user.email alice@example.com
git config --global user.signingkey 0123456789ABCDEF # コミットに署名する場合のみ
git config --global commit.gpgsign true # コミットにGPG署名する場合のみ

歴史修正

いくつかやり方の候補があります。それぞれ実行結果が少しずつ異なるので、状況に合う方法を選択してください。

A. filter-branch 署名あり(全コミット)

git filter-branch -f --commit-filter '
GIT_AUTHOR_NAME="Alice";
GIT_AUTHOR_EMAIL="alice@example.com";
GIT_COMMITTER_NAME="Alice";
GIT_COMMITTER_EMAIL="alice@example.com";
git commit-tree -S "$@";
' HEAD
  • 歴史修正前の AuthorDate と CommitDate の両方を維持
  • Author と Committer を指定したもので上書き
  • filter-branch は何でもできてしまう最強のオプションなので、rebase より気分的にちょっと怖いかも

B. filter-branch 署名なし(全コミット)

git filter-branch -f --env-filter '
GIT_AUTHOR_NAME="Alice";
GIT_AUTHOR_EMAIL="alice@example.com";
GIT_COMMITTER_NAME="Alice";
GIT_COMMITTER_EMAIL="alice@example.com";
' HEAD
  • 歴史修正 A の署名なしバージョン
  • 歴史修正前のコミットに署名があってもその署名は消える

C. filter-branch 署名あり(条件付き)

git filter-branch -f --commit-filter '
  if [ "$GIT_AUTHOR_EMAIL" = "alice@localhost" ];
  then
    GIT_AUTHOR_NAME="Alice";
    GIT_AUTHOR_EMAIL="alice@example.com";
    GIT_COMMITTER_NAME="Alice";
    GIT_COMMITTER_EMAIL="alice@example.com";
    git commit-tree -S "$@";
  else
    git commit-tree -S "$@";
  fi' HEAD
  • if の test 条件に一致するコミットのみ上書き
  • 署名なしの場合も歴史修正 B と同様の考え方でできると思います

D. rebase & amend author(全コミット)

git rebase -i --root -x 'git commit --amend --author="Alice <alice@example.com>" -C HEAD'

# エディタが起動するので何も編集せずに保存して閉じる
  • 歴史修正前の AuthorDate を維持
  • Author を指定したもので上書き
  • 現在の git config に従って Committer と CommitDate を更新

E. rebase & amend reset-author(全コミット)

git rebase -i --root -x "git commit --amend --reset-author -C HEAD"

# エディタが起動するので何も編集せずに保存して閉じる
  • 歴史修正前のメタデータは原則すべて消える
  • 現在の git config に従って Author と AuthorDate を更新
  • 現在の git config に従って Committer と CommitDate を更新

F. rebase & amend reset-author(一部のコミット)

git rebase -i <上書きしない中で最新のコミットハッシュ> -x "git commit --amend --reset-author -C HEAD"

# エディタが起動するので何も編集せずに保存して閉じる
  • author オプションを使う場合も同様

備考

  • いずれの方法でもオリジナルのコミット署名は消えます。デジタル署名が歴史修正に負けたらまずいので当然ですが
  • オプションなしの $ git log で表示されるタイムスタンプは AuthorDate ですが、GitHub上で表示されるタイムスタンプは CommitDate です(2022-04-21現在)

確認

git log --pretty=fuller --show-signature

リモートリポジトリへの反映

必要な場合のみ。

git push --force-with-lease [origin] [branch]

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?