Un repo git è costituito da un insieme di branch. Per visualizzare tutti i branch git branch git branch evidenzia anche il branch su cui vi trovate al momento Per cambiare branch: git checkout -modifica il contenuto dell'albero di file affinché combaci col contenuto del branch git status Per controllare lo stato del repository ed avere indicazioni su come procedere per effettuare le operazioni principali correlate con tale stato. Usate questo comando tutte le volte che non vi ricordate lo stato o quello che dovete fare. Pagine di manuale di git man git- Ad esempio, per visualizzare la pagina di manuale del comando status man git-status Per vedere l'elenco dei commit git log Ogni commit contiene: hash (che lo identifica univocamente), autore, subject, messaggio di commit e altre info. git log vi mostra esattamente queste info. Per vedere anche il contenuto dei commit (diff): git log -p Per visualizzare solo l'hash e il subject di ogni commit: git log --oneline git clean -fd - aiuta anche se un checkout o qualche altra operazione si interrompe nel mezzo - attenzione al caso in cui abbiate veramente qualche vostro file in più' nel tree Per controllare cosa c'è di diverso nell'albero rispetto al commit su cui vi trovate: git diff Per resettare il contenuto dell'albero rispetto a un commit (modifica solo i file nel repo): git reset --hard Per resettare rispetto al commit in testa: git reset --hard HEAD oppure git reset --hard Per resettare al commit che precede quello in testa git reset --hard HEAD~ Per resettare al commit che precede di n posizioni quello in testa git reset --hard HEAD~n - anche questo aiuta nel caso di operazioni sospese nel mezzo, a volte va combinato con git clean Per visualizzare i repo remoti: git remote Per visualizzare tutte le info sui repo remoti: git remote -vvv Per sincronizzarsi con un branch remoto la cui storia è cambiata: git pull # per scaricare i cambiamenti # se tutto va bene, il git pull gia' basta per la sincronizzazione # altrimenti: git reset --hard / Per applicare patch git am ... In caso di fallimento, dovuto di norma a conflitti: git am --abort Per applicare una o più patch facendosi aiutare da git in caso di conflitti: git am -3 ... -Vi consiglio di applicare e gestire una patch alla volta Per controllare i conflitti: git diff Per risolvere i conflitti, editare i file interessati a mano. Per ciascun conflitto evidenziato da git, bisogna decidere fondamentalmente quale delle due versioni ci va bene, oppure decidere se è necessario qualcosa di diverso da entrambe le proposte. Ricordarsi di eliminare dal file anche i marker messi da git. Per segnalare che riteniamo che un conflitto sia stato risolto su un dato file: git add Per fare continuare git am dopo la risoluzione dei conflitti su tutti i file coinvolti: git am --continue Per abbandonare se ci arrendiamo: git am --abort Configurazione nome utente ed indirizzo email (necessario per i passaggi successivi). git config --global user.email "you@example.com" git config --global user.name "Your Name" NOTA: Un errore comune, per il quale git non da segnalazioni, ma si limita poi solo a funzionare male, è scrivere mail al posto di email! Per creare un commit che contiene tutte le modifiche attuali git commit -a Per creare un commit con solo una parte dei file git add ... git commit (in prammatica i file aggiunti passano nello stato staged for commit) Per controllare le modifiche pronte per il commit, ossia quelle che sarebbero trasformate in un commit nel caso invochiate il comando "git commit" senza opzioni: git diff --cached Per creare un commit solo da parte delle modifiche: 1. git add -p 2. Seguire poi le istruzioni per aggiungere un hunk alla volta. Nel caso abbiate bisogno anche di spezzare qualche hunk (opzione split), attenzione al fatto che git riesce a spezzare un hunk solo nei punti in cui ci sono righe in cui l'hunk non effettua modifiche. Se, invece, l'hunk costituito da un blocco unico di righe modificata, allora, per spezzarlo, dovete scegliere l'opzione edit, e seguire le istruzioni fornite da git. 3. Per controllare le modifiche pronte per il commit git diff --cached 4. Per effettuare il commit git commit Per spezzare un commit 1. Se si vuole riutilizzare il titolo ed il messaggio di commit, metterli da parte in qualche modo 2. git reset HEAD~ # elimina l'ultimo commit senza modificare l'albero di lavoro 3a. git add -p # aggiungere solo gli hunk che si vuole oppure 3b. git add ... # per aggiungere solo i file che si vuole 4. git commit # fare un commit con gli hunk parziali 5. Ripetere dal punto 3 per il prossimo commit, e così via Per modificare il commit in testa: git commit --amend -a Per modificare solo titolo e messaggio del commit in testa: git commit --amend Per creare una patch dal commit in testa: git format-patch HEAD~ Per creare delle patch per gli n commit in testa git format-patch HEAD~n Per creare una sola patch git format-patch ~.. Per creare una copia del branch corrente (e selezionarla come nuovo branch corrente): git checkout -b Per cambiare la storia: git rebase -i Per eliminare un branch: git branch -D -------------------------- Per eliminare la storia da un branch: (per esempio perché è diventato troppo grande per stare su un repo ospitato da un servizio tipo bitbucket) https://passingcuriosity.com/2017/truncating-git-history/ Ad esempio, per ottenere un branch bfq-mq-private in cui la storia parte solo dal commit che introduce la versione 4.16 di Linux, e farne il push su un repository remoto che si chiama anch'esso bfq-mq-private: git checkout master git checkout -b master-v4.16 v4.16 git checkout --orphan temp 0adb32858b0bddf4ada5f364a84ed60b196dbcda # commit Linux 4.16 git commit -m "Linux 4.16" git cherry-pick 622821c94591~..c614f6586fd8 # sequenza di commit di bfq in bfq-mq-private # risolvere i conflitti, se necessario, usando poi # git add -u # se git diff da ancora differenze # git cherry-pick --continue git branch -D bfq-mq-private # se bfq-mq-private esiste gia' (passo distruttivo!) git branch -m temp bfq-mq-private git push --force --set-upstream bfq-mq-private bfq-mq-private git branch -D master-v4.16 -------------------------- Git vieta di eseguire operazioni sui branch (checkout, pull, merge, rebase, ...) se ci sono modifiche pendenti nel repository. Quindi, per poter effettuare tali operazioni, ci sono varie possibilità. 1. git reset --hard Questo distrugge però tutte le modifiche 2. git commit -a E si mettono tutte le modifiche in un commit temporaneo 3. git stash A volte creare dei commit temporanei può essere sorgente di confusione. Per evitare di creare tali commit temporanei, si può utilizzare git stash. Per mettere da parte modifiche pendenti: git stash Per vedere la lista delle modifiche pendenti: git stash list Per riapplicare le ultime modifiche messe da parte, e toglierle dalla lista: git stash pop -------------------------- Per tenere un commit ancora in sviluppo in un branch, in modo tale da non perdere/dimenticare il commit, senza avere gli effetti del commit sui file, e senza dover adottare soluzione più complesse (staging, branch multipli), un semplice trucco è git revert Questo crea un nuovo commit che effettua il revert di quello che si vuole tenere. Per tornare a lavorare sul commit, basterà poi eliminare semplicemente il revert (e risolvere gli eventuali conflitti che l'eliminazione del revert potrebbe causare). -------------- PROBLEMA ri-compilazione dopo cambio branch git aggiorna i timestamp di TUTTI i file che vengono modificati se si cambia branch, anche se, nel nuovo branch, i file sono più vecchi rispetto al branch di partenza. Un trucco per evitare poi compilazioni inutili è sfruttare make --dry-run poi fare un touch dei file che effettivamente potrebbero essere cambiati, quindi effettuare la vera e propria compilazione Il trucco non funziona per certe configurazioni del kernel. Ad esempio, nel caso ci sia objtool abilitato. ---------------- Scaricamento di un commit da GitHub, direttamente sotto forma di patch: http://chem-bla-ics.blogspot.com/2011/01/github-tip-download-commits-as-patches.html