Git workflow | Comparing workflows

Comparando fluxos de trabalho

 

Um Fluxo de trabalho do Git é uma receita ou recomendação sobre como usar o Git para realizar o trabalho de maneira consistente e produtiva. Os fluxos de trabalho do Git incentivam os usuários a aproveitar o Git de modo eficiente e consistente. O Git oferece muita flexibilidade em como os usuários gerenciam mudanças. Dado o foco do Git em flexibilidade, não há nenhum processo padronizado de como interagir com o Git. Ao trabalhar com uma equipe em um projeto gerenciado pelo Git, é importante ter certeza de que a equipe toda esteja de acordo com como o fluxo de mudanças será aplicado. Para garantir que a equipe esteja na mesma página, deve ser desenvolvido ou selecionado um acordo sobre o fluxo de trabalho do Git. Há vários fluxos de trabalho do Git divulgados que podem ser uma boa opção para sua equipe. Aqui, estaremos discutindo algumas dessas opções de fluxo de trabalho.

A matriz de possíveis fluxos de trabalho pode dificultar saber onde começar ao implementar o Git no local de trabalho. Esta página fornece um ponto de partida ao pesquisar os fluxos de trabalho mais comuns do Git para equipes de software.

Como você lê, lembre-se de que esses fluxos de trabalho são projetados para serem orientações e não regras concretas. Queremos mostrar o que é possível, então, você pode misturar e combinar aspectos de fluxos de trabalho diferentes para atender às suas necessidades individuais.

O que é um fluxo de trabalho bem-sucedido do Git?

Ao avaliar um fluxo de trabalho para sua equipe, o mais importante é considerar a cultura da equipe. Você quer que o fluxo de trabalho melhore a eficácia da equipe e não seja uma carga que limita a produtividade. Algumas coisas a considerar ao avaliar um fluxo de trabalho do Git são:

  • Este fluxo de trabalho é dimensionado com o tamanho da equipe?
  • É fácil desfazer erros com este fluxo de trabalho?
  • Este fluxo de trabalho impõe alguma nova sobrecarga cognitiva desnecessária à equipe?

Fluxo de trabalho centralizado

git workflow | Central and local repositories

O Fluxo de trabalho centralizado é um grande fluxo de trabalho do Git para equipes em transição do SVN. Como o Subversão, o Fluxo de trabalho centralizado usa um repositório central para servir como único ponto de entrada para todas as mudanças no projeto. Em vez de trunk, a ramificação de desenvolvimento padrão é chamada de master e todas as mudanças são confirmadas nesta ramificação. Este fluxo de trabalho não requer nenhuma outra ramificação além de master.

Fazer a transição para um sistema de controle de versão distribuído pode parecer uma tarefa assustadora, mas você não tem que mudar seu fluxo de trabalho existente para aproveitar o Git. Sua equipe pode desenvolver projetos exatamente da mesma maneira que faz com o Subversão.

No entanto, usar o Git para impulsionar o fluxo de trabalho de desenvolvimento apresenta algumas vantagens sobre o SVN. Em primeiro lugar, dá a cada desenvolvedor sua própria cópia local do projeto inteiro. Este ambiente isolado permite que cada desenvolvedor trabalhe de modo independente de todas as outras mudanças em um projeto — ele pode adicionar confirmações ao repositório local e esquecer completamente sobre desenvolvimentos de upstream até que seja conveniente para ele.

Em segundo lugar, dá a você acesso ao robusto modelo de ramificação e mesclagem do Git. Ao contrário do SVN, as ramificações do Git são projetadas para serem um mecanismo à prova de falhas para integrar o código e compartilhar mudanças entre os repositórios. O Fluxo de trabalho centralizado é semelhante a outros fluxos de trabalho em sua utilização de um repositório hospedado do lado do servidor remoto que os desenvolvedores empurram e puxam. Comparado a outros fluxos de trabalho, o Fluxo de trabalho centralizado não tem nenhum padrão definido de solicitação pull ou ramificação. Um Fluxo de trabalho centralizado geralmente é mais adequado para equipes que estão migrando do SVN para o Git e equipes menores.

