Računi.hr

Novi projekt Damira Sabola, Računi.hr, ima za cilj olakšavanje procesa primanja i plaćanja računa, uz eliminaciju papirologije, čekanja u redovima ili prekucavanja kriptičnih poziva na brojeve.

Odlična ideja, napokon se netko odlučio pozabaviti tim problemom! Stvar nikako nije trivijalna, trebat će puno guranja ideje uzbrdo, ali vjerujem da računi.hr imaju veliku šansu za uspjeh u svom poduhvatu; ne samo zbog odličnog tima koji stoji iza projekta, nego i zbog činjenice da je već od početka (javnog postojanja) tvrtka osigurala investiciju od strane Bicroa te integraciju sa 20-tak hrvatskih banaka.

Prilikom objave novosti, Gadgeterija komentira “[...] čisto sumnjam da će je korisnicima ponuditi besplatno.” Krenuo sam napisati komentar na to na Gadgeteriji, ali se komentar dovoljno povećao da ga stavim u zaseban post:

Vjerujem da korisnici računa.hr (oni od kojih namjeravaju zarađivati) nisu krajnji korisnici, građani, ljudi (ili tvrtke) koji plaćaju račune, nego tvrke koje izdaju račune. Izdavanje papirnatih računa je, naime, poprilično skup posao ako imate mnogo računa. Samo kao brzi primjer, Vipnet ima oko 2.6 milijuna korisnika – ne znam koliko retplatnika, recimo 1 milijun. Ako uzmemo okvirnu cijenu od samo 10lp po printanju i slanju računa poštom, radi se o 100 tisuća kuna mjesečno. (Napomena: moja računica je vrlo otprilike i odokativna, i prave vrijednosti vjerojatno se prilično razlikuju – ali siguran sam da su iznosi veliki.)

Ušteda od 50% kakvu nude Računi.hr na takve iznose nije uopće zanemariva. S druge strane, dio ostvarenog prihoda dijelit će s bankama, koje zbog toga imaju interes u integriranju sa Računi.hr servisom. U cijeloj priči krajnji korisnici nemaju apsolutno nikakve brige – oni uslugu samo dobiju kao opciju u postojećem netbanking sučelju.

Ovaj način integracije s bankama je zanimljiv – kad sam pogledao intro video, pomislio sam da će Računi.hr biti izravan portal za korisnike, preko čijeg sučelja će raditi plaćanje. Problem s takvim pristupom bi bio činjenica da bi od banaka trebali dobiti pristup na korisničkov račun, što ne vjerujem da bi ijedna banka olako dala – minimalno bi Računi.hr morali imati vlastiti netbanking sustav, zajedno sa karticama, tokenima, čitačima i svom skupom zbrkom koja iz toga slijedi. Činjenica da su banke one koje se vežu na računi.hr lijepo zaobilazi cijelu tu zavrzlamu.

Bit će zanimljivo i vidjeti kako će reagirati velike tvrtke koje već imaju razvijen neki vlastiti način paperless računa. Primjerice i Vipnet i T-Com imaju e-račun opcije i stalno gnjave korisnike da pređu na njih. Kad pogledamo gornju računicu očito je zašto. S jedne strane, oni dakle već imaju sustav koji ih ne košta “ništa” (osim održavanja), ali s druge strane, vjerojatno relativno mali broj korisnika koristi njihov sustav.

Ukoliko Računi.hr pokriju većinu velikih banaka (a ako već imaju dogovor sa 20-tak, vjerojatno već imaju tu većinu), imat će veliku bazu korisnika. U tom će slučaju i velikim tvrtkama sa vlastitim sustavima biti isplativo preći na njihov servis. Paperless troškovi će biti veći, ali će biti manje papirnatih računa.

U svakom slučaju, ukoliko Računi.hr projekt uspije (što uvjeren sam hoće, samo je pitanje dinamike), biti će bolje i krajnjim korisnicima, i bankama, i tvrtkama koje izdaju račune. Ali, netko će i nadrapati: oni koji zarađuju na izdavanju i slanju računa. Dakle, pošta te proizvođači/prodavači printera, papira i ostale opreme potrebne za tiskanje, kuvertiranje i pripremanje papirnatih računa.

