Кто-нибудь знает способ рекурсивно удалить все файлы в рабочей копии, которые не находятся под контролем версий? (Мне это нужно, чтобы получить более надежные результаты при автоматической сборке VMware.)
hg purge --all
в Mercurial.
Кто-нибудь знает способ рекурсивно удалить все файлы в рабочей копии, которые не находятся под контролем версий? (Мне это нужно, чтобы получить более надежные результаты при автоматической сборке VMware.)
hg purge --all
в Mercurial.
Ответы:
Редактировать:
В Subversion 1.9.0 появилась возможность сделать это:
svn cleanup --remove-unversioned
До этого я использую этот скрипт на Python для этого:
import os
import re
def removeall(path):
if not os.path.isdir(path):
os.remove(path)
return
files=os.listdir(path)
for x in files:
fullpath=os.path.join(path, x)
if os.path.isfile(fullpath):
os.remove(fullpath)
elif os.path.isdir(fullpath):
removeall(fullpath)
os.rmdir(path)
unversionedRex = re.compile('^ ?[\?ID] *[1-9 ]*[a-zA-Z]* +(.*)')
for l in os.popen('svn status --no-ignore -v').readlines():
match = unversionedRex.match(l)
if match: removeall(match.group(1))
Кажется, он неплохо справляется со своей задачей.
svn cleanup --remove-unversioned
лучше. И это для Subversion 1.9.0 (эта версия от 2015 года). Он стабилен и стандартен.
это работает для меня в bash:
svn status | egrep '^\?' | cut -c8- | xargs rm
У Сета Рино лучше:
svn status | grep ^\? | cut -c9- | xargs -d \\n rm -r
Он обрабатывает неверсированные папки и пробелы в именах файлов.
Согласно комментариям ниже, это работает только с файлами, о которых Subversion не знает (status =?). Все , что подрывная действительно знает о (включая игнорируемые файлы / папки) не будут удалены.
Если вы используете Subversion 1.9 или выше, вы можете просто использовать команду svn cleanup с параметрами --remove-unversioned и --remove-ignored.
svn status | grep "^?" | awk '{print $2}' | xargs -d \\n rm -r
Я наткнулся на эту страницу, пытаясь сделать то же самое, но не для автоматизированной сборки.
Пройдя еще немного, я обнаружил « Расширенное контекстное меню » в TortoiseSVN. Удерживая нажатой клавишу Shift, щелкните правой кнопкой мыши рабочую копию. В меню TortoiseSVN теперь есть дополнительные параметры, включая « Удалить неверсированные элементы ... ».
Хотя, возможно, это не применимо к этому конкретному вопросу (например, в контексте автоматизированной сборки), я подумал, что это может быть полезно для других, желающих сделать то же самое.
Если вы находитесь в командной строке Windows,
for /f "tokens=2*" %i in ('svn status ^| find "?"') do del %i
Улучшенная версия:
for /f "usebackq tokens=2*" %i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%i %j"
Если вы используете это в пакетном файле, вам необходимо удвоить %
:
for /f "usebackq tokens=2*" %%i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%%i %%j"
Я добавил это в свой профиль Windows PowerShell
function svnclean {
svn status | foreach { if($_.StartsWith("?")) { Remove-Item $_.substring(8) -Verbose } }
}
--no-ignore
к svn status
и -Recurse
кRemove-Item
Командная строка Linux:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | xargs -d \\n rm -r
Или, если некоторые из ваших файлов принадлежат пользователю root:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | sudo xargs -d \\n rm -r
Это основано на ответе Кена. (Ответ Кена пропускает игнорируемые файлы; мой ответ удаляет их).
Просто сделайте это в unix-shell с помощью:
rm -rf `svn st . | grep "^?" | cut -f2-9 -d' '`
Если на вашем пути есть TortoiseSVN и вы находитесь в правильном каталоге:
TortoiseProc.exe /command:cleanup /path:"%CD%" /delunversioned /delignored /nodlg /noui
Параметры описаны в справке TortoiseSVN для /command:cleanup
:
Используйте / noui, чтобы предотвратить появление диалогового окна с результатами, сообщающего о завершении очистки или отображающего сообщение об ошибке). / noprogressui также отключает диалог выполнения. / nodlg отключает отображение диалогового окна очистки, в котором пользователь может выбрать, что именно следует сделать при очистке. Доступные действия можно указать с помощью параметров / cleanup для очистки статуса, / revert, / delunversioned, / delignored, / refreshshell и / externals.
Если вы используете tortoise svn, для этого есть скрытая команда. Удерживая нажатой клавишу Shift, щелкните папку правой кнопкой мыши, чтобы запустить контекстное меню в проводнике Windows. Вы получите команду «Удалить неверсированные элементы».
см. подробности внизу этой страницы или снимок экрана ниже, на котором расширенные функции выделены зелеными звездами, а интересующий - желтым прямоугольником ...
Subversion 1.9.0 представила возможность удаления неверсированных элементов [1]
svn cleanup --remove-unversioned
[1] https://subversion.apache.org/docs/release-notes/1.9.html#svn-cleanup-options
Мое преобразование сценария Python Томаса Уотнедалса на C #:
Console.WriteLine("SVN cleaning directory {0}", directory);
Directory.SetCurrentDirectory(directory);
var psi = new ProcessStartInfo("svn.exe", "status --non-interactive");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.WorkingDirectory = directory;
using (var process = Process.Start(psi))
{
string line = process.StandardOutput.ReadLine();
while (line != null)
{
if (line.Length > 7)
{
if (line[0] == '?')
{
string relativePath = line.Substring(7);
Console.WriteLine(relativePath);
string path = Path.Combine(directory, relativePath);
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
else if (File.Exists(path))
{
File.Delete(path);
}
}
}
line = process.StandardOutput.ReadLine();
}
}
svn st --no-ignore | grep '^[?I]' | sed 's/^[?I] *//' | xargs -r -d '\n' rm -r
Это команда оболочки unix для удаления всех файлов, не находящихся под контролем Subversion.
Ноты:
st
в svn st
это встроенный псевдоним для status
, т.е. команда эквивалентнаsvn status
--no-ignore
также включает файлы, не являющиеся репозиториями, в вывод состояния, в противном случае игнорирует с помощью таких механизмов, как .cvsignore
и т. д. - поскольку цель состоит в том, чтобы иметь чистую отправную точку для сборок, этот переключатель является обязательнымgrep
фильтры на выходе таким образом, что только те файлы , неизвестным в подрывной осталось - строки , начинающиеся с ?
списком файлами неизвестной диверсии , которые были бы проигнорированы без --no-ignore
опцииsed
xargs
команда проинструктирован с помощью -r
не выполнить rm
, когда список аргументов будет пустым-d '\n'
параметр указывает xargs
использовать символ новой строки в качестве разделителя , например команда также работает для имен файлов с пробеламиrm -r
используется в случае, если необходимо удалить полные каталоги (которые не являются частью репозитория)Я не мог заставить что-либо из вышеперечисленного работать без дополнительных зависимостей, которые я не хотел добавлять в свою автоматизированную систему сборки на win32. Итак, я собрал следующие команды Ant - обратите внимание, что они требуют установки Ant-contrib JAR (я использовал последнюю версию 1.0b3 с Ant 1.7.0).
Обратите внимание, что при этом без предупреждения удаляются все неверсированные файлы.
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<taskdef name="for" classname="net.sf.antcontrib.logic.ForTask" />
<macrodef name="svnExecToProperty">
<attribute name="params" />
<attribute name="outputProperty" />
<sequential>
<echo message="Executing Subversion command:" />
<echo message=" svn @{params}" />
<exec executable="cmd.exe" failonerror="true"
outputproperty="@{outputProperty}">
<arg line="/c svn @{params}" />
</exec>
</sequential>
</macrodef>
<!-- Deletes all unversioned files without warning from the
basedir and all subfolders -->
<target name="!deleteAllUnversionedFiles">
<svnExecToProperty params="status "${basedir}""
outputProperty="status" />
<echo message="Deleting any unversioned files:" />
<for list="${status}" param="p" delimiter="
" trim="true">
<sequential>
<if>
<matches pattern="\?\s+.*" string="@{p}" />
<then>
<propertyregex property="f" override="true" input="@{p}"
regexp="\?\s+(.*)" select="\1" />
<delete file="${f}" failonerror="true" />
</then>
</if>
</sequential>
</for>
<echo message="Done." />
</target>
Для другой папки измените ${basedir}
ссылку.
svn status --no-ignore | awk '/^[I\?]/ {system("echo rm -r " $2)}'
удалите эхо, если вы уверены, что хотите сделать.
/bin/sh
и n rm
процессов.
Поскольку все остальные делают это ...
svn status | grep ^? | awk '{print $2}' | sed 's/^/.\//g' | xargs rm -R
Может также предложить другой вариант
svn status | awk '{if($2 !~ /(config|\.ini)/ && !system("test -e \"" $2 "\"")) {print $2; system("rm -Rf \"" $2 "\"");}}'
/(Config|.ini)/ предназначен для моих целей.
И было бы неплохо добавить --no-ignore к команде svn
Я наткнулся на svn-clean на своей машине RH5. Он находится в / usr / bin / svn-clean
http://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svn-clean
Чистое решение cmd / bat для windows:
@echo off
svn cleanup .
svn revert -R .
For /f "tokens=1,2" %%A in ('svn status --no-ignore') Do (
If [%%A]==[?] ( Call :UniDelete %%B
) Else If [%%A]==[I] Call :UniDelete %%B
)
svn update .
goto :eof
:UniDelete delete file/dir
if "%1"=="%~nx0" goto :eof
IF EXIST "%1\*" (
RD /S /Q "%1"
) Else (
If EXIST "%1" DEL /S /F /Q "%1"
)
goto :eof
Я пробовал версию Сета Рино из этого ответа, но у меня это не сработало. У меня было 8 символов перед именем файла, а не 9 в cut -c9-
.
Итак, это моя версия sed
вместо cut
:
svn status | grep ^\? | sed -e 's/\?\s*//g' | xargs -d \\n rm -r
Если вам нравится Powershell:
svn status --no-ignore | ?{$_.SubString(0,1).Equals("?")} | foreach { remove-item -Path (join-Path .\ $_.Replace("?","").Trim()) -WhatIf }
Снимите флаг -WhatIf, чтобы команда действительно выполняла удаление. В противном случае он просто выведет то, что он будет делать, если запустить без -WhatIf.
Я бы добавил это как комментарий к ответу Томаса Уотнедала , но пока не могу.
Небольшая проблема с ним (которая не повлияет на Windows) заключается в том, что он проверяет только файлы или каталоги. Для Unix-подобных систем, где могут присутствовать символические ссылки, необходимо изменить строку:
if os.path.isfile(fullpath):
к
if os.path.isfile(fullpath) or os.path.islink(fullpath):
также удалить ссылки.
Для меня изменение последней строки if match: removeall(match.group(1))
на
if match:
print "Removing " + match.group(1)
removeall(match.group(1))
чтобы он отображал то, что удаляет, тоже было полезно.
В зависимости от варианта использования, ?[\?ID]
часть регулярного выражения может быть лучше ?[\?I]
, так как D
также удаляет удаленные файлы, которые находились под контролем версий. Я хочу использовать это для создания чистой, проверенной папки, поэтому в состоянии не должно быть файлов D
.
@zhoufei Я проверил ваш ответ и вот обновленная версия:
FOR /F "tokens=1* delims= " %%G IN ('svn st %~1 ^| findstr "^?"') DO del /s /f /q "%%H"
FOR /F "tokens=1* delims= " %%G IN ('svn st %~1 ^| findstr "^?"') DO rd /s /q "%%H"
%
отметки перед буквами G и H.%~1
может использоваться любое имя каталога, я использовал это как функцию в файле bat, так что %~1
это первый входной параметрДля людей, которым нравится делать это с помощью perl вместо python, оболочки Unix, java и т. Д. Это небольшой скрипт на perl, который также выполняет jib.
Примечание: это также удаляет все неверсированные каталоги
#!perl
use strict;
sub main()
{
my @unversioned_list = `svn status`;
foreach my $line (@unversioned_list)
{
chomp($line);
#print "STAT: $line\n";
if ($line =~/^\?\s*(.*)$/)
{
#print "Must remove $1\n";
unlink($1);
rmdir($1);
}
}
}
main();
Использование TortoiseSVN: * щелкните правой кнопкой мыши папку с рабочей копией, удерживая нажатой клавишу Shift * выберите «удалить неверсированные элементы»
Как я могу удалить все неверсированные / проигнорированные файлы / папки в моей рабочей копии?
Чистый способ сделать это в PERL:
#!/usr/bin/perl
use IO::CaptureOutput 'capture_exec'
my $command = sprintf ("svn status --no-ignore | grep '^?' | sed -n 's/^\?//p'");
my ( $stdout, $stderr, $success, $exit_code ) = capture_exec ( $command );
my @listOfFiles = split ( ' ', $stdout );
foreach my $file ( @listOfFiles )
{ # foreach ()
$command = sprintf ("rm -rf %s", $file);
( $stdout, $stderr, $success, $exit_code ) = capture_exec ( $command );
} # foreach ()
Я использовал ~ 3 часа, чтобы сгенерировать это. В Unix на это уйдет 5 минут. Основной проблемой были: пробелы в именах папок Win, невозможность редактирования %% i и проблема с определением переменных в цикле Win cmd.
setlocal enabledelayedexpansion
for /f "skip=1 tokens=2* delims==" %%i in ('svn status --no-ignore --xml ^| findstr /r "path"') do (
@set j=%%i
@rd /s /q !j:~0,-1!
)
Фрагмент кода C #, приведенный выше, у меня не работал - у меня есть клиент tortoise svn, и строки отформатированы немного по-другому. Вот тот же фрагмент кода, что и выше, только переписанный для работы и с использованием регулярного выражения.
/// <summary>
/// Cleans up svn folder by removing non committed files and folders.
/// </summary>
void CleanSvnFolder( string folder )
{
Directory.SetCurrentDirectory(folder);
var psi = new ProcessStartInfo("svn.exe", "status --non-interactive");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.WorkingDirectory = folder;
psi.CreateNoWindow = true;
using (var process = Process.Start(psi))
{
string line = process.StandardOutput.ReadLine();
while (line != null)
{
var m = Regex.Match(line, "\\? +(.*)");
if( m.Groups.Count >= 2 )
{
string relativePath = m.Groups[1].ToString();
string path = Path.Combine(folder, relativePath);
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
else if (File.Exists(path))
{
File.Delete(path);
}
}
line = process.StandardOutput.ReadLine();
}
}
} //CleanSvnFolder