🫐

git replay を触ってみる

2024/03/09に公開

git replay という新しいコマンドが誕生したようです。(まだEXPERIMENTALです)

https://github.blog/2024-02-23-highlights-from-git-2-44/

「どんな感じなのかちょっとみてみたい」という程度の気持ちですが触ってみます。

Gitをアップデートする

update完了。

% git --version
git version 2.44.0

触ってみる

https://git-scm.com/docs/git-replay/2.44.0
EXAMPLES があるのでそれをみながら触ってみる。

シンプルにsample1ブランチをmainにrebaseしてみたい。

ちなみに今のブランチはこんな状態(こんなにコミット要らなかったな)。

% git log --oneline --graph --all
* 6fe0d48 (HEAD -> main) 7
* 2d2e6d6 6
* 9ea9e28 5
| * a954b33 (sample1) 4-3
| * fdb3cc0 4-2
|/  
* b8dfb34 4
* e0a2544 3
* f041279 2
* deb7eed 1

「いざreplay!」と思ったが、EXAMPLESだけだとちょっとよくわからなかったので結局、DESCRIPTIONとかontoとかrevision-rangeの説明を読む。

さらに他の方のブログも参考にさせていただきました。ありがとうございます!

https://bufferings.hatenablog.com/entry/2024/02/24/161729

以下と理解。

git replay --onto <新しい元> <新しい元にくっつけるコミット範囲>

今やりたいのは、sample1ブランチをmainにrebaseしたくて、mainの先頭にfdb3cc0コミットとa954b33コミットを作り直したい。コミット範囲の指定がいまいち理解できていないけど、main..sample1でよさそう、ということで実行してみる。

% git branch                             
  main
* sample1
% git replay --onto main main..sample1
update refs/heads/sample1 b17177e03b1a5749afc1ce85699f6961cc19180d a954b336f15939fd25b1508ef83c56f57534bbb1

動いた!

OUTPUT によると、update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} という形式で表示されるとのこと。 b17177e03b1a5749afc1ce85699f6961cc19180dが新しいコミットだ。

今の状態を見ると、前と変わっていないけどこれでOK。
DESCRIPTION

Takes ranges of commits and replays them onto a new location. Leaves the working tree and the index untouched, and updates no references.

% git log --oneline --graph --all     
* 6fe0d48 (main) 7
* 2d2e6d6 6
* 9ea9e28 5
| * a954b33 (HEAD -> sample1) 4-3
| * fdb3cc0 4-2
|/  
* b8dfb34 4
* e0a2544 3
* f041279 2
* deb7eed 1

新しくできたコミットを見てみる。

% git show --format=oneline b17177e03b1a5749afc1ce85699f6961cc19180d
b17177e03b1a5749afc1ce85699f6961cc19180d 4-3

できてるできてる。

DESCRIPTION

The output of this command is meant to be used as input to git update-ref --stdin, which would update the relevant branches (see the OUTPUT section below).

git update-ref --stdin に渡せる形式で表示されているとのことなので、結果を渡して実行すればsample1ブランチが更新されるのでは。

% echo "update refs/heads/sample1 b17177e03b1a5749afc1ce85699f6961cc19180d a954b336f15939fd25b1508ef83c56f57534bbb1" | git update-ref --stdin
% git log --oneline --graph --all                       
* b17177e (HEAD -> sample1) 4-3
* c762c38 4-2
* 6fe0d48 (main) 7
* 2d2e6d6 6
* 9ea9e28 5
* b8dfb34 4
* e0a2544 3
* f041279 2
* deb7eed 1

できてるできてる!なるほど。

まとめ

なるほど、なんとなく理解です。
HEADを移動しないというのがへ〜〜〜という感じでした。
複数ブランチを一気にrebaseできるらしく、(私は今は使わないけど)利用できそうなシーンはありそうだなと思いました。

Discussion