Qual é a diferença entre a adição bin
, bin/
, bin/*
e bin/**
no meu arquivo .gitignore? Tenho usado bin/
, mas olhando outros arquivos .gitignore (no arquivo eclipse, a estrela dupla e a única são usadas juntas assim: o tmp/**/*
que há com isso?), Vejo que os dois primeiros padrões também são amplamente usados. Alguém pode explicar as diferenças entre os três?
90
**
: stackoverflow.com/questions/1470572/…Respostas:
bin
corresponde a qualquer arquivo ou diretório denominado 'bin'.bin/
corresponde a qualquer diretório denominado 'bin', o que na verdade significa todo o seu conteúdo, já que o Git não rastreia os diretórios sozinho.bin/*
corresponde a todos os arquivos e diretórios diretamente em qualquerbin/
. Isso evita que o Git encontre automaticamente qualquer arquivo em seus subdiretórios, mas se, digamos, umbin/foo
subdiretório for criado, esta regra não corresponderáfoo
ao conteúdo de.bin/**
corresponde a todos os arquivos e diretórios em qualquerbin/
diretório e todos os seus subdiretórios.A palavra "qualquer" é crítica aqui, uma vez que as regras não são relativas à raiz do repositório e se aplicam a qualquer lugar na árvore do sistema de arquivos. Você deve começar as regras com um
/
(ou!/
para não ignorar), o que significa a raiz do repositório, não a raiz do sistema, para corresponder apenas ao que foi pretendido.AVISO: Você nunca deve usar regras como
dir/*
,/dir/**
etc. sozinhas, a menos que também não ignore algo que existe dentro desse diretório . Omita o asterisco ou você pode perder permanentemente muitos dados de certas invocações degit gc
,git stash
e muito mais.Eu realmente não sei o que devo
tmp/**/*
fazer. Inicialmente pensei que poderia ser usado para combinar arquivos nos subdiretórios do,tmp/
mas não arquivos diretamente presentes neletmp/
. Mas um teste simples parece sugerir que isso ignora todos os arquivos emtmp/
.fonte
bin/
ebin/**
?bin/
irá ignorar o diretório bin,bin/**
mas incluirá o diretório bin, mas nenhum de seu conteúdobin/
irá ignorar o próprio diretório (incluindo todos os subdiretórios e arquivos), enquantobin/**
irá ignorar todos os arquivos no diretório bin e seus subdiretórios, mas não o próprio diretório bin. Se isso é preciso ou não, não tenho certeza.bin/** \n !bin/*
(já que não consigo ver como forçar umabin
corresponde a um arquivo nomeadobin
e ao conteúdo dabin
pasta. Terceiro,bin/*
corresponde a quaisquer arquivos em seus subdiretórios. Vocês ao menos testaram isso?bin
ebin/
diferem apenas porque o último corresponderá apenas a um diretório.bin/**/*
é o mesmo quebin/**
(aparentemente desde 1.8.2, de acordo com a resposta de @VonC).O complicado, que acabei de passar uma hora ou mais arrancando meu cabelo, é isso
bin/
ebin/**
não são exatamente iguais! Já que o anterior ignora o diretório como um todo, e o último ignora cada um dos arquivos dentro dele, e o git em quase todos os casos não se preocupa com diretórios, normalmente não há diferença. No entanto, se você tentar!
cancelar a ignorar um subcaminho, descobrirá que o git (ahem) o ignora se você ignorou o diretório pai! (novamente, em vez do conteúdo do diretório)Isso é mais claro por exemplo, portanto, para um repositório recém-iniciado, configure assim:
Existem os seguintes arquivos não rastreados:
Mas você pode ver que os seguintes arquivos não são ignorados:
E se você tentar adicionar, obterá:
Eu considero esse comportamento um bug. (Está tudo ligado
git version 1.8.4.msysgit.0
)fonte
dir/
edir/**
re. des-ignorar!
acontece porque "Não é possível incluir novamente um arquivo se um diretório pai desse arquivo for excluído" [fonte ]. Confuso, mas feito por motivos de desempenho. Veja uma pergunta relacionada ao SO .Observe que, estritamente falando, git não rastreia diretórios, apenas arquivos. Portanto, não é possível adicionar um diretório, apenas seu conteúdo .
No
.gitignore
entanto, no contexto de git finge entender os diretórios pela única razão deO que isso significa para os padrões de exclusão? Vamos examiná-los em detalhes:
bin
Isso ignora
bin
.bin
Você pode colocar na lista de permissões
bin
arquivos e pastas ignorados adicionando!
entradas subsequentes , mas você não pode colocar na lista de permissões o conteúdo de pastas nomeadasbin
bin/
O mesmo que acima, exceto que não corresponde a arquivos nomeados
bin
. Adicionar um final/
diz ao git para corresponder apenas aos diretórios.bin/*
Isso ignora
bin
bin
bin/**
Isso ignora
bin
bin
fonte
Acabei de fazer um novo repo e tentei algumas coisas. Aqui estão meus resultados:
NOVOS RESULTADOS
git versão 2.10.1.windows.1
bin
diretório com várias camadas de profundidadebin.txt
Test.txt
bin/a/b/bin.txt
bin/a/b/Test.txt
bin/a/bin/bin.txt
bin/a/bin/Test.txt
bin/a/bin.txt
bin/a/Test.txt
bin/bin.txt
bin/Test.txt
bin
ao gitignore: Resultadosbin
diretório (e mais profundo) agora é ignoradobin
parabin/
no gitignore: Resultadosbin/
parabin/*
bin/*
parabin/**
bin/**
parabin/**/
bin/bin.txt
ebin/Test.txt
não são mais ignoradosbin/**/
parabin/**/*
bin/bin.txt
ebin/Test.txt
voltaram a ser ignoradosRESULTADOS ANTIGOS
versão git: 2.7.0.windows.1
bin
diretório com várias camadas de profundidadebin/a/b/Test.txt
bin/a/bin/Test.txt
bin/a/Test.txt
bin/Test.txt
bin
ao gitignore: Resultadosbin
diretório (e mais profundo) agora é ignoradobin
parabin/
no gitignore: Resultadosbin
diretório (e mais profundo) ainda é ignorado (sem alteração)bin/
parabin/*
bin
diretório (e mais profundo) ainda é ignorado (sem alteração)bin/*
parabin/**
bin
diretório (e mais profundo) ainda é ignorado (sem alteração)bin/**
parabin/**/
bin/Test.txt
não é mais ignoradobin/**/
parabin/**/*
bin
diretório (e mais profundo) é ignorado novamentefonte
Observe que o '
**
', quando combinado com um subdiretório (**/bar
), deve ter mudado de seu comportamento padrão, uma vez que a nota de lançamento para git1.8.2 agora menciona:A regra a lembrar (e que ajuda a entender a diferença de intenção por trás dessa sintaxe) é:
Não é possível incluir novamente um arquivo se um diretório pai desse arquivo for excluído.
Normalmente, se você deseja excluir arquivos de uma subpasta de uma pasta ignorar f, você faria:
Isso é:
f/
, a pastaf/
seria ignorada e as regras abaixo relacionadasf
não importariam.f/**
obter o mesmo quef/
, mas ignorar todos os subelementos (arquivos e subpastas).Isso dá-lhe a oportunidade de whitelist (excluir da gitignore) as subpastas:
!f/**/
.f
subpastas não são ignoradas, você pode adicionar uma regra para excluir um arquivo (!f/a/sub/folder/someFile.txt
)fonte
Há outra diferença entre
bin/*
ebin/
.bin/
correspondefoo/bin/test.txt
(como esperado), masbin/*
não, o que parece estranho, mas está documentado: https://git-scm.com/docs/gitignoreA razão para isso parece ser estas regras:
Portanto, se o padrão terminar com uma barra, a barra será removida e tratada como um padrão shell glob, caso em que
bin
correspondefoo/bin/test.txt
. Se terminar com/*
, a barra não é removida e é passada para fnmatch, que não corresponde aos subdiretórios.No entanto, o mesmo não é verdadeiro para
foo/bin/
efoo/bin/*
, porque mesmo depois de remover a barra final defoo/bin/
, ele ainda contém uma barra, então é tratado como um padrão fnmatch, não um glob. Ou seja, não vai combinarbar/foo/bin/test.txt
fonte