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.
- Livello: Intermedio
- 10 minuti di lettura
- 4 minuti di video
- Aggiornato
- Prima di questa lezione: Unisci rami con cronologia divergente
Avanzamenti salvati in questo browser.
La riproduzione carica il video da YouTube (modalità ottimizzata per la privacy).
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
: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
: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.
- Costruisci il ramo, il commit e il server locale come mostra la sezione successiva. Mantieni
shared/dark-regressionestratto e l'albero di lavoro pulito. - Nel grafico seleziona il commit errato e leggine i dettagli: un percorso modificato,
styles.csse una riga aggiunta. - 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….
- 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. - Apri
styles.css: è CSS_RESTORED, senza la regola aggiunta. - 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".
- 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:
git switch --create shared/dark-regressionSalva DOC_DARK_BAD come styles.css, quindi:
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-regressionOra ripristina, pubblica e leggi il risultato:
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 HEAD0
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.
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.
Relativo
Termini del glossario introdotti
Ripristina — عكس; cambiamento inverso: تغيير معاكس; genitore principale: الأب الرئيسي.
Trascrizione video
La narrazione del video, spunto per spunto.
Mostra la trascrizione
- Annulla una modifica già eseguita da altre persone avere.
- Reset sposta indietro il ramo. Ripristina aggiunge a nuovo commit invece.
- Altri hanno già il vecchio commit. Ripristina lascia valida la loro copia.
- Costruisci il ramo condiviso con un commit errato, e un server locale che ce l'ha.
- Il grafico mostra M e il commit errato superiore.
- Il commit errato aggiunge una riga e il testo diventa pallido.
- Annotare il suo ID.
- Fare clic con il pulsante destro del mouse e scegliere Ripristina commit.
- Si applica immediatamente. Non c'è nessun messaggio editore.
- L'avviso dice ripristinato.
- Il nuovo commit prende il nome da quello vecchio.
- Il suo genitore è il commit errato. Niente lo era rimosso.
- Il file è tornato com'era. La regola pallida è andato.
- E il grafico mostra entrambi i commit. Il la storia non ha fatto altro che crescere.
- Si è mosso solo questo ramo. Niente lo è ancora pubblicato.
- Il ramo è un commit prima di servitore.
- Fare clic su Spingi. Questa è una spinta normale.
- L'avviso nomina la filiale e il servitore.
- Non era necessaria alcuna forza. La spinta ha aggiunto solo a impegnarsi.
- Nel terminale, git ripristina senza modifiche fa lo stesso.
- Il cattivo commit è ancora un antenato. Il la risposta è zero.
- E l'argomento inizia con Ripristina.
- Premi, quindi confronta l'ID del server con TESTA. Sono uguali.
- Cambia l'input: qualcuno ha modificato lo stesso riga più tardi.
- Il ripristino si interrompe con un conflitto. Risolvi e continuare o interrompere.
- Il ripristino di un'unione richiede un genitore. Di solito è il primo.
- Dopo aver ripristinato un'unione, unirlo branch di nuovo potrebbe non fare nulla.
- Esercizio: riportare il soggetto, il genitore, controllo dell'antenato e l'ID del server.
- Successivamente, trova un commit perduto con il reflog.