Gitでローカルコミットを破棄する


1469

チェリーの選択が悪いため、私のローカルGitリポジトリは現在、オリジンより5コミット進んでおり、良好な状態ではありません。私はこれらのコミットをすべて取り除き、もう一度やり直したいです。

明らかに、私の作業ディレクトリを削除して再クローニングすればそれは可能ですが、GitHubからすべてを再度ダウンロードするのはやり過ぎのようで、私の時間を有効に利用できません。

たぶんgit revert私が必要とするものですが、たとえコード自体が正しい状態に戻ったとしても、最初から10回(または6回)先にコミットしたくはありません。私は最後の30分が起こったことがないふりをしたいだけです。

これを行う簡単なコマンドはありますか?明らかなユースケースのようですが、私はそれの例を見つけていません。


この質問は具体的にはコミットに関するものであり、次のものではないことに注意してください。

  • 追跡されていないファイル
  • ステージングされていない変更
  • 段階的だがコミットされていない変更

回答:


2470

過剰なコミットが自分にしか表示されない場合git reset --hard origin/<branch_name> は、元の場所に戻ることができます 。これにより、リポジトリの状態が以前のコミットにリセットされ、ローカルの変更がすべて破棄されます。

を実行するとgit revert新しいコミットが作成され、全員の履歴を正常に保つ方法で古いコミットが削除されます。


91
git reset --hard <commit hash, branch, or tag>リモートブランチ以外の特定の参照に移動する場合。
Sam Soffes 2014年

55
ただ、明確にするために、あなたが上で作業していない場合masterが、別の枝に、あなたが実行する必要がありますgit reset --hard origin/<your-branch-name>
ゾルタン・

33
これにより、ローカルコミットが破棄されるだけでなく、作業ツリー内のすべて(つまり、ローカルファイル)も破棄されます。あなたがしたいすべてがuncommitですが、そのまま自分の作品を残している場合は、「gitのリセットHEAD ^」を行う必要があります...ごとstackoverflow.com/questions/2845731/...
aaronbauman

3
この後でフェッチを実行することができます。これにより、SourceTreeのコミット数-プッシュされるのを待つカウンターが修正されました。
スタン

2
git reset --hard origin/<branch_name>プロジェクト構成もリセットされるので注意してください。.cfgデフォルトにリセットされた大きなファイルがあります。私はそれに何時間も費やす必要がありました。
MAC

271

ローカルマスターブランチを削除して、次のように再作成するだけです。

git branch -D master
git checkout origin/master -b master

2
これは、変更をバックトラックするのに時間がかかりすぎる場合にうまく機能します。これは、2回のリベース後に発生しました。
aros

1
チームメンバー間のサブツリーのプル/プッシュの問題に役立ちます。
ホルヘオルピネル2014

これは、マスターだけでなくブランチを復元したい場合に最適です。
Vladimir Ralev、2014年

1
これは単一のローカルコミットを削除する良い方法ではありません。使用する方が良いgit reset --hard origin/<branch_name>
キリットヴァゲラ2016

1
多分その解決策はうまくいくかもしれませんが、それが適切な解決策であるという意味ではありません。
ADLY

202

試してください:

git reset --hard <the sha1 hash>

頭をどこにでもリセットできます。gitkを使用して、どのコミットにするかを確認します。gitk内でもリセットできます。


5
このb / cは有益な情報ですが、ベンジャクソンの答えは、私が望んでいたことを正確に解決するためのチェックマークを取得します-コミットハッシュを調べる必要がない方法で。:)
David Moles

2
これはあなたの新しい枝がまだ原点にプッシュされていなかったものである

126

最新のコミットを削除します。

git reset --hard HEAD~1

行った作業を破棄せずに、最新のコミットを削除します。

git reset --soft HEAD~1


5
役に立つ答え。ありがとうございました!私はgit reset --soft origin / masterを使用しました
Tarun Kumar

2
@TarunKumarありがとうございます!私はVSの統合を使用していますし、あなたのソリューションは、私がチェックする権限を持っていなかった私はブランチに私は望んでいなかったことをマージコミットの束を一掃することができた唯一の方法でした。
DVK

