2007.06_Continuous Integration w .NET_[Programowanie .N].pdf

(702 KB) Pobierz
441715031 UNPDF
Programowanie
.NET
Marcin Kawalerowicz
Continuous
Integration w .NET
cja) to termin ukuty dla zdobywającego co-
raz większą popularność procesu polegają-
cego na jak najczęstszym automatycznym konsolido-
waniu wysiłków grupy programistów. Członkowie tej
grupy, wraz z postępem prac przekazują kod źródło-
wy do centralnego repozytorium. Zmiany w repozyto-
rium są wykrywane przez automatyczny proces inte-
gracyjny, który dokonuje kompilacji kodu, przeprowa-
dza testy oraz wszelkie zadania związane z dostar-
czeniem (delivery) oprogramowania.
Continuous Integration (dalej CI) to proces dość
ściśle związany z nowymi technikami wytwarzania
oprogramowania spod znaku eXtreme Programming .
CI bardzo dobrze sprawdza się w scenariuszach,
gdzie narzucono szybkie tempo pracy, a wymagania
funkcjonalne podlegają częstym zmianom. Świetnie
sprawdza się w grupach stosujących programowanie
sterowane testami (TDD). Korzyści z CI czerpać mo-
gą jednak nie tylko „ekstremalni programiści”. CI może
z powodzeniem zastąpić techniki nocnych kompilacji,
a na grupach nie stosujących systemów kontroli wersji
i „kompilacji w jednym kroku” wymusi on kilka koniecz-
nych usprawnień. Przykładowy scenariusz z zastoso-
waniem CI wyglądać może tak jak na Rysunku 1.
W niniejszym artykule prześledzimy kolejne kroki
składające się na ten proces w środowisku .NET. Za
pomocą Visual Studio 2005 utworzymy prosty pro-
jekt ASP.NET. Przetestujemy go zestawem testów
jednostkowych NUnit. Wykorzystując MSBuild napi-
szemy skrypt budujący. Stworzymy ogólnie dostęp-
ną wersję testową i pakiet instalacyjny. Do zautoma-
tyzowania całego procesu ciągłej integracji użyjemy
CruiseControl.NET .
wykonać za pomocą VSTest . Dane na temat wyko-
nanej pracy, błędów czy też dokumentację przecho-
wywać na SQL Server 2005 i udostępniać za pomo-
cą SharePoint Services. Microsoft przygotował VS
2005 Team System szczególnie z myślą o większych
grupach programistów, ale swoje usługi równie do-
brze może oferować mniejszym zespołom. Szcze-
góły na temat przystosowania Microsoft Visual Stu-
dio 2005 Team System w procesie ciągłej integra-
cji w przystępny sposób przedstawia ten oto artykuł:
http://msdn.microsoft.com/msdnmag/issues/06/03/
TeamSystem/default.aspx
Alternatywa 2. Z obozu Javy. Właściwie nazy-
wać to rozwiązanie alternatywą jest trochę niepre-
cyzyjnie. CI właściwie narodziło się w świecie Ja-
vy. CruiseControl.NET powstał z żebra projektu Cru-
iseControl. Projekt ten od dość dawna w tandemie
z Ant, JUnit i innymi narzędziami z bogatej rodziny
Javy służy celom ciągłej integracji: http://cruisecon-
trol.sourceforge.net/
Alternatywa 3. Z obozu Unix/Linux. Podobne
rozwiązanie jest od dawna realizowane za pomocą
skryptów powłoki, plików makeile i crona na przy-
kład przy produkcji jądra Linuxa http://test.kernel.org
http://www.toolchain.org/
Alternatywy jak wiadomo są cztery, tak więc po-
dane przykłady nie wyczerpują szerokiej rodziny na-
rzędzi wspomagających ciągłą integrację. Projekt
Mozilla oferuje Tinderbox ( http://www.mozilla.org/
tinderbox.html ), Apache Maven ma swój Continuum
( http://maven.apache.org/continuum/ ), a Python Bu-
ildBota ( http://buildbot.sourceforge.net/ ).
Kalkulator
Kod projektu wraz z wymaganymi bibliotekami za-
mieszczony został na dołączonym do tego numeru
dysku CD. Tworzony projekt to prosty kalkulator in-
ternetowy, który jednak został tak pomyślany, by za-
demonstrować kilka przydatnych wzorców i technik.
Przyjrzymy się trójwarstwowej strukturze wzorca pro-
jektowego Model-View-Controller, a całość zaprojek-
tujemy zgodnie z zasadami programowania stero-
wanego testami (Test Driven Developement - TDD).
Jeśli więc nie spieszy Ci się za bardzo, to proponuję
prześledzić tworzenie całego projektu krok po kroku.
Zakładam, że praca z Visual Studio 2005 nie jest dla
Ciebie nowością, że wiesz jak stworzyć solucję, pro-
jekt, dodać do niego referencję i skompilować całość.
Zacznijmy od napisania testów jednostkowych.
Stwórzmy nową pustą solucję i nazwijmy ją CISolu-
tion. Dodajmy do niej bibliotekę klas o nazwie Calcu-
lationTests . Do testów użyjemy darmowego pakietu
Alternatywy 3
Alternatywa 1. Z obozu .NET. Nic (oprócz ceny) nie
stoi na przeszkodzie, by całość przedstawionych
w tym artykule działań wykonać za pomocą oprogra-
mowania Microsoftu. Jako serwer CI można z powo-
dzeniem wykorzystać Team Foundation Server. Kod
umieścić w Visual SourceSafe. Testy jednostkowe
Autor pracuje jako główny programista .NET w mo-
nachijskiej irmie Trygon Softwareberatung, gdzie to
z upodobaniem majstruje przy procesach wytwarza-
nia oprogramowania i z determinacją aspiruje do mia-
na „pragmatycznego programisty”. Prywatnie miło-
śnik dobrego kina i równie dobrej fotograii (szczegól-
nie własnej).
Kontakt z autorem: mkawalerowicz@poczta.onet.pl
46
www.sdjournal.org Software Developer’s Journal 06/2007
C ontinuous Integration (z ang. ciągła integra-
441715031.034.png
Continuous Integration w .NET
������������
mentacją wzorca projektowego MVP a la Microsoft, pliki aspx
tworzą warstwę prezentera ( View ), a aspx.cs kontrolera ( Con-
troller ). Dobrym pomysłem, szczególnie w scenariuszu z uży-
ciem CI, jest skorzystanie z projektu typu ASP.NET Web Ap-
plication jako podstawy dalszej pracy. Dzięki temu dodatko-
wi, który jest częścią Service Pack 1 dla Visual Studio 2005,
projekty webowe mogą być traktowane tak jak wszystkie in-
ne projekty Visual Studio 2005 (mają materialny plik projektu
csproj). Nowy projekt ASP.NET nazwijmy WebCalc. Wykorzy-
stajmy i uzupełnijmy automatycznie wygenerowany dokument
Default.aspx zgodnie z Listingiem 3 oraz Default.aspx.cs tak
jak to pokazano na Listingu 4.
Po dodaniu referencji do biblioteki Calculations nasz pro-
jekt jest gotowy do użytku.
���������
������
Integracja
Jako narzędzia wspomagającego proces ciągłej integra-
cji użyjemy CruiseControl.NET ( CC.NET ). Jest to darmowy,
dość łatwy w użyciu zbiór programów z dostępnym kodem
źródłowym. W jego skład wchodzi między innymi serwer inte-
gracyjny oraz WebDashboard , czyli strona internetowa na któ-
rej prezentowane mogą być wyniki integracji (wymagany jest
IIS). Poręcznym dodatkiem jest CCTray – mały programik,
który działając w tle może informować o bieżącym stanie pro-
jektów administrowanych przez CC.NET .
Zainstalujmy oba dostępne na płycie CD lub w interne-
cie (adres w ramce) pakiety. Proponuję nie instalować od razu
CC.NET jako procesu. Dzięki temu będziemy mieć stały wgląd
w postępy pracy poprzez konsolę systemu operacyjnego.
Działanie CC.NET sterowane jest plikiem koniguracyjnym
ccnet.conig (dostępnym z menu start). W pliku tym deiniuje-
my projekty, ich źródła oraz zbory działań jakie mają na tych
projektach być wykonane. Przykładową prostą konigurację,
którą możemy zastosować do naszego internetowego kalkula-
tora przedstawia Listing 5
Przygotujmy strukturę katalogów dla CC.NET . Zgodnie
z tym co zaplanowaliśmy w pliku koniguracyjnym, nasz pro-
jekt o nazwie WebCalculator znajdzie się w katalogu c:\ci\
WebCalc . Raporty z integracji będą zapisywane w katalogu c:\
������������
�����������
�����������
����������������
Rysunek 1. Continuous Integration w akcji
NUnit. Będzie to pierwszy program jaki umieścimy w podka-
talogu tools naszej solucji. Dzięki temu sposobowi będziemy
pewni, że wszystko co potrzebne do integracji projektu ma-
my w jednym miejscu, to znaczy w katalogu solucji. Tak każdy
programista, jak i automatyczny system ciągłej integracji będą
w stanie skompilować projekt po jednokrotnym pobraniu go
z repozytorium bez potrzeby doinstalowywania jakichkolwiek
bibliotek. Do naszych celów najlepiej nada się dystrybucja
NUnit w postaci archiwum, z którego wypakujemy zawartość
katalogu bin do tools/nunit . W bibliotece testowej umieszcza-
my referencję do podzespołu tools/nunit/nunit.framework.dll .
Klasę testującą tworzymy zgodnie z Listingiem 1.
Jak wynika z testów, naszym celem będzie napisanie bi-
blioteki matematycznej zawierającej podstawowe działania
arytmetyczne. Będziemy potrzebowali klasy Operation z czte-
rema statycznymi metodami Add, Subtract, Divide oraz Multi-
ply. Stwórzmy ją w osobnej bibliotece, którą wykorzystamy ja-
ko Model zgodnie z wymogami wzorca projektowego Model-
View-Controller. Nowy projekt nazwijmy Calculations i dodaj-
my do niego klasę Operations zgodnie z Listingiem 2.
Proszę załagodzić ból brzucha powstały przez patrzenie
na metodę Divide. Dzielenie przez zero z powodzeniem wyła-
pie i przetestuje test jednostkowy ShouldReturnIninity() . Po-
zostanie z biblioteki testującej utworzyć referencje do projektu
Calculations , a później skompilować i przetestować cały pro-
jekt. Jednym ze sposobów na szybkie przetestowanie projek-
tu będzie użycie NUnit z poziomu konsoli systemu operacyj-
nego. Z katalogu w którym znajduje się nasza biblioteka testo-
wa wywołujemy
<project_path>\tools\nunit\nunit-console.exe
CalculationTests.dll
Jeśli otrzymamy informację o pięciu przeprowadzonych bez-
błędnie testach to warstwę modelu danych mamy gotową.
Pora zabrać się za części View oraz Controller . Nic prost-
szego! Stwórzmy nowy projekt ASP.NET. Zgodnie z imple-
Rysunek 2. WebDashboard z raportem NUnit
Software Developer’s Journal 06/2007
www.sdjournal.org
47
441715031.035.png 441715031.036.png 441715031.037.png 441715031.001.png
Programowanie
.NET
Listing 1. Klasa testująca kalkulator
using NUnit . Framework ;
namespace CalculationTests
{
[ TestFixture ]
public class CalculationTest
{
[ Test ]
public void ShoulAddTwoValues ()
{
Assert . AreEqual ( Calculations . Operation . Add ( 1, 1 ) ,
2 );
public void ShouldMultiplyTwoValues ()
{
Assert . AreEqual ( Calculations . Operation . Mulitiply (
1, 1 ) , 1 );
}
[ Test ]
public void ShouldDivideTwoValues ()
{
Assert . AreEqual ( Calculations . Operation . Divide ( 1,
1 ) , 1 );
}
[ Test ]
public void ShouldReturnIninity ()
{
Assert . IsTrue ( double . IsIninity (
Calculations . Operation . Divide ( 1, 0 )));
}
}
}
}
[ Test ]
public void ShouldSubtractTwoValues ()
{
Assert . AreEqual ( Calculations . Operation . Subtract ( 1,
1 ) , 0 );
}
[ Test ]
CI\Artiicial . Jeśli zainstalowaliśmy WebDashboard to standar-
dowo będzie on dostępny pod adresem http://localhost/ccnet .
Zanim skorzystamy z prawdziwego systemu kontro-
li wersji, jako źródła naszego projektu ( sourcecontrol ) uży-
jemy po prostu katalogu ( ilesystem ) c:\Projects\Software\
CISolution . CC.NET będzie porównywał zawartość tego ka-
talogu z katalogiem źródłowym ( repositoryRoot ) i w razie
wykrycia zmian pobierze nowości i wykona zdeiniowane
zadanie. Zanim uruchomimy CC.NET musimy dać mu ma-
teriał do porównań. Skopiujmy więc całość naszego projek-
tu do katalogu c:\ci\WebCalc .
Ostatnim elementem pliku koniguracyjnego są zada-
nia ( <tasks> ). Na razie ograniczymy się do jednego. Zada-
nie to określa, że CC.NET ma użyć narzędzia MSBuild.exe
na pliku solucji CISolution.sln . MSBuild szczegółowo zajmie-
my się za chwilę, teraz wystarczy nam wiedzieć, że to nic
innego jak narzędzie do automatyzacji procesów budowania
oprogramowania. Jest to darmowy produkt Microsoftu sta-
nowiący część .NET Framework 2.0. Zanim będziemy mo-
gli pogratulować sobie wdrożenia serwera integracji musimy
załatać jedną małą dziurkę. MSBuild nie jest niestety w sta-
nie wytwarzać raportów w formie zrozumiałej dla CC.NET
(czyli w XMLu ). Musimy więc pomóc im się porozumieć po-
przez umieszczenie w katalogu solucji biblioteki Though-
tWorks.CruiseControl.MSBuild.dll (link w ramce, biblioteka
na dołączonym dysku CD).
Wszystkie klocki są na swoim miejscu. Nie pozostaje nam
nic innego jak tylko wystartować serwer CC.NET.
Budowanie jednym kliknięciem
Skrypt sterujący MSBuild to dokument XML o ściśle określonej
budowie. O to, żeby plik solucji Visual Studio 2005, który plikiem
XML niewątpliwie nie jest, był kompatybilny z MSBuild , postara-
li się programiści Microsoftu. Wystarczy spróbować z konsoli Vi-
sual Studio 2005 Command Prompt wydać polecenie:
msbuild CISolution.sln
My, by mieć większą kontrolę na tym co dzieje się podczas budo-
wy naszego programu, będziemy musieli stworzyć skrypt MSBu-
ild sami. Do procesu budowy od razu włączymy przygotowane
testy jednostkowe. Przed przystąpieniem do pracy proponuję dla
Listing 2. Zaawansowana klasa matematyczna
public class Operation
{
public static double Add ( double val1 , double val2 )
{
return val1 + val2 ;
}
public static double Subtract ( double val1 , double val2 )
{
return val1 - val2 ;
}
public static double Mulitiply ( double val1 , double
val2 )
<cc.net_path>\server\ccnet.exe
{
return val1 * val2 ;
}
public static double Divide ( double val1 , double val2 )
{
return val1 / val2 ;
}
}
Dokonajmy jakiejkolwiek zmiany w projekcie (dodajmy na
przykład atrybut readOnly do pola z wynikiem działania) i za-
piszmy zmiany. Spójrzmy w okno CC.NET. Po chwili pobierze
on zmieniony projekt i go skompiluje. Komunikat Integration
complete: Success obwieści pierwszą zakończoną powodze-
niem integrację.
48
www.sdjournal.org Software Developer’s Journal 06/2007
441715031.002.png 441715031.003.png 441715031.004.png 441715031.005.png 441715031.006.png 441715031.007.png 441715031.008.png 441715031.009.png
 
Continuous Integration w .NET
Rysunek 3. Koniguracja CCTray
( Clean ), a później przebudowuje (Rebuild). Jeśli na tym etapie
nie wystąpią żadne błędy to wykonany zostanie kolejny krok. Za
pomocą tagu Exec można wykonać dowolny program. My wyko-
rzystamy go do przetestowania projektu. Na końcu zaznaczymy
jedynie, że wynik działania NUnit ma zostać zapisany do pliku ra-
portu ( standardowo /xml=NUnitReport.xml ).
Pozwólmy teraz by regularnym wykonywaniem tego skryptu
zajął się CruiseControl.NET . W tym celu edytujemy plik konigura-
cyjny ccnet.conig i zmieniamy go zgodnie z Listingiem 7. Tym ra-
zem deiniujemy dwa projekty. Jeden będzie zajmował się budo-
waniem kalkulatora internetowego w trybie Relase, a drugi w try-
bie Debug. Po wykonaniu pierwszego zadania (msbuild) w obu
projektach wydajemy drugą dyrektywę (merge). Zdanie merge
nakaże CC.NET wziąć określone pliki raportów i dołączyć je do
pełnego raportu dostępnego na serwerze WWW, na stronie We-
bDashboard . Po standardowej instalacji (z działającym serwe-
rem IIS) będzie on dostępny pod adresem http://localhost/ccnet
(Rysunek 2). Dzięki temu narzędziu będziemy mogli swobod-
nie nawigować pomiędzy skonigurowanymi projektami, przeglą-
dać wszystkie dokonane integracje i raporty. To będzie również
pierwsze miejsce, na które zaglądać będziemy w razie kłopo-
tów. Zintegrowane z WebDashboard raporty są niezastąpionym
źródłem informacji na temat problemów oraz dobrym miejscem
gdzie można zorientować się w postępach prac nad projektem.
Innym przydatnym narzędziem z rodziny CC.NET jest CCTray .
Po instalacji jest on dostępny z systemowego zasobnika ( tray ).
Program ten jest w stanie na bieżąco informować użytkownika
o postępach integracji, ewentualnych problemach i sukcesach.
Przykładową konigurację przedstawia Rysunek 3.
wprawy spojrzeć do katalogu projektu i przejrzeć zawartość pli-
ków z rozszerzeniem csproj . Tak, to już są pełnoprawne skryp-
ty MSBuild. Dodajmy do solucji plik CISolution.msbuild i uzupeł-
nijmy jego treść tak jak pokazano na listingu 6. Dobrym zwycza-
jem w procesie ciągłej integracji jest testowanie wszystkich moż-
liwych koniguracji. Nasz skrypt budujący powinien być w stanie
dokonać kompilacji tak w trybie Debug jak i Release (i wszelkich
innych, jeśli zajdzie taka konieczność). Zadbamy o to sprawdza-
jąc na początku czy skrypt został wykonany ze zmienną Coni-
guration. Jeśli nie (jeśli jest ona pusta) to standardowo ustawimy
ją na Debug. Dla wygody zadeklarujmy jeszcze jedną zmienną,
która będzie przechowywać ścieżkę do biblioteki testującej ( Te-
stAssembly ). Nasz skrypt posiada jeden tylko cel (Target), któ-
ry nie robi nic innego jak to, czego nauczyliśmy się przed chwilą.
Najpierw uruchamia plik solucji CISolution.sln , w którym sprząta
�������������
����
����������
�������
����
������������������������
����������
���������������������
��������
������������
��������������������
��������������
���������������������
�����������������
������������������������
����������
������������
Rysunek 4. Schemat przedstawionego procesu ciągłej integracji
Software Developer’s Journal 06/2007
www.sdjournal.org
49
441715031.010.png 441715031.011.png 441715031.012.png 441715031.013.png 441715031.014.png 441715031.015.png 441715031.016.png 441715031.017.png 441715031.018.png 441715031.019.png 441715031.020.png 441715031.021.png 441715031.022.png 441715031.023.png 441715031.024.png
Programowanie
.NET
Listing 3. Default.aspx jako View
Tak oczyszczone katalog wprowadzamy do repozytorium
< asp : TextBox ID = "txtVal1" runat = "server" >< / asp : TextBox >
< asp : DropDownList ID = "ddlOperation" runat = "server" >
< asp : ListItem >+< / asp : ListItem >
< asp : ListItem >-< / asp : ListItem >
< asp : ListItem >*< / asp : ListItem >
< asp : ListItem > / < / asp : ListItem >
< / asp : DropDownList >
< asp : TextBox ID = "txtVal2" runat = "server" >< / asp : TextBox >
< asp : Button ID = "btnOperate" runat = "server" OnClick =
"btnOperate_Click" Text = "=" Width = "15px" / >
< asp : TextBox ID = "txtSolution" runat = "server" >< / asp : TextBox >
svn commit -m "Ignored iles"
Od tej pory możemy już normalnie pracować z repozytorium.
Aktualną wersję ściągamy poleceniem svn checkout ile:///c:/
svn/CISolution a po dokonaniu zmian w projekcie wprowadza-
my do repozytorium za pomocą svn commit .
Praca z svn z poziomu linii komend nie należy do najwy-
godniejszych. O wiele lepszym sposobem jest skorzystanie
dedykowanych programów do obsługi SVN takich jak Torto-
iseSVN lub plugin do Visual Studio ankhsvn . Szczegóły w ram-
ce. Repozytorium gotowe, pora nauczyć CC.NET korzystania
z niego. Zatrzymujemy CC.NET i edytujemy plik ccnet.conig
zgodnie z Listingiem 7.
Przed ponownym uruchomieniem CC.NET oczyśćmy
jeszcze katalog c:\CI\ i do katalogów c:\CI\WebCalc.De-
bug oraz c:\CI\WebCalc.Release pobieramy aktualną kopię
zawartości repozytorium (tak jak w poprzednim przypad-
ku będzie ona służyć za materiał do pierwszego porówna-
nia). Startujemy CC.NET . Od tej pory każde wprowadzenie
zmian do repozytorium wymusi na serwerze budowy doko-
nanie integracji.
System kontroli wersji
Czy ktoś z was próbował uczestniczyć w projekcie programi-
stycznym, w którym nie korzystało by się z systemu kontro-
li wersji? Ja miałem to szczęście, nigdy w czymś takim palców
nie maczać, tobie też tego nie radzę i proponuję użyć systemu
Subversion (SVN) do zarządzania naszym kodem źródłowym.
Jako, że szczegółowe omówienie zagadnień związanych z ad-
ministracją serwera SVN wykracza poza ramy tego artykułu,
kroki potrzebne do przystosowania go do procesu ciągłej in-
tegracji przejrzymy w telegraicznym skrócie. Na początku za-
opatrzmy się w najnowszy pakiet Subversion (adres w ram-
ce lub CD). Rozpakowujemy go na przykład do katalogu c:\
Program Files\svn i ustawiamy ścieżkę systemową do podka-
talogu bin. Tworzymy katalog w którym będziemy składować
nasze repozytoria. Może to być na przykład c:\svn. Teraz z po-
ziomu konsoli systemu operacyjnego tworzymy repozytorium
Statyczna analiza kodu
Programiści często dość po macoszemu traktują tematy-
kę analizy własnego kodu. O ile w małych projektach au-
tomatyczną analizę kodu z powodzeniem może zastąpić
Listing 4. Default.aspx.cs jako Controller
svnadmin create c:\svn\CISolution
protected void btnOperate_Click ( object sender , EventArgs e )
{
double v1 = double . Parse ( txtVal1 . Text );
double v2 = double . Parse ( txtVal2 . Text );
switch ( ddlOperation . SelectedValue )
{
case "+" :
txtSolution . Text = Calculations . Operation . Add (
v1 , v2 ) .
ToString ();
break ;
case "-" :
txtSolution . Text = Calculations . Operation . Subtr
act ( v1 , v2 ) .
ToString ();
break ;
case "*" :
txtSolution . Text = Calculations . Operation . Mulit
iply ( v1 , v2 ) .
ToString ();
break ;
case "/" :
txtSolution . Text = Calculations . Operation . Divid
e ( v1 , v2 ) .
ToString ();
break ;
}
}
Usuwamy z katalogu solucji wszystkie niepotrzebne pliki, tak
by pierwsza wprowadzona do repozytorium wersja posiada-
ła tylko to co niezbędne. Tak więc pozbywamy się wszystkich
katalogów bin i obj oraz pliku CISolution.suo . Tak przygoto-
wany projekt importujemy do repozytorium. Będąc w katalo-
gu solucji wydajemy komendę
svn import ile:///c:/svn/CISolution -m "Initial checkin"
Od tej pory wszystkie pliki, których potrzebujemy do kompila-
cji znajdują się na serwerze SVN. Nasza kopia katalogu pro-
jektu nie będzie nam już potrzebna, bo od tej pory będziemy
pracować na lokalnej kopii repozytorium. Kasujemy więc ka-
talog solucji i pobieramy w jego miejsce kopię z serwera
svn checkout ile:///c:/svn/CISolution
Kompilujemy projekt we wszystkich skonigurowanych try-
bach. Musimy teraz poinformować repozytorium, że nie intere-
sują nas te pliki, które i tak zmieniają się podczas każdej kom-
pilacji (bin, obj, itd.). Dla każdego katalogu i pliku który chce-
my ignorować wydajemy komendę:
svn propset svn:ignore *.suo .
svn propset svn:ignore Calculations\bin .
svn propset svn:ignore Calculations\obj .
50
www.sdjournal.org Software Developer’s Journal 06/2007
441715031.025.png 441715031.026.png 441715031.027.png 441715031.028.png 441715031.029.png 441715031.030.png 441715031.031.png 441715031.032.png 441715031.033.png
 
Zgłoś jeśli naruszono regulamin