Gitのブランチからコミットを削除する


3233

コミットを削除する方法を教えてください。

ことでdelete、私はそれがコミットしなかった、と私は将来的にプッシュを行うときに、私の変更は、リモートブランチにプッシュしないであろうかのように、それはある意味。

私はgit helpを読んで、私が使用すべきコマンドはだと思いますgit reset --hard HEAD。これは正しいです?


41
私はこれがあると思わないの重複コミット元に戻す最後のGitそれは削除する方法を尋ねると任意のブランチからコミットを。私はまた、答えのどれも実際にこの質問に対処していないと思います。それらは最後のコミットではなく、少し前に発生した単一のコミットではなくcherry-pick、すべて巻き戻しdeleteます。
Chris

12
@Chrisの回答でgit rebase -i HEAD~10は、削除するコミットを任意に選択できるため、質問に対応しています。Gitは、ログから削除したコミットを無視して、指定した範囲のコミットを1つずつ適用します。今日このコマンドを使用して、一番上のコミットを維持しながら、私のリポジトリへの最新の2番目と3番目のコミットを削除しました。他のどの回答も満足できるものではないことに同意します。
MST

@MSTはい、私は言ったはずです、受け入れられた回答のオプションではなく、この質問に対処しますが、あなたは完全に正しいです-そのコマンドは機能するようです
Chris

回答:


4127

注意: git reset --hard 作業ディレクトリの変更を削除します。このコマンドを実行する前に、保持したいローカルの変更隠しておいてください

あなたがそのコミットに座っていると仮定すると、このコマンドはそれを壊します...

git reset --hard HEAD~1

これHEAD~1は頭より前のコミットを意味します。

または、の出力をgit log確認し、バックアップするコミットのコミットIDを見つけて、次のようにすることもできます。

git reset --hard <sha1-commit-id>

すでにプッシュしている場合は、強制プッシュを実行して取り除く必要があります...

git push origin HEAD --force

ただし、他の人がプルした可能性がある場合は、新しいブランチを開始することをお勧めします。彼らが引っ張るとき、それは彼らの仕事にそれをマージするだけなので、あなたはそれを再び押し上げることになるでしょう。

既にプッシュしている場合は、を使用してgit revert、変更を元に戻す「ミラーイメージ」コミットを作成することをお勧めします。ただし、両方のコミットはログに記録されます。


参考までに、進行中の作業git reset --hard HEADを取り除きたい場合に最適です。それはあなたを最新のコミットにリセットし、作業ツリーとインデックスのすべての変更を消去します。


最後に、「削除」したコミットを見つける必要がある場合git reflog、リポジトリをガベージコレクションしていない限り、通常はそこに存在します。


59
HEAD~1または単にHEAD^。プッシュした場合は、git revert代わりに使用する必要があります。
JakubNarębski、2009

13
もちろん、頭からコミットHEAD~nに「戻る」こともできnます。この時点から多分=>進行中の作業を削除すると解釈すること... --hard HEADもできますHEAD~0
nuala

13
@ beamrider9 imho git rebaseは、ほとんどの場合、コミットを削除するためのより良い方法です(Greg Hewgillの回答で説明されています)-特に、rebaseには実際に4realzを削除するという大きな警告が含まれているためです。
Noah Sussman、2012年

20
ただし、これはコミットツリーから変更を削除しません。OPは既にコミットを要求しました。あなたの場合はreset --hard、チェックlog --oneline --all、コミットはまだツリーに残ります。これらのコミットをツリーからどのように削除しますか?ありがとう。
iGbanam 2013年

17
reset --soft進行中の作業を元に戻さずにローカルコミットを削除するために使用します!

704

まだどこにもコミットをプッシュしていない場合は、を使用git rebase -iしてそのコミットを削除できます。最初に、そのコミットが(およそ)どれだけ遡っているかを調べます。次に行います:

git rebase -i HEAD~N

