Git Fetch Pull Request: proficiência desbloqueada
Nicola Paolucci
Representante do desenvolvedor
Hoje em dia, aplicar uma correção a um projeto é tão fácil quanto criar uma bifurcação (que evoca uma cópia remota completa do projeto para você hackear): é só selecionar o arquivo que você quer alterar, pressionar Editar e fazer o commit das correções.
E se você for quem recebe uma pull request (a partir daqui, PR)? Usar uma interface de usuário da web polida é ótimo e costuma ser tudo de que você precisa. Clique em um botão para aprovar, clique em um botão para fazer o merge e pronto.
Mas nem sempre esse é o caso! É comum ter que baixar as alterações incluídas em uma pull request (PR) localmente, executar alguns testes e ver como elas ficam no IDE para entender o que foi feito.
As etapas para fazer o download — para ser mais explícito: fazer o fetch
e o checkout
— das pull requests de seu colega ou colaborador são conceitualmente simples, mas se tornam ainda mais fáceis se você conhecer algumas informações e dicas importantes.
Então, deixe-me guiá-lo para uma melhor compreensão dos recursos de linha de comando que o git
oferece para lidar com pull requests da linha de comando com facilidade.
Antes de começar: enriquecer o prompt do shell com o nome e o status do branch
Sempre fico surpreso com quantas pessoas têm um prompt de comando simples que não mostra o branch do git
em que estão ou se têm arquivos modificados ou sem commit no diretório de trabalho. Se você pensou "Ei, sou eu!", permita que eu ajude você e o deixe de queixo caído ao mesmo tempo!
Faça um favor a si mesmo e instale algo parecido com o incrível Liquid Prompt, que mostra excelentes anotações sobre o status do seu diretório de trabalho git
(e também vai ser compatível com qualquer outro VCS):
(Na captura de tela acima, você vê meu prompt alertando que estou no branch newbranch
, adicionei 5
linhas aos arquivos que rastreio no meu diretório de trabalho e removi 0
)
Material relacionado
Instalar o Git
VER SOLUÇÃO
Aprenda a usar o Git com o Bitbucket Cloud
Todos trabalhando no mesmo repositório
Se você trabalha no mesmo repositório que sua equipe, o processo de check out de uma pull request é muito simples: basta fazer o fetch
e o checkout
o branch do qual a pull request foi criada:
- Obtenha todos os branches que foram publicados no seu repositório compartilhado:
git fetch origin
- Crie um branch local que rastreie o branch remoto em que você tem interesse:
git checkout -b PRJ-1234 origin/PRJ-1234
- Agora você pode fazer
diff
,merge
e testar o que quiser assim:
git diff main ./run-tests.sh
- Quando estiver satisfeito, volte para a IU da web e dê feedback ou aprove a alteração na hora.
Colaboradores trabalhando em suas próprias bifurcações
O processo muda um pouco quando alguns dos colaboradores trabalham em bifurcações separadas. Nesse caso, você pode fazer o fetch
do branch remoto em que houve o commit da função ou da contribuição:
- Adicione o branch remoto do colaborador primeiro:
git remote add jsmith http://bitbucket.org/jsmith/coolproject.git
- Colete todas as atualizações mais recentes do
origin
primeiro, seu repositório principal:
git checkout main git fetch origin git merge main
- Obtenha todos os branches que foram publicados na bifurcação do colaborador:
git fetch jsmith
- Crie um branch local que rastreie o branch remoto em que você tem interesse:
git checkout -b jsmith-PRJ-1234 jsmith/PRJ-1234
- Agora você pode fazer
diff
,merge
e testar o que quiser assim:
git diff main ./run-tests.sh
Reduzir o trabalho usando refs de pull request
A estratégia acima funciona, mas várias coisas podem dificultar sua vida:
- E se você tiver muitos colaboradores, cada um com suas próprias bifurcações? Adicionar todas as bifurcações e lidar com elas em separado se torna impraticável.
- E se você nem mesmo tiver acesso a algumas das bifurcações e não puder fazer o checkout do branch de origem?
A solução para ambos os problemas acima é usar refs de pull requests que alguns servidores git oferecem. O procedimento que vou mostrar é compatível com alguns servidores git
e varia um pouco dependendo do que você usa. A seguir, vou mostrar como efetuar o fetch
de todas as pull requests no Stash (agora chamado de Bitbucket Data Center) e no GitHub.
Não tenha medo das Refspecs
O primeiro pré-requisito é conhecer as Refspecs. Refspecs são legais e você não deve ter medo delas. São mapeamentos simples de branches remotos para referências locais. Em outras palavras, uma maneira direta de dizer ao git
que "tal branch remoto (ou tal conjunto de branches remotos), deve ser mapeado para tais nomes no local, em tal espaço de nome".
Por exemplo, um comando como:
git fetch +refs/heads/main:refs/remotes/origin/main
Vai mapear o branch remoto main
no branch remoto origin
para um origin/main
local, então você pode digitar:
git checkout origin/main
E ainda fazer referência a esse branch remoto. O sinal de mais (+
) na definição está lá para indicar que a gente quer que o git
atualize a referência mesmo que ela não seja rápida.
Esse comando é usado para baixar todas as pull requests pelo mapeamento de como o repositório remoto armazena os HEADs de PR e pelo mapeamento deles para um espaço de nome local para facilitar a referência.
Portanto, desde que você tenha um branch remoto origin
(ou upstream
) definido, veja a seguir o que fazer.
Observação: como já destacado por vários desenvolvedores do Stash (agora chamado de Bitbucket Data Center), as referências que vou demonstrar abaixo são consideradas não documentadas
e privadas
e podem ser alteradas a qualquer momento.
Baixar todas as pull requests: Stash
- Bifurque um repositório.
- Clone a bifurcação no local:
git clone git@stash.atlassian.com:durdn/tis.git
- Adicione o repositório original upstream como
upstream
.
git remote add upstream git@stash.atlassian.com:tpettersen/tis.git
- Obtenha os heads mais recentes do mantenedor "upstream"
git fetch upstream
- Adicione a
refspec
que vai mapear os heads de pull requests remotos para um espaço de nome depr
local. Você pode usar um comandoconfig
:
git config --add remote.origin.fetch '+refs/pull-requests/*/from:refs/remotes/origin/pr/*'
- Se você olhar em
.git/config
, as entradas defetch
passam a ser:
[remote "upstream"]
url = git@stash.atlassian.com:docker/libswarm.git
fetch = +refs/heads/*:refs/remotes/upstream/*
fetch = +refs/pull-requests/*/from:refs/remotes/upstream/pr/*
- Agora ficou fácil fazer o
fetch
de todos os branches de pull requests:
$ git fetch upstream
remote: Counting objects: 417, done.
remote: Compressing objects: 100% (274/274), done.
remote: Total 417 (delta 226), reused 277 (delta 128)
Receiving objects: 100% (417/417), 105.28 KiB | 0 bytes/s, done.
Resolving deltas: 100% (226/226), done.
From stash.atlassian.com:docker/libswarm
* [new ref] refs/pull-requests/10/from-> upstream/pr/10
[...]
* [new ref] refs/pull-requests/100/from -> upstream/pr/100
* [new ref] refs/pull-requests/101/from -> upstream/pr/101
[...]
* [new ref] refs/pull-requests/109/from -> upstream/pr/109
* [new ref] refs/pull-requests/110/from -> upstream/pr/110
[...]
- Agora, para mudar para uma pull request específica, é só fazer assim:
git checkout pr/102
Baixar todas as pull requests: GitHub
Se as bifurcações ou upstreams estiverem no GitHub, ele vai funcionar exatamente como mostrado acima, mas o comando config
muda para:
git config --add remote.origin.fetch '+refs/pull//head:refs/remotes/origin/pr/'
E o remoto em .git/config
vai mudar para incluir uma configuração de fetch
adicional para mapear os heads de PR para um espaço de nome local chamado pr
:
[remote "upstream"] url = git@github.com:docker/libswarm.git fetch = +refs/heads/*:refs/remotes/upstream/* fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*
Fetch de uma única pull request usando refs
Se você não quiser configurar as entradas de fetch
em .git/config
e só quiser chegar logo a uma pull request, pode usar um único comando:
- Confira uma única PR no Stash:
git fetch refs/pull-requests/your-pr-number/from:local-branch-name
- Confira uma única PR no GitHub:
git fetch refs/pull/your-pr-number/head:local-branch-name
E se você estiver usando muito o comando acima, você pode agilizar o processo criando um git
alias:
# For Stash
git config alias.spr '!sh -c "git fetch origin pull-requests/${1}/from:pr/${1}" -'
# For Github
git config alias.gpr '!sh -c "git fetch origin pull/${1}/head:pr/${1}" -'
Com esse alias configurado, é possível fazer o fetch de uma pull request com este comando simples (obrigado, Inuits):
Conclusão
Controlar o trabalho de colegas ou colaboradores é fácil quando você cria alguns aliases simples ou adiciona as refspecs adequadas ao .git/config
.
Compartilhar este artigo
Próximo tópico
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.