Musiałem utworzyć do firmy mały poradnik, jak korzystać z branchy i tagów w Subversion, a że pisałem to w miarę (jak mi się zdaje) łopatologicznie, to stwierdziłem że umieszczę to i tutaj dla szerszego grona :)

Nie jest to pozycja dla osoby nie mającej dotychczas styczności z Subversion, nie jest więc wytłumaczone co to jest commit i w ogóle Subversion czy też system kontroli wersji, są za to informacje jak ja i kilka osób na świecie widzą korzystanie z tak ważnych rzeczy jakimi są branche i tagi :)

Generalnie, podstawową strukturą katalogów jest układ:

/
|-trunk
|-branches
|-tags

W trunk przechowywana jest aktualna rozwojowa wersja systemu. Tutaj nanoszone są bieżące zmiany, poprawki etc. Branches służą do przechowywania oddzielnych gałęzi systemu, które niosą zbyt rewolucyjne zmiany, żeby umieszczać je w drzewku głównym, które musi być czasem gotowe do natychmiastowej synchronizacji z systemem głównym. W katalogu tags tworzone są aktualne snapshoty systemu produkcyjnego - każda wersja, która idzie na system produkcyjny, powinna najpierw zostać przeniesiona (zamrożona) do konkretnego taga, i dopiero później system powinien zostać zsynchronizowany.

Najpierw troszkę samej teorii:

Zarówno branche, jak i tagi, tworzone są poprzez skopiowanie dowolnej z gałęzi
rozwijanego systemu (może to być zarówno system trunk, jak i dowolna gałąź utworzona przez któregokolwiek użytkownika) poleceniem cp (copy):

svn cp svn://repo/trunk svn://repo/branches/moja_galaz

Powyższe polecenie tworzy nową gałąź o nazwie moja_galaz którą można dowolnie sobie rozwijać, testować, modyfikować według własnych potrzeb, a następnie, gdy przyjdzie odpowiedni czas/ochota, dołączyć do aktualnego systemu.

W podobny sposób tworzy się konkretne tagi (tagi zwyczajowo oznacza się wielkimi literami):

svn cp svn://repo/trunk svn://repo/tags/HOME_20071210_1

Utworzy to aktualny snapshot repozytorium w katalogu /tags/HOME_20071210_1 (ostatnia
cyfra oznacza rewizję w ciągu tego samego dnia - oczywiście schemat nazewnictwa jest umowny).

Po utworzeniu własnej gałęzi, powinniśmy się na nią przełączyć, ponieważ domyślnie ciągle pracujemy na poprzedniej wersji repozytorium. Do przełączania się między gałęziami służy polecenie sw (switch):

svn sw svn://repo/branches/moja_galaz

W tym momencie pracujemy już na naszej gałęzi, i wszelkie commity, zmiany etc będą się odnosić do naszej wersji.
Co dalej?

Podstawowe prace i rozwijanie systemu powinno odbywać się na gałęzi trunk, która w razie puszczania zmian na system produkcyjny, powinna zostać skopiowana do odpowiedniego tagu, a następnie zsynchronizowana. Pozostaje jeszcze jeden problem: jak połączyć zmiany dokonane na osobnej gałęzi z tym, co dzieje się w aktualnym drzewku?

Tutaj pomoże nam komenda merge. Załóżmy hipotetyczną sytuację:

W repozytorium, w gałęzi trunk, znajduje się plik index.php. Ma on zawartość:

<?php

include 'some_file.php';

?>

W tej chwili tworzymy osobnego brancha:

svn cp svn://repo/trunk svn://repo/branches/mysz1
svn sw svn://repo/branches/mysz1

Od tego momentu pracujemy już na branchu mysz1. Sprawdzić to możemy za pomocą
komendy info:

svn info
[...]
URL: svn://repo/branches/mysz1
[...]

Dokonujemy zmiany w pliku index.php, tak że zawiera on teraz:

<?php
include 'some_file.php';
echo date ('Ymdhis'); // branches/mysz1
?>

Wykonujemy commit pliku, po czym przenosimy się na trunka:

svn sw svn://repo/trunk
svn info
[...]
URL: svn://repo/trunk
[...]

Sprawdzamy zawartość pliku index.php:

svn cat index.php
<?php
include 'some_file.php';
?>

Dokonujemy zmian, żeby plik wyglądał tak:

<?php
include 'some_file.php';
print strftime ('%Y%m%d %H%M%S', time ()); // trunk
?>

Commit, i wracamy na mysz1:

svn sw svn://repo/branches/mysz1
svn info
[...]
URL: svn://repo/branches/mysz1
[...]
svn cat index.php
<?php
include 'some_file.php';
echo date ('Ymdhis'); // branches/mysz1
?>

No to teraz próbujemy nanieść zmiany z branches/mysz1 na główną gałąź systemu:

