Heavymind
Gdyby ludzie rozmawiali tylko o tym, co rozumieją, zapadłaby nad światem wielka cisza.

29/08/2007

Koszmar powrócił pod nową postacią: svn:ignore

Opublikowane jako: Subversion — Tags: , — Kubek Bartosz @ 22:03

Przez okres ostatniego tygodnia, starałem się odpowiednio skonfigurować repozytorium SVN projektu nad którym trzymam pieczę. Najważniejszą rzeczą jaką musiałem wykonać było wykluczenie każdej treści z repozytorium, która nie była statyczną częścią projektu. Mam tutaj na myśli pliki i katalogi, które zawierały różnorodne dane sesyjne, logów czy cache. Niestety, jak się okazało, zadanie to nie jest w cale takie proste, a rozwiązywanie drobnych problemów jakie można napotkać wykonując odpowiednie operacje jest bardzo czasochłonne. Tak więc jak uczyniłem to już w jednym z poprzednich artykułów, mając na uwadze chęć pomocy wszystkim, którzy będą kiedyś zmuszeni przechodzić przez podobne zagadnienia, postaram się opisać moje eksperymenty i doświadczenia. Potrzeba opisania tego jest tym większa, że po raz pierwszy nie mogłem “zguglować” problemu, by dostać satysfakcjonującą odpowiedź na pytanie: “jak ignorować katalogi w svn”.

Chciałbym dodać, iż używam aktualnej wersji klienta SVN w shell’owej linii poleceń (debian linux). Tak więc pozwolę sobie wprowadzić Cię w strukturę. Załóżmy, że pracujemy z repozytorium SVN, które zawiera kompletną strukturę katalogów i plików naszego projektu. Ja z kolei będę mówił o małym wycinku repozytorium, które będzie wystarczające dla naszego przykładu. Część ta wygląda następująco:

/logs/
/logs/sess/
/logs/sess/14/
/logs/sess/14/data.dat
/logs/sess/17/
/logs/sess/17/data.dat
/logs/logins/
/logs/registers/

Ta struktura jest częścią repozytorium, jak również występuje w strukturze mojej lokalnej kopii roboczej tego repozytorium (dla przykładu w /home/my_proj/logs/…., choć to akurat jaka jest ścieżka bezwzględna, w żaden sposób nas nie interesuje). Tak więc moim zadaniem jest by wyłączyć z repozytorium na stałe wszystkie katalogi, które mieszczą się w katalogu logs/sess/, czyli w tym przypadku “14/” oraz “17/”. Tę czynność możemy łatwo wykonać poprzez wywołanie poniższych komend:

