世界を動かす技術を、日本語で。

プルリクエストとコードレビューの舞台

概要

  • Goatmire Elixir ConfでのSaša Jurić氏による「Tell Me a Story」講演の要点
  • コードレビューとPull Request(PR)の課題と改善策
  • レビューしやすいPRの作り方とコミットメッセージの重要性
  • クリーンなコミット履歴がもたらす価値
  • コラボレーションを成功に導くための具体的なプラクティス

Goatmire Elixir Conf「Tell Me a Story」講演レポート

  • Goatmire Elixir Conf にてSaša Jurić氏が「Tell Me a Story」を発表
  • 演劇的なストーリーテリング実践的な技術アドバイス の融合
  • 技術的な内容 を物語として展開し、理解しやすさと面白さを両立
  • 講演録画は後日オンライン公開予定、視聴を強く推奨

コードレビューとPull Request(PR)の課題

  • コードレビュー は多くのエンジニアが敬遠しがちな作業
  • PRが 大規模・複雑・理解困難・テスト困難 になりやすい現状
  • 「Looks Good To Me」や表面的な指摘で済ませてしまう傾向
  • git blame で責任を個人に押し付けがちだが、システム全体の責任は全員にある

レビューしやすいPRとは

  • 理解困難なPR は著者に返却することを推奨
  • 「理解できないので承認できない」と伝える勇気の重要性
  • 本当にレビュー可能なPRとは「 5〜10分でレビュー可能」な範囲
  • 中堅〜シニアレベル の開発者が対象、初心者や10xエンジニアではない
  • PRのスコープを縮小 し、1つの機能でも複数PRに分割
  • 目安は 300行以内500行超えはレビュー困難

ストーリー性のあるコミットの作り方

  • コミットは物語を語るもの として設計
  • 変更内容を 段階的かつ論理的 に提示し、レビュアーが思考の流れを追いやすくする
  • 「add dependency」「implement file upload feature」などの 汎用的なコミットメッセージ は避ける
  • 目的や背景、具体的な変更点を明記

デモによる実践例

  • Saša氏は 152行の追加と2行の削除13個のコミット に分割
  • コミットごとのストーリーを追うことで、なぜその変更が必要かが明確に
  • 例:mix.exsへの:runtime_tools追加の理由も、コミットの流れで納得

イテレーティブな開発とコミットの整理

  • fixupコミット を活用し、インタラクティブリベースで履歴をクリーンに保つ
  • autosquash オプションで自動的にfixup対象に統合
  • コンフリクト解決が困難な場合は 新規コミット作成も許容
  • 履歴の一貫性と可読性を重視

クリーンな履歴の価値

  • 全コミットがコンパイル可能・アプリが動作可能 であることを推奨
  • git bisect によるバグ発見効率の向上
  • 大規模コミットやビルド不能コミットは デバッグを困難
  • ストーリー性ある履歴が 回帰調査やコード理解 に役立つ

コラボレーション成功のためのポイント

  • フォーカスしたPRストーリー性あるコミット で早期フィードバック
  • レビュアーが理解しやすく、 質の高いレビュー が得られる
  • 履歴が明快 なため、過去の経緯も追いやすい
  • 次回PR作成時は「 レビュアーがストーリーを追えるか」を意識
  • 小さな改善から始める(例:300行以内、説明的なメッセージ)

参考リソース

  • git blame :各行の最終変更者・リビジョン表示
  • git rebase :コミット履歴の整理
  • git fixup :過去コミットの修正
  • git bisect :バグ導入コミットの特定

Hackerたちの意見

PRレビューって、ちょっとパフォーマンス的なところもあるよね。でも、同僚たちがちゃんとレビューしてくれるって信じてるし、逆に自分のPRを無視してくれるのも全然OK。それがみんなが望んでる形だと思う。特定の変更については、該当の行にコメントでタグ付けして、影響の説明と直接的な質問を添えてレビューをお願いすることが多いんだ。この「コードを壁に投げて解釈してもらう」スタイルのPRは、忙しい人たちにとって優先度が低くなりがちだと思う。コメントにちょっとしたストーリーを加えるのもいいけど、根本的な問題は、変更のブロックをそのまま提示して、全体に対して「OK」の一言を求めるのはコストがかかるってこと。文脈や意図を共有することに代わるものはないし、それはコードの外で伝えるべきだよね。

逆に自分のPRを無視してくれるのも全然OK。PRはオプションであるべきだと思う。すべての変更がピアレビューを必要とするわけじゃないし、同僚を信頼するなら、パフォーマンス的なPRに時間を無駄にせずに、自分のブランチをマージできるようにすべきだよ。