svn merge -r 6:HEAD svn://repo/branches/mysz1 .

(na końcu jest kropka).

Co znaczą poszczególne części, wyjaśniam poniżej:

svn merge
polecenie
-r 6:HEAD
wersje która mają zostać połączone: najpierw numer wersji na której aktualnie pracujemy (w tym wypadku 6), później wersji do której chcemy się uaktualnić (HEAD, oznaczający najbardziej aktualną wersję, ale może to również być liczba oznaczająca konkretną rewizję)
svn://repo/branches/mysz1
branch który łączymy z trunkiem
.
(kropka) aktualna ścieżka (równie dobrze mogło to być svn://repo/trunk)

W tym wypadku powstanie nam konflikt, który rozwiązujemy tradycyjnym sposobem (kasując, dodając i poprawiając konkretne linie), a na końcu, po rozwiązaniu wszystkich problemów, robimy tradycyjny commit.

Więcej informacji znaleźć można na:


Twórcy Blip!a wydali wersję 0.02 API, więc zrobiłem co w mojej mocy aby skończyć moją PeHaPową bilbiotekę do tegoż ;) Zmian dużo, do wersji API 0.01 była ona mocno testowa, i w sumie nie jest poprawnie zrobiona, są w niej błędy etc, których nie zamierzam już poprawiać. Wersja 0.02.4 niesie z sobą pełną obsługę protokołu, wykorzystując wszystko co producenci dali, szczegóły w oficjalnej dokumentacji Blip!a.

Szczegóły numeracji biblioteki: pierwszą część stanowi wersja API (w tym wyapdku 0.02), drugą - odsłona samej biblioteki (w tym wypadku 4).

BlipApi.php można używać na dwa sposoby:

  1. wywołując metodę BlipApi::execute(), gdzie pierwszym parametrem jest nazwa komendy do wykonania (spis komend w oficjalnej dokumentacji, jedyną różnicą jest dirmsg zamiast directed_messages), a następnie dostępne parametry metody (szczegóły w pliku klasy i w oficjalnej dokumentacji Blip!a), np.:

    $bapi = new BlipApi ('login', 'haslo');
    $bapi->connect ();
    $bapi->execute ('update_read', null, 'mysz');

    Pobierze ostatnie 10 statusów użytkownika mysz.

  2. wywołując komendę jako konkretną metodą obiektu BlipApi:

    $bapi->update_read (null, 'mysz');

    Powyższe dwa wywołania są sobie równoważne.

Jeśli ktoś znajdzie jakieś błędy, lub ma uwagi co do samej biblioteki, proszę o komentarze tutaj, lub kontakt mailowy: urzenia.net/email. Z góry dziękuję za feedback ;)

Bibliotekę można pobrać/obejrzeć z: repo.urzenia.net/files/blipapi-0.02.phps. W tej chwili nie ma skąd pobrać samej biblioteki, jako że usunąłem repo.urzenia.net. Dołączona jest za to do pakietu WP Blip!, skąd można ją “ręcznie” wyciągnąć :) Przepraszam za kłopot :)


