マスターすることをコミットした最後のコミットを新しいブランチに移動し、それらのコミットが行われる前にマスターを戻します。残念ながら、私のGit-fuはまだ十分に強力ではありません。
すなわちどうやってこれから行けますか
master A - B - C - D - E
これに?
newbranch C - D - E
/
master A - B
警告: 最初のコマンドgit branch newbranch
で新しいブランチを作成しているので、この方法はうまくいきます。コミットを 既存のブランチに移動したい場合 git reset --hard HEAD~3
を実行する前に変更内容を既存のブランチにマージする必要があります(下記の既存のブランチへの移動を参照)。 最初に変更内容をマージしないと、変更内容は失われます。
他に状況が関係していない限り、これは分岐してロールバックすることで簡単に行えます。
# Note: Any changes not committed will be lost.
git branch newbranch # Create a new branch, saving the desired commits
git reset --hard HEAD~3 # Move master back by 3 commits (GONE from master)
git checkout newbranch # Go to the new branch that still has the desired commits
しかし、元に戻すコミット数を確認してください。あるいは、HEAD~3
の代わりに、master(/ current)ブランチで「元に戻す」コミットのハッシュ(またはOrigin/masterのような参照)を指定することもできます。 :
git reset --hard a1b2c3d4
* 1あなたは only masterブランチからコミットを "失う"ことになるでしょう、しかし心配しないでください、あなたはそれらのコミットをnewbranchに持つでしょう!
警告: Gitバージョン2.0以降では、後で元の(master
)ブランチに新しいブランチをgit rebase
した場合、繰り越されたコミットを失うことを避けるために明示的な--no-fork-point
オプションが必要になるかもしれません。 branch.autosetuprebase always
を設定すると、これが起こりやすくなります。詳細については、 John Mellorの回答 を参照してください。
コミットを 既存のブランチ に移動したい場合は、このようになります。
git checkout existingbranch
git merge master
git checkout master
git reset --hard HEAD~3 # Go back 3 commits. You *will* lose uncommitted work.
git checkout existingbranch
それがなぜうまくいくのか疑問に思う人のために(私が最初にいたように):
Cに戻り、DとEを新しいブランチに移動したいとします。これは、最初は次のようになります。
A-B-C-D-E (HEAD)
↑
master
git branch newBranch
の後:
newBranch
↓
A-B-C-D-E (HEAD)
↑
master
git reset --hard HEAD~2
の後:
newBranch
↓
A-B-C-D-E (HEAD)
↑
master
分岐は単なるポインタなので、 master は最後のコミットを指しています。 newBranch を作ったとき、あなたは単に最後のコミットへの新しいポインタを作っただけです。それからgit reset
を使って master ポインタを2コミット戻しました。しかし、あなたは newBranch を動かさなかったので、それはまだそれが最初に行ったコミットを指しています。
この場合、sykoraによって公開された方法が最良の選択肢です。しかし時にはそれが最も簡単ではなく、一般的な方法でもありません。一般的な方法では git cherry-pick を使います。
OPが望んでいることを達成するために、それは2段階のプロセスです。
newbranch
にあなたが望むmasterからのコミットを書き留めますExecute
git checkout master
git log
(例えば3)のハッシュがnewbranch
に必要なコミットをしていることに注意してください。ここで私は使用します:
Cコミット:9aa1233
Dコミット:453ac3d
Eコミット:612ecb3
注: /最初の7文字または全コミットハッシュを使用できます
newbranch
に置くgit checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233
git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233
git cherry-pick これら3つのコミットをnewbranchに適用します。
たった2つのコマンドを使用してこれを実行するもう1つの方法。現在の作業ツリーもそのまま残します。
git checkout -b newbranch # switch to a new branch
git branch -f master HEAD~3 # make master point to some older commit
古いバージョン - 私がgit branch -f
について学ぶ前
git checkout -b newbranch # switch to a new branch
git Push . +HEAD~3:master # make master point to some older commit
Push
を.
にできるようにすることは、知っておくといいニースのトリックです。
以下の場合:
master
をロールバックすることです。 それから、以下ははるかに簡単です(3つの誤ったコミットを持つブランチmaster
から始めます)。
git reset HEAD~3
git stash
git checkout newbranch
git stash pop
master
への取り消しはしますが、作業ファイルはすべてそのまま残します。master
作業ツリーをHEAD〜3状態と完全に一致させます。newbranch
に切り替えます通常どおりgit add
およびgit commit
を使用できるようになりました。すべての新しいコミットはnewbranch
に追加されます。
OPは、目標は変更を失うことなく「コミットする前にマスターに戻す」ことであり、この解決策はそれを実現することであると述べました。
私は誤ってmaster
ではなくdevelop
に誤ってコミットしたとき、少なくとも週に1回これを行います。通常、ロールバックするコミットは1つだけです。その場合、1行目でgit reset HEAD^
を使用するのが1つのコミットだけをロールバックするためのより簡単な方法です。
マスターの変更を上流にプッシュした場合はこれをしないでください
他の誰かがそれらの変更を引っ張ったかもしれません。ローカルマスターのみを書き換える場合は、アップストリームにプッシュしても影響はありませんが、書き換えられた履歴を共同編集者にプッシュすると頭痛の種になる可能性があります。
これは技術的な意味でそれらを「動かす」わけではありませんが、同じ効果があります。
A--B--C (branch-foo)
\ ^-- I wanted them here!
\
D--E--F--G (branch-bar)
^--^--^-- Opps wrong branch!
While on branch-bar:
$ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range)
A--B--C (branch-foo)
\
\
D-(E--F--G) detached
^-- (branch-bar)
Switch to branch-foo
$ git cherry-pick E..G
A--B--C--E'--F'--G' (branch-foo)
\ E--F--G detached (This can be ignored)
\ /
D--H--I (branch-bar)
Now you won't need to worry about the detached branch because it is basically
like they are in the trash can waiting for the day it gets garbage collected.
Eventually some time in the far future it will look like:
A--B--C--E'--F'--G'--L--M--N--... (branch-foo)
\
\
D--H--I--J--K--.... (branch-bar)
履歴を書き換えずにこれを行うには(つまり、既にコミットをプッシュしている場合):
git checkout master
git revert <commitID(s)>
git checkout -b new-branch
git cherry-pick <commitID(s)>
両方の枝は、力を加えずに押すことができます。
まさにこのような状況でした:
Branch one: A B C D E F J L M
\ (Merge)
Branch two: G I K N
私は実行しました:
git branch newbranch
git reset --hard HEAD~8
git checkout newbranch
私はHEADになると私は確信していましたが、コミットLは今です….
歴史の中で正しい場所に着地することを確実にするために、コミットのハッシュで作業することはより簡単です
git branch newbranch
git reset --hard #########
git checkout newbranch
1)すべての変更をnew_branchに移動する新しいブランチを作成します。
git checkout -b new_branch
2)それから古い枝に戻ります。
git checkout master
3)git rebaseをする
git rebase -i <short-hash-of-B-commit>
4)それから開かれたエディタは最後の3つのコミット情報を含みます。
...
pick <C's hash> C
pick <D's hash> D
pick <E's hash> E
...
5)これら3つのコミットすべてでpick
をdrop
に変更します。その後、保存してエディタを閉じます。
...
drop <C's hash> C
drop <D's hash> D
drop <E's hash> E
...
6)最後の3コミットが現在のブランチから削除されました(master
)。ブランチ名の前に+
の印を付けてブランチを強く押します.
git Push Origin +master
どうやってこれから行けますか
A - B - C - D - E
|
master
これに?
A - B - C - D - E
| |
master newbranch
2つのコマンドで
与える
A - B - C - D - E
|
newbranch
そして
与える
A - B - C - D - E
| |
master newbranch
すべてのnpushedコミットを新しいブランチに移動する必要がある場合は、次のようにします。
create a現在のブランチからの新しいブランチ:git branch new-branch-name
プッシュ your新しいブランチ:git Push Origin new-branch-name
元に戻す yourold(current)branch最後のプッシュ/安定状態:git reset --hard Origin/old-branch-name
upstreams
ではなくOrigin
を持っている人もいます。適切なupstream
を使用する必要があります
あなたはこれを行うことができます私が使ったことをちょうど3つの簡単なステップです。
1)最近の更新をコミットしたい場所に新しいブランチを作成します。
git branch <branch name>
2)新しいブランチでコミットするための最近のコミットIDを見つけます。
git log
3)そのコミットIDをコピーして、最新のコミットリストが一番上になるようにします。だからあなたはあなたのコミットを見つけることができます。あなたはまたメッセージを通してこれを見つけます。
git cherry-pick d34bcef232f6c...
コミットIDをいくつか指定することもできます。
git cherry-pick d34bcef...86d2aec
これであなたの仕事は終わりました。あなたが正しいIDと正しい枝を選んだなら、あなたは成功するでしょう。だから前にこれは注意してください。そうでなければ、別の問題が発生する可能性があります。
今すぐあなたのコードをプッシュすることができます
git Push