Chapters ▾ 2nd Edition

2.5 Fundamentos do Git - Trabalhando com Repositórios Remotos

Trabalhando com Repositórios Remotos

Para poder colaborar em qualquer projeto Git, você precisa saber como gerenciar seus repositórios remotos. Repositórios remotos são versões do seu projeto que estão hospedadas na Internet ou em algum lugar da rede. Você pode ter vários deles, cada um geralmente sendo somente leitura ou leitura/gravação para você. Colaborar com outras pessoas envolve gerenciar esses repositórios remotos e enviar (push) e extrair (pull) dados de e para eles quando você precisa compartilhar o trabalho. O gerenciamento de repositórios remotos inclui saber como adicionar repositórios remotos, remover remotos que não são mais válidos, gerenciar várias branches remotas e defini-las como sendo rastreadas (tracked) ou não e muito mais. Nesta seção, abordaremos algumas dessas habilidades de gerenciamento de remotos.

Note
Repositórios remotos podem estar na sua máquina local.

É inteiramente possível que você esteja trabalhando com um repositório “remoto” que, de fato, esteja no mesmo host que você. A palavra “remoto” não implica necessariamente que o repositório esteja em outro lugar na rede ou na Internet, apenas que está em outro lugar. Trabalhar com um repositório remoto assim ainda envolveria todas as operações padrão de push, pull e fetch, como em qualquer outro remoto.

Mostrando seus Remotos

Para ver quais servidores remotos você configurou, você pode executar o comando git remote. Ele lista os nomes curtos (shortnames) de cada handle remoto que você especificou. Se você clonou seu repositório, você deve pelo menos ver origin — esse é o nome padrão que o Git dá ao servidor do qual você clonou:

$ git clone https://github.com/schacon/ticgit
Cloning into 'ticgit'...
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity... done.
$ cd ticgit
$ git remote
origin

Você também pode especificar -v, que mostra as URLs que o Git armazenou para o nome curto (shortname) a ser usado ao ler e gravar nesse remoto:

$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)

Se você tiver mais de um remoto, o comando lista todos eles. Por exemplo, um repositório com vários remotos para trabalhar com vários colaboradores pode ser parecido com isto.

$ cd grit
$ git remote -v
bakkdoor  https://github.com/bakkdoor/grit (fetch)
bakkdoor  https://github.com/bakkdoor/grit (push)
cho45     https://github.com/cho45/grit (fetch)
cho45     https://github.com/cho45/grit (push)
defunkt   https://github.com/defunkt/grit (fetch)
defunkt   https://github.com/defunkt/grit (push)
koke      git://github.com/koke/grit.git (fetch)
koke      git://github.com/koke/grit.git (push)
origin    git@github.com:mojombo/grit.git (fetch)
origin    git@github.com:mojombo/grit.git (push)

Isso significa que podemos extrair (pull) contribuições de qualquer um desses usuários com bastante facilidade. Adicionalmente, podemos ter permissão para enviar (push) para um ou mais deles, embora não possamos dizer isso aqui.

Observe que esses remotos usam uma variedade de protocolos; cobriremos mais sobre isso em Colocando o Git em um Servidor.

Adicionando Repositórios Remotos

Mencionamos e demonstramos como o comando git clone adiciona implicitamente o remoto origin para você. Veja como adicionar um novo remoto explicitamente. Para adicionar um novo repositório Git remoto como um nome curto (shortname) que você pode referenciar facilmente, execute git remote add <shortname> <url>:

$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)
pb	https://github.com/paulboone/ticgit (fetch)
pb	https://github.com/paulboone/ticgit (push)

Agora você pode usar a string pb na linha de comando em vez da URL inteira. Por exemplo, se você quiser buscar (fetch) todas as informações que Paul tem, mas que você ainda não tem em seu repositório, você pode executar git fetch pb:

$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
 * [new branch]      master     -> pb/master
 * [new branch]      ticgit     -> pb/ticgit

O branch master de Paul agora está acessível localmente como pb/master — você pode mesclá-lo (merge) em um dos seus branches, ou você pode fazer checkout em um branch local naquele ponto se quiser inspecioná-lo. Veremos o que são branches e como usá-los com muito mais detalhes em Ramificação (Branching) no Git.

Buscando (fetching) e Extraindo (pulling) de Seus Remotos

Como você acabou de ver, para obter dados de seus projetos remotos, você pode executar:

$ git fetch <remote>

O comando vai para aquele projeto remoto e puxa (pulls down) todos os dados daquele projeto remoto que você ainda não tem. Depois de fazer isso, você deve ter referências para todos os branches daquele remoto, os quais você pode mesclar (merge) ou inspecionar a qualquer momento.

Se você clonar um repositório, o comando adicionará automaticamente esse repositório remoto com o nome “origin”. Portanto, git fetch origin busca (fetches) qualquer trabalho novo que tenha sido enviado (pushed) para aquele servidor desde que você o clonou (ou buscou dele pela última vez). É importante observar que o comando git fetch apenas baixa os dados para o seu repositório local — ele não os mescla (merge) automaticamente com nenhum de seus trabalhos, nem modifica o que você está trabalhando no momento. Você deve mesclá-lo manualmente em seu trabalho quando estiver pronto.

