Como remover todos os diretórios .svn dos meus diretórios de aplicativos

192

Uma das missões de uma ferramenta de exportação que tenho no meu aplicativo é limpar todos os .svndiretórios da minha árvore de diretórios do aplicativo. Estou procurando um comando recursivo no shell do Linux que percorra a árvore inteira e exclua os .svnarquivos.

Não estou usando exportação, pois esse script será usado para outros nomes de arquivos / diretórios que não estão relacionados ao SVN. Eu tentei algo como:

find . -name .svn | rm -fr

Não deu certo ...

Itay Moav-Malimovka
fonte
3
Seu comando deve funcionar se você usar 'xargs rm -rf'
Peter van der Heijden
1
Você também pode modificar o comando de exclusão "rm -rfi" apenas para garantir que deseja excluir os diretórios.
Bedwyr
Porém, não use xargs. Você terá problemas com diretórios com espaços, etc. Use find como descrito abaixo.
John Hunt

Respostas:

438

Tente o seguinte:

find . -name .svn -exec rm -rf '{}' \;

Antes de executar um comando como esse, geralmente gosto de executar isso primeiro:

find . -name .svn -exec ls '{}' \;
Greg
fonte
43
Pode ser necessário colocar {} entre aspas simples, se houver espaço ou esses caracteres nos diretórios: find . -name .svn -exec rm -rf '{}' \;
mtoloo
38
Este teste funciona melhor no meu bash:find . -name .svn -exec echo {} \;
Fedir RYKHTIK
6
Executar eco / ls primeiro é o toque 'profissional' para esta resposta. Qualquer tolo pode destruir um sistema.
John Hunt
6
o que {} \;faz?
quer
3
Ao executar o segundo comando, incluindo ls, recebo entries prop-base props text-base tmpsaída ...
Rasoul
51

O que você escreveu envia uma lista de nomes de arquivos separados por nova linha (e caminhos) rm, mas a rm não sabe o que fazer com essa entrada. Espera apenas parâmetros de linha de comando.

xargs recebe entrada, geralmente separada por novas linhas, e as coloca na linha de comando; portanto, adicionar xargs faz com que você trabalhe:

find . -name .svn | xargs rm -fr

xargsé inteligente o suficiente para transmitir apenas o maior número de argumentos rmpossível. Portanto, se você tivesse um milhão de arquivos, ele pode ser executadorm 1.000.000 / 65.000 vezes (se seu shell puder aceitar 65.002 argumentos na linha de comando {65k arquivos + 1 para rm + 1 para -fr}).

Como as pessoas apontaram habilmente, o seguinte também funciona:

find . -name .svn -exec rm -rf {} \;
find . -depth -name .svn -exec rm -fr {} \;
find . -type d -name .svn -print0|xargs -0 rm -rf

Os dois primeiros -execformulários chamam rma exclusão de cada pasta, portanto, se você tivesse 1.000.000 de pastas, rmseria invocado 1.000.000 de vezes. Isso certamente é menos que o ideal. As implementações mais recentes de rmpermitem concluir o comando com uma +indicação que rmaceitará o maior número possível de argumentos:

find . -name .svn -exec rm -rf {} +

A última versão find / xargs usa print0, o que faz com que find gerar saída que use \0como um terminador em vez de uma nova linha. Como os sistemas POSIX permitem qualquer caractere, exceto \0o nome do arquivo, esta é realmente a maneira mais segura de garantir que os argumentos sejam passados ​​corretamente pararm ou que o aplicativo esteja sendo executado.

Além disso, há um -execdirque será executado a rmpartir do diretório em que o arquivo foi encontrado, em vez de no diretório base e um -depthque iniciará a profundidade primeiro.

Kaleb Pederson
fonte
31

Não há necessidade de pipes, xargs, exec ou qualquer coisa:

find . -name .svn -delete

Edit: Brincadeirinha, evidentemente -deletechama por unlinkat()baixo do capô, por isso se comporta como unlinkou rmdire se recusará a operar em diretórios contendo arquivos.

