Close

Comparando fluxos de trabalho do Git: o que você deve saber

Git é o sistema de controle de versões mais usado hoje em dia. 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 desenvolvedores e as equipes de DevOps a aproveitar o Git com eficácia e estabilidade. 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 sobre como o fluxo de mudanças vai ser aplicado. Para garantir que a equipe esteja alinhada, 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 a equipe. Aqui, vamos discutir algumas dessas opções de fluxo de trabalho do Git.

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 tem escalabilidade para diferentes tamanhos de equipe?
  • É fácil de desfazer erros e enganos com este fluxo de trabalho?
  • Este fluxo de trabalho adiciona alguma carga cognitiva desnecessária à equipe?

Fluxo de trabalho centralizado


Repositórios centrais e locais

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 tronco, a ramificação de desenvolvimento padrão é chamada de branch main e todas as alterações recebem commit nesta ramificação. Este fluxo de trabalho não requer nenhum outro branch além do branch main.

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.

Janela do console
Material relacionado

Log avançado do Git

Logotipo do Bitbucket
VER SOLUÇÃO

Aprenda a usar o Git com o Bitbucket Cloud

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 alterações no projeto oficial, os desenvolvedores enviam o branch main local ao repositório central. É o equivalente de svn commit, exceto que ele adiciona todos os commits locais que ainda não estão no branch main central.

Inicializar o repositório central

Inicializar o repositório central de cuidados

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, por convenção, a extensão .git é anexada ao nome do repositório para indicar que é um repositório vazio.

Repositórios centrais hospedados

Em geral, os repositórios centrais são criados por meio de serviços de hospedagem do Git de terceiros, como Bitbucket Cloud. O processo de início de um repositório vazio discutido acima é entregue para você pelo serviço de hospedagem. O serviço de hospedagem vai disponibilizar um endereço para o repositório central acessar a partir do repositório local.

Clonar o repositório central

Em seguida, cada desenvolvedor cria uma cópia local de todo o projeto usando o comando git clone:

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

Quando você clona um repositório, o Git faz a adição automática de um atalho chamado origem que aponta de volta para o repositório “pai”, sob a suposição de que você vai querer interagir com ele no futuro.

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 # View the state of the repo
git add <some-file> # Stage a file
git commit # Commit a file</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 funções grandes que precisam ser divididas 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 main

Este comando vai enviar as novas mudanças com commit 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, o git pull deve ser executado primeiro. Este cenário de conflito vai 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.

Como gerenciar conflitos

