Como ignoro arquivos em um diretório no Git?

544

Qual é a sintaxe adequada para o .gitignorearquivo ignorar arquivos em um diretório?

Seria

config/databases.yml
cache/*
log/*
data/sql/*
lib/filter/base/*
lib/form/base/*
lib/model/map/*
lib/model/om/*

ou

/config/databases.yml
/cache/*
/log/*
/data/sql/*
/lib/filter/base/*
/lib/form/base/*
/lib/model/map/*
/lib/model/om/*

?

Chris McKnight
fonte
5
a .gitignorediferença entre arquivos e diretórios que ignora? por exemplo, datavs data/significa coisas diferentes?
Charlie Parker
6
@CharlieParker yes-ish: dataignorará os arquivos e diretórios correspondentes, data/ignorará apenas os diretórios correspondentes.
jox
Lembre-se sempre de que você preparou ou confirmou o arquivo que está tentando ignorar, então não há como ignorá-lo :( Apenas meus 2 centavos depois de pensar que eu tinha errado meu padrão e desperdiçado um quarto de hora.
Adam
@ Adam correto, você precisaria atualizar o .gitignore e depois desstage / git rm --cache o arquivo.
Chris McKnight

Respostas:

374

FORMATO DO PADRÃO

  • Uma linha em branco não corresponde a nenhum arquivo, portanto pode servir como um separador para facilitar a leitura.

  • Uma linha que começa com #serve como um comentário.

  • Um prefixo opcional !que nega o padrão; qualquer arquivo correspondente excluído por um padrão anterior será incluído novamente. Se um padrão negado corresponder, isso substituirá as origens de padrões de precedência mais baixa.

  • Se o padrão terminar com uma barra, ele será removido com a finalidade da descrição a seguir, mas somente encontraria uma correspondência com um diretório. Em outras palavras, foo/corresponderá a um diretório fooe caminhos abaixo dele, mas não a um arquivo regular ou a um link simbólico foo(isso é consistente com a maneira como o pathspec funciona em geral no git).

  • Se o padrão não contiver uma barra /, o git o tratará como um padrão shell glob e procurará uma correspondência com o nome do caminho em relação à localização do .gitignorearquivo (em relação ao nível superior da árvore de trabalho, se não em um .gitignorearquivo).

  • Caso contrário, o git trata o padrão como um shell shell adequado para consumo fnmatch(3)com a FNM_PATHNAMEbandeira: curingas no padrão não corresponderão a /no nome do caminho. Por exemplo, Documentation/*.htmlcorresponde Documentation/git.htmlmas não Documentation/ppc/ppc.htmlou tools/perf/Documentation/perf.html.

  • Uma barra à esquerda corresponde ao início do nome do caminho. Por exemplo, /*.ccorresponde , cat-file.cmas não mozilla-sha1/sha1.c.

Você pode encontrar mais aqui

git help gitignore
ou
man gitignore

Op De Cirkel
fonte
2
Como posso colocar um arquivo .gitignore no nível superior e fazê-lo funcionar em qualquer pasta abaixo dele? Obrigado.
Royi 18/03/2015
104
-1 TL; DR e mal responde à pergunta. É sobre diretórios, não arquivos, então a seção em negrito é apenas apropriada com alguma ginástica mental. @Jefromi foi mais direto.
Bob Stein
Eu li o homem, e a resposta de @ Jefromi é melhor - desde que você também leia o aviso de @ jox - e @ Luke Hutton pode ser mais útil para ignorar, por exemplo, arquivos de projeto IDE.
WillC
1
Esta é realmente uma cópia e colar a partir da documentação git
Mcont
1
Não tenho certeza (essencialmente) cópia-colar uma manpágina ou documento oficial é o melhor formato para SO ...
jdk1.0
183

Seria o primeiro. Vá também por extensões em vez de estrutura de pastas.

Ou seja, meu exemplo de desenvolvimento em C # ignora o arquivo:

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
ipch/
obj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad

#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*

#Project files
[Bb]uild/

#Subversion files
.svn

# Office Temp Files
~$*

Atualizar

Eu pensei em fornecer uma atualização a partir dos comentários abaixo. Embora não responda diretamente à pergunta do OP, consulte o seguinte para obter mais exemplos de .gitignoresintaxe.

Wiki da comunidade (sendo constantemente atualizado):

.gitignore para projetos e soluções do Visual Studio

Mais exemplos com o uso específico da linguagem podem ser encontrados aqui (graças ao comentário de Chris McKnight):

https://github.com/github/gitignore

Luke Hutton
fonte
5
@Stallman, esse é o range. Por isso, combina *.Objtão bem quanto *.obj.
Norbert
131

Os caminhos que contêm barras são considerados relativos ao diretório que contém o arquivo .gitignore - geralmente o nível superior do seu repositório, embora você também possa colocá-los em subdiretórios.

Portanto, como em todos os exemplos que você fornece, os caminhos contêm barras, as duas versões são idênticas. A única vez em que você precisa colocar uma barra principal é quando não uma no caminho. Por exemplo, para ignorar foo apenas no nível superior do repositório, use /foo. Simplesmente escrever fooignoraria qualquer coisa chamada foo em qualquer lugar do repositório.

Seus curingas também são redundantes. Se você deseja ignorar um diretório inteiro, simplesmente nomeie-o:

lib/model/om

O único motivo para usar curingas da maneira que você usa é se você pretende posteriormente ignorar algo no diretório:

lib/model/om/*      # ignore everything in the directory
!lib/model/om/foo   # except foo
Cascabel
fonte
5
Explicação melhor do que resposta aceita para esta pergunta
eerrzz
78

Uma barra inicial indica que a entrada ignorar deve ser válida apenas no diretório em que o arquivo .gitignore reside. A especificação *.oignoraria todos os arquivos .o nesse diretório e todos os subdiretórios, enquanto /*.oos ignoraria nesse diretório, enquanto os /foo/*.oignoraria apenas em /foo/*.o.

jørgensen
fonte
34

Se você deseja colocar um arquivo .gitignore no nível superior e fazê-lo funcionar em qualquer pasta abaixo dele, use /**/ .

