がんばれ fixup と autosquash おまえがナンバー 1 だ!!(WIP コミットにおいて)

2.3K Views

August 04, 22

スライド概要

ぼくのかんがえたさいきょうの開発環境 天下一武道会で発表したスライドです。

`wip`エイリアス
```
alias wip='git commit --fixup $(git log -1 --pretty=format:"%H" --grep="^fixup\!" --invert-grep)'
```

このスライドのコード
https://github.com/korosuke613/zenn-articles/tree/9498a8a6f03791b8619dfd4f759f11f3e4311ab2/slides/git-commit-fixup

profile-image

サイボウズ株式会社 開発本部 生産性向上チームで働いています。

シェア

埋め込む »CMSなどでJSが使えない場合

各ページのテキスト
1.

がんばれ`fixup`と`autosquash` おまえがナンバー1だ!! (WIP コミットにおいて) 2022/08/04 (木) ぼくのかんがえたさいきょうの開発環境 天下一武道会 平木場 風太 <Futa Hirakoba> 🥊

2.

平木場 風太 - Futa Hirakoba 🌋 出身 - 鹿児島 🏢 勤め先 - サイボウズ株式会社 / 開発本部 / 生産性向上チーム 🧑‍💻 役割 - Engineering Productivity 🍣 好きな食べ物 - チキン南蛮、辛麺 💪 AWS や CI、Terraform を触ることが多い [1] @korosuke613 @shitimi_613 1. 写真は桝元の辛麺(トマト 5 辛中華麺チーズトッピング)。毎日食べたい。 ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 2 / 22 ]

3.

今日話すこと `git commit --fixup` と `git rebase --autosquash` をうまく使って WIP コミットの作成とマージを高速にやっていくよ ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 3 / 22 ]

4.

WIP コミットとは? トピックブランチで作業中、作業途中の状態を保存目的でコミットを積むこと[1][2] 個人作業だけでなくモブプログラミングのドライバー交代時に登場することも `git commit -m "wip"` というふうにしがち fix :. .. fe at :. .. main 3 w ip 2 w ip 1 w ip fe at :h og e develop 1. 平木場による造語。 2. `git commit --amend --no-edit` でもいいけどプッシュ時に force push しないといけないため、めんどい&あんまりやりたくない。 ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 4 / 22 ]

5.

WIP コミットはマージ前にまとめる 開発 & WIP コミットを繰り返す 完成したら main ブランチへマージ前に WIP コミットはまとめる ヒストリーに WIP コミットを残したくないよね まとめるのには `git rebase --interactive` などのコマンドを使いがち fix :. .. fe at :. .. main fe at :h og e develop ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 5 / 22 ]

6.

WIP コミットを使った開発の流れ 意味のあるメッセージのコミットを作成 コーディング WIP WIP コミット コミットを意味のあるメッセージのコミットにマージ # 準備 git commit --allow-empty -m "feat: hoge" [topic b13be29] feat: hoge ❯ git push origin HEAD ❯ コミットを積んでいく # WIP ❯ vim hoge ❯ git add hoge ❯ git commit -m "wip" [topic 188ff3b] wip 1 file changed, 123 insertions(+) create mode 100644 hoge vim hoge git add hoge git commit -m "wip" [topic 0a4efa9] fixup! hoge 1 file changed, 10 insertion(+), 2 deletions(-) ❯ ❯ ❯ まとめたコミットをプッシュ # ❯ ❯ コミットをまとめてプッシュ git rebase --interactive main git push --force-with-lease ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 6 / 22 ]

7.
[beta]
`git rebase --interactive`
マージ先ブランチ名>` をするとインタラクティブに rebase できる

`git rebase --interactive <

デフォルトエディタ[1]が立ち上がるので、コミットごとにコマンドを指定する
pick acea229 feat: hoge
pick fa27bfa wip
pick 2795746 wip
#
#
#
#
#
#
#
#
#
#
#
#

Rebase 6be49d1..2795746 onto 6be49d1 (3 commands)
Commands:
p, pick <commit> =
r, reword <commit>
e, edit <commit> =
s, squash <commit>
f, fixup [-C | -c]

