Annulla un commit particolare in Git che è stato inserito nei repository remoti

Qual è il modo più semplice per annullare un commit particolare che è:

  • non nella testa o TESTA
  • È stato spinto al telecomando.

Perché se non è l’ultimo commit,

git reset HEAD 

non funziona E perché è stato spinto a un telecomando,

 git rebase -i 

e

 git rebase --onto 

causerà qualche problema nei telecomandi.

Inoltre, non voglio davvero modificare la storia. Se c’era codice cattivo, era lì nella storia e può essere visto. Lo voglio solo nella copia di lavoro, e non mi interessa un commit di inversione inversa.

In altre parole, qual è l’equivalente Git dei seguenti comandi svn:

 svn merge -r 303:295 http://svn.example.com/repos/calc/trunk 

che rimuove tutte le modifiche da 295 a 302 invertendo la fusione di tutte le modifiche in quelle revisioni, come un nuovo commit.

 svn merge -c -302 ^/trunk 

che annulla il commit 302, ovviamente aggiungendo un altro commit che inverte le modifiche da quel rispettivo commit.

Ho pensato che dovrebbe essere un’operazione abbastanza semplice in Git e un caso d’uso abbastanza comune. Cos’altro è il punto dei comandi atomici?

Abbiamo messo in scena la messa in scena e tutti per garantire che i commit siano perfettamente atomici, non dovresti essere in grado di annullare facilmente uno o più di questi comandi atomici?

Identifica l’hash del commit, usando git log , quindi usa git revert per creare un nuovo commit che rimuove queste modifiche. In un certo senso, git revert è l’inverso di git cherry-pick – quest’ultimo applica la patch a un ramo che manca, il primo lo rimuove da un ramo che lo ha.

Non mi piace l’auto-commit che fa git revert , quindi questo potrebbe essere utile per alcuni.

Se vuoi solo che i file modificati non siano il commit automatico , puoi usare --no-commit

 % git revert --no-commit  

che è lo stesso di -n

 % git revert -n  

Perché è già stato spinto, non si dovrebbe manipolare direttamente la cronologia. git revert ripristinerà le modifiche specifiche da un commit usando un nuovo commit, in modo da non manipolare la cronologia del commit.