58

gitリポジトリから変更をプルするとします。次に、レポフォースの作成者が中央レポにプッシュします。履歴が書き換えられているので引っ張れません。

作成者が正しいバージョンを強制的にプッシュしたと仮定して、新しいコミットをプルする(そして古いコミットを破棄する)にはどうすればよいですか?

これは悪いgitワークフローであることは知っていますが、これを避けられない場合もあります。

4

4 に答える 4

112

ローカルの変更を破棄する

あなたがあなたの仕事を捨てたいならば、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 resetgit rebaseのローカルの変更を失った場合は、reflogで変更を見つけることができます。

コメントでは、ユーザーが提案git reflog expireして--expire=nowいますが、このコマンドを実行しないでください。これにより、セーフティネットが破壊されます。reflogを使用する目的は、間違ったコマンドを実行したときにGitが首を救うことがあるようにすることです。

基本的に、このコマンドが行うことは、上記の例のB、C、X、Y、およびZコミットをすぐに破棄するため、それらを元に戻すことはできません。このコマンドを実行することによる実際のメリットはありませんが、ディスクスペースを少し節約できる可能性がありますが、Gitは90日後にすでにデータをパージするため、このメリットは短命です。

于 2013-02-09T11:48:50.787 に答える
0

このシナリオのわずかに変更されたバージョンに出くわしました。これが私がしたことです:

最初の状態

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

ローカルの同期変更-2/マスター

$ 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
于 2018-09-28T16:19:00.447 に答える
0

ローカルブランチに変更を加えていない場合は、次の一連のコマンドを試すことができます。これは、あなたが求めていることを達成するための大雑把な方法であることを忘れないでください。

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

どちらのテクニックも本当に長くて面倒です。しかし、仕事を終わらせてください。

于 2020-08-11T11:57:43.993 に答える
0

ローカルコミットがない場合、これにより強制プッシュからチェックアウトが回復します。リモートブランチの最新情報を入手し、後でローカル作業をコミットできます。

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

この時点で、以前と同じようにローカルの変更があります。チェックアウトは、マスターまたは作業中のブランチのすべての変更について最新です。

于 2021-01-23T18:04:10.283 に答える