Como funciona

Os desenvolvedores começam clonando o repositório central. Em suas próprias cópias locais do projeto, eles editam arquivos e confirmam mudanças como fariam com o SVN; no entanto, essas novas confirmações são armazenadas localmente — elas estão completamente isoladas do repositório central. Isso permite que os desenvolvedores adiem a sincronização de upstream até que estejam em um ponto de interrupção conveniente.

Para publicar as mudanças no projeto oficial, os desenvolvedores "empurram" sua ramificação mestre local para o repositório central. Isso é o equivalente de svn commit, exceto que ele adiciona todas as confirmações locais que ainda não estão na ramificação mestre central.

Inicializar o repositório central

Git Workflow: Initialize Central Bare Repository

Em primeiro lugar, alguém precisa criar o repositório central em um servidor. Se for um novo projeto, você pode iniciar um repositório vazio. Caso contrário, será necessário importar um repositório Git ou SVN existente.

Repositórios centrais devem sempre ser repositórios vazios (eles não devem ter um diretório de trabalho), que podem ser criados da seguinte maneira:

ssh user@host git init --bare /path/to/repo.git

Tenha certeza de usar um nome de usuário SSH válido para user, o domínio ou endereço IP do seu servidor para host e o local em que você gostaria de armazenar o repositório para /path/to/repo.git. Note que a extensão .git é convencionalmente anexada ao nome do repositório para indicar que é um repositório vazio.

Repositórios centrais hospedados

Os repositórios centrais são, com frequência, criados através de serviços de hospedagem do Git de terceiros, como Bitbucket Cloud ou Bitbucket Server. O processo de início de um repositório vazio discutido acima é realizado para você pelo serviço de hospedagem. O serviço de hospedagem vai fornecer um endereço para o repositório central acessar a partir de seu repositório local.

Clonar o repositório central

Em seguida, cada desenvolvedor cria uma cópia local de todo o projeto. Isso é realizado através do comando git clone:

git clone ssh://user@host/path/to/repo.git

Quando você clona um repositório, o Git automaticamente adiciona um atalho chamado origem que aponta novamente para o repositório “pai”, sob a suposição de que você vai querer interagir com ele ainda mais no caminho. 

Fazer mudanças e confirmar

Depois que o repositório é clonado localmente, um desenvolvedor pode fazer mudanças usando o processo de confirmação padrão do Git: editar, montar e confirmar. Se você não estiver familiarizado com a área de staging, é uma maneira de preparar uma confirmação sem ter que incluir cada mudança no diretório de trabalho. Isso permite criar confirmações altamente focadas, mesmo que você tenha feito muitas mudanças locais.

git status # Exibir o estado do repositório
git add <some-file> # Montar um arquivo
git commit # Confirmar um arquivo</some-file>

Lembre-se de que, desde que esses comandos criem confirmações locais, John pode repetir esse processo quantas vezes quiser sem se preocupar com o que está acontecendo no repositório central. Isso pode ser muito útil para recursos grandes que precisam ser divididos em partes mais simples, mais atômicas.

Envie novas confirmações para o repositório central

Depois que o repositório local tiver novas mudanças confirmadas, essas mudanças deverão ser enviadas para compartilhamento com outros desenvolvedores no projeto.

git push origin master

Este comando enviará as novas mudanças confirmadas para o repositório central. Ao enviar as mudanças para o repositório central, é possível que tenham sido enviadas atualizações de outro desenvolvedor que contêm código que entrem em conflito com as atualizações de envio pretendidas. O Git vai imprimir uma mensagem indicando esse conflito. Nesta situação, git pull primeiro deverá ser executado. Este cenário de conflito será expandido na próxima seção.

Como gerenciar conflitos

O repositório central representa o projeto oficial, então, sua história de confirmação deve ser tratada como sagrada e imutável. Se as confirmações locais de um desenvolvedor divergirem do repositório central, o Git recusará enviar suas mudanças porque isso substituiria as confirmações oficiais.

Git Workflows: Managing conflicts