Por exemplo, para ignorar todos os *.maparquivos em uma /src/main/pasta e subpastas, use:

/src/main/**/*.map
petrsyn
fonte
Eu precisava fazer isso. Não sei por que você precisa de dois ** . Um foi o suficiente para mim.
Novocaine
8
** partidas também arquivos em subdiretórios
petrsyn
Obrigado pela informação @petrsyn
Novocaine
30

Ambos os exemplos da pergunta são realmente muito ruins que podem levar à perda de dados!

Meu conselho: nunca anexe /*diretórios em arquivos .gitignore, a menos que você tenha um bom motivo!

Uma boa razão seria, por exemplo, o que Jefromi escreveu: "se você pretende posteriormente ignorar algo no diretório" .

A razão pela qual isso não deveria ser feito é que o acréscimo /*aos diretórios funciona, por um lado, da maneira que ignora corretamente todo o conteúdo do diretório, mas, por outro lado, tem um efeito colateral perigoso:

Se você executar git stash -u(para esconder temporariamente arquivos rastreados e não rastreados) ou git clean -df(para excluir arquivos não rastreados, mas manter ignorados) em seu repositório, todos os diretórios ignorados com um anexo /*serão excluídos irreversivelmente !

Alguma experiência

Eu tive que aprender isso da maneira mais difícil. Alguém da minha equipe estava anexando/* alguns diretórios em nosso .gitignore. Ao longo do tempo, tive ocasiões em que certos diretórios desapareceram repentinamente. Diretórios com gigabytes de dados locais necessários para a nossa aplicação. Ninguém poderia explicar e eu sempre lembro de baixar novamente todos os dados. Depois de um tempo, tive a noção de que isso poderia ter a ver git stash. Um dia, eu queria limpar meu repositório local (enquanto mantinha os arquivos ignorados) e estava usando, git clean -dfe novamente meus dados se foram. Desta vez, tive o suficiente e investiguei o problema. Eu finalmente percebi que o motivo é o anexo /*.

Suponho que isso possa ser explicado de alguma forma pelo fato de que directory/* ignorar todo o conteúdo do diretório, mas não o próprio diretório. Portanto, não é considerado rastreado nem ignorado quando as coisas são excluídas. Mesmo assim, git statuse git status --ignoreddê uma imagem um pouco diferente.

Como reproduzir

Aqui está como reproduzir o comportamento. Atualmente, estou usando o Git 2.8.4.

Um diretório chamado localdata/com um arquivo fictício nele ( important.dat) será criado em um repositório git local e o conteúdo será ignorado ao ser /localdata/*inserido no .gitignorearquivo. Quando um dos dois comandos git mencionados for executado agora, o diretório será (inesperadamente) perdido.

mkdir test
cd test
git init
echo "/localdata/*" >.gitignore
git add .gitignore
git commit -m "Add .gitignore."
mkdir localdata
echo "Important data" >localdata/important.dat
touch untracked-file

Se você fizer um git status --ignoredaqui, receberá:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  untracked-file

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

  localdata/

Agora, faça

git stash -u
git stash pop

ou

git clean -df

Nos dois casos, o diretório supostamente ignorado localdata desaparecerá!

Não tenho certeza se isso pode ser considerado um bug, mas acho que é pelo menos um recurso que ninguém precisa.

Vou relatar isso na lista de desenvolvimento do git e ver o que eles pensam sobre isso.

jox
fonte
15

Seria:

config/databases.yml
cache
log
data/sql
lib/filter/base
lib/form/base
lib/model/map
lib/model/om

ou possivelmente até:

config/databases.yml
cache
log
data/sql
lib/*/base
lib/model/map
lib/model/om