省略>

<

use commit
= use commit, but edit the commit message
use commit, but stop for amending
= use commit, but meld into previous commit
<commit> = like "squash" but keep only the previous
commit's log message, unless -C is used, in which case
keep only this commit's message; -c is same as -C but
opens the editor

1. `$EDITOR` または `$VISUAL` または git config の `core.editor` に設定されているエディタ。どれも設定されてなければ `vi` が使わ
れる。設定の優先順位は知らない。

ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 7 / 22 ]

8.
[beta]
`git rebase --interactive`
今回はコミットをまとめたいので `pick` の部分を `fixup` に変える[1][2]

`fixup` を指定したコミットは 1 つ上のコミットにマージされる。ただし、コミットメッセージは 1 つ上の
ものが使用される
エディタが Vim なら `Shift` + `v` -> fixup したいコミットの行を選択 -> `:'<,'>s/pick/fixup/g` で
複数の `pick` を `fixup` に置き換えられる
pick acea229 feat: hoge
fixup fa27bfa wip
fixup 2795746 wip

省略>

<

1. `fixup` 以外にも便利なコマンドがたくさんある。みんな `git rebase --interactive` を使いこなしてくれよな!コミットの順序を
入れ替えることだってできるぞ!
2. `fixup` の代わりに `f` でも可。

ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 8 / 22 ]

9.

`git rebase --interactive` エディタを保存して終了すると `fixup` で指定したコミットが 1 つ若い(古い)コミットにマージされる before git log main.. --oneline 2795746 (HEAD -> topic) wip fa27bfa wip acea229 feat: foo 6be49d1 (main) feat: hoge ❯ after git log main.. --oneline dbe67da (HEAD -> topic) feat: foo 6be49d1 (main) feat: hoge ❯ 今回の例では「feat: foo (acea229)」にマージされる この後はヒストリーがきれいになったので force push して main ブランチにマージする ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 9 / 22 ]

10.

`pick` を `fixup` に 変えていくのめんどいな 🤔 ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 10 / 22 ]

11.

というわけで本題に入ります ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 11 / 22 ]

12.

`git rebase --autosquash` マージ対象コミットのハッシュまたはメッセージ>` となっているコミットの コミットメッセージが `fixup! < コマンドを自動で `fixup` にしてくれる[1] マージ対象コミットの真下になるように並び替えもしてくれる `--interactive` も必要[2] 1. 他にも `squash!` や `amend!`、`fixup! -C` などがある。https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt--autosquash 2. `--interactive` をつけなくてもできる方法知っている人いたら教えてください。 ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 12 / 22 ]

13.

`git rebase --autosquash` git log main.. --oneline e5c1a0f (HEAD -> topic) fixup! feat: hoge 1ec880d fixup! feat: hoge 83791fc feat: hoge ❯ `git rebase --interactive --autosquash main` pick 83791fc feat: hoge fixup 1ec880d fixup! feat: hoge fixup e5c1a0f fixup! feat: hoge 省略> < `fixup!` のコミットのコマンドが最初から `fixup` となっている ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 13 / 22 ]

14.

毎回コミットメッセージを `fixup! 〜` ってするのめんどいな 🫠 ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 14 / 22 ]

15.
[beta]
`git commit --fixup`
`git commit --fixup <

マージ対象コミットのハッシュ>` を実行すると自動で `fixup!` のコミットメッセ

ージを作成してくれる

マージ対象コミットのメッセージ>` という形式になる[1]

`fixup! <

git commit --fixup c0af36
[fixup 2e719be] fixup! feat: hoge
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 ccaca
❯

マージ対象コミットのハッシュ>` とならないのかは知らない。人間が読むのを想定してるから?rebase 時にコミットハ

1. なんで `fixup! <

ッシュが変わってしまう可能性があるから?

ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 15 / 22 ]

16.

毎回マージ対象のコミットハッシュを打ち込むのめんどいな 🫥 ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 16 / 22 ]

17.