Svi mi ostali možemo se veseliti što nam je napokon 21. stoljeće zakucalo na vrata i u Lijepoj Našoj :)

PS. Sasvim je prerano pričati o tome, ali ne bih se čudio da u jednom trenu osim samo plaćanja i pregleda računa uvedu analytics ala Mint.

PPS. Sve ovdje navedeno su čisto moja razmišljanja na osnovu zasad poznatih podataka – nisam u nikakvoj vezi sa projektom pa je moguće da sam potpuno promašio poantu. Kakvo je vaše mišljenje?

Razvoj za Android (većinom) iz shella

Dobričin zanimljiv post o komandnoj liniji na Androidu potaknuo me da opišem svoj Android dev setup. (Update: moj setup je na Linux sustavu, iako vjerujem da su koraci slični ili isti i za OS X ili Windows platforme – jedina razlika je u shellu koji koristite i načinu na koji postavljate path)

Vjerojatno većina programera koji razvijaju za Android (ili su bar skinuli SDK i malo gledaju o čemu se tu radi) koriste Eclipse kao razvojno okruženje. Uostalom, Eclipse je i preporučen način razvoja za Android. No kako stvarno ne volim ovaj alat, pri svom radu radije koristim (većinom) komandnolinijske alternative. Na moju sreću, Google nije zanemario i nas koji ne volimo Eclipse, nego nam je osigurao solidan set alata s kojima možemo (gotovo) sve što je moguće i sa Eclipseom.

Uz pretpostavku da je Android SDK instaliran u /opt/android-sdk, pokušajmo kreirati, isprogramirati i deployati “Hello World” aplikaciju. Prvo ćemo podesiti path tako da možemo jednostavno pozivati SDK alate:

> export PATH=/opt/android-sdk

Prvi alat koji nam je potreban se zove android, koji nam koristi za kreiranje naših projekata, konfiguriranje emulatora, nadogradnju projekatata kod nadogradnje SDK-a. Ovaj program ima i GUI i komandnolinijsku varijantu – GUI varijanta je nešto očitija (pogotovo kod kreiranja i konfiguriranja emulatora, odnosno Android Virtual Devicea), no mi ćemo se zasad zadržati na komadnoj liniji.

Pogledajmo prvo koje verzije Androida možemo targetirati:

> android list targets

Ovim ćemo dobiti popis verzija za koje možemo razvijati našu aplikaciju – primjerice, Android 2.1 ovdje ima oznaku “android-7″. Sa ovom informacijom možemo kreirati naš novi projekt:

> android create project --target android-7 \
            --name HelloWorldProject \
            --path moji-projekti/HelloWorldProject \
            --activity Main
            --package hr.primjer.mojprojekt

Alat će kreirati potrebne direktorije i popuniti ih potrebnim stvarima, tako da mi možemo odmah otvoriti novostvorenu moji-projekti/HelloWorldProject/src/hr/primjer/mojprojekt/Main.java i editirati activity naše aplikacije.

Nakon što napravimo promjene, možemo buildati cijeli projekt, za početak u debug modu, koristeći ant, vrlo popularan build tool za Java projekte općenito (svu potrebnu konfiguraciju generirao je prethodni poziv android alata):

> cd moji-projekti/HelloWorldProject
> ant debug

Ukoliko nije bilo grešaka prilikom kompajliranja, trebali bi na kraju dobiti poruku BUILD SUCCESSFUL. Yay! Sada možemo i isprobati kako naša aplikacija radi. Ali prije toga, morat ćemo kreirati i konfigurirati emulator. Naime, Android SDK omogućuje korištenje više emulatora uređaja što je korisno za isprobavanje na različitim hardverskim karakteristikama (npr veličine ekrana, memorija, različiti senzori i slično).

Kako bi kreirali AVD odnosno emulator, najjednostavnije je pokrenuti android bez ikakvih argumenata, čime će se pokrenuti GUI sučelje za konfiguraicju AVD-ova. (Stvar se može i preko komandne linije, ali tko će popamtiti sve switcheve za to).

Kada imamo jedan ili više AVDova kreiranih, možemo ih na brzaka izlistati sa android list avd, a potom i pokrenuti željeni emulator (ili više njih):

> emulator -avd ImeAVDUređaja

