11 pontos por GN⁺ 4 시간 전 | 3 comentários | Compartilhar no WhatsApp
  • As regras de ignorar arquivos no Git se dividem em três níveis conforme o escopo de compartilhamento: .gitignore, .git/info/exclude e ~/.config/git/ignore
  • O .gitignore é commitado junto com o código do repositório, então é o lugar para colocar regras compartilhadas que a equipe ou o projeto devem aplicar em conjunto
  • Itens como arquivos pessoais ou arquivos de trabalho local, que são necessários no repositório mas difíceis de justificar como regra da equipe, são mais adequados em .git/info/exclude
  • Arquivos que precisam ser excluídos repetidamente em todos os repositórios, como .DS_Store no macOS, podem ser colocados em ~/.config/git/ignore, o arquivo de ignore global da máquina
  • git check-ignore -v <nome_do_arquivo> é útil para rastrear qual regra está fazendo um arquivo ser ignorado; se não houver regra correspondente, não há saída

Onde as regras de ignore do Git se aplicam

  • O Git pode processar regras para ignorar arquivos em três locais
    • .gitignore
    • .git/info/exclude
    • ~/.config/git/ignore

.gitignore: regras compartilhadas que são commitadas no repositório

  • .gitignore é o arquivo comum onde se escrevem os nomes dos arquivos a serem ignorados
  • Ele é versionado no Git junto com o restante do código
  • Arquivos que correspondem às regras do .gitignore não são considerados durante a execução de comandos do git

.git/info/exclude: regras pessoais por repositório

  • O arquivo exclude fica dentro do diretório .git de todo repositório Git
  • Alterações nesse arquivo não são commitadas no Git
  • Em um repositório Git novo, ele normalmente contém algumas linhas de comentário
  • É apropriado para arquivos que você quer ignorar apenas naquele repositório, mas não quer colocar no .gitignore
    • Exemplo: se você quiser manter notes.txt fora dos commits sem adicioná-lo ao .gitignore do projeto, por ser algo necessário apenas no seu fluxo de trabalho pessoal, adicione notes.txt em .git/info/exclude

~/.config/git/ignore: regras globais da máquina

  • O arquivo global de ignore fica em ~/.config/git/ignore no diretório home
  • Nomes de arquivos adicionados ali passam a ser ignorados globalmente no nível da máquina
  • Ele não é commitado no Git nem está vinculado a um repositório específico
  • É um bom lugar para colocar arquivos que você quer ignorar em todos os repositórios Git do computador
    • Exemplo: no macOS, faz sentido adicionar .DS_Store aqui

Alterando o caminho do arquivo global de ignore

  • O arquivo global de ignore pode ser definido para outro arquivo
  • Para usar .gitignore_global como arquivo global de ignore do Git, execute o seguinte comando
git config --global core.excludesFile ~/.gitignore_global
  • Para voltar à configuração padrão, execute o seguinte comando
git config --global --unset core.excludesFile

Como verificar qual regra está ignorando um arquivo

  • Com git check-ignore -v <nome_do_arquivo>, você pode verificar qual regra está fazendo um arquivo específico ser ignorado
  • Para verificar como .DS_Store está sendo ignorado, execute o seguinte comando dentro de um repositório Git
git check-ignore -v .DS_Store
  • Se o .gitignore do repositório estiver ignorando .DS_Store, um exemplo de saída será o seguinte
$ git check-ignore -v .DS_Store
.gitignore:1:.DS_Store	.DS_Store
  • Se o .git/info/exclude do repositório estiver ignorando .DS_Store, um exemplo de saída será o seguinte
$ git check-ignore -v .DS_Store
.git/info/exclude:7:.DS_Store	.DS_Store
  • Se o arquivo global ~/.config/git/ignore estiver ignorando .DS_Store, um exemplo de saída será o seguinte
$ git check-ignore -v .DS_Store
/Users/nelson/.config/git/ignore:2:.DS_Store	.DS_Store
  • Se o arquivo global de ignore personalizado .gitignore_global estiver ignorando .DS_Store, um exemplo de saída será o seguinte
$ git check-ignore -v .DS_Store
/Users/nelson/.gitignore_global:1:.DS_Store	.DS_Store
  • Se não houver nenhuma regra para ignorar um arquivo específico, o comando git check-ignore -v não produz nenhuma saída

