Nyní je stejný „obrovský“ soubor umístěn v obou vývojářských větvích na serveru. Nevytvoří pevný odkaz automaticky
Ve skutečnosti s Git 2.20 může tento problém zmizet kvůli ostrovům delta , nový způsob výpočtu delta tak, aby z objektu, který existuje v jedné větvi, nevznikla delta proti jinému objektu, který se nevyskytuje ve stejném rozvětveném úložišti .
Viz commit fe0ac2f, commit 108f530, commit f64ba53 (16. srpna 2018) od Christiana Coudera (chriscool
).
Pomáhal:Jeff King (peff
) a Duy Nguyen (pclouds
).
Viz commit 9eb0986, commit 16d75fa, commit 28b8a73, commit c8d521f (16. srpna 2018) od Jeffa Kinga (peff
).
Pomoci:Jeff King (peff
) a Duy Nguyen (pclouds
).
Přidat
delta-islands.{c,h}
Poskytovatelé hostingu, kteří uživatelům umožňují „forkovat“ existující úložiště, chtějí, aby tyto forky sdílely co nejvíce místa na disku.
Alternativy jsou existujícím řešením, jak uchovávat všechny objekty ze všech forků do jedinečného centrálního úložiště, ale to může mít určité nevýhody.
Zejména při balení centrálního úložiště se mezi objekty z různých forků vytvoří delty.Díky tomu může být klonování nebo načítání větvení mnohem pomalejší a mnohem náročnější na CPU, protože Git možná bude muset počítat nové delty pro mnoho objektů, aby se vyhnul odesílání objektů z jiné větve.
Protože k neefektivitě dochází primárně, když je objekt deltifikovaný proti jinému objektu, který neexistuje ve stejné větvi, rozdělujeme objekty do sad, které se objevují na stejné větvi, a definujeme „ostrovy delta“.
Při hledání základny delty nedovolíme, aby byl za základnu považován objekt mimo stejný ostrov.Takže „ostrovy delta“ představují způsob, jak ukládat objekty z různých fork do stejného úložiště a souboru balíčku, aniž by mezi objekty z různých fork byly rozdíly.
Tento patch implementuje mechanismus delta ostrovů v "
delta-islands.{c,h}
“, ale zatím jej nevyužívá.V '
struct object_entry
je přidáno několik nových polí “ v „pack-objects.h
“ ačkoli.
Viz Documentation/git-pack-objects.txt
:Delta Island:
DELTA OSTROVY
Pokud je to možné,
pack-objects
se snaží znovu použít existující delty na disku, aby nemuseli za chodu hledat nové. Toto je důležitá optimalizace pro obsluhu načítání, protože to znamená, že server se může vyhnout nafouknutí většiny objektů a pouze odeslat bajty přímo z disku.Tato optimalizace nemůže fungovat, když je objekt uložen jako delta vůči základně, kterou přijímač nemá (a kterou již neposíláme). V takovém případě server „rozbije“ deltu a musí najít novou, což má vysoké náklady na CPU. Proto je pro výkon důležité, aby sada objektů v delta vztazích na disku odpovídala tomu, co by klient načetl.
V normálním úložišti to obvykle funguje automaticky.
Objekty jsou většinou dosažitelné z poboček a značek, a to klienti získávají. Jakékoli delty, které najdeme na serveru, budou pravděpodobně mezi objekty, které klient má nebo bude mít.Ale v některých nastaveních úložiště můžete mít několik souvisejících, ale samostatných skupin referenčních tipů, přičemž klienti mají tendenci získávat tyto skupiny nezávisle.
Představte si například, že hostujete několik „forků“ úložiště v jediném úložišti sdílených objektů a umožňujete klientům, aby si je prohlíželi jako samostatné úložiště prostřednictvím GIT_NAMESPACE nebo jako samostatné úložiště pomocí mechanismu alternativ.
Naivní přebalení může zjistit, že optimální delta pro objekt je proti základně, která se nachází pouze v jiné vidlici.
Ale když klient načte, nebude mít základní objekt a my budeme muset za běhu najít novou deltu.Podobná situace může nastat, pokud máte mnoho odkazů mimo
refs/heads/
arefs/tags/
které ukazují na související objekty (např.refs/pull
neborefs/changes
používané některými poskytovateli hostingu). Ve výchozím nastavení klienti načítají pouze hlavy a značky a delty proti objektům nalezeným pouze v těchto jiných skupinách nelze odeslat tak, jak jsou.Delta ostrovy řeší tento problém tím, že vám umožňují seskupit vaše reference do samostatných „ostrovů“ .
Pack-objects vypočítá, které objekty jsou dosažitelné z jakých ostrovů, a odmítne vytvořit deltu z objektu
A
proti základu, který není přítomen ve všechA
's ostrovy. To má za následek o něco větší balíky (protože promeškáme některé možnosti delta), ale zaručuje to, že načtení jednoho ostrova nebude muset přepočítávat delty za běhu kvůli překročení hranic ostrovů.
Vedlejší efekt však:některé příkazy byly podrobnější. Git 2.23 (3. čtvrtletí 2019) to opravuje.
Viz commit bdbdf42 (20. června 2019) od Jeffa Kinga (peff
).
delta-islands
:respektujteprogress
vlajkaDelta ostrovní kód vždy vypíše "
Marked %d islands
", i když byl postup potlačen pomocí--no-progress
nebo odesláním stderr toa non-tty.Předáme
progress
boolean naload_delta_islands()
.
Totéž již děláme pro měřič průběhu vresolve_tree_islands()
.
Rozhodl jsem se udělat toto:
shared-objects-database.git/
foo.git/
objects/info/alternate (will have ../../shared-objects-database.git/objects)
bar.git/
objects/info/alternate (will have ../../shared-objects-database.git/objects)
baz.git/
objects/info/alternate (will have ../../shared-objects-database.git/objects)
Všechny větve budou mít ve svém souboru objects/info/alternates položku, která poskytuje relativní cestu k úložišti databáze objektů.
Je důležité vytvořit z databáze objektů úložiště, protože můžeme ukládat objekty a odkazy různých uživatelů, kteří mají úložiště stejného jména.
Kroky:
git init --bare shared-object-database.git
-
Následující řádky kódu spouštím buď pokaždé, když dojde k odeslání do libovolného forku (prostřednictvím post-recieve), nebo spuštěním cronjob
for r in list-of-forks do
(cd "$r" &&git push ../shared-objects-database.git "refs/:refs/remotes/$r/ " &&echo ../../shared-objects-database.git/objects>objects/info/alternates# pro uložení Přidám "tlusté" objekty do alternativ pokaždé) hotovo
Potom v dalším "git gc" budou všechny objekty ve forku, které již existují v alternativní, odstraněny.
git repack -adl
je také možnost!
Tímto způsobem ušetříme místo, takže dva uživatelé, kteří na svých příslušných rozvětvení na serveru vloží stejná data, budou sdílet objekty.
Musíme nastavit gc.pruneExpire
proměnná až do never
v databázi sdílených objektů. Jen pro jistotu!
Chcete-li občas ořezat objekty, přidejte všechny vidlice jako vzdálené do sdílené, načítat a ořezávat! Git udělá zbytek!
(Konečně jsem našel řešení, které mi vyhovuje! (Netestováno ve výrobě! :p Díky tomuto příspěvku.)