Najlepsze praktyki Wskazówki jak efektywniej używać Subversion. W tym rozdziale, skupimy się na omówieniu kilku pułapek systemów kontroli wersji w ogólności, a Subversion w szczególności. Powiemy także, jak je omijać. Formatowanie kodu źródłowego Subversion porównuje i łączy pliki tekstowe linia po linii. Nie rozumie składni języków programowania, nawet nie domyśli się, że tekst został przeformatowany z inną długością linii. Biorąc to pod uwagę, ważnym jest by unikać niepotrzebnego reformatowania. Tworzy to zbędne konflikty w czasie łączenia gałęzi, aktualizacji kopii roboczych, czy też aplikowania patchy. Może także utopić w szumie w czasie rozpatrywania różnic między poszczególnymi wersjami. Tych problemów można uniknąć przez wprowadzenie i przestrzeganie jasno zdefiniowanych reguł formatowania. Dokument HACKING projektu Subversion (http://svn.collab.net/repos/svn/trunk/HACKING) oraz Reguły Formatowania dla Języka Java (Code Conventions for the Java Programming Language; http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html), są dobrymi przykładami (Warto też zajrzeć pod http://www.doc.ic.ac.uk/lab/cplus/c++.rules/ --tłum). Szczególnie ważnym punktem są tabulacje. Niektóre projekty, jak Subversion, w ogóle nie używają tabulacji w kodzie źródłowym. Inne używają ich zawsze, a nawet szczegółowo definiują jej rozmiar. Nieoceniony może stać się edytor, który jest na tyle inteligentny, by wspomagać dotrzymywania tychże reguł. Na przykład vim potrafi to zrobić, rozdzielając reguły wg. projektu przy pomocy .vimrc jak np.: autocmd BufRead,BufNewFile */rapidsvn/*.{cpp,h} setlocal ts=4 noexpandtab autocmd BufRead,BufNewFile */subversion/*.[ch] setlocal sw=2 expandtab cinoptions=>2sn-s{s^-s:s Sprawdź dokumentację swojego ulubionego edytora, może i on to potrafi. Gdy musisz reformatować W prawdziwym świecie, nic nie jest doskonałe. Formatowanie może się z czasem zmienić, albo po prostu zrobimy błąd. Są jednak czynności, które możesz wykonać by zminimalizować problem reformatowania. Te wskazówki warte są rozpatrzenia: Jeśli dokonujesz rozległych zmian w formatowaniu (np. dostosowując kod do innych reguł formatowania), zrób to w pojedynczym zatwierdzeniu bez jakichkolwiek zmian semantycznych. Podaj szczegółowe wskazówki, jak zduplikować zmiany w formatowaniu. Jeśli dokonałeś zmian semantycznych w pewnej części kodu i dostrzegasz nieścisłości formatowania w przyległym kontekście, przeformatuj go. W tym przypadku konflikty spowodowane reformatowaniem nie są tak znaczące, gdyż i tak zmiany semantyczne pewnie je spowodują. Oto jeden z przykładów takich rozległych zmian: $ svn co file:///repo/path/trunk indent_wc $ indent -gnu indent_wc/src/*.[ch] $ svn commit -m 'Ran indent -gnu src/*.[ch]' indent_wc Zmiana ta przestrzega wszystkich powyższych reguł: braku zmian semantycznych (żaden z plików nie zmienił się inaczej niż poprzez zastosowanie polecenia indent. Wywołanie polecenia podano wraz z parametrami, więc zmiany te mogą łatwo zostać zduplikowane) oraz wszystkie zmiany zostały wprowadzone w pojedynczej wersji. Powiedzmy, że zmiany te zostały wprowadzone w wersji 26 głównej linii kodu (trunk). Główna wersja (head) nosi teraz numer 42. W wersji 13 stworzono gałąź (branch), którą teraz chcemy dołączyć do głównej linii kodu. Normalnie robi się to poprzez: $ svn co file://repo/path/trunk merge_wc $ svn merge -r 13:head file://repo/path/branches/mybranch merge_wc … # resolve conflicts $ svn commit -m 'Merged branch' Jednak zmiany w formatowaniu powodują, nieskończoną liczbę konfliktów. Przestrzeganie poniższych reguł może znacząco ułatwić łączenie kodu: $ svn co -r 25 file://repo/path/trunk merge_wc $ svn merge -r 13:head file://repo/path/branches/mybranch merge_wc … # resolve conflicts $ indent -gnu src/*.[ch] $ svn up … # resolve conflicts $ svn commit -m 'Merged branch' Tłumacząc to na polski: Wyprowadź kopię roboczą sprzed reformatowania. Dołącz wszystkie zmiany z zadanej gałęzi. Rozwiąż konflikty. Przeformatuj kod. Zaktualizuj kopię do głównej wersji. Rozwiąż konflikty. Wprowadź nową wersję z połączonej kopii roboczej. Ignorowanie różnic w białych znakach Przeglądając różnice między wersjami, można wyregulować wynik polecenia svn diff tak, by różnice w białych znakach zostały ukryte. Opcja przekazuje wszystkie swoje argumenty do polecenia GNU diff. Niektóre, warte uwagi, argumenty: Opcja Opis Ignoruj zmiany tylko w białych znakach. Ignoruj dodane/usunięte puste linie. Ignoruj zmiany w wielkości liter. Rozszerz spacje, by zachować wyrównanie. Wyświetlaj tabulację zamiast spacji na początku każdej linii, zaczynającej się na pozycji tabulacji (tab stop).
Emaile wysyłane przy zatwierdzaniu zawsze pokazują zmiany tylko w białych znakach. Polecenie commit-email.pl używa komendy svnlook diff do pobrania różnic, a która nie wspiera opcji .
Zakończenia linii Różne platformy (Unix, Windows, MacOS) utrzymują różne konwencje oznaczania końca linii w plikach tekstowych. Proste edytory mogą nadpisywać zakończenia linii, powodując problemy z różnicowaniem i łączeniem. Jest to część problemów związanych z reformatowaniem. Subversion posiada wbudowaną obsługę normalizacji znaków końca linii. By ją włączyć, trzeba ustawić własność svn:eol-style na wartość "native". Zajrzyj do podrozdziału Własności w Podręczniku Subversion by uzyskać więcej informacji.
Gdy zatwierdzasz wersje Przejrzenie wszystkich zmian i stworzenie sensownego wpisu logu bardzo popłaca. W zasadzie publikuje się nowy projekt przy zatwierdzeniu każdej zmiany. Ma to dwa znaczenia: Gdy zatwierdza się zmiany, można potencjalnie zdestabilizować główną linię kodu. Wiele projektów zakłada, że główna linia jest stabilna—powinna zawsze się parsować/kompilować, przechodzić pozytywnie jednostki testowe, itp. Jeśli coś pójdzie źle, może to utrudnić pracę wielu ludziom, dopóki ktoś nie zatwierdzi poprawki. Nie można łatwo usunąć wersji. (Nie ma czegoś takiego jako polecenie cvs admin -o.) Jeśli w kopii roboczej jest element niepożądany w repozytorium, należy się upewnić że nie jest on załączony w poleceniu zatwierdzenia. Szczególnie należy zwrócić uwagę na ważne (prywatne) informacje, pliki wygenerowane automatycznie czy też niepotrzebnie duże pliki. Jeśli zajdzie konieczność zmiany wpisu logu, istnieje możliwość jego zmiany. Polecenie svnadmin setlog zrobi to lokalnie. Można ustawić skrypt http://svn.collab.net/repos/svn/trunk/tools/cgi/tweak-log.cgi,tweak-log.cgi by zezwolić na zmiany wpisów zdalnie. Jak zawsze, stworzenie zawczasu przemyślanego i klarownego wpisu pomaga wyrazić swoje myśli i uniknąć zatwierdzenia błędu czy pomyłki. Przed każdym zatwierdzeniem powinno się samemu uruchomić polecenie svn diff i zadać pytania: czy te zmiany tworzą logiczną całość? Najlepiej gdy każda wersja to pojedyncza lokalna zmiana. Bardzo łatwo jest zapomnieć, że już się zaczęło kolejną zmianę. czy mogę stworzyć dobry wpis logu dla tych zmian? Stworzenie polityki tworzenia wpisów logu też może być pomocne --- dokument HACKING z Subversion http://svn.collab.net/repos/svn/trunk/HACKING stanowi dobrą podstawę. Jeśli zawsze załączasz nazwy plików, funkcji itp. to łatwo można przeglądać logi za pomocą search-svnlog.pl http://svn.collab.net/repos/svn/trunk/tools/client-side/search-svnlog.pl. Można tworzyć wpis logu "w locie". To powszechna praktyka; tworzy się plik changes zawierający wpis poprawiany na bieżąco. W czasie zatwierdzania należy użyć polecenia svn ci -F changes. Jeśli taki wpis nie powstaje na bieżąco, można utworzyć początkowy wpis poprzez użycie wyjścia polecenia svn status (które zawiera spis wsyzstkich zmodyfikowanych plików/katalogów) i dopisać komentarz dla każdego z nich. Pliki binarne Subversion nie umie w żaden sposób połączyć lub przejrzeć różnic w plikach binarnych, więc dokładność wpisów logu dla takich plików jest czynnikiem krytycznym. Ze względu na niemożność użycia polecenia svn diff, dobrym pomysłem jest tworzenie wpisu dla takich plików na bieżąco, wraz z pracą nad nimi. Tłumaczenie: Marcin Dentharg Gil [mgil : bmp net pl]