Vai al contenuto
GitTree

Lezione 28 · Recupero

Annulla una modifica nella cronologia condivisa

Annulla una modifica errata già apportata da altri aggiungendo un nuovo commit che la annulla, invece di eliminare la cronologia, e pubblica la correzione con un normale push.

Avanzamenti salvati in questo browser.

La riproduzione carica il video da YouTube (modalità ottimizzata per la privacy).

Narrazione in inglese · English and Arabic didascalie

Apri la pagina del videoGuarda su YouTube

Cosa imparerai

  • Spiega il ripristino come commit inverso e perché si adatta alla storia degli altri.
  • Prevedere il genitore del nuovo commit e il file che lascia.
  • Gestisci un ripristino in conflitto e scopri perché il ripristino di un'unione richiede un genitore.
  • Pubblica la correzione senza forzatura.

Prima di iniziare

Ti trovi su shared/dark-regression, un ramo del risultato M della lezione 18. Il suo ultimo commit, "style: introduce the rehearsal contrast regression", aggiunge una regola a styles.css, body { color: #f7f8fa; }, che trasforma il testo della pagina nello stesso colore pallido dello sfondo. Quel commit è già su un server locale che hai configurato per questa lezione, quindi un compagno di squadra potrebbe averlo. Vuoi che il testo sia nuovamente leggibile senza riscrivere nulla di ciò che già hanno gli altri.

Tutto è locale e nel piano gratuito (GitTree ti chiede di accedere): nessun account di hosting, nessun provider, niente Internet. Il server è un repository nudo locale, non GitHub. Ogni identità è fittizia (esempio.com). Non eseguire mai questa lezione in un progetto reale.

Apporta le modifiche in GitTree o con i comandi Git nativi, non entrambi nella stessa copia. Leggere il risultato è sempre sicuro. Le etichette dei menu provengono dalle stringhe proprie di GitTree 2.0 e i comandi nativi sono stati eseguiti con Git 2.43 in copie usa e getta. I passaggi GitTree non sono stati eseguiti su macOS, Windows o Linux.

Effetti del concetto e dello stato

Ripristina esamina ciò che è stato modificato da un commit e aggiunge un new commit che applica la modifica opposta. L'errore commesso rimane nella storia, così come la prova che è avvenuto. Reset fa il contrario: sposta indietro il ramo e lascia fuori il commit, il che va bene per il lavoro che hai solo tu, ma costringe tutti coloro che hanno già il commit a riparare la propria copia.

Qui il genitore del nuovo commit è il commit errato e il file finisce esattamente come prima. Il ramo avanza di un commit e il server lo accetta con un push ordinario, perché aggiunge solo quello che c'è.

Un cambiamento inverso dipende da ciò che lo circonda. Se qualcuno ha cambiato le stesse righe dopo un commit errato, il ripristino si interrompe con un conflitto e lo risolvi come qualsiasi altro (lezione 23) o interrompi. Il ripristino di un commit merge ti chiede di scegliere rispetto a quale genitore viene misurata la modifica: solitamente il primo, in cui si è unito il ramo. Annullare un'unione indica inoltre a Git che le sue modifiche sono state gestite, quindi unire lo stesso ramo in un secondo momento potrebbe non riportare nulla da unire. Questa lezione ripristina un commit ordinario e mostra solo quella finestra di dialogo.

Solo il ramo corrente ottiene un commit. Nient'altro si muove finché non spingi.

Preparare lo stato esatto del progetto

Inizia da una copia ordinaria separata del risultato M della lezione 18 e lascia intatto il tuo originale. Crea il ramo, salva DOC_DARK_BAD su styles.css e confermalo, crea un nuovo repository nudo vuoto accanto alla copia, aggiungilo come remoto chiamato rehearsal ed esegui il push del ramo con il suo upstream. CSS_RESTORED è l'aspetto che deve avere il file dopo il ripristino.

Completare gli input del file

Risparmia solo nella fase denominata di seguito. Questi sono corpi UTF-8/LF completi con un ritorno a capo finale; non incollare mai le recinzioni Markdown. I file eseguibili non modificati ereditano l'input denominato. Le versioni in varianti separate non devono sovrascrivere l'originale.

stili.css — DOC_DARK_BAD

Estratto del file · css
:root {
  color-scheme: light;
  --page: #f7f8fa;
  --surface: #ffffff;
  --text: #17212e;
  --link: #154ab5;
  --line: #bac4d0;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font: 1rem/1.6 system-ui, sans-serif;
}

a {
  color: var(--link);
}

.site-header,
main,
footer {
  width: min(68rem, 100% - 2rem);
  margin-inline: auto;
}

.site-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1rem;
}

.hero {
  max-width: 48rem;
  padding-block: 3rem;
}

h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1.2;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: 1rem;
}

.feature-card {
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  background: var(--surface);
}

section {
  margin-block-end: 2rem;
}

button,
input {
  font: inherit;
}

button,
input {
  padding: 0.5rem 0.75rem;
}