それはコードの外で伝えるべきだよね。理想的にはそうだね。ゼロ金利政策の下で10年近く過ごした後、多くの労働者は、自分の意図を文脈の中で意識し続けるインセンティブがなかったように思える。私が一緒に働いた人の半分は、前の文の苦々しさではなく、その長さに気分を害するだろう。実際に機能することと、期待されることの間にはインピーダンスミスマッチがある。これは、文脈や意図を明確にするよりも、むしろ痛々しいシンタックスエラーを引き起こすことが多い。そうなると、コードベースはすべての貢献者の文脈と意図の標準的な表現となり、彼らが最善を尽くしていないときでも、正直なところ、それが悪いことなのか?もしかしたら、コードの中で伝える方が劣った体験になるかもしれない。でも、コードの外でのコミュニケーションが確立できないとき、他に何ができる?こういうコミュニケーションをコードを通じて促進するツールがあれば嬉しいな。例えばGitHubは、そういうことをするのに完璧な位置にいるのに、やってないよね。Git + PR + プロジェクトは、情報の流れが逆になっていて、最近ではその失敗モードについて全体のカンファレンスで話されることもある。

これ、めっちゃ気になるんだよね。仕事では、結構多くの貢献があるコードベースの専門家なんだけど、同僚から「承認して!」みたいなプライベートIMがたくさん来る。100行以上のコードが送られてきて、その中で私に関係あるのは10行くらい(私が専門としているファイルや挙動だから、承認が必要なんだ)。最低限、変更の背景や、なぜこの部分のコードベースに変更が必要だったのか、その考え方を知りたい。たまに、でもあまり頻繁ではないけど、レビューを返してこの情報を求めることもある。私の意見では、多くのソフトウェア開発者は、書くのが速くないから、自分の変更に対する説明を提供するのが大変なんだと思う。あるいは、AIやIDEに従って作業しているだけで、説明を提供できるほどの理解がないこともある。人々が時間をかけないのが、レビューを形式的にしてしまう原因だと思う。

何行かの変更があるPRについて、開発者が自己レビューをしていなかったら、私は全くレビューしない。代わりに、自己レビューをして、文脈を追加してから再レビューをリクエストするようにお願いしてる。さらに、「これらの洞察の中で、コードに直接コメントとして追加する価値があるものはある?」って質問することが多い。9割の確率で、彼らが書いた文脈はコード内の良いコメントになるはず。人々は時々、意図せずにすごく怠けることがある。私たちは、モンキーブレインがより良く機能するためのリントツールが必要だ。gitプラットフォームがこの種のコンプライアンスを強制するためのUXフレンドリーな方法をもっと提供してくれたらいいのに。CI/CDでそれをある程度偽装できるけど、私の意見ではそれだけじゃ不十分だね。

そうそう、コードや変更について考えてもらいたいなら、必要なコンテキストを提供できるようにしないとね。もしそれが分からないなら、自分のコードがみんなが待ってたギフトだと思わないでほしい。自分はそう思ってるかもしれないけど、他の人には何をしたのか分からないから、誰かがその作業をしてくれるまで待つことになる。要するに、追加したコードは作業を生むってこと。だから、せめてその作業を減らすために、自分のコードが何で何じゃないのかを分かりやすくする努力をしよう。どんな変更をしたのか(機能的に)、なぜそれをしたのか、どんな選択をしたのか(あれば)とその理由、PRのコードの状態について自分の意見をまとめてみて。必要な理由や、将来のメンテナンスがどうなるか(理想は低い)についても考えてみて。要するに、誰かがドアをノックして、自分のプロジェクト用のパッチが入ったUSBを渡してきたときに、何を知りたいか自問自答して、その知識を加えてみて。大きな機能については早めにドラフトPRを作成することも考えてみて。そうすれば、誰も望んでいないものをプログラミングしたり、他の誰かがすでに作業していることを避けられるし、メンテナが方向性を示したり、作業を始める前に断ることができる。

全体的な意見には賛成だけど、 > 「良い目安は300行のコード変更。500行を超えると、レビューできない領域に入る」っていうのには反対かな。提案されたようにコミットを分けると、行数はあまり関係ないことがわかったよ。重要なのは、変更がどれだけ物議を醸すかってこと。理想的には、PRには多くの議論を生む部分が一つだけあればいいと思う。そういうPRは、できるだけ少ないコミット数(単独では意味がないものだけ)を持つべきだね。もちろん、これは一般的な経験とレビュー担当者との経験に依存するから、行数のカウントみたいな指標が役立つこともあるよ。

