Risposta breve
Hai omesso il fatto di aver eseguito git push, ottenuto il seguente errore e quindi eseguito 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.
Nonostante Git cerchi di essere d'aiuto, il suo consiglio "git pull" molto probabilmente non è quello che vuoi fare .
Se sei:
- Lavorare su un "ramo di caratteristica" o "ramo developer" da solo , quindi è possibile eseguire
git push --forcel'aggiornamento del telecomando con i tuoi post-commit rebase ( come da risposta di user4405677 ).
- Lavorando su un ramo con più sviluppatori contemporaneamente, probabilmente non dovresti usarlo
git rebase in primo luogo. Per aggiornare devcon le modifiche da master, dovresti, invece di correre git rebase master dev, correre git merge mastermentre sei acceso dev( come da risposta di Justin ).
Una spiegazione leggermente più lunga
Ogni hash di commit in Git si basa su una serie di fattori, uno dei quali è l'hash del commit che lo precede.
Se riordini i commit, cambierai gli hash dei commit; il rebasing (quando fa qualcosa) cambierà gli hash di commit. Con ciò, il risultato dell'esecuzione git rebase master dev, dove non devè sincronizzato con master, creerà nuovi commit (e quindi hash) con lo stesso contenuto di quelli attivi devma con i commit masterinseriti prima di essi.
Puoi finire in una situazione come questa in diversi modi. Due modi in cui posso pensare:
- Potresti avere impegni su
mastercui vuoi basare il tuo devlavoro
- Potresti avere commit su
devche sono già stati inviati a un telecomando, che poi procedi a modificare (riformulare i messaggi di commit, riordinare i commit, squash commit, ecc.)
Comprendiamo meglio cosa è successo: ecco un esempio:
Hai un repository:
2a2e220 (HEAD, master) C5
ab1bda4 C4
3cb46a9 C3
85f59ab C2
4516164 C1
0e783a3 C0

Si procede quindi alla modifica dei commit.
git rebase --interactive HEAD~3 # Three commits before where HEAD is pointing
(Qui è dove devi credermi sulla parola: ci sono molti modi per cambiare i commit in Git. In questo esempio ho cambiato l'ora di C3, ma tu stai inserendo nuovi commit, cambiando i messaggi di commit, riordinando i commit, schiacciare i commit insieme, ecc.)
ba7688a (HEAD, master) C5
44085d5 C4
961390d C3
85f59ab C2
4516164 C1
0e783a3 C0

È qui che è importante notare che gli hash di commit sono diversi. Questo è un comportamento previsto poiché hai cambiato qualcosa (qualsiasi cosa) su di loro. Va bene, MA:

Provare a spingere mostrerà un errore (e suggerirà che dovresti eseguire 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.
Se corriamo git pull, vediamo questo registro:
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
Oppure, mostrato in un altro modo:

E ora abbiamo commit duplicati a livello locale. Se dovessimo eseguire git push, li invieremo al server.
Per evitare di arrivare a questa fase, avremmo potuto correre git push --force(dove invece abbiamo corso git pull). Ciò avrebbe inviato i nostri commit con i nuovi hash al server senza problemi. Per risolvere il problema in questa fase, possiamo ripristinare prima di eseguire git pull:
Guarda il reflog ( git reflog) per vedere qual era l'hash del commit prima di essere eseguito 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
Sopra vediamo che ba7688aera il commit in cui eravamo prima di correre git pull. Con quell'hash di commit in mano possiamo reimpostare su that ( git reset --hard ba7688a) e quindi eseguire git push --force.
E abbiamo finito.
Ma aspetta, ho continuato a basare il lavoro sui commit duplicati
Se in qualche modo non hai notato che i commit erano duplicati e hai continuato a lavorare sopra i commit duplicati, hai davvero combinato un pasticcio per te stesso. La dimensione del pasticcio è proporzionale al numero di commit che hai in cima ai duplicati.
Che aspetto ha:
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

Oppure, mostrato in un altro modo:

In questo scenario vogliamo rimuovere i commit duplicati, ma mantenere i commit che abbiamo basato su di essi: vogliamo mantenere da C6 a C10. Come per la maggior parte delle cose, ci sono diversi modi per farlo:
O:
- Crea un nuovo ramo all'ultimo commit duplicato 1 ,
cherry-pickogni commit (da C6 a C10 compreso) su quel nuovo ramo e considera quel nuovo ramo come canonico.
- Esegui
git rebase --interactive $commit, dov'è $commitil commit prima di entrambi i commit duplicati 2 . Qui possiamo eliminare completamente le righe per i duplicati.
1 Non importa quale dei due scegli, ba7688ao 2a2e220funziona bene.
2 Nell'esempio sarebbe 85f59ab.
TL; DR
Imposta advice.pushNonFastForwardsu false:
git config --global advice.pushNonFastForward false