Osim samog emulatora, korisna stvar je i Dalvik Debug Monitor (ddms), standalone GUI alat koji omogućuje pregledavanje trace logova, očitanje stanja uređaja, ili emulatora, uzimanje screenshota i slično. Neke od ovih stvari dostupne su i izravno iz komandne linije (za potpun popis upišite samo adb što će vam prikazati pomoć):

> adb devices # lista spojenih uređaja
> adb logcat # ispis trace logova
> adb emu <cmd> # zadavanje naredbe emulatoru
> adb shell # remote shell na emulator ili uređaj

Nakon što smo napravili debug build naše aplikacije, i pokrenuli emulator, trebamo aplikaciju “instalirati” u emulator kako bi je mogli isprobati:

> adb install -r bin/HelloWorldProject-debug.apk

Opcija -r znači “reinstall” i govori adbu da, ukoliko aplikacija već postoji na uređaju, makne postojeću i instalira je nanovo (korisnički podaci pritom ostaju netaknuti).

Ukoliko imate istovremeno pokrenut emulator i spojen uređaj, opcijama -e (emulator) ili -d (device) određujete kamo želite poslati instalaciju. U slučaju da istovremeno imate spojeno nekoliko emulatora ili uređaja, opcijom -s možete točno odrediti cilj naredbe (argument za -s je ID emulatora kojeg možete saznati sa adb devices).. Sve tri opcije vrijede za većinu adb naredbi, ne samo za install.

Nakon što je aplikacija dovršena i prošla je testiranje u emulatorima i na testnim uređajima, potrebno je napraviti release paket, koji možemo distribuirati korisnicima naše aplikacije. Prilikom izrade release paketa, potrebno ga je potpisati našim developerskim ključem (koji, ukoliko aplikaciju distribuirate na Market, mora biti također prijavljen na Android Marketu). Developerski ključ možete sami kreirati alatom keytool, a više o tome možete pročitati na Android Dev Guide stranicama. Procedura je zapravo ista i za Eclipse korisnike i za ostale, osim što ako ne koristite eclipse, putanju do keystorea je potrebno ručno dodati u build.properties datoteku unutar vašeg projekta.

Sam postupak buildanja u release modu i potpisivanja je jednostavan:

> ant release

…nakon čega dobijate bin/HelloWorldProject-release.apk datoteku koju možete instalirati na uređaje, uploadati na Market ili distribuirati na neki drugi način.

Domaće Android aplikacije

Update: složio sam novu, osvježenu listu za 2011. godinu. Novu listu možete pronaći ovdje.

Android

Domaća mobile developer scena zahuktala se u posljednjih par mjeseci. Uz pokretanje Mobile Mondaya, tu su i VIPNet Android Izazov te Budi kreaTivan 2010 natječaji koji su izazvali razmjerno velik interes potencijalnih developera.