おかげで、私が探していたのは、 "git reset --soft HEAD〜1"が意図せずにコミットして元に戻したいが、元に戻した後に破棄したくない他のファイルがあったためです。
edvard_munch

47

あなたが使用している場合はアトラシアンSourceTreeのアプリを、あなたは、コンテキストメニューのリセットオプションを使用することができます。

ここに画像の説明を入力してください


42

あなたのブランチの試みで:

git reset --hard origin/<branch_name>

" git log"または " git status" を使用して、(ローカルコミットのない状態への)反転を検証します


1
@Troyseph:上記のすべての回答、そのまま試してみましたが、シナリオを修正できませんでした。上記の回答のいずれにも示されていない一般的なアプローチは、ここで回答しようとしたものです。
Parasrish

3
受け入れられた答えは、一般的なブランチ名を除いて、あなたの答えと同じであり、コメントで@Zoltanは明示的に言っていますJust to be clear, if you're not working on master but on another branch, you should run git reset --hard origin/<your-branch-name>
Troyseph

1
これは私の意見では最良の答えです。
dwjohnston

21

git reset --hard @{u}*コミットを含め、現在のブランチ上のローカルの変更をすべて削除します。ブランチに戻ったり、ブランチを操作したりするためのコミットを調べる必要がないことを考えると、まだ誰もこれを投稿していないことに驚いています。

*つまり、現在のブランチに@{upstream}-common でリセットしますが、origin/<branchname>常にではありません