:focus-visible {
  outline: 3px solid var(--link);
  outline-offset: 3px;
}

form {
  display: grid;
  max-width: 28rem;
  gap: 0.5rem;
}

body { color: #f7f8fa; }

stili.css — CSS_RESTORED

Estratto del file · css
:root {
  color-scheme: light;
  --page: #f7f8fa;
  --surface: #ffffff;
  --text: #17212e;
  --link: #154ab5;
  --line: #bac4d0;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font: 1rem/1.6 system-ui, sans-serif;
}

a {
  color: var(--link);
}

.site-header,
main,
footer {
  width: min(68rem, 100% - 2rem);
  margin-inline: auto;
}

.site-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1rem;
}

.hero {
  max-width: 48rem;
  padding-block: 3rem;
}

h1 {
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1.2;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: 1rem;
}

.feature-card {
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  background: var(--surface);
}

section {
  margin-block-end: 2rem;
}

button,
input {
  font: inherit;
}

button,
input {
  padding: 0.5rem 0.75rem;
}

:focus-visible {
  outline: 3px solid var(--link);
  outline-offset: 3px;
}

form {
  display: grid;
  max-width: 28rem;
  gap: 0.5rem;
}

Tra GitTree

Apri la tavolozza con Comando+Maiusc+P (Ctrl+Maiusc+P su Ubuntu). Le azioni su un commit utilizzano il menu di scelta rapida del commit.

  1. Costruisci il ramo, il commit e il server locale come mostra la sezione successiva. Mantieni shared/dark-regression estratto e l'albero di lavoro pulito.
  2. Nel grafico seleziona il commit errato e leggine i dettagli: un percorso modificato, styles.css e una riga aggiunta.
  3. Fai clic con il pulsante destro del mouse e scegli Revert Commit. Si applica immediatamente alla filiale in cui ti trovi; non esiste un editor di messaggi. L'avviso dice "Ripristinato". Se invece si ferma, il banner "Reverting… on shared/dark-regression" offre Resolve, Continue e Abort….
  4. Seleziona il nuovo commit. Il suo oggetto è Revert "style: introduce the rehearsal contrast regression" e il suo genitore è il commit errato. Il commit errato è ancora nel grafico.
  5. Apri styles.css: è CSS_RESTORED, senza la regola aggiunta.
  6. Fai clic sulla barra degli strumenti Push. Si tratta di una normale spinta del ramo verso monte; non scegliere Force Push (con leasing)…. L'avviso dice "Condiviso/dark-regression spostato alle prove/condiviso/dark-regressione".
  7. Controlla il risultato: l'albero di lavoro è pulito, entrambi i commit sono nel grafico e il ramo del server è sul nuovo commit.

Se fai clic con il pulsante destro del mouse su un commit di unione, Revert Commit apre "Ripristina unione..." con First parent (the branch merged into) e Second parent (the branch merged in). Non eseguirlo qui.

Per ogni commit ordinario nel corso: Summary è l'oggetto dichiarato, Description è vuoto e le opzioni Amend Previous Commit, Skip Hooks, Add Signed-off-by, Different Author, Push After Commit e Allow Empty Commit rimangono disattivate.

Nel terminale

In una copia separata del risultato della lezione 18:

Command · bash
git switch --create shared/dark-regression

Salva DOC_DARK_BAD come styles.css, quindi:

Command · bash
git add -- styles.css
git commit --quiet -m "style: introduce the rehearsal contrast regression"
BAD_SHA="$(git rev-parse HEAD)"
git init --quiet --bare --initial-branch=main ../gittree-revert-origin.git
git remote add rehearsal ../gittree-revert-origin.git
git push --quiet --set-upstream rehearsal shared/dark-regression

Ora ripristina, pubblica e leggi il risultato:

Command · bash
git revert --no-edit "$BAD_SHA"
git merge-base --is-ancestor "$BAD_SHA" HEAD; echo $?
git log -1 --format=%s
git push --quiet rehearsal shared/dark-regression
git status --short
git ls-remote --heads rehearsal refs/heads/shared/dark-regression
git rev-parse HEAD
Uscita
0
Revert "style: introduce the rehearsal contrast regression"

Il controllo dell'antenato stampa 0: il commit errato è ancora dietro HEAD. styles.css è CSS_RESTORED, lo stato è vuoto e i due ID da ls-remote e rev-parse sono uguali. Non è stata coinvolta alcuna opzione di forza. In una copia separata in cui un commit successivo modifica la stessa riga, git revert si interrompe con "CONFLICT (contenuto)" e i suggerimenti git revert --continue e git revert --abort. E git revert su un commit di unione rifiuta con "è un'unione ma non è stata fornita l'opzione -m"; -m 1 sceglie il primo genitore.

Risultato

Where you end: shared/dark-regression ha un nuovo commit che annulla quello errato. La pagina utilizza CSS_RESTORED, il commit errato è ancora nella cronologia, il ramo del server è sul nuovo commit, l'albero di lavoro è pulito e nulla è stato forzato.

