Skip to content
This page has been auto-translated and may contain errors.View in English

Remotes e GitHub ​

docs.scrimba.com

Até agora, todo repositório deste manual viveu em um único lugar: a sua própria máquina. Isso funciona bem até o momento em que você quer um backup que sobreviva à morte do seu notebook, quer continuar o projeto a partir de um segundo computador, ou quer que outra pessoa também toque no código. Nesse momento você precisa de uma cópia do repositório em algum lugar que todas as máquinas envolvidas consigam acessar. Essa cópia se chama remote, e é no GitHub que a maioria dos desenvolvedores a coloca.

O que é um remote (e onde o GitHub entra nisso) ​

Um remote é uma cópia do seu repositório hospedada em algum lugar que não seja a sua própria máquina, geralmente no GitHub. Quando você clona um repositório, o Git já configura um para você, chamado origin por padrão. Execute git remote -v (o -v pede também as URLs, além dos nomes) para ver isso:

bash
$ git remote -v
origin  https://github.com/mara-chen/weather-app.git (fetch)
origin  https://github.com/mara-chen/weather-app.git (push)

Todo remote que o Git conhece aparece listado duas vezes, uma para fetch e outra para push, porque, em teoria, os dois poderiam apontar para endereços diferentes. Na prática, quase sempre são o mesmo. origin é o apelido que o Git atribui automaticamente ao clonar. Você pode renomeá-lo ou adicionar um segundo remote apontando para outro lugar, mas quase todo projeto que você tocar vai chamar seu remote principal de origin.

Este é um bom momento para reforçar a distinção que confunde quase todo mundo no início: Git e GitHub não são a mesma coisa. O Git é a ferramenta de controle de versão que roda na sua máquina, registrando commits esteja você conectado a algo ou não. O GitHub é um site que hospeda uma cópia do seu repositório e te dá um remote para o qual enviar (push) e do qual baixar (pull). git remote, git push e git pull são os comandos que ligam os dois: são como o Git rodando no seu notebook conversa com um repositório que está nos servidores do GitHub.

Um remote nada mais é do que um nome mapeado para uma URL, guardado na configuração do seu repositório. Junto com ele, o Git mantém um remote-tracking branch: um marcador local que registra onde uma branch daquele remote estava na última vez que sua máquina conferiu. origin/main é exatamente isso. Não é a branch main de fato, sentada no GitHub. É a memória do seu repositório sobre onde estava a main do GitHub na última vez que você fez um fetch ou pull. Liste os remote-tracking branches que o Git mantém atualmente com git branch -r:

bash
$ git branch -r
origin/main

Tudo o que um remote faz passa por essa entrada de configuração mais esses marcadores de rastreamento. Não existe nenhuma conexão em segundo plano, nem nada observando mudanças. O Git só atualiza sua imagem do remote quando você pede, com fetch ou pull, que é justamente o que o restante deste capítulo aborda.

JunoO que é um remote Um remote é uma cópia do seu repositório hospedada em outro lugar, geralmente no GitHub, e o Git chama o remote padrão de origin. Execute git remote -v a qualquer momento para ver quais remotes o seu repositório conhece. Git e GitHub não são a mesma coisa: o Git é a ferramenta na sua máquina, o GitHub é onde o seu remote costuma morar. Deixar essa distinção clara desde já evita muita confusão depois.
JunoO que é um remoteorigin é só o nome padrão que o Git dá ao remote que ele configura ao clonar, então você pode renomeá-lo ou adicionar mais remotes quando um projeto precisar. git remote -v mostra a URL de cada remote, tanto para fetch quanto para push. Tenha em mente a distinção entre Git e GitHub: os comandos que você executa localmente são do Git, e o GitHub é apenas um dos destinos possíveis que esses comandos podem alcançar.
JunoO que é um remote Um remote é um nome mapeado para uma URL na sua configuração, associado a remote-tracking branches como origin/main, a memória da sua máquina sobre onde essa branch estava no último fetch ou pull. Nada se atualiza por conta própria; o Git só verifica o remote quando você pede. Essa diferença entre o que o GitHub realmente tem e o que o seu remote-tracking branch lembra é a causa de quase toda surpresa envolvendo fetch versus pull.

Onde hospedar seu remote: GitHub e as alternativas ​