Antes de o desenvolvedor poder publicar sua função, 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 commits upstream, o Git vai pausar o processo de rebase para que você possa fazer a resolução manual dos conflitos. O bom do Git é que ele usa os mesmos comandos git status e git add tanto para gerar commits quanto para resolver conflitos de mesclagem. Assim fica fácil para os novos desenvolvedores gerenciarem suas próprias mesclagens. Além do mais, se eles tiverem problemas, no Git é muito fácil abortar todo o rebase e tentar de novo (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 funções separadas e compartilhar suas contribuições por meio de um repositório centralizado.

John trabalha em sua função

Editar o processo da função Stage Commit

Em seu repositório local, John pode desenvolver funções 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 sua função

Editar a função Stage Commit

Ao mesmo tempo, Mary está trabalhando em sua própria função em seu próprio repositório local usando o mesmo processo editar/montar/fazer commit. Como John, ela não se importa com o que está acontecendo no repositório central e não se importa mesmo com o que John está fazendo no repositório local dele, uma vez que todos os repositórios locais são privados.

John publica sua função

Função publicar

Depois que John termina a função, ele deve publicar os commits locais no repositório central para que outros membros da equipe possam ter acesso. Ele pode usar o comando git push da seguinte maneira:

git push origin main

Observe que a origin é a conexão remota com o repositório central que o Git criou quando John o clonou. O argumento main diz ao Git para tentar fazer com que o branch main de origin se pareça com o branch main local. Como o repositório central não foi atualizado desde que John o clonou, nenhum conflito vai ser gerado e o envio vai funcionar como esperado.

Mary tenta publicar sua função

Erro no comando push

Vamos ver o que acontece se Mary tentar enviar sua função 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 main

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:

error: failed to push some refs to '/path/to/repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

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 pull rebase

Mary pode usar o git pull para integrar as alterações upstream ao próprio repositório. Este comando é parecido com o svn update— ele envia todo o histórico de commits upstream para o repositório local de Mary e tenta integrar aos commits locais dela:

git pull --rebase origin main

A opção --rebase diz ao Git para mover todos os commits de Mary para a ponta do branch main depois de o sincronizar com as alterações do repositório central, como mostrado abaixo:

Fazer rebase para principal

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

Fazer rebase em commits

O rebase funciona transferindo cada commit local para o branch main atualizado, um de cada vez. Ou seja: você captura conflitos de mesclagem de commit em commit em vez de resolver todos eles em um commit de mesclagem em massa. Assim os commits ficam o mais focados possível e o histórico do projeto fica limpo, o que 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 funções não relacionadas, é 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:

CONFLICT (content): Merge conflict in <some-file>
Fluxo de trabalho do Git de resolução de conflitos durante um merge.

A melhor coisa do Git é que qualquer pessoa pode resolver os próprios conflitos de mesclagem. No exemplo, Mary executa um simples git status para saber onde está o problema. Arquivos com conflito vão aparecer na seção Caminhos não mesclados:

# Unmerged paths:
# (use "git reset HEAD <some-file>..." to unstage)
# (use "git add/rm <some-file>..." as appropriate to mark resolution)
#
# both modified: <some-file>

Em seguida, ela vai editar o(s) arquivo(s) da maneira que quiser. Quando estiver feliz com o resultado, ela vai poder organizar o(s) arquivo(s) da maneira habitual e deixar o git rebase fazer o resto:

git add <some-file>
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 sua função com êxito

Sincronizar repositório central

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

git push origin main

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 função. Ao dedicar uma ramificação isolada a cada função, é possível iniciar discussões mais profundas sobre novas adições antes de fazer a integração delas 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 funções, hot fixes e lançamento eventual.

Ramificação de funções


A Ramificação de funções é uma extensão lógica do Fluxo de trabalho centralizado. A ideia central por trás do Fluxo de trabalho de ramificação de funções é que todo desenvolvimento de funções deve ocorrer em uma ramificação dedicada em vez de no branch main. Esse encapsulamento facilita para vários desenvolvedores trabalharem em uma função particular sem perturbar a base de código principal. Assim, o branch main nunca deve conter código quebrado, o que é uma enorme vantagem para ambientes de integração contínua.

Saiba tudo sobre o Gitflow Workflow


O Fluxo de trabalho de Gitflow foi publicado pela primeira vez em um blog de 2010 de alto prestígio de Vincent Driessen no nvie. O Gitflow Workflow 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 funções. O que ele faz é atribuir 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 tem diferenças fundamentais em relação aos 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. Quer dizer 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 antes, é importante desenvolver um fluxo de trabalho do Git que seja uma melhoria de produtividade para a equipe. Além da cultura da equipe, o fluxo de trabalho também deve complementar a cultura da empresa. funções do Git, como ramificações e marcadores, devem complementar a programação de lançamento da empresa. Se sua equipe estiver usando o software de gestão de projetos de controle de tarefa, talvez você queira usar ramificações que correspondam às tarefas em andamento. Além desses aspectos, 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, com iniciativa, mesclagens que vão ter que ser revertidas. Um fluxo de trabalho que teste uma ramificação antes de permitir que ela seja mesclada no branch main é um exemplo. No entanto, acidentes acontecem. Então é 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 da empresa. Se você planeja lançar várias vezes por dia, vai querer manter o branch main estável. Se a programação de lançamento for menos frequente, talvez você considere a possibilidade de usar marcadores 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á um fluxo de trabalho específico do Git que atenda a todos os casos
  • Um fluxo de trabalho deve ser simples e melhorar a produtividade da sua equipe
  • Seus requisitos de negócios 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 função.


Compartilhar este artigo

Leitura recomendada

Marque esses recursos para aprender sobre os tipos de equipes de DevOps ou para obter atualizações contínuas sobre DevOps na Atlassian.

Pessoas colaborando usando uma parede cheia de ferramentas

Blog do Bitbucket

Ilustração do DevOps

Caminho de aprendizagem de DevOps

Demonstrações de funções no Demo Den com parceiros da Atlassian

Como o Bitbucket Cloud funciona com o Atlassian Open DevOps

Inscreva-se para receber a newsletter de DevOps

Thank you for signing up