よく機能している環境では、逆の相関関係があることが多いよ。物議を醸す変更やバグ修正は小さくてターゲットが明確で、意図しない副作用について深くレビューされる一方で、大きな変更セットは、事前に話し合われた新しい作業で、確立されたパターンに従ってスルーされることが多い。

90%の開発者にこのレベルの履歴手術をやらせるのは難しいよ(ハハ)。実際にできる人(典型的なエンジニアの中のごく一部)でも、正しくやるための忍耐を持っているのはさらに少ないと思う。開発者にこういうことをやらせようとすると、理解できないから目が glazed over したり、余計な作業にイライラしたり、頷いても無関心になるだけ。トップエンジニアの一人がやっても、他の組織がちゃんとしたコミットの衛生を守らないことにフラストレーションを感じるだろうね。自動化で簡単に強制できるものではないから、基本的には達成不可能だと思う。Netflixみたいにトップパフォーマーだけを雇っているなら別だけど、あなたはNetflixじゃないから。

業界の一部では、CRの数やCRごとの修正回数をパフォーマンス指標として追跡してるんだよね。多くの人がこれを利用して、自分の「数字」を良く見せようとする。つまり、CRの数を増やして、CRごとの修正回数を減らすってこと。

コードレビューの目的によって、かなり変わるよね。目的はコードベースの異なる部分で違うかもしれないし。 - もし複数の人間がそのコードを見たことを確認したいなら、10分でPRを読んで「LGTM」か丁寧な「WTF」で返事するだけでもいいかも。チームにセンスがあって、クリーンに分離されたモジュールが明確なAPIを実装しているなら、これでうまくいくよ。最悪のダメージは、一つのモジュールが時々少し微妙になることだけど、大きなプロジェクトではそれも許容できるトレードオフかもしれない。 - すべての変更を徹底的に議論する必要があるなら、事前のデザインディスカッションやペアリング、図解したデザインドキュメント、非常に詳細なレビュー(差分だけでなく、変更を文脈に入れてモジュール全体を再レビューすること)が必要かも。PRの著者に自分のコードを発表して、他の人と一緒に進めるのもいいかもしれない。これはシステムの「コア」に該当する重要な部分に適しているかも。 - あなたのコードの半分が、全体像を理解していないAIによって書かれていて、大規模なメンテナンス性を理解していなくて、手を抜いて、あなたの書いたポリシーやベストプラクティスを_意図的に_破っているなら、正直言って、あなたのチームがAIをしっかり監視しない限り、テクニカルデット地獄にまっしぐらだと思う。一人でも無知な人がAIに微妙に壊れたコードを出させると、どれだけのレビュアーがいても簡単には元に戻せない混乱を生む可能性がある。そうなると、うーん、5,000行未満に抑えて、定期的に全部燃やすとか、そういう感じかな?

コードレビューの議論でよく混乱を招くもう一つの要因は、オープンソースプロジェクトと内部コードベースが一般的にかなり異なる状況にあることだと思う。内部コードベースは、比較的小さな経験豊富なグループによって作業されることが多く、彼らはPRを作成し、レビューも行っている。だから、 - 「この人が何をしているか知っていると仮定してもいいのか?」というベースラインが高い - レビューを早くするために「PRを作成する」プロセスに時間がかかるのは、チーム内の時間のトレードオフに過ぎない - コミットされたコードに問題があれば、そのコードを書いた人がそれを修正するために周りにいる でも、オープンソースプロジェクトでは、「コア」の長期的な開発チームの外からの貢献が多いから、 - 貢献者がコードベースに精通していると仮定できないので、余分な注意が必要 - 変更を提出する人よりもコードレビューを行う人が少ないことが多いので、提出者がレビューアの仕事を楽にするために余分な努力をするプロセスが理にかなっている - コードに問題があれば、提出者がアップストリームに行った後に修正するために利用可能または興味がある保証はないので、微妙な問題を事前にキャッチすることがより重要で、これによりコードレビューのプロセスは「レビューアを楽にするために、たとえそれが提出者にとって余分な作業を必要とする場合でも」という方向に傾くことが多い。

よく聞く意見だけど、あんまり賛成できないな。「どうやって5〜10分でレビューできるPRを作るか?それはスコープを減らすことだ。フル機能は複数のPRに分けるべきだよ。目安としては300行のコード変更がいい。500行を超えると、レビューできない領域に入っちゃう。」でも、これをやると、もし500行以上の大きくて複雑なものを作ってる場合、複数のPRに分けるとこんな問題が出てくる。 - レビュアーのためにPRのキューがたくさんできる - 機能が複数の変更セットに分かれて、認知負荷が増える(整合性が失われる) - ブランチのブランチで作業することになって、リベースの達人にならなきゃいけなくなったり、各PRがマージされるたびにたくさんのコンフリクトが発生することになる。PRのサイズに関する正しい答えは、コード行数じゃないよ。論理的にレビューしやすいものを判断することが大事。時には大きい方がいいこともあるし、状況による。経験から学んで、お互いにコミュニケーションを取りながら、レビューの際には優しく接して、無駄にブロックしないようにしよう。