Tudo o que um remote faz é puro Git, e isso tem uma consequência que vale conhecer desde já: o host do outro lado é intercambiável. Para o Git, todo host é apenas uma URL na sua configuração, e git push, git pull e git fetch se comportam de forma idêntica em qualquer um deles. O que um host acrescenta fica em uma camada acima: uma visualização web do seu código, um fluxo de revisão, controle de issues e controle de acesso. Aqui está o panorama, com as vantagens e desvantagens ditas sem rodeios:

  • GitHub é, de longe, o maior e hospeda a grande maioria dos projetos open-source. Sua força é a rede: os projetos aos quais você quer contribuir já estão lá, os tutoriais partem do pressuposto de que você o usa, e empregadores procuram seu perfil nele. A contrapartida é que se trata de uma plataforma fechada (de propriedade da Microsoft), e quanto mais você depende dos recursos extras dele além da hospedagem Git, mais amarrado a ele você fica.
  • GitLab é a alternativa completa mais próxima, com os mesmos recursos principais sob nomes ligeiramente diferentes (os pull requests lá se chamam "merge requests"). Seu grande diferencial é uma versão auto-hospedada que você pode rodar nos seus próprios servidores, motivo pelo qual empresas que mantêm o código internamente costumam escolhê-lo. A contrapartida é que ele vem com muita coisa embutida, e a plataforma pode parecer mais pesada do que a simples hospedagem de código que você buscava.
  • Bitbucket é o host da Atlassian, feito para funcionar junto com suas ferramentas de acompanhamento de projetos e documentação, o Jira e o Confluence. Se sua equipe já vive nessas ferramentas, ele se encaixa perfeitamente. Fora desse ecossistema, é o que tem a menor comunidade dos três grandes e pouca presença no mundo open-source.
  • Codeberg é um host sem fins lucrativos para projetos open-source, rodando sobre a plataforma open-source Forgejo. O atrativo é que nenhuma empresa é dona do seu host, e a própria plataforma é open-source. A contrapartida é a escala: menos integrações, uma comunidade menor e um foco em open-source em vez de trabalho privado de equipe.
  • Auto-hospedagem está na base de todas essas opções: você pode rodar o Forgejo ou o Gitea, ambos gratuitos e open-source, ou a versão auto-hospedada do GitLab, em hardware controlado por você. Você ganha controle total e privacidade; a contrapartida é que manter tudo funcionando passa a ser tarefa sua.

Este manual usa o GitHub nos exemplos porque ele hospeda a maior parte dos projetos open-source e é onde você provavelmente vai colaborar por primeiro. Todo comando deste capítulo funciona sem alteração em qualquer outro host: troque a URL e o fluxo diário permanece o mesmo. As diferenças ficam uma camada acima, na interface web de cada site para revisar e mesclar (merge) trabalho, que é justamente o assunto do fluxo de pull request do próximo capítulo.

Quando a escolha é sua, raramente ela gira em torno de recursos do Git, já que o conjunto básico (repositórios hospedados, revisões, issues, pipelines de CI) existe em todos eles. Tudo se reduz ao contexto: contribuir com open-source ou construir um perfil público aponta para o GitHub; uma empresa que já roda em ferramentas da Atlassian aponta para o Bitbucket; código que precisa ficar na sua própria infraestrutura aponta para o GitLab auto-hospedado ou para o Forgejo; e um projeto open-source movido por valores pode se sentir mais em casa no Codeberg. A escolha também não é definitiva. Mover o repositório em si entre hosts é só um git remote set-url mais um push; a parte cara de uma migração é a camada acima do Git, as issues, wikis e configurações de CI, que não viajam junto com os commits.

A auto-hospedagem merece uma análise sem ilusões antes de você se comprometer com ela. O Forgejo e o Gitea rodam sem problemas em um servidor pequeno, mas a carga operacional é real: atualizações de segurança, backups tanto dos repositórios quanto do banco de dados da própria plataforma, gerenciamento de contas e chaves SSH, e disponibilidade, porque um forge fora do ar bloqueia todo push e pull da sua equipe. Ela se justifica quando regras de compliance impedem que o código saia de uma infraestrutura própria, em ambientes isolados (air-gapped), ou quando uma organização quer manter suas ferramentas sob seu próprio controle. Abaixo da camada web nada muda: todos esses hosts falam o mesmo protocolo Git, motivo pelo qual seu push e seu fetch não conseguem distingui-los.

