{"id":8069,"date":"2011-12-12T12:20:33","date_gmt":"2011-12-12T11:20:33","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=8069"},"modified":"2011-12-12T12:21:12","modified_gmt":"2011-12-12T11:21:12","slug":"impariamo-ad-usare-git-prima-parte","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/impariamo-ad-usare-git-prima-parte\/","title":{"rendered":"Impariamo ad usare git (prima parte)"},"content":{"rendered":"<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/12\/git-logo.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/12\/git-logo.jpg\" alt=\"git-logo\" title=\"git-logo\" width=\"114\" height=\"106\" class=\"alignleft size-full wp-image-8142\" \/><\/a> In questa nuova guida, utile a tutti gli iPhone e iPad developers (ma non solo) non parleremo di programmazione vera e propria, ma vedremo come utilizzare e sfruttare al meglio un utile strumento \/ servizio durante lo sviluppo delle nostre applicazioni iOS: <strong>git<\/strong>, una delle migliori alternative a Mercurial o Subversion, che ci aiuter\u00e0 a tenere ordine tra le diverse versioni dei nostri progetti e a lavorare in team con altri sviluppatori. Oggi vedremo come utilizzare git via terminale ma, prima di addentrarci nella pratica, scopriamo insieme di cosa si tratta.<!--more--><\/p>\n<blockquote><p>&#8220;Git is a free &amp; open source, distributed version control system designed to handle everything from small to very large projects with speed and efficiency.&#8221;<\/p><\/blockquote>\n<h4>Cos&#8217;\u00e8 git?<\/h4>\n<p>Questa \u00e8 la descrizione che offrono i creatori di git sul loro sito <a href=\"http:\/\/git-scm.com\/\" target=\"_blank\">http:\/\/git-scm.com\/<\/a>. Il nodo cruciale di questa definizione \u00e8 &#8220;version control system&#8221; e se se ne ignora il significato tutto resta piuttosto oscuro.<\/p>\n<p>Cos`\u00e8, quindi, un &#8220;version control system&#8221;? Se mi \u00e8 perdonata la tautologia un &#8220;version control system&#8221; \u00e8 un &#8220;version control system&#8221;, nient&#8217;altro! Non \u00e8 un tool di backup, non \u00e8 un modo per condividere un progetto ma \u00e8 solo un sistema per mantenere il controllo delle versioni. Mantenere il controllo delle versioni ci aiuta poi in altri aspetti come appunto la condivisione di un progetto e le copie di backup, ma \u00e8 bene non confondere i ruoli.<\/p>\n<p>Git \u00e8 quindi un sistema di controllo delle versioni, significa quindi che riesce a mantenere memoria degli stati precedenti dei nostri progetti. Chiaramente git non si limita solo a questo ma fa anche molto altro e lo vedremo lungo l&#8217;articolo.<\/p>\n<p>Git non \u00e8 l&#8217;unico software per il controllo di versione, ne esistono tantissimi e i pi\u00f9 famosi sono forse quelli citati ad inizio articolo: SVN e Mercury. <\/p>\n<p>Git \u00e8 riuscito a farsi strada tra questi colossi grazie ad alcune caratteristiche che lo rendono unico nel suo genere e non a caso viene utilizzato da diversi progetti importanti quali il kernel linux, android, debian&#8230; oltre ovviamente allo stesso git. Ricordiamo inoltre che git \u00e8 il sistema di controllo della versione che viene usato dal nostro amato Xcode.<\/p>\n<p>Probabilmente l&#8217;aspetto che pi\u00f9 differenzia git da altri sistemi di versioning \u00e8 l&#8217;essere <em>server-less<\/em> non viene usato infatti nessun server centralizzato per mantenere le informazioni sul progetto (come avviene ad esempio con svn) ma ciascuna copia ne detiene una versione completa, rendendo obsoleto il concetto di working-copy tipico degli ambienti di sviluppo basati su svn.<br \/>\nC&#8217;\u00e8 un aspetto di git, forse meno importante, ma che soddisfa la mia voglia di ordine nel filesystem ed \u00e8 il fatto che git memorizza tutte le info necessarie in una cartella &#8220;.git&#8221; all&#8217;interno della root del progetto senza riempire il filesystem di cartelle .svn.<\/p>\n<h4>Facciamo pratica<\/h4>\n<p>Per comprendere git non ci servir\u00e0 n\u00e9 Xcode n\u00e9 altri programmi. Ci baseremo infatti esclusivamente sul terminale. Avviamo quindi il terminale e creiamo la cartella &#8220;learn git&#8221; dove meglio ci piace. (ricordo che nel terminale <em>cd<\/em> \u00e8 il comando per cambiare directory e <em>mkdir<\/em> quello per crearne una nuova).<\/p>\n<p>Dall&#8217;interno della cartella appena creata digitiamo il comando<\/p>\n<pre>\r\ngit init\r\n<\/pre>\n<p>Vedremo quindi un messaggio simile a questo:<\/p>\n<pre>\r\nInitialized empty Git repository in \/Users\/ignazioc\/Desktop\/learn git\/.git\/\r\n<\/pre>\n<p>Abbiamo appena creato il nostro primo <strong>repository<\/strong>. Possiamo infatti vedere che all&#8217;interno della cartella &#8220;learn git&#8221; \u00e8 stata creata una cartella nascosta &#8220;.git&#8221;<\/p>\n<pre>\r\n$ ls -laF\r\ntotal 0\r\ndrwxr-xr-x   3 ignazioc  staff  102 Dec  8 18:07 .\/\r\ndrwx------+ 22 ignazioc  staff  748 Dec  8 18:07 ..\/\r\ndrwxr-xr-x  10 ignazioc  staff  340 Dec  8 18:07 .git\/\r\n<\/pre>\n<p>Una volta che il <strong>repository<\/strong> \u00e8 stato creato iniziamo ad aggiungere files al nostro progetto, aggiungiamo ad esempio un file di testo &#8220;file1.txt&#8221; che al suo interno abbia questo testo:<\/p>\n<pre>\r\nQuesta \u00e8 la prima versione del progetto.\r\n<\/pre>\n<p>Per farlo da terminale potete semplicemente scrivere:<\/p>\n<pre>\r\necho \"Questa \u00e8 la prima versione del progetto\" &gt; file1.txt\r\n<\/pre>\n<h4>Facciamo il commit del nostro primo progetto<\/h4>\n<p>Supponiamo che il nostro lavoro sia finito qui, siamo soddisfatti della frase scritta e vogliamo che diventi un punto fermo nella storia del nostro progetto: quello che vogliamo \u00e8 creare un oggetto <strong>commit<\/strong> o come si dice in gergo &#8220;fare il commit del progetto&#8221;.<\/p>\n<p>Un commit \u00e8 composto dai file che sono stati modificati dal precedente commit, un riferimento a tale commit e da un nome univoco.<\/p>\n<p>Se avete studiato un p\u00f2 di teoria dei grafi potete immaginare i vari commit come un grafo aciclico e diretto:<\/p>\n<ul>\n<li>ciascun commit, escluso il primo, ha un riferimento ai precedenti commit (pu\u00f2 essere figlio di due o pi\u00f9 commit)<\/li>\n<li>ciascun commit, escluse le foglie, hanno un riferimento ai commit successivi.<\/li>\n<\/ul>\n<p>Per creare il nostro primo commit digitiamo:<\/p>\n<pre>\r\ngit add .\r\n<\/pre>\n<p>Questo comando dir\u00e0 a git quali files aggiungere nel commit, in questo caso verranno aggiunti tutti i files modificati o aggiunti dal precedente commit.<\/p>\n<p>Eseguimo quindi il commit digitando:<\/p>\n<pre>\r\ngit commit -m \"Primo commit\"\r\n<\/pre>\n<p>Dovreste ottenere questo output:<\/p>\n<pre>\r\n$ git commit -m \"Primo commit\"\r\n[master (root-commit) 5b28669] Primo commit\r\n 1 files changed, 1 insertions(+), 0 deletions(-)\r\n create mode 100644 file1.txt\r\n<\/pre>\n<p>in cui si vede chiaramente che abbiamo aggiunto un file.<\/p>\n<p>Creiamo altri due file sulla falsariga del primo e creiamo un nuovo commit dopo aver creato ciascun file.<\/p>\n<p>Dopo aver creato tre commit digitiamo:<\/p>\n<pre>\r\ngit log\r\n<\/pre>\n<p>vedremo un risultato simile al seguente:<\/p>\n<pre>\r\n$ git log\r\n\r\ncommit a727634e6807cbae1eb1a0e2c01e68d08ded3e1b\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 18:38:14 2011 +0100\r\n\r\n    Terzo commit\r\n\r\ncommit d4faaf42fa6cd1bc8e2d045c7bc5fb4fae0ab021\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 18:37:50 2011 +0100\r\n\r\n    Secondo commit\r\n\r\ncommit 5b2866927ff5477ec225259dbf502577b44e7afa\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 18:34:47 2011 +0100\r\n\r\n    Primo commit\r\n<\/pre>\n<p>Vediamo in ordine inverso i tre oggetti commit che abbiamo creato, con tanto di nome univoco SHA1, l&#8217;autore la data ed il commento.<\/p>\n<p>Altri comandi molto utili sono:<\/p>\n<ul>\n<li><strong>git status<\/strong>: mostra quali file sono cambiati tra lo stato attuale del progetto e lo stato <em>corrente<\/em> del repository (*)<\/li>\n<li><strong>git diff<\/strong>: mostra le differenze sui singoli files<\/li>\n<li><strong>git mv<\/strong>: marca un file come da spostare sul repository<\/li>\n<li><strong>git rm<\/strong>: marca un file come da rimuovere sul repository<\/li>\n<\/ul>\n<p>(*) l&#8217;indicazione dello stato corrente necessita una spiegazione: all&#8217;interno del repository vengono mantenuti dei riferimenti ai diversi oggetti commit, il riferimento HEAD punta al commit <em>corrente<\/em> e viene portato avanti automaticamente quando si effettua un nuovo commit.<\/p>\n<h4>Una vita non lineare<\/h4>\n<p>I progetti non hanno mai una vita lineare, neanche nel mondo ideale. Ci sono sempre almeno un paio di versioni &#8220;funzionanti&#8221; nelle quali si prova ad aggiungere nuove funzionalit\u00e0 o rimuovere vecchi problemi. git tiene conto di queste esigenze e risponde con la funzionalit\u00e0 chiamata <strong>branch<\/strong>. In un repository possono coesistere pi\u00f9 branch contemporaneamente, il primo viene creato di default e si chiama <em>master<\/em> tutti gli altri possono essere creati successivamente dall&#8217;utente.<\/p>\n<p>Per creare un nuovo branch occorre digitare:<\/p>\n<pre>\r\ngit branch nuovo_ramo\r\n<\/pre>\n<p>in questo modo abbiamo creato un nuovo ramo. Possiamo vedere il risultato di questo comando digitando<\/p>\n<pre>\r\n$ git branch\r\n* master\r\n  nuovo_ramo\r\n<\/pre>\n<p>Questo per\u00f2 non ci porter\u00e0 automaticamente a lavorare sul ramo appena creato, infatti, se proviamo a fare delle modifiche e creare un nuovo commit, vedremo che le modifiche vengono apportate al branch master.<\/p>\n<pre>\r\n$ echo \"Questa \u00e8 la quarta versione del progetto\" &gt; file4.txt\r\n$ git add .\r\n$ git commit -m \"Quarto commit\"\r\n$ git log\r\ncommit 738018f1e5058e4c6f8f23f13960dbf8c7740976\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 19:32:29 2011 +0100\r\n\r\n    Quarto commit\r\n\r\ncommit a727634e6807cbae1eb1a0e2c01e68d08ded3e1b\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 18:38:14 2011 +0100\r\n\r\n    Terzo commit\r\n\r\ncommit d4faaf42fa6cd1bc8e2d045c7bc5fb4fae0ab021\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 18:37:50 2011 +0100\r\n\r\n    Secondo commit\r\n\r\ncommit 5b2866927ff5477ec225259dbf502577b44e7afa\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 18:34:47 2011 +0100\r\n\r\n    Primo commit\r\n<\/pre>\n<p>Per iniziare a sviluppare sul nuovo branch dobbiamo digitare il comando:<\/p>\n<pre>\r\ngit checkout nuovo_ramo\r\n<\/pre>\n<p>Dopo aver switchato sul branch su cui vogliamo lavorare effettuiamo un nuovo commit come abbiamo fatto in precedenza:<\/p>\n<pre>\r\n$echo \"Questa \u00e8 la quinta versione del progetto\" &gt; file5.txt\r\ngit add .\r\ngit commit -m \"Quinto commit\"\r\n<\/pre>\n<p>Se guardiamo il log vediamo che non appare il quarto commit, perch\u00e9 \u00e8 stato effettuato sul branch master, mentre stiamo lavorando sul branch nuovo_ramo.<\/p>\n<pre>\r\ncommit eb9a069a7d566363fcfa772d41d50713f875c7f7\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 19:41:03 2011 +0100\r\n\r\n    Quinto commit\r\n\r\ncommit a727634e6807cbae1eb1a0e2c01e68d08ded3e1b\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 18:38:14 2011 +0100\r\n\r\n    Terzo commit\r\n\r\ncommit d4faaf42fa6cd1bc8e2d045c7bc5fb4fae0ab021\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 18:37:50 2011 +0100\r\n\r\n    Secondo commit\r\n\r\ncommit 5b2866927ff5477ec225259dbf502577b44e7afa\r\nAuthor: Ignazio \r\nDate:   Thu Dec 8 18:34:47 2011 +0100\r\n\r\n    Primo commit\r\n<\/pre>\n<p>Per avere una idea grafica di quello che sta succedendo possiamo usare questo comando (trovato su <a href=\"http:\/\/stackoverflow.com\/questions\/1057564\/pretty-git-branch-graphs\" target=\"_blank\">stackoverflow<\/a>):<\/p>\n<pre>\r\ngit log --graph --date-order -C -M --pretty=format:\" %ad [%an] %Cgreen%d%Creset %s\" --all --date=short\r\n<\/pre>\n<p>il cui output \u00e8 questo:<\/p>\n<pre>\r\n*  2011-12-08 [Ignazio]  (nuovo_ramo) Quinto commit\r\n| *  2011-12-08 [Ignazio]  (HEAD, master) Quarto commit\r\n|\/  \r\n*  2011-12-08 [Ignazio]  Terzo commit\r\n*  2011-12-08 [Ignazio]  Secondo commit\r\n*  2011-12-08 [Ignazio]  Primo commit\r\n<\/pre>\n<p>In questa immagine, invece, vedete lo stesso output con un programma dotato di GUI:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/12\/tutorial_git_img1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/12\/tutorial_git_img1.png\" alt=\"\" width=\"192\" height=\"94\" class=\"aligncenter size-full wp-image-8123\" \/><\/a><br \/>\n<\/center><\/p>\n<h4>merge<\/h4>\n<p>Terminate le modifiche effettuate sul branch <em>nuovo_ramo<\/em> \u00e8 adesso il momento riportarle sul <em>branch master<\/em>. Purtroppo non abbiamo garanzia che nessuno abbia intanto modificato i file del branch master, anzi, in uno sviluppo condiviso, questa \u00e8 la norma, quindi incrociamo le dita e speriamo che non ci siano conflitti di sorta.<\/p>\n<p>Switchiamo sul branch master e digitiamo:<\/p>\n<pre>\r\ngit merge nuovo_ramo\r\n<\/pre>\n<p>Ok, ci \u00e8 andata bene, non ci sono stati problemi ed il merge \u00e8 andato a buon fine:<\/p>\n<pre>\r\nMerge made by recursive.\r\n file5.txt |    1 +\r\n 1 files changed, 1 insertions(+), 0 deletions(-)\r\n create mode 100644 file5.txt\r\n<\/pre>\n<p>Se esaminiamo i log a questo punto noteremo che \u00e8 stato creato il commit di tipo merge e sono presenti sia il quarto che il quinto commit:<\/p>\n<pre>\r\ncommit 1bfdc5768b55b80b50bff8a8c3ad28e6fd6dd699\r\nMerge: 738018f eb9a069\r\nAuthor: Ignazio Cal\u00f2 \r\nDate:   Thu Dec 8 22:15:42 2011 +0100\r\n\r\n    Merge branch 'nuovo_ramo'\r\n\r\ncommit eb9a069a7d566363fcfa772d41d50713f875c7f7\r\nAuthor: Ignazio Cal\u00f2 \r\nDate:   Thu Dec 8 19:41:03 2011 +0100\r\n\r\n    Quinto commit\r\n\r\ncommit 738018f1e5058e4c6f8f23f13960dbf8c7740976\r\nAuthor: Ignazio Cal\u00f2 \r\nDate:   Thu Dec 8 19:32:29 2011 +0100\r\n\r\n    Quarto commit\r\n<\/pre>\n<p>Diamo uno sguardo al grafo per capire cosa \u00e8 successo:<\/p>\n<pre>\r\n*    2011-12-08 [Ignazio]  (HEAD, master) Merge branch 'nuovo_ramo'\r\n|\\  \r\n| *  2011-12-08 [Ignazio]  (nuovo_ramo) Quinto commit\r\n* |  2011-12-08 [Ignazio]  Quarto commit\r\n|\/  \r\n*  2011-12-08 [Ignazio]  Terzo commit\r\n*  2011-12-08 [Ignazio]  Secondo commit\r\n*  2011-12-08 [Ignazio]  Primo commit\r\nignaziocmac:learn git ignaziocalo$ \r\n<\/pre>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/12\/tutorial_git_img2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/12\/tutorial_git_img2.png\" alt=\"\" width=\"282\" height=\"119\" class=\"aligncenter size-full wp-image-8125\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Da notare che il nuovo oggetto commit ottenuto con il merge ha due genitori, il quarto commit del brach master ed il quinto commit del branch nuovo_ramo.<\/p>\n<h4>Rimuovere il branch<\/h4>\n<p>Una volta effettuato il merge probabilmente il branch <em>secondo_ramo<\/em> non ci servir\u00e0 pi\u00f9, possiamo quindi rimuoverlo digitando:<\/p>\n<pre>\r\ngit branch -d nuovo_ramo\r\n<\/pre>\n<p>Questa prima parte della guida all&#8217;uso di git termina qui, nella prossima puntata affronteremo la condivisione dello stesso progetto su pi\u00f9 utenti, anche attraverso internet.<\/p>\n<p>Buon coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In questa nuova guida, utile a tutti gli iPhone e iPad developers (ma non solo) non parleremo&#8230;<\/p>\n","protected":false},"author":53,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[8],"tags":[990,991,995,993,988,989,992,994,987],"class_list":["post-8069","post","type-post","status-publish","format-standard","hentry","category-guide-varie","tag-alternativa-a-mercurial","tag-alternativa-a-svn","tag-branch-git","tag-commit-git","tag-git-da-terminale","tag-git-iphone-e-ipad","tag-git-xcode","tag-repository-git","tag-version-control-system-xcode"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/8069","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=8069"}],"version-history":[{"count":36,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/8069\/revisions"}],"predecessor-version":[{"id":8145,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/8069\/revisions\/8145"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=8069"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=8069"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=8069"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}