Kao rezultat toga, na Android Marketu pojavljuje se sve više domaćih aplikacija, većinom lokalnog karaktera. Kako zapravo ne postoji način za saznati otkud su autori pojedine aplikacije i koliko je aplikacija iz Hrvatske, tijekom posljednjih nekoliko dana bilježio sam domaće aplikacije na koje sam naišao, skupio ih u listu, te vam sada ponosno predstavljam svjetsku premijeru najveće i jedine liste domaćih Android aplikacija:

  • Advanced Call History – praćenje poziva i generiranje izvješća na osnovu prikupljenih podataka.
  • aMazing Submarine – vodite podmornicu kroz labirint, sakupljajte blago i izbjegavajte ribe
  • ATFLOCK – zaključajte telefon za slučaj krađe
  • Aukcije.hr Mobile – pregled najnovijih aukcija na stranicama Aukcije.hr te pregled aktualnih kupnji i prodaje predmeta u aukcijama u kojima korisnik sudjeluje
  • BankoMap – prikaz lokacije bankomata (zasad samo PBZ) u Zagrebu koristeći Google Maps
  • Bela Brojalica – aplikacija za zbrajanje osvojenih bodova u Belotu za četiri igrača
  • Belo zbrajalo – zbrajanje bodova i pregled stanja u Beli
  • Brick Annoyed – klon klasične arkadne igre
  • Burza.ZG – trenutne cijene dionica na Zagrebačkoj Burzi
  • Buzdo, swinging mace – simulacija klatna, koristi akcelerometar za kontrolu
  • Croatian keyboard – hrvatska tipkovnica za Android
  • Croatian News Widget – najnovije vijesti iz Hrvatske na home screenu (widget i aplikacija)
  • CRO City Info – u par klikova iz vašeg mobitela pronađite sve važne lokacije, druge informacije, prijevoz te mapu pokrivenosti besplatnim Wi-Fi-jem
  • CRO Prognoza / Weather – sedmodnevna vremenska prognoza za više od 40 hrvatskih gradova
  • Cro Tourist Guide – pretraživanje turističkih odredišta i smještaja u Hrvatskoj (vuče podatke sa www.crotouristguide.com)
  • Crypto – aplikacija za kriptiranje slika
  • DSSAndroidAutomation – info o kontaktima, nepročitanim porukama, propuštenim pozivima
  • DSS Numerologija – izračunajte svoj sretan broj ili provjerite “kompatibilnost” sa simpatijom
  • Elevation and Sea Depth – saznajte nadmorsku visinu i dubinu mora u smjeru u kojem usmjerite svoj mobitel
  • Gdjesi.com – mobilni klijent za gdjesi.com servis
  • GPS Explorer – aplikacija za mjerenje područja i praćenje ruta
  • GPS Tracker – praćenje lokacije i slanje podataka na server tracking.virtualniured.hr
  • HGSpot Mobile – čitajte vijesti i pretražujte proizvode iz HGSpota
  • HNB Exchange Rate – tečaj Hrvatske Narodne Banke
  • Hoću u kino! – popis hrvatskih kina i njihov raspored
  • Horvat Andro – aplikacija za Android uređaje koja prikazuje najnovije informacije iz hrvatskog internetskog prostora.
  • HotFuzz – saznajte što se zbiva u vašem gradu
  • HRT Teletext – čitajte najnovije informacije objavljene na HRT teletekstu
  • HrStock – pregled burzovnih indeksa regije
  • Lociraj! – traženje obližnjih točaka (POI) – mobilni klijent za Lociraj.net
  • Lokacijski Alarm – podsjetnik o vama važnim lokacijama, pali se kad ste u blizini neke od njih
  • Ljetni Recepti – 20-ak recepata za osvježavajuće napitke koje možete sami napraviti u svega nekoliko minuta
  • Meet Croatia – sakupljajte bodove posjećivanjem lokacija u Hrvatskoj
  • Meet Friends@Vip – jednostavno organiziranje sastanaka s prijateljima putem poruka, slika, zvučnih zapisa i lokacija te pregleda javnih događaja u blizini
  • Mjere (Measures) – ucrtavanje mjera u postojeće slike
  • Mobilisis ATM – pronađite najbliži bankomat u Hrvatskoj
  • Mobilisis Fleet – pratite lokaciju svojih vozila, zaposlenika ili djece (moraju imati instaliranu Mobilisis Tracker aplikaciju)
  • Mobilisis Parking – aplikacija za plaćanje parkinga
  • Mobilisis Tracker – aplikacija za praćenje lokacije mobitela (za praćenje treba koristiti Mobilisis Fleet aplikaciju)
  • mPlaćanje – brzo i jednostavno plaćanje parkinga, garaže ili javnog gradskog prijevoza putem SMS-a u raznim gradovima Hrvatske
  • Novinator – Novinator vam omogućuje pregledavanje vaših omiljenih news portala čak i kada nemate pristup Internetu
  • Novine – pratite najnovije vijesti iz nekoliko domaćih portala
  • Parking – jednostavno plaćanje parkinga
  • Poštanski broj – pregled poštanskih brojeva i ureda unutar Republike Hrvatske.
  • Praznik – prikaz hrvatskih praznika i blagdana
  • Prepaid status widget – provjeravanje stanja prepaid računa i drugih USSD funkcija
  • PrvaPomoc (First Aid) – aplikacija za bilježenje kritičnih informacija kod hitnog slučaja
  • Qibla Compass – aplikacija za vjernike muslimanske vjeroispovjesti – vremena molitava te udaljenost i smjer Meke
  • Rođoš – omogućava vam da na jednom mjestu vidite sve nadolazede rođendane
  • Slooshaj! – aplikacija za slušanje hrvatskih radio stanica putem Interneta
  • Slušaj Radio! – slušanje hrvatskih radio stanica putem Interneta
  • SMSparking – plaćanje parkinga u preko 50 hrvatskih gradova
  • StormWatcher – korištenjem radarske snimke oblaka, aplikacija pokušava predvidjeti nevrijeme
  • Teletext – aplikacija za čitanje HRT Teleteksta
  • Tele2SMS – aplikacija za besplatno slanje SMSova za Tele2 korisnike (putem online Tele2 usluge besplatnog slanja SMSa)
  • This phone is mine! – osvetite se prijateljima koji isprobavaju vaš mobitel
  • Trambus – lakše snalaženje u autobusnom i tramvajskom prijevozu Zagreba automatski računajući rute, locirajući najbliže stanice.
  • Tramzilla – aplikacija za praćenje tramvajskog prometa
  • TransDict – riječnik i prevoditelj
  • Transmeet.TV MusicMap – detaljni pregled zanimljivih glazbenih događanja
  • Troskovnik – planiranje odlaska u kupovinu i računanje troškova prilikom kupovine
  • TVDroid – TV vodič, podržava ~260 TV postaja u Hrvatskoj i široj regiji + satelitski programi
  • Tv Guide – prikaz programa hrvatskih TV postaja s mogućnošću odabira kanala, filtriranja i detaljnog pregleda
  • TV Raspored – brzi pregled tjednog TV programa
  • VIP RoamingViewer – informacije o roaming cijenama, operaterima za korisnike VIPNeta
  • VMC application – mobilni klijent za Croatian Vip Music Club portal
  • Weather Forecast USA – vremenska prognoza za SAD
  • Weekend in Croatia – višejezična aplikacija za pronalaženje vikend/turističkih lokacija (mobilni klijent za vikendi.com)
  • Svjetozor / Worldscope – pregledavanje slika s web kamera diljem svijeta
  • Young Duke Domagoj – preživite što duže dok vas napada horda zombija
  • Zagreb Tram – prikaz tramvajskih linija, stanica, najbliže stanice, voznog reda, kupnja karte za ZET
  • ZETPanic – brzo aktiviranje usluge ZET mPrijevoz
  • Žabolomac – žabac iz bajke kroz 30 nivoa i 3 područja treba savladati niz izazova kako bi došao do svoje princeze

