間違ったGitブランチへのコミットを修正する方法は?


621

私は間違ったブランチに完全に良いコミットをしました。masterブランチの最後のコミットを元に戻し、同じ変更を加えてアップグレードブランチに取り込むにはどうすればよいですか?

回答:


975

まだ変更をプッシュしていない場合は、ソフトリセットを実行することもできます。

git reset --soft HEAD^

これはコミットを元に戻しますが、コミットされた変更をインデックスに戻します。ブランチがお互いに関して比較的最新であると仮定すると、gitは他のブランチへのチェックアウトを可能にし、その後すぐにコミットすることができます:

git checkout branch
git commit

欠点は、コミットメッセージを再入力する必要があることです。


10
ソフトリセットでは、変更がステージングされ、コミットする準備ができていることに注意してください。ソフトリセット後にファイルが変更された状態に戻ることがIDEに表示されなかったとき、少し混乱しました。
mtjhax 2012年

9
完璧な修正、実際にはいくつかのコミットがあったので、HEAD ^^とbamはすべて肉汁でした
パブロ

8
ありがとう。これは私を2度救った。ブランチが多少異なる場合は、リセット後、チェックアウト前に、別のブランチをチェックアウトする前に変更を隠しておく必要がある場合があります。チェックアウト後にスタッシュを再適用します
Kirby

17
zshのユーザー:あなたがそうのように^をエスケープする必要があるかもしれません:git reset --soft HEAD\^
スティーブンFuhry

54
もっと得たら?Windowsコマンドラインで、引用符を使用してHEAD ^を次のように囲みます。git reset --soft "HEAD ^"
Nate Cook

141

このトピックについては4年遅れていますが、これは誰かに役立つかもしれません。

コミットする前に新しいブランチを作成するのを忘れて、マスターですべてをコミットした場合は、コミットの数に関係なく、次のアプローチの方が簡単です。

git stash                       # skip if all changes are committed
git branch my_feature
git reset --hard origin/master
git checkout my_feature
git stash pop                   # skip if all changes were committed

これで、マスターブランチがに等しくなりorigin/master、すべての新しいコミットがオンになりmy_featureます。my_featureはローカルブランチであり、リモートブランチではないことに注意してください。


答えてくれてありがとう。今、私はegitを使用していますが、次のことを実行して同じことを達成できるかどうか疑問に思っています:1)現在の「master」の名前を「my_feature」に変更します。2)「origin / master」からローカル「master」を再作成します。これらの操作の
背後でegit

なぜ合併?あなたは直接のブランチを作成することができmaster、その後リセットし、masterorigin/master
caesarsol 2015年

1
これが最も興味深い部分origin/masterです。リセットしたいコミットがすでにコミットされているので、多くのコミットは必要ありません。:先端のためのクレジットは、しかし、このページでgithub.com/blog/...
caesarsol

4
これは受け入れられる答えになるはずです。シンプルで明白でわかりやすいものは、コミットの数に関係なく機能し、基本的なGit機能のみを使用します。TortoiseGitでこれらの手順を実行しました。ありがとう!:)
Ian Grainger

1
これが最良の答えだと思いましたが、制限があります。最近リモートからプルした場合にのみ役立ちます。そして、それはあなたが最初にリモコンを持っていると仮定しています。ローカルブランチに "マスター"のみがあり、新しい機能が修正されている場合、正しい答えは、マスターを特定の数のコミットをカウントしてリセットすることです。
pauljohn32 2018年

111

クリーンな(変更されていない)作業コピーがある場合

1つのコミットをロールバックするには(次のステップのコミットのハッシュに注意してください):

git reset --hard HEAD^

そのコミットを別のブランチにプルするには:

git checkout other-branch
git cherry-pick COMMIT-HASH

変更または追跡されていない変更がある場合

また、これにより、追跡されていない変更や変更が強制終了git reset --hardされるため、変更がある場合は次のようにしてください。

git reset HEAD^
git checkout .

git rev-parse BRANCH_NAMEシャを得るために。
ヴィルヘルムテル

12
最初にハッシュを書き忘れた場合は、単にgit reflog show <branch>
カスカベル

2
@Jefromiちょっと怖かった。
Ian Hunter

13
安全性を高めるために、最初に正しいブランチでチェリーピックを実行してから、間違ったブランチをリセットしてください。
Mooij氏の年齢11