これ~Nは、最後のNコミットをリベースすることを意味しNます(たとえば、数値でなければなりませんHEAD~10)。次に、Gitが提示するファイルを編集して、問題のコミットを削除できます。そのファイルを保存すると、Gitは、削除したコミットが存在しないかのように、次のすべてのコミットを書き換えます。

Git Bookには、写真と例を使ったリベースに関する優れたセクションがあります。

あなたがいることを何か変更した場合ので、このかかわらには注意してくださいしている他の場所でプッシュを使用すると、力のプッシュを行うことを計画している場合を除き、別のアプローチが必要になります。


2
注:コミットの最後のバッチで--no-ffマージが発生した場合、リベースによりそれらがブッチャーされます:(これは、このページの -pで説明されています。問題は、-iを-pに置き換えた場合、 「このコミットを編集して、そのコミットを押しつぶす」などの選択肢がポップアップ表示されることはもうありません。誰かが解決策を知っていますか?
Bukov

4
プッシュした場合はどうなりますか?(私だけがリモートリポジトリを使用している)
Costa

6
@Costaを使用push -fして、リモートブランチを強制的にプッシュし、ローカルブランチに置き換えることができます。自分だけのリモートリポジトリであれば問題ありません。問題が発生するのは、その間に誰かがフェッチした場合です。
Greg Hewgill、2015年

3
GitHubには大きすぎるデータファイルを追加してコミットしました(そうです、とにかくソースレポにあるべきではありません。まあ)。プッシュしようとすると、GitHubはファイルが大きすぎるため拒否しました。私がやりたかったのは、この1つのコミットを取り消すことでしたが、その後に続いたいくつかの無関係なコミットを保存しました。git rebase -i HEAD~5コマンドでした正確に、私は完全にこれは私の地元のレポからコミット削除するために必要なもの!ありがとう!
アルド2015

4
@dumbledad:を使用rebase -iすると、削除されたコミットに対応する変更は保持されません。
グレッグヒューギル2016年

517

別の可能性は、私の個人的なお気に入りのコマンドの1つです。

git rebase -i <commit>~1

これにより、-iやりたいコミットの直前にインタラクティブモードでリベースが開始されます。その後、エディターはすべてのコミットのリストを表示し始めます。消去するコミットを含む行を削除して、ファイルを保存します。リベースは残りの作業を行い、そのコミットのみを削除し、その他すべてをログに再生します。


3
thx、btw(空のコミットなどの)問題が発生した場合に使用できますgit rebase --continue
realgt

8
さらに簡単: git rebase -i HEAD~1
mmell

2
Wowzers。git rebase -i HEAD~1本当にレポをたくさん掃除しました!それが何をしたのか正確に言うのは難しいですが、全体としてはとてもすっきりしているように見えます。実際、少し憂慮すべきです。
Charles Wood

7
コミットは抹消されておらず、単にリストから削除されているだけであることは注目に値します。失敗した場合は、reflogを使用してコミットを取り戻すことができます。
Zaz 2015

6
行の削除はd / dropと同じですか?
レオ

345

Gitの使用ミスのため、作業をコミットしようとしたばかりの人がすべての作業を削除する理由がわからないので、この回答を追加します。

作業を続けて、そのコミットコマンドを「元に戻す」だけの場合(リポジトリにプッシュする前にキャッチしました):

git reset --soft HEAD~1

最後のコミット以降に進行中の作業を破棄したくない場合を除いて、--hardフラグを使用しないでください


5
理由の例を次に示します。コミットする開発サーバーで小さな作業を行います。次に、そのサーバーには発信HTTPSアクセスがないため、コミットをどこにもプッシュできないことがわかります。それが起こらなかったふりをして、ローカルマシンからパッチをやり直すのが最も簡単です。
Steve Bennett

1
@KarthikBose常にreflogがあります。git reset --hard HEAD~1以前の最新のコミットがreflogを介して利用可能になった後でも(期限が切れるまで)、こちらも参照してくださいgitready.com/intermediate/2009/02/09/...
codeling

4
ありがとう。この回答は上位にランク付けするか、受け入れられた回答に含める必要があります。コミットの削除!=コミットを元に戻します。
アルシエンデ2014年

2
@RandolphCarter:た​​だし、コミットされていない変更はすべて失われます。
naught101

7
@Robの1つの例は、ソース管理にしてはならないシークレット(パスワードなど)を含むファイルを誤ってコミットした場合です。ローカルコミットをしなければならない破壊され、それがサーバーにプッシュしない飽きないだろうので、ちょうど、取り消されません。
Bob Meyers 2016年

142

コミット全体を削除する

git rebase -p --onto SHA^ SHA

明らかに、「SHA」を削除したい参照に置き換えます。そのコマンドの「^」はリテラルです。

http://sethrobertson.github.io/GitFixUm/fixup.html#change_deep


26
どうすればこの回答をもっと賛成できますか??? 他のソリューションは、それを対話的に行う方法、または上位のコミットを削除する方法を示しています。
リバマー

5
-p, --preserve-merges マージコミットが導入するコミットを再生して履歴を平坦化する代わりに、マージコミットを再作成します。マージ競合解決またはマージコミットの手動修正は保持されません。
ライツ

5
これが実際の正確な答えです
Hamman Samuel

9
「SHAを削除したい参照で置き換える」とありますが、この行にはSHAが2回あります。これが私がしたことです。git rebase -p --onto 5ca8832c120 ^ 5ca8832c120しかし、何も変わっていません。同じSHAを2回使用することになっていますか?そうでない場合、コミットを削除するためのSHAはどれで、他のSHAはどうあるべきですか?
ルービックマン

3
うわー、それは完璧に働いた!これは受け入れられる答えになるはずです!
Liran H

51

変更を公開しなかった場合、最新のコミットを削除するには、次のようにします

$ git reset --hard HEAD^

(これにより、コミットされていない変更もすべて削除されることに注意してください。注意して使用してください)。

削除予定のコミットをすでに公開している場合は、git revertを使用してください

$ git revert HEAD

それはうまくいきませんでした。git logを実行しても、なぜそれを実行しても、コミットが追加されるだけで、すべてが残っています。歴史を片付けたい。
コスタ

@Costa:機能しなかったもの(つまり、どのバージョンを使用したか)と、どのようにgit logを行いましたか?
JakubNarębski、2014年

私はこのQ&Aでほとんどすべてを試しました。(最近、git revert HEADを試しました)私のgitログ:tree = log --all --graph --format=format:'%C(bold blue)%h%C(reset) %C(dim black)%s%C(reset)%C(bold red)%d%C(reset) %C(green)by %an, %ar%C(reset)'
コスタ

1
コミットを削除したいだけです(まるで存在しないかのように)。私はいくつかの奇妙なコーディングの冒険に出かけました、いくつかの新しいコミットで、そしてそれはすべてゴミになりました。どうすればgitログからそれらを消去できますか?
コスタ

2
神聖ながらくたが魔法のように私が望んだことを正確に実行しました...それらのコマンドのどれがそれをしましたか?
コスタ

45

リポジトリからコミット2と4を削除したいとします。

commit 0 : b3d92c5
commit 1 : 2c6a45b
commit 2 : <any_hash>
commit 3 : 77b9b82
commit 4 : <any_hash>

注:およびを使用しているため、リポジトリに対する管理者権限が必要です。--hard-f

  • git checkout b3d92c5 最後に使用可能なコミットをチェックアウトします。
  • git checkout -b repair 作業する新しいブランチを作成します。
  • git cherry-pick 77b9b82 コミット3を実行します。
  • git cherry-pick 2c6a45b コミット1を実行します。
  • git checkout master チェックアウトマスター。
  • git reset --hard b3d92c5 マスターを最後の使用可能なコミットにリセットします。
  • git merge repair 新しいブランチをマスターにマージします。
  • git push -f origin master マスターをリモートリポジトリにプッシュします。

1
最後のステップはgit push -f origin masterオプションがないはずです--hard
Vivex 2018年

2
commit 0より古いと思いcommit 1ます。最初にcommit 3(cherry-pickで)を実行し、次にを実行する理由を教えてくださいcommit 1b3d92cdcommit 0)のチェックアウト後commit 1、チェリーピックを期待しcommit 3ます。ありがとう。
Jarek C

