Aguarde...

21 de fevereiro de 2019

Destaques do Git 2.21

Destaques do Git 2.21

O projeto Git de código aberto acaba de lançar o Git 2.21 com recursos e correções de bugs de mais de 60 colaboradores. Nós nos encontramos com você nos últimos lançamentos do Git quando o 2.19 foi lançado . Aqui está uma olhada em alguns dos recursos e mudanças mais interessantes introduzidos desde então.

Datas legíveis para humanos com --date=human

Como parte de sua saída, git logexibe a data em que cada confirmação foi criada. Sem fazer uma seleção alternativa, os timestamps serão exibidos no formato “default” do Git (por exemplo, “Tue Feb 12 09:00:33 2019 -0800”).

Isso é muito preciso, mas muitos desses detalhes são coisas que você já conhece ou não se importa. Por exemplo, se o commit aconteceu hoje, você já sabe em que ano está. Da mesma forma, se um commit aconteceu há sete anos, você não se importa em qual segundo ele foi criado. Então, o que você faz? Você poderia usar --date=relative, o que lhe daria saída como 6 days ago, mas muitas vezes, você quer relacionar “seis dias atrás” para um evento específico, como “minha reunião na quarta-feira passada.” Então, foi seis dias atrás terça-feira, ou foi quarta-feira? estava interessado em?

Git 2,21 introduz um novo formato de data que lhe diz exatamente quando algo ocorreu com apenas a quantidade certa de detalhes: --date=human. Aqui está como git logparece com o novo formato:

Destaques do Git 2.21

Isso é mais preciso --date=relativee mais fácil de consumir do que o peso total --date=default.

Mas e quando você está escrevendo? Aqui, você pode alternar com freqüência entre os formatos humano e legível por máquina ao montar um pipeline. Git 2,21 tem uma opção adequada para essa configuração, também: --date=auto:human. Ao imprimir a saída para um pager, se o Git tiver essa opção, ela atuará como se tivesse sido passada --date=human. Quando de outra forma imprimir a saída para um não-pager, o Git irá agir como se nenhum formato tivesse sido dado. Se humannão é bem a sua velocidade, você pode combinar autocom qualquer outro formato de sua escolha, como --date=auto:relative.

Destaques do Git 2.21

Detectando colisões de caminho insensíveis a maiúsculas e minúsculas

Uma pergunta comum ao Git é: “Depois de clonar um repositório, por que git statusrelatar alguns dos arquivos como modificados?”. Muitas vezes, a resposta é que o repositório contém uma árvore que não pode ser representada em seu sistema de arquivos. Por exemplo, se ele contém file, bem como FILEe seu sistema de arquivos é case-insensitive, Git pode somente check-out um desses arquivos. Pior, o Git não detecta este caso durante o clone; ele simplesmente escreve cada caminho, sem saber que o sistema de arquivos os considera como o mesmo arquivo. Você só descobre que algo deu errado quando você vê uma modificação misteriosa.

As regras exatas para quando isso ocorre variam de sistema para sistema. Além de “dobrar” o que normalmente consideramos caracteres maiúsculos e minúsculos em inglês, você também pode ver isso de conversões específicas de idioma, caracteres não imprimíveis ou normalização Unicode.

No Git 2.20, git cloneagora detecta e reporta a colisão de grupos durante o checkout inicial, o que deve remover parte da confusão. Infelizmente, o Git não consegue consertar o problema para você. O que o committer original colocou no repositório não pode ser verificado como está em seu sistema de arquivos. Então, se você está pensando em colocar arquivos em um projeto multi-plataforma que diferem apenas no caso, o melhor conselho ainda é: não.

Destaques do Git 2.21

Melhorias de desempenho e outros bits

Nos bastidores, muita coisa mudou nos últimos lançamentos do Git também. Estamos dedicando esta seção à visão geral de algumas dessas alterações. Nem todos eles afetarão seu uso diário do Git, mas alguns o farão, e todas as mudanças são especialmente importantes para os administradores do servidor.

