短い答え
実行したという事実を省略しgit push
、次のエラーを受け取ってから、実行を続行しましたgit pull
。
To git@bitbucket.org:username/test1.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@bitbucket.org:username/test1.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Gitが役立つように努力しているにもかかわらず、その「git pull」アドバイスは、おそらくあなたがやりたいことではありません。
あなたがいる場合:
- 「機能ブランチ」または「開発者ブランチ」だけで作業している場合は、実行
git push --force
して、リベース後のコミットでリモートを更新できます(user4405677の回答に従って)。
- 同時に複数の開発者がいるブランチで作業する場合、おそらく
git rebase
最初から使用するべきではありません。dev
からの変更で更新するにはmaster
、を実行するのではなくgit rebase master dev
、実行git merge master
中に実行する必要がありますdev
(ジャスティンの回答に従って)。
少し長い説明
Gitの各コミットハッシュは、いくつかの要因に基づいています。そのうちの1つは、その前にあるコミットのハッシュです。
コミットを並べ替えると、コミットハッシュが変更されます。リベース(何かを行う場合)は、コミットハッシュを変更します。これにより、との同期がとれていないgit rebase master dev
場所でのの実行結果は、オンと同じ内容であるが、その前にコミットオンが挿入された新しいコミット(およびハッシュ)を作成します。dev
master
dev
master
複数の方法でこのような状況になる可能性があります。私が考えることができる2つの方法:
master
自分のdev
作業のベースにしたいことにコミットすることができます
- あなた
dev
はすでにリモートにプッシュされているコミットを持っている可能性があり、それから次に変更に進みます(コミットメッセージの書き換え、コミットの並べ替え、コミットのスカッシュなど)
何が起こったのかをよく理解しましょう。例を示します。
リポジトリがあります:
2a2e220 (HEAD, master) C5
ab1bda4 C4
3cb46a9 C3
85f59ab C2
4516164 C1
0e783a3 C0
次に、コミットの変更に進みます。
git rebase --interactive HEAD~3 # Three commits before where HEAD is pointing
(ここで私の言葉を言う必要があります。Gitでコミットを変更する方法はいくつかあります。この例ではの時間を変更しましたがC3
、新しいコミットの挿入、コミットメッセージの変更、コミットの並べ替え、コミットをまとめてスカッシュするなど)
ba7688a (HEAD, master) C5
44085d5 C4
961390d C3
85f59ab C2
4516164 C1
0e783a3 C0
ここで、コミットハッシュが異なることに注意することが重要です。それらについて何か(何か)を変更したので、これは予想される動作です。これは大丈夫ですが、
プッシュしようとすると、エラーが表示されます(実行する必要があるというヒントも表示されますgit pull
)。
$ git push origin master
To git@bitbucket.org:username/test1.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@bitbucket.org:username/test1.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
を実行するとgit pull
、次のログが表示されます。
7df65f2 (HEAD, master) Merge branch 'master' of bitbucket.org:username/test1
ba7688a C5
44085d5 C4
961390d C3
2a2e220 (origin/master) C5
85f59ab C2
ab1bda4 C4
4516164 C1
3cb46a9 C3
0e783a3 C0
または、別の方法で示します:
そして今、ローカルで重複したコミットがあります。実行する場合はgit push
、サーバーに送信します。
この段階に到達しないようにするには、実行しますgit push --force
(代わりに実行しましたgit pull
)。これにより、新しいハッシュを含むコミットが問題なくサーバーに送信されます。この段階で問題を修正するために、実行前の状態にリセットできますgit pull
。
(REFLOGを見てgit reflog
ハッシュだったコミットかを確認する)前に、私たちが走りましたgit pull
。
070e71d HEAD@{1}: pull: Merge made by the 'recursive' strategy.
ba7688a HEAD@{2}: rebase -i (finish): returning to refs/heads/master
ba7688a HEAD@{3}: rebase -i (pick): C5
44085d5 HEAD@{4}: rebase -i (pick): C4
961390d HEAD@{5}: commit (amend): C3
3cb46a9 HEAD@{6}: cherry-pick: fast-forward
85f59ab HEAD@{7}: rebase -i (start): checkout HEAD~~~
2a2e220 HEAD@{8}: rebase -i (finish): returning to refs/heads/master
2a2e220 HEAD@{9}: rebase -i (start): checkout refs/remotes/origin/master
2a2e220 HEAD@{10}: commit: C5
ab1bda4 HEAD@{11}: commit: C4
3cb46a9 HEAD@{12}: commit: C3
85f59ab HEAD@{13}: commit: C2
4516164 HEAD@{14}: commit: C1
0e783a3 HEAD@{15}: commit (initial): C0
上記ba7688a
は、実行前のコミットでしたgit pull
。そのコミットハッシュを取得したら、リセットして(git reset --hard ba7688a
)に戻し、実行できgit push --force
ます。
これで完了です。
しかし、待って、重複したコミットに基づいて作業を続けました
どういうわけかコミットが重複していることに気付かず、重複したコミットの上で作業を続行し続けた場合は、本当にごちゃごちゃしています。混乱のサイズは、重複の上にあるコミットの数に比例します。
これはどのように見えるか:
3b959b4 (HEAD, master) C10
8f84379 C9
0110e93 C8
6c4a525 C7
630e7b4 C6
070e71d (origin/master) Merge branch 'master' of bitbucket.org:username/test1
ba7688a C5
44085d5 C4
961390d C3
2a2e220 C5
85f59ab C2
ab1bda4 C4
4516164 C1
3cb46a9 C3
0e783a3 C0
または、別の方法で示します:
このシナリオでは、重複するコミットを削除しますが、それらに基づいたコミットは保持します。C6からC10まで保持します。ほとんどの場合と同様に、これにはいくつかの方法があります。
どちらか:
- 最後に複製されたコミット1で新しいブランチを作成し、
cherry-pick
各コミット(C6からC10までを含む)をその新しいブランチに作成し、その新しいブランチを正規として扱います。
- ファイル名を指定して実行
git rebase --interactive $commit
、$commit
コミットされる前に複製されたコミットの両方に2。ここで、重複する行を完全に削除できます。
1それはあなたが選択した2のどの、いずれかの問題ではありませんba7688a
か、2a2e220
仕事の罰金を。
2この例では、次のようになります85f59ab
。
TL; DR
セットadvice.pushNonFastForward
へfalse
:
git config --global advice.pushNonFastForward false