Czy ktoś zna sposób na rekurencyjne usuwanie wszystkich plików w kopii roboczej, które nie są objęte kontrolą wersji? (Potrzebuję tego, aby uzyskać bardziej wiarygodne wyniki w mojej automatycznej kompilacji VMware).
hg purge --all
w Mercurial.
Czy ktoś zna sposób na rekurencyjne usuwanie wszystkich plików w kopii roboczej, które nie są objęte kontrolą wersji? (Potrzebuję tego, aby uzyskać bardziej wiarygodne wyniki w mojej automatycznej kompilacji VMware).
hg purge --all
w Mercurial.
Odpowiedzi:
Edytować:
Subversion 1.9.0 wprowadził opcję, aby to zrobić:
svn cleanup --remove-unversioned
Wcześniej używam tego skryptu Pythona, aby to zrobić:
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))
Wydaje się, że całkiem nieźle wykonuje swoją pracę.
svn cleanup --remove-unversioned
jest lepsze. I to jest dla Subversion 1.9.0 (ta wersja pochodzi z 2015 roku). Jest stabilny i standardowy.
to działa dla mnie w bash:
svn status | egrep '^\?' | cut -c8- | xargs rm
Seth Reno jest lepszy:
svn status | grep ^\? | cut -c9- | xargs -d \\n rm -r
Obsługuje niewersjonowane foldery i spacje w nazwach plików
Zgodnie z komentarzami poniżej, działa to tylko w przypadku plików, o których subversion nie wie (status =?). Wszystko, Subversion nie wiedzieć (w tym Ignorowani plików / folderów) nie zostaną usunięte.
Jeśli używasz subversion 1.9 lub nowszej, możesz po prostu użyć polecenia svn cleanup z opcjami --remove-unversioned i --remove-ignored
svn status | grep "^?" | awk '{print $2}' | xargs -d \\n rm -r
Natknąłem się na tę stronę, szukając tego samego, ale nie dla automatycznej kompilacji.
Po dokładniejszym przyjrzeniu się odkryłem „ Rozszerzone menu kontekstowe ” w TortoiseSVN. Przytrzymaj klawisz Shift i kliknij prawym przyciskiem myszy kopię roboczą. Istnieją teraz dodatkowe opcje w menu TortoiseSVN, w tym „ Usuń niewersjonowane elementy… ”.
Chociaż być może nie dotyczy tego konkretnego pytania (tj. W kontekście automatycznej kompilacji), pomyślałem, że może to być pomocne dla innych, którzy chcą zrobić to samo.
Zobacz: svn-clean
Jeśli korzystasz z wiersza poleceń systemu Windows,
for /f "tokens=2*" %i in ('svn status ^| find "?"') do del %i
Poprawiona wersja:
for /f "usebackq tokens=2*" %i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%i %j"
Jeśli używasz tego w pliku wsadowym, musisz podwoić %
:
for /f "usebackq tokens=2*" %%i in (`svn status ^| findstr /r "^\?"`) do svn delete --force "%%i %%j"
Dodałem to do mojego profilu Windows PowerShell
function svnclean {
svn status | foreach { if($_.StartsWith("?")) { Remove-Item $_.substring(8) -Verbose } }
}
--no-ignore
do svn status
i -Recurse
doRemove-Item
Linia poleceń Linuksa:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | xargs -d \\n rm -r
Lub, jeśli właścicielem niektórych plików jest root:
svn status --no-ignore | egrep '^[?I]' | cut -c9- | sudo xargs -d \\n rm -r
To jest oparte na odpowiedzi Kena. (Odpowiedź Kena pomija ignorowane pliki; moja odpowiedź usuwa je).
Po prostu zrób to na powłoce unix za pomocą:
rm -rf `svn st . | grep "^?" | cut -f2-9 -d' '`
Czy nie możesz po prostu wyeksportować do nowej lokalizacji i stamtąd budować?
Jeśli masz TortoiseSVN na swojej ścieżce i jesteś we właściwym katalogu:
TortoiseProc.exe /command:cleanup /path:"%CD%" /delunversioned /delignored /nodlg /noui
Opcje są opisane w pomocy TortoiseSVN dla /command:cleanup
:
Użyj / noui, aby zapobiec wyświetlaniu okna dialogowego wyników, informującego o zakończeniu czyszczenia lub wyświetlającego komunikat o błędzie). / noprogressui wyłącza również okno dialogowe postępu. / nodlg wyłącza wyświetlanie okna dialogowego czyszczenia, w którym użytkownik może wybrać, co dokładnie powinno zostać zrobione podczas czyszczenia. Dostępne akcje można określić za pomocą opcji / cleanup dla czyszczenia statusu, / revert, / delunversioned, / delignored, / refreshshell i / externals.
Jeśli używasz żółwia svn, istnieje ukryte polecenie, aby to zrobić. Przytrzymaj klawisz Shift, klikając prawym przyciskiem myszy folder, aby uruchomić menu kontekstowe w eksploratorze Windows. Otrzymasz polecenie „Usuń elementy bez wersji”.
zobacz szczegóły na dole tej strony lub zrzut ekranu poniżej, który podkreśla rozszerzone funkcje zielonymi gwiazdami, a ten, który Cię interesuje, żółtym prostokątem ...
Subversion 1.9.0 wprowadził opcję usuwania niewersjonowanych elementów [1]
svn cleanup --remove-unversioned
[1] https://subversion.apache.org/docs/release-notes/1.9.html#svn-cleanup-options
Moja konwersja C # skryptu Thomas Watnedals w języku 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
To jest polecenie powłoki unix, które usuwa wszystkie pliki poza kontrolą subversion.
Uwagi:
st
w svn st
to wbudowany alias status
, czyli komenda jest równoważnasvn status
--no-ignore
włącza również pliki niezwiązane z repozytoriami w wyjściu statusu, w przeciwnym razie ignoruje je za pomocą mechanizmów, takich jak .cvsignore
itp. - ponieważ celem jest uzyskanie czystego punktu startowego dla kompilacji, ten przełącznik jest koniecznościągrep
filtry wyjście takie, że tylko te pliki, nie wiadomo do Subversion pozostało - linie począwszy ?
Files list nieznany wywrotową, które byłyby ignorowane bez --no-ignore
opcjised
xargs
komenda jest instruowany przez -r
nie wykonać rm
, gdy lista argumentem byłaby pusta-d '\n'
opcja nakazuje xargs
używać nowej linii jako separator takie polecenie działa również w nazwach plików ze spacjamirm -r
jest używany w przypadku konieczności usunięcia kompletnych katalogów (które nie są częścią repozytorium)Nie mogłem uruchomić żadnego z powyższych bez dodatkowych zależności, których nie chciałem dodawać do mojego automatycznego systemu kompilacji na win32. Dlatego zestawiłem następujące polecenia Ant - zauważ, że wymagają one zainstalowania pliku JAR Ant-contrib w (używałem wersji 1.0b3, najnowszej, z Ant 1.7.0).
Zauważ, że powoduje to usunięcie wszystkich niewersjonowanych plików bez ostrzeżenia.
<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>
W przypadku innego folderu zmień ${basedir}
odniesienie.
svn status --no-ignore | awk '/^[I\?]/ {system("echo rm -r " $2)}'
usuń echo, jeśli to jest pewne, co chcesz zrobić.
/bin/sh
i n rm
procesów.
Równie dobrze może przynieść inną opcję
svn status | awk '{if($2 !~ /(config|\.ini)/ && !system("test -e \"" $2 "\"")) {print $2; system("rm -Rf \"" $2 "\"");}}'
Plik /(config|.ini)/ jest przeznaczony do moich własnych celów.
Dobrym pomysłem może być dodanie --no-ignore do polecenia svn
Natknąłem się na svn-clean na mojej maszynie RH5. Znajduje się w / usr / bin / svn-clean
http://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svn-clean
Czyste rozwiązanie 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
Wypróbowałem wersję Setha Reno z tej odpowiedzi, ale nie zadziałała. Mam 8 znaków przed nazwą pliku, a nie 9 używanych wcut -c9-
.
Więc to jest moja wersja z sed
zamiast cut
:
svn status | grep ^\? | sed -e 's/\?\s*//g' | xargs -d \\n rm -r
Jeśli nie przeszkadza Ci PowerShell:
svn status --no-ignore | ?{$_.SubString(0,1).Equals("?")} | foreach { remove-item -Path (join-Path .\ $_.Replace("?","").Trim()) -WhatIf }
Usuń flagę -WhatIf, aby polecenie faktycznie wykonało usuwanie. W przeciwnym razie wyświetli tylko to, co by zrobił, gdyby działał bez -WhatIf.
Dodałbym to jako komentarz do odpowiedzi Thomasa Watnedala , ale jeszcze nie mogę.
Drobny problem z nim (który nie wpłynie na system Windows) polega na tym, że sprawdza tylko pliki lub katalogi. W przypadku systemów typu Unix, w których mogą występować dowiązania symboliczne, konieczna jest zmiana linii:
if os.path.isfile(fullpath):
do
if os.path.isfile(fullpath) or os.path.islink(fullpath):
aby również usunąć linki.
Dla mnie zmiana ostatniej linii if match: removeall(match.group(1))
na
if match:
print "Removing " + match.group(1)
removeall(match.group(1))
aby wyświetlał to, co usuwa, też był przydatny.
W zależności od przypadku użycia ?[\?ID]
część wyrażenia regularnego może być lepsza ?[\?I]
, ponieważ D
usuwa również usunięte pliki, które były pod kontrolą wersji. Chcę użyć tego do zbudowania w czystym, zaznaczonym folderze, więc nie powinno być żadnych plików w D
stanie.
@zhoufei Przetestowałem twoją odpowiedź i tutaj jest zaktualizowana wersja:
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"
%
znaków przed G i H.%~1
można użyć dowolnej nazwy katalogu, użyłem tego jako funkcji w pliku bat, więc %~1
jest to pierwszy parametr wejściowyDla ludzi, którzy lubią to robić za pomocą perla zamiast pythona, powłoki Unix, javy itp. Oto mały skrypt w Perlu, który również wykonuje jib.
Uwaga: spowoduje to również usunięcie wszystkich niewersjonowanych katalogów
#!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();
Używając TortoiseSVN: * kliknij prawym przyciskiem myszy folder kopii roboczej, trzymając wciśnięty klawisz Shift * wybierz "usuń niewersjonowane elementy"
Jak mogę usunąć wszystkie niewersjonowane / ignorowane pliki / foldery z mojej kopii roboczej?
Czystym sposobem na zrobienie tego w PERL byłoby:
#!/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 ()
Wygenerowałem to przez około 3 godziny. Zrobienie tego w systemie Unix zajęłoby 5 minut. Głównymi problemami były: spacje w nazwach folderów Win, niemożność edycji %% i oraz problem z definiowaniem zmiennych w pętli 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!
)
Fragment kodu C # powyżej nie działał dla mnie - mam klienta svn żółwia, a linie są sformatowane nieco inaczej. Oto ten sam fragment kodu, co powyżej, tylko przepisany do funkcji i przy użyciu wyrażenia regularnego.
/// <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