@JarekC私は何かが間違っていない限り、一番上のコミットが最新のコミットだと思います...
Jeff Huijsmans

41
git reset --hard commitId

git push <origin> <branch> --force

PS:CommitIdは、元に戻したいものを指します


git push --force <origin> <branchName>。ブランチ名について言及しないと、リモート上のすべてのファイルが変更される可能性があります。
sheelpriy

39

履歴を強制的に変更

最後のコミットを削除するだけでなく、最後のn個のコミットの特定のコミットを削除する場合は、次のようにします。

git rebase -i HEAD~<number of commits to go back>なのでgit rebase -i HEAD~5、最後の5つのコミットを確認したい場合は、

次に、テキストエディタで、削除するすべてのコミットの横に単語pickを変更しdropます。エディターを保存して終了します。出来上がり!

追加的に変更履歴

お試しくださいgit revert <commit hash>Revertは、指定されたコミットを取り消す新しいコミットを作成します。


dropキーワードが定義されていません。コミットを削除するには、行全体を削除してください。
Shayan Salehian 2018

1
私にとって、ドロップはキーワードとして定義されていましたが、ドロップを実行しても、履歴からコミットが削除されたようには見えませんでした。ただし、インタラクティブリベースから行を削除すると、削除されました。
Adam Parkin

