O Refspec
Ao longo deste livro, você usou um simples mapeamento de branches remotos para referências locais; mas eles podem ser mais complexos. Suponha que você adicione um remoto como este:
$ git remote add origin [email protected]:schacon/simplegit-progit.git
Ele adiciona uma seção em seu arquivo .git/config
, especificando o nome do remoto (origin
), a URL do repositório remoto, e o refspec a ser buscado:
[remote "origin"]
url = [email protected]:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
O formato do refspec é um +
opcional, seguido por <src>:<dst>
, onde <src>
é o padrão para referências no lado remoto e <dst>
é onde essas referências serão escritas localmente. O +
diz ao Git para atualizar a referência, mesmo que não seja um fast-forward.
No caso padrão que é automaticamente escrito por um comando git remote add
, Git busca todas as referências em refs/heads/
no servidor e grava-os em refs/remotes/origin/
localmente. Então, se há um branch master
no servidor, você pode acessar o log desse branch localmente através de
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
Eles são todos equivalentes, porque Git expande cada um deles em refs/remotes/origin/master
.
Se você quiser que o Git só faça o pull do branch master
toda vez, e não qualquer outro branch do servidor remoto, você pode alterar a linha fetch para
fetch = +refs/heads/master:refs/remotes/origin/master
Este é apenas o refspec padrão do git fetch
para esse remoto. Se você quiser fazer algo apenas uma vez, você pode especificar o refspec na linha de comando também. Para fazer o pull do branch master
do remoto até origin/mymaster
localmente, você pode executar
$ git fetch origin master:refs/remotes/origin/mymaster
Você também pode especificar múltiplos refspecs. Na linha de comando, você pode fazer pull de vários branches assim:
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic
From [email protected]:schacon/simplegit
! [rejected] master -> origin/mymaster (non fast forward)
* [new branch] topic -> origin/topic
Neste caso, o pull do branch master foi rejeitado, porque não era uma referência fast-forward. Você pode evitar isso especificando o +
na frente do refspec.
Você também pode especificar múltiplos refspecs em seu arquivo de configuração. Se você quer sempre buscar os branches master e experiment, adicione duas linhas:
[remote "origin"]
url = [email protected]:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
Você não pode usar globs parciais no padrão, então isto seria inválido:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
No entanto, você pode usar namespacing para realizar algo assim. Se você tem uma equipe de QA que faz push de uma série de branches, e você deseja obter o branch master e qualquer um dos branches da equipe de QA, mas nada mais, você pode usar uma seção de configuração como esta:
[remote "origin"]
url = [email protected]:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
Se você tem um fluxo de trabalho complexo que tem uma equipe de QA fazendo push de branches, desenvolvedores fazendo push de branches, e equipes de integração fazendo push e colaborando em branches remotos, você pode nomeá-los (namespace) facilmente desta forma.
Fazendo Push de Refspecs
É legal que você possa buscar referências nomeadas dessa maneira, mas como é que a equipe de QA obtêm os seus branches em um namespace qa/
? Você consegue fazer isso utilizando refspecs para fazer o push.
Se a equipe de QA quer fazer push de seu branch master
em qa/master
no servidor remoto, eles podem executar
$ git push origin master:refs/heads/qa/master
Se eles querem que o Git faça isso automaticamente toda vez que executar git push origin
, eles podem adicionar o valor push
ao seu arquivo de configuração:
[remote "origin"]
url = [email protected]:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
Novamente, isso vai fazer com que git push origin
faça um push do branch master
local para o branch remoto qa/master
por padrão.
Deletando Referencias
Você também pode usar o refspec para apagar referências do servidor remoto executando algo como isto:
$ git push origin :topic
Já que o refspec é <src>:<dst>
, ao remover <src>
, basicamente diz para enviar nada para o branch tópico no remoto, o que o exclui.