Do branch ao pull request, colaboração distribuída com Git e GitHub
por Frank de Alcantara em 30/08/2026
No artigo Do Git ao domínio próprio, construímos uma cadeia completa: uma colaboradora criou commits em um fork, abriu um pull request, o administrador integrou a mudança e o GitHub Pages publicou a nova versão. A cadeia funciona. Contudo, ela passa depressa justamente pelo ponto em que uma equipe iniciante costuma se perder: há uma main no repositório oficial, outra no fork, uma terceira no computador, uma ramificação da tarefa e um pull request comparando duas delas. Todas podem exibir arquivos parecidos sem apontar para o mesmo commit.
Este artigo abre essa caixa. Vamos distinguir branch, fork e clone pelo objeto que cada operação cria; acompanhar os ponteiros que o Git mantém; montar um pull request com a direção correta; revisar a proposta sem criar outra; comparar as estratégias de integração; resolver um conflito; e concluir com um laboratório em que cada resultado pode ser conferido.
O objetivo não é decorar uma procissão de comandos.
A estudante precisa conseguir olhar para qualquer etapa e responder três perguntas: em qual repositório estou, qual ramificação estou alterando e para onde esta mudança pretende ir?
1. O problema escondido na main compartilhada
Quando uma única pessoa trabalha na main, a linha do tempo parece suficiente. Ela modifica um arquivo, cria um commit e executa git push. A dificuldade começa quando Ana e Bruno partem do mesmo commit e trabalham ao mesmo tempo. Bruno publica primeiro; Ana tenta publicar depois. O GitHub não pode simplesmente mover a main remota para o commit de Ana, porque esse movimento abandonaria a contribuição de Bruno.
O defeito não está no Git. O defeito está no acordo de trabalho. Uma main compartilhada usada como área de rascunho mistura duas decisões diferentes: registrar uma tentativa e aceitar essa tentativa como versão oficial. O branch separa a primeira decisão; o pull request governa a segunda.
Vamos fixar o vocabulário antes de montar o fluxo:
- Um commit registra um estado do projeto, metadados de autoria, uma mensagem e uma ligação com seu commit ou seus commits anteriores.
- Um branch é um nome móvel que aponta para um commit dentro de um repositório Git. Criá-lo não duplica todos os arquivos.
- Um fork é outro repositório no GitHub, pertencente a outra conta ou organização e ligado ao repositório de origem pela rede de forks da plataforma.
- Um clone cria um repositório Git local a partir de um repositório acessível por uma URL. A cópia local contém histórico, referências e uma árvore de trabalho.
- Um pull request é uma proposta do GitHub que compara uma ramificação de origem, chamada head, com uma ramificação de destino, chamada base. Ele não é um comando nativo do Git e não integra nada sozinho.
Esses cinco objetos cooperam, mas não são versões maiores e menores da mesma coisa. Confundi-los produz perguntas como já fiz o fork, por que o arquivo não apareceu no meu computador? ou abri o pull request, por que a main ainda não mudou?. A resposta, nos dois casos, é a mesma: a operação criou outro tipo de objeto.
2. Branch, fork e clone atravessam fronteiras diferentes
Uma branch vive dentro de um repositório. Um fork cria outro repositório no GitHub. Um clone atravessa a fronteira entre um repositório acessível por rede e o computador da colaboradora. A Figura 1 reúne essas três operações sem fingir que são equivalentes.
Figura 1: O *fork* e o *clone* criam repositórios distintos; a *branch* cria apenas outro ponteiro dentro do repositório local.
Observe a consequência. Se Ana executar git switch -c feature/ana-souza, nenhum novo repositório aparecerá no GitHub. A nova ramificação existirá apenas no repositório local até que um push a publique. De modo semelhante, clicar em Fork não cria uma pasta no computador. O fork existirá no GitHub até que Ana faça o clone.
2.1 A branch é um ponteiro, e HEAD diz qual ponteiro se move
Suponha que main aponte para o commit C2. Ao executar:
git switch -c feature/ana-souza
o Git cria feature/ana-souza apontando para o mesmo C2 e faz HEAD referenciar a nova ramificação. HEAD representa o ponto de trabalho atual. Quando Ana cria C3, o ponteiro feature/ana-souza avança para C3; main permanece em C2.
Podemos observar esse estado sem depender da memória:
git branch --show-current
git log --oneline --decorate --graph --all
O primeiro comando responde em qual ramificação estamos. O segundo mostra o grafo de commits e decora os pontos alcançados por HEAD, main, feature/ana-souza e pelas referências remotas. A interface gráfica ajuda, mas o grafo continua sendo o objeto que precisamos compreender.
2.2 Trocar de branch também troca os arquivos visíveis
Se cada branch aponta para um estado do projeto, mudar de ramificação precisa materializar esse estado na árvore de trabalho. É por isso que git switch main pode alterar vários arquivos de uma vez sem apagar o trabalho registrado na outra ramificação. Os arquivos passam a refletir o commit alcançado por main.
O Git recusa a troca quando modificações ainda não registradas seriam sobrescritas. Essa recusa não é um obstáculo caprichoso; ela impede que uma mudança sem commit seja misturada silenciosamente ao estado da outra ramificação. Antes de trocar, lemos git status, terminamos o commit coerente ou guardamos conscientemente o trabalho para depois.
3. Origin, upstream e as quatro referências chamadas main
Depois do fork e do clone, o repositório local de Ana precisa conversar com dois repositórios no GitHub. O nome origin costuma apontar para o endereço clonado, portanto o fork de Ana. Acrescentaremos o nome upstream para apontar ao repositório oficial do professor:
git clone https://github.com/ana/lab-git-colaborativo.git
cd lab-git-colaborativo
git remote add upstream https://github.com/professor/lab-git-colaborativo.git
git remote -v
origin e upstream são apelidos armazenados na configuração do repositório local. Eles não significam, por natureza, meu repositório e repositório oficial. O significado nasce das URLs que acabamos de associar. Ler git remote -v é mais seguro do que confiar no nome.
Nesse ponto, a palavra main aparece em quatro posições:
| Referência | Onde vive | Quem a move | O que representa |
|---|---|---|---|
main do repositório oficial |
GitHub, conta do professor | A integração aceita pelo mantenedor | A versão oficial do laboratório |
main do fork |
GitHub, conta de Ana | Um push de Ana ou a sincronização pela interface | A base remota que Ana controla |
main local |
Computador de Ana | Um commit, merge ou avanço em linha reta | A ramificação local de base |
upstream/main e origin/main |
Computador de Ana | git fetch atualiza cada referência de acompanhamento |
A última posição observada de cada main remota |
A diferença entre main e upstream/main merece uma pausa. A primeira é uma ramificação local, na qual podemos trabalhar. A segunda é uma referência local de acompanhamento que registra onde a main do upstream estava no último fetch. Ela não se atualiza por telepatia quando o professor integra outro pull request.
Por isso, a sincronização começa buscando informação:
git fetch upstream
git switch main
git merge --ff-only upstream/main
git push origin main
git fetch upstream atualiza as referências que descrevem o repositório oficial sem alterar imediatamente os arquivos de trabalho. Em seguida, git merge --ff-only upstream/main move a main local para a mesma ponta somente se ela não tiver história própria divergente. Por fim, git push origin main publica essa base atualizada no fork.
O --ff-only funciona aqui como uma regra de higiene: a main pessoal acompanha a main oficial; as tarefas pertencem a ramificações feature/*. Se a main local contiver um commit exclusivo, o comando recusará o avanço e revelará que uma tarefa foi registrada no lugar errado.
4. O percurso completo de uma contribuição
Agora temos todos os territórios nomeados. Vamos percorrer uma contribuição do início ao fim, usando o repositório público professor/lab-git-colaborativo e o arquivo participantes.md.
4.1 Começar sempre de uma base conhecida
Antes de abrir uma tarefa, Ana atualiza a main local e o fork:
git switch main
git fetch upstream
git merge --ff-only upstream/main
git push origin main
Somente depois ela cria a ramificação:
git switch -c feature/ana-souza
git branch --show-current
Criar a ramificação depois da sincronização faz com que sua base seja o commit oficial mais recente. Esse detalhe reduz conflitos sem prometer eliminá-los, pois a main pode avançar novamente enquanto Ana trabalha.
4.2 Separar edição, preparação e commit
Ana acrescenta ao arquivo:
| Ana Souza | 20261234 |
Em seguida, ela inspeciona cada fronteira:
git status
git diff
git add participantes.md
git diff --staged
git commit -m "Adiciona Ana Souza à lista de participantes"
git diff mostra o que foi modificado, mas ainda não foi preparado. git diff --staged mostra exatamente o que o próximo commit registrará. Essa segunda leitura evita incluir uma senha, um arquivo gerado ou uma edição que pertencia a outra tarefa.
Um commit útil possui uma unidade de intenção. Se a mesma edição também corrigisse quarenta nomes de colegas, mudasse a licença e reorganizasse o README.md, a revisão precisaria decidir sobre quatro assuntos de uma vez. Pequenos commits não servem para produzir um histórico cheio de migalhas; servem para tornar cada mudança explicável.
4.3 Publicar a branch no fork
A ramificação ainda existe somente no computador. O primeiro push cria sua correspondente no fork e configura o acompanhamento:
git push -u origin feature/ana-souza
A opção -u grava a relação entre a ramificação local e origin/feature/ana-souza. Os próximos envios poderão usar apenas git push. Nenhum desses envios altera a main oficial: Ana publicou commits em uma ramificação do próprio fork.
4.4 Abrir o pull request na direção correta
Na tela de criação do pull request, a direção será:
| Papel | Repositório | Ramificação | Pergunta que responde |
|---|---|---|---|
| base | professor/lab-git-colaborativo |
main |
Onde a mudança deve chegar? |
| head | ana/lab-git-colaborativo |
feature/ana-souza |
De onde vêm os commits propostos? |
Trocar esses lados produz outra proposta, possivelmente tentando levar a main oficial para o fork. Antes de selecionar Create pull request, Ana lê os nomes dos dois repositórios e das duas ramificações.
O título deve completar mentalmente a frase se esta proposta for integrada, ela…. Um corpo mínimo informa contexto, alteração e verificação:
## O que mudou
Adiciona Ana Souza e o RA 20261234 à tabela de participantes.
## Como foi verificado
- `git diff --staged` mostrou apenas a nova linha.
- A tabela continuou com duas colunas e um separador Markdown válido.
Não precisamos esperar que o trabalho termine para compartilhar contexto. Um draft pull request permite expor uma proposta ainda em construção sem declará-la pronta para integração.
5. Pull request é comparação viva, não envelope fechado
Ao abrir o pull request, o GitHub calcula o conjunto de mudanças introduzido pela head em relação ao ponto comum de onde head e base divergiram. A aba Files changed mostra esse diff; Commits mostra a evolução da ramificação; Checks reúne verificações automatizadas; Conversation conserva descrição, comentários e decisões de revisão.
Nada disso congela a ramificação de Ana.
A Figura 2 mostra o ciclo. Quando a revisora solicita uma correção, Ana modifica a mesma feature/ana-souza, cria outro commit e envia novamente para origin. A head avança, o diff é recalculado e o mesmo pull request recebe a nova versão.
Figura 2: Uma revisão não devolve um arquivo separado; ela faz a *head* avançar e atualiza a comparação mantida pelo mesmo *pull request*.
5.1 Revisar a proposta, não apenas sua aparência
Uma revisão começa pelo propósito declarado e termina no efeito real do diff. Para o laboratório, a revisora confere:
- A proposta altera somente
participantes.md. - O nome e o RA ocupam duas células da mesma linha.
- Nenhuma linha de outra participante foi removida.
- A ramificação de destino é a
mainoficial. - As conversas abertas foram respondidas e, quando aplicável, marcadas como resolvidas.
O GitHub oferece três decisões de revisão. Comment registra observações sem aprovar nem bloquear. Approve declara a proposta pronta segundo os critérios da revisora. Request changes indica que a autora precisa agir antes da integração. Contudo, uma solicitação de mudanças só se torna um bloqueio técnico quando uma regra da ramificação exige revisões.
Essa distinção separa norma social de mecanismo. Escrever ninguém integra sem revisão no README.md comunica a norma; configurar uma regra para main faz a plataforma aplicá-la.
5.2 Corrigir na mesma branch
Suponha que Ana tenha escrito o RA sem dois dígitos. Ela corrige o arquivo e executa:
git status
git diff
git add participantes.md
git commit -m "Corrige o RA de Ana Souza"
git push
O novo commit aparece no pull request existente. A autora responde à conversa explicando a correção e solicita outra revisão quando necessário. Abrir uma segunda proposta dividiria o contexto e obrigaria a revisora a reconstruir uma história que o primeiro pull request já conservava.
5.3 Reproduzir localmente o diff principal
Depois de atualizar as referências do repositório oficial, Ana pode aproximar localmente a comparação da aba Files changed:
git fetch upstream
git diff upstream/main...HEAD
Os três pontos pedem a diferença entre a ponta atual, HEAD, e a base de integração comum às duas linhas. Essa comparação se concentra no que a ramificação da tarefa introduziu desde a divergência. Quando a main avança muito, integrar a base recente na ramificação torna o teste mais representativo do estado que realmente receberá a mudança.
6. Integrar é escolher a forma do histórico
Uma proposta aprovada ainda precisa entrar na main. O GitHub pode oferecer três estratégias, conforme a configuração do repositório. Elas preservam o mesmo conteúdo final quando aplicadas à mesma proposta sem conflitos, mas não preservam o mesmo grafo de commits.
A Figura 3 parte de dois commits de trabalho, C e D, criados depois da base B. Cada painel mostra o que ficará alcançável a partir de main depois da integração.
Figura 3: As três estratégias podem entregar os mesmos arquivos, mas preservam granularidades e topologias diferentes no histórico oficial.
| Estratégia no GitHub | Resultado na main |
Vantagem principal | Custo principal |
|---|---|---|---|
| Create a merge commit | Preserva C e D e acrescenta um commit M com dois pais |
Conserva a fronteira explícita da ramificação e seus commits | Produz um grafo não linear e mantém commits de tentativa |
| Squash and merge | Combina o conteúdo de C e D em um novo commit S |
Gera uma unidade oficial por pull request | Não preserva na main as identidades originais de C e D |
| Rebase and merge | Recria C e D sobre a ponta da main, com novas identidades |
Mantém uma linha histórica e preserva a separação lógica dos commits | Reescreve os commits e exige disciplina quando a ramificação já foi compartilhada |
Para uma turma iniciante, squash and merge oferece um contrato simples: a ramificação pode conter commits de correção, mas a main recebe uma contribuição coerente por pull request. A mensagem final precisa resumir a mudança inteira, não o último ajuste. Essa escolha não é universal; uma equipe que investe em commits cuidadosamente revisados pode preferir rebase and merge, enquanto outra pode conservar a topologia com um merge commit.
A estratégia deve ser definida pelo repositório, não improvisada por estudante. Um histórico previsível é mais útil que uma disputa religiosa entre linhas retas e grafos.
7. Quando a main avança durante o trabalho
Enquanto Ana prepara sua contribuição, Bruno pode integrar outra linha em participantes.md. O fork de Ana e sua feature/ana-souza não se atualizam automaticamente. Há duas necessidades diferentes:
- Sincronizar a
maindo fork para que ela volte a espelhar amainoficial. - Trazer a nova
mainoficial para a ramificação aberta, quando a proposta precisa ser testada contra a base atual ou quando existe um conflito.
Já vimos a primeira:
git switch main
git fetch upstream
git merge --ff-only upstream/main
git push origin main
Para atualizar a ramificação da tarefa com uma mesclagem explícita, fazemos:
git fetch upstream
git switch feature/ana-souza
git merge upstream/main
Se Git conseguir combinar as mudanças, ele concluirá a mesclagem. Se duas linhas alterarem a mesma região de modo incompatível, ele interromperá o processo e marcará o arquivo. Um conflito não significa que o repositório foi corrompido; significa que a intenção humana é necessária para escolher o conteúdo final.
7.1 Ler as três versões de um conflito
Quando estamos em feature/ana-souza e executamos git merge upstream/main, o Git compara três estados: a base comum, a versão da ramificação atual e a versão trazida de upstream/main. No arquivo, a região pode aparecer assim:
<<<<<<< HEAD
| Ana Souza | 20261234 |
=======
| Bruno Lima | 20260001 |
>>>>>>> upstream/main
HEAD identifica o conteúdo da ramificação atual; a parte abaixo do separador veio de upstream/main. A resolução correta para uma lista de participantes não escolhe uma pessoa e apaga a outra. Ela preserva as duas linhas:
| Bruno Lima | 20260001 |
| Ana Souza | 20261234 |
Depois de editar todas as regiões, Ana verifica e conclui:
git status
git diff --check
git add participantes.md
git commit -m "Resolve conflito na lista de participantes"
git push
git diff --check ajuda a encontrar marcadores de conflito remanescentes e problemas de espaços. O push atualiza o mesmo pull request. A revisão anterior pode precisar ser refeita, pois o diff agora inclui a resolução.
7.2 O que não fazer
Não copiamos o arquivo da main por cima do arquivo da tarefa sem inspecionar o conteúdo, pois isso pode apagar o trabalho local. Também não executamos um push forçado por reflexo. Para este fluxo, integrar upstream/main, resolver e criar um novo commit preserva a história observável da correção.
Depois que o pull request for integrado, a próxima tarefa nasce de uma main sincronizada, nunca da ramificação antiga. Reutilizar feature/ana-souza mistura bases, commits e assuntos que deveriam permanecer independentes.
8. A main precisa de uma regra, não de um desejo
O professor pode proteger main com um ruleset em Settings, Rules, Rulesets. Regras clássicas de proteção de ramificação continuam existindo, mas os rulesets permitem combinar e tornar visíveis várias políticas aplicáveis.
Para o laboratório, o conjunto mínimo será:
- exigir um pull request antes da integração;
- exigir uma aprovação;
- exigir a resolução das conversas;
- bloquear force push e exclusão da
main; - exigir verificações de estado somente quando o repositório realmente possuir uma automação com nomes estáveis.
A última condição evita uma armadilha administrativa. Marcar Require status checks before merging sem possuir uma verificação válida pode bloquear todas as propostas. Uma política executável precisa nomear um teste executável.
O mantenedor também deve decidir quais estratégias de integração ficam disponíveis. Se o laboratório adotará squash and merge, desabilitar as outras opções transforma a decisão pedagógica em um contrato do repositório.
9. Laboratório: uma turma, muitos forks e uma main protegida
O laboratório usa um repositório público chamado lab-git-colaborativo. O professor cria este participantes.md:
# Participantes
| Nome | RA |
|:---|:---|
Ele protege main, habilita squash and merge e publica no README.md três critérios: uma pessoa por pull request, nenhuma alteração fora de participantes.md e um RA com oito dígitos. Como todas as estudantes acrescentarão linhas à mesma tabela, os primeiros pull requests devem integrar sem conflito e os seguintes podem exigir sincronização. Isso não é defeito do exercício. É o ponto em que a colaboração deixa de ser uma sequência individual de comandos e passa a incluir mudanças concorrentes.
1. Criar o fork, clonar e configurar os dois remotos
Crie um fork do repositório do professor, faça o clone do seu fork e configure o repositório oficial com o nome upstream. Demonstre, pelo resultado de um comando, qual URL receberá seu push e de qual URL virão as atualizações da turma.
Solução: Na página https://github.com/professor/lab-git-colaborativo, selecionamos Fork e criamos https://github.com/ana/lab-git-colaborativo. Depois, executamos:
git clone https://github.com/ana/lab-git-colaborativo.git
cd lab-git-colaborativo
git remote add upstream https://github.com/professor/lab-git-colaborativo.git
git remote -v
O resultado terá duas operações para cada apelido:
origin https://github.com/ana/lab-git-colaborativo.git (fetch)
origin https://github.com/ana/lab-git-colaborativo.git (push)
upstream https://github.com/professor/lab-git-colaborativo.git (fetch)
upstream https://github.com/professor/lab-git-colaborativo.git (push)
O fato de a tabela mostrar uma URL de push para upstream não concede permissão sobre ela; a autorização ainda será decidida pelo GitHub. Neste fluxo, enviamos nossas ramificações para origin e buscamos a versão oficial em upstream. A evidência pedida é a associação entre apelido e URL, não apenas a existência da pasta local.
2. Isolar a alteração, criar o commit e publicar a branch
Partindo da main oficial mais recente, crie feature/ana-souza, acrescente Ana Souza e o RA 20261234 a participantes.md, registre somente esse arquivo e publique a ramificação no fork. Mostre como verificar que main não avançou junto com a ramificação da tarefa.
Solução: Primeiro sincronizamos a base e somente depois criamos a ramificação:
git switch main
git fetch upstream
git merge --ff-only upstream/main
git push origin main
git switch -c feature/ana-souza
Acrescentamos a linha abaixo da separação da tabela:
| Ana Souza | 20261234 |
Em seguida, inspecionamos, preparamos e registramos:
git diff
git add participantes.md
git diff --staged
git commit -m "Adiciona Ana Souza à lista de participantes"
git push -u origin feature/ana-souza
git log --oneline --decorate --graph --all
No grafo, feature/ana-souza e origin/feature/ana-souza apontarão para o novo commit. main continuará no commit anterior, salvo se outra sincronização legítima tiver ocorrido. Essa diferença demonstra o isolamento: o conteúdo foi publicado no fork, mas ainda não foi aceito na main oficial.
3. Abrir um pull request verificável
Abra um pull request com o repositório e a ramificação de destino corretos. Escreva um título que descreva o efeito da integração e um corpo que permita reproduzir a verificação. Registre quais quatro identificadores definem a comparação.
Solução: Na página do fork, selecionamos Compare & pull request. Se o aviso não aparecer, abrimos a área de pull requests do repositório oficial e escolhemos a comparação entre forks.
Os quatro identificadores serão:
| Campo | Valor |
|---|---|
| base repository | professor/lab-git-colaborativo |
| base branch | main |
| head repository | ana/lab-git-colaborativo |
| compare branch | feature/ana-souza |
O título será Adiciona Ana Souza à lista de participantes. O corpo poderá ser:
## O que mudou
Adiciona Ana Souza e o RA 20261234 à tabela de participantes.
## Como foi verificado
- O pull request altera somente participantes.md.
- A nova linha contém duas células.
- O RA possui oito dígitos.
Antes de criar a proposta, lemos a prévia de Files changed. Ela deve mostrar uma linha adicionada e nenhuma remoção. A direção, o escopo do diff e o corpo verificável são os resultados do exercício; o botão sozinho não é.
4. Responder a uma revisão sem abrir outro pull request
Suponha que a revisora encontre o RA 2026123, com sete dígitos, e selecione Request changes. Corrija a proposta, preserve a conversa e demonstre que o mesmo pull request recebeu a atualização.
Solução: Continuamos em feature/ana-souza e corrigimos a linha para:
| Ana Souza | 20261234 |
Conferimos e publicamos:
git branch --show-current
git diff
git add participantes.md
git commit -m "Corrige o RA de Ana Souza"
git push
git branch --show-current deve responder feature/ana-souza. Como o primeiro push configurou o acompanhamento, o segundo encontra origin/feature/ana-souza sem argumentos adicionais. Na aba Commits, o mesmo pull request agora contém o commit inicial e o de correção; em Files changed, o resultado acumulado apresenta o RA com oito dígitos. Respondemos à conversa, explicamos que o valor foi corrigido e solicitamos nova revisão.
A permanência do número e da URL do pull request demonstra que não criamos outra proposta. O objeto durável é a comparação entre head e base; os commits da head podem avançar.
5. Sincronizar, resolver um conflito e limpar a tarefa
Antes da integração da proposta de Ana, o professor integra a linha | Bruno Lima | 20260001 | no mesmo ponto da tabela. Atualize a ramificação de Ana com upstream/main, preserve as duas participantes, publique a resolução e, depois da integração do pull request, sincronize a main e remova a ramificação concluída.
Solução: Buscamos a nova posição oficial e tentamos integrá-la na ramificação aberta:
git fetch upstream
git switch feature/ana-souza
git merge upstream/main
Se Git marcar o conflito, git status identificará participantes.md como não mesclado. Abrimos o arquivo e encontramos as duas alternativas. Como as duas linhas representam contribuições válidas, o conteúdo resolvido será:
# Participantes
| Nome | RA |
|:---|:---|
| Bruno Lima | 20260001 |
| Ana Souza | 20261234 |
Removemos todos os marcadores e concluímos:
git diff --check
git add participantes.md
git commit -m "Resolve conflito na lista de participantes"
git push
O mesmo pull request passa a conter a resolução e deve voltar à revisão. Depois que o professor aprovar e integrar com squash and merge, Ana atualiza sua base:
git switch main
git fetch upstream
git merge --ff-only upstream/main
git push origin main
git branch -D feature/ana-souza
git push origin --delete feature/ana-souza
O -D exige cuidado porque força a remoção da referência local. Ele é necessário neste caso específico: squash and merge criou outro commit na main, portanto os commits originais da ramificação não se tornaram ancestrais dela e o -d conservador recusaria a exclusão. Só usamos -D depois de confirmar no GitHub que o pull request foi integrado, que a main contém o resultado e que a ramificação não guarda outro trabalho. O último comando remove a referência remota da tarefa no fork. O histórico oficial permanece em main; apagar a ramificação concluída não apaga o commit produzido pelo squash. O estado final verificável possui as duas participantes na main oficial, a main do fork sincronizada e nenhuma ramificação de tarefa ainda aberta.
10. Um protocolo curto para o próximo trabalho
O fluxo inteiro pode ser lembrado como uma sequência de decisões, não como uma reza de terminal:
- Atualizar a base: buscar
upstream/main, avançar amainlocal e publicar a atualização emorigin/main. - Isolar uma intenção: criar uma ramificação curta a partir da base atual.
- Registrar com critério: ler o diff, preparar apenas o escopo da tarefa e criar commits explicáveis.
- Publicar sem integrar: enviar a ramificação ao próprio fork.
- Propor na direção correta: escolher a
mainoficial como base e a ramificação do fork como head. - Revisar e corrigir no mesmo lugar: usar comentários, novos commits, verificações e aprovação no mesmo pull request.
- Integrar segundo o contrato: aplicar a estratégia habilitada pelo repositório.
- Fechar o ciclo: sincronizar a
maine remover a ramificação da tarefa.
No artigo anterior, o pull request aparecia como a porta pela qual uma alteração alcançava o GitHub Pages. Agora sabemos o que existe de cada lado dessa porta. Há dois repositórios remotos, um repositório local, vários ponteiros e uma comparação que permanece aberta enquanto a conversa amadurece a mudança.
Trabalhar em equipe com Git não significa evitar divergências. Significa dar nome, fronteira e revisão a cada divergência antes que ela se torne a versão oficial.
Referências
CHACON, Scott; STRAUB, Ben. Pro Git: branches in a nutshell. 2. ed. Apress, 2014. Disponível em: https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell. Acesso em: 30 ago. 2026.
GIT. git-branch documentation. Disponível em: https://git-scm.com/docs/git-branch. Acesso em: 30 ago. 2026.
GITHUB. About merge methods on GitHub. GitHub Docs. Disponível em: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/about-merge-methods-on-github. Acesso em: 30 ago. 2026.
GITHUB. About protected branches. GitHub Docs. Disponível em: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches. Acesso em: 30 ago. 2026.
GITHUB. About rulesets. GitHub Docs. Disponível em: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets. Acesso em: 30 ago. 2026.
GITHUB. Branches. GitHub Docs. Disponível em: https://docs.github.com/en/pull-requests/reference/branches. Acesso em: 30 ago. 2026.
GITHUB. Creating a pull request from a fork. GitHub Docs. Disponível em: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork. Acesso em: 30 ago. 2026.
GITHUB. Merge conflicts. GitHub Docs. Disponível em: https://docs.github.com/en/pull-requests/reference/merge-conflicts. Acesso em: 30 ago. 2026.
GITHUB. Pull request reviews. GitHub Docs. Disponível em: https://docs.github.com/en/pull-requests/reference/pull-request-reviews. Acesso em: 30 ago. 2026.
GITHUB. Pull requests. GitHub Docs. Disponível em: https://docs.github.com/en/pull-requests/reference/pull-requests. Acesso em: 30 ago. 2026.
GITHUB. Syncing a fork. GitHub Docs. Disponível em: https://docs.github.com/en/pull-requests/how-tos/work-with-forks/syncing-a-fork. Acesso em: 30 ago. 2026.
(Updated: )