Questa pagina raccoglie una serie di consigli utili per evitare gli errori comunemente commessi dai laureandi durante la fase di sviluppo dei progetti di tesi.

Le linee guida fornite fanno riferimento a Git come sistema di versionamento del codice (Distributed Version Control System — DVCS) e GitHub come ambiente per la gestione dei progetti.

Inoltre, esse assumono che abbiate già scaricato e installato Git sul vostro sistema. Infine, qualora non aveste alcuna familiarità con l’uso di Git da riga di comando, vi consiglio di leggere le seguente risorsa prima di proseguire.

1. Modello di sviluppo collaborativo

Per sviluppare i progetti, al Collab seguiamo il modello di sviluppo collaborativo denominato Fork & pull. GitHub descrive il modello Fork & pull così:

The fork & pull model lets anyone fork an existing repository and push changes to their personal fork without requiring access be granted to the source repository. The changes must then be pulled into the source repository by the project maintainer. This model […] allows people to work independently without upfront coordination.

Questo modello si oppone all’altro esistente detto shared repository, per il quale tutti i partecipanti al progetto hanno i permessi di modificare il codice dell’unico repository di progetto condiviso tra tutti.

Pertanto, la Figura 1 mostra il worflow adottato per i progetti Collab derivante dalla scelta del modello Fork & Pull. Secondo questo workflow, per ogni progetto esisterà un repository sorgente, appartenente all’organizazione collab-uniba su GitHub, gestito da un collaboratore del Collab (l’integration manager). Ciascuno degli studenti che che vorranno collaborare al medesimo progetto, effettuerà un cosiddetto fork del progetto nel proprio spazio di progetti su GitHub. Questo fork sarà poi “clonato” da ciascuno degli studenti in un repository privato sulla propria macchina.

Ciascuno studente avrà  pieni poteri di modifica solo sul repository clone e il relativo repository pubblic su GitHub (detto origin); invece, non avrà alcun permesso di modifica su quello sorgente appartenente collab-uniba. Per contribuire con una modifica, i cambiamenti dovranno essere inviati all’integration manager il quale, una volta verificati, provvederà a integrarli nel repo sorgente (per maggiordi dettagli sull’integrazione, si veda la sezione 4. Restituire modifiche al progetto sorgente del Collab).

Figura 1. Il workflow distributo adottato per tutti i progetti Collab
Figura 1. Il workflow distributo adottato per tutti i progetti Collab

2. Setup

Come primo passo, occorre registrarsi su GitHub e comunicare il proprio nome utente. Sarete quindi aggiunti al team di sviluppo.

L’elenco dei progetti sviluppati dal gruppo Collab è disponibile qui: https://github.com/collab-uniba. Potete consultarlo per scegliere a quale progetto contribuire.

Dopo averlo selezionato, collegatevi alla pagina del progetto su GitHub ed effettuate un fork nel vostro spazio di progetti personali. Per effettuare il fork, occorre premere il tasto in Figura 2. Nell’esempio in figura, l’utente bateman sta effettuando il fork personale del progetto demosistemicollab, appartentente all’organizzazione collab-uniba. L’utente bateman avrà così permessi completi per modificare qualsiasi elemento del fork, mentre su progetto sorgente avrà accesso esclusivamente in lettura.

Figura 2. Effettuare un fork

Dopodiché, bisognerà collegare il fork con una cartella locale della propria macchina di sviluppo, ossia creare il repository clone. Tipicamente, esiste una cartella git nel propria home folder (e.g., c:\Users\bateman\git). Ogni progetto sarà quindi una sottocartella di questa.

Per effettuare il collegamento, aprire la pagina di progetto e copiare l’url come da Figura 3.

Figure 2. Selezionare url per il clone
Figura 3. Copiare url del fork per creare il clone locale

Quindi eseguite:

$ git clone https://github.com/collab-uniba/demosistemicollab.git

Questa operazione creerà la cartella di progetto c:\Users\bateman\git\demosistemicollab

3. Sviluppo

Per avviare l’attività di sviluppo, dalla home page del progetto sorgente, scegliete uno degli issue (i.e., attività) assegnati a voi dall’integration manager. Come da Figura 4, immaginiamo che vi sia stato assegnato l’Issue X.

Figure 3. Selezionare uno degli issue assegnati
Figura 4. Selezionare uno degli issue assegnati

3.1. Struttura del progetto

