Mercurial workflow

Imparare un flusso di lavoro che permetta la condivisione del codice fra colleghi in modalità idonea alla revisione del codice.

In particolare saranno di grande aiuto le seguenti estensioni/comandi:

  • topics

  • histedit

  • absorb

Gran parte delle cose che presento si basano sulla alcuni concetti:

fasi

mercurial distingue i commit in base alla fase, la vedete anche in tortoisehg. Quando un commit viene creato (localmente) è in fase draft, quando in seguito viene eseguito hg push il file viene considerato pubblico. Esiste la possibilità di create un repository «non pubblico» per cui il changeset non diventi pubblico

histedit

è un comando che permette l’edit dei changeset passati purché siano in stato draft

code-review

è la possibilità di commentare del codice altrui e suggerire miglioramenti. È auspicabile che poi i «balbettamenti» non finiscano nel codice finale.

I topics sono un nuovo modello di branching che viene implementata da heptapod che si basa sulla possibilità di condividere codice in fase draft.

Suggerimenti di letture

  • La introduzione ufficiale all’estensione evolve

  • una semplice introduzione pragmatica ai topics

  • un’introduzione alla funzione absorbe

  • un lungo tutorial, ma molto asciutto, sui topics

  • La FAQ principale di Heptapod

Linee guida

Dal momento che in questo modo è possibile correggee quello che si pubblica, vi consigliamo di pubblicare spesso in modo da dre la possibilità ai colleghi di commentare il codice.

È importante che si tengano presente in modo ferreo alcune regole importanti:

  1. I commit devono essere atomici ovvero devono ciascuno contenere un solo punto (topic, appunto), ma nello stesso tempo deve contenere tutto quello che questo topic richiede.

    Ad esempio, se serve documentazione (sia generica sia nelle docstring delle funzioni) deve essere presente nello stesso commit del codice. Idem, quando vengono fatti per i test / remote test.

  2. Dal momento che un commit può essere solo un modo di condividere il codice, abbiamo deciso di adottare una convenzione che indichi chiaramente già dalla prima riga del commento che tipo di commit è:

    TMP -

    Indica che il commit NON è pronto per la revisione, deve essere terminato ed è stato committato solo per fare capire il lavoro della giornata o per poterlo scaricare da altre postazioni

    HELP -

    Il commit è stato fatto per permettere ad altri di commentarlo e verificare qualcosa che non ci torna

  3. Richiesta di merge: una volta pronti deve essere fatta la richesta di merge, basta seguire il link generato in automatico dal push (che altrimenti ignorate). Aprite il link dal terminale al solito con click destro.

    È importante che compiliate nella pagina che vi compare gli assegnatari (presumibilmente il vostro responsabile e Vitto che dopo la prima fase deciderà se continuare a ricevere…

    È importante -per progetti Django- chiarire nel messaggio di merge almeno 2 cose:

    1. Se il branch include delle migrazioni

    2. Se il branch aggiunge delle dipendenze

Alcuni suggerimenti pratici

Q: Come convertire in topics una stack (non ancora pubblicata)?

Il comando topics ha un’opzione -r che può avere come argomento il range (con ::) che si vuole tramutare in topic.:

hg topic -r sx::sy topic-name

Q: Come fare il merge di un topic se non ci son biforcazioni?

In questa situazione non si riesce a fare merge, verrà fuori il messaggio che non c’è nulla da «mergiare». È suff. rendere pubblic le parti interessate:

hg phase -r sx::sy --publish

o alternativamente se si prevede di pubblicare:

hg push --publish (-t topic_name)

Q: come inviare solo un topic sul repo condiviso?

Esistono 2 possibilità:

hg push -t my_topic

Q: Fallisce hg in

Questo si risolve facendo prima hg pull. A mio avviso succede quando la struttura dati interna è stata fatta da mercurial pre 5 senza topics. Una volta fatto hg pull viene aggiornata e l’errore sparisce.

Q: come eliminare dei file capitati erroneamente in un commit?

Basta eliminarlo usando hg amend:

hg amend --exclude file-or-directory [file-or-directory ...]

Quel file rimarrà nella working directory e quindi andrà gestito (ad esempio creando un commit per lui, o eliminandolo). Supponiamo voi creiate un nuovo commit per questo:

$ mkdir /tmp/test && cd /tmp/test $ hg init $ touch .hgignore $ hg ci -A -m hgignore $ hg topics conta $ touch uno due tre otto $ hg ci -Am «init» $ touch quter cinq $ hg ci -Am «altro giro» $ touch ses sett $ hg ci -Am «ultimo arrivato paga da bere» $ hg up s1 $ hg stack ### topic: conta ### target: default (branch) s3: ultimo arrivato paga da bere s2: altro giro s1@ init (current) s0^ hgignore (base)

$ hg st –ch . A due A otto A tre A uno

$ hg amend –extract otto 2 new orphan changesets $ hg st A otto

La nostra correzione ha lasciato il file otto aggiunto da committare ma ha anche cambiato i due commit successivi che quindi sono ora orfani, indicato dal $ nella stack:

$ hg stack
### topic: conta
### target: default (branch)
s3$ ultimo arrivato paga da bere (orphan)
s2$ altro giro (orphan)
s1@ init (current)
s0^ hgignore (base)

Ci occupiamo anzitutto del file da committare:

hg ci -m "otto"

che ci porta in una situazione biforcata:

$ hg log
@  changeset: [draft] 5 : d9ae185e86b6 default [#conta] tip
|  node:      d9ae185e86b68a5f716b55c868bf3845308806fa
|  author:    Sandro Dentella <adentella@thux.it>
|  date:      Mon, 23 Mar 2020 19:55:46 +0100 (2 seconds ago)
|  summary:   otto
|
o  changeset: [draft] 4 : 572ee3d89198 default [#conta]
|  node:      572ee3d891986a5c3490b18d1d64530a3927e15f
|  author:    Sandro Dentella <adentella@thux.it>
|  date:      Mon, 23 Mar 2020 19:43:38 +0100 (12 minutes ago)
|  summary:   init
|
| *  changeset: [draft] 3 : dacdfc8e209a default [#conta]
| |  node:      dacdfc8e209a75ae660273b2f9ad73aad23ec200
| |  author:    Sandro Dentella <adentella@thux.it>
| |  date:      Mon, 23 Mar 2020 19:43:38 +0100 (12 minutes ago)
| |  summary:   ultimo arrivato paga da bere
| |
| *  changeset: [draft] 2 : 0b82bf9cdc53 default [#conta]
| |  node:      0b82bf9cdc53b8f85b172bcf767159e7ff3af46d
| |  author:    Sandro Dentella <adentella@thux.it>
| |  date:      Mon, 23 Mar 2020 19:43:38 +0100 (12 minutes ago)
| |  summary:   altro giro
| |
| x  changeset: [draft] 1 : 0190f266a5c7 default [#conta]
|/   node:      0190f266a5c7dc00bbc05a97e25b462bd402038c
|    author:    Sandro Dentella <adentella@thux.it>
|    date:      Mon, 23 Mar 2020 19:43:38 +0100 (12 minutes ago)
|    summary:   init
|
o  changeset: [draft] 0 : 4d506ac20847 default
   node:      4d506ac20847a463a15e049734f4b9441e25af7d
   author:    Sandro Dentella <adentella@thux.it>
   date:      Mon, 23 Mar 2020 19:43:37 +0100 (12 minutes ago)
   summary:   hgignore

che sistemeremo in 2 mosse::

$ hg evolve
$ hg log
o  changeset: [draft] 7 : bb9b54592e7b default [#conta] tip
|  node:      bb9b54592e7b412617784e5deb68d72eada4f320
|  author:    Sandro Dentella <adentella@thux.it>
|  date:      Mon, 23 Mar 2020 19:43:38 +0100 (13 minutes ago)
|  summary:   ultimo arrivato paga da bere
|
o  changeset: [draft] 6 : 3d788e78fe92 default [#conta]
|  node:      3d788e78fe92933f177e7bf420f1f382e9ed8721
|  author:    Sandro Dentella <adentella@thux.it>
|  date:      Mon, 23 Mar 2020 19:43:38 +0100 (13 minutes ago)
|  summary:   altro giro
|
| @  changeset: [draft] 5 : d9ae185e86b6 default [#conta]
|/   node:      d9ae185e86b68a5f716b55c868bf3845308806fa
|    author:    Sandro Dentella <adentella@thux.it>
|    date:      Mon, 23 Mar 2020 19:55:46 +0100 (67 seconds ago)
|    summary:   otto
|
o  changeset: [draft] 4 : 572ee3d89198 default [#conta]
|  node:      572ee3d891986a5c3490b18d1d64530a3927e15f
|  author:    Sandro Dentella <adentella@thux.it>
|  date:      Mon, 23 Mar 2020 19:43:38 +0100 (13 minutes ago)
|  summary:   init
|
o  changeset: [draft] 0 : 4d506ac20847 default
   node:      4d506ac20847a463a15e049734f4b9441e25af7d
   author:    Sandro Dentella <adentella@thux.it>
   date:      Mon, 23 Mar 2020 19:43:37 +0100 (13 minutes ago)
   summary:   hgignore

Ora vedete che non esistono più orfani: in questa visualizzazione non ci son più * o x. Esiste però una biforcazione che sistemiamo subito:

$ hg rebase [ -d tip ]
rebasing 5:d9ae185e86b6 "otto" (conta)
sandro@bluffx:/tmp/test$ hg log
@  changeset: [draft] 8 : 9697e04af32a default [#conta] tip
|  node:      9697e04af32a3fe2333ae54e04d4c6a5e39b27e4
|  author:    Sandro Dentella <adentella@thux.it>
|  date:      Mon, 23 Mar 2020 19:55:46 +0100 (7 minutes ago)
|  summary:   otto
|
o  changeset: [draft] 7 : bb9b54592e7b default [#conta]
|  node:      bb9b54592e7b412617784e5deb68d72eada4f320
|  author:    Sandro Dentella <adentella@thux.it>
|  date:      Mon, 23 Mar 2020 19:43:38 +0100 (19 minutes ago)
|  summary:   ultimo arrivato paga da bere
|
o  changeset: [draft] 6 : 3d788e78fe92 default [#conta]
|  node:      3d788e78fe92933f177e7bf420f1f382e9ed8721
|  author:    Sandro Dentella <adentella@thux.it>
|  date:      Mon, 23 Mar 2020 19:43:38 +0100 (19 minutes ago)
|  summary:   altro giro
|
o  changeset: [draft] 4 : 572ee3d89198 default [#conta]
|  node:      572ee3d891986a5c3490b18d1d64530a3927e15f
|  author:    Sandro Dentella <adentella@thux.it>
|  date:      Mon, 23 Mar 2020 19:43:38 +0100 (19 minutes ago)
|  summary:   init
|
o  changeset: [draft] 0 : 4d506ac20847 default
   node:      4d506ac20847a463a15e049734f4b9441e25af7d
   author:    Sandro Dentella <adentella@thux.it>
   date:      Mon, 23 Mar 2020 19:43:37 +0100 (19 minutes ago)
   summary:   hgignore

Tutto è in ordine, otto che si era maldestramente infilato nel changeset iniziale è tornato dopo gli altri (e paga da bere). Abbiamo ordinato i commit con un rebase invece che un hg histedit, ma avremmmo anche potuto fare diversamente.