93

git は初めてで、すでに台無しになっています。

リモート開発マシンにいくつかの変更をコミットしてプッシュしました。古いバージョンを回復する必要がありますが、別のブランチで作業を続けるために、これまでのところ「悪い進行状況」を維持してください。

私はこのようにすることを考えていました:

  1. 「tested-thing」という名前のローカル ブランチを作成します。
  2. ローカル リポジトリを機能していた状態に戻します(意味のあるコミットが役立つことを願っています)
  3. リモートにプッシュ

  4. テスト済みのもののテストを終了する

  5. 「テスト済みのもの」を開発にマージ
  6. リモートにプッシュ

ステップ 3 と 5 の間で、他の開発者がコミットしてプッシュする可能性があり、これが「マージの悲劇」につながるのではないかと心配しています。

アップデート:

ここでの主な問題は 2) にあります。

ここで、トピックについて:「トピックブランチへの作業の分割」 http://learn.github.com/p/undoing.html

彼らは提案します:

  1. $ git ブランチ テスト
  2. $ git リセット --hard a6b4c974

そうすることで、他の開発者は引き続き次のことができます。

$ git commit(開発ブランチ上)

チェックアウトしてテストし、マージ時まで解決することができます。

すべてのオプションにもかかわらず、これは従うべき良いアプローチのように感じます. ただし、プッシュした後にこれを実行できるかどうかは明記されていません。

次の点に注意してください:私がこれらの変更を行ってから、すべてを台無しにしてしまったため、これまでのところ、他の誰もリポジトリで作業していません。したがって、作業ディレクトリを元に戻しても、誰も気付かないでしょう。

4

3 に答える 3

164

問題

使用できるワークフローは多数あります。要点は、ブランチを消費する可能性があり、全員のクローンに手術を行う意思のあるすべての人に連絡しない限り、公開されたブランチの歴史を壊さないことです。避けられるならやらないほうがいいです。

公開ブランチのソリューション

概説した手順にはメリットがあります。開発ブランチをすぐに安定させる必要がある場合は、そのようにしてください。適切な分岐点を見つけるのに役立つGit を使用したデバッグ用のツールが多数あり、最後の安定したコミットと HEAD の間のすべてのコミットを元に戻すことができます。

一度に 1 つずつコミットを逆の順序で元に戻すか、<first_bad_commit>..<last_bad_commit>範囲を使用します。ハッシュはコミット範囲を指定する最も簡単な方法ですが、他の表記法もあります。たとえば、5 つの不正なコミットをプッシュした場合、次のようにして元に戻すことができます。

# Revert a series using ancestor notation.
git revert --no-edit dev~5..dev

# Revert a series using commit hashes.
git revert --no-edit ffffffff..12345678

これにより、リバース パッチが作業ディレクトリに順番に適用され、既知の適切なコミットに向かって逆方向に作業されます。--no-editフラグを使用すると、リバース パッチが適用されるたびに作業ディレクトリへの変更が自動的にコミットされます。

man 1 git-revertその他のオプション、およびman 7 gitrevisions元に戻すコミットを指定するさまざまな方法については、を参照してください。

または、HEAD から分岐し、必要な方法で修正して、再マージすることもできます。その間、ビルドは壊れますが、状況によってはこれが理にかなっている場合があります。

危険地帯

もちろん、あなたの不正なプッシュ以降誰もリポジトリからプルしていないことが確実で、リモートが裸のリポジトリである場合は、非早送りコミットを行うことができます。

git reset --hard <last_good_commit>
git push --force

これにより、システムとアップストリーム ホストの reflog はそのまま残りますが、不正なコミットは直接アクセス可能な履歴から消え、プルで伝播されません。古い変更は、リポジトリが削除されるまで残りますが、誤って作成したコミットを表示または復元できるのは Git 忍者だけです。

于 2012-05-28T06:51:01.930 に答える
35

すでにリモート サーバーにプッシュしている場合 (そして、同じリモート ブランチで作業している他の開発者がいる場合) に留意すべき重要なことは、履歴を書き換えたくないということです。

git reset --hard を使用しないでください

変更を元に戻す必要があります。そうしないと、削除されたコミットが履歴にあるチェックアウトは、次回のプッシュ時にそれらをリモート リポジトリに追加してしまいます。他のチェックアウトは、その後の次のプルでそれらをプルします。

変更をリモートにプッシュしていない場合は、次を使用できます

git reset --hard <hash>

変更をプッシュしたが、誰もそれらをプルしていないことが確実な場合、使用できます

git reset --hard
git push -f

あなた変更をプッシュし、誰かがそれらをチェックアウトにプルした場合、あなたはそれを行うことができますが、他のチームメンバー/チェックアウトは協力する必要があります:

(you) git reset --hard <hash>
(you) git push -f

(them) git fetch
(them) git reset --hard origin/branch

しかし、一般的に言えば、それは混乱に変わりつつあります。したがって、元に戻す:

削除するコミットは最新のものです

これはおそらく最も一般的なケースです。あなたは何かをしてしまったのです。

最初に、戻りたいコミットを特定する必要があります。これは次の方法で実行できます。

git log

変更前のコミットを探し、コミット ハッシュに注意してください。-nフラグを使用して、ログを最新のコミットに制限できます。git log -n 5

次に、他の開発者に見せたい状態にブランチをリセットします。

git revert  <hash of first borked commit>..HEAD

最後のステップは、元に戻した変更を再適用する独自のローカル ブランチを作成することです。

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

完了するまで作業を続けてmy-new-branchから、メインの開発ブランチにマージします。

削除するコミットが他のコミットと混在しています

元に戻したいコミットがすべて揃っていない場合は、おそらく個別に元に戻すのが最も簡単です。もう一度使用しgit logて、削除するコミットを見つけてから、次のようにします。

git revert <hash>
git revert <another hash>
..

次に、作業を継続するためのブランチを作成します。

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

もう一度、ハックして、完了したらマージします。

次のようなコミット履歴になるはずですmy-new-branch

2012-05-28 10:11 AD7six             o [my-new-branch] Revert "Revert "another mistake""
2012-05-28 10:11 AD7six             o Revert "Revert "committing a mistake""
2012-05-28 10:09 AD7six             o [master] Revert "committing a mistake"
2012-05-28 10:09 AD7six             o Revert "another mistake"
2012-05-28 10:08 AD7six             o another mistake
2012-05-28 10:08 AD7six             o committing a mistake
2012-05-28 10:05 Bob                I XYZ nearly works

ベターウェイ®

特に、複数の開発者が同じブランチで作業することの危険性を認識したので、常に機能ブランチを使用することを検討してください。つまり、何かが完了するまでブランチで作業し、それをメイン ブランチにマージするだけです。また、 git-flowなどのツールを使用して、ブランチの作成を一貫した方法で自動化することも検討してください。

于 2012-05-28T07:51:33.193 に答える
-2
git revert HEAD -m 1

上記のコード行。「最後の引数が表す」

  • 1 - 1 つのコミットを元に戻します。2 - 最後のコミットを元に戻します。n - 最後の n 件のコミットを元に戻します

また

git リセット --hard siriwjdd

于 2015-08-20T14:38:10.243 に答える