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/*

?


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


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


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

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.


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

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.


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).


14

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


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


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.