2024年9月15日日曜日

gitの古いコミットを1つにまとめる


背景

スマホアプリの開発に別のリポジトリをcloneして利用したところ、自分のコミットより前のコミット履歴が残っているため開発者(contributors)がやたら多く見えるリポジトリになってしまいました。


開発の方針が同じなら履歴を維持したら良いと思いますが「アプリ開発の仕組み作り」と「アプリ自体の開発」では趣旨が異なるため、古いコミットは統合して履歴で表示される開発者が自分だけにしました。

しかしながら、githubの開発者一覧は一度でもそのリポジトリに対してpushしたcommitの作成者が表示されるらしく、統合してpushしただけでは更新されなかったです。
開発者一覧に表示される人を減らすには、コミット履歴を統合し、リポジトリを一度消して作り直し、pushし直しが必要ようでした。(時間経過で消えることを期待して、ここはまだ試していません。)

最初の目的が達成できていないとは言えコミットの統合方法は覚えておきたいので、備忘録として実行したコマンドと方針を記事に残します。

使ったもの


方針説明

下記のようにコミット履歴を変更します。

変更前
自分の最新
.
.
自分の最古
他のリポジトリだった頃の最新
.
.
他のリポジトリだった頃の最古

変更後
自分の最新
.
.
自分の最古
履歴を統合した旨のコミット

コマンド

git logから下記の4つのコミットのhash値調べてをエディタなどに記しておきます。
自分の最新
自分の最古
他のリポジトリだった頃の最新
他のリポジトリだった頃の最古
git log

コマンドを間違えても今までの変更が破棄されないように別ブランチにバックアップしておきます。
git checkout -b backup

作業用のブランチを作ります。
git checkout -b change-history

変更を保持せず他のリポジトリだった頃の最新に戻ります。
git reset --hard [他のリポジトリだった頃の最新のhash]

変更を保持して最古の履歴に戻ります。(--hard無しです)
git reset [他のリポジトリだった頃の最古のhash]

破棄したい最古のコミットがgitの履歴の最初のコミットの場合は更にupdate-refを実行します。
git update-ref -d HEAD

履歴を破棄しつつ保持している変更内容をコミットします。
これが別のリポジトリで行われた履歴をまとめるコミットになります。
後で見返せるように下記のxxxxx/xxxxxにclone元のリポジトリのurlなどを記載するのが良いと思います。
git add .
git commit -m "Bundle commits on xxxxx/xxxxx until [他のリポジトリだった頃の最新のhash]"

他のブランチに退避させている自分が行ったコミットを適用します。
git cherry-pick [自分のコミットの最古のコミットのhash]^..[自分のコミットの最新のコミットのhash]
説明文が多い上記のコマンドの具体例はこちらです。
# a94685a: 自分のコミットの最新
# ee6af93: 自分のコミットの最古
git cherry-pick ee6af93^..a94685a

上記のコマンドで古いコミットの統合終了です。
ログを見ると統合したコミットが新し目の日時の不思議な履歴が出来ます。


githubの履歴を書き換えて良いならforce pushします。

余談: githubのcontributors一覧は履歴を上書きしても残り続ける?

githubのリポジトリに対して、masterの履歴を書き換え、他のブランチが存在しない状態にしました。
しかしながら、それでも一度pushしたコミットはgithub上に残り続けるためか、一覧は維持されました。


時間が経てば消えるのか様子を見ます。
それでも消えない場合は、気が向いたらリポジトリを一度消して作り直して関連を消したいコミットを消すかもしれません。

おわり

期待通りにコミットを統合しつつ履歴を更新できました。
squashを使う方法も見つけはしましたが、対象のコミットが多いと処理中に競合が発生して難儀そうだったのでresetとcherry pickの組み合わせで実現しました。

しかしながら、force pushしてもgithubのcontributors一覧は維持されたので、githubのリポジトリのcontributors一覧から統合されたコミットの作成者を消したい場合はリポジトリの削除と作り直しが必要そうでした。

参考

初回のコミットを取り消したいときにはgit update-refを使う
How to cherry-pick multiple commits

0 件のコメント :