Domanda

Ho un repository git che assomiglia a questo:

A -> B -> C -> D -> HEAD

Voglio la testa del ramo al punto A, cioè voglio B, C, D, e HEAD scomparire e voglio testa per essere sinonimo con A.

Sembra che posso neanche provare a rebase (non si applica, dal momento che ho spinto cambiamenti nel mezzo), o tornare. Ma come faccio a Revert multipli impegna? Ho Ripristina uno alla volta? È l'ordine importante?

È stato utile?

Soluzione

Espansione quello che ho scritto in un commento

La regola generale è che non si deve riscrivere (cambiamento) storia che hai pubblicato, perché qualcuno potrebbe aver basato il loro lavoro su di esso. Se si riscrive la storia (cambio), si dovrebbe creare problemi con la fusione dei loro modifiche e con l'aggiornamento per loro.

Quindi la soluzione è quella di creare un nuova commettere , che ritorna modifiche che si desidera eliminare. È possibile farlo utilizzando git tornare comando

Si ha la seguente situazione:

A <-- B  <-- C <-- D                                               <-- master <-- HEAD

(frecce qui si riferisce alla direzione del puntatore: il riferimento "padre" nel caso di commit, all'inizio commit nel caso di testa ramo (ramo ref), e il nome del ramo in caso di riferimento HEAD ).

Quello che vi serve per creare è la seguente:

A <-- B  <-- C <-- D <-- [(BCD)^-1]                   <-- master <-- HEAD

dove "[(BCD) ^ - 1]" indica il commit che ripristina variazioni impegna B, C, D. matematica ci dice che (BCD) ^ - 1 = D ^ -1 C ^ -1 ^ B - 1, in modo da poter ottenere la situazione desiderata con i seguenti comandi:

$ git revert --no-commit D
$ git revert --no-commit C
$ git revert --no-commit B
$ git commit -m "the commit message"

soluzione alternativa potrebbe essere quella di cassa contenuto di commettere un, e si impegnano questo stato:

$ git checkout -f A -- .
$ git commit -a

Poi si avrebbe la seguente situazione:

A <-- B  <-- C <-- D <-- A'                       <-- master <-- HEAD

Il commettere un' ha lo stesso contenuto commettere, ma è un diverso commit (messaggio di commit, i genitori, la data di commit).

La soluzione href="https://stackoverflow.com/questions/1463340/revert-multiple-git-commits/1463390#comment1312779_1463390"> si basa sul stessa idea, ma usi git resettare :

$ git reset --hard A
$ git reset --soft @{1}  # (or ORIG_HEAD), which is D
$ git commit

Altri suggerimenti

Per fare ciò è necessario solo per utilizzare il Ripristina di comando, specificare l'intervallo di commit si desidera ottenere ritornato.

Prendendo in considerazione il vostro esempio, dovreste fare questo (supponendo che si sta sul ramo 'master'):

git revert master~3..master

Questo creerà un nuovo commit nel vostro locale con l'inverso commit di B, C e D (il che significa che sarà annullare le modifiche introdotte da questi commit):

A <- B <- C <- D <- BCD' <- HEAD

modo pulito, che ho trovato utile

git revert --no-commit HEAD~3..

Questo comando ritorna ultimi 3 impegna con un solo commit.

Inoltre non riscrivere la storia.

Simile alla risposta di Jakub, questo permette di selezionare facilmente impegna consecutivi di tornare.

# revert all commits from B to HEAD, inclusively
$ git revert --no-commit B..HEAD  
$ git commit -m 'message'
git reset --hard a
git reset --mixed d
git commit

che fungerà da un Revert per tutti in una volta. Dare un buon messaggio di commit.

In primo luogo essere sicuri che la vostra copia di lavoro non viene modificato. Poi:

git diff HEAD commit_sha_you_want_to_revert_to | git apply

e poi basta impegnarsi. Non dimenticare di documentare ciò che è il motivo per il ripristino.

Sono così frustrato che la questione non può essere risolta solo. Ogni altra questione è in relazione a come ripristinare in modo corretto e conservare la storia. Questa domanda dice "Voglio che il capo del ramo per puntare a A, vale a dire che voglio B, C, D, e la testa di sparisco e voglio la testa di essere sinonimo di A."

git checkout <branch_name>
git reset --hard <commit Hash for A>
git push -f

Ho imparato molto leggendo il post di Jakub, ma un ragazzo in azienda (con accesso a spingere per il nostro "test" ramo senza Pull-Request) spinto come 5 cattiva impegna cercando di risolvere e fissare e fissare un errore ha fatto 5 impegna fa. solo, ma uno o due richieste Pull non sono state accettate, che erano ormai male. Così dimenticare, ho trovato l'ultima buona commit (abc1234) e appena eseguito lo script di base:

git checkout testing
git reset --hard abc1234
git push -f

Ho detto agli altri 5 ragazzi che lavorano in questo repo che meglio prendere nota delle loro cambiamenti per le ultime ore e pulire / Re-Branch dall'ultimo test. Fine della storia.

Questo è un ampliamento di una delle soluzioni fornite nella risposta di Jakub

ero di fronte ad una situazione in cui i commit avevo bisogno di ripristinare erano un po 'complessa, con diversi dell'essere commit fusione impegna, e avevo bisogno di evitare di riscrivere la storia. Non ero in grado di utilizzare una serie di comandi git revert perché alla fine ho incontrato i conflitti tra le modifiche che si aggiunge alla reversione. Ho finito per usare la seguente procedura.

In primo luogo, controllare il contenuto del target commettere lasciando TESTA sulla punta del ramo:

$ git checkout -f <target-commit> -- .

(La - si assicura <target-commit> viene interpretato come un commit piuttosto che un file, la si riferisce alla directory corrente.).

Poi, determinare quali file sono stati aggiunti nel corso di commit rollback, e quindi devono essere cancellati:

$ git diff --name-status --cached <target-commit>

I file che sono stati aggiunti dovrebbe presentarsi con una "A" all'inizio della linea, e non ci dovrebbero essere altre differenze. Ora, se i file devono essere rimossi, in scena questi file per la rimozione:

$ git rm <filespec>[ <filespec> ...]

Infine, il commit della reversione:

$ git commit -m 'revert to <target-commit>'

Se lo si desidera, fare in modo che siamo di nuovo allo stato desiderato:

$git diff <target-commit> <current-commit>

Non ci dovrebbero essere differenze.

Il modo più semplice per ripristinare un gruppo di commit sul repository condiviso (che la gente usa e si desidera preservare la storia) è quello di utilizzare git revert in combinazione con git rev-list. Quest'ultimo vi fornirà un elenco di commit, il primo farà il revert stesso.

Ci sono due modi per farlo. Se si desidera che il multiplo Revert impegna in un singolo uso commit:

for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert -n $i; done

questo tornerà un gruppo di commit è necessario, ma lasciare tutte le modifiche sul vostro albero di lavoro, si dovrebbe impegnare tutti, come al solito.

Un'altra opzione è quella di avere un unico commit a cambio ritornato:

for i in `git rev-list <first-commit-sha>^..<last-commit-sha>`; do git revert --no-edit -s $i; done

Per esempio, se si dispone di un albero di impegnarsi come

 o---o---o---o---o---o--->    
fff eee ddd ccc bbb aaa

per ripristinare le modifiche da eee per bbb , eseguire

for i in `git rev-list eee^..bbb`; do git revert --no-edit -s $i; done

Nessuno di coloro che ha lavorato per me, così ho avuto tre impegna a riportare i (le ultime tre commit), così ho fatto:

git revert HEAD
git revert HEAD~2
git revert HEAD~4
git rebase -i HEAD~3 # pick, squash, squash

Ha lavorato come un fascino:)

A mio parere un modo molto semplice e pulito potrebbe essere:

tornare alla A

git checkout -f A

testa punto di master per lo stato attuale

git symbolic-ref HEAD refs/heads/master

Salva

git commit

Se si desidera ripristinare temporaneamente i commit di una funzione, quindi è possibile utilizzare la serie di comandi seguenti.

Ecco come funziona

git log --pretty = oneline | grep 'feature_name' | cut -d '' -f1 | xargs git -n1 tornare --no-modifica

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top