100%同意だね。正しい答えは、機能を原子的なコミットに分けつつ、PRは機能レベルで保つことだと思う。これでPRの摩擦を減らしつつ、レビュアーが特定の機能の変更セットを簡単に見ることができる。特定の機能にパッチが必要な場合も、リベースの手間なしにパッチコミットを追加するだけで済む。AIエージェントは頻繁なチェックポイントを好むから、git diffはタスクの作業記憶のようなもので、悪いアプローチを簡単に元に戻せる。エージェントはこれを自動でやってくれるから、やらない理由はあまりないけど、プロンプトの前に作業の整理が必要だね。

これには賛成だな。変更を小さく保ちながら、まとまりのあるPRにする一つの方法は、最終的なPRの各コミットを独立して意味のあるものにすることだと思う。TFAもこれに少し触れていて、引用した部分と矛盾してる。簡単な例としては、最初のコミットでコアロジックと関連するテストを追加し、その後のコミットで残りのスキャフォールディングや儀式を行うこと。既存のコードのリファクタリングが必要な場合、期待されるレビュー内容や専門性が全く異なることが多いから、この技術は特に役立つ。PRが承認された後にマージする前にブランチをスカッシュするのは全然気にしない。個々のコミットはレビューの文脈でしか意味がないけど、PRはgitの履歴で保存したいユニットだからね。

  • レビュアーのためにPRのキューがたくさんできる これは機能だよ。1時間かかる1つのPRよりも、5分でレビューできる12のPRの方が無限に好ましい。キューを進めるために5〜15分の隙間を見つける方が、1時間の集中した時間を見つけるよりもずっと簡単だよ。 > - 機能が複数の変更セットに分かれて、認知負荷が増える(整合性が失われる) 確かに少し増えるけど、物事を集中させるのにも役立つ。例えば、リファクタリングとそのリファクタリングによって有効化された新機能を1つのPRでレビューすると、どちらの部分も悪いレビューになりがち。良いツールも助けになる。このスタイルのコードレビューは、シリーズを追跡するためにPRを何らかの形で結びつける必要がある。PRを読んで「なんでこんな風にやってるの?」って思ったら、いくつか先のPRを覗いて答えを得ることができる。 > - ブランチのブランチで作業することになって、リベースの達人にならなきゃいけなくなったり、各PRがマージされるたびにたくさんのコンフリクトが発生することになる これはツールの問題だね。GitやGithubは特にこの点で悪い。GraphiteやJujutsu、Sapling、git-branchless、あるいはスタックをサポートするVCSのようなものがあれば、これがほぼ問題にならない。

https://jj-vcs.github.io/

PRの山は、単一の巨大なPRよりもレビューアにとってずっと良いよ。柔術を使えば、ブランチを積み重ねるのも楽勝。

代わりにこんなアプローチもあるよ:事前にチームとデザインについて話し合って、開発プロセス中にアクティブな議論やサニティチェック、ペアプログラミングを行う。そうすれば、レビューは徹底的なエンドツーエンドのレビューではなく、すでに話し合われ合意された長い決定のチェーンの最終承認ステップになる。もちろん、これがすべてのプロジェクトやチーム、組織に合うわけではないけど、私が参加して貢献してきたプロジェクトやチーム、組織ではかなりうまくいってるよ。

ブランチのブランチで作業をすることになり、リベースの達人にならなければならなかったり、各PRがマージされるたびにたくさんのコンフリクトが発生する これは、PRの前にツリーのさらに後ろでコミットをスクワッシュするか、他の人がメインにマージしている場合を除いて、あまり関係ないと思うよ。もし多くの人がメインにマージしていて、それが問題を引き起こすのが心配なら、メインから長寿命のブランチを作って、そこからブランチを切って小さなPRを戻していくのもいいかも。そして、終わったらその全体をメインにマージすればいい。マージは2k行のコードになるかもしれないけど、その過程でレビューされているからね。あなたに反対しているわけじゃないけど、管理する方法はいくつかあることを指摘しておきたい。

