Git
Chapters ▾ 2nd Edition

5.1 Distributed Git - Fluxos de Trabalho Distribuídos

Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you.

In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing.

Fluxos de Trabalho Distribuídos

Em contraste com Sistemas de Controle de Versão Centralizados (CVCSs), a natureza compartilhada do Git permite ser muito mais flexível na maneira que desenvolvedores colaboram em projetos. Em sistemas centralizados, cada desenvolvedor é um nó trabalhando mais ou menos pareado com o ponto central (hub). No Git, entretanto, cada desenvolvedor pode ser tanto um nó quanto um hub; ou seja, cada desenvolvedor pode tanto contribuir para o código de outros repositórios quanto manter um repositório público no qual outros podem basear o trabalho deles e contribuir. Isto permite várias possibilidades no fluxo de trabalho de seu projeto e/ou da sua equipe, então iremos explorar alguns paradigmas comuns que aproveitam esta flexibilidade. Cobriremos os pontos fortes e as possíveis fraquezas de cada design; você poderá escolher apenas um para usar, ou uma combinação de suas características.

Fluxo de Trabalho Centralizado

Em sistemas centralizados, geralmente há um único modelo de colaboração — o fluxo de trabalho centralizado. Um hub central, ou repositório, que pode aceitar código e todos sincronizam seu trabalho com ele. Alguns desenvolvedores são nós — consumidores daquele hub — e sincronizam com aquela localização central.

Centralized workflow.
Figure 54. Fluxo de trabalho centralizado

Isto significa que se dois desenvolvedores clonarem do hub e ambos fizerem alterações, o primeiro desenvolvedor que publicar (push) no servidor pode fazê-lo sem problemas. O segundo desenvolvedor deve mesclar (merge) com o trabalho do primeiro antes de publicar suas mudanças, para não sobrescrever as modificações do primeiro desenvolvedor. Este conceito é tão verdadeiro em Git quanto em Subversion (ou qualquer CVCS), e este modelo funciona perfeitamente bem em Git.

Se você já é confortável com um fluxo de trabalho centralizado na sua companhia ou equipe, pode facilmente continuar usando este fluxo de trabalho com o Git. Simplesmente configure um único repositório, e dê para todos no seu time permissão de publicação (push); Git não permitirá os usuários sobrescreverem-se.

Digamos que John e Jessica começaram a trabalhar ao mesmo tempo. John termina sua modificação e dá um push para o servidor. Então Jessica tenta dar um push das alterações dela, mas o servidor as rejeita. Ela recebe uma mensagem de que está tentando dar um push com modificações conflitantes (non-fast-forward) e que não conseguirá até as resolver e mesclar. Este fluxo de trabalho atrai várias pessoas pois já é um modelo familiar e confortável para muitos.

Isto não é limitado apenas a equipes pequenas. Com o modelo de ramificações do Git, é possível para centenas de desenvolvedores conseguirem trabalhar em um único projeto através de dúzias de ramos (branches) simultaneamente.

Fluxo de Trabalho Coordenado

Como o Git permite ter múltiplos repositórios remotos, é possível ter um fluxo de trabalho onde cada desenvolvedor tem permissão de escrita para o seu próprio repositório, e permissão de leitura para o de todos os outros. Este cenário geralmente inclui um repositório canônico que representa o projeto “oficial”. Para contribuir com este projeto, você cria seu próprio clone público do projeto e dá um push das suas modificações. Então você pode mandar um pedido para os coordenadores do projeto principal para aceitarem (pull) suas mudanças. Os coordenadores podem então adicionar seu repositório como um repositório remoto deles, testar suas mudanças localmente, mesclá-las (merge) nos respectivos branches e publicar (push) no repositório principal. O processo funciona assim (ver Fluxo de trabalho coordenado):

  1. Os coordenadores do projeto publicam no repositório público.

  2. Um colaborador clona o repositório e faz modificações.

  3. O colaborador dá um push para a sua própria cópia pública.

  4. Este contribuinte manda aos coordenadores um email pedindo para incluir as modificações.

  5. Os coordenadores adicionam o repositório do colaborador como um repositório remoto e o mesclam localmente.

  6. Os coordenadores publicam as alterações combinadas no repositório principal.

Integration-manager workflow
Figure 55. Fluxo de trabalho coordenado

Este é um fluxo de trabalho bastante comum em ferramentas baseadas em um hub como GitHub ou GitLab, onde é fácil bifurcar (fork) um projeto e publicar suas modificações no seu próprio fork para todos verem. Uma das principais vantagens desta abordagem é que você pode continuar a trabalhar, e os coordenadores do repositório principal podem incluir as suas modificações a qualquer hora. Colaboradores não tem que esperar pelo projeto para incorporar suas mudanças -– cada grupo pode trabalhar na sua própria velocidade.

Fluxo de Trabalho Ditador e Tenentes

Esta é uma variante de um fluxo de trabalho com múltiplos repositórios. É geralmente usada por projetos gigantescos com centenas de colaboradores; um exemplo famoso é o kernel Linux. Vários coordenadores são responsáveis por partes específicas do repositório, eles são chamados tenentes. Todos os tenentes têm um coordenador conhecido como o ditador benevolente. O ditador benevolente publica (push) do diretório deles para um repositório de referência do qual todos os colaboradores precisam buscar (pull). Este processo funciona assim (ver Fluxo de trabalho do ditador benevolente):

  1. Desenvolvedores comuns trabalham no seu próprio branch, baseando seu trabalho no master. Este branch master é aquele do repositório de referência no qual o ditador publica (push).

  2. Tenentes mesclam (merge) cada branch dos desenvolvedores ao branch master deles.

  3. O ditador mescla os branches master dos tenentes no branch master do ditador.

  4. Finalmente, o ditador publica aquele branch master para o repositório de referência então os desenvolvedores podem se basear nele.

Benevolent dictator workflow
Figure 56. Fluxo de trabalho do ditador benevolente

Este tipo de fluxo de trabalho não é comum, mas pode ser útil em projetos muito grandes, ou em ambientes altamente hierárquicos. Ele permite ao líder de projeto (o ditador) delegar muitas tarefas e coletar vários pedaços de código de múltiplas fontes antes de combiná-los.

Padrões para Controlar Branches de Código Fonte

Note

Martin Fowler fez um manual "Patterns for Managing Source Code Branches". Este guia cobre todos os fluxos de trabalho comuns, e explica como/quando utilizá-los. Há também uma seção comparando fluxos com muitas ou poucas combinações.

Resumo do Fluxo de Trabalho

Estes são alguns fluxos de trabalho comumente utilizados graças a sistemas distribuídos como o Git, mas muitas variações podem ser adaptadas ao seu fluxo de trabalho no mundo real. Agora que você é capaz (tomara) de determinar qual combinação de fluxo de trabalho deve funcionar para você, iremos cobrir alguns exemplos mais específicos de como realizar as principais funções que compõem os diferentes fluxos. Na próxima seção, você irá aprender sobre alguns padrões comuns para contribuir com um projeto.