1
fishのような一部のシェルは「@」を解釈するので、 '@ {u}'を引用符で囲む必要がある場合があります(例: `git reset --hard '@ {u}')。とにかく、良い発見!
トリシス

素晴らしい答えは素晴らしい
Marko

1
@ {u}の値をどのように出力しますか?
Philip Rego

12

戻ってきたいコミットのSHA-1 IDを表示/取得するには

gitk --all

そのコミットにロールバックするには

git reset --hard sha1_id

!注意。そのコミット後に行われたすべてのコミット(およびプロジェクトに対するすべての変更)が削除されます。したがって、まずプロジェクトを別のブランチにクローンするか、別のディレクトリにコピーします。


これは、リモートが利用できなくなった場合に最適で、ローカルコミットにリセットする必要があるだけです。gitkはすごい-事前に気づかなかった。
theRiley

すでにgitkを使用している場合は、コミットを右クリックして[ブランチXYをここにリセット]を選択することもできます。
mkrieger1

そして、新しいコミットはすぐには削除されません。それらを指すブランチはもうありません(ブランチは特定のコミットへの「ブックマーク」にすぎないことを忘れないでください)。
mkrieger1 2016年

9

プッシュされなかったコミットを削除したい状況がありましたが、そのコミットは別のコミットより前でした。これを行うには、次のコマンドを使用しました

git rebase -i HEAD~2 ->最後の2つのコミットをリベースします

そして、削除したいコミット署名に「ドロップ」を使用しました。


9

追跡されていないファイルを削除する(コミットされていないローカル変更)

git clean -df

すべてのローカルコミットを完全に削除し、最新のリモートコミットを取得する

git reset --hard origin/<branch_name>

8

プッシュされていないローカルコミットの場合、を使用git rebase -iしてコミットを削除またはスカッシュすることもできます。


1
これは最短の解決策ではないかもしれませんが、IMHO git rebase -iは多くの同様の問題を解決するより一般的な方法であり、さまざまな状況で役立つため、私はあなたに賛成しました。
Stefan Marinov 2017年

1
dropリベースが中止されないように、すべてのコミットを削除するときは、(行を削除するのではなく)キーワードを使用してください。
MichalČizmazia19年

6

簡単な解決策は、ローカルマスターブランチのHEADをオリジン/マスターブランチのHEADに一致させることです。

git reset --hard origin/master

PS:origin / master-マスターブランチへのリモートポインターです。マスターを任意のブランチ名に置き換えることができます


4

回答する前に、背景を追加し、これが何であるかを説明しましょうHEAD。以下のオプションの一部は分離したヘッドになるため

First of all what is HEAD?

HEAD現在のブランチの現在のコミット(最新)への参照です。
常に1つしか存在できませんHEAD。(除くgit worktree

の内容HEADは内部に格納され.git/HEAD、現在のコミットの40バイトのSHA-1が含まれています。


detached HEAD

あなたが最新のコミットをしていない場合-これHEADは、履歴内の以前のコミットを指していることを意味しdetached HEADます。

ここに画像の説明を入力してください

コマンドラインでHEADは、は現在のブランチの先端を指していないため、ブランチ名ではなく、SHA-1のようになります。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

切り離されたヘッドから回復する方法に関するいくつかのオプション:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

これにより、目的のコミットを指す新しいブランチがチェックアウトされます。
このコマンドは、特定のコミットにチェックアウトします。
この時点で、ブランチを作成して、この時点から作業を開始できます。

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

いつでも使用できreflogます。
git reflog更新された変更が表示さHEADれ、目的のreflogエントリをチェックアウトすると、HEADこのコミットに戻ります。

HEADが変更されるたびに、新しいエントリが reflog

git reflog
git checkout HEAD@{...}

これにより、目的のコミットに戻ります

ここに画像の説明を入力してください


git reset --hard <commit_id>

HEADを目的のコミットに「移動」します。

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • 注:(Git 2.7以降
    も使用できgit rebase --no-autostashます。

git revert <sha-1>

指定されたコミットまたはコミット範囲を「元に戻す」。
リセットコマンドは、指定されたコミットで行われた変更を「取り消し」ます。
元に戻すコミットを含む新しいコミットはコミットされますが、元のコミットも履歴に残ります。

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

このスキーマは、どのコマンドが何を実行するかを示しています。
ご覧のとおり、をreset && checkout変更しHEADます。

ここに画像の説明を入力してください


3

Visual Studioソリューションに興味がある人のために、ここにドリルがあります:

  1. ではTeam Explorer、ウィンドウ、ターゲット・レポに接続します。
  2. 次に、からBranches目的のブランチを右クリックして、を選択しますView history
  3. Historyウィンドウ内のコミットを右クリックして、を選択しますReset -> Delete changes (--hard)

これにより、ローカルコミットが破棄され、リポジトリの状態が選択したコミットにリセットされます。つまり、レポをプルした後の変更は失われます。


2

あなたのブランチが ' origin/XXX'より5コミット進んでいる場合。

以下を発行できます。

git reset --hard HEAD~5

そして、最後の5つのコミットを削除する必要があります。


0
git reset --hard <SHA-Code>

これは、ローカルコピーで、誤ってリモートブランチにプッシュされないようにする必要があるいくつかのミスをした場合に便利です。

SHAコードは、ブランチの最後のコミットのgitダッシュボードのwebVersionを確認することで取得できます。

このようにして、ブランチの最後のコミットと同期させることができます。

git pullハードリセットが正常に完了した後で、synに新しいものがないことを確認できます。つまり、メッセージが表示されます。

ブランチは最新です Origin/<Branch Name>


0

ローカルリポジトリを完全に混乱させた場合、Gitでローカルコミットを破棄する信頼できる方法は...

  1. 「git config --get remote.origin.url」を使用して、リモートオリジンのURLを取得します
  2. ローカルgitフォルダーの名前を「my_broken_local_repo」に変更します
  3. 「git clone <url_from_1>」を使用して、リモートgitリポジトリの新しいローカルコピーを取得します

私の経験では、Eclipseは変化する世界を非常にうまく処理します。ただし、Eclipseで影響を受けるプロジェクトを選択してクリーンアップし、Eclipseにそれらを強制的に再構築させる必要がある場合があります。他のIDEでも強制的な再構築が必要になる可能性があります。

上記の手順の副次的な利点は、プロジェクトがgitに入れられなかったローカルファイルに依存しているかどうかを確認できることです。ファイルが見つからない場合は、「my_broken_local_repo」からコピーしてgitに追加できます。新しいローカルリポジトリに必要なものがすべて揃っていることを確認したら、「my_broken_local_repo」を削除できます。


0

ローカルコミットを
破棄し、ファイルの変更を維持したい場合は、git reset @〜を実行します。
他の回答はハードリセットに関するものです。

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