Como o git detecta arquivos semelhantes, para sua detecção de renomeação?

91

Wikipedia explica a detecção automática de renomeação:

Resumidamente, dado um arquivo na revisão N, um arquivo com o mesmo nome na revisão N − 1 é seu ancestral padrão. No entanto, quando não há nenhum arquivo com o mesmo nome na revisão N − 1, o Git procura por um arquivo que existia apenas na revisão N − 1 e é muito semelhante ao novo arquivo.

A detecção de renomear aparentemente se resume à detecção de arquivo semelhante. Esse algoritmo está documentado em algum lugar? Seria bom saber quais tipos de transformações são detectadas automaticamente.

mahemoff
fonte

Respostas:

92

Git rastreia o conteúdo do arquivo, não os nomes dos arquivos. Portanto, renomear um arquivo sem alterar seu conteúdo é fácil para o git detectar. (Git não rastreia, mas realiza a detecção ; usando git mvou git rme git addé efetivamente o mesmo.)

Quando um arquivo é adicionado ao repositório, o nome do arquivo está no objeto árvore. O conteúdo real do arquivo é adicionado como um objeto binário grande ( blob ) no repositório. O Git não adicionará outro blob para arquivos adicionais que contenham o mesmo conteúdo. Na verdade, o Git não pode, pois o conteúdo é armazenado no sistema de arquivos com os primeiros dois caracteres do hash sendo o nome do diretório e o restante sendo o nome do arquivo dentro dele. Portanto, detectar renomeações é uma questão de comparar hashes.

Para detectar pequenas alterações em um arquivo renomeado, o Git usa certos algoritmos e um limite para ver se é uma renomeação. Por exemplo, dê uma olhada na -Mbandeira de git diff. Existem também valores de configuração como merge.renameLimit(o número de arquivos a serem considerados ao executar a detecção de renomeação durante uma mesclagem).

Para entender como o git trata arquivos semelhantes (ou seja, quais transformações de arquivo são consideradas como renomeações), explore as opções de configuração e sinalizadores disponíveis, conforme mencionado acima. Você não precisa ser considerado com o como. Para entender como o git realmente realiza essas tarefas, observe os algoritmos para encontrar diferenças no texto e leia o código-fonte do git.

Algoritmos são aplicados apenas para propósitos de diff, merge e log - eles não afetam como o git os armazena. Qualquer pequena mudança no conteúdo do arquivo significa que um novo objeto é adicionado a ele. Não há delta ou diferença acontecendo nesse nível. É claro que, posteriormente, os objetos podem ser empacotados onde os deltas são armazenados em packfiles, mas isso não está relacionado à detecção de renomeação.

manojlds
fonte
57
"Você não precisa ser considerado com o como." - Achei que fosse essa a pergunta?
banho de
2

Existem muitos algoritmos que detectam semelhanças entre os textos, e os sistemas de controle de versão costumam usar esses algoritmos para armazenar apenas a diferença entre duas versões. Ferramentas como WinMerge são inteligentes o suficiente para detectar diferenças, mesmo dentro de linhas, então não vejo uma razão pela qual esses algoritmos não seriam usados ​​para essa detecção de renomeação.

Aqui está uma discussão sobre algoritmos para detectar textos semelhantes . Alguns desses algoritmos podem ser otimizados para linguagens naturais, enquanto outros podem funcionar melhor para o código-fonte, mas, em essência, eles são muito semelhantes.

GolezTrol
fonte