Napomene: Oneliner opisi pojedine aplikacije preuzeti su iz njenog opisa u Marketu, uz ponegdje slobodan prijevod sa engleskog i skraćivanje/parafraziranje opisa – ako uočite bilo koju grešku ili smatrate da sam krivo prepričao opis, ili ste našli aplikaciju koju ja nisam pa je nema u popisu, molim vas da mi javite. Također, većinu ovih aplikacija nisam isprobao, a i za one koje jesam, ovdje ne donosim svoj sud, mišljenje ili preporuku. Prilikom isprobavanja pojedine aplikacije, preporučam pročitati komentare na Marketu (te dati i vlastiti komentar/ocjenu, čime ćete autoru aplikacije dati dragocijeni feedback za daljnji razvoj iste).

Update: dodane aplikacije: Žabolomac, aMazing Submarine, HrStock, Meet Croatia, Tv Guide, Mobilisis (ATM, Fleet, Parking, Tracker), Praznik, Rođoš, VMC application, Hoću u kino!, Gdjesi.com, Tele2SMS. Maknut Columbus (slovačka aplikacija).

Update2: dodani HRT Teletext, HotFuzz, Transmeet.TV MusicMap, Worldscope

Update3: dodani Elevation and Sea Depth, Qibla Compass, Weather Forecast USA.

Rat web video formata: VP8 vs. H.264 (iliti Google vs. Apple)

VP8 vs. H.264

Prošli tjedan je Google na svojoj IO konferenciji objavio kako će svoj VP8 video kodek učiniti dostupnim svima pod slobodnim licencama. Samu objavu podržao je veliki broj organizacija i firmi, među ostalima Mozilla, Opera, Adobe, donekle Microsoft, kao i neki proizvođači hardvera – nVidia, ARM, AMD, Texas Instruments.

