サポンテ 勉強ノート

サポンテの勉強ノート・読書メモなどを晒します。

Git の「ステージング」はなんのためにある?【git/add/ステージ】

不思議な手順「ステージング」

 Git には、変更点を記録する「コミット」__他の VCSバージョン管理システム だと「チェックイン」と呼称される場合もあります__の前に「ステージに追加」という不思議な手順があります。

 他の VCS を経験してから Git に入門すると、このひと手間ワンクッションが、まったく不思議なのです。なぜ直接コミットできないのか。この手順が一体なんのためにあるのか、どんな場合に有用なのか。

 Git の入門的な書籍やサイトには、腑に落ちるわかりやすい具体的な説明がなぜか少ない。サポンテがかつて読んだ入門的なテキストにも納得できる説明はありませんでした。

 そのような訳で、わりと長い間の疑問でした。

彷徨

 この記事を書くにあたって、もう一度ネットでも検索してみました。以下のサイトが出てきましたが、残念ながらサポンテの満足の行くものではありませんでした。

 Git の開発者の意図した「ステージが存在する本来の目的」らしきものは、まったく腑に落ちないものでした。

 そもそも説明が抽象的に過ぎて、Git に使い慣れた今なら同意できても入門時にこれを読んでもとうてい理解・納得はできなかったでしょう。

個人的な経験から

 そのような入門だったため、サポンテもはじめは git add → 即 git commit あるいは git commit -a を連発していました。

 しかし最近、気がつくと git add を多用していることに気が付きました。長い時間がかかりましたが、無意識的・おぼろげに、ステージングの有用性に至ったのです。

 そうして長い時間をかけて得心しても良いのですが、最初から理解して納得して使い始めた方が、おそらく望ましい。ですので、サポンテの考える「ステージングの使いどころ」のようなものを以下に説明したいと思います。

免責

 それは、上述のように「Git の開発者の意図した『ステージングが存在する本来の目的』」とは異なると感じる方もいらっしゃるでしょう。しかし言葉の上では異なっても、突き詰めて考えると、それはコインの裏表だったり根っこの深いところでつながっていると解るはずです。

ステージングの使いどころ

コミットの粒度

 まず「コミット」は、ひとつのテーマに沿った変更点を履歴として残すものと考えられます。例えば「ここの部分の関数の使い方は間違っている。複数のファイルに同じ誤りを見つけた。修正したい」という場合、その複数のファイルの変更は「関数 XXX の使い方誤りを修正」といった、ひとつの「作業タスク」または「課題イシュー」になります。大抵の場合、一つのイシューは、一つのコミットに対応させたくなるかと思います。複数のファイルだからとそれぞれ別のコミットにしてしまったり、反対にひとつのコミットに複数のイシューを含めてしまうと、後で履歴を振り返るときに変更の範囲が不明瞭になって困るためです。そういうわけでコミットは「意味が共通する変更点のまとまり」になってていることが多い。

 反対の言い方をすると、一つのコミットは「一つ以上複数の『課題に対応する変更点』」で構成されます。

タスクに関係のない気になる点

 しかしながら作業をしていると「おや、こんなところにバグが有るぞ」とか「このコメントは不明瞭だから追記したいな」など、作業中のイシューとは関係ないところが気になったりします。

 だからと言ってそういう部分に次々に手を加えてしまうと、コミットに不純物が紛れ込んで履歴が混乱してしまいます。

先に『気になった点』をステージング

 そんなときにステージングが有用です。

 コミット対象の変更点は、現在ステージに置いてある変更点です。作業中のイシューがまだ完了していないなら、気になってしまった修正したい点を先にステージング → コミットしておくことができます。ステージングしていないイシューに関連する変更は、作業中のままにできます。

先に『イシュー関連』をステージング

 反対に、現在のイシューに関連する変更点だけを先に、作業が終わった順にステージングしておき、ステージングが終わったらその他の気になった点について作業ディレクトリのファイルに手を加えるというやり方もあります。

 どうやら、むしろこちらが Git 開発者の意図した使い方らしいのですが。

振り返りとまとめ

 ステージングは「次コミット対象の変更点1を置いておく場所」です。

 様々な作業をしているときに、必ずしも全部の変更点を一つのコミットに入れたいとは限りません。

 現在の作業タスク課題イシューとは別に「修正したい箇所を見つけたので先にコミットしておきたい」などの場合にステージングが有用です。

 そういうケースはむしろ頻繁にあります。

 ステージングは「コミット前のワンクッション」ではなく「コミット準備が完了した変更点の置き場所」とイメージできます。


  1. 変更点=ファイルではないことに注意しましょう。一つのファイルの中の、特定の行だけをステージングすることができます。