3 comentários

 
sudoeng 1 시간 전

Também pode ser útil colocar coisas como o spec de trabalho ou arquivos plan.md em .git/info/exclude.

 
yangeok 2 시간 전

Então existia uma configuração na raiz, hein? haha

 
GN⁺ 4 시간 전
Comentários do Hacker News
  • Artigo interessante, mas faltou o meu recurso favorito de quase ignorar no Git: .gitattributes
    Com esse arquivo, dá para dizer ao Git para "ignorar" diferenças de arquivos específicos. Por exemplo, em projetos Node, package-lock.json é quase puro ruído do ponto de vista do Git. Você acaba vendo diferenças enormes com versões exatas de bibliotecas, enquanto a informação real de versão, mais legível para humanos, já está separada no package.json
    Se adicionar uma linha package-lock.json -diff no .gitattributes da raiz do projeto, o arquivo continua sendo staged/commitado, mas o git diff deixa de mostrar aquelas diferenças gigantes e sem significado

    • package-lock.json não deveria ser ruído. Se você não pretende atualizá-lo de propósito, então não deveria atualizá-lo; caso contrário, fica exposto a risco de cadeia de suprimentos sem motivo
      Se mudanças em package-lock.json aparecem com frequência de forma inesperada, então algo está sendo feito errado
    • package-lock.json mostra todas as dependências transitivas, enquanto package.json mostra apenas dependências diretas. Então dizer que o segundo traz a "versão real legível por humanos" não está correto
      Os dois têm propósitos diferentes, e dizer que sempre dá para ignorar diferenças no arquivo de lock é perigoso
    • Para quem faz upgrade de dependências e rastreia a causa de bugs, eu ficaria realmente irritado se o git diff não mostrasse as diferenças do arquivo de lock
      Entendo que pareça ruído linha a linha, mas quando precisa, precisa mesmo
  • Configuração global/de usuário para exclusões é um recurso que deveria ser mais conhecido. Eu recebo com frequência mudanças querendo adicionar arquivos de IDE/OS/IA ao .gitignore de todos os projetos, e quando explico que dá para colocar isso na configuração padrão, ignorar em todo lugar, não mexer em cada projeto e ainda evitar o risco de commitar sem querer em projetos cujo .gitignore não foi atualizado, a maioria gosta da ideia
    Minha regra pessoal é que o .gitignore dentro do repositório deveria ser usado só para itens específicos do repositório, como artefatos de build e pastas de dependências, enquanto a maioria das ferramentas de usuário deveria ficar na configuração individual de cada um

    • O fato de precisar divulgar com frequência a configuração global de .gitignore é uma consequência natural do princípio de usar o .gitignore do repositório apenas para itens específicos do repositório
      Se a ideia é gastar menos tempo de todo mundo, é melhor simplesmente colocar esses arquivos no .gitignore em todos os projetos
    • Sempre coloquei esses arquivos no .gitignore do projeto para evitar que alguém, por desconhecimento, os adicionasse ao projeto
      No fim das contas, isso seria removido do Git de qualquer forma, e a pessoa teria dor de cabeça; então eu já bloqueava antes por gentileza. Talvez eu seja menos gentil daqui para frente
    • Prefiro o lado do gitignore porque ele sobrevive à reconstrução de contêineres de desenvolvimento
      Se for para evitar gitignore, ainda dá para restaurar/manter a configuração com script de geração ou volume, mas aí você precisa de script extra ou configuração de mount no devcontainer em vez de uma simples linha no .gitignore
    • Não é contraditório ver o mesmo comportamento errado repetidamente e, ao mesmo tempo, impor uma regra rígida que proíbe explicitamente a forma mais fácil de corrigir esse comportamento?
  • Quanto à configuração global do Git e arquivos de ignore, acho mais correto usar ~/.config/git/ignore e ~/.config/git/config em vez de criar ~/.gitignore_global e mexer na configuração
    Quando você usa ~/.config/ para várias coisas, a quantidade de dotfiles na raiz fica bem menor
    O Git exclude é menos usado porque não é commitado no repositório; então, sempre que você quer usá-lo, precisa recriá-lo. Não estou dizendo que isso é ruim, só que é esse o motivo de ser menos usado

    • Como bônus, se você versionar o diretório ~/.config, depois fica fácil modificar e compartilhar
    • Você também pode usar ~/.cvsignore para outras ferramentas que leem o mesmo arquivo
  • Não sei onde aprendi isso, mas adicionei attic ao meu Git ignore global
    Aí posso criar um diretório attic em qualquer projeto para guardar coisas aleatórias que jamais deveriam ser commitadas. Ainda não vi um repositório que de fato verifique a existência de um diretório desses

    • Também dá para fazer meio que o contrário, mas precisa ser caso a caso
      Se houver um diretório como attic, você pode criar attic/.gitignore com /**, e isso faz com que o diretório e todo o conteúdo dele sejam ignorados, inclusive o próprio arquivo de ignore
      Normalmente eu dou ao meu diretório uma versão com um único caractere U+1F4A9, mas o HN não permite colocar isso nos comentários
    • No meu caso eu uso aux
      Coloco dentro dele um .gitignore contendo apenas um asterisco *, e isso faz com que ele ignore a si mesmo e todo o conteúdo
    • Eu também faço isso. Só que chamo de .local
    • O meu é scratch/
      Até agora ainda não me atrapalhou
  • Sobre ignores por usuário: no macOS, o ideal seria colocar .DS_Store ali, mas isso exige que todos os usuários de Mac do projeto façam o mesmo
    Se forem duas pessoas ou mais, talvez seja melhor não deixar isso a cargo de cada uma

    • Não sei ao certo de onde veio, mas nos meus dois Macs (um com Ventura, outro com Sequoia) existe uma entrada .DS_Store no arquivo ~/.gitignore_global, e a configuração global do Git também já está definida para ignorar os itens desse arquivo
      A data desse arquivo no Mac novo é de dois dias antes de eu encomendá-lo, e não lembro de ter configurado isso manualmente, então imagino que tenha vindo por padrão. O Mac antigo provavelmente era parecido e, olhando as versões do macOS, isso talvez já seja o padrão há bastante tempo
      Então talvez já tenha passado a época em que era preciso adicionar .DS_Store/ ao .gitignore
    • Seu jeito de olhar minoria e maioria é bem peculiar. Se um usuário de macOS trabalha em dez projetos, faz mais sentido adicionar essa linha nos dez projetos ou resolver isso na mão desse único usuário?
  • Uau, como eu não sabia disso? Sou desenvolvedor profissional de software há 20 anos e sempre usei só .gitignore
    Percebi que nunca nem me perguntei se havia um jeito melhor do que bagunçar o .gitignore com todo tipo de exclusão que só importa para mim. Eu simplesmente aceitava o mundo como ele aparecia
    Hoje o mundo ficou um pouco melhor

  • Uso muito .git/info/exclude. É perfeito para scripts/Makefile só locais, que não são necessários para colaboradores nem poderiam ser usados por eles

    • Fiquei curioso sobre que exemplos existem de scripts que outros colaboradores não poderiam usar. Algo como scripts para fluxo de trabalho de PR, por exemplo?
    • Já faz bastante tempo que uso uma função shell que empurra para .git/info/exclude todos os arquivos não rastreados mostrados por git status
      Normalmente aplico isso depois de add e commit no que eu realmente quero colocar no repositório
  • Em diretórios de projeto com configuração Git por projeto diferente para vários repositórios, eu uso arquivos de excludes desta forma
    https://laszlo.nu/blog/project-level-git-config.html

  • Tenho alguns aliases relacionados que uso
    assume = update-index --assume-unchanged
    unassume = update-index --no-assume-unchanged
    assumed = "!git ls-files -v | grep ^h | cut -c 3-"
    unassumeall = "!git assumed | xargs git update-index --no-assume-unchanged"
    assumeall = "!git st -s | awk {'print $2'} | xargs git assume"

  • Para arquivos já rastreados, também existe git update-index --[no]-skip-worktree
    Pode ser útil para experimentos locais, mas como não é uma funcionalidade que o Git exponha muito bem, acaba sendo um pouco chato de usar. Você precisa lembrar do que configurou e, se esquecer, isso pode bloquear outras operações, como checkout