Errori comuni

  • Utilizzando il ripristino e una spinta forzata per "rimuovere" un commit che altri hanno già.
  • Aspettarsi che il commit errato scompaia dal registro.
  • Annullare un'unione senza sceglierne di proposito il genitore.
  • Spingendo prima di guardare il file si ripristina a sinistra.

Se qualcosa va storto

Se il ripristino si interrompe con un conflitto, leggere il banner. Resolve e Continue finiscono come nella lezione 23; Abort… riporta il ramo al punto in cui si trovava. Se il ripristino stesso è stato un errore al termine, ripristina il ripristino: è solo un altro commit.

Controlla la tua comprensione

Rispondi a ciascuna domanda, quindi leggi il motivo. Le domande contrassegnate come "Obbligatorio" contano ai fini del completamento della lezione.

  1. Domanda 1 di 6

    Cosa fa il ripristino al commit errato?

    Scegli una risposta.

  2. Domanda 2 di 6

    Dopo il ripristino, quali di queste sono vere?

    Scegli ogni risposta applicabile.

  3. Domanda 3 di 6
    Obbligatorio

    Annulla il commit errato ed esegui il push normalmente. Dov'è il ramo del server dopo?

    Scegli una risposta.

  4. Domanda 4 di 6

    Modifica l'input: un commit successivo modifica la stessa riga aggiunta dal commit errato, quindi annulli il commit errato. Che succede?

    Scegli una risposta.

  5. Domanda 5 di 6
    Obbligatorio

    Provi a ripristinare un commit di unione e Git dice "è un'unione ma non è stata fornita l'opzione -m". Cosa sta succedendo e cosa fai?

    Scegli una risposta.

  6. Domanda 6 di 6
    Obbligatorio

    Dopo il ripristino e il push, quali riletture mostrano che ha fatto ciò che dice la lezione?

    Scegli ogni risposta applicabile.

0 di 6 corretto

Rispondi correttamente alle domande richieste per completare la lezione.

Controllato in questo browser.

Pratica

Segnala l'oggetto del ripristino, il suo genitore, se il commit errato è ancora un antenato e se il ramo del server è uguale a HEAD. Quindi prevedi cosa accadrebbe se un commit successivo avesse modificato la stessa riga prima del ripristino.

La tua conferma: il sito non può vedere il tuo computer.

Per completare la lezione rispondere correttamente alle domande richieste e confermare l'esercizio pratico.

Riepilogo

  • Revert aggiunge un commit che ne annulla un altro.
  • La storia resta; il file torna indietro.
  • È sufficiente una spinta normale.

Termini del glossario introdotti

Ripristina — عكس; cambiamento inverso: تغيير معاكس; genitore principale: الأب الرئيسي.

Trascrizione video

La narrazione del video, spunto per spunto.

Mostra la trascrizione
  1. Annulla una modifica già eseguita da altre persone avere.
  2. Reset sposta indietro il ramo. Ripristina aggiunge a nuovo commit invece.
  3. Altri hanno già il vecchio commit. Ripristina lascia valida la loro copia.
  4. Costruisci il ramo condiviso con un commit errato, e un server locale che ce l'ha.
  5. Il grafico mostra M e il commit errato superiore.
  6. Il commit errato aggiunge una riga e il testo diventa pallido.
  7. Annotare il suo ID.
  8. Fare clic con il pulsante destro del mouse e scegliere Ripristina commit.
  9. Si applica immediatamente. Non c'è nessun messaggio editore.
  10. L'avviso dice ripristinato.
  11. Il nuovo commit prende il nome da quello vecchio.
  12. Il suo genitore è il commit errato. Niente lo era rimosso.
  13. Il file è tornato com'era. La regola pallida è andato.
  14. E il grafico mostra entrambi i commit. Il la storia non ha fatto altro che crescere.
  15. Si è mosso solo questo ramo. Niente lo è ancora pubblicato.
  16. Il ramo è un commit prima di servitore.
  17. Fare clic su Spingi. Questa è una spinta normale.
  18. L'avviso nomina la filiale e il servitore.
  19. Non era necessaria alcuna forza. La spinta ha aggiunto solo a impegnarsi.
  20. Nel terminale, git ripristina senza modifiche fa lo stesso.
  21. Il cattivo commit è ancora un antenato. Il la risposta è zero.
  22. E l'argomento inizia con Ripristina.
  23. Premi, quindi confronta l'ID del server con TESTA. Sono uguali.
  24. Cambia l'input: qualcuno ha modificato lo stesso riga più tardi.
  25. Il ripristino si interrompe con un conflitto. Risolvi e continuare o interrompere.
  26. Il ripristino di un'unione richiede un genitore. Di solito è il primo.
  27. Dopo aver ripristinato un'unione, unirlo branch di nuovo potrebbe non fare nulla.
  28. Esercizio: riportare il soggetto, il genitore, controllo dell'antenato e l'ID del server.
  29. Successivamente, trova un commit perduto con il reflog.