1
また、追跡されていない変更の場合はgit stash、リセットの前に、git stash pop後で使用してそれらを復元することができるため、--hardパーツを恐れる必要はありません
Clemens Klein-Robbenhaar

20

すでに変更をプッシュしている場合は、HEADをリセットした後、次のプッシュを強制する必要があります。

git reset --hard HEAD^
git merge COMMIT_SHA1
git push --force

警告:ハードリセットは作業コピーのコミットされていない変更を元に戻しますが、強制プッシュはリモートブランチの状態をローカルブランチの現在の状態で完全に上書きします。

念のため、Windowsでは(BashではなくWindowsコマンドラインを使用)、実際^^^^には1つではなく4つなので、

git reset --hard HEAD^^^^

6
絶対に必要でない限り、他の人が使用しているブランチに強制プッシュしないでください。そうしないと、リベースするまでプッシュできなくなります。ただし、gitを使用する唯一の開発者であれば、これで問題ありません。
ブレアホロウェイ2010年

2
または、誰かが誤ったコミットをプルする前に十分に迅速に気づかない限り。
マイケルミオール

:あなたはより多くの1がオフにコミットするよりも場合は、あなたが必要なコミットを指定することができます git reset --hard COMMIT_HASH git push --force
デヴィッドCramblett

17

私は最近同じことをしましたが、誤ってマスターに変更をコミットしましたが、他のブランチにコミットするべきでした。しかし、私は何も押しませんでした。

間違ったブランチにコミットしただけで、その後何も変更しておらず、リポジトリにプッシュしていない場合は、次のようにすることができます。

// rewind master to point to the commit just before your most recent commit.
// this takes all changes in your most recent commit, and turns them into unstaged changes. 
git reset HEAD~1 

// temporarily save your unstaged changes as a commit that's not attached to any branch using git stash
// all temporary commits created with git stash are put into a stack of temporary commits.
git stash

// create other-branch (if the other branch doesn't already exist)
git branch other-branch

// checkout the other branch you should have committed to.
git checkout other-branch

// take the temporary commit you created, and apply all of those changes to the new branch. 
//This also deletes the temporary commit from the stack of temp commits.
git stash pop

// add the changes you want with git add...

// re-commit your changes onto other-branch
git commit -m "some message..."

注:上記の例では、1つのコミットをgit reset HEAD〜1で巻き戻していました。ただし、n個のコミットを巻き戻したい場合は、git reset HEAD〜nを実行できます。

また、間違ったブランチにコミットしてしまい、間違ったブランチにコミットしたことに気づく前にコードを書き終えた場合は、git stashを使用して進行中の作業を保存できます。

// save the not-ready-to-commit work you're in the middle of
git stash 

// rewind n commits
git reset HEAD~n 

// stash the committed changes as a single temp commit onto the stack. 
git stash 

// create other-branch (if it doesn't already exist)
git branch other-branch

// checkout the other branch you should have committed to.
git checkout other-branch

// apply all the committed changes to the new branch
git stash pop

// add the changes you want with git add...

// re-commit your changes onto the new branch as a single commit.
git commit -m "some message..."

// pop the changes you were in the middle of and continue coding
git stash pop

注:このWebサイトを参照として使用しました https://www.clearvision-cm.com/blog/what-to-do-when-you-commit-to-the-wrong-git-branch/


同様のことが私にも起こりました、masterにいくつかの変更をコミットしましたが、新しいブランチで実行してPRを送信する必要がgit checkout -b new_branchありました。もう一度コミットする必要があります。
Nishchal Gautam 2017

11

したがって、masterコミットしたがコミットするつもりanother-branchである(まだ存在していない場合もある)シナリオで、まだプッシュしていない場合、これは簡単に修正できます。

// if your branch doesn't exist, then add the -b argument 
git checkout -b another-branch
git branch --force master origin/master

これで、すべてのコミットmasterがオンになりますanother-branch

出典:http : //haacked.com/archive/2015/06/29/git-migrate/


最も簡単なアプローチのようです!なぜそんなに愛と賛否が少ないのかわからない
keligijus

4
これは私にはうまくいかなかったようです。another-branchすでに存在しています。この場合、それは私がマスターするために行ったコミットを無効にしただけで、それらをオンにしませんでしたanother-branch
ジゼルセレート2018

6

この回答について詳しく説明するために、たとえば次のdevelopように移動するコミットが複数ある場合new_branch

