Menu

SVN - merging

fzymek

Jak powstają konflikty:

Kiedy nad projektem pracuje kilka osób, może zdarzyć się, że będą edytować w tym czasie ten sam plik (a nawet te same linie w pliku). Przykładowy flow pracy może wtedy wyglądać tak:

  1. Developer1 i Developer2 edytują plik hello.txt (np. o rewizji 20)
  2. Developer2 commituje zmiany na repo (problemów brak, plik hello.txt otrzymuje rewizje 21)
  3. Developer1 postanowił że zmieni jeszcze coś w pliku hello.txt
  4. Developer1 commituje plik hello.txt (commit jest odrzucony z tego powodu, że na repo istnieje nowsza rewizja pliku - on edytował plik w wersji 20, natomiast svn wykrył, że na repo jest już nowsza wersja oznaczona jako 21)
  5. SVN oznacza plik hello.txt jako skonfliktowany i dopóki konflikt nie zostanie rozwiązany, nie można commitować tego pliku dalej (svn nam nie pozwoli)

Jak rozwiązywać konflikty:

Jeśli wystąpi konflikt, należy "zmergować" skonfliktowane pliki/katalogi(tu już jest gorzej, odsyłam do lektury svn-booka lub do wujka google). Merge polega na takim połączeniu 2 plików aby w ich wyniku zachować zmiany z repo jak również wprowadzić swoje. Do mergowania używać można narzędzia wbudowanego w Tortoisa, aczkolwiek ja preferuje DiffMerge'a lub WinMerge'a (są wg. mnie bardziej user-friendly :))

  1. Podczas nieudanego commita (tego z konfliktem) svn powinien nas poinformować jakie pliki są skonfliktowane (wyświetli okienko lub poinformuje nas w inny sposób).
  2. Dodatkowo powinien utworzyć w skonfliktowanym pliku sekcje oznaczone mniej wiecej tak:~
    >>>>>>>> r.21
    zmiany developera2
    <<<<<<<<
    >>>>>>> r.20
    zmiany dev.1
    <<<<<<<<

w taki sposób oznacza miejsca gdzie w pliku znajduje się konflikt

  1. Klikamy na taki plik i wybieramy opcję "edit conflict". Powinno pojawić się okienko z narzędziem do mergowania w którym wyświetlone będą obie wersje pliku.
  2. W zależności co jest skonfliktowane wykonujemy mergea (dodając do któregoś z plików nasze zmiany jakie chcemy żeby się znalazły na repo)
    4.1 Konflikt może wyglądać tak że my dodaliśmy tylko jakiś fragment do pliku (np. edytowaliśmy plik *.h i dodaliśmy nagłówek funkcji w C) i wtedy wystarczy go "domergeowac" do pliku wyjściowego
    4.2 Konflikt może dotyczyć zmian w tej samej linii/liniach kodu (np. dev2 dodał argument do nagłówka funkcj, i my także dodaliśmy argument do tego samego nagłówka). Wtedy trzeba już głębiej przeanalizować zmiany, ew. skonsultować się z kimś kto wprowadzał zmianę i wtedy robić merga.

  3. Po wykonaniu mergra commitujemy plik na repo z opisem zmian :)

Polecam pobawić się jakimś narzędziem "na sucho" żeby poznać się z nim, np. tworząc dwa identyczne pliki i edytując to jeden, to drugi, albo oba. Pomergować jeden do drugiego aby zobaczyć jak dane narzędzie działa :)

Jak zapobiegać konfliktom:

Istnieje w miarę prosty sposób na zapobieganie konfliktom (tj. commitom w tym samym czasie). Polega on na tym, że przed commitem danego pliku/plików "lockujemy" te pliki które chcemy zmienić (klikamy na pliki i wybieramy opcję lock + podajemy krotki opis dlaczego blokujemy). W ten sposób blokujemy innym możliwość commitowania zmian w tych plikach w tym samym czasie co my. Po udanym commici pliki są automatycznie odblokowywane.

Należy także ZAWSZE pamiętać że PRZED commitem należy wykonać update na plikach które chcemy commitować. Wtedy jeżeli plik się zmienił na repo, zostaniemy poinformowani o tym wcześniej i bez obaw będziemy mogli zalockować pliki, dokonać merga i commitować.

Krótki opis poprawnego flow podczas comitowania

  1. Przed rozpoczęciem pracy z kodem robimy update do najnowszej wersji
  2. Edytujemy kod
  3. Robimy update
    1. jak nic sie nie zmieniło robimy lock
    2. jak występuje konflikt, robimy lock->merge
  4. Commitujemy kod (poprawny commit automatycznie zdejmuje locka)

Related

Wiki: Home