Resumidamente, o Gitflow é um modelo fortemente baseado em branches, mas focado nas entregas. Foi criado em 2010 e hoje em dia é muito utilizado por equipes de desenvolvedores em todo o mundo.
Historic Branches: Ao invés de trabalhar apenas com o branch master, esse workflow utiliza dois branches principais para guardar histórico do projeto. O branch master guarda o histórico oficial das entregas, já o branch develop serve como integração entre todos os branches de funcionalidades (feature branches).
Feature Branches: Cada funcionalidade deve ter seu próprio branch, e ele deve ser criado a partir do branch develop. Quando uma funcionalidade for concluída, ela é mesclada (merged) novamente com o seu branch pai. As features nunca devem interagir diretamente com o master.
Release Branches: Quando o branch develop estiver com funcionalidades suficientes para uma entrega, nós criamos um branch de entrega (release branch). Com isso, nós damos início ao próximo ciclo de entrega, ou seja, nenhuma nova funcionalidade pode ser incluída a partir desse momento. Quando estivermos prontos para realizar a entrega, o release é mesclada com os branches master e develop.
Maintenance Branches: Também conhecidos como hotfix. Eles são usados para corrigir rapidamente algum problema em produção. Este é o único branch que deve ser criado a partir do master. Assim que a correção for finalizada, o branch é fechado e mesclado com o master e develop, mantendo assim as linhas completamente atualizadas.
É extramemente indicado executar o comando "git fetch" várias vezes ao dia, principalmente ao iniciar o trabalho e antes de fazer merge da sua feature. Por quê? Porque dessa forma, você garante que a estoria do seu repositório local esteja sempre atualizada com a do servidor. O Gitflow já nos traz um padrão de nomenclatura para a criação de branchs (tirando master, master sempre será master por definição do próprio Git), essa nomenclatura é develop (dev, developer) e, todas as branchs criadas a partir de develop são features (exemplo de uma feature: feature/<nome_da_nova_funcionalidade>). Branchs de hotfix podem seguir o mesmo padrão das branchs de feature (exemplo: hotfix/<nome_da_funcionalidade>) e essas branchs geralmente são criadas para correções de bugs de uma release, que não podem esperar por uma próxima release. Commits, as mensagens de commits são muito importantes. Elas possuem duas partes: um header e um body. No header você deve descever de forma suscinta o que você implementou/corrigiu, sem passar de 50 caracteres. No body, você pode escrever de forma mais detalha tudo o que você fez. E lembre-se, de preferência os seus commits devem conter poucas modificações sobre um mesmo assunto/contexto. E NUNCA, NUNCA utilize caracter especiais (assentos, cedilha, etc.), pois isso irá truncar o texto das mensagens de commit para quem não costuma utilizar ferramentas como Kraken, Tortoise Git, Source Tree, etc.
Abaixo descrevo em ordem quais comandos devem ser utilizados para realizar merges, commits, rebase e pull.
A) Merge: execute o comando git fetch, se sua branch de feature já está atualizada com a branch de develop, ou seja, está saindo do último merge de develop, significa que você não precisa fazer rebase e, caso você já tenha finalizado e testado todo seu trabalho nessa branch, sua branch está apta para voltar para develop (você pode fazer merge).
1. Volte para a branch develop com o comando: git checkout develop (ou outro nome que sua equipe tenha adotado, como: dev ou developer)
2. Execute o comando: git merge --no-ff <feature/nome_funcionalidade> (A flag --no-ff é utilizada para não deixar o git fazer um fast-foward, ou seja, ele irá manter o histórico da branch que está voltando para develop.
3. Após executar o comando a cima, no terminal, irá abrir o editor vim com a mensagem de commit gerada automaticamente, utilize o comando :wq e aperte ENTER para sair do editor e finalizar o merge.
4. Rode o projeto e teste, se tudo estiver certo, execute o comando git push, para subir o seu merge para a branch develop remota.
B) Rebase: após executar o comando git fetch, você identifica que algum colega fez merge na branch de develop e você precisa dessas modificações. Uma forma de fazer isso é com o rebase, dessa forma você atualiza a base da sua branch reescrevendo a história dela para o último commit da branch develop, movendo sua feature para esse último commit.
1. Volte para a branch develop com o comando: git checkout develop (ou outro nome que sua equipe tenha adotado, exemplo: dev ou developer)
2. Atualize sua branch develop comm o comando: git pull --rebase (Explico sobre o rebase na sessão anterior sobre boas práticas)
3. Após atualizar sua branch develop, volte para sua feature: git checkout <feature/nome_funcionalidade>
4. Execute o comando git rebase develop
5. Caso ocorra conflito em algum commit que o git não conseguiu resolver sozinho, você precisará resolver de forma manual. Indico o TortoiseGit para resolver conflitos. Após resolver os conflitos manuais, execute o comando git rebase --continue, \esse processo pode ser necessário mais de uma vez, dependendo da quantidade e complexidade dos conflitos.
6. Rode o comando git log --graph --all --pretty --oneline, para mostrar a arvore do git. É muito provável que sua branch local esteja divergindo da branch remota e você pode verificar isso ao executar o comando git status, se o output desse comando estiver dizendo para você fazer um git pull, significa que sua branch local está divergindo da remota. Então, execute o projeto e faça alguns testes, caso esteja tudo ok, verifique a árvore do git e veja se sua branch remota tem todos os commits da sua branch local, caso sim, utilize o comando git push --force. Mas tenha cuidado, esse passo é muito importante, pois a flag --force irá dizer para o servidor ignorar o que já existe nele e aceitar a nova história da sua branch.