AB
fonte
54
Um problema, -deletenão tocará em um diretório se ele contiver arquivos.
Xeoncross
2
Não há -forcesinalizador recursivo ou nenhum para -deletepredicado, portanto, essa resposta é inútil. Assim, ele está de volta para |xargs rm -rf, que é menos feio para digitar, em seguida, -execcom os seus espaços reservados feias e vírgula: -exec rm -rf '{}' \;.
Tomasz Gandor
13

Já existem muitas respostas fornecidas para excluir o diretório .svn. Mas quero acrescentar que você pode evitar esses diretórios desde o início, se fizer uma exportação em vez de uma finalização da compra:

svn export <url>
Mnementh
fonte
+1, não há necessidade de refazer isso quando já estiver incorporado ao svn.
Powerlord 18/08/09
1
O único problema que vejo com essa abordagem é se você deseja manter arquivos não versionados na exportação. Nos documentos svn, "Todas as alterações locais serão preservadas, mas os arquivos que não estiverem sob controle de versão não serão copiados."
raidfive
@raidfive: Geralmente eu prefiro ter todos os arquivos relevantes sob controle de versão, até mesmo bibliotecas usadas, para que o projeto funcione imediatamente. Os arquivos não versionados nesta configuração são binários compilados, que são refeitos por uma meta no arquivo de compilação. Mas você está certo, se o seu projeto depender de arquivos que não estão sob controle de versão, uma exportação não funcionará.
Mnementh
mas ... eu precisava de uma resposta mais generalista. O .svn era apenas o exemplo mais comum, observei isso na pergunta.
Itay Moav -Malimovka
12

Se você não gosta de ver muitas

find: `./.svn': No such file or directory

avisos e use o -depthcomutador:

find . -depth -name .svn -exec rm -fr {} \;
lazy1
fonte
10

No Windows, você pode usar o seguinte script do Registro para adicionar "Excluir pastas SVN" ao menu de contexto do botão direito do mouse. Execute-o em qualquer diretório que contenha esses arquivos desagradáveis.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
@="Delete SVN Folders"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]
@="cmd.exe /c \"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""
Nathan Taylor
fonte
Truque puro. Não é útil para o OP, mas +1 porque fiquei impressionado!
Rrhartjr 3/13/13
isso é incrível. obrigado. Eu sei que isso é super antigo, mas tanto faz. eu amo mesmo assim.
Anthony
9

Você quase teve. Se você deseja passar a saída de um comando como parâmetros para outro, precisará usar xargs. A adição -print0garante que o script possa manipular caminhos com espaço em branco:

find . -type d -name .svn -print0|xargs -0 rm -rf
soulmerge
fonte
2
por algum motivo, o que funcionou eventualmente foi encontrar. -name .svn | xargs rm -rf A sua versão me deu a direção, porém, graças
Itay Moav -Malimovka
4
find . -name .svn |xargs rm -rf
Itay Moav-Malimovka
fonte
4

Como uma questão importante, quando você deseja utilizar o shell para excluir pastas .svn, você precisa do argumento -thpth para evitar que o comando find entre no diretório que acabou de ser excluído e mostre mensagens de erro como, por exemplo,

"find: ./.svn: No such file or directory"

Como resultado, você pode usar o comando find, como abaixo:

cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;
fatihk
fonte
Isto é o que eu estava procurando e deve ser a resposta correta.
23316 luckytaxi #
3

Tente o seguinte:

find . -name .svn -exec rm -v {} \;

Leia mais sobre o comando find no developerWorks .

Edward Dale
fonte
2

Como alternativa, se você deseja exportar uma cópia sem modificar a cópia de trabalho, pode usar o rsync:

rsync -a --exclude .svn path/to/working/copy path/to/export
pimlottc
fonte
1
Ou use svn export / path / to / repository, que basicamente faz a mesma coisa.
21430 Kaleb Pederson
O autor disse especificamente que não queria usar svn; talvez seu ambiente de destino não tenha o svn instalado.
Pimlottc 18/08/09