これについて感じるのは、作っているものが大きな既存プロジェクトの中の小さな機能だけじゃないってことだよね。時には、比較的新しいプロジェクトに大きなサブシステムを追加することもあるし。もしそれを機能に分けたら、20個のPRが必要になるし、レビューを待っていると、あるいは待たずにリクエストされた変更を統合するために戻ってくると、数週間の作業が2〜3ヶ月に変わっちゃう。そんなの、モラセスのように動くのが許される大企業じゃないと無理だよね。品質が落ちることになるのかな?多分ね。でも、それが早く出荷するためのトレードオフなんだ。

PRを分けることじゃなくて、作業を分けることが大事なんだよね。もしフィーチャーフラグがなければ、それが第一歩。フレームワークがなくても、戦略や設定パラメータを使って新しい機能をオンオフできるし、変更があっても自動テストはできるよ。

各PRをフィーチャーフラグの下でマスターにマージし続けるんだ、それがやり方だよ。一気に機能を実装する巨大なPRは、レビュー、テスト、デプロイ、モニタリングの各段階で最悪のシナリオだ。

Jane Streetは素晴らしいコードレビューシステムを実装してるよ: https://janestreet.com/tech-talks/janestreet-code-review > [...] コミットでストーリーを語る [...] > [...] 平均的なレビュアーが5〜10分でレビューできるべき [...] Jane Streetのコードレビューシステムは、 - 各コミットをブランチにして、 - ブランチを重ねて(リベースやそれに伴うすべてを優雅に処理して)、 - 一度に1つのイテレーションをレビューすることで、この問題を解決してる。だから、レビュアーは個々のコミットを独立してレビューする(大体5分くらいかかる)、そして「大きな差分に至るまでのストーリーを再体験させる」ことになる。私はJane Streetでは働いていないけど、一般的なコードレビューシステムや文化がどれだけ壊れているかを考えることがよくある。graphite.devのようなツールがgitの上に構築されて、Jane Streetのようなコードレビューシステムを提供していると聞いたけど、まだアクティブなユーザーではない(今は手動でPRを重ねて、小さく保って、同僚に1つずつレビューをお願いして、リベースなども手動でやっている)。

リベースなどを今は手動で自分で処理する jj[1] がこれに役立つよ。A -> B -> Cのようなコミットのチェーンがあって、Aに変更を加えると、残りのチェーンが自動的にリベースされる。

これ、gerritで使ってたシステムでもあるよ。GoogleのPRシステムね。ブランチの代わりにチェリーピックを使うけど、素晴らしいし、PR作業をレビューアとコミッターの間でうまく分けてくれる。

プルリクエストの主な価値は、何に取り組んでいるかを知ることだと思ってる。私は、GitHubでドラフトにマークされたPRに自分のローカル変更を積極的に同期させてる。他の開発者も同じことをしてるよ。日中は、他の人の作業範囲を非同期でチェックしてる。もし、何かコンフリクトしそうなものがあれば、会議を開くんだ。私にとって実際のコードレビューのフェーズは、チェックインがクリーンであることを確認することと、自分が取り組もうとしていることがコンフリクトに巻き込まれないようにすることが主な目的なんだ。コードレビューは、チームメイトを純粋性テストするための繰り返しの機会じゃないよ。彼らが最初に私たちと一緒に働いている理由は、すでに成功しているからだと思う。「信頼して確認する」っていうのは、間違いの結果が一方通行で何百万ドルもかかるようなところで働いているなら面白いトロープだけど、悪いコミットは10秒で元に戻せるし、ソフトウェアのビルドも簡単に再作成できる。プロダクションにデプロイするのはまだ敏感だけど、開発やQA環境を素早く反復することに対して、なんでそんなに変に思うの?

なんでフィードバックを「純度テスト」と見なすの?新聞記者はプロだけど、編集者がいるよね。有名になりすぎて編集ができなくなるとどうなるか、みんな見たことあるでしょ。しかも、後でその文章を一緒に作業する必要もないし。コードレビューは「私の」コードが「私たちの」コードになる場所:私は同僚が私の提案する変更に対して快適に感じ、完全に理解し、サポートしてくれることを望んでる。

