ステージング領域の目的は、コミットのための柔軟なスペースを確保することです。gitをsubversionなどの一元化されたバージョン管理システムと対比すると、これはより明確になると思います。
Subversion
subversionでは、作業コピーの特定のファイルをコミットすることを選択できます。しかし、完全なファイルのみ。今:file A
ではなくfile B
、およびfileの変更に依存する部分ではなくfile C
に関連するfileの部分をステージングしたい場合(コミットの整合性に問題があるため)。A
B
ギット
Gitは、ステージングを2番目の作業コピーとして提供することでこれを解決します。ステージング領域内で、(大まかに)コミットするスナップショットをまとめます。
したがって、ステージング領域内で、への変更との変更のみを反映するA
ファイルのバージョンを含むスナップショットを作成できます。C
A
特定の質問について
好きなときにステージングできます。個人的には、コミットを開始する直前にステージングすることを好みます。
ステージングされたファイルの変更があり、作業コピーでそのファイルを変更する場合、ステージングされたファイルはもちろん変更していません。これらもステージングするか、変更をステージングしないかを決定できます。つまり、実行git gui citool
すると、ステージングされたバージョンとステージングされていないバージョンの差分が表示されます(行ごとのステージングとコミットのための便利でシンプルなツール)。
Gitはここで慎重であり、これはおそらく良いことです。
一般的なコミット戦略:きめ細かなコミット
「いつステージングすべきか」という質問について話すときは、コミットの習慣についても話す必要があると思います。
集中型VCS
中央サーバーにコミットする集中型バージョン管理システムでは、コミットが完全で十分にテストされていることが同僚にとって重要でした。したがって、人々はそれほど頻繁にコミットせず、エラーの可能性を最小限に抑えるために完全なファイルの状態をコミットしようとします。したがって、コミットは多くの変更を含む非常に大きなチャンクになる傾向があります(単純な修正ではない場合)。コミットの変更は完全に無関係である可能性があります。
ギット
Gitではコミットがローカルで実行され、サーバーにプッシュするだけでパブリックになります。したがって、ある意味でコミットは安価です。転覆という意味でのコミットは、いくつかのgit commit
後に続くに相当しgit push
ます。この違いは重要です。
Gitでは、同じファイルの他の行も変更した場合でも、コードの1行をコミットできます。これにより、たとえば、行300〜350を変更して新機能を導入しながら、行100でセキュリティバグ修正をコミットできるため、多くの利点があります。
- コミットごとに異なる変更を分離できます。これにより、バージョン履歴でそれらがうまく分離され、一方を元に戻すことはできますが、もう一方は元に戻せません。
- あなたのコミットは、必ずしもあなたの作業コピーの「コンパイル」状態を反映する必要はありません(私はその方法を維持しようとしますが)。
では、Subversionユーザーが期待するコミットの「品質管理」とビルド保証はどこにあるのでしょうか。gitでは他のアクションに移行しています。それでも、プログラムの機能状態をパブリックリポジトリにプッシュしたいとします。したがって、変更が適用される前に、テストが成功し、プログラムが機能することを確認します。
また、ブランチを最大限に活用してみてください。小さな変更をたくさんコミットすると、かなり大きなバージョン履歴ができてしまいます。ブランチで作業している場合は、それらの細かいコミットをブランチ名で分類してからマージして戻すことができます(オプションにより、--no-ff
これらの機能が一意のブランチに存在することも維持されます)。
master
つまり、ブランチが良好な状態である場合にのみ、ブランチにマージする習慣を保つことができます。タグを使用して、マイルストーンとリリースを追跡することもできます。
ステージングに戻ります:コミットごとに数行をコミットすると、コミットする前に直接ステージングします。(少なくともそれが私が行う方法です)。
git diff
とgit diff --cached
良いですが、時々私はもっと欲しいです)。