Se o seu branch atual estiver configurado para rastrear um branch remoto (consulte a próxima seção e Ramificação (Branching) no Git para obter mais informações), você poderá usar o comando git pull para buscar (fetch) e, em seguida, mesclar (merge) automaticamente aquele branch remoto em seu branch atual. Esse pode ser um fluxo de trabalho mais fácil ou mais confortável para você; e, por padrão, o comando git clone configura automaticamente seu branch master local para rastrear o branch master remoto (ou qualquer que seja o nome do branch padrão) no servidor de onde você clonou. A execução do git pull geralmente busca (fetches) dados do servidor do qual você clonou originalmente e tenta mesclá-los (merge) automaticamente no código em que você está trabalhando no momento.

Note

A partir do Git versão 2.27, o git pull emitirá um aviso se a variável pull.rebase não estiver definida. O Git continuará avisando você até que você defina a variável.

Se você quiser o comportamento padrão do Git (fast-forward se possível, caso contrário crie um commit de mesclagem (merge commit)): git config --global pull.rebase "false"

Se você quiser fazer rebase ao extrair (pulling): git config --global pull.rebase "true"

Enviando (pushing) para seus Remotos

Quando você tiver seu projeto em um ponto que deseja compartilhar, você deve enviá-lo (push) para upstream. O comando para isso é simples: git push <remote> <branch>. Se você quiser enviar (push) seu branch master para o seu servidor origin (novamente, a clonagem geralmente configura ambos os nomes para você automaticamente), você pode executar isso para enviar todos os commits que você fez de volta para o servidor:

$ git push origin master

Este comando funciona apenas se você clonou de um servidor no qual você tem acesso de gravação e se ninguém fez o push nesse meio tempo. Se você e outra pessoa clonarem ao mesmo tempo, e ela enviar (push) para upstream e depois você enviar (push) para upstream, o seu push será corretamente rejeitado. Você terá que buscar (fetch) o trabalho deles primeiro e incorporá-lo ao seu antes de ter permissão para fazer o push. Consulte Ramificação (Branching) no Git para obter informações mais detalhadas sobre como fazer push para servidores remotos.

Inspecionando um Remoto

Se você quiser ver mais informações sobre um remoto específico, você pode usar o comando git remote show <remote>. Se você executar este comando com um nome curto (shortname) específico, como origin, você obterá algo assim:

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

Ele lista a URL para o repositório remoto, bem como as informações do branch de rastreamento (tracking branch). O comando informa utilmente que se você estiver no branch master e executar git pull, ele mesclará (merge) automaticamente o branch master do remoto no local depois de ser buscado (fetched). Ele também lista todas as referências remotas que puxou (pulled down).

Esse é um exemplo simples que você provavelmente encontrará. Quando você estiver usando o Git de forma mais intensa, no entanto, poderá ver muito mais informações do git remote show:

$ git remote show origin
* remote origin
  URL: https://github.com/my-org/complex-project
  Fetch URL: https://github.com/my-org/complex-project
  Push  URL: https://github.com/my-org/complex-project
  HEAD branch: master
  Remote branches:
    master                           tracked
    dev-branch                       tracked
    markdown-strip                   tracked
    issue-43                         new (next fetch will store in remotes/origin)
    issue-45                         new (next fetch will store in remotes/origin)
    refs/remotes/origin/issue-11     stale (use 'git remote prune' to remove)
  Local branches configured for 'git pull':
    dev-branch merges with remote dev-branch
    master     merges with remote master
  Local refs configured for 'git push':
    dev-branch                     pushes to dev-branch                     (up to date)
    markdown-strip                 pushes to markdown-strip                 (up to date)
    master                         pushes to master                         (up to date)

Este comando mostra para qual branch o envio é feito automaticamente quando você executa git push enquanto está em certos branches. Ele também mostra quais branches remotos no servidor você ainda não tem, quais branches remotos você tem que foram removidos do servidor e vários branches locais que podem ser mesclados automaticamente com seus branches de rastreamento remotos (remote-tracking branch) quando você executa git pull.

Renomeando e Removendo Remotos

Você pode executar git remote rename para alterar o nome curto (shortname) de um remoto. Por exemplo, se você quiser renomear pb para paul, você pode fazê-lo com git remote rename:

$ git remote rename pb paul
$ git remote
origin
paul

Vale a pena mencionar que isso também altera todos os nomes dos seus branches de rastreamento remoto (remote-tracking branch). O que costumava ser referenciado em pb/master agora está em paul/master.

Se você quiser remover um remoto por algum motivo — você mudou de servidor ou não está mais usando um espelho (mirror) específico, ou talvez um colaborador não esteja mais contribuindo — você pode usar git remote remove ou git remote rm:

$ git remote remove paul
$ git remote
origin

Depois de excluir a referência a um remoto dessa maneira, todos os branches de rastreamento remoto (remote-tracking branches) e definições de configuração associados a esse remoto também serão excluídos.