Bifurcações e upstreams do Git: instruções e uma dica legal

Nicola Paolucci
Representante do desenvolvedor
A bifurcação de projetos para fazer suas próprias alterações permite integrar com facilidade as próprias contribuições. Mas se você não estiver enviando essas alterações de volta para o upstream, o que significa enviar de volta para o repositório pai, você corre o risco de perdê-las, o que pode causar linhas divergentes no repositório. Para garantir que todos os colaboradores estejam desenhando do mesmo lugar, você vai precisar saber alguns princípios de como o git forking interage com o git upstream. Neste blog, vou apresentar o básico, as pegadinhas e até deixar uma dica legal para você ficar à frente da curva.
Git upstream: fique atualizado e contribua
A gente vai começar detalhando uma configuração comum e o fluxo de trabalho mais básico para interagir com repositórios upstream
.
Em uma configuração padrão, você em geral tem uma origem
e um remoto
upstream — o último é o guardião do projeto ou a fonte da verdade para a qual você quer contribuir.
Primeiro, verifique se você já configurou um remoto para o repositório upstream
e, com sorte, uma origem
também:
git remote -v
origin git@bitbucket.org:my-user/some-project.git (fetch)
origin git@bitbucket.org:my-user/some-project.git (push)
Se você não tiver um upstream
, vai poder adicionar com facilidade com o comando remote
:
git remote add upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git

Material relacionado
Como mover um Repositório do Git completo

VER SOLUÇÃO
Aprenda a usar o Git com o Bitbucket Cloud
Verifique se o controle remoto foi adicionado com precisão:
git remote -v
origin git@bitbucket.org:my-user/some-project.git (fetch)
origin git@bitbucket.org:my-user/some-project.git (push)
upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (fetch)
upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (push)
Agora você pode coletar as alterações mais recentes do repositório upstream
com fetch
. Repita sempre que quiser receber atualizações:
(Se o projeto tiver marcações que não passaram por merge para o mestre, você também deve fazer git fetch upstream --tags)
git fetch upstream
No geral, você quer manter a ramificação master
local como um espelho próximo do upstream
master
e executar qualquer trabalho em ramificações de funções, pois elas podem se tornar pull requests em seguida.
Nesse ponto, não importa se você usa merge
ou rebase
, pois o resultado tende a ser o mesmo. Vamos usar o merge
:
git checkout main
git merge upstream/main
Quando você quiser compartilhar algum trabalho com os mantenedores upstream
que você ramifica fora do principal
, crie uma ramificação de função. Quando estiver satisfeito, envie-o para o repositório remoto.
Você também pode usar o rebase
e, em seguida, o merge
para garantir que o upstream
tenha um conjunto limpo de confirmações (de preferência um) para avaliar:
git checkout -b feature-x
#some work and some commits happen
#some time passes
git fetch upstream
git rebase upstream/main
Publicar com git fork
Após as etapas acima, publique o trabalho na bifurcação remota com um simples push
:
git push origin feature-x
git push -f origin feature-x
Em particular, prefiro manter o histórico o mais limpo possível e optar pela opção três, mas equipes diferentes têm fluxos de trabalho diferentes. Nota: Você deve fazer isso somente quando estiver trabalhando com sua própria bifurcação. Reescrever o histórico de repositórios e branches compartilhados é algo que você NUNCA deve fazer.
Dica do dia: números à frente/atrás no prompt
Depois de um fetch
, git status
mostra quantos commits você está à frente ou atrás da ramificação remota
sincronizada. Não seria bom se você pudesse ver essas informações no fiel prompt de comando? Eu também pensei assim, então comecei a mexer meus pauzinhos bash
e cozinhei.
Veja como ele vai ficar no prompt depois da configuração:
nick-macbook-air:~/dev/projects/stash[1|94]$
E isso é o que você vai precisar adicionar ao .bashrc
ou equivalente — apenas uma única função:
function ahead_behind {
curr_branch=$(git rev-parse --abbrev-ref HEAD);
curr_remote=$(git config branch.$curr_branch.remote);
curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
}
export PS1="\h:\w[\$(ahead_behind)]$"
Funcionamento interno
Para quem gosta de informações e explicações, é assim que funciona:
Obtemos o nome simbólico para o HEAD atual, ou seja, a ramificação atual:
curr_branch=$(git rev-parse --abbrev-ref HEAD);
Obtemos o remoto para o qual a ramificação atual está apontando:
curr_remote=$(git config branch.$curr_branch.remote);
Obtemos a ramificação ao qual esse remoto deve passar por merge (com um truque do Unix para descartar tudo e incluindo a última barra [ / ]):
curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
Agora a gente tem o que precisa para coletar o número de contagens das confirmações que temos à frente ou atrás:
git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
Usamos o antigo Unix tr
para converter o TAB
em um separador |
.
Primeiros passos com o git upstream
Esse é um passo a passo básico no git upstream
— como configurar um git upstream, criar uma nova ramificação, coletar alterações, publicar com git fork e uma dica sobre quantas ramificações à frente/atrás você está da ramificação remota.
O Bitbucket Data Center faz a sincronização de bifurcações, que, em resumo, alivia o desenvolvedor de todo o peso de se manter atualizado com as bifurcações. E o Bitbucket Cloud tem uma sincronização fácil de 1 etapa, Confira!
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.

Blog do Bitbucket

Caminho de aprendizagem de DevOps
