”Si prega di rebase in cima al master e uniremo la tua richiesta di pull”.
“Puoi per favore schiacciare i tuoi commit insieme in modo da ottenere una githistory pulita e reversibile?”.
“Puoi riscrivere il messaggio del tuo commit per descrivere meglio il problema itsolves e come lo risolve?”.
Domande come queste sono comunemente poste nelle richieste pull. Vediamo perché loroesistono, come eseguirli e i loro possibili problemi.,
Riformulare l’ultimo messaggio di commit
Una delle più semplici riscritture della cronologia che possiamo fare con git sta cambiando il messaggio lastcommit. Diciamo che subito dopo aver effettuato un commit trovi un errore di battitura nella suadescrizione, o trovi un modo migliore per descrivere il changeset. Per fare la correzione si esegue:
git commit --amend
Si aprirà un editor con l’ultimo messaggio di commit, in modo da poterlo modificare. Dopo il salvataggio, verrà creato un nuovo commit con le stesse modifiche e il nuovo messaggio, sostituendo il commit con il messaggio precedente.,
Questo può essere utile per includere i file che hai dimenticato di tenere traccia, o includemodifications ai file che hai appena commesso. Per fare ciò, è possibile aggiungere le modifiche e quindi eseguire la modifica:
git add README.md config/routes.rb git rm notes.txt git commit --amend
Oltre a modificare il messaggio di commit, il nuovo commit conterrà le modifiche specificate con git add
e git rm
. È inoltre possibile modificare l’autore. Per esempio:
git commit --amend --author="Tute Costa and Dan Croak <[email protected]>"
Realizzazione sbloccata!, È ora possibile modificare l’ultimo commit del repository per includere modifiche più recenti ai file e/o per migliorare il messaggio di commit. Ma non iniziare a modificare tutte le cose prima di capire l’ultima sezione di questo post sul blog intitolato “PERICOLO”.
Riformulare altri messaggi di commit
Mi piacerebbe parlarne ora, ma abbiamo bisogno di capire uno strumento più generale prima. Restate sintonizzati! Tutto il resto sarà più facile una volta letto su Reb
Interactive Rebase
git rebase
ri-applica commit, uno per uno, in ordine, dal tuo ramo corrente su un altro., Accetta diverse opzioni e parametri, quindi questa è una punta della spiegazione dell’iceberg, sufficiente a colmare il divario tra i commenti StackOverflow o GitHub e le pagine man di git.
Un’opzione interessante che accetta è--interactive
(-i
in breve), che aprirà un editor con un elenco dei commit che stanno per essere modificati. Thislist accetta comandi, consentendo all’utente di modificare l’elenco prima di avviare l’azione di base.
Vediamo un esempio.,
Riformulare altri messaggi di commit, prendere 2
Diciamo che voglio riformulare uno degli ultimi 4 commit di questo blog. Quindi eseguo git rebase -i HEAD~4
, ed ecco quello che vedo:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls pick 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend # Rebase 8db7e8b..fa20af3 onto 8db7e8b # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
Vediamo i quattro ultimi commit, dal più vecchio al più recente. Vedi il commento qui sotto thelist of commit? Ottimo lavoro a spiegare, git! pick
(p
in breve) è l’azione predefinita. In questo caso riapplicherebbe il commit così com’è, senza modifiche nei suoi contenuti o messaggi. Salvare (ed eseguire) questo file non apporterebbe modifiche al repository.,
Se io dico reword
(r
breve) in un commit voglio modificare:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls r 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
Quando ho salvare e chiudere l’editor, git seguire i comandi descritti, landingmyself nell’editor di nuovo, come se avessi modificato il commit 3e7ee36
. Modifico quellomessaggio commit, salva e esci dall’editor, ed ecco l’output:
Ora Caleb dice nel suo messaggio di commit “Interrompi tutte le evidenziazioni”, che tu sia un bambino o meno.
Realizzazione sbloccato! È ora possibile modificare il messaggio di anycommit che si desidera., Puoi farlo, assicurati di aver compreso la sezione “PERICOLO”.
Squash impegna insieme
altri Due comandi rebase interactive offre ci sono:
-
squash
(s
in breve), che fonde l’impegnarsi in quello precedente (quella in prima linea) -
fixup
(f
in breve), che agisce come “squash”, ma elimina questo commit’smessage
continueremo a lavorare con il rebase esempio abbiamo workedbefore., Abbiamo avuto quattro impegna, mio per questo post del blog, andthree altri da Caleb, che riguardavano la sua precedente post su PGP:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls pick 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
diciamo che voglio combinazione di Caleb si impegna insieme, perché appartengono alla stesso logiche di modifiche, e così siamo in grado di git revert
facilmente se troviamo weprefer di non avere tali cambiamenti in questo repository. Vorremo mantenere il primo messaggio di commit e schiacciare i due commit successivi nel precedente., Modificare pick
squash
dove appropriato:
pick 07c5abd Introduce OpenPGP and teach basic usage s de9b1eb Fix PostChecker::Post#urls s 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
Salva, e I terreni nell’editor per decidere il messaggio di commit della meldedthree impegna, per vedere come sono concatenati l’uno dopo l’altro):
# This is a combination of 3 commits. # The first commit's message is: Introduce OpenPGP and teach basic usage Besides demystifying a relatively complex tool, protocol, and etiquette, this post is intended to help with problems such as the one outlined in this tweet: > Emailed sensitive info to someone with PGP. They replied, with my > original email, all in clear text. They didn't realize it. # This is the 2nd commit message: Fix PostChecker::Post#urls # This is the 3rd commit message: Hey kids, stop all the highlighting # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Author: Caleb Hearth # Date: Tue Sep 2 09:39:07 2014 -0500 # # rebase in progress; onto 71d4789 # You are currently editing a commit while rebasing branch 'tc-git-rebase' on '71d4789'.
ho deciso di rimuovere il terzo messaggio di commit, e aggiungere più rilevante, nota per il secondo messaggio di commit. Salva l’editor e i quattro commit sono stati trasformatiin due: quello di Caleb e il mio dopo. Bene!,
Avremmo potuto usare il comandofixup
, se avessimo visto prima che volevamo i cambiamenti, ma non il messaggio di commit, del terzo commit. In tal caso, thecommands sarebbe stato simile a:
pick 07c5abd Introduce OpenPGP and teach basic usage s de9b1eb Fix PostChecker::Post#urls f 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
Quando salvato, l’editor avrebbe incluso il terzo messaggio di commit giàcommentato per noi:
Salva, e output:
Il risultato è lo stesso: 2 commit invece di 4, ognuno con un singolo blogpost diverso.
Realizzazione sbloccato! Ora puoi unire i commit insieme. Asalways, essere consapevoli della sezione pericolo.,
Rebase in cima a master
Fork una libreria open source, iniziare a lavorare su un ramo di funzionalità, e master inthe progetto upstream si muove avanti. La nostra cronologia assomiglia a:
A---B---C feature / D---E---F---G upstream/master
Il manutentore della libreria chiede come “rebase in cima al master”, quindi risolviamo eventuali conflitti di fusione che possono sorgere tra entrambi i rami e manteniamo insieme il nostro changeset.Il manutentore vorrebbe vedere una cronologia come:
A'--B'--C' feature / D---E---F---G upstream/master
Vogliamo riapplicare i nostri commit, uno per uno, in ordine, sul master di upstream.,Sembra la descrizione del comando rebase! Vediamo quali comandi ci farebbero entrare nello scenario desiderato:
# Point our `upstream` remote to the original fork git remote add upstream https://github.com/thoughtbot/factory_girl.git # Fetch latest commits from `upstream` (the original fork) git fetch upstream # Checkout our feature branch git checkout feature # Reapply it onto upstream's master git rebase upstream/master # Fix conflicts, then `git rebase --continue`, repeat until done # Push to our fork git push --force origin feature
Achievement sbloccato! Il tuo ramo di funzionalità verrà applicato in cima all’ultimo master della forcella originale.
E così arriviamo a DANGER
PERICOLO: Stai riscrivendo la cronologia
Vedi il--force
nell’ultimogit push
comando? Ciò significa che stiamo sovrascrivendo la storia di relepository., Questo è sempre sicuro da fare in commit che non condividiamo con altri membri del team, o in rami che ci appartengono (vedi le mie iniziali nell’esempio di questo post del blog).
Ma se forzate le edizioni push che erano già condivise con il team (commitsthat esistono al di fuori del mio repository, come le modifiche apportate ai commitsthat PGP sono già state condivise), allora il ramo di tutti non viene sincronizzato.
Riscrivere la storia significa abbandonare i commit esistenti e crearne di nuovi, che possono essere molto simili ma sono diversi., Se altri basano il lavoro sul tuo precedentecommits, e poi riscrivi e spingi i tuoi commit, i membri del tuo team dovranno ri-unire il loro lavoro (se notano la potenziale perdita).
A thoughtbot prefiggiamo i nostri rami con le nostre iniziali, segnalando che thosecommits potrebbe essere riscritto e altri non dovrebbero aggiungere commit al ramo. Whenthose impegna land in master o in un ramo condiviso, non li riscriviamo mai più.
Quindi riscrivi la cronologia git, a condizione che i commit riscritti esistano solo in yourrepository, o tu e il tuo team sapete che nessun altro dovrebbe basare il lavoro su di loro.,
Realizzazione sbloccato! Ora sapete come rebase pur essendo agood cittadino.