gitリポジトリから変更をプルするとします。次に、レポフォースの作成者が中央レポにプッシュします。履歴が書き換えられているので引っ張れません。
作成者が正しいバージョンを強制的にプッシュしたと仮定して、新しいコミットをプルする(そして古いコミットを破棄する)にはどうすればよいですか?
これは悪いgitワークフローであることは知っていますが、これを避けられない場合もあります。
gitリポジトリから変更をプルするとします。次に、レポフォースの作成者が中央レポにプッシュします。履歴が書き換えられているので引っ張れません。
作成者が正しいバージョンを強制的にプッシュしたと仮定して、新しいコミットをプルする(そして古いコミットを破棄する)にはどうすればよいですか?
これは悪いgitワークフローであることは知っていますが、これを避けられない場合もあります。
あなたがあなたの仕事を捨てたいならば、fetch
そしてreset
。たとえば、次の名前のリモートと次の名前origin
のブランチがある場合master
:
$ git fetch origin
$ git reset --hard origin/master # Destroys your work
作業を破棄したくない場合は、を実行する必要がありますgit rebase --onto
。古いものorigin
が次のようになっているとします。
A ---> B ---> C
^
origin/master
そして、あなたはこれを持っています:
A ---> B ---> C ---> X ---> Y ---> Z
^ ^
| master
origin/master
今、上流の変更は物事を変えます:
A ---> B ---> C ---> X ---> Y ---> Z
\ ^
---> B'---> C' master
^
origin/master
を実行する必要がありますgit rebase --onto origin/master <C> master
。ここで、はアップストリームを変更する前の古いブランチ<C>
のSHA-1です。origin/master
これはあなたにこれを与えます:
A ---> B ---> C ---> X ---> Y ---> Z
\
---> B'---> C'---> X'---> Y'---> Z'
^ ^
| master
origin/master
B、C、X、Y、およびZが「到達不能」になっていることに注目してください。それらは最終的にGitによってリポジトリから削除されます。その間(90日)、Gitは、間違いが判明した場合に備えて、reflogにコピーを保持します。
あなたが間違っていて、誤っていくつgit reset
かgit rebase
のローカルの変更を失った場合は、reflogで変更を見つけることができます。
コメントでは、ユーザーが提案git reflog expire
して--expire=now
いますが、このコマンドを実行しないでください。これにより、セーフティネットが破壊されます。reflogを使用する目的は、間違ったコマンドを実行したときにGitが首を救うことがあるようにすることです。
基本的に、このコマンドが行うことは、上記の例のB、C、X、Y、およびZコミットをすぐに破棄するため、それらを元に戻すことはできません。このコマンドを実行することによる実際のメリットはありませんが、ディスクスペースを少し節約できる可能性がありますが、Gitは90日後にすでにデータをパージするため、このメリットは短命です。
このシナリオのわずかに変更されたバージョンに出くわしました。これが私がしたことです:
A--->B--->C--->D--->E
|
local-1/master
A--->B--->C--->D--->E
|
origin/master
A--->B--->C--->D--->E
|
local-2/master
A--->B--->CDE
|
local-1/master
A--->B--->CDE
|
origin/master
A--->B--->C--->D--->E
|
local-2/master
$ git reset --soft B
A--->B---> (local uncommitted changes)
|
local-2/master
$ git stash save "backup"
A--->B
|
local-2/master
$ git pull origin master
A--->B--->CDE
|
local-2/master
ローカルブランチに変更を加えていない場合は、次の一連のコマンドを試すことができます。これは、あなたが求めていることを達成するための大雑把な方法であることを忘れないでください。
git checkout master
git pull
git remote update origin -p
git branch -D myBranch
git checkout myBranch
git remote update origin -p
オプションです。
変更を加え、ローカルブランチの内容を気にしない場合は、次のことを試すことができます。
git stash
git stash drop
git checkout master
git pull
git remote update origin -p
git branch -D myBranch
git checkout myBranch
どちらのテクニックも本当に長くて面倒です。しかし、仕事を終わらせてください。
ローカルコミットがない場合、これにより強制プッシュからチェックアウトが回復します。リモートブランチの最新情報を入手し、後でローカル作業をコミットできます。
git fetch
git stash
git reset --hard origin/master # destroys your work
git stash pop # restores your work as local changes
git mergetool # fix any conflicts
この時点で、以前と同じようにローカルの変更があります。チェックアウトは、マスターまたは作業中のブランチのすべての変更について最新です。