Posebnost objave je to da je VP8 ne samo kvalitetan (kvalitetniji od H.263, Theore ili Flash videa) i besplatan (odnosno enkoder/dekoder i specifikacija su potpuno otvoreni i slobodni za korištenje) nego je i neopterećen patentima. Točnije, Google kaže da je u posjedu svih patenata koje VP8 koristi, kao i da te patente daje u slobodno korištenje svim korisnicima VP8 kodeka. U praksi ovo znači da bilo tko može koristiti kodek (bilo za kreiranje sadržaja, distribuciju, ili samo gledanje) bez da ima obavezu bilo kome bilo što plaćati.

Worse is better?

To ga čini puno privlačnijim (sa pravno/ekonomske strane) od H.264, trenutno najzastupljenijeg (ako ne računamo ne-hd Flash videe, koji koriste stariji i lošiji kodek) kodeka za web video. H.264 je tehnološki bolji od VP8, ali je opterećen patentima. MPEG-LA, organizacija koja zastupa vlasnike patenata koje koristi H.264 trenutno dozvoljava njegovo korištenje uz prilično liberalne uvjete, ali vrlo je vjerojatno da će ih pooštriti (tj. početi naplaćivati) kad zaključi da joj se to isplati – odnosno čeka da većina sadržaja bude u H.264 i da ga svi koriste, pa će onda samo ubirati svoj dio.

Iscrpnu usporedbu tehničkih karakteristika oba kodeka napravio je Jason Garrett-Glaser, glavni developer na x.264 (open source H.264 enkoder, vjerojatno najbolji na svijetu). Njegov zaključak je kako je VP8 tu negdje po kvaliteti kao osnovna verzija H.264 (tzv. Baseline Profile, inačica koja se većinom koristi u mobilnim uređajima), dok su naprednije verzije H.264 puno bolje od VP8 (dakle, nećemo uskoro gledati 1080p filmove u VP8 kodeku). Također kaže da su sami enkoder i dekoder trenutačno prilično ne-optimalni, za što je realnio zaključiti da će se popraviti s vremenom.

Jason također tvrdi da su VP8 i H.264 zapravo vrlo slični – toliko slični da je moguće da VP8 ipak krši patente iz H.264. Njegovo mišljenje također dijeli i Steve Jobs, iako je za vjerovati da je to Jobsov primarno politički stav (Apple svugdje koristi H.264, jedan je od vlasnika patenata nad njim, i nikako im ne odgovara da svi ostali pređu na VP8).

Rat patenata

S druge strane, prilično je teško vjerovati da brojni odvjetnici Googlea i ostalih firmi koje ga podržavaju u ovome projektu nisu vrlo pažljivo pregledali svaki komadić kodeka i uvjerili se da nema opasnosti. Softverski patenti su vrlo specifični – da bi se dokazalo da netko koristi tuđi patent, potrebno je dokazati da precizno radi točno ono što piše u patentu. Kod H.264 stvar je čista, jer sam standard specificira točno one stvari koje su i u patentima. Ali kod VP8, ako je on samo “sličan”, ne mora značiti da krši bilo što. Dapače, lako je moguće da su očiti nedostaci VP8 u odnosu na H.264 izostavljeni baš zato kako bi se zaobišli patenti.

Naravno, MPEG-LA je već najavila pripremanje “patent poola” i analizu VP8 kako bi ustanovila koji su patenti prekršeni. Ali njihovu izjavu treba shvatiti u kontekstu toga da se oni samo tim i bave, i već godinama najavljuju da će krenuti u pohod na Vorbis (slobodni i otvoreni audio kodek) zbog povrede neimenovanih patenata, pa još nisu. S druge strane, Google se drži prilično samouvjereno, i već je najavio da će svi sadržaji na YouTube-u biti rekodirani u VP8.

Ono čemu se mnogi nadaju i što bi svakako zacementiralo sigurnost u VP8 je Googleova izjava da će na sebe preuzeti sav rizik od eventualne tužbe za povredu patenata – no teško je vjerovati da bi se Google želio toliko izložiti, bez obzira na to koliko su samouvjereni. U nedostatku toga, vrijeme će pokazati koliko su strahovi oko VP8 utemeljeni. U svakom slučaju, zanimljiva su vremena za web <video/> pred nama.

PS. VP8 podrška dostupna je već za brojne free software multimedia projekte, među kojima su GStreamer, FFMpeg, MPlayer, VLC, itd. Više informacija kako gledati VP8 sadržaje može se naći na stranicama WebM projekta. I hrvatski web može se pohvaliti eksperimentalnom podrškom za VP8 na CARNet Media on Demand portalu.