`git commit --fixup` はコミットハッシュを指定し ないといけないからめんどい `git commit --fixup < マージ対象コミットのハッシュ>` しないといけない WIP コミットを作るたびにマージ対象コミットのハッシュを指定するのがめんどい `HEAD` を指定するのはどうだい? `git commit --fixup HEAD` にすると HEAD のコミットを指定することになるので、常に HEAD を指 定すると `fixup!` の先のコミットへマージされることになる ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 17 / 22 ]

18.

`git commit --fixup HEAD` してみる 変更を加えるたびに `git commit --fixup HEAD` を実行する 現実は非情だった![1] 1199b2a 637a150 2e719be c0af36a (HEAD -> topic) fixup! fixup! fixup! feat: hoge fixup! fixup! feat: hoge fixup! feat: hoge feat: hoge HEAD のコミットメッセージが入るため、永遠に `fixup!` が増えていくことになる 見づらいし、いつかメッセージサイズの限界が来る 1. `--autosquash` したらちゃんと `c0af36a` 以外のコミットのコマンドは `fixup` となる。 ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 18 / 22 ]

19.

じゃあもう自動でマージ対象コミットを取ってくるか 要は `fixup!` でないコミットハッシュを取ってくればいい `git log -1 --pretty=format:"%H" --grep="^fixup\!" --invert-grep` で取ってこれる `-1`: 一番新しい 1 コミットだけ表示 `--pretty=format:"%H"`: コミットハッシュだけ表示 `--grep="^fixup\!"`: `fixup!` で始まるコミットメッセージのコミットを抽出 `--invert-grep`: `--grep` の結果を反転させる 例)`fixup!` で始まらない `feat: hoge` のコミットハッシュのみが表示される git log main.. --oneline c801878 (HEAD -> topic) fixup! feat: hoge dbae606 fixup! feat: hoge c855557 fixup! feat: hoge 667f80d feat: hoge ❯ git log -1 --pretty=format:"%H" --grep="^fixup\!" --invert-grep 667f80dafbb9449c0d0f1aeff9831afb234af434 ❯ ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 19 / 22 ]

20.
[beta]
最終的なコマンド
`--fixup` の引数にハッシュ取得コマンドを埋め込む
git commit --fixup $(git log -1 --pretty=format:"%H" --grep="^fixup\!" --invert-grep)

wip みたいな名前で alias 化
alias wip='git commit --fixup $(git log -1 --pretty=format:"%H" --grep="^fixup\!" --invert-grep)'

例)
git log main.. --oneline
c801878 (HEAD -> topic) fixup! feat: hoge
dbae606 fixup! feat: hoge
c855557 fixup! feat: hoge
667f80d feat: hoge
❯

wip
[fixup dbae606] fixup! feat: hoge
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bar
❯

ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 20 / 22 ]

21.

まとめ `git rebase` の `--autosquash` オプションを使うと WIP コミットをまとめるのが楽になる `git commit` の `--fixup` オプションを使うと `fixup! ~` コミットメッセージをつけるのが楽になる `git commit --fixup $(git log -1 --pretty=format:"%H" --grep="^fixup\!" --invert-grep)` を使うと `--fixup` するのが楽になる さらに alias 化すると `--autosquash` のための WIP コミットの作成を 1 コマンドでできて楽 結論: 開発力が 53 万になる ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 21 / 22 ]

22.

参考情報 Fixing commits with git commit --fixup and git rebase --autosquash | Jordan Elver[1] `--fixup` と `--autosquash` の解説記事 tummychow/git-absorb: git commit --fixup, but automatic[2] `git commit --fixup` 周りをいい感じに行うツール Slidev[3] このスライドは Slidev というスライド作成ツールで作りました[4] マークダウンとか HTML とかで作れるよ 1. https://jordanelver.co.uk/blog/2020/06/04/fixing-commits-with-git-commit-fixup-and-git-rebase-autosquash/ 2. https://github.com/tummychow/git-absorb 3. https://sli.dev 4. https://github.com/korosuke613/zenn-articles/pull/236 ぼくのかんがえたさいきょうの開発環境 天下一武道会 - [ 22 / 22 ]