/logs/$ svn delete sess/*
D         sess\14\format
D         sess\14\format_as
D         sess\14
D         sess\17\format
D         sess\17\format_as
D         sess\17

/logs/$ svn ci -m "*deleted remotely"
Usuwanie       logs\sess\14
Usuwanie       logs\sess\17

Ok, więc usunęliśmy z repozytorium niechciane katalogi z podporządkowanymi im plikami, po czym zmianę tem wysłaliśmy do repozytorium drugą komendą.

W tym momencie jednak zażegnaliśmy sprawę chwilowo, ponieważ gdy tylko zostaną stworzone ponownie jakieś podkatalogi w katalogu sess/ np (stwórzmy ręcznie) :

/logs/sess/22/
/logs/sess/25/

…to ponownie się wyświetlą nam one na liście nowych elementów w naszym projekcie :

/logs/$ svn status
?     /sess/22
?     /sess/25

Znak “?” informuje, że powstał nowy element, który czaka na dodanie do repozytorium, bądź usunięcie.

Więc przypominam, naszym celem jest doprowadzić do sytuacji, by jakikolwiek nowy katalog lub plik powstały w katalogu sess/ był ignorowany przez svn, tzn. by komenda ’svn status’ nie zwracała ich - są one dla naszego projektu jak i dla nas bezwartościowe.

Tak więc skorzystamy z komendy svn propset wraz z odpowiednimi parametrami. Dzięki niej wszystko co jest wewnątrz katalogu /logs/sess/ będzie ignorowane przez svn. Tak więc po pierwsze, przejdę do katalogu sess/, gdzie chcę wywołać ową komendę :

/logs/$ cd sess/

/logs/sess/$ svn propset svn:ignore '*' .

Powyższy zapis jest esencją wielu, wielu godzin jakie spędziłem na nauce i eksperymentach z svn. To, co on tak naprawdę oznacza, to “dodaj własność ‘ignoruj’ do każdego (’*') elementu wewnątrz aktualnego (’.') katalogu. Wygląda dość prosto i intuicyjnie? Niestety wcale takie nie jest.

Przede wszystkim proszę zauważyć, że znak gwiazdki (*) jest umieszczony wewnątrz znaków apostrofu: ‘*’. Jest to krytyczny warunek działania tego polecenia prawidłowo, ponieważ gdyby wywołać tę komendę bez tych znaków apostrofu, polecenie to nie zostało by zinterpretowane prawidłowo jako: “zignoruj każdy element w bieżącym katalogu”, tylko jako “dla każdego podkatalogu w bieżącym katalogu, dodaj własność svn:ignore“. Dzieje się tak, ponieważ znak gwiazdki ma także znaczenie jako operator linii poleceń shell w linuxie. Więc w tym błędnym przypadku, po prostu dodalibyśmy własność svn:ignore do podkatalogów “22/” i “25/”. Bardzo podchwytliwe, prawda?

Po drugie, istnieje alternatywna droga ustawienia tej własności w właściwy sposób. Wystarczy nie przechodzić do katalogu sess/ przed ustawieniem jej, tylko wywołać komendę z poziomu katalogu logs/ z wskazaniem na katalog sess/ :

/logs/$ svn propset svn:ignore '*' sess/

Ten przykład będzie działał identycznie.

I po trzecie i ostatnie, ważne jest by pamiętać, że wykluczenie elementów na stałe z repozytorium, poprzez ignorowanie ich, zadziała właściwie wyłącznie dla elementów które nie są częścią repozytorium. To także jest ważny wymóg. To właśnie dlatego całkiem pierwszym krokiem, jaki poczyniliśmy, było usunięcie poprzez ’svn delete’ wszystkich elementów, które później mieliśmy zamiar wykluczyć. Jeśli elementy te nadal były by częścią repozytorium, nie moglibyć my po prostu ich wykluczyć. Jest to dość oczywiste.

Mam nadzieję, że części z Was, moi drodzy czytelnicy, posłużą moje przykłady w tym temacie. Chciałbym w tym miejscu przesłać podziękowania dla Steffen’a, ponieważ bez wspólnych z nim konsultacji, nie rozwiązał bym zagadnienia tak sprawnie. Pozdrawiam.



Komentarze: 10 »

  1. Dzięki! ;)

    Komentarz od killingmachine — 30/10/2007 @ 11:48

  2. Witam.

    Swietny artykul. Po caly dniu siedzenia nad SVNem bardzo mnie ucieszyl…

    Komentarz od bart78 — 07/11/2007 @ 18:13

  3. Hmmm… A nie łatwiej:
    $svn propedit svn:ignore .

    Komentarz od Piru — 21/11/2007 @ 20:24

  4. niechcący wysłałem…

    $svn propedit svn:ignore .

    w korzeniu kopii roboczej
    i dopisujemy nazwę katalogu.

    Komentarz od Piru — 21/11/2007 @ 20:27

  5. Ehhh… Połowę wczorajszego dnia na to zmarnowałem a tu proszę…:) Dzięki wielkie!

    Komentarz od slodki — 27/02/2008 @ 12:58

  6. niedawno się z tym męczyłem i poległem. a tu proszę, rozwiązanie…
    super:)

    Komentarz od r — 12/06/2008 @ 17:12

  7. Bardzo przydatny wpis. Dzięki za zaoszczędzony czas.

    Komentarz od wasieal — 12/08/2008 @ 16:41

  8. dzieki:)

    Komentarz od dagthore — 03/12/2008 @ 22:37

  9. masz u mnie plusa, dobry krótki artykuł na bardzo ważny temat ;>

    Komentarz od Grzesiek — 23/12/2008 @ 00:59

  10. Dodam jeszcze, że aby usunąć svn:ignore należy użyc polecenia propdel svn:ignore. Być może jest to oczywiste, ale chwilę zajeło mi szukanie tego.

    Komentarz od gaza — 17/02/2010 @ 13:13

Kanał RSS dla tego wpisu. TrackBack URL

Dodaj komentarz

Oparte na WordPress