Portál AbcLinuxu, 8. května 2025 19:06
Teoreticky ti můžou chodit jednotlivé patche, které si budeš postupně aplikovat. To není moc praktické, ale ani to není moc potřeba. U DVCS není problém provozovat několik serverů souběžně, klidně v různých zemích nebo i přes Tor či jinou podobnou síť, a být odolný proti výpadkům a cenzuře. Pokud ti neprojde hg pull
(nebo obdobný příkaz u jiného VCS) z jednoho serveru, stáhneš si změny odjinud. Když budou autoři podepisovat jednotlivé verze pomocí GPG nebo ti alespoň důvěryhodnou cestou sdělí hash verze, kterou si máš stáhnout, tak nemusíš ani věřit provozovateli toho hostingu. Integrita dat přenášených od autora k tobě by měla být zajištěna.
Problém s e-mailovými konferencemi je hlavně mizerné rozhraní archivů – většinou je to nějaká webová aplikace nebo staticky vygenerované HTML stránky, ale procházet si starší konverzace (z doby, kdy jsi do konference nebyl přihlášený) nebo se do nich dokonce zapojit je značně nepohodlné. Tenhle problém řeší protokol NNTP – přes něj si můžeš stáhnout i starší zprávy do své schránky. Většina projektů má ale jen e-mailovou konferenci bez NNTP rozhraní (byť tyhle dvě technologie lze propojit/přemostit a mít oboje). Pak je taky problém s uživatelským rozhraním e-mailových (či NNTP) klientů, které by mohlo být výrazně lepší.
Další možnost je Fossil, což je distribuovaný verzovací systém, který v sobě obsahuje i systém na správu požadavků/chyb, wiki a fórum (příklad). Stejně jako si stahuješ zdrojáky (clone
, pull
), tak si můžeš stahovat i ty další věci a všichni mají kopii všeho.
U DVCS není problém provozovat několik serverů souběžně, klidně v různých zemích nebo i přes Tor či jinou podobnou síť, a být odolný proti výpadkům a cenzuře.Mně to teda tak jednoduché nepřijde. Jakým způsobem se má udržovat vzájemně konzistentní stav třeba 10 gitových upstream repozitářů? Má se pushovat do jednoho a mirrorovat do ostatních? V té chvíli máš opět jednu achilovu patu. Má se pushovat do všech najednou? V té chvíli narazíš na problém se synchronizací. Když budou dva lidi pushovat souběžně, tak se může stát, že se člověku podaří pushnout třeba do poloviny repozitářů, tomu druhému mezitim do druhé poloviny a pak jim to oboum selže. A v té chvíli jsou ta repa v navzájem nekonzistentním stavu. Tady narážíme na to, oni ty DVCS až tak moc distribuované ve skutečnosti nejsou.
Problém s e-mailovými konferencemi je hlavně mizerné rozhraní archivů – většinou je to nějaká webová aplikace nebo staticky vygenerované HTML stránky, ale procházet si starší konverzace (z doby, kdy jsi do konference nebyl přihlášený) nebo se do nich dokonce zapojit je značně nepohodlné. Tenhle problém řeší protokol NNTP – přes něj si můžeš stáhnout i starší zprávy do své schránky. Většina projektů má ale jen e-mailovou konferenci bez NNTP rozhraní (byť tyhle dvě technologie lze propojit/přemostit a mít oboje). Pak je taky problém s uživatelským rozhraním e-mailových (či NNTP) klientů, které by mohlo být výrazně lepší.Vetsina projektu, do kterejch prispivam, pouziva na archivy https://public-inbox.org/design_notes.html , kterej podporuje NNTP a dokonce se da i pres web stahnout mbox, takze tvuj popis by sedel spis tak na situaci z doby po tom, co zmizel news.gmane.org
Možná jsem to někde zahlédl, ale spíš je v nějakých zprávičkách, než že bych to viděl někoho používat v praxi. Možná škoda jejich pojetí marketingu:
It's online and public, so it already markets itself.
Nicméně podívám se na to, může to být fajn. BTW: je někde seznam projektů, které to používají? (zatím jsem našel jen seznam hostovaných u nich)
a je nejaky rozumny zpusob, jak … ze dvou repositaru udelat jeden
Ale on je. Říká se mu "merge".
Vůbec ne, v tom je největší síla gitu. Než jsem poznal git, měl jsem ze SVN dojem, že větve jsou opruz a merge je něco strašidelného, čemu je lepší se za každou cenu vyhnout. S gitem bylo najednou všechno přehledné a srozumitelné a merge přirozená a logická operace.
Jen je potřeba překonat myšlenkový blok, že větev má být lineární posloupnost commitů. Pak v tom, že dva lidé do větve nezávisle přidají každý něco jiného, přestanete vidět problém.
přidají každý něco jinéhoTo je takovy ten drobny detail, ktery radeji nebudeme rozpitvavat...
Vůbec ne, v tom je největší síla gitu. Než jsem poznal git, měl jsem ze SVN dojem, že větve jsou opruz a merge je něco strašidelného, čemu je lepší se za každou cenu vyhnout. S gitem bylo najednou všechno přehledné a srozumitelné a merge přirozená a logická operace.
Modernější VCS oproti SVN sice přinášejí nějaký pokrok, ale… Jednak to není specifické pro Git a jednak: vědět, co se změnilo a na jaké verze to navazuje, to je ta lehčí část.
Skutečné problémy jsou dva: 1) Řešení konfliktů, pokud nastanou – to většinou nakonec musí dělat člověk. 2) Ověření, že máme použitelný výsledek, i když „merge proběhl hladce“. I když ke konfliktu nedojde, tak to ještě neznamená, že program bude fungovat a dělat, to co autoři jednotlivých změn zamýšleli. Část této kontroly za nás udělá kompilátor a část testy, ale většinou se úplně bez lidské kontroly obejít nelze.
Jen je potřeba překonat myšlenkový blok, že větev má být lineární posloupnost commitů.
Tak zrovna větev v Gitu je pouze štítek ukazující na určitý uzel grafu. Tento štítek se automaticky posouvá při přidávání nových uzlů. Ve skutečnosti tedy v Gitu nic jako větve neexistuje (skutečné větve jsou třeba v Mercurialu, kde se ty pseudo-větve gitovského stylu nazývají bookmark).
Ale to nechme stranou. Když dělám merge, tak pod pojmem „větev“ chápu spíš celou tu část grafu od společného předka až k tomu štítku, ne jen ten štítek samotný. A co jiného než lineární posloupnost to potom je?
Z hlediska funkce to pořadí většinou významné je a kdybychom ty patche aplikovali v jiném pořadí, často by došlo ke konfliktu, program by nešel přeložit nebo by nefungoval, jak má.
Můžeme mít architekturu softwaru dostatečně modulární, můžeme mít kód šikovně rozdělený do spousty menších souborů, můžeme uvnitř nich mít funkce/metody/struktury šikovně uspořádané tak, aby nebylo potřeba nic moc přepisovat a aby změnu stačilo dělat na jednom místě, můžeme práci organizovat tak, aby každý vývojář dělal na něčem jiném… a tím předejít konfliktům (a často je to dobrá praxe i z jiných důvodů), ale pak nemůžeme říkat, že za nás Git magicky řeší nějaký problém – my jsme ten problém totiž odstranili nebo obešli, takže k němu vůbec nedochází a není co řešit (tzn. podobně hladce by to mohlo fungovat i v SVN nebo jiném systému). Pak můžeme skutečně jednotlivé skupiny patchů nebo větve chápat jako jakési (sub)moduly, které můžeme libovolně přidávat do výsledné kompilace (opět nějaké větve). Ten merge je pak něco jako instalace modulu.
Tak zrovna větev v Gitu je pouze štítek ukazující na určitý uzel grafu. Tento štítek se automaticky posouvá při přidávání nových uzlů. Ve skutečnosti tedy v Gitu nic jako větve neexistuje (skutečné větve jsou třeba v Mercurialu, kde se ty pseudo-větve gitovského stylu nazývají bookmark).Vim, jakej je technickej rozdíl mezi větvema v gitu a v Mercurialu (mam zkušenost s Mercurialem), ale zatim mi nikdo moc neuměl říct, k čemu jsou ty Mercurial-like (kterým říkáš 'skutečné') větve dobré. Co se s nima dá udělat co nejde s git branchema? O jednom rozdílu vim: hg commity si "pamatujou" jméno původní branche. Přiznám se, že nerozumim moc, k čemu to je dobré, navíc vzhledem k tomu, že to je jen jméno, ne nějaká unikátní identifikace (branchí se stejným jménem ale jiným obsahem může existovat v čase i prostoru libovolné množství). Jinak zatim nevim.
O jednom rozdílu vim: hg commity si "pamatujou" jméno původní branche. Přiznám se, že nerozumim moc, k čemu to je dobré, navíc vzhledem k tomu, že to je jen jméno, ne nějaká unikátní identifikace (branchí se stejným jménem ale jiným obsahem může existovat v čase i prostoru libovolné množství).Pokud v projektu existuje standardizovaný způsob pojmenovávání větví podle issue a používáš feature/issue větve, tak máš zpětně možnost se kdykoliv podívat, v rámci jaké issue byl daný commit vytvořený, bez toho, že by takhle musely být pojmenované jednotlivé commity. Hodí se obzvlášť, když změny pro jednu issue jsou rozdělené do více commitů za sebou. Pokud tohle chceš u gitu, tak musíš, AFAIK, nechávat ty větve v existenci, což rychle udělá branch listing nepoužitelným. Je to prostě další možnost, jak si nastavit tyhle procesní záležitosti tak, aby vyhovovaly workflow projektu.
Pokud v projektu existuje standardizovaný způsob pojmenovávání větví podle issue a používáš feature/issue větve, tak máš zpětně možnost se kdykoliv podívat, v rámci jaké issue byl daný commit vytvořený, bez toho, že by takhle musely být pojmenované jednotlivé commity.Tohle v gitu řeší merge commit, v něm je zapsaná informace o větvi, která se merguje, a IIRC i třeba případný konflikty. Případně některý projekty maj tooling, kterej tam dává další informace. Z tohohle důvodu řada projektů vůbec nedovoluj fast-forward merge, IIRC tohle je default nastavení na GitLabu.
Tak zrovna větev v Gitu je pouze štítek ukazující na určitý uzel grafu. Tento štítek se automaticky posouvá při přidávání nových uzlů. Ve skutečnosti tedy v Gitu nic jako větve neexistuje (skutečné větve jsou třeba v Mercurialu, kde se ty pseudo-větve gitovského stylu nazývají bookmark).
To ale není nedostatek nebo slabina návrhu gitu, ale právě jeho obrovská síla: že nemusím řešit, jestli mi větev ukazuje na konkrétní uzel grafu nebo jestli reprezentuje celou historii, která k němu vedla, protože tím uzlem je dána celá historie až k němu.
Ale to nechme stranou. Když dělám merge, tak pod pojmem „větev“ chápu spíš celou tu část grafu od společného předka až k tomu štítku, ne jen ten štítek samotný. A co jiného než lineární posloupnost to potom je?
Je to část grafu, ale vůbec to nemusí být - a velmi často není - lineární posloupnost.
K tomu zbytku: ano, teoreticky to už z principu nemůže rozumně fungovat a je pošetilé se o něco snažit. V praxi s tím většina projektů žádný problém nemá a ne že by nějaké větší problémy s řešením konfliktů občas nebyly, ale nedějí se ani zdaleka tak často, aby si z toho bylo potřeba dělat těžkou hlavu.
tím uzlem je dána celá historie až k němu.
…dokud někdo ten štítek nepřelepí někam jinam – pak se ta informace ztratí a nikdo už nedohledá, jak to tehdy bylo.
To ale není nedostatek nebo slabina návrhu gitu, ale právě jeho obrovská síla…
Proto třeba ten Mercurial podporuje oboje, můžeš si tam vybrat, jestli tvému scénáři víc vyhovuje bookmark (gitovská pseudo-větev) nebo branch (git je nemá).
Je to část grafu, ale vůbec to nemusí být - a velmi často není - lineární posloupnost.
Ano, dá se na to dívat jako na hromádku .diff souborů od různých lidí, kterými si volitelně opatchujeme původní zdrojáky. Ale verzovací systém do toho má vnášet nějaký řád a spolehlivost. Proto DVCS staví na hashovém stromu a to pořadí je tam natvrdo zadrátované, protože jednotlivé verze jsou identifikované pomocí hashe a ten v sobě zahrnuje jak data té verze, tak hash předchozího uzlu, na který se navazuje. Štítky pak ukazují na tyto hashe1 tzn. na přesně danou posloupnost změn.
Někdo sice používá agresivně git pull --rebase
a git push --force
, ale to podle mého patří maximálně tak do soukromých větví, které nesdílím2 s ostatními. Ale jednou zveřejněná historie by měla být posvátná, tesaná do kamene – a pak je to striktně daná posloupnost změn. Pokud by se jejich pořadí mělo měnit nebo by z toho některá změna měla vypadnout nebo se doprostřed vsunout jiná, tak by z toho byl úplně jiný produkt, za který nikdo z těch autorů nemůže ručit a neplatí o tom původní předpoklady a tvrzení, které platily o té původní posloupnosti3 – je potřeba to celé znovu otestovat – do té doby je to neidentifikovatelná hromada kódu s nedefinovaným chováním, zcela bez záruky.
K tomu zbytku: ano, teoreticky to už z principu nemůže rozumně fungovat a je pošetilé se o něco snažit. V praxi s tím většina projektů žádný problém nemá a ne že by nějaké větší problémy s řešením konfliktů občas nebyly, ale nedějí se ani zdaleka tak často, aby si z toho bylo potřeba dělat těžkou hlavu.
Tohle je dost subjektivní a takovou zkušenost nelze moc zobecňovat. Zažil jsem oboje – jak projekty, kde šlo o víceméně nezávislé patche, které by šlo aplikovat v libovolném pořadí, a kde se lidi vzájemně moc nepotkávali a jen sem tam přidali někam kus kódu, tak i projekty, kde se hodně refaktorovalo, vylepšovaly se i starší části kódu, místo pouhého přidávání nových a lidé běžně měnili i cizí kód.
[1] mimochodem v Mercurialu je i přidávání a odebírání štítků verzované, takže víme kdy a kdo štítek přidal – což souvisí s tím prvním odstavcem: dohledatelnost – např. když u zákazníka najdeme nasazenou verzi v4.5.6, tak jsme schopní zjistit, kam v té době (ne jen dnes!) ten štítek ukazoval a zda s ním někdo nemanipuloval nebo zda ukazuje pořád na ten stejný hash
[2] nebo je sdílím jen pro náhled, třeba při revizi a ostatní počítají s tím, že se jim to bude měnit pod rukama
[3] např. tvrzení, že tenhle hash/štítek opravuje nějakou chybu nebo přidává určitou funkci
Proto třeba ten Mercurial podporuje oboje, můžeš si tam vybrat, jestli tvému scénáři víc vyhovuje bookmark (gitovská pseudo-větev) nebo branch (git je nemá).Jak jsem psal výše, v gitu jsou od tohohle merge commity, pokud to tak na projektu chceš. Já právě nevidim, v čem je v hg na výběr víc než v gitu, přijde mi, že není. Samozřejmě když děláš rebasing a striktně lineární historii, tak tu informaci nemáš, ale tam to ani moc nedává smysl IMO. A koneckonců AFAIK to samé platí o stejném workflow v Mercurial (dříve MQs, dnes
histedit
a graft
)
Proto DVCS staví na hashovém stromu a to pořadí je tam natvrdo zadrátovanéMůj dojem z Mercirualu je, že se furt taknějak snaží proti tomu Merkle tree bojovat a tak trochu emulovat - asi za účelem uživatelské přívětivosti - něco jako SVN.
Obávám se, že si pořád nerozumíme. Já se nebavil o nějakém přepisování historie nebo vkládání do historie. Upozorňoval jsem, že větev není (obecně) lineární posloupnost commitů, protože jakmile uděláte jeden merge, který není fast forward, tak lineární být přestane. Častou chybou je právě to, že lidé si představují pod pojmem větev jen tu jednu posloupnost commitů a přimergeované větve do ní nepočítají. To je ale chyba, protože ve filosofii gitu je větev celá ta historie, ne jen ta "hlavní linie". To, že si git eviduje, který předek merge commitu je první (a i pořadí ostatních u "octopus merges") je jen technická záležitost a spíš bych řekl, že je to hlavně kvůli jednoznačnosti hashe toho merge commitu.
On ten vztah může být podstatně složitější, běžně se třeba stává, že když má někdo připravenou větev, ve které dlouho na něčem pracoval, takže očekává konflikty, tak nejdřív udělá merge master
do té své a pak se teprve udělá merge jeho větve do master
, který pak už může být jen triviální fast forward. Rozdíl oproti tomu, kdyby se udělal merge rovnou ve "správném směru" je právě jen v tom pořadí předků merge commitu, z praktického hlediska dostanete úplně totéž.
Rebase nebo jiná manipulace s historií u veřejné neexperimentální větve je samozřejmě bad practice a u slušně vedeného projektu by se to mělo dít jen zcela výjimečně za účelem odstranění katastrofální chyby maintainera. Lokálně při vývoji nebo experimentech je to naopak velice užitečný nástroj, takže je dobře, že mi git nehází klacky pod nohy.
Obávám se, že si pořád nerozumíme. Já se nebavil o nějakém přepisování historie nebo vkládání do historie.
OK
Upozorňoval jsem, že větev není (obecně) lineární posloupnost commitů, protože jakmile uděláte jeden merge, který není fast forward, tak lineární být přestane.
Já to beru tak, že ten kdo dělá merge je programátor (ne jen nějaký úředník nebo údržbář, jak to někteří chápou) a vytváří nový commit úplně stejně tak, jako ti, kdo třeba opravovali chyby nebo přidávali nějakou funkcionalitu. Vytváří tedy nový stav (verzi) opět označený hashem a může o této verzi třeba tvrdit, že opravuje nějaké chyby a přidává nějaké funkce a nese za tato tvrzení odpovědnost (autoři původních patchů nemůžou ručit za to, že ty patche budou fungovat po provedení merge s nějakým, v té době, neznámým kódem). Merge je tedy commit stejně jako kterýkoli jiný – může vnášet do softwaru chyby, opravovat je, měnit funkcionalitu.
Častou chybou je právě to, že lidé si představují pod pojmem větev jen tu jednu posloupnost commitů a přimergeované větve do ní nepočítají.
Když si do své větve dotáhnu (opět přes merge) změny z hlavní větve, tak za ně přebírám odpovědnost a musím si znovu přetestovat ty svoje části – protože by klidně mohly začít fungovat jinak (i kdyby merge prošel hladce a program šel zkompilovat).
To je ale chyba, protože ve filosofii gitu je větev celá ta historie, ne jen ta "hlavní linie".
Souhlasím, že tohle lineární posloupností nazývat nelze.
Bral jsem to z toho praktického pohledu – když začleňuji větev někoho jiného, tak mne primárně zajímá ta část, kterou se liší od našeho společného předka (a jestli měl v téhle části nějaké svoje odbočky a merge, to je mi celkem jedno, jde o ten výsledek). To „lineární“ vs. „nelineární“ v této diskusi jsem chápal jako rozdíl mezi jednoznačně zapsanými vazbami mezi uzly v hashovém stromu vs. různé divoké rebase operace a aplikování jednotlivých patchů na jiné části stromu, než zamýšleli jejich autoři. Ale to už se vysvětlilo.
Rebase nebo jiná manipulace s historií u veřejné neexperimentální větve je samozřejmě bad practice a u slušně vedeného projektu by se to mělo dít jen zcela výjimečně za účelem odstranění katastrofální chyby maintainera. Lokálně při vývoji nebo experimentech je to naopak velice užitečný nástroj, takže je dobře, že mi git nehází klacky pod nohy.
Souhlas. (jen poznámka: nepublikovaná historie se dá hezky editovat i v tom Mercurialu případně dalších systémech; a kdyby v nejhorším případě bylo potřeba zasáhnout do té publikované historie, tak jde násilně přepsat historii i na společném úložišti nebo tam část toho stromu odmazat pomocí hg strip
)
Tu nelinearitu historie jsem zdůrazňoval právě proto, že i z vlastní zkušenosti vím, že není úplně jednoduché si na to zvyknout. Většina lidí má ze začátku tendenci udržovat historii pokud možno lineární (k tomu trochu napomáhá např. Github tím, že prezentuje "rebase merge" a dokonce i "squash merge" jako rovnocenné alternativy ke klasickému merge) a i když se od toho oprostí, pořád se drží představy, že je "hlavní" a "vedlejší" větev a merge je zásadně vedlejší do hlavní.
Mimochodem, před chvílí jsem se úplnou náhodou dozvěděl (z oznámení, že tato featura odteď funguje na kernel.org), že git umožňuje (pokud pro to existuje podpora na serveru) také signed push, což by možná mohla být částečná odpověď na tu otázku auditovatelnosti historie větve. Ještě jsem to nezkoušel, ale mělo by jít o to, že když podepíšu commit, tak tím jen říkám, že tenhle stav spolu s historií, která k němu vedla, pochází ode mne, ale už to neříká nic o tom, kam jsem ho vlastně pushnul a proč. Signed push by měl nést i informaci o tom, kam jsem ten push dělal, tj. že např. šlo o push do nějaké experimentální vývojové větve a ne někam, kde by to mohlo být chápáno jako pull request.
[1] mimochodem v Mercurial je i přidávání a odebírání štítků verzované, takže víme kdy a kdo štítek přidal – což souvisí s tím prvním odstavcem: dohledatelnost – např. když u zákazníka najdeme nasazenou verzi v4.5.6, tak jsme schopní zjistit, kam v té době (ne jen dnes!) ten štítek ukazoval a zda s ním někdo nemanipuloval nebo zda ukazuje pořád na ten stejný hashJak se to lisi od informace, kdyz najdu u zakaznika nasazenej hash GGGGGG? My delame verze YYMM-CCC-GGGGGG, kde GGGGGG je git hash tagu YYMM-CCC (C je counter). Hash v cisle verze je mnohem robustnejsi, protoze historii Mercurialu muzu podvrhnout, pokud budu chtit podvrhnout verzi s hashem, budu muset najit kolizi.
Jen je potřeba překonat myšlenkový blok, že větev má být lineární posloupnost commitů. Pak v tom, že dva lidé do větve nezávisle přidají každý něco jiného, přestanete vidět problém.Ale tak jasně, v tom problém nevidim, merge a rebase používám na denní bázi. A to někdy i celkem divoké. Ono to funguje, ale nemůžu se zbavit dojmu, že by to mělo vyžadovat méně manuální práce.
Jen je potřeba překonat myšlenkový blok, že větev má být lineární posloupnost commitů. Pak v tom, že dva lidé do větve nezávisle přidají každý něco jiného, přestanete vidět problém.Dokud se neco nevysere a nebudete muset delat bisect. Pokud mate linearni historii, tak bisect najde konkretni commit, kdezto u merge se muze zastavit u merge commitu a pak to musite stejne rebasenout a testovat znova.
se zeptam, jaka je historie vetve V. A odpovedi mi bude nejaky seznam commitu, pro ktery bych ocekval, ze bude platit alespon, ze muzu dostat z ruznych nodu napr. a->b->c, nebo jen a->b, ale nikdy ne a->b->x. K tomu ma git fakt dalekoTodle to je dost blbej priklad, protoze nic jako historie vetve V v gitu neexistuje. Pokud se ale podivate na historii commitu C, tak ta bude ve vsech instancich repositare stejna.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.