Como gerencio conflitos com submódulos git?

127

Eu tenho um superprojeto git que faz referência a vários submódulos e estou tentando bloquear um fluxo de trabalho para o restante dos membros do meu projeto trabalharem.

Para esta pergunta, digamos que meu superprojeto seja chamado superye o submódulo seja chamado subby. (Em seguida, há uma simplificação do que estou tentando fazer ... Na verdade, não estou usando as ramificações para versões, mas achei que seria mais fácil definir como uma pergunta.)

Minha ramificação principal de superytem a tag v1.0do projeto git subbyreferenciada como um submódulo. A ramificação de superychamada one.onee alterou a referência do submódulo para apontar para a tag v1.1de subby.

Posso trabalhar em cada uma dessas ramificações sem problemas, mas se tentar atualizar a one.oneramificação com alterações da masterramificação, recebo alguns conflitos e não sei como resolvê-los.

Basicamente, depois de executar um git pull . mastertempo no subbyramo, parece que ele cria submódulos adicionais.

Antes do pull / mesclar, recebo a resposta desejada git submoduleda one.oneramificação:

$ git checkout master
$ git submodule
qw3rty...321e subby (v1.0)
$ git checkout one.one
$ git submodule
asdfgh...456d subby (v1.1)

Mas após a atração, ele adiciona submódulos adicionais quando executo git submodule:

$ git pull . master
Auto-merged schema
CONFLICT (submodule): Merge conflict in subby - needs qu3rty...321e
Automatic merge failed; fix conflicts and then commit the results.

$ git submodule
qw3rty...321e subby (v1.0)
asdfgh...456d subby (v1.1)
zxcvbn...7890 subby (v1.1~1)

Como faço para excluir / ignorar as referências indesejadas do sub-módulo e confirmar meus conflitos e alterações? Ou existe um parâmetro que eu possa usar com o meu original git pullque ignorará meus submódulos?

Tyler
fonte

Respostas:

23

Eu não vi esse erro exato antes. Mas tenho um palpite sobre o problema que você está enfrentando. Parece que porque os ramos mastere one.onede superycontêm refs diferentes para o subbysubmódulo, quando você mescla alterações do mastergit, não sabe qual ref - v1.0ou v1.1- deve ser mantido e rastreado pelo one.oneramo de supery.

Se for esse o caso, será necessário selecionar o árbitro que você deseja e confirmar essa alteração para resolver o conflito. Qual é exatamente o que você está fazendo com o comando reset .

Esse é um aspecto complicado do rastreamento de diferentes versões de um submódulo em diferentes ramos do seu projeto. Mas o submodule ref é como qualquer outro componente do seu projeto. Se os dois ramos diferentes continuarem a rastrear os mesmos respectivos submodulos refs após mesclagens sucessivas, o git deverá ser capaz de elaborar o padrão sem gerar conflitos de mesclagem em mesclagens futuras. Por outro lado, se você alternar o submódulo com frequência, poderá ter de suportar muitas soluções de conflitos.

Jesse Hallett
fonte
1
Obrigado por esclarecer um pouco a questão. Isso faz total sentido para mim agora e o comando reset funciona perfeitamente para a minha situação acima. Mas quais seriam os comandos para aceitar o sub-módulo ref do ramo mestre e jogar fora o ref para o sub-módulo do ramo atual? Eu sei como lidar com conflitos normais, mas depois de três dias vasculhando a web, não consigo encontrar um exemplo de código diferente de rm -r. E estou começando a pensar que há uma razão para os exemplos não existirem; O submódulo está tão abstraído do superprojeto que você precisa gerenciar todas as transições.
Tyler
26
FINALMENTE! Uma resposta! Eu tinha added by us: ../Mono.Cecilem git statusmas git adde git rmfalhou com Mono.Cecil: needs merge, pathspec 'Mono.Cecil/' did not match any filesporque era apenas uma pasta vazia e git realmente só arquivos alças. git checkoutme deu Mono.Cecil: needs merge, error: you need to resolve your current index first, git submodule updatedeu Skipping unmerged submodule Mono.Cecile git checkout master Mono.Cecilfinalmente consertou. Problema básico: a git statussugestão está errada, então escolha um ramo e leve sua cópia da pasta checkout!
IBBoard
6
@ Comando do IBBoard me ajudou com esta situação - eu tentei git checkout --ours SUBMODe git add SUBMODe outros, mas fazendo finalmente git checkout master SUBMODresolveu o conflito. Este comentário provavelmente deve ser uma resposta, não comentário ... :)
Colin D Bennett
89