これはまさに私が必要としたものです。よく働く; ありがとう!
diekunstderfuge

30

最新のコミットを修正したい場合は、次のようにして、コミットを元に戻し、その中のファイルをアンステージできます。

git reset HEAD~1

これにより、リポジトリがファイルをステージングしたgit addコマンドの前の状態に戻ります。変更は作業ディレクトリにあります。HEAD〜1は、ブランチの現在のティップの下のコミットを指します。

N個のコミットをコミット解除したいが、コードの変更は作業ディレクトリに残したい場合:

git reset HEAD~N

最新のコミットを取り除き、コードの変更を保持したくない場合は、「ハード」リセットを実行できます。

git reset --hard HEAD~1

同様に、最後のN回のコミットを破棄し、コードの変更を保持したくない場合:

git reset --hard HEAD~N

22
git rebase -i HEAD~2

ここで「2」は、リベースするコミットの数です。

'git rebase -i HEAD`

すべてのコミットをリベースする場合。

次に、これらのオプションのいずれかを選択できます。

p, pick = use commit

r, reword = use commit, but edit the commit message

e, edit = use commit, but stop for amending

s, squash = use commit, but meld into previous commit

f, fixup = like "squash", but discard this commit's log message

x, exec = run command (the rest of the line) using shell

d, drop = remove commit

これらの行は並べ替えることができます。それらは上から下に実行されます。ここで行を削除すると、そのコミットは失われます。ただし、すべて削除すると、リベースは中止されます。空のコミットはコメントアウトされていることに注意してください

オプション "d"を使用してそのコミットを削除するか、コミットを含む行を削除するだけです。


最新のgitバージョンでは、オプションdはありません。コミットを含む行をリベースから削除するだけで削除できます。
Oleg Abrazhaev

17

ローカルブランチで削除するには、次を使用します

git reset --hard HEAD~1

リモートブランチで削除するには、次を使用します

git push origin HEAD --force

12

[素早い回答]

あなたは多くの選択肢があります、例えば:

  • 代替1:

    git rebase -i <YourCommitId>~1
    

    YourCommitIdを、元に戻したいコミットの番号に変更します。

  • 代替2:

    git reset --hard YourCommitId
    git push <origin> <branch> --force
    

    YourCommitIdを、元に戻したいコミットの番号に変更します。

    進行中の作業が失われる可能性があるため、このオプションはお勧めしません。

  • 代替3:

    git reset --soft HEAD~1
    

    作業を維持して、コミットのみを取り消すことができます。


サンキューサンキューサンキューサンキューサンキュー(Y)
ハビブレーマン

