Por que os repositórios Git / Mercurial usam menos espaço?

15

Eu li em várias discussões aqui e no SO que os repositórios DVCS usam aproximadamente o mesmo ou menos espaço que suas contrapartes centralizadas. Eu posso ter perdido, mas não encontrei uma boa explicação sobre o motivo. Ninguem sabe?

Alex Florescu
fonte
1
Não, obrigado! Portanto, entendo daqueles que existem duas respostas: compactação usando zlib e salvando objetos como arquivos de pacote, quando possível. Os exemplos do Mozilla também são ótimos!
Alex Florescu
1
@ Alex Não, isso perde o principal motivo. O SVN salva instantâneos completos, Git e Mercurial apenas salvam a revisão HEAD e as diferenças. O uso da compactação convencional pode fornecer taxas de melhor caso, de cerca de 60 a 80% de compactação. Usar diffs pode fornecer até 99%. Esses números são arrancados da minha bunda - números reais podem ser diferentes; a tendência será a mesma.
Konrad Rudolph
@KonradRudolph, não é disso que se trata o packfiles?
Alex Florescu
@ Alex Na verdade não. Tanto quanto sei, o packfile também está compactando vários arquivos em um. Isso não está necessariamente relacionado.
Konrad Rudolph

Respostas:

18

De minha própria experiência, as seguintes afirmações são verdadeiras:

  • O Git é muito eficiente no armazenamento de arquivos de texto e apenas no armazenamento desses arquivos que foram alterados. portanto, ao fazer uma comparação do SVN e do Git para comparar os tamanhos do repositório, eles podem ser semelhantes ou pode haver uma pequena vantagem para o Git.
  • Isso está completamente errado se você comparar o tamanho dos repositórios em que uma quantidade significativa de arquivos são arquivos de escritório (como MS Word, Excel, Powerpoint, ...). Aqui, o Git também armazena cópias completas, o que significa que 10 pequenas alterações em uma pilha de slides do powerpoint resultam em 10 cópias completas, onde o Subversion apenas armazena um diff binário, que pode ser um fator 100 menor.

Se você comparar o local do checkout (que é um repositório em si com o Git), a história é totalmente diferente:

  • O Subversion armazena para cada arquivo uma cópia completa, de modo que o tamanho do local do checkout é normalmente duas vezes o tamanho dos arquivos.
  • O Git armazena o histórico completo do repositório localmente, portanto, dependendo do tamanho do histórico, este pode ser menor ou muito maior que o da cópia de verificação do Subversion.

Se você comparar a quantidade de bytes que precisa baixar ou enviar, será diferente novamente.

  • O Subversion normalmente tem que enviar ou receber menos bytes, porque apenas envia diferenças. Ele precisa fazer isso em cada confirmação e atualização.
  • O Git precisa obter o repositório inteiro (inicialmente) e, em seguida, envia arquivos completos (compactados?) Que não são tão diferentes para arquivos de texto, mas podem ser diferentes para arquivos binários. E sim, o Git só faz isso quando você envia ou envia algo para o repositório remoto.

Portanto, no final, você compara maçãs com laranjas e, dependendo do que você quer fazer com o Subversion ou Git, o resultado pode ser diferente.


O @jk perguntou sobre cópias completas ou diferenças binárias, e eu não pude responder a essa pergunta. Perguntei a Matthew McCullough, que deu um workshop sobre Git recentemente em Jax 2012 (que visitei). Ele reservou um tempo (muito obrigado a ele) para explicar com uma essência detalhada o trabalho interno do Git. Então, sim, existe uma compactação trabalhando lá (e farei um experimento com um arquivo do Microsoft Office e o compararei com a essência dele), mas não, a compactação é feita em todo o arquivo. Citando sua essência:

Objetos soltos são gravados no formato compactado, mas não delta, no momento de cada confirmação.

mliebelt
fonte
1
tem certeza de que o git armazena cópias completas dos arquivos do office? Eu acho que também armazena diffs binários. é claro que o problema realmente com esse tipo de arquivo é que eles já estão compactados, portanto uma pequena alteração pode fazer com que o arquivo inteiro seja alterado
jk.
2
Perguntou a alguém (por e-mail) que sabe muito mais do que eu e, então, incluirá sua resposta na minha resposta.
Mliebelt
6
O Git trata os arquivos de texto e binários exatamente da mesma maneira em todos os aspectos em relação ao armazenamento. Os objetos soltos vs. compactados não estão relacionados ao texto vs. binário. A razão pela qual os arquivos binários geralmente resultam em diferenças muito maiores do que os arquivos de texto é que muitos formatos binários (incluindo todos os novos formatos de escritório) já estão compactados e, portanto, mesmo uma pequena alteração no conteúdo geralmente causa grandes alterações no blob binário resultante. Isso é igualmente preocupante para o git e o subversion, mas o subversion apenas aplica a penalidade no servidor, enquanto o git está em todo lugar.
Jan Hudec
4
Os objetos soltos versus compactados não têm nada a ver com texto versus binário. É a amortização do difícil trabalho de encontrar as diferenças binárias. A velocidade é um recurso importante do git; portanto, durante a operação regular, o git apenas fecha os novos dados e os coloca no repositório. São objetos soltos. Do que quando você pede, chamando git gcou muitos objetos soltos se acumulam, ele encontra bons candidatos para compactá-los com delta (o git pode ser diferente da versão anterior), armazena os deltas em um "pacote" e remove os objetos soltos.
Jan Hudec
3
Para aqueles que estão interessados ​​em números do mundo real: acabei de comparar duas cópias de trabalho do mesmo repositório. A cópia de trabalho SVN é de cerca de 2,9 GB, a cópia de trabalho GIT é de cerca de 0,8 GB.
JensG