JunoOnde hospedar seu remote O GitHub é onde a maioria dos projetos vive e a opção padrão mais segura para quem está começando, mas é apenas um host entre vários: GitLab, Bitbucket e o Codeberg (sem fins lucrativos) armazenam os mesmos repositórios Git. Push e pull funcionam do mesmo jeito onde quer que o remote esteja, então nada do que você aprende aqui se perde se um projeto morar em outro lugar.
JunoOnde hospedar seu remote Os hosts se diferenciam numa camada acima do Git: o GitLab chama pull requests de merge requests e oferece uma versão auto-hospedada, o Bitbucket se conecta às ferramentas da Atlassian, e o Codeberg roda sobre o Forgejo, que é open-source. Escolha com base em onde seus colaboradores e ferramentas já estão, e lembre-se de que trocar de host depois é barato do lado do Git; o que não viaja são as issues e a CI.
JunoOnde hospedar seu remote Como um remote é um nome mapeado para uma URL, mover um projeto de um host para outro é só git remote set-url mais um push. Auto-hospedar Forgejo ou Gitea te dá controle e privacidade e custa em forma de patches, backups e disponibilidade; assuma essa troca quando a política exigir, não por diversão, diz quem já carregou o pager por um deles. Tudo que é específico de host fica na camada web, acima do protocolo Git.

Enviando e buscando seu trabalho: git push e git pull ​

Com um remote configurado, dois comandos cobrem a maior parte do trabalho do dia a dia. git push envia seus commits locais para o remote. git pull traz commits feitos em outro lugar e os mescla na branch em que você está.

bash
$ git push origin main
Enumerating objects: 5, done.
Writing objects: 100% (3/3), 312 bytes | 312.00 KiB/s, done.
To https://github.com/mara-chen/weather-app.git
   9f8e7d6..a1b2c3d  main -> main

origin é o remote, main é a branch que você está enviando. Aquela última linha é a parte que vale a pena ler: ela mostra a main no remote avançando de um commit para o próximo.

Fazer pull funciona do mesmo jeito, ao contrário:

bash
$ git pull origin main
remote: Enumerating objects: 4, done.
Unpacking objects: 100% (4/4), done.
Updating a1b2c3d..b7c9e21
Fast-forward
 src/index.js | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

Esse é o ciclo completo para trabalhar junto com outras pessoas em um projeto: baixe (pull) o que mudou antes de começar, faça seu próprio trabalho e comite, envie (push) de volta. Faça pull antes de fazer push sempre que compartilhar uma branch com outra pessoa. Pule o pull e o seu push pode acabar sobrepondo commits que você nunca viu, coisa que o Git vai recusar em vez de arriscar perder o trabalho de alguém.

Na primeira vez que você enviar uma branch nova, adicione -u (abreviação de --set-upstream):

bash
$ git push -u origin feature/add-forecast-icons
Enumerating objects: 5, done.
Writing objects: 100% (5/5), 412 bytes | 412.00 KiB/s, done.
To https://github.com/mara-chen/weather-app.git
 * [new branch]      feature/add-forecast-icons -> feature/add-forecast-icons
branch 'feature/add-forecast-icons' set up to track 'origin/feature/add-forecast-icons'.

Isso registra feature/add-forecast-icons como rastreando origin/feature/add-forecast-icons, uma ligação chamada upstream. Uma vez configurada, todo push e pull seguinte pode omitir o nome do remote e da branch e simplesmente rodar git push ou git pull na branch. Se uma branch ainda não tiver upstream configurado, o Git avisa e mostra o comando exato para resolver isso, então raramente você precisa memorizar a flag, só reconhecer a mensagem quando ela aparecer.

Essa ligação de upstream existe como duas linhas simples escritas na configuração do seu repositório no momento em que o -u é executado: branch.feature/add-forecast-icons.remote nomeia o remote, branch.feature/add-forecast-icons.merge nomeia a branch nele. Execute git config --get branch.main.remote em uma branch que você já enviou antes e vai ver exatamente esse valor voltar. Essas duas linhas também são o que o git status lê para te dizer que sua branch está dois commits adiante de origin/main, ou que as duas se distanciaram: a comparação roda inteiramente contra o seu remote-tracking branch, uma verificação local sem nada buscado no GitHub. Configure o upstream uma vez, e toda contagem de "adiante/atrás" que o Git te mostrar depois estará lendo esse mesmo par de linhas de configuração.

JunoEnviando e buscando seu trabalhogit push envia seus commits para o remote, e git pull traz commits feitos em outro lugar e os mescla na sua branch. Faça pull antes de começar a trabalhar e push quando terminar, e você se mantém sincronizado com qualquer outra pessoa que esteja tocando no projeto. Pular o pull é o motivo mais comum de um push ser rejeitado.
JunoEnviando e buscando seu trabalhogit push origin main envia commits, git pull origin main busca e os mescla, e depois que uma branch tem um upstream configurado com git push -u, os dois comandos funcionam sem que você precise nomear de novo o remote ou a branch. Faça pull antes de fazer push em uma branch compartilhada, ou seu push será rejeitado porque o remote já avançou além do seu histórico local.
JunoEnviando e buscando seu trabalho O upstream que você configura com git push -u se resume a duas linhas de configuração, branch.<name>.remote e branch.<name>.merge, escritas no momento em que a flag é executada. O git status lê esse mesmo par para te dizer o quanto sua branch está adiante ou atrás de origin/main, uma comparação que ele faz inteiramente contra o seu remote-tracking branch local. Configure isso uma vez por branch, e todo push ou pull simplificado, e toda contagem de "adiante/atrás", vem de graça.

