====== Git ====== Molto utile questo howto: **[[http://b.lesseverything.com/2008/3/25/got-git-howto-git-and-github|Got Git? HOWTO git and github]]**. Vedere anche **[[https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow|Comparing Workflows]]**. Installare i pacchetti Debian * **''git-core''** Creare una copia locale di un progetto: git clone http://rivendell.lovergine.com/pubgit/ecw.git ecw Le informazioni relative al repository vengono salvate in una sola directory **''.git''** nella directory radice del progetto. Per aggiornare il repository locale basta eseguire nella directory del progetto: git pull ===== Prompt personalizzato ===== Quando si lavora in una copia locale Git, è comodo sapere a quale repository siamo sincronizzati. Questo trucco (da aggiungere al proprio **''.bashrc''** o simili) mostra il nome del repository git nel prompt: parse_git_branch() { git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/' } PS1="${debian_chroot:+($debian_chroot)}\u@\h:\w\$(parse_git_branch)$ " ===== Commit come se fosse SVN ===== Anzitutto si deve registrare un account su **[[https://github.com/]]**, si prende nota della **API token** (menu //Account Settings//, //Account Admin//) e si carica la propria chiave pubblica SSH (menu //Account Settings//, //SSH Public Keys//). Il proprietario del progetto deve concedere i permessi di commit. Per testare il funzionamento della chiave RSA: ssh -T git@github.com Se si ha una copia locale di un repository a cui si era fatto accesso via HTTPS, per passare alla modalità SSH: git remote -v origin https://github.com/RigacciOrg/ProTherm (fetch) origin https://github.com/RigacciOrg/ProTherm (push) git remote set-url origin git@github.com:RigacciOrg/ProTherm.git ==== git clone ==== Fare un **''clone''** del master repository e verificare che sia aggiornato. In questo esempio l'URL è di tipo //read only// ad accesso anonimo, il che obbliga a fare uno sgamotto prima del commit (vedi avanti). git clone git://github.com/qgis/qgis-web-client.git cd qgis-web-client git pull ==== git commit ==== A differenza che con SVN, il **''commit''** si intende rispetto alla propria copia locale. Verificare che le informazioni personali siano corrette (vengono salvate in **''$HOME/.gitconfig''**). In questo esempio viene corretto l'autore del commit dopo averlo fatto: git status git commit -a git config --global user.name "Niccolo Rigacci" git config --global user.email niccolo@rigacci.org git commit --amend --author='Niccolo Rigacci ' ==== git push ==== Solo con il **''push''** le modifiche vengono propagate sul server remoto. Le credenziali di accesso a github sono salvate in ''$HOME/.gitconfig''. In questo esempio è necessario specificare dove fare il push, perché il ''clone'' è stato fatto da un repository in sola lettura: git config --global github.user RigacciOrg git config --global github.token 2045669db9df8ba1dd13a13f62f2f793 git push git@github.com:qgis/qgis-web-client.git In alternativa si definisce un nuovo repository remoto (questo in lettura/scrittura) e si fa il ''push'' su di esso: git remote git remote add origin_rw git@github.com:qgis/qgis-web-client.git git push origin_rw ===== Fork e Request Merge su Sourceforge ===== Se si vuole contribuire a un progetto su Sourceforge usando Git: - **Fork** Dalla pagina web del progetto si clicca sul pulsante //Fork//, il codice in questione viene duplicato sotto il proprio account, sotto una gerarchia del tipo **u/niccolo**. - **Dowload** Sul proprio PC si esegue il download (clone) del codice (nella pagina web viene indicato come fare accesso RW): git clone ssh://niccolo@git.code.sf.net/u/niccolo/phpmpreloaded u-niccolo-phpmpreloaded - **Modifica** Dopo aver modificato i sorgenti con l'editor preferito, ecc. si verifica lo stato del repository con **''git status''**, si aggiungono i file modificati al successivo commit con **''git add file''**. - **Upload** Impostare i dati del proprio profilo (vedi sopra i comandi **''%%git config --global%%''**), quindi eseguire git commit -m "Comment to this commit" git push - **Request Merge** Dalla pagina web del progetto si clicca sul pulsante //Request Merge//, viene chiesto un commento più ampio della motivazione. ===== Fork e Pull Request su GitHub ===== - Navigare sul sito web, ad esempio [[https://github.com/osmandapp/OsmAnd-resources/]] - Cliccare sul pulsante **Fork**. Viene richiesto un account GitHub. Il fork viene creato all'interno di questo account. - Scaricare i sorgenti sul PC, con git clone https://github.com/RigacciOrg/OsmAnd-resources OsmAnd-resources - Modificare i sorgenti secondo il bisogno. - Fare il commit e il push delle modifichegit commit -a git push - Navigare alla radice del proprio fork e cliccare sul pulsante **New pull request**. ===== Eliminare un fork ===== Dalla propria home page, cliccare sul fork. Controllare che il titolo della pagina sia **%%/%%**. Quindi cliccare sul tab **Settings** e quindi in fondo alla pagina **Delete this repository**. ===== Gestione dei tag ===== Uno dei motivi più comuni per cui creare un **tag** è dare un nome e un numero di versione di una particolare versione del progetto. Quello che viene maracto con un tag diventa **immutabile** e non potrà essere cambiato in futuro. Per contro i **branch** servono a identificare rami diversi dello sviluppo che subiranno eventuali cambiamenti. Ad esempio per marcare la versione corrente con il nome **print3d-1.0** si esegue: git tag -a print3d-1.0 se invece della versione corrente si vuole etichettare un commit precedente, bisogna individuare l'hash ed eseguire il comando (notare che l'hash è indicato in forma abbreviata): git log --pretty=oneline ... d7dd3e5c44023bfefc6a6c649506e3e029929b4c Added a 3D printable OpenSCAD model. ... git tag -a print3d-1.0 d7dd3e5 Infine bisogna salvare sul repository remoto (origin) il nuovo tag: git push origin print3d-1.0 Se si desidera rimuovere un tag dal repository remoto: git push --delete origin print3d-1.0 ===== Gestionde dei branch ===== Mostra i rami di sviluppo, locali e remoti: git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/master ''remotes/origin/HEAD'' is the default branch for the remote named origin. This lets you simply say ''origin'' instead of ''origin/master''. ==== Creazione di un nuovo branch ==== Per creare localmente un nuovo branch di nome **jessie**: git branch jessie Si può verificare che sia stato creato: git branch -a jessie * master remotes/origin/HEAD -> origin/master remotes/origin/master Si vede che localmente esistono i due branch **jessie** e **master**; il secondo è marcato con un asterisco ed è quindi quello utilizzato per effettuare i commit locali. Quindi aver creato un branch nuovo non significa automaticamente lavorarci sopra. ==== Selezionare il branch di lavoro locale ==== Per iniziare a lavorare localmente su un determinato branch si usa il comando **git switch**: git switch jessie Si verifica che il branch locale predefinito (marcato con un asterisco) sia effettivamente cambiato: git branch -a * jessie master remotes/origin/HEAD -> origin/master remotes/origin/jessie remotes/origin/master In ogni momento è possibile cambiare branch di lavoro locale, ad esempio tornando su master: git switch master **ATTENZIONE** Prima di Git 2.23 si utilizzava il comando **git checkout** per cambiare branch di lavoro locale. ==== Propagare un branch locale anche in remoto ==== Per propagare il nuovo branch anche sul repository remoto: git push --set-upstream origin jessie È possibile verificare che localmente si sta lavorando ancora sul branch **master** e che sul repository remoto esistono i branch **master** e **jessie**: git branch -a jessie * master remotes/origin/HEAD -> origin/master remotes/origin/jessie remotes/origin/master Avendo fatto lo switch (o il checkout) ad uno specifico branch, gli eventuali commit andranno su di esso. Lo possiamo verificare con ''git status'': git status On branch jessie Your branch is ahead of 'origin/jessie' by 1 commit. (use "git push" to publish your local commits) ==== Clonare uno specifico branch ==== Quando si clona il repository remoto è possibile indicare subito su quale branch si intende lavorare: git clone --branch jessie https://github.com/RigacciOrg/project.git Con **git branch** sarà possibile verificare quale è il branch locale predefinito, marcato con un asterisco. ===== Misc Commands ===== ==== Restore o revert di un singolo file ==== A partire da Git 2.23 esiste il comando **git restore** che consente di ripristinare un file modificato localmente alla sua versione di checkout: git restore path/to/file Con versioni precedenti di Git si può usare: git checkout -- path/to/file Se si desidera tornare ad uno specifico commit, si può visualizzare il log degli stessi e richiederlo esplicitamente: git log path/to/file git checkout path/to/file ==== Colors ==== Disable GUI colors: git config --global color.ui false ==== Locally Committed Differences ==== Per vedere le differenze tra il master remoto e quello locale (**ATTENZIONE** questo comando non controlla la versione ultima presente sul repository, lavora sui dati salvati localmente!): git diff --name-only remotes/origin/master..master L'opzione ''%%--name-only%%'' limita l'output al solo nome dei file cambiati. ==== Mostrare l'URL del repository ==== git remote show origin ===== Annullare le modifiche locali ===== I file modificati localmente possono essere in uno dei seguenti **tre stati**: * **Type 1**. Staged Tracked files * **Type 2**. Unstaged Tracked files * **Type 3**. Unstaged UnTracked files a.k.a UnTracked files Dove i termini significano: * **Staged** - File che sono stati aggiunti all'area di lavoro (staging area) o all'indice. * **Tracked** - File modificati, di cui il sistema Git si è accorto. * **UnTracked** - File nuovi, sempre //unstaged//. Se sono //staged// allora sono //tracked//. Per annullare delle modifiche si possono usare i seguenti comandi: * **''git checkout .''** - Removes Unstaged Tracked files ONLY [Type 2] * **''git clean -f''** - Removes Unstaged UnTracked files ONLY [Type 3] * **''git reset --hard''** - Removes Staged Tracked and UnStaged Tracked files ONLY [Type 1, Type 2] * **''git stash -u''** - Removes all changes [Type 1, Type 2, Type 3] Effettuare lo **stash** significa //mettere da parte// provvisoriamente le modifiche locali. Ciò che è stato //stashed// può essere visto con **git stash list**. Questi passaggi riallineano il repository locale con quello remoto. L'operazione conclusiva di merge comunque viene registrata in Git e pertanto viene chiesa una riga di commento: # Get remote files. git fetch # Remove local tracked files. git reset --hard HEAD # Merge the upstream branch into local files. git merge '@{u}' ===== Chiave SSH per Github.com ===== Dal **13 agosto 2021** [[https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/|Github non accetterà più accesso utilizzando login e password]]. Ad esempio l'accesso da riga di comando tramite il comando **git** cesserà di funzionare. Sarà possibile utilizzare una chiave SSH/RSA; volendo utilizzare una chiave appositamente dedicata, quella che segue è la procedura. Creare la chiave RSA apposita: ssh-keygen -f ~/.ssh/id_github_rsa Aggiungere una sezione nel file **$HOME/.ssh/config**: Host github github.com HostName github.com IdentityFile ~/.ssh/id_github_rsa User RigacciOrg Collegarsi all'interfaccia web di amministrazione del proprio account, nella sezione **Settings** => **SSH and GPG keys** è possibile aggiungere una chiave, copiando il contenuto del file **id_github_rsa.pub**. A questo punto si può verificare che la chiave RSA funzioni: ssh -T git@github.com Hi RigacciOrg! You've successfully authenticated, but GitHub does not provide shell access. Verifichiamo che un repository locale sia stato clonato tramite protocollo HTTPS: git remote -v origin https://github.com/RigacciOrg/photo-reframe-slideshow.git (fetch) origin https://github.com/RigacciOrg/photo-reframe-slideshow.git (push) Si modifica il protocollo per utilizzare SSH/RSA: git remote set-url origin git@github.com:RigacciOrg/photo-reframe-slideshow.git In queste condizioni il **git clone** assume questo formato: git clone git@github.com:RigacciOrg/matrix-personal-bot.git