
<chapter id="misc-docs-best_practices">
	<title>Najlepsze praktyki</title>

	<simplesect>

		<para>
			Wskazówki jak efektywniej używać Subversion. 
		</para>

		<para>
			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ć.
		</para>

	</simplesect>

  <!-- ================================================================= -->
  <!-- ======================== SECTION 1 ============================== -->
  <!-- ================================================================= -->
	<sect1 id="misc-docs-best_practices-sect-1">
		<title>Formatowanie kodu źródłowego</title>

		<para>
			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.
		</para>

		<para>
			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.
		</para>

		<para>
			Tych problemów można uniknąć przez wprowadzenie i przestrzeganie
			jasno zdefiniowanych reguł formatowania. Dokument HACKING projektu
			Subversion (<systemitem class="url">http://svn.collab.net/repos/svn/trunk/HACKING</systemitem>)
			oraz Reguły Formatowania dla Języka Java (Code Conventions for the Java Programming Language;
      <systemitem class="url">http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html</systemitem>),
      są dobrymi przykładami
			(Warto też zajrzeć pod <systemitem class="url">http://www.doc.ic.ac.uk/lab/cplus/c++.rules/</systemitem>
			 --tłum).
		</para>

		<para>
			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.
		</para>

		<para>
			Nieoceniony może stać się edytor, który jest na tyle inteligentny,
			by wspomagać dotrzymywania tychże reguł. 
			Na przykład <command>vim</command> potrafi to zrobić, rozdzielając
			reguły wg. projektu przy pomocy <filename>.vimrc</filename>
			jak np.:
		</para>

		<screen>
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
    </screen>

		<para>
			Sprawdź dokumentację swojego ulubionego edytora, może i on to potrafi.
		</para>

		<sect2 id="misc-docs-best_practices-sect-1.1">
			<title>Gdy musisz reformatować</title>

			<para>
				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.
			</para>
			
			<para>
				Te wskazówki warte są rozpatrzenia:
			</para>

			<itemizedlist>

				<listitem>
					<para>
						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.
					</para>
				</listitem>

				<listitem>
					<para>
						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ą.
					</para>
				</listitem>

			</itemizedlist>

			<para>
				Oto jeden z przykładów takich rozległych zmian:
			</para>

			<screen>
$ svn co file:///repo/path/trunk indent_wc
$ indent -gnu indent_wc/src/*.[ch]
$ svn commit -m 'Ran indent -gnu src/*.[ch]' indent_wc
        </screen>

			<para>
				Zmiana ta przestrzega wszystkich powyższych reguł: braku zmian
				semantycznych (żaden z plików nie zmienił się inaczej niż
				poprzez zastosowanie polecenia <command>indent</command>.
				Wywołanie polecenia podano wraz z parametrami, więc zmiany
				te mogą łatwo zostać zduplikowane) oraz wszystkie zmiany zostały wprowadzone
				w pojedynczej wersji.
			</para>

			<para>
				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:
			</para>

			<screen>
$ svn co file://repo/path/trunk merge_wc
$ svn merge -r 13:head file://repo/path/branches/mybranch merge_wc
&hellip; # resolve conflicts
$ svn commit -m 'Merged branch'
      </screen>

			<para>
				Jednak zmiany w formatowaniu powodują, nieskończoną liczbę
				konfliktów. Przestrzeganie poniższych reguł może znacząco
				ułatwić łączenie kodu:
			</para>

			<screen>
$ svn co -r 25 file://repo/path/trunk merge_wc
$ svn merge -r 13:head file://repo/path/branches/mybranch merge_wc
&hellip; # resolve conflicts
$ indent -gnu src/*.[ch]
$ svn up
&hellip; # resolve conflicts
$ svn commit -m 'Merged branch'
      </screen>

			<para>
				Tłumacząc to na polski:
			</para>

			<itemizedlist>

				<listitem>
					<para>
						Wyprowadź kopię roboczą sprzed reformatowania.
					</para>
				</listitem>

				<listitem>
					<para>
						Dołącz wszystkie zmiany z zadanej gałęzi. Rozwiąż konflikty.
					</para>
				</listitem>

				<listitem>
					<para>
						Przeformatuj kod.
					</para>
				</listitem>

				<listitem>
					<para>
						Zaktualizuj kopię do głównej wersji. Rozwiąż konflikty.
					</para>
				</listitem>

				<listitem>
					<para>
						Wprowadź nową wersję z połączonej kopii roboczej.
					</para>
				</listitem>

			</itemizedlist>

		</sect2>

		<sect2 id="misc-docs-best_practices-sect-1.2">
			<title>Ignorowanie różnic w białych znakach</title>

			<para>
				Przeglądając różnice między wersjami, można wyregulować wynik
				polecenia <command>svn diff</command> tak, by różnice w białych znakach
				zostały ukryte. Opcja <option>-x</option> przekazuje wszystkie swoje
				argumenty do polecenia GNU diff. Niektóre, warte uwagi, argumenty:</para>

			<table id="misc-docs-best_practices-table-1">
				<title></title>
				<tgroup cols="2">
					<thead>
						<row>
							<entry>Opcja</entry>
							<entry>Opis</entry>
						</row>
					</thead>
					<tbody>

						<row>
							<entry>
								<option>-b</option>
							</entry>
							<entry>Ignoruj zmiany tylko w białych znakach.</entry>
						</row>

						<row>
							<entry>
								<option>-B</option>
							</entry>
							<entry>Ignoruj dodane/usunięte puste linie.</entry>
						</row>

						<row>
							<entry>
								<option>-i</option>
							</entry>
							<entry>Ignoruj zmiany w wielkości liter.</entry>
						</row>

						<row>
							<entry>
								<option>-t</option>
							</entry>
							<entry>Rozszerz spacje, by zachować wyrównanie.</entry>
						</row>

						<row>
							<entry>
								<option>-T</option>
							</entry>
							<entry>Wyświetlaj tabulację zamiast spacji na początku każdej
								linii, zaczynającej się na pozycji tabulacji (tab stop).</entry>
						</row>

					</tbody>
				</tgroup>
			</table>

			<para>
				Emaile wysyłane przy zatwierdzaniu zawsze pokazują zmiany tylko
				w białych znakach. Polecenie <filename>commit-email.pl</filename> używa
				komendy <command>svnlook diff</command> do pobrania różnic, a która nie
				wspiera opcji <option>-x</option>.
			</para>

		</sect2>

		<sect2 id="misc-docs-best_practices-sect-1.3">
			<title>Zakończenia linii</title>

			<para>
				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.
			</para>

			<para>
				Subversion posiada wbudowaną obsługę normalizacji znaków końca linii.
				By ją włączyć, trzeba ustawić własność <command>svn:eol-style</command>
        na wartość "native". Zajrzyj do podrozdziału Własności w Podręczniku
				Subversion by uzyskać więcej informacji.
			</para>

		</sect2>

	</sect1>

  <!-- ================================================================= -->
  <!-- ======================== SECTION 2 ============================== -->
  <!-- ================================================================= -->
	<sect1 id="misc-docs-best_practices-sect-2">
		<title>Gdy zatwierdzasz wersje</title>

		<para>
			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:
		</para>

		<itemizedlist>

			<listitem>
				<para>
					Gdy zatwierdza się zmiany, można potencjalnie zdestabilizować
					główną linię kodu. Wiele projektów zakłada, że główna linia
					jest <quote>stabilna</quote>&mdash;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.
				</para>
			</listitem>

			<listitem>
				<para>
					Nie można łatwo usunąć wersji. (Nie ma czegoś takiego jako
					polecenie <command>cvs admin -o</command>.) 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.
				</para>
			</listitem>

		</itemizedlist>

		<para>
			Jeśli zajdzie konieczność zmiany wpisu logu, istnieje możliwość jego
			zmiany. Polecenie <command>svnadmin setlog</command> zrobi to
			lokalnie. Można ustawić skrypt <systemitem class="url">http://svn.collab.net/repos/svn/trunk/tools/cgi/tweak-log.cgi,tweak-log.cgi</systemitem>
      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.
		</para>

		<para>
			Przed każdym zatwierdzeniem powinno się samemu uruchomić polecenie
			<command>svn diff</command> i zadać pytania:
		</para>

		<itemizedlist>

			<listitem>
				<para>
					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ę.
        </para>
			</listitem>

			<listitem>
				<para>
					czy mogę stworzyć dobry wpis logu dla tych zmian?
        </para>
			</listitem>

		</itemizedlist>

		<para>
			Stworzenie polityki tworzenia wpisów logu też może być pomocne ---
			dokument HACKING z Subversion <systemitem class="url">http://svn.collab.net/repos/svn/trunk/HACKING</systemitem>
      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 <systemitem class="url">http://svn.collab.net/repos/svn/trunk/tools/client-side/search-svnlog.pl</systemitem>.
		</para>

		<para>
			Można tworzyć wpis logu "w locie". To powszechna praktyka; tworzy się
			plik <filename>changes</filename> zawierający wpis poprawiany
			na bieżąco. W czasie zatwierdzania należy użyć polecenia
			<command>svn ci -F changes</command>.
		</para>

		<para>
			Jeśli taki wpis nie powstaje na bieżąco, można utworzyć początkowy
			wpis poprzez użycie wyjścia polecenia <command>svn
      status</command> (które zawiera spis wsyzstkich zmodyfikowanych
			plików/katalogów) i dopisać komentarz dla każdego z nich.
		</para>

		<sect2 id="misc-docs-best_practices-sect-2.1">
			<title>Pliki binarne</title>

			<para>
				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 <command>svn diff</command>,
				dobrym pomysłem jest tworzenie wpisu dla takich plików na bieżąco,
				wraz z pracą nad nimi. 
			</para>

		</sect2>

	</sect1>

	<para>Tłumaczenie: Marcin <quote>Dentharg</quote> Gil [mgil : bmp net pl]</para>
	
</chapter>

<!--
local variables: 
sgml-parent-document: ("misc-docs.xml" "chapter")
end:
-->
