gitの2段階のコミットプロセス(ステージング)の利点は何ですか?


174

gitを学んでいますが、2段階のコミットプロセスがあることに気付きました。

  1. git add <files>
  2. git commit

最初のステップでは、リビジョンを「ステージング領域」または「インデックス」と呼ばれるものに配置します。

私が興味を持っているのは、この設計上の決定が行われる理由と、その利点は何ですか?

また、gitユーザーとしてこれを行うか、単に使用しgit commit -aますか?

この機能を持っていないbzr(Bazaar)から来たので、これを尋ねます。


3
+1を求めるため。私は同じアプローチのTortoise SVNを使用しますが、その理由はわかりません。
DPD

3
ステージングエリアはそれほど珍しいものではありません。たとえば、TFSの同等の機能は、チェックインする前にファイルの横にあるボックスをオンまたはオフにします。チェックされたファイルのみがコミットされます。Gitとの違いgit add -pは、同じファイルの別の部分をコミットせずに、ファイルの1つの部分をコミットすることを選択できることです
キラレッサ

このリンクは、ここで回答された内容のほとんどを要約し、ステージングの必要性を正当化するために、いくつかのユースケースを追加していることがわかりました。
Veverke

2
この質問は、実際にはすでに答えですが、ここにも一つの良い説明です:stackoverflow.com/questions/4878358/...
guitar_freak

1
忘れてはいけない git statusと、おそらくgit push。gitのについてのすべての誇大宣伝のために、部品は非常に迷惑している(とGitHubの共有コードは素晴らしいです)
user949300

回答:


83

作業を個別のコミットに分割します。おそらく、1行の修正を書き込むためにファイルを何度も開いたことがありますが、同時に、書式設定が間違っている、いくつかのドキュメントが改善される、または他の無関係な修正があることに気づきました。他のRCSでは、それを書き留めるかメモリにコミットし、目的の修正を完了し、それをコミットしてから、他のものを修正するために戻る必要があります(または無関係なもので泥沼コミットを作成します) 。Gitを使用すると、すべてを一度に修正し、git add -iまたは+で1行を個別にステージ+コミットしgit-guiます。

ビルドを壊さないでください。あなたは複雑な修正に取り組んでいます。そのため、さまざまなことを試してみてください。一部は他の機能よりもうまく機能し、一部は機能しません。Gitを使用すると、変更が改善されたときにステージングを行いcheckout、変更が機能しなかったときにステージングを行います(または、さらに調整します)。エディターの元に戻す機能に依存する必要はありません。checkoutファイルごとの代わりにリポジトリ全体を使用したり、ファイルレベルの間違い(コミットされていないファイルを削除したり、悪い変更)は、多くの作業の損失につながりません。


3
この機能を持たないDVCS(bzr)から来ます。これは、エディターの「元に戻す」バッファーの自由な使用、「<file>を戻す」コマンド、および選択的なコミット( " commit <file> ")。gitのこの機能のようなサウンドは、より系統的なものになる可能性があります。
thomasrutter

1
「他のRCS」については、必ずしもそうではありません。実際、パッチを使用してMercurialで同じ機能を実現できます
ルシオパイヴァ14年

1
@ l0b0、2番目のポイントについて。単一のステージコミットしかない場合は、(git addで使用する)変更をコミットとして直接コミットすることもできます。何か間違ったことをしていることがわかった場合は、コミットを削除して、コミットする前の状態に戻ります。ステージングの概念では、それを行うだけでなく、さらに複雑になりますか?
alpha_989

あなたの最初のポイントは理にかなっていますが、私は今のところ使用していません。理論的には、なぜgit add -i単一ステージのコミットでaのようなことができないのですか?単一の機能に関連する一連のファイル(またはファイル内の行)を選択し、コミットするだけです。その後、戻って別の機能に関連する2回目のコミットを行います
。– alpha_989

@thomasrutter、あなたの声明から、ステージング領域が「手動の取り消しポイント」を作成することを提案しているようです。永続的な取り消しを備えたVIMでは、無制限の履歴を非常に確実に取得できます。また、これはgit-branch型式で自動的に追跡されます(jovicailic.org/2017/04/vim-persistent-undo)。さらに、通常モードに入るたびに、元に戻す履歴が自動的に追跡されます。したがって、「手動の取り消しポイント」を作成しなければならないという精神的な負担が軽減されます。エディタを使用すると、バッファが「アンドゥ」バッファとして整然としていないのはなぜですか?
alpha_989

65

私にとっての利点の1つは、ファイルを段階的に「追加」できることです。コミットする前に、各ファイルを確認します。ファイルを確認したら、追加します。I git statusまたはの場合git diff、gitは変更されてまだ追加されていないファイルのみを表示します。すべてのファイルを確認して追加したら、コミットできます。

はい、ステージングエリアは非常に役立ちます。

いいえ、使用しませんgit commit -a。ただし、よく使用しますgit add -u。このようにして、コミットする内容を視覚化できます。


2
まさに。利点は、正確にあなたが書いているものをはるかにきめ細かく制御できることです。
ジョシュK

1つのファイルを複数回ステージングするとどうなりますか?ステージング領域で「マージ」されますか?
m4l490n

21

利点は非常に簡単です。どのファイルをいつコミットするかを完全に制御できます。さらに、コミットするgit add -pを制御するために使用できます。


2
私はいつもこれを行う方法について疑問に思っていました。ファイルが.gitignorelinesあれば、コミットを生き残り、そのままの状態を維持できるように、個々の行にローカルな変更を加えることができます。
アレックスグレー

3
@ReinHenrichs、各開発者による変更が必要な設定ファイルについて考えてください。
イアン14

1
@Ianファイルの一部は頻繁に変更されずに共有され、ファイルの一部は互換性のない方法で頻繁に変更され、共有されませんか?この虚偽の抑圧をサポートすることは、間違いなく反機能のように聞こえます。
ラインヘンリヒス14

1
@ReinHenrichs、はい、ファイルにデータベースサーバーの名前が含まれていて、各開発者が独自のデータベースを持っている場合は非常に一般的です。
イアン14

4
@Ianあなたの問題は本当にそこにあります。あなたはアプリケーションの設定であるはずのファイルを持っているということは、いくつかのマシン/開発者固有の設定も含んでいます。私が知っているすべての構成システムでは、それを複数のファイルに分割できます。したがって、たとえばapp.conf、共有したいものが含まれているを持ち、それをdb.conf.gitignoreリストに追加するだけです。問題が解決しました。プロプライエタリなものを使用している場合は、そこでとてもシンプルなものを実際に検討する必要があります。または、ビルド前イベントでプリプロセッサを介してそれを置きます。多くのソリューションがあります。
アイディアカピ

1

私が気に入っている利点の1つは、変更の一部をコミットできることです。つまり、git add -eを使用します。時々コミットすることはあまりありませんが、git add -eコマンドを使用すると、ある程度の変更を解くことができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.