11

出典:https : //gist.github.com/sagarjethi/c07723b2f4fa74ad8bdf229166cf79d8

最後のコミットを削除する

例えばあなたの最後のコミット

git push origin + aa61ab32 ^:master

今、あなたはこのコミットを削除したいので、これを行う簡単な方法

手順

  1. 最初にブランチを現在のコミットの親にリセットします

  2. それをリモートに強制的にプッシュします。

git reset HEAD^ --hard

git push origin -f

特定のコミットの場合、リセットしたいのは以下です

git reset bb676878^ --hard

git push origin -f

9

これを行う別の方法を次に示します。

元に戻すブランチをチェックアウトし、ローカルの作業用コピーを、リモートサーバー上の最新のものにするコミットにリセットします(それ以降はすべてバイバイ)。これを行うには、SourceTreeでを右クリックして、「BRANCHNAMEをこのコミットにリセット」を選択しました。コマンドラインは:

git reset --hard COMMIT_ID

ブランチをリモートからチェックアウトしたので、ローカルで変更して失うことを心配する必要はありません。しかし、あなたがそうした場合、これはそれらを失うでしょう。

次に、リポジトリのローカルディレクトリに移動して、次のコマンドを実行します。

git -c diff.mnemonicprefix=false -c core.quotepath=false \
push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

これにより、ローカルリポジトリ内の現在のコミット以降のすべてのコミットが消去されますが、その1つのブランチについてのみです。


9

間違い:

私はgit rebase -i --root自分のブランチを使用しましたが、マスター(GitHub for Windows)とは異なる最初のコミットを言い換えることができると考えていましたデフォルトビューはマスターとの比較であり、全体を隠しています)。

900以上のコミットがSublimeにロードされる間、私はシリコンバレーのひげを育てました。変更せずに終了し、バッテリーを充電してからひげそりに進みました。900人以上の個人がさりげなくリベースし、コミット時間を現在にリセットしています。

Gitを打ち負かして元の時間を維持することを決意したため、このローカルリポジトリを削除し、リモートから再クローンしました。

これで、削除したいマスターに最新の不要なコミットが再度追加されたので、そのように続行しました。

オプションを使い果たす:

したくなかった git revert -それは追加のコミットを作成し、Gitを優勢にしました。

git reset --hard HEAD チェックした後、何もしませんでした reflogた。最後で唯一HEADのクローンでした-Gitが勝利しました。

最新のSHAを取得するために、github.comでリモートレポジトリを確認しました-少し勝ちました。

考えた後 git reset --hard <SHA>うまくいったた、私はもう1つのブランチをmasterと1 ... 2 ...に更新しました。コミットが戻ってきました-Gitが勝利しました。

マスターに戻ってチェックアウトし、試行してgit rebase -i <SHA>から、行を削除してください... 「ここで行を削除すると、そのコミットは失われます」。ああ... n00bの新機能をトロールして、 2.8.3リリースノート

ソリューション:

git rebase -i <SHA> その後 d, drop = remove commit

確認するために、別のブランチにチェックアウトしました。マスターからフェッチ/プルするコミットを非表示にする必要はありません。

https://twitter.com/holman/status/706006896273063936

あなたに良い日。


8

上記のすべてのコマンドは、作業ツリーとインデックスの状態をコミット前の状態に復元しますが、リポジトリの状態は復元しません。これを見ると、「削除された」コミットは実際には削除されておらず、単に現在のブランチの先端にあるコミットではありません。

磁器のコマンドでコミットを削除する方法はないと思います。唯一の方法は、ログとreflogから削除してからを実行することgit prune --expire -nowです。


1
StackOverflowで回答が表示される順序は固定されていません。「上記のすべてのコマンド」を参照しないでください。あなた自身の答えを自己完結させてください。
Pascal Cuoq 2014年

