Ostatnio zainstalowałem lokalne repozytorium Subversion i wczekinowałem solucję nad którą ostatnio pracuję. Niestety, okazało się, że oprócz wartościowych plików VB/C# znalazły się tam śmieci typu bin/*.* (głównie dll-ki). Szybko naprawiłem błąd i zacząłem od nowa, tym razem ustawiając w TortoiseSvn ignorowanie plików dll. Wszystko było OK do czasu, aż zacząłem pracować z kodem – okazało się, że warto byłoby wyrzucić z repozytorium także katalogi obj/Debug/ – oprócz dll-ek znajdują się tam np. pliki .projdata, które Visual Studio chce lockować, co nie bardzo podoba się żółwikowi (Tortoise).
Niestety, w międzyczasie mam wprowadzone sporo zmian i nie chcę tworzyć repozytorium od nowa (w końcu po coś ono istnieje ;-)
Aby repozytorium było bez skazy, zacząłem mozolnie usuwać z niego niechciane foldery i pliki. Niestety, obecna solucja zawiera około 50 takich zestawów w poszczególnych podprojektach. Zamiast poświęcić pół godziny na wyszukiwanie i usuwanie tych śmieci, postanowiłem zaprząc do pracy…
PowerShell.
Czytałem swego czasu o projekcie nowego shella (command line’a) Microsoftu, pierwotnie nazywanego Monad. Przemianowany na PowerShell i wydany oficjalnie pod koniec 2006 coraz częściej przewija się na blogach i webcastach. Jest podobny do powłok *niksowych, duży nacisk położono w nim na przekazywanie wyników jednego polecenia do następnego (piping), przy czym ma jedną bardzo istotną zaletę – zamiast stringów przekazuje obiekty. To się wiąże z kolejną zaletą: działa na .necie i w pełni korzysta z jego dobrodziejstw.
W rezultacie dostajemy nowoczesny sposób dostępu do bardzo różnych struktur danych (system plików, rejestr, otoczenie sieciowe, różnorakie API programów…). Microsoft zobowiązał się publikować wszystkie nowe narzędzie administracyjne w formie nakładek GUI na właśnie skrypty i klasy (tzw. cmdlety)PowerShella. Tak właśnie wygląda panel administracyjny najnowszego MS Exchange Servera.
Kilka przykładów z wikipedii:
- Stop all processes that begin with the letter “p”:
PS> get-process p* | stop-process
- Find the processes that use more than 1000 MB of memory and kill them:
PS> get-process | where { $_.WS -gt 1000MB } | stop-process
- Calculate the number of bytes in the files in a directory:
PS> get-childitem | measure-object -property length -sum
Get-ChildItem .\ -include bin,obj -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse }
O ile dobrze rozumiem (dopiero zaczynam się tym bawić), to teoretycznie używając składni z ostatniego przykładu i podając inne dane wejściowe, możemy np. usunąć wszystkie klucze rejestru lub np. userów z grupy. Raj dla adminów/skrypciarzy/hackerów :-)
Wracając do mojego Subversiona…
Po kilku godzinach :-D udało mi się usiągnąć cel. Znajduję wszystkie niechciane katalogi na dysku i na ich podstawie uzyskuję bliźniaczą listę takich katalogów, tyle że w Subversion. Pozostało tylko wykasować je z repozytorium, co uczyniłem z poczuciem dobrze spełnionego obowiązku. Co prawda w tym przypadku to była armata na muchy, ale za to mam zainstalowanego PowerShella, napisane pierwsze skrypty w nowym środowisku z użyciem pajpingu i iterowania, poustawiane kilka rzeczy w systemie na przyszłość no i …czyste repozytorium :-]
Get-ChildItem Src\ -include bin,obj -Recurse | foreach {
$fullPath = $_.FullName.Replace("\","/")
$srcPath = (get-location).Path.Replace("\","/")
$repoPath = "file:///c:/Repo/NexTra"
$fullPath = $fullPath.Replace("$srcPath","$repoPath")
svn delete --message "AutoDelete" --force --non-interactive "$fullPath"
}