Estou me fundindo em um ramo remoto que pode ter muitos conflitos. Como posso saber se haverá conflitos ou não?
Eu não vejo nada como um --dry-run
on git-merge
.
Estou me fundindo em um ramo remoto que pode ter muitos conflitos. Como posso saber se haverá conflitos ou não?
Eu não vejo nada como um --dry-run
on git-merge
.
Respostas:
Como observado anteriormente, passe o --no-commit
sinalizador, mas para evitar um commit de avanço rápido, também passe --no-ff
o seguinte:
$ git merge --no-commit --no-ff $BRANCH
Para examinar as alterações faseadas:
$ git diff --cached
E você pode desfazer a mesclagem, mesmo que seja uma mesclagem de avanço rápido:
$ git merge --abort
git merge --only-if-there-wont-be-any-conflicts
ou git diff --show-conflicts <commit>
seria realmente útil. Pena que ainda não é possível, ou estou perdendo alguma coisa?
git pull --ff-only
!
Eu apenas tive que implementar um método que encontre automaticamente conflitos entre um repositório e seu controle remoto. Essa solução mescla a memória para não tocar no índice nem na árvore de trabalho. Penso que esta é a forma mais segura possível de resolver este problema. Veja como funciona:
git fetch origin master
git merge-base FETCH_HEAD master
git merge-tree mergebase master FETCH_HEAD
(a base de fusão é o ID hexadecimal que a base de mesclagem imprimiu na etapa anterior)Agora, suponha que você queira mesclar o mestre remoto com o mestre local, mas você pode usar quaisquer ramificações. git merge-tree
executará a mesclagem na memória e imprimirá o resultado na saída padrão. Grep para o padrão <<
ou >>
. Ou você pode imprimir a saída em um arquivo e verificar isso. Se você encontrar uma linha que começa com 'alterado em ambos', provavelmente haverá um conflito.
git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"
Simplesmente incrível! +100
+<<<<<<< .our
então eu uso uma expressão grep comogrep -q '^+<* \.our$'
Minha solução simples de força bruta para isso é:
Crie uma ramificação "pré-mestre" (do mestre, é claro)
Mesclar todas as coisas que você deseja neste pré-mestre.
Então você pode ver como a fusão aconteceu sem tocar no mestre.
Enfim, eu seguiria o conselho da @ orange80.
git merge --abort
se houver conflitos, git reset --hard HEAD~1
se houve uma mesclagem ou git reset --hard origin/master
. Criar outro ramo dá a você uma sensação de segurança, mas se você aprender como o git funciona, entenderá que é um medo equivocado. Quando se trata de não alterar a cópia de trabalho, isso não oferece solução.
git merge --no-commit
não abortará uma mesclagem se puder ser encaminhada rapidamente. git merge --abort
não funciona se foi mesclado. Se você deseja escrever isso como um script, é estranho, pois git merge
não responde com códigos de erro suficientes para explicar os diferentes tipos de conflitos. Trabalhar com uma ramificação nova impede que um script quebrado deixe seu repositório em um estado que exija intervenção manual. Claro que você não pode perder nada. Mas é mais fácil construir de outra maneira.
Desfazer uma mesclagem com o git é tão fácil que você nem precisa se preocupar com a execução a seco:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
EDIT: Como observado nos comentários abaixo, se você tiver alterações no diretório de trabalho ou na área de armazenamento temporário, provavelmente desejará armazená-las antes de fazer o procedimento acima (caso contrário, elas desaparecerão após o procedimento git reset
acima)
git branch --contains HEAD
ou até mesmo mais diretamente, o uso apenasgit merge --ff-only
--dry-run
não "simplesmente verifica se uma mesclagem será rápida". Ele retornaria a saída exata que uma mesclagem faria: arquivos, conflitos etc. Se will will ff não é realmente interessante, é?
git stash; git reset --hard
? @BrianPhillips
Fiz um alias para fazer isso e funciona como um encanto, faço o seguinte:
git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '
Agora eu só ligo
git mergetest <branchname>
Para descobrir se há algum conflito.
Apenas diferencie sua ramificação atual em relação à ramificação remota, isso informará o que será alterado quando você fizer uma extração / mesclagem.
#see diff between current master and remote branch
git diff master origin/master
Eu uso o comando request-pull git para fazer isso. Ele permite que você veja todas as alterações que aconteceriam durante a mesclagem, mas sem fazer nada em seus repositórios locais ou remotos .
Por exemplo, imagine que você deseja mesclar um ramo chamado "feature-x" em seu ramo mestre
git request-pull master origin feature-x
mostrará um resumo do que aconteceria (sem fazer nada):
The following changes since commit fc01dde318:
Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
Adding some layout
Refactoring
ioserver.js | 8 +++---
package.json | 7 +++++-
server.js | 4 +--
layout/ldkdsd.js | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js
Se você adicionar o -p
parâmetro, também receberá o texto completo do patch, exatamente como se estivesse fazendo um diff git em cada arquivo alterado.
master
e origin
fazer nas opções de linha de comando, e que sobre se estou, por exemplo, a nível local branch1
e quer fazer um request-pull
em um ramo de funcionalidade locais branch2
? Eu ainda preciso origin
? Claro, sempre se pode ler a documentação.
Estou surpreso que ninguém tenha sugerido o uso de patches ainda.
Digamos que você gostaria de testar uma mesclagem de your_branch
dentro master
(eu estou supondo que você tenha master
check-out):
$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch
Isso deve fazer o truque.
Se você receber erros como
error: patch failed: test.txt:1
error: test.txt: patch does not apply
isso significa que o patch não foi bem-sucedido e uma fusão produziria conflitos. Nenhuma saída significa que o patch está limpo e você poderá mesclar facilmente a ramificação
Observe que isso realmente não altera sua árvore de trabalho (além de criar o arquivo de correção, é claro, mas você pode excluí-lo com segurança depois). Na documentação do git-apply:
--check
Instead of applying the patch, see if the patch is applicable to the
current working tree and/or the index file and detects errors. Turns
off "apply".
Observe para quem é mais esperto / mais experiente com o git do que eu: informe-me se eu estiver errado aqui e esse método mostra um comportamento diferente do que uma mesclagem regular. Parece estranho que, nos mais de 8 anos em que essa pergunta existisse, ninguém sugerisse essa solução aparentemente óbvia.
git diff master your_branch | git apply --check
.
Isso pode ser interessante: Na documentação:
Se você tentou uma mesclagem que resultou em conflitos complexos e deseja recomeçar, é possível recuperar com o git merge --abort .
Mas você também pode fazê-lo da maneira ingênua (mas lenta):
rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)
(Nota: não funcionará apenas na clonagem em / tmp, você precisará de uma cópia para garantir que as alterações não confirmadas não entrem em conflito).
cp -r repository/.git /tmp/repository/.git
, cd /tmp/repository
, git reset --hard
, git add --all
, git reset --hard
(para uma boa medida), git status
(para verificar se ele está limpo).
Estou ciente de que essa é uma pergunta antiga, mas é a primeira a aparecer em uma pesquisa no Google.
O Git introduziu uma opção --ff-only ao mesclar.
From: http://git-scm.com/docs/git-merge
--ff-only
Recuse-se a mesclar e sair com um status diferente de zero, a menos que o HEAD atual já esteja atualizado ou a mesclagem possa ser resolvida como um avanço rápido.
Fazer isso tentará mesclar e avançar rapidamente e, se não puder, interrompe e solicita que o avanço rápido não possa ser executado, mas deixa o ramo de trabalho intocado. Se puder avançar rapidamente, executará a mesclagem em sua ramificação de trabalho. Esta opção também está disponível em git pull
. Assim, você pode fazer o seguinte:
git pull --ff-only origin branchA #See if you can pull down and merge branchA
git merge --ff-only branchA branchB #See if you can merge branchA into branchB
Eu uso o git log para ver o que mudou em um ramo de recurso do ramo mestre
git log does_this_branch..contain_this_branch_changes
por exemplo - para ver quais confirmações estão em um ramo de recurso que / não foi mesclado ao mestre:
git log master..feature_branch
Se você quiser avançar de B para A, certifique-se de que o git log B..A não mostre nada, ou seja, A não possui nada que B não possua. Mas mesmo que B..A possua alguma coisa, você ainda poderá mesclar sem conflitos, portanto, o acima mostra duas coisas: haverá um avanço rápido e, portanto, você não terá um conflito.
Minha solução é mesclar para trás.
Em vez de mesclar sua ramificação na ramificação "alvo" remota, mesclar essa ramificação na sua.
git checkout my-branch
git merge origin/target-branch
Você verá se há algum conflito e pode planejar como resolvê-lo.
Depois disso, você pode interromper a mesclagem via git merge --abort
ou (se não houver nenhum conflito e mesclagem) reverter para a consolidação anterior viagit reset --hard HEAD~1