Antes de o desenvolvedor poder publicar seu recurso, ele precisa buscar as confirmações centrais atualizadas e fazer rebase de suas mudanças na parte de cima delas. Isso é como dizer “Quero adicionar minhas mudanças ao que todo mundo já fez”. O resultado é uma história perfeitamente linear, como nos fluxos de trabalho tradicionais de SVN.

Se as mudanças locais entrarem em conflito direto com confirmações a montante, o Git vai pausar o processo de rebase e dar a você a chance de resolver manualmente os conflitos. O bom sobre o Git é que ele usa os mesmos comandos git status e git add tanto para gerar confirmações quanto para resolver conflitos de mesclagem. Isso torna mais fácil para os novos desenvolvedores gerenciar suas próprias mesclagens. Além disso, se eles tiverem problemas, o Git torna muito fácil abortar todo o rebase e tentar novamente (ou procurar ajuda).

Exemplo

Vamos dar um exemplo geral sobre como uma equipe pequena típica poderia colaborar usando esse fluxo de trabalho. Vamos ver como dois desenvolvedores, John e Mary, podem trabalhar em recursos separados e compartilhar suas contribuições por meio de um repositório centralizado.

John trabalha em seu recurso

Git Workflows: Edit Stage Commit Feature Process

Em seu repositório local, John pode desenvolver recursos usando o processo de confirmação padrão do Git: editar, montar e confirmar.

Lembre-se de que, como esses comandos criam confirmações locais, John pode repetir esse processo quantas vezes quiser sem se preocupar com o que está acontecendo no repositório central.

Mary trabalha em seu recurso

Git Workflows: Edit Stage Commit Feature

Enquanto isso, Mary está trabalhando em seu próprio recurso em seu próprio repositório local usando o mesmo processo editar/montar/confirmar. Como John, ela não se importa com o que está acontecendo no repositório central e realmente não se importa com o que John está fazendo no repositório local dele, uma vez que todos os repositórios locais são privados.

John publica seu recurso

Git Workflows: Publish Feature

Depois que John termina seu recurso, ele deve publicar suas confirmações locais no repositório central para que outros membros da equipe possam acessá-lo. Ele pode fazer isso com o comando git push, da seguinte maneira:

git push origin master

Lembre-se de que a origem é a conexão remota com o repositório central que o Git criou quando John o clonou. O argumento mestre diz ao Git para tentar fazer com que a ramificação mestre da origem se pareça com sua ramificação mestre local. Como o repositório central não foi atualizado desde que John o clonou, isso não vai resultar em nenhum conflito e o envio funcionará como esperado.

Mary tenta publicar seu recurso

Git Workflows: Push Command Error

Vamos ver o que acontece se Mary tentar enviar seu recurso após John ter publicado com êxito as mudanças dele no repositório central. Ela pode usar exatamente o mesmo comando de envio:

git push origin master

Mas, como a história local dela diverge do repositório central, o Git vai recusar a solicitação com uma mensagem de erro mais detalhada:

erro: falha ao enviar algumas referências para '/path/to/repo.git'
dica: as atualizações foram rejeitadas porque a ponta de sua ramificação atual está para trás
dica: sua contraparte remota. Mesclar as mudanças remotas (por exemplo, 'git pull')
dica: antes de enviar novamente.
dica: Veja a 'Nota sobre avanços rápidos' em 'git push —help' para obter detalhes.

Isso impede que Mary substitua as confirmações oficiais. Ela precisa enviar pull das atualizações de John para o repositório dela, integrá-las com suas mudanças locais e depois tentar novamente.

Mary faz o rebase na parte superior da(s) confirmação(ões) de John

Git Workflows: Git Pull Rebase

Mary pode usar git pull para incorporar as mudanças a montante no repositório dela. Este comando é parecido com svn update—ele puxa toda a história de confirmação a montante para o repositório local de Mary e tente integrá-la com as confirmações locais dela:

git pull --rebase origin master

A opção --rebase diz ao Git para mover todas as confirmações de Mary para a ponta da ramificação mestre após sincronizar com as mudanças do repositório central, como mostrado abaixo:

