2011-12-01 21 views
7

Per quanto ne so, quando vuoi annullare qualcosa in Git devi trovare esplicitamente il comando per annullare qualsiasi cosa tu abbia fatto e rilasciarlo. Per esempio, uno dei tanti modi di annullare un commesso e rifare è quello di seguire l'esempio da here,Perché non c'è un annullamento/ripristino in Git?

$ git commit ... 
$ git reset --soft HEAD^ 
$ edit 
$ git add .... 
$ git commit -c ORIG_HEAD 

O per annullare un pull, è possibile seguire le istruzioni da here,

$ git reset --hard 

Ma questi comandi non necessariamente funzionano in modo intercambiabile. C'è un motivo per cui Git non consente comandi di annullamento e ripetizione semplici? Qualcosa che ha a che fare con la filosofia che ci sta dietro? Inoltre, non ho molta esperienza con altri sistemi di controllo delle versioni, ma nessuno di essi offre un semplice comando di annullamento e ripetizione?

+0

Non sono sicuro, ma penso che si possa fare usando 'git rebase'. Controlla questo http://gitready.com/intermediate/2009/01/31/intro-to-rebase.html – gustavotkg

+2

L'idea è che generalmente non vuoi mai fare cose che ti fanno perdere parti della storia. Annullare un commit rimuoverlo dalla cronologia, quindi di solito non è qualcosa che si farebbe. – poke

+0

@poke Bene, Adobe Photoshop, ad esempio, mantiene una cronologia estesa e consente comunque di annullare/ripristinare. Perché Git non farebbe lo stesso? – john

risposta

6

Ci sono diversi problemi con una tale nozione:

  • Non tutte le operazioni sono reversibili. A volte questo è dovuto al fatto che Git non registra abbastanza informazioni per dedurre lo stato precedente - che in generale sarebbe proibitivo. A volte sono cose come git reset --hard o git clean, che distruggono le modifiche non tracciate. Per annullarli, dovrebbe essere continuamente il backup automatico. A volte questo perché la nozione di annullamento è ambigua - come lei stesso ha sottolineato, ci sono molti modi per annullare un commit.

  • Se un'operazione è reversibile e ha implicato una sorta di cronologia, anche la funzione annulla/ripeti si trova nella cronologia o dovrebbe farla sparire? Dovrebbe essere annullato un commit reimpostando o ripristinando (creando un altro commit per annullarlo)?

  • Senza registrare ogni ultima cosa che fai, come faresti a sapere qual è stata l'operazione più recente? Supponiamo che tu abbia aggiunto un file all'indice e creato un ramo. Non c'è alcuna registrazione di quale sia stato il primo.

Anche se tutto fosse chiaramente definito, sarebbe una quantità assurda di lavoro per l'attuazione. Come decidi cosa costituisce una singola azione? Un singolo comando Git potrebbe fare molte cose. Dovrebbe annullare un passo, il tutto? Cosa succede se esegui un comando di zillion facendo ciascuno un piccolo passo e vuoi annullare tutto? E dovrebbe essere perfetto, completamente perfetto, perché è il tipo di funzionalità che verrà utilizzato da utenti inesperti che non hanno idea di come recuperare da qualsiasi errore.

Quindi, proprio come Git ti dà gli strumenti per fare le cose, ti dà gli strumenti per vedere cosa hai fatto e disfare le cose da soli se lo si desidera.

Inoltre, rispetto a "ripetizione", come è stato definito nella domanda, è ripetere un comando, non ripetere l'operazione originale. Quando hai rifatto un commit, era diverso. Rieseguire un comando precedente è qualcosa che le shell della riga di comando erano progettate per fare. Git non ha bisogno di reinventarlo.

4

In realtà il tuo primo esempio può essere eseguita con:

$ git commit ... 
$ edit 
$ git add ... 
$ git commit --amend 

tuo secondo esempio dovrebbe essere più simile a git reset --hard <hash>

La risposta alla tua domanda è che è potenzialmente possibile, ma sì è più la guida filosofia Questo significa che non è stato fatto. In teoria non c'è modo di sapere se si è arrivati ​​a un commit creando o eliminando un altro, ma usando il reflog è forse possibile ... non ci ho mai pensato prima in quel modo.

Non credo che "Annulla" e "Ripristina" siano una cosa molto comune nel controllo del codice sorgente, ma correggimi se sbaglio.

MODIFICA: è possibile inserire una sceneggiatura che potrebbe fare ciò che si è dopo aver usato il reflog - non è sicuro se ci siano abbastanza informazioni lì, ma potrebbe valere la pena di provarlo.

1

git è in realtà più piccoli strumenti che agiscono sul repository, indice e directory di lavoro, quindi non ha una parte 'core' per qualsiasi 'annulla'.

Detto questo ha vari registri, come ad esempio reflog per voi a guardare indietro a ciò che è stato fatto.

Infine, per convenzione, molte azioni git sono normalmente pensate come "un modo solo", cioè, non si vorrebbe che nessuno lo veda pubblicamente, quindi git cerca di "farti girare attorno al blocco 'quando in pubblico. Se si è ancora nel repository locale è possibile eseguire il backup con vari comandi, ma un annullamento globale non è un'offerta di comando appropriata.

+0

'one-way only' è un buon modo di pensarci in realtà, come una volta che qualcosa è in the wild annulla e redo diventa pericoloso – MattJenko

0

Insieme agli altri commenti vorrei verificare git stash. Molte volte nascondo del lavoro, aggiusto qualcos'altro, poi disimpegno e continuo. In alternativa, per un'applicazione Web, riponi il mio lavoro finito e senza commit, aggiorna il browser, disattiva, apri una nuova scheda e poi confronta i due avanti e indietro per assicurarti che una correzione di bug relativa all'interfaccia utente non abbia infranto qualcos'altro.

Problemi correlati