A abordagem ingênua é find dir1 dir2 dir3 -type d -name .git | xargs -I {} dirname {}
, mas é muito lenta para mim, porque eu tenho muitas estruturas de pastas profundas nos repositórios git (pelo menos eu acho que esse é o motivo). Eu li sobre isso que posso usar prune
para impedir que o find seja recursivo em diretórios, uma vez que ele encontrou algo, mas há duas coisas. Não sei ao certo como isso funciona (quero dizer, não entendo o que prune
faz, embora tenha lido a página de manual) e o segundo não funcionaria no meu caso, porque impediria find
recursão na .git
pasta, mas não em todos outras pastas.
Então, o que eu realmente preciso é:
para todos os subdiretórios, verifique se eles contêm uma .git
pasta e se é, então pare de procurar nesta ramificação do sistema de arquivos e relate o resultado. Seria perfeito se isso também excluísse qualquer diretório oculto da pesquisa.
getpof .git
é o que eu uso. github.com/thrig/scripts/blob/master/filesys/getpof.cRespostas:
Ok, ainda não tenho muita certeza de como isso funciona, mas eu testei e funciona.
Estou ansioso para fazer o mesmo mais rápido.
fonte
-prune
maneira: você começa na raiz de uma árvore e a move para baixo; quando uma determinada condição se aplica, você corta uma subárvore inteira (como uma "poda real"), para que não veja mais nós nessa subárvore .-type d
qual condiçãotest -e ...
é verdadeira e, se for verdade, executamos ações-print -prune
que significam imprimi-la e cortar subárvore, certo?find . -type d -exec test -e '{}/.git' \; -print -prune | parallel cd "{}" \&\& git pull --rebase
GNUparallel
é um substituto muito útil paraxargs
Solução possível
Para GNU
find
e outras implementações que suportam-execdir
:(veja os comentários)
Coisas discutidas anteriormente
Solução se a poda abaixo
.git
for suficienteSe
-printf '%h'
for suportado (como no caso do GNUfind
), não precisamosdirname
:Depois de encontrar uma pasta
.git
no caminho atual, ela será impressa e depois deixará de olhar mais abaixo na subárvore.Solução para remover toda a árvore de pastas quando
.git
for encontradoUsando
-quit
se o seufind
suporte:(De acordo com este post detalhado de Stéphane Chazelas
-quit
é suportado no GNU e no FreeBSDfind
e no NetBSD como-exit
.)Novamente com
-printf '%h'
se suportado:Solução para poda no mesmo nível em que a
.git
pasta estáConsulte a parte "Solução possível" para obter a solução atual para esse problema específico.
(Ah, e obviamente as soluções usando
xargs
assumem que não há novas linhas nos caminhos, caso contrário, você precisaria de magia de bytes nulos.)fonte
dir1
contém dois diretóriosdirx
ediry
cada um contém um.git
diretório, isso somente informadirx/.git
dir1/.git
existe, ele ainda descedir1/dirx
, que, com base na minha leitura da exigência do OP, não é desejadoIdealmente, você deseja rastrear as árvores de diretórios em busca de diretórios que contenham uma
.git
entrada e parar de pesquisar mais abaixo (supondo que você não tenha mais repositórios git dentro dos repositórios git).O problema é que, com o padrão
find
, fazer esse tipo de verificação (se um diretório contém uma.git
entrada) envolve gerar um processo que executa umtest
utilitário usando o-exec
predicado, o que será menos eficiente do que listar o conteúdo de alguns diretórios.Uma exceção seria se você usasse o built-in
find
dobosh
shell (um fork POSIXified do shell Bourne desenvolvido por @schily ) que possui um-call
predicado para avaliar o código no shell sem precisar gerar um novo interpretador sh:Ou o uso
perl
deFile::Find
:Mais longo, mas mais rápido do que
zsh
'sprintf '%s\n' **/.git(:h)
(que desce em todos os diretórios não ocultos), ou GNUfind
' sfind . -name '.?*' -prune -o -type d -exec test -e '{}/.git' \; -prune -print
que corre umtest
comando em um novo processo para cada diretório não oculta.fonte
.git
pode ser um arquivo - viagit worktree
-d
para-e
.Se você usar o localizador, poderá encontrar diretórios com:
A lista de resultados é rápida e o processamento adicional também é fácil.
fonte
locate '*/.git'
deve ser suficiente.Usar
time
isso, para ver a diferença com e sem-prune
.Isso é baseado em uma solução no
man find
. Você pode editarCVS
e,svn
se não for necessário. o conteúdo da página de manual segueDado o seguinte diretório de projetos e seus diretórios administrativos associados do SCM, execute uma pesquisa eficiente pelas raízes dos projetos:
Neste exemplo,
-prune
evita a descida desnecessária em diretórios que já foram descobertos (por exemplo, não pesquisamosproject3/src
, porque já encontramosproject3/.svn
), mas assegura a localização de diretórios irmãos (project2
eproject3
).fonte