Od kilku tygodni bawię się po trochu CURLem, w ramach tworzenia PeHaPowej biblioteki do Blip!a. Poniżej kilka zagwozdek, na które ciężko znaleźć sensowną odpowiedź w google, albo ja nie wiem jak pytać…

  1. Jak poprawnie wykonać zapytanie PUT? (aka: metoda PUT i “select/poll returned error”)

    Nad tym spędziłem najwięcej czasu. Kombinowałem na mnóstwo sposobów. Kluczem do sukcesu okazało się podejrzenie wersji konsolowej CURLa z dokładnie takim samym zapytaniem, jakie wysyłałem za pomocą skryptu PHP. W skrócie: należy wymusić na CURLu HTTP 1.0, za pomocą ustawienia opcji:

    curl_setopt ($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); # gdzie $ch jest obiektem utworzonym za pomocą curl_init ()

    Po tej operacji zapytania śmigają jak należy (dodam tylko, że czasem zamiast “select/poll returned error” dostawałem “connection reset by peer”).

  2. Przy rozwiązywaniu powyższego problemu, pomogła mi mała sztuczka. Mianowicie musiałem podejrzeć jakie nagłówki wysyła CURL. Normalnie PHPowy CURL nie zamierza pokazać co jest wysyłane i odbierane (Rozpisałem się - oczywiście nagłówki odbierane bez problemu można zobaczyć. Dzięki, Arek ;) ), bo i po co… Ja posłużyłem się tutaj specjalnie na tą okazję utworzonym skryptem PHP z dokładnie wyizolowanym ‘testcase’. Tutaj, po zaimplementowaniu opcji:

    curl_setopt ($ch, CURLOPT_VERBOSE, 1);

    i odpaleniu skryptu z konsoli, grzecznie została mi pokazana komunikacja wychodząca z serwerem, co było kluczem do rozwiązania problemu (okazało się że był wysyłany dodatkowy nagłówek Expect należący do HTTP 1.1, a po wrzuceniu tego w google znalazłem informacje które mnie nakierowały na właściwy trop).

  3. Jak wysłać plik POSTem?

    Ech, w sumie rozwiązanie jest banalne, jeśli ktoś dokładniej przeczyta manual na stronach PHP dotyczący CURLa. Ale skoro już opisuję zagwozdki…

    PHPowy CURL pozwala wysyłać dane na dwa sposoby (akceptowane i sprecyzowane, oczywiście, w odpowiednim RFC). Jeden to x-www-form-urlencoded (tak są wysyłane dane za pomocą webowych formularzy), drugi to multi-part form-data (tak są wysyłane pliki, także z formularzy). Normalnie dla opcji CURLOPT_POSTFIELDS podaje się string który wygląda dokładnie tak samo jak ten widoczny w URLach skryptów pehapowych (mówiąc po laicku), np. a=1&b=2 - wtedy dane są wysyłane metodą x-www-form-urlencoded. Aby zmusić CURLa do wysłania danych metodą multi-part form-data, jako parametr opcji CURLOPT_POSTFIELDS musimy podać tablicę. Tak, właśnie tablicę, gdzie kluczem powinne być nazwa pola (odpowiadająca temu z prawdziwego formularza), a wartością ścieżka do pliku, ale uwaga: ścieżka powinna być poprzedzona znakiem “małpy”: @. Czyli powinno wyglądać to tak:

    curl_setopt ($ch, CURLOPT_POSTFIELDS, array ('pole' => '@/sciezka/do/pliku.jpg'));

    Po tej operacji wysłanie pliku nie powinno być już problemem :)


Co prawda, od około roku nie używam za dużo PHP, ale generalnie śledzę co się w tym języku dzieje. Podobają mi się nawet zmiany zaplanowane na wersję 5.3:

  • dodanie obsługi przestrzeni nazw (namespaces)
  • usunięcie w końcu safe_mode, register_globals i magic_quotes - szczególnie tych ostatnich nie trawię…
  • dodanie poziomu raportowania błędów E_DEPRECATED - będą tym, jak się domyślam, oznaczane funkcje/moduły/klasy mające być wycofane w niedługim czasie z core języka (jak np. moduł ereg)
  • nowa magiczna metoda: _callStatic, wywoływana w momencie gdy zostanie użyta metoda statyczna nie istniejąca w danej klasie

To nie są jeszcze końcowe ustalenia, wszystko może się jeszcze zmienić, ale to co powyżej prawdopodobnie zostanie wdrożone.

Jednak ja, jak i spore stadko innych osób używających PHP, oczekuje jednej, bardzo ważnej zmiany: uporządkowania w końcu core języka: ujednolicenie nazewnictwa funkcji, nauczenie funkcji wbudowanych wyjątków etc. To jest rzecz najbardziej potrzebna na tą chwilę, gdyż sądzę że bez tego przyszłość “pehapa” pójdzie elegancko po równi pochyłej w dół…


Ta strona skończyła wczoraj kolejny roczek - już trzeci ;) Nie za dużo się niestety dzieje, ale tak to w życiu bywa - praca i dom zabierają większość czasu, to co pozostaje nie pozwala na zbyt wiele, niestety. Mam nadzieję że jednak niedługo się to zmieni :)


Jakiś czas temu zacząłem się bawić Blip!em. Wstawiłem sobie nawet na główną stronę myGeeBloga wklejkę z ostatnim statusem ;) Ichnich wklejki sa jak dla mnie kiepskie (flasha nie lubię, a wersja jsowa pozwala na pobranie tylko ostatniego statusu), więc pomyślałem o pluginie do WordPressa. Żeby móc to urzeczywistnić, potrzeba mi jakiejś klasy do obsługi tego - a z pomocą udostępnionego API zrobiłem sobie taką. Na razie wersja pre-alpha ;)

do podejrzenia:
repo.urzenia.net/files/blipapi.phps
do pobrania:
http://repo.urzenia.net/files/get.php?f=blipapi.php

O feedback poproszę za pomoca formularza: urzenia.net/email lub na liście blip-api: groups.google.com/group/blip-devel/browse_thread/thread/3096e1724d036f55.

UPDATE: wprowadziłem kilka zmian w klasie blipapi, częściowo kosmetycznych, częściowo optymalizacyjnych. Do pobrania pod wymienionymi wyżej adresami :)


Mała statystyka:

liczba klas (plików):
6
liczba linii:
9602
liczba linii kodu:
5730
liczba linii komentarzy i dokumentacji:
3872
liczba znaków:
274713
ilość rzuconych w międzyczasie kur* i innych ch*:
-> ∞