no caso de filtere formserem os únicos diretórios na lib que possuem um basesubdiretório que precisa ser ignorado (veja como um exemplo do que você pode fazer com os asterics).

aefxx
fonte
14

O primeiro. Esses caminhos de arquivo são relativos de onde está o arquivo .gitignore.

Unixmonkey
fonte
2
Isso é verdade apenas para padrões que contêm uma barra. Um único nome de diretório como "mydir" também ignorará os diretórios (e arquivos) localizados em subpastas a qualquer profundidade. Apenas colocar uma barra na frente o tornará relativo de onde está o arquivo .gitignore.
jox
4

Estou mantendo um serviço baseado em GUI e CLI que permite gerar .gitignoremodelos com muita facilidade em https://www.gitignore.io .

Você pode digitar os modelos que deseja no campo de pesquisa ou instalar o alias da linha de comando e executar

$ gi swift,osx

Joe
fonte
0

Um exemplo de arquivo .gitignore pode se parecer com um abaixo para um projeto do Android Studio

# built application files
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties


#Eclipse
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
YourProjetcName/.gradle/
YourProjetcName/app/build/
*/YourProjetcName/.gradle/
*/YourProjetcName/app/build/

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# PDT-specific
.buildpath

# Proguard folder generated by Eclipse
proguard/

# Intellij project files
*.iml
*.ipr
*.iws
.idea/
/build
build/
*/build/
*/*/build/
*/*/*/build/
*.bin
*.lock
YourProjetcName/app/build/
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
.gradle/
app/build/
*app/build/

# Local configuration file (sdk path, etc)
local.properties
/YourProjetcName/build/intermediates/lint-cache/api-versions-6-23.1.bin
appcompat_v7_23_1_1.xml
projectFilesBackup
build.gradle
YourProjetcName.iml
YourProjetcName.iml
gradlew
gradlew.bat
local.properties
settings.gradle
.gradle
.idea
android
build
gradle
Shirish Herwade
fonte