Índices multipacote

O Git armazena objetos (por exemplo, representações de arquivos, diretórios e mais que compõem seu repositório Git) nos formatos “loose” e “packed”. Um objeto “solto” é uma codificação compactada de um objeto, armazenada em um arquivo. Um objeto “empacotado” é armazenado em um arquivo de pacotes, que é uma coleção de objetos, escritos em termos de deltas um do outro.

Como pode ser custoso reescrever esses pacotes toda vez que um novo objeto é adicionado ao repositório, os repositórios tendem a acumular muitos objetos soltos ou pacotes individuais ao longo do tempo. Eventualmente, eles são reconciliados durante uma operação de “reembalagem”. No entanto, essa reconciliação não é possível para repositórios maiores, como o repositório do Windows .

Em vez de reembalar, o Git agora pode criar um arquivo de índice multi-pack, que é uma listagem de objetos que residem em vários pacotes, eliminando a necessidade de executar consertos caros (em muitos casos).

Ilhas Delta

Uma importante otimização para os servidores Git é que o formato dos objetos transmitidos é o mesmo dos arquivos de pacote em disco altamente compactados. Isso significa que, em muitos casos, o Git pode servir repositórios para clientes simplesmente copiando bytes do disco sem ter que inflar objetos individuais.

Mas às vezes essa suposição se quebra. Objetos no disco podem ser armazenados como “deltas” uns contra os outros. Quando duas versões de um arquivo têm conteúdo semelhante, podemos armazenar o conteúdo completo de uma versão (a “base”), mas apenas as diferenças em relação à base da outra versão. Isso cria uma complicação ao servir uma busca. Se o objeto Afor armazenado como um delta contra o objeto B, só poderemos enviar ao cliente nossa versão em disco Ase também estivermos enviando-a B(ou se soubermos que ela já existe B). Caso contrário, temos que reconstruir o conteúdo completo Ae comprimá-lo novamente.

Isso acontece raramente em muitos repositórios onde os clientes clonam todos os objetos armazenados pelo servidor. Mas pode ser bastante comum quando vários conjuntos de objetos distintos, mas sobrepostos, são armazenados no mesmo arquivo de pacote (por exemplo, devido a forquilhas de repositório ou solicitações de recebimento não-mescladas). O Git pode armazenar um delta entre objetos encontrados apenas em dois garfos diferentes. Quando alguém clona um dos garfos, eles querem apenas um dos objetos, e temos que descartar o delta.

Git 2.20 resolve isso introduzindo o conceito de “ ilhas delta ” . Administradores de repositórios podem particionar o namespace ref em “ilhas” distintas, e o Git evitará deltas entre ilhas. O resultado final é um repositório que é um pouco maior no disco, mas ainda é capaz de atender os clientes de forma muito mais barata.

Reutilização de Delta com bitmaps

Nós já discutimos a importância de reutilizar deltas em disco quando servimos buscas, mas como sabemos quando o outro lado tem o objeto base que eles precisam usar o delta que enviamos a eles? Se também estamos enviando a base, a resposta é fácil. Mas se não formos, como sabemos se eles têm isso?

Essa resposta é enganosamente simples: o cliente já nos disse quais commits (para que não nos incomodemos em enviá-los novamente). Se eles afirmam ter um commit que contém o objeto base, então podemos reutilizar o delta. Mas há um problema: não precisamos saber apenas sobre o commit mencionado, mas também o gráfico inteiro do objeto. A base pode ter sido parte de um commit de centenas ou milhares de commits profundamente na história do projeto.

O Git não percorre todo o gráfico de objetos para verificar possíveis bases porque é muito caro fazê-lo. Por exemplo, andar todo o gráfico de um kernel Linux leva cerca de 30 segundos.

Felizmente, já existe uma solução no Git: bitmaps de acessibilidade . O Git possui uma estrutura de dados opcional no disco para registrar os conjuntos de objetos “acessíveis” de cada commit. Quando esses dados estão disponíveis, podemos consultá-los para determinar rapidamente se o cliente tem um objeto base. Isso resulta no servidor gerando pacotes menores que são produzidos mais rapidamente para uma experiência geral de busca mais rápida.