Git početnica, 4. dio – rješavanje konflikata

U prošlom postu u Git serijalu spomenuli smo mogućnost konflikata prilikom rebaziranja ili spajanja grana te dali par sugestija kako ih izbjeći. No kod kompliciranijih projekata i workflowova konflikti su ponekad neizbježni, stoga je korisno znati kako riješiti konflikt kad do njega dođe.

Rješavanje konflikata

Ukoliko sami radite na projektu, konflikti vam se vjerojatno neće događati (osim ukoliko ne pazite). No, ukoliko radite na projektu sa više ljudi, može vam se zadesiti da se nađete u situaciji gdje ćete morati riješiti konflikt.

Recimo da je naš helloworld projekt dobio na važnosti i sada na njemu rade dva developera, Mirko i Slavko. Mirko i Slavko u stvarnom životu radit će na svojim granama u svojim klonovima repozitorija, ali da si ovdje pojednostavnimo priču, svaki će imati po jednu granu u našem zajedničkom repozitoriju.

Kreirajmo obje grane, bez prebacivanja u njih:

> git checkout master
Switched to branch 'master'

> git branch mirko
> git branch slavko
> git branch -l
  helloworld-0
* master
  mirko
  slavko

Dolazi Mirko, vidi problem u načinu kako je definirana funkcija main i popravlja ga u svojoj grani:

> git checkout mirko
Switched to branch 'mirko'

[...promjene hello.c...]

> git diff
diff --git a/hello.c b/hello.c
index 0bb4941..8b08068 100644
--- a/hello.c
+++ b/hello.c
@@ -1,6 +1,7 @@
 #include <stdio.h>

