プッシュされていないgitコミットを削除するにはどうすればよいですか?


948

誤って間違ったブランチにコミットしました。そのコミットを削除するにはどうすればよいですか?

回答:


1811

行った作業を維持しながら、最新のコミットを削除します。

git reset --soft HEAD~1

最新のコミットを削除して、実行した作業破棄します。

git reset --hard HEAD~1

13
HEADがブランチを指していることを確認します。(最初にチェックアウトしてください)
フランクシュウィーターマン2010

128
そして、git reset --hard origin
HEAD〜1

13
考えgit remoteは私のために起源をリストアップするgit reset --hard originと言いfatal: ambiguous argument 'origin': unknown revision or path not in the working tree.ます。どうして?
trss 2013

7
これは素晴らしいです。ちょうど私の命を救った。
NinjaBoy 2013

2
git reset HEAD~1また、すべての変更を保持しますが、(--softオプションのように)すべてを保持するのではなく、空のインデックスを残します。
Holloway 2014

139

なぜ私が見つけた最良の答えがコメントだけにあるのだろう!投票数86のDaenythによる

git reset --hard origin

このコマンドは、ローカルリポジトリをリモートリポジトリと同期し、ローカルで行ったすべての変更を削除します。以下を実行して、オリジンにある正確なブランチをフェッチすることもできます。

git reset --hard origin/<branch>

16
これをありがとう、説明を少し広げます:特定のブランチの場合:git reset --hard origin/<branch>
cleary

4
またはgit reset --soft origin/<branch>、コミットを取り除き、ローカルの作業を維持したい場合。
リバーホース

1
私が取得するfatal: ambiguous argument 'origin': unknown revision or path not in the working tree.:あなたが枝のように指定する必要があり、git reset --hard origin/feature/my-cool-stuff
キップ

鮮やかさ!これは実際に機能しますが、単に頭を外してぶら下げたままにする「受け入れられた」回答とは異なります。
前日

55

削除しないでください。1つのコミットgit cherry-pickで十分です。

しかし、間違ったブランチで複数のコミットがあった場合、それがgit rebase --onto優れています。

これがあるとします:

 x--x--x--x <-- master
           \
            -y--y--m--m <- y branch, with commits which should have been on master

、それからマークmasterしたい場所に移動します:

 git checkout master
 git branch tmp
 git checkout y
 git branch -f master

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- y branch, master branch

、yブランチを本来の場所にリセットします。

 git checkout y
 git reset --hard HEAD~2 # ~1 in your case, 
                         # or ~n, n = number of commits to cancel

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- master branch
                ^
                |
                -- y branch

、最後にコミットを移動します(再適用して、実際に新しいコミットを作成します)

 git rebase --onto tmp y master
 git branch -D tmp


 x--x--x--x--m'--m' <-- master
           \
            -y--y <- y branch

残念ながら、それは問題ではありませんでした。
KatariaA

1
@KatariaAこれは、間違ったブランチで行われたコミットを削除する有効な代替手段であり、同じ状況で他の人を助けます(間違ったブランチで行われた適切なコミット)。
VonC 2019


6

そのコミットを別のブランチに移動する場合は、問題のコミットのSHAを取得します

git rev-parse HEAD

次に、現在のブランチを切り替えます

git checkout other-branch

そしてへcherry-pickのコミットother-branch

git cherry-pick <sha-of-the-commit>

私の経験から、これは元のブランチからのコミットを取り消さないため、git reset --hard HEAD~1後で必要になります。reset --softブランチを切り替えて再度コミットすると、余分な作業を省けると思います。次に、SourceTreeを使用して基本的なことのほとんどを実行していました。エラーが発生した後は、これをコマンドラインで実行するだけです。
jusopi 2015年

3

参考までに、git reset --hardだけでなく、次のコマンドでも、現在のブランチからコミットを「ハードカット」できると思います。

git checkout -B <branch-name> <SHA>

実際、チェックアウトする必要がない場合は、次のようにブランチを好きなように設定できます。

git branch -f <branch-name> <SHA>

これは、たとえばブランチから新しいコミットをコピーするために(リベースを使用して)ブランチからコミットを削除するプログラム的な方法です。

他の場所からソースを取得してブランチにダンプしたため、マスターから切断されたブランチがあるとします。

これで、変更を適用したブランチができました。「トピック」と呼びましょう。

ここで、トピックブランチの複製を作成し、それをブランチ「dump」にあるソースコードダンプにリベースします。

git branch topic_duplicate topic
git rebase --onto dump master topic_duplicate

これで、「dump」の開始点に基づいてブランチのtopic_duplicateに変更が再適用されますが、「master」以降に発生したコミットのみが適用されます。したがって、マスター以降の変更は「ダンプ」の上に再適用されますが、結果は「トピック_重複」になります。

次に、「dump」を「topic_duplicate」に置き換えることができます。

git branch -f dump topic_duplicate
git branch -D topic_duplicate

または

git branch -M topic_duplicate dump

または、ダンプを破棄するだけで

git branch -D dump

おそらく、現在の "topic_duplicate"をクリアした後でチェリーピックすることもできます。

私が言うことをしようとしていることは、あなたが現在を更新したい場合は、別の祖先のオフに基づいて枝を「複製」あなたが最初以前に実行してコミットを「cherrypicked」を削除しなければならないということですgit reset --hard <last-commit-to-retain>git branch -f topic_duplicate <last-commit-to-retain>、その後、メインから(上の他のコミットをコピーしますトピックブランチ)リベースまたはチェリーピッキング。

リベースは、すでにコミットされているブランチでのみ機能するため、それを行うたびにトピックブランチを複製する必要があります。

チェリーピッキングははるかに簡単です:

git cherry-pick master..topic

したがって、シーケンス全体は次のようになります。

git reset --hard <latest-commit-to-keep>
git cherry-pick master..topic

トピック複製ブランチがチェックアウトされたとき。これにより、以前に選択したコミットが現在の複製から削除され、現在の「ダンプ」(異なる祖先)の上にある「トピック」で発生するすべての変更が再適用されます。別の「ダウンストリーム」マスターを使用しながら、「実際の」アップストリームマスターに基づいて開発を行い、ローカルの変更がまだ適用されるかどうかを確認するのは、かなり便利な方法のようです。あるいは、diffを生成して、Gitソースツリーの外部に適用することもできます。ただし、この方法では、実際の開発が実際のアップストリームマスターに反する一方で、ディストリビューションのバージョンに基づく最新の修正済み(パッチ済み)バージョンを維持できます。

だから単に示すために:

  • resetはブランチを別のコミットにポイントします(--hardは前のコミットもチェックアウトします--formは追加されたファイルをインデックスに保持します(再度コミットするとコミットされます)。デフォルト(--mixed)は以前のコミットをチェックアウトします(ローカルの変更をワイプします)が、インデックスはクリアされます(まだコミット用に何も追加されていません)
  • 別のコミットを指すようにブランチを強制することができます
  • そのコミットもすぐにチェックアウトしながら、そうすることができます
  • 現在のブランチに存在するコミットに基づいてリベースします
  • チェリーピッキングは、別のブランチからコピーすることを意味します

これが誰かを助けることを願っています。これを書き直すつもりでしたが、今はどうしようもありません。よろしく。


0

次のコマンドが機能しました。ローカルでコミットされたすべての変更が削除され、ローカルがリモートの起点/マスターブランチと同じにリセットされます。

git reset-ハードオリジン

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