{"id":496,"date":"2014-11-02T18:17:21","date_gmt":"2014-11-02T17:17:21","guid":{"rendered":"https:\/\/alistapart.com\/it\/article\/git-la-rete-di-sicurezza-dei-vostri-progetti\/"},"modified":"2014-11-02T18:17:21","modified_gmt":"2014-11-02T17:17:21","slug":"git-la-rete-di-sicurezza-dei-vostri-progetti","status":"publish","type":"article","link":"https:\/\/alistapart.com\/it\/article\/git-la-rete-di-sicurezza-dei-vostri-progetti\/","title":{"rendered":"Git: la rete di sicurezza dei vostri progetti"},"content":{"rendered":"<p><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/11\/sketch42112722.jpg\" border=\"0\" align=\"left\" \/>Mi ricordo piuttosto bene il 10 Gennaio 2010: quello fu il giorno in cui perdemmo la cronologia completa di un progetto. Come version control system stavamo usando Subversion, che teneva la cronologia del progetto in un repository centrale su un server e noi facevamo regolarmente il backup di questo server, o perlomeno pensavamo fosse cos\u00ec. Poi, il server si ruppe e il backup non era andato a buon fine. Il nostro progetto non era completamente perso, ma tutte le versioni storiche erano andate.<\/p>\n<p>Migrammo a Git poco dopo la rottura del server. Avevo sempre visto il version control come una tortura: era troppo complesso e non abbastanza utile perch\u00e9 potessi vederne il valore, ma lo usavo comunque per dovere. Per\u00f2, dopo aver passato un po&#8217; di tempo sul nuovo sistema, cominciai a capire quanto potesse essere utile Git. Da allora, mi ha salvato la pelle in molte situazioni.<\/p>\n<p>Nel corso di questo articolo, vi mostrer\u00f2 come Git possa aiutarvi ad evitare gli errori e come rimediarvi se sono gi\u00e0 successi.<\/p>\n<div class=\"paragrafo\">\n<h2>Ogni collega del team \u00e8 un backup<\/h2>\n<p>Dal momento che Git \u00e8 un version control system distribuito, ogni membro del vostro team che ha clonato un progetto (o che ha fatto \u201ccheck out\u201d se venite da Subversion) ha automaticamente un backup sul proprio disco. Questo backup contiene la versione pi\u00f9 recente del progetto cos\u00ec come la sua storia completa.<\/p>\n<p>Questo significa che se la macchina locale di uno sviluppatore o addirittura il nostro server centrale dovessero mai rompersi ancora (e il backup non funzionare per una ragione qualsiasi), saremmo di nuovo \u201cup and running\u201d nel giro di pochi minuti: ogni repository locale dal disco di un collega del team \u00e8 tutto quello di cui abbiamo bisogno per una sostituzione completamente funzionante.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>I branch mantengono separate quel che deve rimanere separato<\/h2>\n<p>Non sono subito impazzito di gioia quando i miei colleghi pi\u00f9 tecnici mi avevano parlato di quanto fosse \u201ccool\u201d il branching in Git. Primo, devo ammettere che non avevo davvero compreso i vantaggi del branching e, secondo, venendo da Subversion, mi ricordavo fin troppo bene quanto la procedura fosse complessa e quanto facile commettere errori. Dati questi brutti ricordi, l&#8217;idea di lavorare con i branch mi metteva ansia e quindi avevo provato ad evitarli quando era possibile.<\/p>\n<p>Mi ci \u00e8 voluto un po&#8217; di tempo per comprendere che il branching e il merging funzionano in maniera completamente differente in Git rispetto alla maggior parte degli altri sistemi, specialmente per la loro facilit\u00e0 di utilizzo! Quindi, se avete imparato il concetto di branching da un altro version control system (come Subversion), vi consiglio di dimenticarvi questa vostra conoscenza pregressa e di iniziare da zero. Cominciamo innanzitutto dal capire perch\u00e9 i branch sono cos\u00ec importanti.<\/p>\n<h3>Perch\u00e9 i branch sono essenziali<\/h3>\n<p>Quando in passato <em>non<\/em> usavo i branch, lavorare su una nuova feature era un disastro. Praticamente, potevo scegliere tra due workflow, entrambe pessimi:<\/p>\n<p>(a) Sapevo gi\u00e0 che fare dei piccoli commit granulari con solo pochi cambiamenti era una buona abitudine di version control. Tuttavia, se lo facevo mentre stavo sviluppando una nuova feature, ogni commit mischiava la mia feature completa a met\u00e0 con la code base principale fino a che non avevo finito. Per i miei colleghi, non era piacevole trovare dei bug nel progetto introdotti dalla mia feature non ancora completata.<\/p>\n<p>(b) Per evitare di mischiare il mio \u201cwork in progress\u201d con altri argomenti (sia dei miei colleghi sia miei), lavoravo su una feature in un mio spazio separato. Creavo una copia della cartella del progetto con cui avrei potuto lavorare tranquillamente e facevo poi il commit una volta completata la mia feature. Ma fare il commit dei miei cambi solo alla fine produceva un unico commit gigante, riempito di tutti i cambiamenti. N\u00e9 io n\u00e9 i miei colleghi potevamo capire cosa fosse successo esattamente in questo commit quando ci saremmo tornati in un secondo momento.<\/p>\n<p>Pian piano, capii che dovevo familiarizzare con i branch se volevo migliorare le mie capacit\u00e0 di programmatore.<\/p>\n<h3>Lavorare nei contesti<\/h3>\n<p>Ogni progetto ha pi\u00f9 contesti in cui avviene il lavoro: ogni feature, bug fix, esperimento o alternativa del prodotto \u00e8 in effetti un contesto a s\u00e9 stante. Pu\u00f2 essere visto come un suo \u201ctopic\u201d chiaramente separato dagli altri topic.<\/p>\n<p>Se non separate questi topic tra loro con il branching, inevitabilmente, aumenterete il rischio di avere problemi. Mischiare diversi topic nello stesso contesto:<\/p>\n<ul>\n<li>rende difficile mantenere una visione globale e con molti topic, diventa quasi impossibile;<\/li>\n<li>rende difficile annullare qualcosa si \u00e8 scoperto contenere un bug, perch\u00e9 \u00e8 gi\u00e0 mischiata a molte altre cose;<\/li>\n<li>non incoraggia a sperimentare e a provare cose nuove, perch\u00e9 \u00e8 difficile togliere il codice sperimentare dal repository una volta che \u00e8 mischiato con il codice stabile.<\/li>\n<\/ul>\n<p>L&#8217;utilizzo dei branch mi ha dato la sicurezza che non avrei distrutto nulla. Nel caso le cose prendano una brutta piega, potrei sempre tornare indietro, annullare e ricominciare, oppure cambiare il contesto.<\/p>\n<h3>Branching: le basi<\/h3>\n<p>Il branching in Git coinvolge solo qualche comando. Per cominciare, osserviamo il workflow di base.<\/p>\n<p>Per creare un nuovo branch basandosi sullo stato corrente, tutto quello che dovete fare \u00e8 scegliere un nome ed eseguire un unico comando da riga di comando. Supponiamo di voler cominciare a lavorare su una nuova versione della nostra form di contatto e quindi creiamo un branch chiamato \u201ccontact-form\u201d:<\/p>\n<pre><code>$ git branch contact-form<\/code>\n<\/pre>\n<p>Usando il comando <code>git branch<\/code> senza specificare un nome far\u00e0 elencare tutti i branch che abbiamo al momento (e la flag \u201c-v\u201d ci fornisce pochi dati in pi\u00f9 rispetto al solito):<\/p>\n<pre><code>$ git branch -v<\/code>\n<\/pre>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/11\/branch-listing.jpg\" border=\"0\" alt=\"Schermata di Git che mostra i branch attuali di contact-form.\" width=\"90%\" \/><\/div>\n<p>Potreste ora aver notato il piccolo asterisco sul branch di nome \u201cmaster\u201d: esso indica il branch attualmente attivo. Quindi, prima di cominciare a lavorare sulla nostra contact form, dobbiamo rendere quest&#8217;ultimo il contesto attivo:<\/p>\n<pre><code>$ git checkout contact-form<\/code>\n<\/pre>\n<p>Adesso Git ha reso questo branch il contesto di lavoro attuale. (Nel gergo di Git, questo viene chiamato \u201cHEAD branch\u201d). Tutti i cambiamenti e qualunque commit faremo d&#8217;ora in poi influenzer\u00e0 solo quest&#8217;unico contesto, gli altri contesti non verranno toccati. Se vogliamo cambiare il contesto ad un altro branch, dobbiamo semplicemente usare di nuovo il comando <code>git checkout<\/code>.<\/p>\n<p>Nel caso vogliamo integrare i cambiamenti da un branch in un altro, possiamo farne il \u201cmerge\u201d nel contesto di lavoro attuale. Immaginate che abbiamo lavorato sulla nostra feature \u201ccontact-form\u201d per un po&#8217; e adesso vogliamo integrare questi cambiamenti nel nostro branch \u201cmaster\u201d. Tutto quello che dobbiamo fare \u00e8 tornare a questo branch e chiamare git merge:<\/p>\n<pre><code>$ git checkout master\n$ git merge contact-form<\/code>\n<\/pre>\n<h3>Usare i branch<\/h3>\n<p>Vi consiglio caldamente di usare i branch il pi\u00f9 possibile nel vostro workflow quotidiano. I branch sono uno dei concetti chiave su cui \u00e8 costruito Git. Sono estremamente economici e facili da creare, nonch\u00e9 semplici da gestire e ci sono <a href=\"http:\/\/www.git-tower.com\/learn\/ebook\/command-line\/branching-merging\/branching-can-change-your-life\">moltissime risorse<\/a> se siete pronti per imparare di pi\u00f9 sul loro utilizzo.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Annullare azioni<\/h2>\n<p>C&#8217;\u00e8 una cosa che ho imparato come programmatore nel corso degli anni: gli errori si fanno, indipendentemente da quanta esperienza si abbia. Non si possono evitare ma si possono tenere a portata di mano degli strumenti che ci aiutino a recuperare.<\/p>\n<p>Una delle feature migliori di Git \u00e8 che si pu\u00f2 fare l&#8217;undo di quasi tutto. Questo mi ha dato la fiducia necessaria per provare cose senza paura, perch\u00e9 finora non sono riuscito a distruggere <em>davvero<\/em> qualcosa oltre il recovery.<\/p>\n<h3>Correggere l&#8217;ultimo commit<\/h3>\n<p>Anche se fate i vostri commit molto attentamente, \u00e8 fin troppo facile dimenticarsi di aggiungere un cambio o scrivere male un messaggio. Con la flag <code>\u2014amend<\/code> del comando <code>git commit<\/code>, Git ci permette di cambiare l&#8217;<em>ultimissimo<\/em> commit ed \u00e8 una fix molto semplice da eseguire. Per esempio, se vi siete dimenticati di aggiungere una certa modifica e avete anche fatto un errore di battitura nell&#8217;oggetto del commit, potete facilmente correggerli:<\/p>\n<pre><code>$ git add <strong>some\/changed\/files<\/strong>\n$ git commit --amend -m \"The message, this time without typos\"<\/code>\n<\/pre>\n<p>C&#8217;\u00e8 solo una cosa che dovreste tenere a mente: non dovreste mai fare l&#8217;amend di un commit che \u00e8 gi\u00e0 stato inviato a un repository remoto. Rispettando questa regola, l&#8217;opzione &#8220;amend&#8221; \u00e8 un grande piccolo aiutante per sistemare l&#8217;ultimo commit.<\/p>\n<p>(Per ulteriori dettagli sull&#8217;opzione <code>amend<\/code>, vi raccomando l&#8217;<a href=\"http:\/\/gitready.com\/advanced\/2009\/01\/12\/fixing-broken-commit-messages.html\">eccellente guida<\/a> di Nick Quaranto).<\/p>\n<h3>Fare l&#8217;undo dei cambiamenti locali<\/h3>\n<p>I cambiamenti di cui non si \u00e8 ancora fatto il commit sono detti &#8220;locali&#8221;. Tutte le modifiche che sono attualmente presenti nella vostra directory di lavoro sono cambiamenti \u201clocal\u201d non &#8220;committed&#8221;.<\/p>\n<p>Scartare questi cambiamenti pu\u00f2 anche aver senso quando il vostro lavoro attuale \u00e8\u2026 beh\u2026 peggiore di quello che avevate prima. Con Git, potete facilmente fare l&#8217;undo dei cambiamenti locali e cominciare da capo con l&#8217;ultima versione del vostro progetto di cui avete fatto il commit.<\/p>\n<p>Se volete ripristinare un singolo file, potete usare il comando <code>git checkout<\/code>:<\/p>\n<pre><code>$ git checkout -- <strong>file\/to\/restore<\/strong><\/code>\n<\/pre>\n<p>Non confondete questo utilizzo del comando <code>checkout<\/code> con il cambio dei branch (vedi sopra). Se lo usate con due trattini (separati con uno spazio!) e il percorso del file, eliminer\u00e0 i cambiamenti di cui non si \u00e8 fatto il commit in un dato file.<\/p>\n<p>Tuttavia, in una giornata cattiva, potreste addirittura voler eliminare tutti i cambiamenti locali e ripristinare l&#8217;intero progetto:<\/p>\n<pre><code>$ git reset --hard HEAD<\/code>\n<\/pre>\n<p>Questo rimpiazzer\u00e0 tutti i files nella vostra directory di lavoro con l&#8217;ultima revisione di cui avete fatto il commit. Proprio come l&#8217;utilizzo del comando checkout sopra, questo eliminer\u00e0 i cambiamenti locali.<\/p>\n<p>State attenti con queste operazioni: dal momento che non avete fatto il check in un repository dei cambiamenti locali, non c&#8217;\u00e8 modo di riaverli una volta eliminati!<\/p>\n<h3>Fare l&#8217;undo dei cambiamenti di cui si \u00e8 fatto il commit<\/h3>\n<p>Ovviamente, l&#8217;annullamento delle cose non \u00e8 limitato solo ai cambiamenti locali. Potete anche fare l&#8217;undo di alcuni commit quando \u00e8 necessario, per esempio, se avete introdotto un bug.<\/p>\n<p>Praticamente, ci sono due comandi principali per fare l&#8217;undo di un commit:<\/p>\n<h4>(a) git reset<\/h4>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/11\/reset-concept.jpg\" border=\"0\" alt=\"Illustrazione che mostra come funziona il comando `git reset`.\" width=\"100%\" \/><\/div>\n<p>Il comando <code>git reset<\/code> fa davvero tornare indietro nel tempo. Gli dite a che versione volete tornare ed esso ripristina esattamente questo stato, annullando tutti i cambiamenti che sono avvenuti dopo questo punto nel corso del tempo. Semplicemente, dategli lo &#8220;hash ID&#8221; del commit a cui volete tornare:<\/p>\n<pre><code>$ git reset -- hard 2be18d9<\/code>\n<\/pre>\n<p>L&#8217;opzione <code>\u2014hard<\/code> \u00e8 l&#8217;approccio pi\u00f9 semplice e pulito, ma elimina anche tutti i cambiamenti locali che potreste ancora avere nella vostra directory di lavoro. Quindi, prima di fare cos\u00ec, assicuratevi che non ci sia alcun cambiamento locale che desiderate ardentemente.<\/p>\n<h4>(b) git revert<\/h4>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/11\/revert-concept.jpg\" border=\"0\" alt=\"Illustrazione che mostra il funzionamento di `git revert`.\" width=\"100%\" \/><\/div>\n<p>Il comando <code>git revert<\/code> \u00e8 usato in uno scenario differente. Immaginatevi di avere un commit che non volete pi\u00f9, ma i commit che sono venuti dopo sono ancora importanti per voi. In questo caso, non dovrete usare il comando <code>git reset<\/code> perch\u00e9 annullerebbe anche tutti i commit successivi!<\/p>\n<p>Tuttavia, il comando <code>revert<\/code> fa il revert solo degli <em>effetti<\/em> di un certo commit. Non rimuove alcun commit, come invece fa <code>git reset<\/code>. Al contrario, crea addirittura un <em>nuovo<\/em> commit, il quale introduce i cambiamenti che sono solo l&#8217;opposto del commit che deve essere ripristinato. Per esempio, se avete cancellato una certa riga di codice, <code>revert<\/code> creer\u00e0 un nuovo commit che introduce di nuovo proprio questa riga.<\/p>\n<p>Per usarlo, passategli semplicemente lo &#8220;hash ID&#8221; del commit di cui volete fare il ripristino:<\/p>\n<pre><code>$ git revert 2be18d9<\/code>\n<\/pre>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Trovare i bug<\/h2>\n<p>Quando si tratta di scovare i bug, devo ammettere di aver passato molto tempo brancolando nel buio. Spesso <em>sapevo<\/em> che un paio di giorni prima funzionava, ma non avevo idea <em>in che punto esattamente<\/em> le cose fossero andate storte. Fu solo quando scoprii <code>git bisect<\/code> che il processo cominci\u00f2 a velocizzarsi un po&#8217;. Con il comando <code>bisect<\/code>, Git fornisce uno strumento che ci aiuta a trovare il commit che ha introdotto un problema.<\/p>\n<p>Immaginatevi questa situazione: sappiamo che la nostra versione attuale (taggata con \u201c2.0\u201d) ha dei problemi. Sappiamo anche che un paio di commit fa (la nostra versione \u201c1.9\u201d) tutto andava bene. Il problema deve essere successo da qualche parte fra questi due punti.<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/11\/bisect-01.jpg\" border=\"0\" alt=\"Illustrazione che mostra i commit tra le versioni funzionante e non funzionante.\" width=\"100%\" \/><\/div>\n<p>Questa informazione \u00e8 gi\u00e0 sufficiente per cominciare la nostra caccia al bug con <code>git bisect<\/code>:<\/p>\n<pre><code>$ git bisect start\n$ git bisect bad\n$ git bisect good v1.9<\/code>\n<\/pre>\n<p>Dopo aver iniziato il processo, avevamo detto a Git che il nostro commit attuale conteneva il bug e pertanto \u00e8 \u201cbad\u201d. Poi, abbiamo anche detto a Git quale commit precedente funziona effettivamente (come parametro per <code>git bisect good<\/code>).<\/p>\n<p>Quindi, Git ripristina il nostro progetto <em>a met\u00e0<\/em> tra le condizioni note di bad e good:<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/11\/bisect-02.jpg\" border=\"0\" alt=\"Illustrazione che mostra che il bisect inizia tra le versioni.\" width=\"100%\" \/><\/div>\n<p>Adesso, testiamo questa versione (per esempio, facendo degli unit test, creando l&#8217;app, facendone il deploy su un sistema di testing, etc.) per trovare se questo stato funziona, o se contiene gi\u00e0 il bug. Non appena lo scopriamo, lo diciamo di nuovo a Git, o con <code>git bisect bad<\/code> o <code>git bisect good<\/code>.<\/p>\n<p>Supponiamo di aver detto che questo commit era ancora \u201cbad\u201d. Questo significa effettivamente che il bug deve essere stato introdotto ancora prima e Git restringer\u00e0 i commit in questione:<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2014\/11\/bisect-03.jpg\" border=\"0\" alt=\"Illustrazione che mostra il modo in cui dei bisect in pi\u00f9 fanno diminuire ulteriormente i commit.\" width=\"100%\" \/><\/div>\n<p>In questo modo, troverete rapidamente il punto esatto in cui \u00e8 successo il problema. Una volta che lo saprete, dovrete chiamare <code>git bisect reset<\/code> per terminare la caccia al bug e ripristinare lo stato originale del progetto.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Uno strumento per salvarvi la pelle<\/h2>\n<p>Devo confessare che il mio primo incontro con Git non \u00e8 stato amore a prima vista. All&#8217;inizio, sembrava proprio come tutte le altre esperienze con il version control: tedioso e inutile. Ma col tempo, la pratica \u00e8 diventata intuitiva e si \u00e8 guadagnato la mia fiducia.<\/p>\n<p>Dopo tutto, gli errori capitano, non importa quanta esperienza abbiate o quanto duramente cerchiamo di evitarli. Quello che separa i professionisti dai principianti \u00e8 la preparazione: aver configurato un sistema su cui fare affidamento in caso di problemi. Vi aiuta a stare aggiornati sulle cose, specialmente in progetti complessi. E, in ultima analisi, vi aiuta a diventare professionisti migliori.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Riferimenti<\/h2>\n<ul>\n<li>Sentitevi liberi di <a href=\"http:\/\/www.git-tower.com\/learn\/ebook\/command-line\/advanced-topics\/undoing-things\">saperne di pi\u00f9 su amend, revert e reset dei commit<\/a>.<\/li>\n<li>Familiarizzate con \u201cgit bisect\u201d con questo <a href=\"http:\/\/www.metaltoad.com\/blog\/beginners-guide-git-bisect-process-elimination\">esempio dettagliato<\/a>.<\/li>\n<li>Una dettagliata <a href=\"http:\/\/www.git-tower.com\/learn\/ebook\/command-line\/branching-merging\/branching-can-change-your-life\">introduzione al branching<\/a>.<\/li>\n<\/ul>\n<p>Illustrazioni: {carlok}<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Siete lontani giusto un ko del server dal perdere l&#8217;ultima settimana di lavoro che avete fatto? Avete costantemente a che fare con codice pieno di bug e passate ore a scoprire quali errori sono stati introdotti? Tobias G\u00fcnther pensava che questo fosse semplicemente il modo in cui funziona la programmazione, fino a che non ha cominciato ad usare Git per il version control e ha cominciato a vedere degli enormi miglioramenti del workflow. Oggi ci guider\u00e0 nel mondo organizzato, semplice e completamente sano di mente di Git come l&#8217;ha imparato. Il vostro prossimo progetto vi ringrazier\u00e0.<\/p>\n","protected":false},"author":818,"featured_media":7000745,"comment_status":"open","ping_status":"open","template":"","categories":[119,276,278],"tags":[],"coauthors":[432],"class_list":["post-496","article","type-article","status-publish","has-post-thumbnail","hentry","category-numero-102-3-novembre-2014","category-project-management","category-workflow-tools"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article\/496","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/types\/article"}],"author":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/users\/818"}],"replies":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/comments?post=496"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media\/7000745"}],"wp:attachment":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media?parent=496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/categories?post=496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/tags?post=496"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/coauthors?post=496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}