Come schiacciare i commit in git dopo che sono stati spinti?

Ciò fornisce una buona spiegazione dello schiacciamento di più commit:

http://git-scm.com/book/en/Git-Branching-Rebasing

ma non funziona per i commit che sono già stati spinti. Come faccio a schiacciare i commit più recenti sia nei repository locali che remoti?

EDIT: Quando git rebase -i origin/master~4 master , mantieni il primo come pick , imposta gli altri tre come squash , e poi esci (tramite cx cc in emacs), ottengo:

 $ git rebase -i origin/master~4 master # Not currently on any branch. nothing to commit (working directory clean) Could not apply 2f40e2c... Revert "issue 4427: bpf device permission change option added" $ git rebase -i origin/master~4 master Interactive rebase already started 

dove 2f40 è il commit di pick . E ora nessuno dei 4 commit appare nel git log . Mi aspettavo che il mio editor fosse riavviato in modo da poter inserire un messaggio di commit. Che cosa sto facendo di sbagliato?

Squash si impegna localmente con

 git rebase -i origin/master~4 master 

e quindi forzare con

 git push origin +master 

Differenza tra --force e +

Dalla documentazione di git push :

Si noti che --force applica a tutti i ref che vengono spinti, quindi usandolo con push.default impostato su matching o con più destinazioni push configurate con remote.*.push potrebbe sovrascrivere refs diversi dal ramo corrente (inclusi i ref locali che sono rigorosamente dietro la loro controparte remota). Per forzare una spinta verso un solo ramo, usa un + davanti al refspec per spingere (ad esempio, git push origin +master per forzare una spinta al ramo master ).

Su un ramo sono riuscito a farlo in questo modo (per gli ultimi 4 commit)

 git checkout my_branch git reset --soft HEAD~4 git commit git push --force origin my_branch 

Molti problemi possono essere evitati solo creando una branch su cui lavorare e non lavorando su master :

git checkout -b mybranch

I seguenti lavori per remote commit a remote già stati inseriti e una combinazione di commit a remote / commit local solo:

 # example merging 4 commits git checkout mybranch git rebase -i mybranch~4 mybranch # at the interactive screen # choose fixup for commit: 2 / 3 / 4 git push -u origin +mybranch 

Ho anche alcune note di richiesta di pull che possono essere utili.

Differenza minore rispetto alla risposta accettata, ma stavo avendo un sacco di difficoltà a schiacciare e alla fine ho ottenuto.

 $ git rebase -i HEAD~4 
  • Sullo schermo interattivo che si apre, sostituisci pick con lo squash in alto per tutti i commit che vuoi schiacciare.
  • Salva e chiudi l’editor tramite esc --> :wq

Premi sul telecomando usando:

 $ git push origin branch-name --force 

git rebase -i master

otterrete l’editor vm open e msgs qualcosa di simile

 Pick 2994283490 commit msg1 f 7994283490 commit msg2 f 4654283490 commit msg3 f 5694283490 commit msg4 #Some message # #some more 

Qui ho cambiato pick per tutti gli altri commit in “f” (Stand per fixup).

git push -f origin feature/feature-branch-name-xyz

questo aggiusterà tutti i commit ad un commit e rimuoverà tutti gli altri commit. L’ho fatto e mi ha aiutato.