git checkout develop # You're probably there already
git reflog # Find LAST_GOOD, FIRST_NEW, LAST_NEW hashes
git checkout new_branch
git cherry-pick FIRST_NEW^..LAST_NEW # ^.. includes FIRST_NEW
git reflog # Confirm that your commits are safely home in their new branch!
git checkout develop
git reset --hard LAST_GOOD # develop is now back where it started

1
私は元に戻すために3つのコミットをしました、そしてこの質問は私のお尻を火から引き離したようです。ありがとう!
holdenweb

3

この問題が発生し、Visual Studioを使用している場合は、次のことができます。

ブランチを右クリックして、次を選択しますView History

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

戻りたいコミットを右クリックします。必要に応じて、元に戻すかリセットします。

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


3

間違ったブランチでの複数のコミット

もしあなたのために、それがちょうど1つのコミットであるならば、利用可能な他の多くのより簡単なリセットソリューションがたくさんあります。私の場合、誤って約10回のコミットが行われたため、それをmaster呼び出しましょうbranch_xyz。コミット履歴を失いたくありませんでした。

あなたが何ができるか、そして私を救ったのは、この回答を参照として使用して、4ステップのプロセスを使用していたことです。

  1. から新しい一時ブランチを作成 master
  2. もともとコミットを目的としたブランチにマージします。 branch_xyz
  3. コミットを元に戻す master
  4. 一時的なブランチを削除します。

上記の手順の詳細は次のとおりです-

  1. master(誤って多くの変更をコミットした) から新しいブランチを作成します

    git checkout -b temp_branch_xyz
    

    注:-bフラグは、新しいブランチを作成するために使用されます。
    これが正しいかどうかを確認するためgit branchに、temp_branch_xyzブランチにいるgit logことを確認し、コミットが正しいかどうかを確認します。

  2. 一時的なブランチを、もともとコミット用に意図されたブランチ、つまりにマージしbranch_xyzます。
    まず、元のブランチに切り替えbranch_xyzます(そうでない場合はgit fetch、必要になる可能性があります)。

    git checkout branch_xyz
    

    注:-bフラグを使用しない
    ここで、一時的なブランチを現在チェックアウトしているブランチにマージしましょうbranch_xyz

    git merge temp_branch_xyz
    

    競合がある場合は、ここでいくつかの競合に注意する必要があります。マージが成功したら、プッシュする(そうする)か、次のステップに進むことができます。

  3. この回答を参照としてmaster使用する際の誤ったコミットを元に戻し、最初にmaster

    git checkout master
    

    その後、元に戻してリモートに一致させる(または必要に応じて特定のコミットに戻す)

    git reset --hard origin/master
    

    繰り返しgit logますが、意図した変更が反映されるようにするために、私は前後に実行します。

  4. 証拠を消去すると、一時的なブランチが削除されます。そのためには、まずtempがマージされたブランチをチェックアウトする必要がありbranch_xyzます(つまり、このままでmaster以下のコマンドを実行すると、が表示される可能性がありますerror: The branch 'temp_branch_xyz' is not fully merged)。

    git checkout branch_xyz
    

    そして、この事故の証拠を削除します

    git branch -d temp_branch_xyz
    

どうぞ。


1

変更を適用したいブランチがすでに存在する場合(ブランチ開発など)、以下のfotanusによって提供された指示に従ってください。

git checkout develop
git rebase develop my_feature # applies changes to correct branch
git checkout develop # 'cuz rebasing will leave you on my_feature
git merge develop my_feature # will be a fast-forward
git branch -d my_feature

そして、明らかにあなたが使用することができtempbranchの代わりに、または任意の他の支店名をmy_featureあなたが望んでいた場合。

また、該当する場合は、ターゲットブランチでマージするまで、スタッシュポップ(適用)を遅らせます。


最初のコマンド(checkout develop)は不要だと思います...リベースは最初に実行する "my_feature"をチェックアウトします。
JoelFan 2017

また、「rebase」コマンドの「my_feature」パラメーターを省略することもできます(「my_feature」をすでにチェックアウトしているため)。「merge」の「develop」パラメータを
省略

1

私にとって、これは私がプッシュしたコミットを元に戻し、そのコミットを他のブランチにチェリーピックすることで解決しました。

git checkout branch_that_had_the_commit_originally
git revert COMMIT-HASH
git checkout branch_that_was_supposed_to_have_the_commit
git cherry pick COMMIT-HASH

を使用git logして正しいハッシュを見つけることができ、いつでもこれらの変更をプッシュできます。

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