この答えは完全に正しいわけではありません。git prune は実際には「磁器」コマンドの1つです。また、reflogを完全に消去することはまれです(1つのユースケースは、リポジトリから機密情報を削除することですが、私が言ったように、これはまれなユースケースです)。多くの場合、データを回復する必要がある場合に備えて、reflogに古いコミットを保持しておくことをお勧めします。Pro Git:9.7 Git Internals-Maintenance and Data Recoveryを参照してください。

8

履歴を保持したい場合は、コミットと復帰を表示するには、以下を使用する必要があります。

git revert GIT_COMMIT_HASH

元に戻す理由を説明するメッセージを入力してから、次のようにします。

git push  

発行git logすると、「間違った」コミットメッセージと元に戻すログメッセージの両方が表示されます。


はい、しかしOPはそれが彼らの望んでいないことは明らかでした。
Steve Bennett

7

最後のコミットを台無しにしただけで(間違ったメッセージ、いくつかの変更を追加するのを忘れた)、それをパブリックリポジトリにプッシュする前に修正したい場合は、なぜ使用しないでください。

git commit --amend -m "New message here"

新しくステージングされた変更がある場合、それらは最後のコミット(削除しようとしている)と結合され、そのコミットを置き換えます。

もちろん、コミットした後でコミットを修正すると、履歴が書き換えられるので、その場合はその影響を必ず理解してください。

以前のコミットのメッセージを使用したい場合は、「-m」の代わりに「--no-edit」オプションを渡すこともできます。

ドキュメント:http : //git-scm.com/docs/git-commit.html


2
それはOPが求めているものではありません。
Steve Bennett

5

すでにプッシュしている場合は、まずHEAD ($ GIT_COMMIT_HASH_HERE)にしたいコミットを見つけてから、次のコマンドを実行します。

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force

次に、リポジトリが複製された各場所で、次のコマンドを実行します。

git reset --hard origin/master

5

私がコミットしてプッシュするときに通常行うこと(誰かがコミットをプッシュした場合、これで問題が解決します):

git reset --hard HEAD~1

git push -f origin

この助けを願っています


5

もう押しました。一部のコミットをリモートで返す必要があります。持っては、多くのバリエーションを試してみましたが、唯一このからジャスティンのgitブッシュを経由して私のために正常に動作されています。

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force

4

ローカルブランチでリセット

git reset --hard HEAD~<Number of commit> So git reset --hard HEAD~3

強制的に原点にプッシュ

git push -f origin

3

コードを一時フォルダにバックアップします。次のコマンドはサーバーと同じようにリセットされます。

git reset --hard HEAD
git clean -f
git pull

変更を保存し、最近のコミットを削除したい場合

git reset --soft HEAD^
git pull


2

ローカルコミットを削除する

上の画像を見るとわかるように、revert "test change 2" commit(SHA1 ID:015b5220c50e3dfbb1063f23789d92ae1d3481a2gitkgit bashのコマンドを使用してSHA1 IDを取得できます))を削除します。

そのために使用できます(以下のすべてのコマンドはローカルでのみ機能します。削除後にプッシュする必要があります):

  1. git reset --hard 515b5220c50e3dfbb1063f23789d92ae1d3481a2//そのコミットにバックアップします(テスト変更4コミットのSHA1 ID は515b5220c50e3dfbb1063f23789d92ae1d3481a2です
  2. git reset --hard HEAD~1 // 1つのコミットの前にバックアップします。
  3. git reset --hard HEAD^ // gitから最後のコミットを削除する

削除後:

コミット削除後


2

git reset --hard HEAD~1
あなたは今、前の頭にいます。枝を引っ張る。新しいコードをプッシュします。コミットはgitから削除されます


すでに変更をプッシュしていない限り。その場合、ハードリセットはリモコンをクリーンアップしません。その場合、リベースが適切なオプションです
c0der512

1

git reset --hard

git push origin HEAD --force

1つ以上のコミットにタグが付けられている場合は、最初にタグを削除します。それ以外の場合、タグ付きコミットは削除されません。



0

私の場合、この目的のための私の魔法のコードはこれです:

git reset --hard @{u}

テストして教えてください。私はいくつかの異なるものを試しましたが、これが私を助けた唯一のものでした。

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