Estou usando o Git agora há alguns meses em um projeto com outro desenvolvedor. Eu tenho vários anos de experiência com SVN , então acho que trago muita bagagem para o relacionamento.
Ouvi dizer que o Git é excelente para ramificação e fusão e, até agora, simplesmente não o vejo. Claro, a ramificação é simples, mas quando tento me fundir, tudo vai para o inferno. Agora, estou acostumado com isso no SVN, mas parece-me que eu apenas troquei um sistema de versões subpars por outro.
Meu parceiro me diz que meus problemas decorrem do meu desejo de mesclar-se à vontade e que eu deveria estar usando rebase em vez de mesclar em muitas situações. Por exemplo, aqui está o fluxo de trabalho que ele estabeleceu:
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
Essencialmente, crie uma ramificação de recurso, SEMPRE rebase do mestre para o ramo e mescle do ramo de volta para o mestre. Importante notar é que a filial sempre permanece local.
Aqui está o fluxo de trabalho com o qual comecei
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
Existem duas diferenças essenciais (eu acho): eu uso a mesclagem sempre em vez de rebasear e empurro minha ramificação de recursos (e minha ramificação de recursos se confirma) para o repositório remoto.
Meu raciocínio para a ramificação remota é que quero fazer backup do meu trabalho enquanto estou trabalhando. Nosso backup é feito automaticamente e pode ser restaurado se algo der errado. Meu laptop não é, ou não tão completamente. Portanto, eu odeio ter código no meu laptop que não seja espelhado em outro lugar.
Meu raciocínio para a mesclagem em vez de rebase é que a mesclagem parece ser padrão e a rebase parece ser um recurso avançado. Meu pressentimento é que o que estou tentando fazer não é uma configuração avançada, portanto a recuperação deve ser desnecessária. Até examinei o novo livro de programação pragmática sobre o Git, e eles cobrem extensivamente a mesclagem e mal mencionam rebase.
De qualquer forma, eu estava acompanhando meu fluxo de trabalho em uma ramificação recente e, quando tentei mesclá-lo de volta ao master, tudo foi para o inferno. Havia toneladas de conflitos com coisas que não deveriam ter importância. Os conflitos simplesmente não faziam sentido para mim. Levei um dia para resolver tudo e, eventualmente, culminou em um empurrão forçado para o mestre remoto, já que meu mestre local todos os conflitos foram resolvidos, mas o remoto ainda não estava feliz.
Qual é o fluxo de trabalho "correto" para algo assim? O Git deve tornar a ramificação e a fusão super fáceis, e eu simplesmente não estou vendo.
Atualização 2011-04-15
Essa parece ser uma pergunta muito popular, então pensei em atualizar com meus dois anos de experiência desde a primeira vez que perguntei.
Acontece que o fluxo de trabalho original está correto, pelo menos no nosso caso. Em outras palavras, é isso que fazemos e funciona:
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
De fato, nosso fluxo de trabalho é um pouco diferente, pois tendemos a fazer mesclagens de squash em vez de mesclas brutas. ( Nota: isso é controverso, veja abaixo. ) Isso nos permite transformar todo o ramo de recursos em um único commit no master. Em seguida, excluímos nosso ramo de recursos. Isso nos permite estruturar logicamente nossos commits no master, mesmo que eles estejam um pouco confusos em nossos branches. Então, é isso que fazemos:
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
Controvérsia de mesclagem de squash - Como vários comentadores apontaram, a mesclagem de squash jogará fora todo o histórico em sua ramificação de recursos. Como o nome indica, esmaga todos os commits em um único. Para pequenos recursos, isso faz sentido, pois o condensa em um único pacote. Para recursos maiores, provavelmente não é uma boa ideia, especialmente se o seu commit individual já é atômico. Realmente se resume à preferência pessoal.
Solicitações Pull do Github e Bitbucket (outras?) - Caso você esteja se perguntando como a mesclagem / rebase se relaciona às Solicitações Pull, eu recomendo seguir todas as etapas acima até estar pronto para voltar ao master. Em vez de mesclar manualmente com o git, você apenas aceita o PR. Observe que isso não fará uma mescla de squash (pelo menos não por padrão), mas não-squash e avanço rápido é a convenção de mesclagem aceita na comunidade Pull Request (tanto quanto eu sei). Especificamente, funciona assim:
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
Eu vim a amar o Git e nunca mais quero voltar ao SVN. Se estiver com dificuldades, fique com ela e, eventualmente, você verá a luz no fim do túnel.
rebase
a compreensão