“Git merge -s theirs” necessário – mas eu sei que não existe

Eu tenho um número de repositorys remotos que eu quero mesclar juntos. Algumas das subtrees nesses repositorys são exclusivas do remoto (elas contêm dados específicos do host), outras subtrees contêm dados que (supostamente) são comuns a todos os controles remotos.

O que eu quero fazer, essencialmente, é executar “git pull” para cada controle remoto. Isso avança rapidamente a ramificação principal local ao longo da ramificação de rastreamento do mestre remoto para arquivos específicos do host que foram alterados no controle remoto e não fará nada pelos arquivos comuns porque eles não serão alterados.

Uma mudança em um arquivo comum (chame-o de F, com a mudança sendo F ‘) não deve ser um problema, mesmo que isso aconteça apenas em um remoto no início. O git-merge fará a coisa certa e me dará uma cópia de F ‘no meu espaço de trabalho composto, que é o que eu quero. O problema surge se o mesmo arquivo comum for alterado de maneira diferente em outro controle remoto (chame-o de F “). O git-merge me dará um composto de F ‘e F”, que não é o que eu quero. Tudo que eu quero é F “.

Quando trabalhei com o ClearCase, chamamos isso de mesclagem de cópias. O resultado da mesclagem sempre foi uma cópia exata do colaborador. Isso soa muito como “git merge -s deles” seria, exceto que não existe.

Eu me pergunto se eu posso cozinhar algo com “git-read-tree -m – trivial” para obter as fusões rápidas fora do caminho, então fazer alguma mágica com git-merge e um mergetool personalizado que simplesmente copia o $ Arquivo REMOTO para $ MERGED. Mas mesmo com isso eu não vejo como eu posso parar o git-merge a partir da composição de F ‘e F “se as coisas da mesclagem forem triviais.

Eu li o link Existe uma versão “deles” do “git merge -s ours”? neste site, e o post de Junio ​​Hamano faz referências explicando porque “git merge -s theirs” é uma idéia tão ruim, mas esse não é o caso para mim. Eu valorizo ​​o histórico antigo, mas preciso pular o barco e seguir a alteração no site remoto quando um deles acontece. Nenhum trabalho novo é feito no site local. Ele simplesmente precisa formar uma composição de todos os sites remotos, obtendo o arquivo “comum” mais recente do último controle remoto pesquisado quando um deles é alterado.

Agradecemos antecipadamente por qualquer ajuda que você possa me dar.

Muito obrigado ao @VonC por sugerir o uso do atributo merge = custom-driver no arquivo .gitattributes . Embora isso funcione, estou relutante em poluir meu espaço de trabalho com arquivos .git e, embora eu possa usar $ GIT_DIR / info / attributes para evitar a poluição, fico incomodado com a necessidade de duas regras para capturar arquivos de ponto e arquivos não pontuais.

Depois de um pouco de experimentação, consegui uma solução com a variável de configuração merge.default (mencionada na página de manual gitattributes (5) ) funcionando. O truque que eu perdi foi que merge.default leva o nome de um driver personalizado que você definiu anteriormente; você não dá o comando personalizado diretamente. Aqui está o que funciona para mim …

Primeiro defina seu driver personalizado de mesclagem de cópias. Você pode usar comandos shell diretamente; não há necessidade de um script externo (apenas certifique-se de obter o seu meta-caractere shell citando corretamente):

 git config merge.copy-merge.name 'Copy Merge' git config merge.copy-merge.driver 'mv %B %A' 

Observe que mv retorna 0 em sucesso, 1 em falha, atendendo aos critérios de relatório de mesclagem “success” de volta ao git.

Agora diga ao git que TODAS as fusões são mescladas:

 git config merge.default copy-merge 

Ei, Presto! Tarefa concluída. O git merge agora vai mesclar tudo de modo que o branch em que você está contenha cópias exatas de todos os arquivos no . QED.

Se você quiser fazer uma mesclagem que não seja de cópia, simplesmente redefina o driver de mesclagem padrão:

 git config --unset merge.default 

Se você quiser ser mais seletivo, deixe merge.default e use os atributos como @VonC diz:

 cd path/to/copy-merge/in echo '* merge=copy-merge' > .gitattributes echo '.* merge=copy-merge' >> .gitattributes 