Git workflows: Rebasing to Master

O pull ainda pode funcionar se você esquecer essa opção, mas seria necessário concluir com uma “confirmação de mesclagem” supérflua toda vez que alguém precisasse sincronizar com o repositório central. Para este fluxo de trabalho, é sempre melhor fazer o rebase em vez de gerar uma confirmação de mesclagem.

Mary resolve um conflito de mesclagem

Git Workflows: Rebasing on Commits

O rebase funciona transferindo cada confirmação local para a ramificação mestre atualizada uma de cada vez. Isso significa que você captura conflitos de mesclagem de confirmação a confirmação em vez de resolver todas elas em uma confirmação de mesclagem em massa. Isso mantém suas confirmações o mais focadas possível e faz uma história de projeto limpa. Por sua vez, isso faz com que seja muito mais fácil descobrir onde os bugs foram introduzidos e, se necessário, reverter as mudanças com impacto mínimo sobre o projeto.

Se Mary e John estiverem trabalhando em recursos não relacionados, é improvável que o processo de rebase gere conflitos. Mas se gerar, o Git vai pausar o rebase na confirmação atual e enviar a seguinte mensagem, juntamente com algumas instruções relevantes:

CONFLITO (conteúdo): mesclar conflito em <um-arquivo>
Git workflows: Conflict Resolution

O importante sobre o Git é que qualquer pessoa pode resolver seus próprios conflitos de mesclagem. No exemplo, Mary simplesmente executaria um git status para ver onde está o problema. Arquivos com conflito aparecerão na seção Caminhos não mesclados:

# Caminhos não mesclados:
# (use "git reset HEAD <um-arquivo>..." para desmontar)
# (use "git add/rm <um-arquivo>..." conforme apropriado para marcar a resolução)
#
# ambos modificados: <um-arquivo>

Em seguida, ela vai editar o(s) arquivo(s) ao seu gosto. Quando estiver feliz com o resultado, ela pode montar o(s) arquivo(s) da maneira habitual e deixar git rebase fazer o resto:

git add <um-arquivo>
git rebase --continue

E isso é tudo o que há para ela. O Git passará para a próxima confirmação e repetirá o processo para qualquer outra confirmação que gere conflitos.

Se você chegar a esse ponto, perceber e não tiver ideia do que está acontecendo, não entre em pânico. Apenas execute o comando a seguir e você voltará para onde começou:

git rebase --abort

Mary publica seu recurso com êxito

Git Workflows: Synchronize Central Repo

Depois que terminar de sincronizar com o repositório central, Mary poderá publicar suas mudanças com êxito:

git push origin master

Onde ir a partir daqui

Como você pode ver, é possível replicar um ambiente de desenvolvimento tradicional do Subversão usando apenas alguns comandos do Git. Isso é excelente para as equipes de transição fora do SVN, mas não aproveita a natureza distribuída do Git.

O Fluxo de trabalho centralizado é ótimo para equipes pequenas. O processo de resolução de conflitos detalhado acima pode formar um gargalo à medida que sua equipe aumentar de tamanho. Se sua equipe estiver confortável com o Fluxo de trabalho centralizado, mas quiser simplificar seus esforços de colaboração, vale a pena explorar os benefícios do Fluxo de trabalho de ramificação de recurso. Ao dedicar uma ramificação isolada a cada recurso, é possível iniciar discussões mais profundas sobre novas adições antes de integrá-las ao projeto oficial.

Outros fluxos de trabalho comuns

O Fluxo de trabalho centralizado é essencialmente um bloco de construção para outros fluxos de trabalho do Git. Os fluxos de trabalho mais populares do Git terão algum tipo de repositório centralizado do qual os desenvolvedores individuais farão envios e enviarão pull. Abaixo, vamos discutir rapidamente alguns outros fluxos de trabalho populares do Git. Esses fluxos de trabalho estendidos oferecem padrões mais especializados em relação ao gerenciamento de ramificações para desenvolvimento de recursos, hot fixes e lançamento eventual.