GitHubのPR UIが、プルリクエストを一つのコミットずつ進めるのがもっと良ければいいのに。良いコミットを作ろうとしている私としては、時々一つずつPRを読むようにしているけど、GitHubのUIが邪魔をして「全体のPR」レビューに戻そうとするんだ。記事の中に、コミットタブのスクリーンショットがあって、多くの人がそれが存在することすら気づいていないし、使おうとも思わないのがとても示唆的だよ。Filesタブでは、コミットピッカーが最近改善されたけど、個別のコミットよりもコミットの範囲を選ぶことに過度に焦点を当てていて、次のコミットや前のコミットに簡単にジャンプするショートカットもないから、毎回自分の位置を覚えてフルプルダウンとやり取りしなきゃいけない。さらに、Filesビューではコミットの詳細を全部読むのが難しくて、別のブラウザタブでコミットを開いたり、CommitsタブとFilesタブの間を行ったり来たりするために流れを中断することがよくある。Commitsタブもほとんどのコミットの説明を隠すデフォルトになっているから、特に良い読み体験とは言えない。GitHubのUIがコミットごとのレビューをクリーンで簡単にしないのは、GitHub自身がほとんどの開発者が良いコミットを書くことを期待していないからで、今日多くの開発者が良いコミットを書かないのは、GitHubのPRインターフェースが個別のコミットのレビューに向いていないからで、レビューされることがないなら意味がないと感じてしまうんだよね。

最新のコミットだけをレビューするのではなく、個別のコミットを通してレビューする理由をもう少し説明してもらえる?

Graphiteはこの問題に別の方法で対処してるんだ。PRをいくつかの小さなPRに分けられるから、部分ごとにレビューできるし、全体のスーパープルリクエストも一つの場所で見れる。スタックされたPRのリベースもまあまあうまくやってくれるよ。

この問題に直面したら、リモート/ブランチをローカルにプルして、コミットごとにステップを踏んでいくかな。お気に入りのGitマネージャー(Lazygit)を使って。

もしかしたら俺がダメなだけかもしれないけど、小さなコミットをするのが難しくなる理由の一つは、エディタでどの行を変更したかを直接見れることに頼ってるからなんだ。コミットすると、vscodeがその行のハイライトを止めちゃうから、今までやったこととの関連が分かりにくくなる。個々の行や、どのファイルが変更されたかを示すgitペインは、作業中の道しるべみたいなもんなんだよね。特に、複雑な機能でファイルが多いときは重要で、また触らないだろうと思うものは意図的にコミットして、視覚的なノイズを減らすことが多い。

git add --patch ...は、変更をしばらく未ステージのままにしておいて、後で複数のコミットに分けたいときの友達だよ。

これは高頻度のコミットサイクルに対する実際の、かつ有効な非互換性のように聞こえるね。もしこれらの戦略を試してみたいなら、選んだエディタにインラインの「git blame」がある?IntelliJでは、自分が作業している行の周りで、誰がいつ最新の変更をコミットしたかを見ることができる。これで「どのファイルを触ったか」という問題は解決しないけど、他の人には役立つかも?未コミットのコードのように異なる色でハイライトされるわけじゃないけど、その方向に進むための一歩にはなるかもね。

それ、めっちゃ面白いね。VS Codeが特定のコミットに対して変更されたすべての行をハイライトする機能を提供してくれたら、もっと良くなると思う。ブランチの始まりとかね。フィーチャーリクエストを出す価値があるかも?(私はそんな使い方しないから、これが既にあるかは分からないけど。)

今ならGPT-5を使って、数日でそれを実現する拡張機能を書けるかもね。

それに慣れてると、ちょっと面倒だよね。部分的に軽減する方法はいくつかあるよ:1. 個々のファイルのタイムラインパネルを使って、そのファイルのすべての履歴変更を見られるし、複数の変更をハイライトして累積変更を確認できる。gitコミットだけやローカル変更だけにフィルタリングすることもできる。2. ソースコントロールエリアのコミット履歴パネルを使って、コミット全体で同じことをするけど、累積変更のためにコミットをまたいでハイライトすることはできない。コードを書くときにチケットのすべての累積変更をハイライトして見るのに頼らないようにするには、時々パラダイムシフトが必要だけど、上記の2つの代替案が役立つことが多いよ。もちろん、あなたが触らない可能性のあるものをコミットするって言ってたのも、すごく助かるよね。

おすすめは、開発プロセスを最終ドラフトとして扱わないことだね。全部一気に書いて、その後にコミットを整理して、自分が伝えたいストーリーを作る感じ。これにはgit rebaseに慣れる必要があるけど、絶対におすすめだよ。このテクニックを使って、最近いくつかの大規模なリファクタリングを問題なくマージできたし、レビューアーにも嫌われなかった。

IntellijでPRを開くと、PR内で変更された行が異なる色でハイライトされるよ(複数のコミットからでも)。その色付きのボーダーをクリックすると、メインブランチのコードのバージョンが見れる。

それならGitLensみたいなのを使えない?しばらく使ってないけど、確か簡単に変更をどのブランチと比較できるんだよね。自分は、何か触ったものを見たいと思ったら、ドラフトPRを開くことにしてる。