Qualora il progetto sia iniziato da voi (cioè, non ereditate nessun codice preesistente), sarà vostro compito creare una struttura di progetto adeguata. Essa dovrà ricalcare, con i dovuti accorgimenti a seconda del tipo di progetto e di linguaggio di sviluppo, la struttura riportata di seguito:

/src – source files
/src/tests – unit tests
/lib – required libraries
/doc – text documentation and development notes
/build – where we build (each separate build item within a subfolder here)
/conf – configurations (each config, production, test, developer, etc gets a folder in here, and when building Jars and Wars the correct set is copied across)
/extras – other stuff
/res – resources that should be included within generated Jars, e.g., icons

3.2. Branching

Prima di iniziare a sviluppare il codice, occorre creare un branch (i.e., ramo) di sviluppo, il cui scopo unico è quello di contenere solo ed esclusivamente le modifiche necessarie per completerare l’attività descritta dall’Issue X e nient’altro. Per convenzione, questi sono chiamati topic (o feature) branch e hanno lo stesso nome dell’issue relativa (senza spazi). Il loro ciclo di vita è pari a quello di esistenza dell’issue. Quando questo sarà chiuso/risolto, il topic branch relativo sarà tipicamente cancellato.

$ git branch issuex
$ git checkout issuex

Mentre proseguite lo sviluppo, ricordate di aggiungere le nuove risorse (e.g., file o immagini) da voi create allo spazio di progetto. Potete aggiungere singolarmente, per cartella, o tutti insieme i file nella cartella di progetto che non sono ancora versionati, rispettivamente, come indicato di seguito.

$ git add nomefile
$ git add nomecartella
$ gitt add -A

Attenzione! Se ci sono file che non hanno bisogno di essere versionati (e.g., dei file temporanei, risultato di ogni compilazione), questi vanno aggiunti al file .gitignore. Si possono aggiungere nomi di file o cartelle, o anche tipi di file:

