Autor Zpráva
GTI
Profil *
Ahoj potřeboval bych pár rad jak používat github. s kolegou jsme se rozhodli verzovat si projekt, vždy si stáhneme verzi z gitu, pracujeme na ní a pak jí tam zase commitneme. problém je ale ten, pokud oba upravíme stejný soubor. zahlásí nám to že došlo ke kolizi. jak se takové věci řeší? Asi je blbost se domlouvat kdo které skripty bude upravovat tak abychom náhodou oba nesáhli do stejného souboru.
S gitem teprve začínám tak bych se rád dozvěděl několik tipů od zkkušenějších. díky :)
juriad
Profil
GTI:
Tak se provede buď merge (obvykle) nebo rebase (pokud dobře víš, co děláš).
http://git-scm.com/book/cs/v1/V%C4%9Btve-v-syst%C3%A9mu-Git-Z%C3%A1klady-v%C4%9Btven%C3%AD-a-slu%C4%8Dov%C3%A1n%C3%AD
Klidně si přečti od začátku prvních 5 kapitol té knihy.

Máte tedy v projektu celkem pět větví (tři uživatelé: A, B a Server):
S ... co je uloženého na serveru
A ... co vidí A
AS ... co si A myslí, že je na serveru
B ... co vidí B
BS ... co si B myslí, že je na serveru

Je několik operací, které pracují s větvemi:
commit - přidá commit do aktuální větve, tedy A -> A
merge - přidá commit, který obsahuje změny ze všech větví (nebo neudělá nic, pokud žádné změny nejsou, případně jen změní, kam větev ukazuje)
Pak jsou operace pracující se vzdálenými větvemi:
fetch - stáhne změny ze serveru do lokální kopie serveru S -> AS (povede se vždy)
pull - provede fetch a následně merge (A, AS) -> A (merge může zůstat viset)
push - pošle lokální verzi na server A -> AS, A -> S (jen když A je potomkem AS)

Obvykle všechny tyto větve ukazují na stejný commit.
Pokud uživatel A změní svou větev A a změnu commitne, git mu zahlásí, že je o 1 krok před AS.
Pak dá push a výsledkem bude (A = AS = S) != (B = BS)
Ty bys v ten okamžik měl provést pull, a tedy si nastavit BS na S a provést fast-forward merge BS do B.

Pokud však něco commitneš, tak (A = AS = S) != B != BS.
Při pushi to selže protože B sice následuje po BS, ale nenásleduje po S (protože je tam ten commit od A).

OK, provedeš pull, který je ve sktečnosti jen zkratka za fetch a merge.
Fetch způsobí že: (A = AS = S = BS) != B. Tedy, zjstí nový stav BS.
A pak provede merge - commit, který spojí změny od obou uživatelů. Merge často může zůstat viset a je potřeba jej doladit ručně (třeba když oba uživatelé změní tu samou řádku kódu). Merge vytvoří nový commit v B, který však už je potomkem BS a tedy může být pushnutý.
Po pushi by si měl A pullnout, nebo se dostane do situace, ve které byl B.

Klidně si vytvoř na githubu nový projekt, vytvoř v něm soubor s jediným řádkem. A můžeš si s tím hrát. Klidně můžeš i sám, protože projekt můžeš mít naklonovaný několikát (stačí je mít v různých adresářích, protože git je jen the stupid content tracker).
Zkus si změny v různých souborech, změny v různých částech stejného souboru a změny stejných řádek v jednom souboru. Vždy napřed commitni změny obou uživatelů a pokus se docílit stavu, aby oba uživatelé viděli soubor po provedení všech změn.


Prakticky: pokud se nepovede push, tak udělej pull a následně znovu push.
Pull může zůstat viset, v takovém případě musíš změny doladit ručně (soubory potvrzuješ pomocí add a nakonec potvrdíš celé pomocí commit).
GTI
Profil *
Děkuji za vyčerpávající odpověď. nejsem si jist jestli jsem to správně pochopil. A a B mají každý vlastní větev (branch)? Každý teda rpogramuje na svém odděleném kodu, commituje si svojí větev a jednou za čas se udělá merge a obě větve se spojí?
Jan Tvrdík
Profil
GTI:
Ano, každý pracuje primárně se svojí lokální větví.
GTI
Profil *
Takže na začátku vytvořím projekt, nahraju ho na github a nasdílím ho kolegovi. on si ho stáhne, vytvoří si na gitu svojí vlastní větev a do ní ho bude commitovat, já budu commitovat tu hlavní větev a čas od času vezmu jeho verzi a udělám merge s mojí? co se přitom merge stane? když budou dvě různý verze jednoho souboru tak co potom?
juriad
Profil
GTI:
Když si ho stáhne (git clone), tak se u něj automaticky vytvoří dvě větve: lokální a klon vzdálené, on sám žádnou nevytváří.
Normálně pracuje v té lokální. Čas od času si pullne, aby měl v projektu aktuální kód, který je v GitHubu.
Předtím než pushne provede pull (aby měl jistotu, že pracuje s aktuální verzí). Pak bez problému provede push.

Takto pracují všichni. Merge obvykle manuálně spouštět nemusí nikdo. O to se postará pull. Musíš však vědět, jak řešit konflikty, které při pullu občas nastanou.

Merge v podstatě funguje tak, že vezme soubory dvou verzí a najde v historii, kdy naposledy byly shodné. A pak změny, které nastaly v jedné verzi (od té společné) aplikuje na tu druhou verzi.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: