Al momento ho un singolo repository Git preesistente per una soluzione client / server che contiene tre sottodirectory per 3 sottoprogetti:
/client - An Angular2 SPA application (client-side TypeScript)
/dtos - Language-agnostic web-service DTO (data contract) definitions written in T4
/client - T4-generated TypeScript typings *.d.ts files
/server - T4-generated C# DTO classes
/server - The web-service
Finora questo è tutto in un singolo ramo master
, con appropriati rami temporanei dev/
che vengono uniti quando il loro lavoro è completato:
o--o--o--o - master
\ /
o-o - dev/foo
Abbiamo bisogno di fare alcuni test A / B (o meglio, A / B / C / D) su opzioni UX radicalmente differenti nel progetto Angular2 - Vorrei separarmi per ogni opzione UX, per generare build differenti possiamo testare, quindi dopo aver eseguito la nostra ricerca UX, uniamo quel ramo specifico in master
per il resto del progetto:
o - master
\
o--o--o---o - ux/red-background
\
o--o----o - ux/new-sidebar
\
o--o - ux/new-sidebar-and-banner
Tuttavia, voglio solo escludere la directory /Client
, quindi le directory /DTOs
e /Server
contengono sempre il codice più recente.
In SVN e TFS questo è facilmente fattibile perché i rami possono essere creati da sottodirectory, non solo dall'intero repository (come con git), quindi se questo fosse un progetto SVN, farei qualcosa del genere:
cd trunk # this is the solution root with the client, dtos and server directories
svn copy ^/trunk/client ^/branches/red-background
svn copy ^/branches/red-background ^/branches/new-sidebar
# then after some commits to 'new-sidebar'...
svn copy ^/branches/new-sidebar ^/branches/new-sidebar-and-banner
Quindi, per creare la soluzione con ciascun ramo differente di /client
, modifichiamo il link simbolico:
cd trunk
# to 'checkout' the red-background version prior to building:
ln -s branches/red-background client
# or the new-sidebar version:
ln -s branches/new-sidebar client
Il vantaggio principale di questo approccio è che è possibile continuare a eseguire commit sulle directory /dtos
e /server
senza influire su client
, indipendentemente da quale ramo di client
viene elaborato.
Mentre con git, un ramo è una timeline separata interamente, quindi questo scenario diventa impossibile.
Capisco che per ottenere il risultato che desidero, avrei comunque bisogno di creare diversi rami per ogni versione da testare o compilare, ma le modifiche a /dtos
o /server
dovrebbero comunque avvenire in master
(solo come in trunk
in SVN) ma dopo ogni commit tutti quelli che lavorano sui diversi rami client
dovrebbero rebase
o merge
da master
, e questo ha il potenziale per diventare davvero brutto (specialmente se le persone individuali rebase
da più commit a /server
scegliendo i propri punti di rebase - potrebbero finire con codebase identici ma diversi hash di commit).
Qual è la soluzione?
(Un'altra soluzione è spostare client
nel proprio repository git, quindi unirli di nuovo nel repository della soluzione quando è tutto fatto - non sono contrario a questo, ma facciamo finta che abbiamo raggiunto il nostro numero massimo di repo nel nostro account GitHub aziendale)