Bem, não é tecnicamente o gerenciamento de conflitos com os submódulos (ou seja: mantenha isso, mas não aquilo), mas eu encontrei uma maneira de continuar trabalhando ... e tudo o que eu precisava fazer era prestar atenção à minha git statussaída e redefinir os submódulos:

git reset HEAD subby
git commit

Isso redefiniria o submódulo para o commit pré-pull. Que neste caso é exatamente o que eu queria. E em outros casos em que preciso das alterações aplicadas ao submódulo, tratarei daquelas com os fluxos de trabalho padrão do submódulo (mestre de checkout, puxe a tag desejada etc.).

Tyler
fonte
Para mim, isso apenas parece alterar o status do módulo conflitante de "ambos modificados" para "excluídos".
Matt Zukowski
4
Você pode querer manter submodule do ramo mesclado em vez disso: git reset <fundiu-branch> subby
Edward Anderson
1
funciona para mim como prescrito na resposta .. git reset HEAD path / to / submodule / dir
estoy
56

Eu lutei um pouco com as respostas sobre essa pergunta e também não tive muita sorte com as respostas em um post semelhante no SO . Então, foi isso que funcionou para mim - tendo em mente que, no meu caso, o submódulo foi mantido por uma equipe diferente; portanto, o conflito veio de diferentes versões do submódulo no master e na filial local do projeto em que eu estava trabalhando:

  1. Executar git status- anote a pasta do submódulo com conflitos
  2. Redefina o submódulo para a versão que foi confirmada pela última vez no ramo atual:

    git reset HEAD path/to/submodule

  3. Neste ponto, você tem uma versão livre de conflito do seu submódulo que agora pode ser atualizada para a versão mais recente no repositório do submódulo:

    caminho do CD / para / submódulo
    submódulo git foreach origem do pull git SUBMODULE-BRANCH-NAME
  4. E agora você pode fazer commitisso e voltar ao trabalho.

Emma Burrows
fonte
16

Primeiro, encontre o hash que você deseja referenciar no seu submódulo. então corra

~/supery/subby $ git co hashpointerhere
~/supery/subby $ cd ../
~/supery $ git add subby
~/supery $ git commit -m 'updated subby reference'

que trabalhou para eu obter meu sub-módulo com a referência correta de hash e continuar com meu trabalho sem obter mais conflitos.

hellatan
fonte
1
ou você poderia apenas fazer um git checkout --theirs (ou --ours) subby
Bachi
@Bachi: git checkout - deles e - nossos não tem efeito nos submódulos.
Edward Anderson
1
Embora isso resolva o conflito, não é fácil determinar <hashpointerhere>. Não conheço uma maneira fácil de ver o commit do submódulo verificado em cada lado do conflito. Qualquer confirmação que você faça check-out no subby pode ser diferente dos dois lados da mesclagem, o que não é apropriado em uma consolidação de mesclagem.
Edward Anderson
@ nilbus isso é verdade. Abandonamos o trabalho com submódulos git, pois essa era uma das preocupações que tínhamos e tornamos muito difícil saber qual comprometimento você realmente queria. Usamos o compositor (php) como um gerenciador de pacotes, o que eu realmente gosto, pois cria um arquivo de bloqueio bloqueando os repositórios para um determinado hash. No entanto, como estamos usando node_modules em vários repositórios, encontraríamos módulos conflitantes aqui e ali. Desde então, mudamos para o npm para gerenciar essas coisas, mas essa também é uma outra lata de worms.
hellatan
12

Eu tive esse problema com git rebase -i origin/masteruma filial. Eu queria pegar a versão mestra do ref do submódulo, então simplesmente:

git reset master path/to/submodule

e depois

git rebase --continue

Isso resolveu o problema para mim.

maratona
fonte
3
Isso funcionou para mim. Ainda estou imaginando o que eles fizeram para danificar o submódulo.
Checo R
3

Obteve ajuda desta discussão. No meu caso, o

git reset HEAD subby
git commit

trabalhou para mim :)

Mithun Das
fonte
2

Bem, no meu diretório pai, vejo:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)

Então eu fiz isso

git reset HEAD linux
Kjeld Flarup
fonte