-int main(void)
+int
+main(int argc, char *argv[])
 {
   printf("Hello world\n");
   return 0;

> git commit -a -m "popravio main prototip"
[mirko 4e5f904] popravio main prototip
 1 files changed, 2 insertions(+), 1 deletions(-)

U međuvremenu, dolazi Slavko, vidi isti problem, ne zna da je Mirko radio na istoj stvari pa ga rješava kod sebe:

> git checkout slavko
Switched to branch 'slavko'

[...promjene hello.c...]

> git diff
diff --git a/hello.c b/hello.c
index 0bb4941..38586b0 100644
--- a/hello.c
+++ b/hello.c
@@ -1,6 +1,6 @@
 #include <stdio.h>

-int main(void)
+int main(int argc, char **argv)
 {
   printf("Hello world\n");
   return 0;

> git commit -a -m "prepravio definiciju funkcije main"
[slavko 4bb59be] prepravio definiciju funkcije main
 1 files changed, 1 insertions(+), 1 deletions(-)

Sve je dobro dok su promjene u zasebnim granama. No u jednom trenu ćemo željeti sve Mirkove i Slavkove promjene spojiti u master. Prva promjena će proći dobro, no na drugoj će nam se dogoditi konflikt.

> git checkout master
Switched to branch 'master'

> git merge mirko
git merge mirko
Updating 302ef80..4e5f904
Fast-forward
 hello.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

> git merge slavko
git merge slavko
Auto-merging hello.c
CONFLICT (content): Merge conflict in hello.c
Automatic merge failed; fix conflicts and then commit the result.

Uh, huh… obojica su mijenjala isto mjesto u istoj datoteci, i git ne zna kako riješiti problem. Zbog toga je merge pauziran i dana nam je prilika da riješimo konflikt. Pogledajmo što se dogodilo:

git diff
diff --cc hello.c
index 8b08068,38586b0..0000000
--- a/hello.c
+++ b/hello.c
@@@ -1,7 -1,6 +1,11 @@@
  #include <stdio.h>

++<<<<<<< HEAD
 +int
 +main(int argc, char *argv[])
++=======
+ int main(int argc, char **argv)
++>>>>>>> slavko
  {
    printf("Hello world\n");
    return 0;

> cat hello.c
#include <stdio.h>

<<<<<<< HEAD
int
main(int argc, char *argv[])
=======
int main(int argc, char **argv)
>>>>>>> slavko
{
  printf("Hello world\n");
  return 0;
}

Diff prikazuje obje nekompatibilne promjene. Prva je iz trenutne grane (odnosno to je ona Mirkova promjena koju smo uspješno preuzeli spajanjem Mirkove grane), dok je druga iz grane slavko. Rješimo konflikt modificiranjem tog dijela datoteke da izgleda onako kako mi želimo:

[...promjene hello.c...]
cat hello.c
#include <stdio.h>

int
main(int argc, char **argv)
{
  printf("Hello world\n");
  return 0;
}

> git diff
diff --cc hello.c
index 8b08068,38586b0..0000000
--- a/hello.c
+++ b/hello.c
@@@ -1,7 -1,6 +1,7 @@@
  #include <<tdio.h>

 -int main(int argc, char **argv)
 +int
- main(int argc, char *argv[])
++main(int argc, char **argv)
  {
    printf("Hello world\n");
    return 0;

> git add hello.c
> git commit
[master fd96bab] Merge branch 'slavko'

Diff prikaz u slučaju konflikata je pomalo zbunjujuć, no snalaženje u samoj datoteci koju treba popraviti je relativno jednostavno - konflikt je između <<<<<<< i >>>>>>>, a ======= razdvaja konfliktne promjene.

Konflikt prilikom rebaziranja

Kao što smo već prije vidjeli, obično želimo grane održavati tako da u svakom trenu njihove promjene budu primjenjive na master (odnosno na baznu granu gdje ih na kraju želimo spojiti), a jedan od razloga je upravo izbjegavanje konflikata kod spajanja.

Jedan od razloga zbog kojih je konflikt kod spajanja nezgodan je i činjenica da problem praktički "prebacujemo" onom tko radi merge, a kod većih projekata to je obično osoba koja održava projekt (tj. glavni developer). Ukoliko od nje tražite da granu sa vašim promjenama spaja sa masterom, a to izaziva konflikte kod mergea, zapravo ste prilično nepristojni.

Zato je bolje prije nego zatražite (ili krenete raditi) spajanje rebazirati svoju granu tako da samo spajanje bude čisto. To znači da ćete eventualne konflikte morati sami rješiti prilikom rebaziranja.

Vratimo se malo u prošlost i zaboravimo da smo radili merge Mirkove i Slavkove grane:

> git reset --hard 302ef80039bd55fbbc680d84e37e5ebcf7f63a5c
HEAD is now at 302ef80 dodan README

Mirko odluči spojiti svoju granu s masterom. Njegovu granu nije potrebno rebazirati jer se nastavlja na master (tj master nema nikakvih novih promjena):

> git merge mirko
Updating 302ef80..4e5f904
Fast-forward
 hello.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

Slavko odluči spojiti svoju granu. Njegovu granu je potrebno rebazirati jer
master ima novih comittova:

> git checkout slavko
Switched to branch 'slavko'

> git rebase master
First, rewinding head to replay your work on top of it...
Applying: prepravio definiciju funkcije main
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging hello.c
CONFLICT (content): Merge conflict in hello.c
Failed to merge in the changes.
Patch failed at 0001 prepravio definiciju funkcije main

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

Ovo izgleda mnogo strašnije nego poruka kod mergea! Ali problem je isti, u što se možemo uvjeriti pomoću git diff (s tim da će umjesto imena naše grane biti naziv commita u našoj grani s kojim ima problema). Nakon što napravimo ispravke u datoteci, trebamo nastaviti proces rebaziranja:

[...promjene hello.c...]
> git add hello.c
> git rebase --continue
Applying: prepravio definiciju funkcije main

Ovdje nismo ručno radili git commit, nego smo nakon popravka nastavili proces rebaziranja. Kako rebaziranje ide commit po commit, ukoliko ima još konflikata u narednim commitovima, rebase bi se opet zaustavio i zatražio da popravimo stvari.

Ukoliko zaključimo da je commit nepotreban (npr. zato što je u drugoj grani taj problem već riješen), možemo ga odbaciti. Ako se radi o ozbiljnom problemu za kojeg ne znamo kako ga riješiti, možemo prekinuti rebase, a grana će nam se vratiti u prvobitno stanje. U tom slučaju ćemo vjerojatno morati rješavati merge konflikte prilikom spajanja i napraviti merge a ne rebase.