2017-06-14 6 views
1

git revertを理解しようとすると、A、B、C、Dの4つの単純なコミットがテキストファイルfoo.txt取り消しの意図はBを後でコミットし、コミットA、C、Dはそのままにします。git revert:単純なケースでも個々のコミットを元に戻すことができない

したがって、コミットごとに、フィーチャーが追加されたか、導入されたバグをエミュレートする新しい行がファイルに追加されました。 foo.txtのAをコミットした後

、内容:

Feature A 

は後にBをコミット、foo.txtの内容:は(ここで、私は私が後で戻す/やり直してみようバグを紹介します。コミットC後)

Feature A 
Bug 

foo.txtの内容:

Feature A 
Bug 
Feature C 

が後foo.txtの内容、Dをコミット:

Feature A 
Bug 
Feature C 
Feature D 

を今、(バグを導入しました)Bのコミットの効果を元に戻すために、私がやった:

git revert master^^ 

私が期待していたのは、ファイルからBug行を削除した新しいコミットEでした。失敗したgit revertビーイング次のファイルの内容で

error: could not revert bb58ed3... Bug introduced 
hint: after resolving the conflicts, mark the corrected paths 
hint: with 'git add <paths>' or 'git rm <paths>' 
hint: and commit the result with 'git commit' 

Feature A 
Feature C 
Feature D 

しかし、私はエラーを得た:エントとして

Feature A 
<<<<<<< HEAD 
Bug 
Feature C 
Feature D 
======= 
>>>>>>> parent of bb58ed3... Bug introduced 

は(bb58ed3は、ハッシュですコミットB、'Bug introduction'このコミットのコメント。)

質問:

  1. ここで何が起こっていますか?

  2. 単純な1行コミットであっても自動的に元に戻す/元に戻すことができず、私の手作業による解決が必要な場合は、元の開発者が他の誰かになる可能性があるもっと複雑なコミットを取り戻すことができます。

  3. git revertのほうが適切な場合がありますか?

答えて

1

gitそれぞれがチェンジとしてコミット(私はここで物事を単純化)し、あなたがgit revertを呼び出すときにすることを「適用解除」にしようと見ています。各チェンジリストには、変更が有効であることを確認するためのコンテキストも含まれています。たとえば、変更したい場合は、「returnを10行目以降に追加する」というより、「7〜9行目にX、Y、Zが含まれている場合は、returnを10行追加してください。ファイルの最初の行がFeature Aであると仮定すると

  1. :だから、我々はあなたの第二(再び、少しここではこれを単純化)としてコミットを記述することができます。
  2. 2行目がないと仮定します。
  3. 2行目にBugが含まれているようにします。

あなたは、いくつかのより多くの行を追加した後、Bugのコンテキストが大幅に変更され、そのgit revertは、それは単に行を削除できるかどうかわからないです。おそらく、新しく追加された行がバグを修正したのかもしれません。したがって、コンテキストの競合を明示的に解決するように求められます。

質問2-3:はい、git revertは、その後変更されていないファイルを元に戻す場合に使用できます。たとえば、foo関数ではバグが導入されましたが、その後はbar関数(これは10行下にあります)のみが変更されました。その場合、git revertは、コンテキストが変更されていないことが分かるため、自動的に変更を元に戻す可能性があります。

UPD:ここコンテキストは、あなた自身のコードを元に戻すためにしようとしている場合でも、重要な理由の例です:

は(ミスタイプを気に)コミット:

int some_vlue = 0; 
read_int_into(some_vlue); 
some_vlue = some_vlue++; 

は、(Bコミットバグ導入):

int some_vlue = 0; 
some_vlue = 123; 
some_vlue = some_vlue++; 

)がC(名前は固定をコミット:

int some_value = 0; 
some_value = 123; 
some_value = some_value++; 

コミットBを元に戻すには、some_value = 123を古い行read_int_into(some_vlue)に置き換えることができないため、コンテキストが必要です。コンパイルエラーです。

+0

私は、文脈のことは助けている以上のことを傷つけていると思います。 'git'は、' git revert'オプションを使ってコンテキストの使用を無効にすることができます。コンテキストが適切なターゲットとそのバージョンに適用されている場合は、パッチを送信して盲目的に適用したり、完全に認識していない場合に役立ちます。しかし、私のような場合は、 'git'自体が正確なソースとターゲットを正確に知っているので、どうしてコンテキストを利用するのでしょうか?あなたの説明を気に入ってください、btw。私はそれを最終にする前にもう少し待つでしょう。 – Harry

+1

@ハリー私はいくつかの説明を追加しました。変数の名前の変更、メソッドの名前の変更など、より複雑な状況が存在することがあります。その中には、結果のコードがコンパイルされるものもあります。したがって、コンテキストを無視するかどうかを自動的にチェックすることは不可能であり、 'git'は安全です。 – yeputons

+0

あなたの例は間違いなく理にかなっています。しかし、その後、名前の変更が文脈の外でも起こることがあるので、 'git'はどのように(限られた)文脈に依存することができましたか? – Harry

関連する問題