Eu gostaria de mesclar dois git
arquivos de texto não baseados usando semântica semelhante a como git
descreve "conflitos de mesclagem".
Por exemplo, suponha que eu tenha dois arquivos de texto com conteúdo semelhante, mas não idêntico, chamados file.1
e file.2
. Gostaria de realizar uma mesclagem desses dois arquivos em um terceiro arquivo, da seguinte forma:
hypothetical-merge-utility file.1 file.2 file.merged
Eu gostaria que produzisse file.merged
, que listaria o conteúdo do arquivo e cada diff de uma maneira semelhante a esta:
common line 1 ...
common line 2 ...
common line 3 ...
<<<<<<< file.1
something unique from file.1
a second line of something unique from file.1
======= file.2
something unique from file.2
>>>>>>> end of diff
common line 4 ...
common line 5 ...
<<<<<<< file.1
something unique from file.1
======= file.2
something unique from file.2
a second line of something unique from file.2
>>>>>>> end of diff
common line 6 ...
common line 7 ...
... etc. ...
Em outras palavras, eu gostaria que cada diferença entre file.1
e file.2
se parecesse com a representação de um git
"conflito de mesclagem".
Eu não me importo se delimitadores diferentes de <<<<<<<<
, ========
e >>>>>>>>
são usados.
Eu sei que existem vários utilitários disponíveis para mesclar arquivos de texto no linux. No entanto, estou apenas procurando algo que apresente especificamente os dados mesclados de uma maneira semelhante à maneira que git
descreve "conflitos de mesclagem".
Alguém conhece tal utilidade?
Agradeço antecipadamente.
ATUALIZAÇÃO : De acordo com a pergunta abaixo de Ed Morton, aqui está o conteúdo dos dois arquivos de teste ...
==== arquivo.1 ====
common line 1 ...
common line 2 ...
common line 3 ...
something unique from file.1
a second line of something unique from file.1
common line 4 ...
common line 5 ...
something unique from file.1
common line 6 ...
common line 7 ...
==== arquivo.2 ====
common line 1 ...
common line 2 ...
common line 3 ...
something unique from file.2
common line 4 ...
common line 5 ...
something unique from file.2
a second line of something unique from file.2
common line 6 ...
common line 7 ...
NOTA : Embora eu considere isso uma "resposta" um tanto razoável, agora cheguei a outra "resposta" que acho melhor. Então, por favor, veja minha outra "Resposta", abaixo.
Versão original desta "Resposta" ...
Oh! Postei muito cedo aqui. Eu não estava ciente da
-D
opção de linha de comando paradiff
, e agora percebo que posso fazer isso ...Ele irá produzir o seguinte dentro de
file.merged
...Posso lidar com as linhas
#ifdef
,#else
, e#endif
da mesma forma que posso lidar comgit
as linhas<<<<<<<<
,========
, e>>>>>>>>
.ATUALIZAÇÃO : ... e acabei de encontrar isso: https://stackoverflow.com/questions/16902001/manually-merge-two-files-using-diff
Ele mostra como também posso fazer algo semelhante com o formato diff unificado. Dê
diff
uma-U
opção com um argumento enorme que seja maior que o número máximo de linhas emfile.1
efile.2
. Por exemplo ...Em seguida, ele produzirá isso:
As
+
linhas representam os dados exclusivos emfile.2
e as-
linhas representam os dados exclusivos emfile.1
.E eu posso lidar com essas
+
e-
linhas.Parece que você realmente não se importa com o formato de saída e, em vez disso, só quer saber como identificar quais linhas são de cada arquivo ou são comuns. Dá isso, que tal:
Desconfie de qualquer solução em que você tenha que testar o conteúdo das linhas para um indicador da fonte para essa linha (por exemplo, se você estiver procurando
<<<<<<< file.1
dizer o que é exclusivofile1
- e sefile
contiver uma linha que seja exatamente essa string? ) em vez de um indicador que está sempre e apenas presente em uma posição única em cada linha, pois o teste de qualquer string falhará se essa string puder estar em sua entrada. Com o acima, o primeiro caractere é sempre um indicador de onde a linha veio, portanto, não pode entrar em conflito com o possível conteúdo do arquivo. Se você REALMENTE quisesse obter exatamente o formato de saída de conflitos de mesclagem do git (o que eu não recomendo), você sempre poderia canalizar o acima para um script awk simples para imprimir<<< file
ou o que você quiser quando o primeiro caractere da linha for alterado e, em seguida, remova esse caractere.Devido às limitações das soluções que postei originalmente na minha primeira "Resposta" aqui que envolve
diff -D ...
ediff -U ...
, decidi escrever uma solução em python, usando odifflib
módulo do python.Eu o escrevi para produzir uma saída que parece relativamente semelhante à saída "conflito de mesclagem" do
git
. Ele utiliza delimitadores contendo as strings<<<<<<<<
,========
, e>>>>>>>>
, e como sabemos, isso pode levar a ambiguidades se o texto original contiver strings como esta. No entanto, esse mesmo problema com ambiguidades pode existir na saída de "conflito de mesclagem" degit
, mas como estou confortávelgit
e disposto a aceitá-lo lá, também estou confortável com essas ambiguidades em minha própria solução.A saída não é exatamente a mesma da
git
saída "conflito de mesclagem", mas é semelhante o suficiente para satisfazer meus desejos.Primeiro, aqui está o programa python (limpei o código python original que postei aqui e esta é a versão limpa). Eu chamo esse programa
filemerge
...Aqui estão os arquivos de entrada com os quais eu testei. Eles são semelhantes, mas não exatamente iguais aos arquivos de entrada que postei originalmente na minha pergunta aqui ...
====
file.1
========
file.2
====Eu executo o comando assim...
E estes são os conteúdos resultantes de
file.merged
...Como mencionei, esse não é exatamente o mesmo formato da saída do "conflito de mesclagem" de
git
, mas é muito semelhante e está próximo o suficiente para mim.