git fetch vs git pull ​

git pull faz duas coisas em uma etapa só: baixa o que mudou no remote e, imediatamente depois, mescla essas mudanças na branch em que você está. git fetch faz apenas a primeira metade. Ele baixa novos commits, mas nunca os mescla na sua branch. Sua branch atual, e seus arquivos de trabalho, permanecem exatamente como estavam até você mandar o Git mesclar ou fazer pull.

Esse é o tropeço em que quase todo mundo cai pelo menos uma vez: você roda git fetch, não vê nenhuma mudança visível em lugar nenhum, e conclui que nada aconteceu no remote. Alguma coisa aconteceu, sim: o fetch só ainda não tocou na sua branch de trabalho. Para ver o que chegou, olhe para o remote-tracking branch de que falamos antes neste capítulo: git log origin/main mostra commits parados no remote que ainda não chegaram à sua main local. Quando você estiver pronto para trazê-los, git merge origin/main faz isso, ou então git pull roda o fetch e esse merge para você em um único comando.

Use o fetch isoladamente quando você quiser olhar antes de mesclar. Digamos que uma colega de equipe, a Priya, mencione que enviou algo para a main: git fetch seguido de git log origin/main ou git diff main origin/main deixa você ler exatamente o que mudou antes que isso chegue à sua branch de trabalho. Uma vez satisfeito, git merge origin/main traz para dentro. No dia a dia, a maioria das pessoas vai direto para git pull, porque ver e mesclar em uma única etapa é mesmo o que elas querem. O fetch se justifica em uma branch compartilhada, quando você prefere ler o trabalho que está chegando primeiro, ou antes de decidir se esse é um bom momento para mesclar.

O que o fetch de fato atualiza é regido por um refspec: um mapeamento, guardado na configuração do seu remote, que diz ao Git quais branches do remote trazer e sob quais nomes locais guardá-las. O refspec padrão em um clone normal é, grosso modo, +refs/heads/*:refs/remotes/origin/*, o que significa "pegue toda branch sob os heads do remote e espelhe nos meus remote-tracking branches, movendo-os para bater mesmo que isso sobrescreva para onde apontavam antes." Esse é todo o mecanismo por trás de origin/main se manter atualizado: o fetch lê as branches do remote e reescreve seus remote-tracking branches para bater com elas, e então para. Nada na sua própria main muda até que um merge, rebase ou pull separado atue sobre o que o fetch trouxe.

Junogit fetch vs git pullgit pull baixa novos commits e os mescla na sua branch em uma única etapa. git fetch só os baixa e atualiza a memória do Git sobre onde o remote está; sua branch fica parada até você mesclar. Não ver nenhuma mudança nos seus arquivos logo depois de um fetch é esperado, os novos commits estão esperando no remote-tracking branch.
Junogit fetch vs git pullgit fetch baixa sem mesclar, git pull baixa e mescla em uma única etapa. Use o fetch isolado quando quiser ler os commits que estão chegando com git log origin/main antes que eles cheguem à sua branch, e use pull quando estiver pronto para mesclá-los de imediato. Confundir os dois é um dos erros mais comuns de Git em uma equipe.
Junogit fetch vs git pull Um refspec decide exatamente o que o fetch traz e quais remote-tracking branches ele atualiza, incluindo o origin/main, e o padrão espelha toda branch sob os heads do remote. O fetch só move seus remote-tracking branches, nunca a branch que você tem em checkout, então mesclar ou fazer pull continua sendo uma etapa separada e deliberada.

Onde isso te deixa ​

Push, pull e fetch levam seus commits até um remote compartilhado e os trazem de volta, o que cobre a maior parte do que a colaboração diária em Git exige. Tudo aqui se apoia no ciclo de commit: você ainda faz stage e commit localmente primeiro, um remote só muda para onde esses commits podem viajar. A próxima peça é fazer essa colaboração através do próprio GitHub, propondo uma mudança e tendo ela revisada antes de ser mesclada. O fluxo de pull request continua exatamente a partir daí. Se algum termo deste capítulo ainda parecer meio incerto, remote-tracking branch, refspec, upstream, o Glossário tem uma definição simples para cada um, e vale a pena revisitar O que é Git para a distinção entre Git e GitHub por si só.