Eu tenho uma filial chamada demo
que preciso fundir com o master
branch. Posso obter o resultado desejado com os seguintes comandos:
git pull origin demo
git checkout master
git pull origin master
git merge demo
git push origin master
Minha única preocupação é, se houver algum problema de mesclagem , quero dizergit
para substituir as alterações no master
branch sem me dar um prompt de mesclagem. Então, basicamente, as alterações no demo
branch devem substituir automaticamente as alterações no master
branch.
Eu olhei ao redor, havia várias opções, mas não quero me arriscar com a fusão.
git push -f origin master
-f
opção commerge
comando e não compush
comandoRespostas:
Realmente não relacionado a esta resposta, mas eu abandonaria
git pull
, o que apenas é executadogit fetch
seguido porgit merge
. Você está fazendo três mesclagens, o que fará seu Git executar três operações de busca, quando uma busca é tudo que você precisa. Conseqüentemente:Controlando a mesclagem mais complicada
A parte mais interessante aqui é
git merge -X theirs
. Como root545 observou , as-X
opções são passadas para a estratégia de mesclagem, e tanto arecursive
estratégia padrão quanto a alternativaresolve
tomam-X ours
ou-X theirs
(uma ou outra, mas não ambas). Para entender o que eles fazem, no entanto, você precisa saber como o Git encontra e trata os conflitos de mesclagem .Um conflito de mesclagem pode ocorrer dentro de algum arquivo 1 quando a versão base difere da versão atual (também chamada local, HEAD ou
--ours
) e da outra versão (também chamada remota ou--theirs
) desse mesmo arquivo. Ou seja, a fusão identificou três revisões (três commits): base, nossa e deles. A versão "base" é a partir da base de mesclagem entre nosso commit e seu commit, conforme encontrado no gráfico de commit (para muito mais sobre isso, veja outras postagens do StackOverflow). O Git então encontrou dois conjuntos de mudanças: "o que fizemos" e "o que eles fizeram". Essas alterações são (em geral) encontradas linha a linha, puramente textuaisbase. Git não tem uma compreensão real do conteúdo do arquivo; é apenas comparar cada linha do texto.Essas mudanças são o que você vê na
git diff
saída e, como sempre, elas também têm contexto . É possível que as coisas que mudamos estejam em linhas diferentes das coisas que eles mudaram, de modo que as mudanças parecem que não iriam colidir, mas o contexto também mudou (por exemplo, devido à nossa mudança estar perto da parte superior ou inferior do arquivo, para que o arquivo se esgote na nossa versão, mas na deles, eles também adicionaram mais texto na parte superior ou inferior).Se as mudanças acontecerem em linhas diferentes - por exemplo, mudamos
color
paracolour
a linha 17 e eles mudamfred
parabarney
a linha 71 - então não há conflito: o Git simplesmente aceita as duas mudanças. Se as mudanças acontecem nas mesmas linhas, mas são mudanças idênticas , o Git pega uma cópia da mudança. Somente se as mudanças estiverem nas mesmas linhas, mas forem mudanças diferentes, ou aquele caso especial de contexto interferente, você obterá um conflito de modificar / modificar.As opções
-X ours
e-X theirs
informam ao Git como resolver esse conflito, escolhendo apenas uma das duas alterações: a nossa ou a deles. Como você disse que está mesclando osdemo
(deles) com osmaster
(os nossos) e deseja as alterações dedemo
, é o que você deseja-X theirs
.Aplicar às cegas
-X
, entretanto, é perigoso. Só porque nossas mudanças não entraram em conflito linha por linha não significa que elas não entrem em conflito! Um exemplo clássico ocorre em linguagens com declarações de variáveis. A versão base pode declarar uma variável não utilizada:Em nossa versão, excluímos a variável não usada para fazer um aviso do compilador desaparecer - e em sua versão, eles adicionam um loop algumas linhas depois, usando
i
como contador de loop. Se combinarmos as duas alterações, o código resultante não será mais compilado. A-X
opção não ajuda aqui, pois as alterações são em linhas diferentes .Se você tiver um conjunto de testes automatizado, a coisa mais importante a fazer é executar os testes após a fusão. Você pode fazer isso após a confirmação e consertar as coisas mais tarde, se necessário; ou você pode fazer isso antes de confirmar, adicionando
--no-commit
aogit merge
comando. Vamos deixar os detalhes de tudo isso para outras postagens.1 Você também pode obter conflitos em relação às operações de "todo o arquivo", por exemplo, talvez consertemos a grafia de uma palavra em um arquivo (para que tenhamos uma mudança), e eles apaguem o arquivo inteiro (para que tenham um excluir). O Git não resolverá esses conflitos por conta própria, independentemente dos
-X
argumentos.Fazer menos mesclagens e / ou mesclagens mais inteligentes e / ou usar rebase
Existem três fusões em ambas as nossas sequências de comando. A primeira é trazer
origin/demo
para o localdemo
(o seu usogit pull
que, se o Git for muito antigo, não será atualizado,origin/demo
mas produzirá o mesmo resultado final). O segundo é trazer paraorigin/master
dentromaster
.Não está claro para mim quem está atualizando
demo
e / oumaster
. Se você escreve seu próprio código em seu própriodemo
branch, e outros estão escrevendo código e empurrando-o para odemo
branchorigin
, então esta fusão de primeira etapa pode ter conflitos ou produzir uma fusão real. Na maioria das vezes, é melhor usar rebase, em vez de mesclar, para combinar trabalho (reconhecidamente, isso é uma questão de gosto e opinião). Em caso afirmativo, você pode querer usargit rebase
. Por outro lado, se você nunca faz nenhum de seus próprios commitsdemo
, você nem mesmo precisa de umdemo
branch. Alternativamente, se você deseja automatizar muito isso, mas ser capaz de verificar cuidadosamente quando há commits que você e outros fizeram, você pode querer usargit merge --ff-only origin/demo
: isso irá acelerar o seu, se possível, e simplesmente falhará completamente se não (nesse ponto você pode inspecionar os dois conjuntos de alterações e escolher uma fusão real ou um rebase, conforme apropriado).demo
para corresponder ao atualizado,origin/demo
Esta mesma lógica se aplica
master
, embora você está fazendo a fusão emmaster
, então você definitivamente precisa de ummaster
. No entanto, é ainda mais provável que você deseje que a mesclagem falhe se não puder ser feita como uma não mesclagem de avanço rápido, então isso provavelmente também deveria sergit merge --ff-only origin/master
.Digamos que você nunca faça seus próprios commits no
demo
. Neste caso, podemos descartar o nomedemo
inteiramente:Se você está fazendo seus próprios
demo
commits de branch, isso não é útil; você também pode manter a fusão existente (mas talvez adicionar--ff-only
dependendo do comportamento que você deseja), ou alternar para fazer um rebase. Observe que todos os três métodos podem falhar: mesclar pode falhar com um conflito, mesclar com--ff-only
pode não ser capaz de avançar e rebase pode falhar com um conflito (rebase funciona, em essência, com commits seletivamente, que usa a fusão máquinas e, portanto, pode obter um conflito de fusão).fonte
Eu tive um problema semelhante, onde precisei substituir efetivamente qualquer arquivo que tinha alterações / conflitos por um branch diferente.
A solução que encontrei foi usar
git merge -s ours branch
.Observe que a opção é
-s
e não-X
.-s
denota o uso deours
como uma estratégia de mesclagem de nível superior,-X
estaria aplicando aours
opção àrecursive
estratégia de mesclagem, que não é o que eu (ou nós) queremos neste caso.Etapas, onde
oldbranch
está o branch que você deseja substituirnewbranch
.git checkout newbranch
verifica o branch que você deseja mantergit merge -s ours oldbranch
funde-se no ramo antigo, mas mantém todos os nossos arquivos.git checkout oldbranch
verifica o branch que você deseja substituirget merge newbranch
funde-se no novo ramo, substituindo o antigo ramofonte
Esta abordagem de mesclagem irá adicionar um commit no topo do
master
qual cola o que estiver dentrofeature
, sem reclamar de conflitos ou outras porcarias.Antes de tocar em qualquer coisa
Agora prepare mestre
Se
feature
vestir bemVá para a matança
fonte
Changes from the other tree that do not conflict with our side are reflected in the merge result
. Não funcionou para mim, pois eu tinha commits de fusão limpa em meu branch que estava sendo sobrescrito. Existe alguma outra maneira?Você pode tentar a opção "nossa" no git merge,
fonte
demo
versão seja preferida, embora ele esteja se fundindo commaster
. Também há-X theirs
, mas não está claro se isso é o que o OP realmente deseja.ours
faz ao usar no back-end com a-s
opção. Ao usarours
com-X
: Descarta tudo o que a outra árvore fez, declarando que nossa história contém tudo o que aconteceu nela. fonteQuando tentei usar
-X theirs
outras opções de comando relacionadas, continuei recebendo um commit de mesclagem. Provavelmente não estava entendendo direito. Uma alternativa fácil de entender é simplesmente excluir o branch e rastreá-lo novamente.Isso não é exatamente uma "fusão", mas é o que eu procurava quando me deparei com essa pergunta. No meu caso, eu queria extrair alterações de um branch remoto que foram empurradas à força.
fonte