Anúncio de referência alternativo personalizado

Alternativas de repositório são uma ferramenta que os administradores do servidor têm à sua disposição para reduzir as informações redundantes. Quando dois repositórios são conhecidos por compartilhar objetos (como uma bifurcação e seu pai), a bifurcação pode listar o pai como uma “alternativa”, e quaisquer objetos que a bifurcação não tenha, ela pode procurar em seu pai. Isso é útil, já que podemos evitar o armazenamento do dobro do grande número de objetos compartilhados entre o fork e o pai.

Da mesma forma, um repositório com alternativas anuncia “dicas” ao receber um push. Em outras palavras, antes de gravar do seu computador para um controle remoto, esse controle remoto lhe dirá quais são as dicas de suas ramificações, para que você possa determinar informações que já são conhecidas pelo controle remoto e, portanto, usar menos largura de banda. Quando um repositório tem alternativas, o anúncio de dicas é a união de todas as dicas de filiais locais e alternativas.

Mas o que acontece quando calcular as dicas de uma alternativa é mais caro do que um cliente enviando dados redundantes? Isso faz com que o push seja tão lento que desativamos esse recurso por anos no GitHub. No Git 2.20, os repositórios podem ligar-se à forma como eles enumeram dicas alternativas e tornam a transação correspondente muito mais rápida.

Petiscos

Agora que destacamos algumas das alterações nos últimos dois lançamentos, queremos compartilhar um resumo de algumas outras alterações interessantes. Como sempre, você pode aprender mais clicando no link “source” ou lendo a documentação ou notas de lançamento .

  • Você já tentou rodar git cherry-pickem um commit merge apenas para falhar? Você pode ter descoberto que a correção envolve passar -m1e seguir em frente. Na verdade, -m1diz para selecionar o primeiro pai como a linha principal e repete os commits relevantes. Antes do Git 2.21, passar esta opção em um commit não-merge causou um erro, mas agora ele transparentemente faz o que você quis dizer. 
  • Os usuários veteranos do Git de nossa última postagem podem se lembrar que git branch -lestabelecem um reflog para uma ramificação recém-criada, em vez de listar todas as ramificações. Agora, em vez de fazer algo que você quase certamente não quis dizer, git branch -llistará todos os ramos do seu repositório, mantendo-se em linha com outros comandos que aceitam -l.
  • Se você já ficou preso ou esquecido do que um determinado comando ou sinalizador faz, você pode ter corrido git --help(ou git -h) para aprender mais. No Git 2.21, essa invocação agora segue os aliases e mostra o texto de ajuda do comando com alias. 
  • Em repositórios com grandes checkouts em disco, git statuspode levar muito tempo para ser concluído. Para indicar que está progredindo, o comando status agora exibe uma barra de progresso.
  • Muitas partes do Git foram historicamente implementadas como scripts de shell, chamando as ferramentas escritas em C para fazer o trabalho pesado. Embora isso permitisse a criação rápida de protótipos, as ferramentas resultantes poderiam ser lentas devido à sobrecarga de executar muitos programas separados. Há esforços contínuos para mover esses scripts em C, afetando git submodulegit bisectgit rebase. Você pode notar, rebaseem particular, ser muito mais rápido, devido ao trabalho árduo dos alunos do Summer of Code, Pratik Karki e Alban Gruin .
  • -Gopção diz git logpara mostrar somente commits cujos diffs correspondam a um padrão específico. Mas até o Git 2.21, ele estava pesquisando arquivos binários como se fossem textos, o que tornava as coisas mais lentas e muitas vezes produziam resultados confusos.

É tudo por agora

Passamos por algumas das mudanças que aconteceram nas últimas versões, mas há muito mais a descobrir. Leia as notas da versão 2.21 ou revise as notas da versão anterior norepositório Git .

Postado em BlogTags:
Escreva um comentário