Od jakiegoś czasu używam na desktopie Ubuntu. Począwszy od chyba 6.06 (jak nie wcześniej, nie pamiętam już) aż do teraz. Wczoraj mnie podkusiło żeby spróbować wersji niestabilnej (tzn każdego Ubuntu próbuję, ale zazwyczaj nie 3 m-ce przed wydaniem wersji stabilnej ;)

Metoda upgrade’u: zmiana wpisów w /etc/apt/sources.list, ja robię zawsze tylko zmianę w nazwie wersji, w tym przypadku: feisty zamieniłem na gutsy. Później na konsoli:

% sudo apt-get update
[...]
% sudo apt-get -d dist-upgrade # tutaj nie byłem jeszcze pewien czy na pewno chcę ryzykować ;)
% sudo apt-get dist-upgrade

Do ściągnięcia było 953MB, ponad 1250 pakietów. Ściągnęło się, jak się już zdecydowałem na ten odważny ( ;) ) krok, to i zainstalowałem wszystkie pakiety, i restart. Wstał - bez problemów. Ale próba zalogowania się powodowała wyłożenie się X-ów. Tu problemem był beryl - wystarczyło zalogować się na “zwykłą” sesję Gnome i poszło. Jeszcze kilka razy się coś wysypało, ale już teraz działa bezproblemowo. Stwierdziłem, że za prosto… no to trzeba dorzucić jakiegoś compiza ;) To już było trudniejsze.

Dodałem repozytoria do sources.list, update, próba instalacji wszystkiego co może być potrzebne - poszło. Próba odpalenia - dupa… I tutaj popełniłem mój największy błąd: postanowiłem odinstalować emerald-a, bo stwierdziłem że może coś nie grać z nim - w końcu to ‘berylowy’ emerald ;) Wywalony, próba instalacji ponowna, i nic z tego - problem z biblioteką libwnck, której beryl potrzebuje w wersji libwnck18 >= 2.1.5, a w GG (Gutsy Gibbon) jest wersja libwnck22. Na nic próby nacisku, walki etc - nie da się zainstalować i koniec ;) Apt-get nie pozwala. A ja nie znam na tyle apt-geta (jak kiedyś poldka) żebym wiedział jak go zmusić do czegoś czego ten nie chce. W ogóle słabo znam te debiany - kiedyś za czasów kiedy bawiłem się admnistrowaniem serwerami poświęcałem czas na naukę danego systemu. Od tego czasu nieco już minęło, a ja wolę używać systemu niż się go uczyć przez 2 miesiące :) Rzycie. Po próbach googlania, czytania, szukania etc, postanowiłem pościągać nieco pakietów ze strony packages.ubuntu.com/gutsy, co było strzałem w dziesiątkę. Po usunięciu wszystkiego compizowo-berylowo-emeraldowego z systemu, ściągnięciu wszystkiego co trzeba (co kojarzyło się z emeraldem i compizem) ręcznie z podanej strony, i zainstalowaniu poprzez % sudo dpkg -i *deb compiz ruszył. Yes!

Jeszcze troszkę walki żeby go uruchomić wraz z logowaniem się do systemu (system >> preferencje >> sesje i trzeba dodać dwie pozycje: compiz --replace cpp i emerald --replace), konfiguracja, żeby animacje były szybsze i kilka innych drobiazgów, i od wczoraj od północy cieszę się działającym compizem na Ubuntu GG :)

Wrażenia z użytkowania GG?

pozytywne:
  • wstaje szybciej
  • działa szybciej
  • w końcu mam osobno na klawiaturze usypianie laptopa, jak i blokowanie klawiatury. Wcześniej działało (z klawiatury) tylko blokowanie wciskając kombinację klawiszy odpowiadającą za usypianie…
  • jest vim 7.1 ;]
negatywne:
  • nie działa usypianie :( nie działa budzenie po usypianiu. Wisi w kosmosie, trzeba go wyłączyć (trzymając power kilka sekund) i bootować od nowa. Porażka :(
  • częściej mi opera muli - szczególnie przy flashkach
  • trochę rzeczy gdzie nie ma polskich tekstów (nie przeszkadza mi zbytnio, choć przyzwyczaiłem się do polskiego ;) )
  • nie działał mi truecrypt, ale też to już zwalczyłem (ściągnięcie źródeł, przejście do katalogu Linux, % sudo ./build.sh - trzeba mieć rozpakowane źródła kernela w /usr/src/linux, % sudo cp Kernel/truecrypt.ko /usr/share/truecrypt/kernel/truecrypt-2.6.22.ko i voila!) ;)
  • gajim nie pobierał z keyringa haseł do moich kont - trzeba było wywalić z pliku konfiguracyjnego gdzie i jakie są to hasła, i podac je jeszcze raz - wtedy zaskoczył