Jawaban singkat
Anda menghilangkan fakta bahwa Anda berlari git push, mendapatkan kesalahan berikut, dan kemudian melanjutkan untuk menjalankan 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.
Meskipun Git berusaha membantu, saran 'git pull' yang dimilikinya kemungkinan besar bukanlah yang ingin Anda lakukan .
Jika Anda:
- Bekerja pada "cabang fitur" atau "cabang pengembang" saja , lalu Anda dapat menjalankan
git push --forceuntuk memperbarui remote dengan komitmen pasca-rebase Anda ( sesuai jawaban pengguna4405677 ).
- Bekerja pada cabang dengan banyak pengembang pada saat yang sama, maka Anda mungkin tidak boleh menggunakannya
git rebase sejak awal. Untuk memperbarui devdengan perubahan dari master, Anda harus, alih-alih menjalankan git rebase master dev, jalankan git merge mastersaat di dev( sesuai jawaban Justin ).
Penjelasan yang sedikit lebih panjang
Setiap hash komit di Git didasarkan pada sejumlah faktor, salah satunya adalah hash komit yang ada sebelumnya.
Jika Anda menyusun ulang komit, Anda akan mengubah hash komit; rebasing (ketika melakukan sesuatu) akan mengubah hash komit. Dengan itu, hasil dari menjalankan git rebase master dev, di mana devtidak sinkron dengan master, akan membuat komit baru (dan dengan demikian hash) dengan konten yang sama seperti yang ada devtetapi dengan komit pada yang masterdisisipkan sebelumnya.
Anda bisa berakhir dalam situasi seperti ini dengan berbagai cara. Dua cara yang bisa saya pikirkan:
- Anda dapat memiliki komitmen
masteryang Anda inginkan sebagai dasar devpekerjaan Anda
- Anda bisa saja komit
devyang telah didorong ke remote, yang kemudian Anda ubah (reword komit pesan, susun ulang komit, komit squash, dll.)
Mari kita lebih memahami apa yang terjadi — berikut ini contohnya:
Anda memiliki repositori:
2a2e220 (HEAD, master) C5
ab1bda4 C4
3cb46a9 C3
85f59ab C2
4516164 C1
0e783a3 C0

Anda kemudian melanjutkan untuk mengubah komit.
git rebase --interactive HEAD~3 # Three commits before where HEAD is pointing
(Di sinilah Anda harus mengambil kata-kata saya: ada sejumlah cara untuk mengubah komit di Git. Dalam contoh ini saya mengubah waktunya C3, tetapi Anda memasukkan komit baru, mengubah pesan komit, menyusun ulang komit, meremas komitmen bersama, dll.)
ba7688a (HEAD, master) C5
44085d5 C4
961390d C3
85f59ab C2
4516164 C1
0e783a3 C0

Di sinilah penting untuk diperhatikan bahwa hash komit berbeda. Ini adalah perilaku yang diharapkan karena Anda telah mengubah sesuatu (apa pun) tentang mereka. Ini tidak masalah, TAPI:

Mencoba mendorong akan menunjukkan kesalahan (dan petunjuk bahwa Anda harus lari 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.
Jika kita jalankan git pull, kita melihat log ini:
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
Atau, ditunjukkan dengan cara lain:

Dan sekarang kami memiliki komitmen ganda secara lokal. Jika kami menjalankannya, git pushkami akan mengirimnya ke server.
Untuk menghindari sampai ke tahap ini, kita bisa saja lari git push --force(di mana kita malah lari git pull). Ini akan mengirimkan komit kami dengan hash baru ke server tanpa masalah. Untuk memperbaiki masalah pada tahap ini, kami dapat mengatur ulang kembali ke sebelum kami menjalankan git pull:
Lihatlah reflog ( git reflog) untuk melihat apa hash komit itu sebelum kita berlari 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
Di atas kami melihat bahwa ba7688akami berkomitmen sebelum berlari git pull. Dengan hash komit di tangan kita dapat mengatur ulang kembali ke itu ( git reset --hard ba7688a) dan kemudian menjalankan git push --force.
Dan kami selesai.
Tapi tunggu, saya terus mendasarkan pekerjaan dari komit yang digandakan
Jika Anda entah bagaimana tidak menyadari bahwa komit diduplikasi dan terus bekerja di atas komit duplikat, Anda benar-benar telah membuat kekacauan untuk diri Anda sendiri. Ukuran kekacauan sebanding dengan jumlah komitmen yang Anda miliki di atas duplikat.
Seperti apa ini:
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

Atau, ditunjukkan dengan cara lain:

Dalam skenario ini kami ingin menghapus komit duplikat, tetapi tetap mempertahankan komitmen yang telah kami lakukan berdasarkan komitmen tersebut — kami ingin mempertahankan C6 hingga C10. Seperti kebanyakan hal, ada beberapa cara untuk melakukannya:
Antara:
- Buat cabang baru di komit 1 duplikat terakhir ,
cherry-pickmasing-masing komit (termasuk C6 hingga C10) ke cabang baru itu, dan perlakukan cabang baru itu sebagai kanonik.
- Jalankan
git rebase --interactive $commit, di mana $commitkomit sebelum kedua komit yang digandakan 2 . Di sini kita bisa langsung menghapus garis untuk duplikat.
1 Tidak masalah mana yang Anda pilih, salah satu ba7688aatau 2a2e220berfungsi dengan baik.
2 Dalam contoh itu akan 85f59ab.
TL; DR
Setel advice.pushNonFastForwardke false:
git config --global advice.pushNonFastForward false