Ramificação de recurso

A Ramificação de recursos é uma extensão lógica do Fluxo de trabalho centralizado. A ideia central por trás do Fluxo de trabalho de ramificação de recursos é que todo desenvolvimento de recursos deve ocorrer em uma ramificação dedicada em vez de na ramificação mestre. Esse encapsulamento facilita para vários desenvolvedores trabalharem em um recurso particular sem perturbar a base de código principal. Isso também significa que a ramificação mestre nunca deve conter código quebrado, o que é uma enorme vantagem para ambientes de integração contínua. 

Fluxo de trabalho de Gitflow

O Fluxo de trabalho de Gitflow foi publicado pela primeira vez em um blog de 2010 altamente conceituado de Vincent Driessen no nvie. O Fluxo de trabalho de Gitflow define um modelo estrito de ramificação projetado em torno do lançamento do projeto. Esse fluxo de trabalho não adiciona nenhum conceito ou comando novo além do exigido para o Fluxo de trabalho de ramificação de recurso. Em vez disso, ele atribui funções muito específicas a diferentes ramificações e define como e quando elas devem interagir. 

Fluxo de trabalho de bifurcação

O Fluxo de trabalho de bifurcação é fundamentalmente diferente dos outros fluxos de trabalho discutidos neste tutorial. Em vez de usar um único repositório do lado do servidor para funcionar como a base de código “central”, ele dá a cada desenvolvedor um repositório do lado do servidor. Isso significa que cada colaborador tem não apenas um, mas dois repositórios do Git: um local privado e um público do lado do servidor. 

Orientações

Não há nenhum fluxo de trabalho do Git de tamanho único. Como dito anteriormente, é importante desenvolver um fluxo de trabalho do Git que seja uma melhoria de produtividade para a equipe. Além da cultura da equipe, um fluxo de trabalho também deve complementar a cultura da empresa. Recursos do Git, como ramificações e tags, devem complementar a programação de lançamento da empresa. Se sua equipe estiver usando o software de gerenciamento de projetos de controle de tarefa , talvez você queira usar ramificações que correspondam às tarefas em andamento. Além disso, algumas orientações a considerar ao decidir sobre um fluxo de trabalho são:

Ramificações de curta duração

Quanto mais uma ramificação durar separada da ramificação de produção, maior o risco de conflitos de mesclagem e desafios de implementação. Ramificações de curta duração promovem mesclagens e implementações mais limpas.

Minimizar e simplificar reversões

É importante ter um fluxo de trabalho que ajude a impedir, de modo proativo, mesclagens que terão que ser revertidas. Um fluxo de trabalho que teste uma ramificação antes de permitir que ela seja mesclada na ramificação mestre é um exemplo. No entanto, acidentes acontecem. Dito isso, é bom ter um fluxo de trabalho que permita reversões fáceis que não interrompam o fluxo para outros membros da equipe.

Coincidir com a programação de um lançamento

Um fluxo de trabalho deve complementar o ciclo de lançamento de desenvolvimento de software de sua empresa. Se você planeja lançar várias vezes por dia, vai querer manter sua ramificação mestre estável. Se sua programação de lançamento for menos frequente, talvez você considere a possibilidade de usar tags do Git para marcar uma ramificação para uma versão.

Resumo

Neste documento, discutimos fluxos de trabalho do Git. Demos uma olhada mais detalhada em um Fluxo de trabalho centralizado com exemplos práticos. Expandindo o Fluxo de trabalho centralizado, discutimos fluxos de trabalho especializados adicionais. Alguns argumentos principais deste documento são:

  • Não há nenhum fluxo de trabalho do Git de tamanho único
  • Um fluxo de trabalho deve ser simples e melhorar a produtividade da equipe
  • Os requisitos de sua empresa devem ajudar a formar seu fluxo de trabalho do Git

Para ler sobre o próximo fluxo de trabalho do Git, confira a abrangente divisão do Fluxo de trabalho de ramificação de recurso.

Pronto para aprender sobre o Git?

Experimente este tutorial interativo.

Comece agora mesmo