Хтось знає спосіб рекурсивного видалення всіх файлів у робочій копії, які не знаходяться під контролем версій? (Мені потрібно це, щоб отримати більш надійні результати в автоматичній збірці 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 року). Він стійкий і стандартний.
це працює для мене в баші:
svn status | egrep '^\?' | cut -c8- | xargs rm
Сет Рено краще:
svn status | grep ^\? | cut -c9- | xargs -d \\n rm -r
Він обробляє неперевершені папки та пробіли у іменах
Згідно з коментарями нижче, це працює лише у файлах, про які не знає підривник (статус =?). Все , що підривна дійсно знає про (включаючи ігноровані файли / папки) не будуть видалені.
Якщо ви використовуєте підрив 1.9 або вище, ви можете просто скористатися командою очищення svn з параметрами --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"
Я додав це до свого профілю windowshell
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 відключає, показуючи діалогове вікно очищення, де користувач може вибрати, що саме слід робити при очищенні. Доступні дії можна вказати за допомогою параметрів / очищення для очищення стану, / повернення, / делюверсія, / зняття, / оновлення та / зовнішнє середовище.
Якщо ви використовуєте svn черепаху, для цього є прихована команда. Утримуйте зсув, натискаючи правою кнопкою миші на папку, щоб запустити контекстне меню в Windows Explorer. Ви отримаєте команду "Видалити неперевершені елементи".
Докладніше див. у нижній частині цієї сторінки , або знімок екрана, під яким висвітлюються розширені функції із зеленими зірками, а також ті, що цікавлять жовтий прямокутник ...
Subversion 1.9.0 введена опція для видалення неперевершених елементів [1]
svn cleanup --remove-unversioned
[1] https://subversion.apache.org/docs/release-notes/1.9.html#svn-cleanup-options
Моє перетворення C # сценарію Thomas Watnedals Python:
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 для видалення всіх файлів, які не перебувають під контролем підривної роботи.
Примітки:
st
в svn st
це вбудований псевдонім для status
, тобто команда еквівалентнаsvn status
--no-ignore
також включає нерепозиторні файли у вихідний стан, інакше ігнорується через такі механізми, як .cvsignore
і т.д.grep
фільтри на виході таким чином, що тільки ті файли , невідомим в підривній залишилося - рядки , що починаються з ?
списком файлами невідомої диверсії , які були б проігноровані без --no-ignore
опціїsed
xargs
команда проінструктований з допомогою -r
не виконати rm
, коли список аргументів буде порожнім-d '\n'
параметр вказує xargs
використовувати символ нового рядка в якості роздільника , наприклад команда також працює для імен файлів з пробіламиrm -r
застосовується у випадку, якщо повні каталоги (які не входять до сховища) потрібно видалитиЯ не міг змусити жодне з перерахованих вище працювати без додаткових залежностей, які мені не хотілося додавати до моєї автоматизованої системи збирання на win32. Тому я зібрав наступні команди Ant - зауважте, що для цього потрібно встановити JAR-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 | awk '{if($2 !~ /(config|\.ini)/ && !system("test -e \"" $2 "\"")) {print $2; system("rm -Rf \"" $2 "\"");}}'
/(Config|.ini)/ призначений для моїх власних цілей.
І може бути хорошою ідеєю додати до команди svn --no-ignore
Я натрапив на svn-clean на своїй машині RH5. Він розташований за адресою / usr / bin / svn-clean
http://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svn-clean
Чистий windows cmd / bat розчин:
@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
Якщо ви круті з powerhell:
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, який також виконує ривок.
Примітка. Це також видаляє всі неперевершені каталоги
#!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 години для створення цього. Це займе 5 хвилин, щоб зробити це в Unix. Основною проблемою були: пробіли в іменах для папок Win, неможливість редагування %% i та проблема з визначенням vars у циклі 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 # не працював для мене - у мене є клієнт-черепаха 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