Faça isso no topo de cada subtree na qual você deseja copiar-mesclar. Se houver uma sub-subtree na qual você NÃO deseja copiar-mesclar, será possível desativá-la novamente:

 cd path/to/copy-merge/in/path/to/normal-merge/in echo '* merge' > .gitattributes echo '.* merge' >> .gitattributes 

ATENÇÃO: jogar lixo na sua tree de trabalho com muitos arquivos .gitattributes pode levar a confusão, especialmente se você também usar coisas como “* .bin -merge” em outros diretórios para forçar todas as mesclas de arquivos .bin a falharem com conflitos. Pode ser melhor usar $ GIT_DIR / info / attributes para esse tipo de coisa, pois tem a maior precedência.

Correu para este problema no outro dia:

http://seanius.net/blog/2011/02/git-merge-s-theirs/

 git merge -s ours ref-to-be-merged git diff --binary ref-to-be-merged | git apply -R --index git commit -F .git/COMMIT_EDITMSG --amend 

(atualização 2011:
A resposta ” comando git para fazer um ramo como outro ” lista todas as maneiras possíveis para simular uma mesclagem git -s deles ` )


Para os arquivos / trees específicos que você deseja mesclar, você pode configurar um valor de gitattributes como o que menciono nesta pergunta SO , definindo um driver de mesclagem personalizado.
O script associado ao atributo de mesclagem garantiria sempre manter o arquivo remoto como o resultado da mesclagem (consulte esta resposta de SO para uma ilustração, embora para o cenário oposto – mantendo a versão local).

 echo * merge=keepTheir > dirWithCopyMerge\.gitattributes git config merge.keepTheir.name "always keep theirduring merge" git config merge.keepTheir.driver "keepTheir.sh %O %A %B" 

Ao definir um .gitattribute no topo da subtree que você quer que seja mesclado com a cópia, com ‘ * merge=keepTheir ‘ como seu conteúdo, você efetivamente atribui um driver de mesclagem personalizado a todos os arquivos dessa subtree (observe o uso do ‘ * ‘ curinga aqui).

Com keepTheir.sh como:

 mv -f $3 $2 exit 0 

você não precisa modificar nenhum driver de mesclagem “padrão” e aplicar o seu próprio somente nos arquivos desejados.

Na versão 1.7.1 do Git, você pode passar uma estratégia “deles” para mesclar com o argumento “-Xtheirs”.

git merge -Xtheirs otherBranch

Não tenho certeza se isso se aplica ao que você está tentando fazer, mas provavelmente vale a pena tentar.

(Veja também esta questão relacionada )

Depois de uma tonelada de pesquisas, passando por todo o barulho do SO, e aprendendo mais sobre o git novamente ( isso nunca acaba? ), Eu acredito que essa resposta é a maneira mais livre de ruído e ideal para alcançar uma --strategy theirs personalizada --strategy theirs motorista. Utilizável sob demanda, não gitattributes necessário nenhum lixo.

Na verdade, eu ainda estou um pouco tonto em saber se isso é uma --strategy theirs simulação, ou o checkout --theirs . usar – checkout --theirs . método de resolução de conflitos. Talvez eles sejam equivalentes, mas eu teria que diagnosticar alguns charts de resultados para entender completamente, que não há tempo para agora.

Props para @kbro fazendo a coisa certa perseguindo os detalhes e chegando bem perto em https://stackoverflow.com/a/1911370/35946

[git:master] é a exibição do prompt do shell.

CONFIGURAÇÃO

 $ [git:master] git config merge.theirs.name 'simulate `-s theirs`' $ [git:master] git config merge.theirs.driver 'cat %B > %A' # same as `mv` or `cp`, matter of taste 

USAR

 $ [git:master] GIT_CONFIG_PARAMETERS="'merge.default=theirs'" git merge develop 

BÔNUS: ALIAS

 $ [git:master] git config alias.merge-theirs \!GIT_CONFIG_PARAMETERS=\""'"merge.default=theirs"'"\"\ git\ merge 

USE: ALIAS

 $ [git:master] git merge-theirs develop 

Observe a estrutura de GIT_CONFIG_PARAMETERS de GIT_CONFIG_PARAMETERS , porque ela deve ter vários valores complexos. Conseguir que a linha de comando do BONUS tenha se esforçado para descobrir.

PS GIT_CONFIG_PARAMETERS deve ser o segredo mais bem guardado no SO, estamos quase terminando em 2016, https://stackoverflow.com/search?q=git_config_parameters tem 1 (um) resultado ( 1 )