この投稿に対する意見は、エンジニアの中でも特定の層、つまりキャリアの中堅で、自分をシニアエンジニアだと思い始めた人たちに結構多い気がする。彼らは自分たちが決めた厳しいルールにみんなが従うべきだと思ってるんだよね。DRYをあらゆる状況に適用しようとしたり、他の人に基本的なアプリにTDDを強制したりするのと同じ考え方だ。実際には、 - 小さなPRが必ずしもレビューしやすいわけじゃない(このこだわりが、意味不明な塊でPRの過剰を引き起こし、結果的にコード品質を下げることがほとんど) - 誰もPRの中間コミットメッセージを一つ一つ読むことはない。リードがこれにこだわって、「このメッセージを読んでるなら、5ドルあげるよ」みたいなメッセージを書き始めたチームで働いてたけど、誰にもお金を払ったことはない。誰も読まないものを書くのに時間を無駄にしないで。 - 「すべてのコミットはコンパイル可能でなければならない」 - これもまた、必要以上の熱心さだよね。MAINブランチのすべてのコミットは確実にコンパイルできるべきだけど、ブランチで作業しているときにこれに時間をかけるのは、間違ったことに焦点を当ててる。PRは他の人が自分のやってることを理解するのに役立つから必要なんだ(遅かれ早かれ、そのコードを読むことになるから)。パフォーマンスシアターを作りたいわけじゃない。

私がチームに言ってるシンプルな提案:PRはチームへのメールであり、未来の自分へのメールでもある。そう考えると、正しいトーンを保ちやすくて、スコープや重要なことについて考えやすくなる。--- > 「あらゆる状況にDRYを厳密に適用するのは、開発者側から見てソフトウェア業界に悪影響を与えてると思う。文脈を考慮せずに人を叩くための大きな棒になってしまったから。」

「自分をシニアだと思ってる中堅レベルの人たち」が、まさにあなたが言ってることを言ってるのをよく見る。つまり、* 「はい、プロダクションコードに対するTDDは理論上はいいけど、私の場合はうまくいかない。」 * 「はい、短いPRは理論上はいいけど、私の場合はうまくいかない。」 って感じ。私が見る限り、これは「うまくいくはずだけど、やり方が分からない」って意味だと思う。「あなたのケースでうまくいかないと思うなら、私に来て、教えてあげるよ」って言うと、たいていは引き下がって、結局大きなPRになっちゃう。実際、戦略的に分けられなかった長いPRを見たことがないけど、毎日のように分けるべきだったPRを見かける。

「誰もPRの中間コミットメッセージを一つずつ読まない」 私は中間コミットが意味を持つように履歴を整理してる。誰もPRの中でこれらのメッセージを読まないけど、6ヶ月後にバグに対してgit blameを実行した時には、「昼食のために停止」以外のことを教えてくれるコミットメッセージが欲しい。 > あらゆる状況にDRYを厳密に適用したり、他人に基本的なアプリのTDDを強制するのは確かに良くないけど、私の経験では、長いメソッドや良いテストが不足しているコピー&ペーストコーディングの方がはるかに一般的な問題だと思う。あなたの特定のケースでは100%正しいかもしれないけど、一般的にシニア開発者があなたのコードが雑でテストが不十分だと不満を言っているなら、ただのペダンティックじゃないかもしれない。

誰もPRの中間コミットメッセージを一つずつ読むことはない、まったく。 私、読むよ!作者がそのように構成する時間をかけてくれたとき、コードレビューが一番楽だと思う。素晴らしい人たちと一緒に働けてラッキーだな。

誰もPRの中間コミットメッセージを一つずつ読むことはない、まったく。 私が働いていたチームでは、リーダーがこれにこだわっていて、「このメッセージを読んでいるなら、5ドルあげるよ」みたいなメッセージを書き始めたことがあった。結局、誰にもお金を払わなかったけどね。誰も読まないものを書くのに時間を無駄にしない方がいいよ。私はするけど、特に作者が有能な場合はね。とはいえ、経験的には、ほとんどの人は読まないのが正しい。でも、実際にはその文化を変える方が、慣習を捨てるよりも良い反応だと思う。クリーンな履歴を読むのは本当に気持ちいいし、履歴をきれいに保つこと(例えば、劇的に小さなコミットをするのではなく)で、作者としてももっと注意深くレビューすることになると思う。

誰もPRの中間コミットメッセージを一つずつ読むことはない、まったく。 PRがドラフト段階のときは、「WIP」コミットメッセージがたくさんあってもいいと思うけど、その後はそれらのゴミコミットを一つにまとめて、全体の変更内容を説明する一行は書くべきだね。10個のゴミコミットが含まれているPRをマージするのは、リポジトリの履歴を理解するのが難しくなると思う。

