Uso Git da un paio di mesi su un progetto con un altro sviluppatore. Ho diversi anni di esperienza con SVN , quindi credo di portare molti bagagli nella relazione.
Ho sentito che Git è eccellente per ramificarsi e fondersi, e finora non lo vedo. Certo, la ramificazione è morta in modo semplice, ma quando provo a fondermi, tutto va all'inferno. Ora, sono abituato a questo da SVN, ma mi sembra di aver appena scambiato un sistema di versioning inferiore a un altro.
La mia compagna mi dice che i miei problemi derivano dal mio desiderio di unirmi volenti o nolenti e che dovrei usare rebase invece di unirmi in molte situazioni. Ad esempio, ecco il flusso di lavoro che ha definito:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature
git checkout master
git merge my_new_feature
In sostanza, creare un ramo di funzionalità, SEMPRE reimpostare dal master al ramo e unire nuovamente dal ramo al master. È importante notare che il ramo rimane sempre locale.
Ecco il flusso di lavoro con cui ho iniziato
clone remote repository
create my_new_feature branch on remote repository
git checkout -b --track my_new_feature origin/my_new_feature
..work, commit, push to origin/my_new_feature
git merge master (to get some changes that my partner added)
..work, commit, push to origin/my_new_feature
git merge master
..finish my_new_feature, push to origin/my_new_feature
git checkout master
git merge my_new_feature
delete remote branch
delete local branch
Ci sono due differenze essenziali (credo): uso sempre la fusione anziché la ridisposizione e spingo il ramo della mia funzione (e il mio ramo della funzione si impegna) nel repository remoto.
Il mio ragionamento per il ramo remoto è che voglio che il mio lavoro sia sottoposto a backup mentre sto lavorando. Il nostro repository viene automaticamente sottoposto a backup e può essere ripristinato se qualcosa va storto. Il mio laptop non lo è o non è così completo. Pertanto, odio avere un codice sul mio laptop che non si rispecchi da qualche altra parte.
Il mio ragionamento per l'unione invece di rebase è che l'unione sembra essere standard e rebase sembra essere una funzionalità avanzata. La mia sensazione è che ciò che sto cercando di fare non sia una configurazione avanzata, quindi rebase non dovrebbe essere necessario. Ho anche sfogliato il nuovo libro di Programmazione pragmatica su Git, e coprono l'unione ampiamente e menzionano a malapena rebase.
Ad ogni modo, stavo seguendo il mio flusso di lavoro su un ramo recente e quando ho provato a fonderlo con il master, tutto è andato all'inferno. Ci sono stati molti conflitti con cose che non avrebbero dovuto avere importanza. I conflitti non avevano senso per me. Mi ci è voluto un giorno per sistemare tutto, e alla fine è culminato in una spinta forzata al master remoto, dal momento che il mio master locale ha risolto tutti i conflitti, ma quello remoto non era ancora felice.
Qual è il flusso di lavoro "corretto" per qualcosa del genere? Si suppone che Git renda le ramificazioni e le fusioni super facili, e non le vedo proprio.
Aggiornamento 15-04-2011
Questa sembra essere una domanda molto popolare, quindi ho pensato di aggiornare con la mia esperienza di due anni dalla prima volta che l'ho chiesto.
Si scopre che il flusso di lavoro originale è corretto, almeno nel nostro caso. In altre parole, questo è ciò che facciamo e funziona:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge my_new_feature
In effetti, il nostro flusso di lavoro è leggermente diverso, poiché tendiamo a fare fusioni di squash invece di fusioni grezze. ( Nota: questo è controverso, vedi sotto. ) Questo ci consente di trasformare l'intero ramo delle caratteristiche in un unico commit sul master. Quindi eliminiamo il nostro ramo di funzionalità. Questo ci consente di strutturare logicamente i nostri commit sul master, anche se sono un po 'disordinati sui nostri rami. Quindi, questo è quello che facciamo:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge --squash my_new_feature
git commit -m "added my_new_feature"
git branch -D my_new_feature
Controversia di fusione delle squash - Come sottolineato da numerosi commentatori, la fusione delle squash getterà via tutta la cronologia del ramo delle funzionalità. Come suggerisce il nome, riduce tutti i commit in uno solo. Per le piccole funzionalità, questo ha senso in quanto lo condensa in un unico pacchetto. Per funzionalità più grandi, probabilmente non è una grande idea, soprattutto se i tuoi singoli commit sono già atomici. Dipende davvero dalle preferenze personali.
Github e Bitbucket (altri?) Richieste pull - Nel caso in cui ti stia chiedendo in che modo l'unione / rebase si collega alle richieste pull, ti consiglio di seguire tutti i passaggi precedenti fino a quando non sei pronto per ricollegarti al master. Invece di unirti manualmente a git, accetti semplicemente il PR. Nota che questo non farà una fusione di squash (almeno non di default), ma non-squash, non-fast-forward è la convenzione di unione accettata nella community di Pull Request (per quanto ne so). In particolare, funziona così:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git push # May need to force push
...submit PR, wait for a review, make any changes requested for the PR
git rebase master
git push # Will probably need to force push (-f), due to previous rebases from master
...accept the PR, most likely also deleting the feature branch in the process
git checkout master
git branch -d my_new_feature
git remote prune origin
Ho imparato ad amare Git e non voglio tornare a SVN. Se stai lottando, resta su di esso e alla fine vedrai la luce alla fine del tunnel.
rebase
comprensione