19

push -fリモートリポジトリで最後のコミット、つまりAをオーバーラップしていて、プッシュする前に他の人がAをプルした場合。

とにかく、他人に迷惑をかけないように、これを元に戻すには?

何も触れていないことを「ふりpush -f」することは、元の人にとって役に立ちますか?

または

git は、ローカル リポジトリがリモート トラッキング リポジトリから分岐しているかどうかをどのように判断しますか?

4

1 に答える 1

49

プッシュする前に元のHEADを見つける方法はいくつかあります(ORIG_HEADはおそらくそれらの1つではありません)。

ターミナルスクロールバック

運が良ければターミナルを開いたままにしておくと、プッシュが行われたときに次のような出力が表示されます。

...
To user@host:repo.git
 + abcdef0...1234567 HEAD -> branchname (forced update)

ここabcdef0に、前のHEAD(your A)があり1234567、代わりにそれを強制したものです。

git reflog

の出力は、git reflogあなたがしたことの時系列の履歴を示します。基本的に、問題の行(変更前にブランチをチェックアウトした場所)に戻り、最初の列からコミットIDを取得します。

ここで最も役立つコマンドはですgit reflog show remotes/origin/branchname。これにより、強制更新(1234567)と以前のコミットID(abcdef0)が上位2行に表示されます。

以前のリファレンス

ここでは、いくつかのコミット参照が役立つ場合があります。

  • @{1}(またはbranchname@{1}、そのブランチにいない場合)は、その参照の以前の値です。ローカルブランチに対して他のコミットを行っていない場合にのみ機能します。(ただし@{2}@{3}などを使用すると、さらに戻ることができます。)
  • 同様にremotes/origin/branchname@{1}、リモートのrefの以前の値になります。他の誰かがリモートにプッシュしていない場合にのみ機能します。(上記と同じ点@{n}です。)

正しいIDを持っていることを確認する

上記のいずれかの方法で取得したIDが正しいことを確認したい場合は、以下を確認してください。

git checkout abcdef0

周りを見回してください。見慣れている場合(リポジトリを参照するためのtiggit logもお勧めします。また、実行して特定のコミットからのログを確認することもできます)、適切な場所にリセットしていると確信できます。tig abcdef0

以前の状態にリセット

以前のコミットIDを取得したら、それにリセットして、もう一度強制的にプッシュできます。

git checkout branchname # if you're not on it already
git reset --hard abcdef0
git push -f

あるいは単に:

git push -f origin abcdef0:branchname

これにより、ブランチの状態が強制的にプッシュされる前の状態に復元されます。(クイックノート:最初のスニペットはリモートブランチだけでなくローカルブランチも更新します。2番目のスニペットはリモートのみを更新します。)

影響は何ですか?

強制的にプッシュしてからブランチをプルした場合、強制的に元に戻すと、後で更新するときに問題が発生します。そのブランチにコミットしていない場合は、ローカルブランチを削除して再チェックアウトするか(git fetch最新の参照があることを確認した後)、次のように実行します。

git fetch
git checkout branchname # if you're not on it already
git reset --hard origin/branchname

ローカルコミットを行った場合は、それらの変更を正しい履歴にリベースする必要があります(そして、競合を解決する可能性があります)。

git fetch
git checkout branchname # if you're not on it already
git rebase --onto origin/branchname 1234567

上記は、「 (正しいヘッド)の1234567上に(間違ったヘッド)の後にすべてのコミットを再生する」ことを意味origin/branchnameします。

于 2013-01-23T09:42:45.500 に答える