確かに、PRごとのLoCみたいな厳密なルールはない方がいいけど、これに関する原則は非常に重要だよ。PR内の複合コミットをレビューする時、異なる変更がどう相互作用しているのかを逆算して意図を理解しなきゃいけない。それを各更新ごとにやらなきゃならないのは大変だよね。コミットを分けている人と比べると、変数の名前変更や関数の抽出をサッと見て、どの一行がその全てを解放したのかがすぐにわかる。更新があれば、更新されたコミットだけを気にすればいいしね。全てのコミットがコンパイルできることは、個々のコミットをレビューするのに役立つ。小さなコミットや全てがコンパイルできることは、バイセクトにも役立つし、問題を分析するのが楽になるよ。

  • 誰もPRの中間コミットメッセージを一つずつ読むことはない、まったく [...]
  • 「すべてのコミットはコンパイル可能でなければならない」 - また、過剰な熱意は不要だよね。 私の地域では、これらはどちらも真実で、誇りに思っている。大小さまざまなエラーをたくさん見つけているし、履歴も読みやすいから、特定のプロジェクトがどう進化してきたかを追うのにも役立つ。全員、全チーム、全業種に当てはまるわけではないことは理解しているけど、この種の規律はコードの質とチームメンバーの能力の両方において報われると思う。

大きなオープンソースプロジェクトに関わったことがないのが明らかだね… 君が軽視しているすべての慣習には良い理由があるんだ。単一の会社で働くプログラマーのチームにとっては、その価値が常にあるわけじゃないのは同意するけど、それが一番簡単で面白くないケースなんだよ… 大規模な分散プロジェクトでは、こういうことが本当に重要なんだ。

誰もPRの中間コミットメッセージを一つずつ読まない、これが現実。自分の前の会社ではよくあったし、今の役割でも続けてるよ。 > 「すべてのコミットはコンパイル可能でなければならない」って、他の誰かが君のブランチを最新のメイン/マスターにリベースしようとする時、全然役に立たない。君のPRが「機能の作業中」から「マージの準備中」に移ったら、ちょっとgit rebase -iをして、本当に中間的なコミットをコンパイルできるものにまとめてみて。もし君のPRが一日以上オープンのままにならない、ちゃんとしたCIがあるなら、これは無視してもいいよ。

これにはあまり同意できないな。PRは一般的に機能のサイズ、または大きな機能の意味のあるサブ機能のサイズであるべきだと思う。PRを「300行」や「5-10分」といった基準で無理に分けると、全体を見失っちゃうことがある。小さい部分は単体では良さそうに見えるけど、全体のアプローチの一部としては意味がない。異なる人が部分的にレビューしてるけど、誰も全体のアプローチを見てるわけじゃないし、パーツがうまく組み合ってるかも確認してない。で、「コミットでストーリーを語る」ってアイデアは時間の無駄に感じる。コードを書いた順番や、何を書いてから書き直したかには興味がない。コード自体が読みやすくなければならない。最終的なコードとそのコメントが自分で語るべきだよ。コードが「何」で、コメントが「なぜ」だ。で、言いたいのは、ジュニアの開発者ほど、コミットは小さくするべきだと思う。でも、それは彼らが小さな機能を担当するべきだからで、途中でより多くのサポートが必要だから。大きなアーキテクチャの変更をする時は、最初から全体のアプローチに対する承認を得るべきだよ。コードレビューで問題に対する全体のアプローチを頻繁に却下しているなら、コミュニケーションプロセスに問題があるんじゃないかな。

そうだね。このナラティブスタイルは、何をしたのかを説明しようとするけど、逆に「なんでこれをやってるの?」って疑問を残すことが多い。コミット#1は何かのためのヘルパー関数を追加して、見た目は無害で実装も正しい。信じられないかもしれないけど、テストもあるし、いい感じ。でも、コミット#8になって初めて、このヘルパー関数は全く必要ないし、全体のアプローチが間違ってることに気づく。毎回そうなる。私はこのチェーンを逆からレビューするようにしていて、全体のチェーンが揃うまでレビューを始めないようにしてる。でも、コミット#2から#5までが徐々に全てを認識できないものにリファクタリングしていると、左側と右側のdiffが両方とも間違っていることもあるから、簡単ではないよね!「この問題は2つ先のコミットで直すから」とか言われても興味ないし、ただプロダクションに入る最終状態をレビューしたいだけ。他はどうでもいい。はい、コミットは可能な限り小さくして、無関係な修正やリファクタを含めないべきだと思う。意味のあるものにしてほしいな。