Thumbs.db
bin/*
*.cab

3.3. Commit delle modifiche

A ogni incremento significativoatomico della base di codice locale deve corrispondere un’operazione di commit che salva nel repository locale le modifiche apportate.

Per incremento significativo e atomico si intende, per esempio, le modifiche per risolvere un issue oppure l’aggiunta di una funzionalità. Un commit non deve mai unire il contributi diversi insieme (e.g., due fix in un solo commit). Contributi diversi vanno aggiunti al repository tramite commit separate.

Inoltre, ogni commit deve obbligatoriamente essere accompagnato da una descrizione delle modifiche in esso contenute. Tale descrizione è tipicamente breve, pari a una riga di testo. Se non foste in grado di riassumere le modifiche brevemente, allora questo sarebbe indice di eccessiva grandezza del commit. Siete invitati, pertanto, a mantenere i commit piccoli ed autoconsistenti.

Il commit può essere fatto indicando il nome della risorsa da committare oppure usare lo switch -a per aggiungere tutti i file non ancora committati.

$ git commit nuovofile -m "Fixed missing try/catch in... "
$ git commit -a -m "Added resources for..."

Per sapere quali file non sono stati ancora committati (pendenti), eseguire:

git status

3.3.1. Riscrivere la commit history

In alcuni casi, può esservi utile modificare la storia locale dei commit prima di salvare le modifiche sull’origin o inviare una pull request (si veda sezione 4. Restituire modifiche al progetto sorgente del Collab per maggiori dettagli sulle pull request).

Per esempio immaginate di aver aggiunto al repository due file pippo.py e pluto.py. Dopodiché, committate per errore solo il primo dei due. La commit è incompleta.

$ git add pippo.py pluto.py
$ git commit pippo.py -m "Added new files pippo.py and pluto.py for new feature..."

Per correggerla, potete usare il comando --amend, che corregge l’ultima commit eseguita.

$ git add pluto.py
$ git commit --amend --no-edit

L’opzione --no-edit dice di usare lo stesso commento del commit precedente, senza modifiche. Se volete inserire un nuovo commento, sostituitelo con -m "new message".

Se invece, aveste già scritto (push) i commit sull’origin, allora potete cancellare gli ultimi N push con il comando revert:

$ git revert --hard HEAD~N

Infine, abbiamo a disposizione il comando rebase per modificare un commit che è molto più indietro nella storia, per cui l’opzione --amend diventa inutile. Un rebase permette di effettuare una “pulitura locale” della commit history, trasformando una serie di commit in un solo commit (operazione detta di squashing [7]).

Consideriamo la storia dei commit locali:

$ git log --oneline
7db68c8 line 4
ffbb22a line 3
e0086aa lines 1 2
b61eedf added header file for main
b3ade8a Update README.md
d39a530 Merge pull request #3 from bateman/issuex
9565a20 Updated description in ENG
8b6b8a2 Added cunit std prologue
a55ca0e Added script for auto download
bb5b361 Merge pull request #1 from bateman/master
3816f4d Update README.md
182549a fixed issue 34
97c7e08 Create README.md
fc9905a Initial commit

Supponiamo di voler fondere gli ultimi 3 commit in un unico solo commit. Eseguirò:

$ git rebase -i HEAD~3

Il comando aprirà una finestra dell’editor vim, con un contenuto simile a questo.

pick e0086aa lines 1 2
pick ffbb22a line 3
pick 7db68c8 line 4
#
# Commands:
...

Per fondere i commit, iniziate a scrivere (digitate i) e scegliete (comando pick) il primo commit, mentre usate il comando squash per i successivi due commit che saranno così fusi con i primo. Terminate la sessione di editing (premete esc e poi digitate :w) e vi sarà proposta un’altra schermata che fonderà i tre commenti dei tre commit insieme. Editate il file fino ad evere un unico commento per il commit globale. Terminate la sessione di editing e Git effettuerà lo squashing. Per controllare il risultato, eseguite:

$ git log --oneline
1aca7eb lines 1 2 3 4
b61eedf added header file for main
b3ade8a Update README.md
d39a530 Merge pull request #3 from bateman/issuex
9565a20 Updated description in ENG
8b6b8a2 Added cunit std prologue
a55ca0e Added script for auto download
bb5b361 Merge pull request #1 from bateman/master
3816f4d Update README.md
182549a fixed issue 34
97c7e08 Create README.md
fc9905a Initial commit

In seguito allo squashing, il rebase ha “schiacciato” i tre commit in un unico commit: 1aca7eb lines 1 2 3 4.

3.4. Quando un issue è da considerarsi completato?

Partiamo sempre dall’assunto: “Una tesi non testata è una tesi non funzionante…”
… e, quindi, incompleta! Pertanto, perché possiate laurearvi, è necessario consegnare, insieme con il codice eventualmente sviluppato, almeno i test di unità realizzati con framework xUnit e relative estensioni.

In conclusione, un issue è da considerarsi completato quando:

  1. Il codice che aggiunge la funzionalità/risolve un difetto è stato implementato completamente.
  2. Il funzionamento del nuovo prodotto è dimostrabile attraverso l’esecuzione e superamento di uno o più casi test di unità (unit testing), scritti per il framework di tipo xUnit usato dal progetto (variano a seconda del linguaggio utilizzato). I nuovi casi di test vanno aggiunti ed eseguiti con i preesistenti.
  3. Tutto il codice sviluppato (nomi file, variabili, funzioni etc.) è stato rigorosamente in Inglese, inclusi i commenti.
  4. Il codice rispetta le condizioni stilistiche definite specificatamente dal progetto. Se non ve ne sono, allora si assume che siano state rispettate quelle tipiche del linguaggio (cfr, Code conventions in JavaStyle Guide for Python Code).

A questo punto, è consigliabile aggiungere il branch issuex, ora presente solo sul repository locale, al repository nel proprio spazio di progetto su GitHub:

$ git push origin issuex

In seguito a un rebase, potrebbe essere necessario “forzare” l’aggiornamento dell’origin che apparirà piu’ aggiornato della storia del repo locale.

$ git push --force origin issuex

3.5. Come aggiornare il clone

Di tanto in tanto, sarà necessario aggiornare il clone sulla vostra macchina con il contenuto del progetto sorgente. Questo, infatti, capiterà quando altre persone stanno collaborando con voi al medesimo progetto. Non aggiornare regolarmente il fork comporterà un sostaziale aumento delle probabilità di fallimento nella creazione di una pull request (si veda sezione successiva), a causa dell’impossibilità di fondere le vostre modifiche con quelle non ancora scaricate dal repo sorgente. Aggiornare regolarmente, permette di scoprire subito nuovi aggiornamenti, di dimensione più piccola, riducendo la possibilità di conflitti e, al contempo, aumentando la semplicità di risoluzione.

Il vostro clone sulla macchina di sviluppo si riferisce al vostro repo su Github con l’etichetta origin. Da riga di comando, eseguite:

$ git remote -v

Il comando restituirà informazioni del tipo:

origin  https://github.com/YOUR_NICK/YOUR_PROJ_NAME.git (fetch)
origin  https://github.com/YOUR_NICK/YOUR_PROJ_NAME.git (push)

Per poter aggiornare il clone con il contenuto del sorgente, dobbiamo aggiungere quest’ultimo alla lista dei repository remoti (appunto remotes) noti. Per fare questo, eseguite:

$ git remote add remote-label https-remote-url.git

Così facendo, associerete l’etichetta remote-label all’indirizzo del repository remoto. Perciò, nel nostro caso, il comando per associare l’etichetta collab-origin al vero url del progetto d’esempio diventa:

$ git remote add collab-origin https://github.com/collab-uniba/demosistemicollab.git

Rieseguendo il comando per la visualizzazione dei remote, adesso compariranno due remote:

$ git remote -v
collab-origin  https://github.com/collab-uniba/demosistemicollab.git (fetch)
collab-origin  https://github.com/collab-uniba/demosistemicollab.git (push)
origin  https://github.com/YOUR_NICK/YOUR_PROJ_NAME.git (fetch)
origin  https://github.com/YOUR_NICK/YOUR_PROJ_NAME.git (push)

Per aggiornare direttamente, posizionatevi sul branch destinazione (locale) e scaricate gli aggiornamenti (pull) dal branch del sorgente più aggiornato (tipicamente master o develop). Nell’esempio seguente, lavoriamo con master.

$ git fetch collab-origin master
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/collab-uniba/demosistemicollab
* branch            master     -> FETCH_HEAD

Git has così recuperato i commit e salvati in indice locale temporaneo. I commit sono qui, ma non fanno parte di nessun branch. Per accedere ai commit e alle loro modifiche, useremo il riferimento (o refspec) temporaneo FETCH_HEAD, creato apposta da Git dopo la fetch.

Per rivedere le modifiche in locale, per prima cosa vediamo il diff tra il branch corrente master e i nuovi cambiamenti. Il risultato assomiglierà a:

$ git diff master FETCH_HEAD
index 08cdfb4..cc11a2f 100644
--- a/README.md
+++ b/README.md
@@ -6,4 +6,3 @@ About
This is a test repository, for testing.
-TEST in sub
diff --git a/TEST b/TEST
index 3fb25cd..bc440ae 100644
--- a/TEST
+++ b/TEST
@@ -1 +1,2 @@
BLA
+FOO

Di solito, è il caso di fare delle prove e testare le modifiche prima di effettuare il merge. Per scaricare le modifiche, si effettua il checkout del riferimento FETCH_HEAD creato per noi da Git (ricordate che questo riferimento è temporaneo e un’altra fetch lo modificherà).

$ git checkout FETCH_HEAD
Note: checking out 'FETCH_HEAD'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at ad38a9b... Updated README

Per elencare i commit e i commenti, eseguite:

$ git log
commit ad38a9b402eac93995902560292697245418a192
Author: Ferry Boender <email@it>
Date: Mon Mar 31 19:37:26 2014 +0200
Updated README
commit c538608863dd9dda276edf5adcad9e0f2ef9f9ed
Author: Ferry Boender <email@it>
Date: Mon Mar 31 19:37:11 2014 +0200
Ammended TEST file
commit f8d3d31ea1195e2cb1c0631d95c2b33c313b60b8
Author: Ferry Boender <email@it>
Date: Mon Mar 31 17:36:23 2014 +0000
Created new branch bugfix

Ora, è tempo di fondere le modifiche analizzate con un branch locale, supponiamo il master.

$ git checkout master
$ git merge FETCH_HEAD
Updating 2f6ecbf..ad38a9b
Fast-forward
README.md | 1 -
TEST | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
$ git push
Counting objects: 13, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (8/8), 873 bytes | 0 bytes/s, done.
Total 8 (delta 2), reused 1 (delta 1)
To git@https://github.com/collab-uniba/demosistemicollab
2f6ecbf..ad38a9b master -> master

Questo scenario, rappresenta un caso in cui il merge automatico è possibile. Nel caso in cui il merge automatico fallisce, eventuali conflitti andranno risolti in locale sul clone, dopodichè dovranno essere committati in locale e scritti (pushed) sul vostro fork origin.

4. Restituire modifiche al progetto sorgente del Collab

Una volta verificato che il contributo per l’Issue X è davvero completo, è tempo di restituire le modifiche dal vostro fork al progetto sorgente del Collab. Nel gergo, si dice che occorre inviare una pull request (PR). Una PR in questo caso è necessaria perché non avete permessi di scrittura (i.e., push) sul repository sorgente del Collab. Pertanto, una PR invia una richiesta al maintainer del progetto, il quale decide se accettare ed incorporare (i.e., fare un merge) il vostro contributo con il codice esistente.

Per effettuare una PR, collegatevi alla pagina del fork su GitHub, selezionate il tab sulla destra denominato Pull Request e premete il tasto verde “New pull request”, come in Figura 5. Nell’esempio, l’utente bateman sta iniziando una pull request dal suo fork bateman/demosistemicollab verso il repository sorgente collab-uniba/demosistemicollab.

Figure 4. Start a new pull request
Figura 5. Avviare una nuova pull request

Per creare una PR è necessario confrontare il contenuto dei due repository. Come in Figura 6, assicuratevi di scegliere come base del confronto il repository sorgente (a sx) e il vostro fork per il repository sulla dx. Occorrerà selezionare anche i branch opportuni. Come vostro branch selezionate quello creato specificatamente per l’issue al quale avete contribuito, ossia il branch issuex. Per quanto riguarda il repository di collab-uniba, selezionate tipicamente il branch develop; solo qualora questo non esista, usate invece il branch master. Questi due sono i rami di sviluppo principali (anche detti long-running), poiché il loro ciclo di vita è il medesimo del progetto stesso.

Figura 5. Creazione della PR
Figura 6. Creazione della PR

Una volta selezionati repository e branch, la schermata sottostante mostrerà le commit (e i commenti) racchiusi in questa PR, nonchè le modifiche ai file in formato diff. Quindi, per continuare nella procedura di creazione della PR, premere il tasto verdeCreate pull request“.

Come ultimo passo, occorre documentare una PR (Figura 7). Normalmente, una PR contiene almeno queste informazioni (in inglese) [2, 3, 4]:

  • Titolo: sceglietelo conciso ed esplicativo.
  • Descrizione: qui è dove inserirete i dettagli (così sarà inutile inviare un’email al docente che spieghi cosa è stato fatto e come…), ossia
    • il riferimento all’Issue X, con link;
    • lo scopo della PR;
    • come testare le modifiche;
    • qualsiasi nota o avvertimento;
    • link a risorse rilevanti (non assumete che chi vi leggerà abbia la stessa familiarità con le tecnologie/risorse usate);
    • se necessario, inserire anche immagini;
    • per menzionare qualcuno su GitHub, usa una menzione in formato @username.
Figura 6. Descrivere una PR
Figura 7. Descrivere una PR

Attenzione! Qualora il testo in verde sulla destra in Figura 7 “Able to merge. These branches can be automatically merged.” fosse in realtà rosso, significherebbe che il vostro contributo non può essere accettato così com’è in quanto esistono conflitti dovute a modifiche concorrenti su uno o più file. A questo punto, abortite la compilazione della PR, tornate sulla console e aggiornate il codice scaricando gli aggiornamenti dal repository sorgente di collab-uniba. Per fare questo, consultate la sezione 3.5. Come aggiornare il clone.

4.1 Code review

Nella sua forma più semplice, una PR è un meccanismo usato da uno sviluppatore per notificare agli altri componenti del team di aver completato un task. Una volta che il proprio topic/feature branch è pronto, lo sviluppatore deposita una PR. Questo consente a tutti coloro che sono coinvolti nello sviluppo di rivedere il codice prima di accettarlo e fonderlo con il branch di destinazione.

Tuttavia, una PR è molto più di una semplice notifica. Essa rappresenta anche la creazione di un forum dedicato alla discussione alla revisione del contributo inviato. Se ci sono dei problemi con i cambiamenti, l’integration manager e gli altri componenti del team possono fornire feedback nel forum o richiedere dei commit di follow-up. Tutte questa attività sono monitorato direttamente all’interno della PR (Figura 8).

Figura 8. PR e attività successive [5]
Figura 8. Attività monitorate in una pull request [5]
4.1.1. La prospettiva del maintainer: testare le modifiche

Queste istruzioni sono rivolte all’integration manager. Come studenti, tipicamente potete saltare questa sottosezione per intero.

Prima di accettare/rifiutare una PR, l’integration manager del progetto sorgente del Collab dovrà testare le modifiche in locale sulla propria macchina di sviluppo [6]. Per fare ciò, se siete uno dei maintainer del progetto Collab, eseguite:

git checkout -b CONTRIBUTORNICK-ISSUEBRANCH STARTPOINT
git pull git://URL-di-progetto-fork.git ISSUEBRANCH

Per convenzione, creaiamo un nuovo branch con il nome del contributor (bateman, in questo caso)-il nome del branch (issuex, in questo caso), ossia bateman-issuex.

Per quanto concerne il parametro STARTPOINT, questo per i progetti Collab sarà o develop oppure master. Lo start point è il punto di partenza da usare per creare il nuovo branch. Se è omesso, si assume come punto di partenza sempre l’HEAD del repository (i.e., HEAD è l’alias che rappresenta il branch corrente di lavoro). Come prova del nove che non si stanno commettendo errori, lo start point e il branch di destinazione nel repo sorgente Collab indicato nella PR dovranno essere per forza di cose coincidenti. Nel nostro caso specifico, le istruzioni diventano:

git checkout -b bateman-issuex master
git pull git://github.com/bateman/demosistemicollab.git issuex

Ora le modifiche sono verificabili in locale. Il branch bateman-issuex può essere cancellato subito dopo.

git branch -D bateman-issuex

4.1.2. La prospettiva del maintainer: cherry-picking

A volte ci si trova nella situazione di dover fondere solo dei commit specifici di un feature branch in un altro. Per esempio, consideriamo questo repository:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
           \
            76cada - 62ecb3 - b886a0 [feature]

Supponiamo che il contenuto del commit 62ecb3 del branch feature contenga un bug fix o codice da incorporare subito nel branch master. Tuttavia, si vuole solo incorporare solo il commit 62ecb3 ma non il resto presente nel branch feature. Per far ciò, basta spostarsi sul master branch ed eseguire:

$ git checkout master
$ git cherry-pick 62ecb3

Le modifiche nel commit 62ecb3 saranno applicate e committate (come un nuovo commit) nel master. Il comando cherry-pick si comporta come il merge: se non riesce ad applicare le modifiche,  lascia a voi il compito di risolvere manualmente i conflitti.

4.1.3. Aggiungere commit alla PR già inviata

In alcuni casi, non sarà possibile accettare la PR inviata così com’è. Vi sarà richiesto, invece, di effettuare alcune modifiche. Le ulteriori modifiche, eseguite da voi in locale, dovranno quindi essere aggiunte come ulteriori commit alla PR già inviata.

Per fare questo sarà sufficiente committare ed effettuare il push delle modifiche sullo stesso branch issuex usato per creare inizialmente la PR: così facendo, la pull request sarà automaticamente aggiornata con i commit aggiuntivi [6].

4.1.4. Pull Request accettata

Una volta che la PR è accettata, siete pronti a incorporare i cambi anche nel clone e nel suo origin. Assumendo di aver inviato la PR dal branch issuex del fork al branch master del repository sorgente, da console posizionatevi sul branch master del clone, ed eseguite il merge con il branch issuex; dopodiché rimuovetelo sia in locale sia in remoto.

$ git checkout master
$ git merge issuex
$ git push origin master

$ git branch -d issuex
$ git push origin :issuex

Riferimenti

  1. Using Pull Requests, https://help.github.com/articles/using-pull-requests
  2. How to write the perfect pull request, https://github.com/blog/1943-how-to-write-the-perfect-pull-request
  3. Effective pull requests and other good practices for teams using github, http://codeinthehole.com/writing/pull-requests-and-other-good-practices-for-teams-using-github
  4. Pull Requests Volume 1: Writing a Great Pull Request, http://nearthespeedoflight.com/article/2013_07_10_pull_requests_volume_1__writing_a_great_pull_request
  5. Making a Pull Request, https://www.atlassian.com/git/tutorials/making-a-pull-request
  6. Test a pull / merge request before accepting on Bitbucket, http://www.electricmonk.nl/log/2014/03/31/test-a-pull-merge-request-before-accepting-on-bitbucket
  7. 7.6 Git Tools – Rewriting History, http://git-scm.com/book/en/v2/Git-Tools-Rewriting-History