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.
Respostas:
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 mv
ougit rm
egit 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
-M
bandeira degit diff
. Existem também valores de configuração comomerge.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.
fonte
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.
fonte