Trabalho em um projeto que possui 2 ramificações, A e B. Normalmente, trabalho na ramificação A e mesclo as coisas da ramificação B. Para a mesclagem, normalmente:
git merge origin/branchB
No entanto, eu também gostaria de manter uma cópia local da ramificação B, pois ocasionalmente posso verificar a ramificação sem antes mesclar com a ramificação A. Para isso, eu faria:
git checkout branchB
git pull
git checkout branchA
Existe uma maneira de fazer o acima em um comando e sem precisar alternar entre ramificações? Devo estar usando git update-ref
para isso? Quão?
git
git-merge
git-pull
git-checkout
Charles
fonte
fonte
--no-ff
opção, o que faz com que um commit de mesclagem seja registrado de qualquer maneira. Se você estiver interessado nisso, minha resposta mostra como você pode fazer isso - não tão robusto quanto minha resposta postada aqui, mas os pontos fortes dos dois certamente poderiam ser combinados.Respostas:
A resposta curta
Desde que você faça uma mesclagem de avanço rápido , você pode simplesmente usar
Exemplos:
Embora a resposta de Amber também funcione em casos de avanço rápido, usar
git fetch
dessa maneira é um pouco mais seguro do que apenas mover a referência de ramificação com força, poisgit fetch
evitará automaticamente avanços acidentais não rápidos desde que você não use+
o refspec.A resposta longa
Você não pode mesclar uma ramificação B na ramificação A sem fazer check-out de A primeiro se isso resultar em uma mesclagem de avanço rápido. Isso ocorre porque é necessária uma cópia de trabalho para resolver possíveis conflitos.
No entanto, no caso de mesclagens de avanço rápido, isso é possível , porque essas mesclas nunca podem resultar em conflitos, por definição. Para fazer isso sem verificar primeiro uma ramificação, você pode usar
git fetch
com um refspec.Aqui está um exemplo de atualização
master
(não permitindo alterações sem avanço rápido) se você tiver outra ramificação emfeature
check-out:Esse caso de uso é tão comum que você provavelmente desejará criar um alias para ele no seu arquivo de configuração git, como este:
O que esse alias faz é o seguinte:
git checkout HEAD
: coloca sua cópia de trabalho em um estado de desanexação. Isso é útil se você deseja atualizarmaster
enquanto faz o check-out. Eu acho que era necessário fazer isso, porque, caso contrário, a referência de ramificação paramaster
não se moverá, mas não me lembro se isso é realmente certo.git fetch upstream master:master
: encaminha o local rapidamentemaster
para o mesmo local queupstream/master
.git checkout -
faz check-out de sua filial com check-out anterior (é o que-
faz neste caso).A sintaxe de
git fetch
mesclagens de avanço rápido (não)Se você deseja que o
fetch
comando falhe se a atualização não for um avanço rápido, basta usar um refspec do formulárioSe você deseja permitir atualizações sem avanço rápido, adicione um
+
à frente do refspec:Observe que você pode passar seu repositório local como o parâmetro "remote" usando
.
:A documentação
A partir da
git fetch
documentação que explica esta sintaxe (ênfase minha):Veja também
Git checkout e mesclar sem tocar na árvore de trabalho
Mesclando sem alterar o diretório de trabalho
fonte
git checkout --quiet HEAD
é agit checkout --quiet --detach
partir do Git 1.7.5.git fetch . origin/foo:foo
para atualizar minha foo local para o meu local de origem / foogit checkout -
truque! Tão fácil quantocd -
.Não, não há. É necessário fazer um checkout do ramo de destino para permitir a resolução de conflitos, entre outras coisas (se o Git não conseguir mesclá-los automaticamente).
No entanto, se a mesclagem for um avanço rápido, você não precisará verificar a ramificação de destino, porque na verdade não precisa mesclar nada - tudo o que você precisa fazer é atualizar a ramificação para apontar para o nova cabeça ref. Você pode fazer isso com
git branch -f
:Será atualizado
branch-b
para apontar para o cabeçalho dobranch-a
.A
-f
opção significa--force
, o que significa que você deve ter cuidado ao usá-lo.fonte
git reset
só funciona na filial com check-out atualmente.git fetch upstream branch-b:branch-b
(retirado desta resposta ).git fetch <remote> B:A
, onde B e A são ramificações completamente diferentes, mas B pode ser incorporado rapidamente em A. Você também pode passar seu repositório local como o "remoto" usando.
como alias remoto:git fetch . B:A
.branch -f
pode ser perigoso, como você aponta. Então não use! Usefetch origin branchB:branchB
, que falhará com segurança se a mesclagem não for avançar rapidamente.Como Amber disse, as fusões de avanço rápido são o único caso em que você poderia fazer isso. É possível que qualquer outra mesclagem precise passar por toda a mescla de três vias, aplicando patches, resolvendo conflitos - e isso significa que precisa haver arquivos por aí.
Por acaso, tenho um script usado para exatamente isso: fazer mesclagens de avanço rápido sem tocar na árvore de trabalho (a menos que você esteja mesclando no HEAD). É um pouco longo, porque é pelo menos um pouco robusto - ele verifica se a mesclagem seria um avanço rápido e, em seguida, executa-o sem verificar a ramificação, mas produzindo os mesmos resultados que se você tivesse - você vê o
diff --stat
resumo das alterações e a entrada no reflog é exatamente como uma mesclagem de avanço rápido, em vez da "redefinição" que você obtém se usarbranch -f
. Se você nomeá-logit-merge-ff
e soltá-lo em seu diretório bin, você pode chamá-lo como um comando git:git merge-ff
.PS Se alguém vir algum problema com esse script, comente! Era um trabalho de escrever e esquecer, mas ficaria feliz em melhorá-lo.
fonte
# or git branch -f localbranch remote/remotebranch
para me lembrar a fonte e as opções. Deu seu comentário no outro link a +1."$branch@{u}"
como committish a fusão para obter a ramificação upstream (em kernel.org/pub/software/scm/git/docs/gitrevisions.html )Você só pode fazer isso se a mesclagem for um avanço rápido. Caso contrário, o git precisa fazer o check-out dos arquivos para que possa mesclá-los!
Para fazer isso apenas para avanço rápido :
onde
<commit>
está o commit buscado, aquele para o qual você deseja avançar rapidamente. Isso é basicamente como usargit branch -f
para mover a ramificação, exceto que também a registra no reflog como se você realmente fizesse a mesclagem.Por favor, por favor, não faça isso por algo que não seja um avanço rápido, ou você apenas redefinirá sua ramificação para o outro commit. (Para verificar, veja se
git merge-base <branch> <commit>
fornece o SHA1 da ramificação.)fonte
git merge-base --is-ancestor <A> <B>
. "B" é o que precisa ser mesclado em "A". O exemplo seria A = mestre e B = desenvolver, garantindo que o desenvolvimento seja rápido no mestre. Nota: Existe com 0 se não for possível ff, existe com 1 se for.No seu caso, você pode usar
que faz o que você deseja (assumindo que a mesclagem é um avanço rápido). Se a ramificação não puder ser atualizada porque requer uma mesclagem de avanço rápido, isso falhará com segurança em uma mensagem.
Essa forma de busca também tem algumas opções mais úteis:
Observe que
<remote>
pode ser um repositório local e<sourceBranch>
uma ramificação de rastreamento. Assim, você pode atualizar uma filial local, mesmo que não tenha feito check-out, sem acessar a rede .Atualmente, o acesso ao servidor upstream é feito por meio de uma VPN lenta, então eu me conecto periodicamente
git fetch
para atualizar todos os controles remotos e depois desconectar. Então, se, digamos, o mestre remoto mudou, eu posso fazerpara atualizar meu mestre local com segurança, mesmo que atualmente eu tenha alguma outra ramificação em dia. Não é necessário acesso à rede.
fonte
Outra maneira reconhecidamente bastante bruta é apenas recriar o ramo:
Isso descarta a ramificação local desatualizada e recria uma com o mesmo nome, portanto, use com cuidado ...
fonte
Você pode clonar o repositório e fazer a mesclagem no novo repositório. No mesmo sistema de arquivos, isso será vinculado em vez de copiar a maioria dos dados. Termine puxando os resultados para o repositório original.
fonte
Digite git-forward-merge :
https://github.com/schuyler1d/git-forward-merge
Funciona apenas para mesclagens automáticas, se houver conflitos, você precisará usar a mesclagem regular.
fonte
Em muitos casos (como mesclagem), você pode simplesmente usar a ramificação remota sem precisar atualizar a ramificação de rastreamento local. Adicionar uma mensagem no reflog soa como um exagero e impedirá que seja mais rápido. Para facilitar a recuperação, adicione o seguinte na sua configuração do git
Então digite
para ver o histórico recente de sua filial
fonte
[core]
não deve ser[user]
? (e é por padrãoEu escrevi uma função shell para um caso de uso semelhante que encontro diariamente em projetos. Este é basicamente um atalho para manter as filiais locais atualizadas com uma filial comum, como desenvolver antes de abrir um PR, etc.
glmh
("git pull and merge here") automaticamentecheckout branchB
,pull
o mais recente, recheckout branchA
, emerge branchB
.Não trata da necessidade de manter uma cópia local da filial A, mas pode ser facilmente modificada para isso adicionando uma etapa antes de verificar a filial B. Algo como...
Para mesclagens de avanço rápido simples, isso pula para o prompt de mensagem de confirmação.
Para mesclagens sem avanço rápido, isso coloca sua ramificação no estado de resolução de conflitos (você provavelmente precisará intervir).
Para configurar, adicionar a
.bashrc
ou.zshrc
, etc:Uso:
fonte
Outra maneira de efetivamente fazer isso é:
Por ser uma letra minúscula
-d
, ela será excluída apenas se os dados ainda existirem em algum lugar. É semelhante à resposta de @ kkoehne, exceto que não força. Por causa-t
disso, o controle remoto será configurado novamente.Eu tinha uma necessidade ligeiramente diferente do OP, que era criar uma nova ramificação de recurso
develop
(oumaster
), depois de mesclar uma solicitação de recebimento. Isso pode ser feito em uma linha sem força, mas não atualiza adevelop
ramificação local . É apenas uma questão de verificar uma nova ramificação e basear-se nelaorigin/develop
:fonte
apenas para puxar o mestre sem verificar o mestre que eu uso
git fetch origin master:master
fonte
É absolutamente possível fazer qualquer mesclagem, mesmo mesclagens sem avanço rápido, sem
git checkout
. Aworktree
resposta do @grego é uma boa dica. Para expandir isso:Agora, você mesclou a ramificação local de trabalho à
master
ramificação local sem mudar sua compra.fonte
Se você deseja manter a mesma árvore que uma das ramificações que deseja mesclar (ou seja, não é uma "mesclagem" real)), você pode fazer assim.
fonte
Você pode tentar
git worktree
abrir dois ramos lado a lado; isso pode parecer o que você deseja, mas muito diferente das respostas que já vi aqui.Dessa forma, você pode ter dois desvios separados no mesmo repositório git, portanto, você só precisa buscar uma vez para obter atualizações nas duas árvores de trabalho (em vez de precisar clonar duas vezes e git pull em cada uma)
O Worktree criará um novo diretório de trabalho para o seu código, onde você poderá fazer check-out de uma ramificação diferente simultaneamente, em vez de trocar as ramificações no local.
Quando você deseja removê-lo, pode limpar com
fonte