Come posso annullare il commit dell'ultimo commit in un repository git bare?


91

Tenendo in considerazione che ci sono diversi comandi git che non hanno senso in un repository nudo (perché i repository spogli non usano indici e non hanno una directory di lavoro),

git reset --hard HEAD^ 

non è una soluzione per annullare l'ultima modifica in un tale repository.

Cercando su Internet, tutto quello che ho trovato relativo all'argomento è questo , in cui mi vengono presentati tre modi per farlo:
1. "aggiornare manualmente il ref (che coinvolge l'impianto idraulico)";
2. " git push -fda un repository non nudo";
3. " git branch -f this $that".

Quale soluzione ritieni sia più appropriata o quali altri modi ci sono per farlo? Sfortunatamente, la documentazione che ho trovato sui repository git bare è piuttosto scarsa.


8
@ Lavinia-Garbriela Dobrovol Non usare le cose complicate qui sotto. Stai cercando di spostare HEAD su un commit diverso ed è a questo che è destinato git reset, anche in un semplice repository. Per la mia risposta di seguito, usa: git reset --soft <commit> Con --soft, non provi a cambiare un albero funzionante e un indice che non esistono, quindi git ti consente di eseguire il ripristino senza problemi.
Hazok

Risposte:


130

Puoi usare il git update-refcomando. Per rimuovere l'ultimo commit, dovresti usare:

$ git update-ref HEAD HEAD^

O se non sei nel ramo da cui non puoi rimuovere l'ultimo commit:

$ git update-ref refs/heads/branch-name branch-name^

Puoi anche passare uno sha1 se vuoi:

$ git update-ref refs/heads/branch-name a12d48e2

Consulta la documentazione del comando git-update-ref .


@ Lavinia-Gabriela Dobrovolschi: giusto, non conoscevo la sintassi esatta.
VonC

@VonC Puoi specificare il <ref> in git update-ref <ref> <newvalue>come ramo giusto, come "refs / heads / master" invece di HEAD, per esempio. Spero di non aver frainteso la tua domanda.
Lavinia-Gabriela Dobrovolschi

@Sylvain: +1 buona modifica. @ Lavinia-Gabriela Dobrovolschi grazie per le precisioni. Questo è molto più pratico (se hai un accesso diretto al server remoto, presumo).
VonC

3
Gli esempi sono fuorvianti per quanto riguarda l' branch-nameargomento. Quando si utilizza update-refcon un "ramo" è assolutamente necessario specificare il nome di riferimento completo del ramo (ovvero anteporre refs/heads/al nome normale del ramo breve). Se usi solo il nome breve, finirai per creare / aggiornare $GIT_DIR/branch-nameinvece di $GIT_DIR/refs/heads/branch-name. L'esistenza di entrambi branch-namee refs/heads/branch-namecauserà avvisi "refname ... è ambiguo".
Chris Johnsen

Questa risposta è molto più complicata di quella proposta da Zach. E la sua soluzione funziona bene.
Krystian

32

Se utilizzi quanto segue in un semplice repository:

git reset --soft <commit>

quindi non si verificano i problemi che si hanno utilizzando --harde le --mixedopzioni in un repository nudo poiché non si sta tentando di modificare qualcosa che il repository nudo non ha (cioè albero di lavoro e indice). Nel tuo caso in particolare vorresti usare (dal semplice repo):

git reset --soft HEAD^

Per passare da un ramo all'altro nel repository remoto :

git symbolic-ref HEAD refs/heads/<branch_name>

Per vedere l'attuale ramo selezionato usa:

git symbolic-ref HEAD

https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html


3
Come si seleziona il ramo che si desidera spostare? Il tuo esempio funziona bene su master ma git checkout other_branchnon funziona su bare.
Gauthier

1
Hmmm ... mi chiedo chi mi ha votato contro questo. La domanda non chiedeva come cambiare i rami su un repository remoto, ma come reimpostare su un repository nudo. Per modificare il ramo predefinito in un repository remoto, usa git symbolic-ref HEAD refs / heads / <branch_name>.
Hazok

7

L' git push -fdovrebbe funzionare bene:
se si clona che nuda pronti contro termine, rimuovere l'ultimo commit ( git reset --hard HEAD^come si parla, ma in un repo non nuda locale) e ritorno push ( -f):

  • non si modifica alcun SHA1 per gli altri commit precedenti a quello rimosso.
  • sei sicuro di respingere il contenuto esatto del repository nudo meno il commit extra (perché l'hai appena clonato prima).

@ VonC Ciao Von, ti ho visto rispondere molto su Git, quindi volevo chiederti ... Ero curioso, perché git reset --soft <sha1>come mostrato nella mia risposta qui sotto non sarebbe stata la pratica consigliata per spostare HEAD su un repository nudo?
Hazok

Immagino che un altro motivo per cui chiedo sia che l'uso del soft reset per i repository nudi non è un'informazione prontamente disponibile e molti forum sembrano avere soluzioni alternative inutilmente complesse quando sembra che il soft reset sia la migliore pratica a causa della minor quantità di digitazione e delle minori possibilità per errore.
Hazok

2
@ Zach: a reset --softdovrebbe funzionare se eseguito direttamente su un semplice repo. Sospetto che questo sia fatto raramente perché un repo nudo è generalmente un repository upstream (cioè un repository a cui stai spingendo i dati) e la maggior parte delle volte non hai un accesso locale diretto ad esso. Ma se lo fai, questo è sicuramente un altro buon esempio di reset --softutilizzo " " (come in stackoverflow.com/questions/5203535/… ) Quindi +1 alla tua risposta.
VonC

2

Puoi anche usare la notazione git refspec e fare qualcosa del genere:

git push -f origin +<commit you want to revert to>:<destination_head | branch_name>

Questo forza l'aggiornamento del ramo di destinazione (come indicato dal ref) al commit di origine come indicato dalla +<object ref>parte.


2
tranne quando c'è un acl sul ramo - che di solito è il caso se "devi farlo sul semplice repo stesso" ...
David Schmitt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.