{"id":120981,"date":"2024-12-14T09:45:59","date_gmt":"2024-12-14T07:45:59","guid":{"rendered":"https:\/\/prohoster.info\/blog\/novosti-interneta\/mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git"},"modified":"2024-12-14T09:45:59","modified_gmt":"2024-12-14T07:45:59","slug":"mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/news\/mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git","title":{"rendered":"mergiraf &#8212; un instrument orientat pe AST pentru unirea tripl\u0103 \u00een Git","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>A fost lansat\u0103 versiunea 0.4 a proiectului mergiraf, care dezvolt\u0103 un driver pentru Git cu implementarea posibilit\u0103\u021bii de fuziune \u00een trei direc\u021bii. Mergiraf suport\u0103 rezolvarea diferitelor tipuri de conflicte \u00een timpul fuziunii \u0219i poate fi utilizat pentru diverse limbaje de programare \u0219i formate de fi\u0219iere. Este posibil at\u00e2t un apel separat mergiraf pentru a gestiona conflictele ap\u0103rute \u00een timpul utiliz\u0103rii Git standard, c\u00e2t \u0219i \u00eenlocuirea \u00een Git a handler-ului de fuziune pentru a extinde func\u021bionalit\u0103\u021bile unor comenzi precum merge, revert, rebase \u0219i cherry-pick. Codul este distribuit sub licen\u021ba GPLv3. Noua versiune adaug\u0103 suport pentru limbaje precum Python, TOML, Scala \u0219i Typescript, precum \u0219i optimiz\u0103ri de performan\u021b\u0103.    <\/p>\n<p>Mai jos este o descriere detaliat\u0103 a problemelor rezolvate cu ajutorul mergiraf:    <\/p>\n<p>Software is a striking example of a highly complex system. Complex systems share one common property \u2014 they are COMPLEX \u2014 and you cannot expect the desired complex behavior to emerge spontaneously or by accident. Instead, these systems evolve over time, step by step, with each mutation being carefully verified at every stage. This requires a well-defined structure and appropriate tools. The evolution of any complex system can be visualized as a directed tree, where the root represents an empty set of functions, and each node \u2014 except for the root \u2014 is the result of applying a mutation to its parent.     <\/p>\n<p>In the context of products, each node is called a 'version', which represents a specific set of functionalities and anti-functionalities. Any change to this set is considered a mutation, forming an edge in our directed acyclic graph. These functionalities are inherently abstract; they do not directly reflect the ways physical systems operate, but rather show how rational agents perceive the utility of these systems. To convert ideas into real-world implementations, it is necessary to roll up your sleeves and dive into *sufficiently* low-level details, in a language that can express and explain how everything works specifically. In software development, these low-level details are typically represented by source code.    <\/p>\n<p>Pentru a aduce treptat codul surs\u0103 \u00eentr-o stare care manifest\u0103 comportamentul dorit \u0219i a documenta cum au ajuns acolo, programatorii \u00ee\u0219i prezint\u0103 munca \u00een termeni de snapshot-uri \u0219i changeset-uri. Un snapshot reprezint\u0103 o stare specific\u0103 a produsului cu toate detaliile sale de nivel inferior, \u00een timp ce un changeset denot\u0103 tranzi\u021bia \u00eentre snapshot-uri. De obicei, snapshot-urile sunt generate de changeset-uri unice c\u0103tre p\u0103rin\u021bii lor, astfel c\u0103 aceste snapshot-uri marcheaz\u0103 aproape \u00eentotdeauna ceea ce fac changeset-urile care le-au creat, motiv pentru care ace\u0219ti termeni sunt adesea folosi\u021bi interschimbabil.     <\/p>\n<p>Sometimes there are snapshots created as a result of several transitions \u2014 merging commits. They are challenging to work with, so they are usually avoided. Modern open-source version control systems like Git provide very basic capabilities for managing development workflows. They allow developers to organize snapshots as directed acyclic graphs, annotate them with comments, and change their order if necessary.     <\/p>\n<p>Aceast\u0103 func\u021bionalitate le permite dezvoltatorilor s\u0103 scrie o poveste semnificativ\u0103 din punct de vedere semantic a proiectului, ceea ce este esen\u021bial pentru depanare \u0219i pentru a r\u0103spunde la \u00eentreb\u0103ri precum \u201eDe ce a fost introdus acest detaliu de nivel inferior (de exemplu, o variabil\u0103)?\u201d, \u201eCe procent aproximativ reprezint\u0103 contribu\u021bia mea \u00een acest proiect?\u201d, \u201eCine a fost afectat de o implementare de backdoor \u0219i c\u00e2nd?\u201d, \u201eCe modificare de nivel inferior a stricat aceast\u0103 func\u021bie (de\u0219i nu ar fi trebuit s\u0103 se \u00eent\u00e2mple, am verificat totul!?)\u201d    <\/p>\n<p>Sistemele de control al versiunilor completeaz\u0103 acest concept prin no\u021biunea de ramur\u0103 \u2014 un concept de nivel inferior care se refer\u0103 pur \u0219i simplu la un segment continuu al istoriei de nivel inferior a proiectului, semnificativ din punct de vedere semantic pentru dezvoltadores. Ramurile sunt utilizate de obicei pentru implementarea specific\u0103 a func\u021biilor, uneori fiind create mai multe ramuri pentru diferi\u021bi candida\u021bi pentru implementarea acelea\u0219i func\u021bii. Utiliz\u00e2nd fluxuri de lucru cu ramificare (care sunt \u00een esen\u021b\u0103 mainstream \u0219i standard \u00een dezvoltare, folosite peste tot), fiecare dezvoltator individual poate gestiona eficient multe ramuri conflictuale ale proiectului, fiecare av\u00e2nd grade diferite de preg\u0103tire sau calitate. Aceasta le permite dezvoltatorilor s\u0103 combine rezultatele muncii lor \u0219i ale altora f\u0103r\u0103 a trebui s\u0103 re\u00eenc\u0103rca\u021bi totul manual de fiecare dat\u0103.     <\/p>\n<p>De obicei, se creeaz\u0103 o ramur\u0103 principal\u0103, care reprezint\u0103 produsul \u201eoficial\u201d, din care se ramific\u0103 ramuri laterale pentru fiecare func\u021bie, care sunt sincronizate periodic (\u00een ideal \u2014 dup\u0103 fiecare commit) cu ramura principal\u0103, permi\u021b\u00e2nd dezvoltatorilor s\u0103 lucreze cu cea mai recent\u0103 versiune a produsului \u0219i s\u0103 implementeze simultan func\u021biile pe care le dezvolt\u0103 \u00een acel moment, detect\u00e2nd problemele care apar din ac\u021biunile altor dezvoltatori c\u00e2t mai devreme posibil.    <\/p>\n<p>Atunci c\u00e2nd \u00eencerci s\u0103 combini func\u021biile diferitelor snapshot-uri (ceea ce este pur \u0219i simplu identificarea unui str\u0103mo\u0219 comun \u0219i aplicarea, \u00een mod secven\u021bial, a changeset-urilor care le genereaz\u0103, deasupra altora, aceast\u0103 opera\u021bie se nume\u0219te rebase; \u00een schimb, \u00eembinarea este aproape ca rebase, doar c\u0103 structureaz\u0103 graficul de commit-uri diferit, ceea ce face mai dificil\u0103 manipularea acestora, astfel c\u0103 se tinde s\u0103 se renun\u021be la \u00eembin\u0103ri \u00een favoarea rebase-urilor), apar probleme. Sistemele moderne de control al versiunilor (VCS) folosesc algoritmi interni de combinare a modific\u0103rilor, care \u00eempart pur \u0219i simplu fi\u0219ierele \u00een linii separate, trateaz\u0103 fiecare linie ca pe un simbol, iar fi\u0219ierele - ca pe secven\u021bele lor, aplic\u00e2nd apoi algoritmi pentru combinarea acestora, provenind din bioinformatic\u0103.     <\/p>\n<p>Din p\u0103cate, aceast\u0103 reprezentare pe linii a codului surs\u0103 nu are nimic de-a face cu con\u021binutul s\u0103u. Singura sa valoare este c\u0103 este simpl\u0103 \u0219i universal\u0103. Neconcordan\u021bele duc la conflicte, reprezent\u00e2nd o surs\u0103 constant\u0103 de dureri de cap pentru dezvoltatori. Rezolvarea conflictelor necesit\u0103 de la dezvoltator o examinare atent\u0103 a ambelor versiuni ale codului, nu doar a sec\u021biunilor marcate de algoritmul de comparare pe linii ca fiind \u201emodificate\u201d sau \u201econflictuale\u201d, ci, posibil, \u0219i a \u00eentregului proiect.     <\/p>\n<p>Dezvoltatorul trebuie s\u0103 \u00een\u021beleag\u0103 modific\u0103rile, s\u0103 scrie manual codul combinat \u0219i s\u0103 elimine orice neconcordan\u021be. Problema devine \u0219i mai mare atunci c\u00e2nd instrumentul pe linii identific\u0103 incorect modific\u0103rile, ceea ce se \u00eent\u00e2mpl\u0103 frecvent \u00een cazul modific\u0103rilor mari, inclusiv a celor triviale, cum ar fi reformat\u0103rile codului. Dac\u0103 modific\u0103rile ulterioare nu pot fi aplicate codului combinat manual, situa\u021bia se transform\u0103 \u00eentr-un co\u0219mar total. \u00cen ciuda cazurilor \u00eengrozitoare, \u00een majoritatea cazurilor, algoritmul pe linii func\u021bioneaz\u0103, mai ales dac\u0103 dezvoltatorii se str\u0103duiesc activ s\u0103 nu \u00eei creeze probleme. O metod\u0103 de minimizare a acestor probleme este cerin\u021ba obligatorie de a procesa sursele cu instrumente de canonizare, cum ar fi black.    <\/p>\n<p>Desigur, solu\u021bia corect\u0103 pentru cazurile teribile (\u0219i nu numai pentru ele, algoritmul pe linie - este o heuristic\u0103, poate duce \u00een mod trivial la un cod nefunc\u021bional, de exemplu, un dezvoltator a redenumit o variabil\u0103, iar altul a scris \u00eentre timp o bucat\u0103 de cod nou care folose\u0219te acea variabil\u0103; nu va avea loc un conflict de fuziune\/rebasing, dar rezultatul va deveni nefunc\u021bional) - este utilizarea unui model intern corect.     <\/p>\n<p>Cu toate c\u0103 cercet\u0103rile \u00een acest domeniu au loc de aproximativ 30 de ani \u0219i au dus la crearea mai multor produse comerciale proprietare, aceste cercet\u0103ri nu au fost transformate, p\u00e2n\u0103 de cur\u00e2nd, \u00een produse practic aplicabile cu surs\u0103 deschis\u0103. Majoritatea solu\u021biilor software cu surs\u0103 deschis\u0103 au \u00eenceput s\u0103 se dezvolte la \u00eenceputul anilor 2010 \u0219i au fost concentrate \u00een principal pe limbajul Java.    <\/p>\n<p>Cea mai proeminent\u0103 implementare gratuit\u0103 din acea perioad\u0103, GumTree, a fost creat\u0103 de un cercet\u0103tor cu un fundal academic, fiind scris\u0103 \u00een Java, av\u00e2nd o reprezentare intern\u0103 abstract\u0103, anterioar\u0103 lui treesitter, \u0219i oferind backend-uri at\u00e2t bazate pe treesitter, c\u00e2t \u0219i pe alte instrumente pentru parsarea codului surs\u0103 \u00een reprezent\u0103ri abstracte. Aceast\u0103 sistem\u0103 poate doar s\u0103 genereze (sub form\u0103 de jurnal de evenimente text, exist\u00e2nd \u0219i un API care poate fi apelat u\u0219or din orice limbaj de programare cu bindings pentru Java) \u0219i s\u0103 vizualizeze modific\u0103rile. Totu\u0219i, pentru fuzionarea modific\u0103rilor, precum \u0219i pentru vizualizarea fi\u0219ierelor diff generate de aceasta, nu este aplicabil\u0103 din cutie (de\u0219i este probabil ca \u00eenc\u0103rcarea fi\u0219ierelor diff s\u0103 poat\u0103 fi realizat\u0103 prin API).    <\/p>\n<p>O implementare mai t\u00e2n\u0103r\u0103 \u0219i mai aplicabil\u0103 \u00een practic\u0103 a difftastic este scris\u0103 \u00een Rust, bazat\u0103 pe treesitter, concentr\u00e2ndu-se pe generarea de diffs eviden\u021biate \u00een consol\u0103. Acest sistem este de asemenea orientat spre vizualizarea diffs \u0219i nu \u00ee\u0219i propune deloc s\u0103 fuzioneze modific\u0103rile sau s\u0103 aplice patch-uri.    <\/p>\n<p>Recent a ap\u0103rut \u0219i se dezvolt\u0103 activ proiectul mergiraf. Acest instrument, scris \u00een Rust (ocup\u0103 21 MiB!) este, de asemenea, bazat pe treesitter, care a devenit un standard pentru parserii gramaticilor independente de context \u00een instrumentele de dezvoltare, a\u0219a cum este LLVM pentru optimizarea reprezent\u0103rilor de instruc\u021biuni de nivel inferior. Spre deosebire de concuren\u021bi, mergiraf ofer\u0103 func\u021bii nu pentru generarea de dif-uri, ci pentru rezolvarea automat\u0103 a conflictelor de fuziune. Sub capot\u0103, mergiraf utilizeaz\u0103 pentru generarea patch-urilor o implementare a algoritmului utilizat \u00een GumTree, iar pentru aplicare - o implementare a algoritmului utilizat \u00een spork, adaptate pentru structurile treesitter.     <\/p>\n<p>Serializarea patch-urilor \u00een fi\u0219iere care pot fi aplicate mai t\u00e2rziu nu este implementat\u0103, din p\u0103cate (dar este foarte probabil ca aceasta s\u0103 poat\u0103 fi realizat\u0103 prin parsarea jurnalelor de evenimente generate de GumTree). O alt\u0103 modalitate promi\u021b\u0103toare de a aplica diferen\u021bele ar putea fi aplicarea diferen\u021belor nu prin patch-uri, ci prin func\u021bionalitatea de refactoring a serverelor LSP, ceea ce ar putea ajuta la detectarea conflictelor la nivelul \u00eentregului proiect. Vizualizarea este sus\u021binut\u0103 doar pentru conflicte.    <\/p>\n<p>Exemplu de func\u021bionare:  str\u0103mo\u0219 comun \u201ebase.py\u201d (indent\u0103ri cu tab-uri, linie suplimentar\u0103 la \u00eenceput) foo = 1 def main(): print(foo + 2 + 3) \u201ea.py\u201d (indent\u0103rile sunt \u00eenc\u0103 cu tab-uri, 2 linii suplimentare la \u00eenceput \u00een loc de una, pentru imprimarea de depanare este utilizat\u0103 biblioteca icecream, ad\u0103ugat clasa \u201ebaz\u201d: from icecream import ic foo = 1 def main(): ic(foo + 2 + 3) class baz: def __init__(self): \u201e\u201e\u201ebaz\u201d\u201e\u201e \u201eb.py\u201d (variabila \u201efoo\u201d a fost redenumit\u0103 \u00een \u201ebar\u201d, procesat\u0103 cu ajutorul \u201eblack\u201d dup\u0103 modific\u0103ri, ca rezultat, indent\u0103rile - cu spa\u021bii \u0219i liniile suplimentare eliminate): bar = 1 def main(): print(bar + 2 + 3)  Apel . \/mergiraf merge . \/base.py . \/a.py . \/b.py -x a.py -y b.py -s base.py -o . \/res.py produce urm\u0103torul rezultat from icecream import ic bar = 1 def main(): ic(bar + 2 + 3) class baz: def __init__(self): \u201e\u201e\u201ebaz\u201d\u201e\u201e (pentru imprimarea de depanare este utilizat\u0103 biblioteca \u201eicecream\u201d, variabila \u201efoo\u201d a fost redenumit\u0103 \u00een \u201ebar\u201d, procesat\u0103 cu ajutorul \u201eblack\u201d dup\u0103 modific\u0103ri, ca rezultat, indent\u0103rile - cu spa\u021bii \u0219i liniile suplimentare eliminate, amestec de tab-uri \u0219i spa\u021bii pentru indentare, dar aspectul permis).    <\/p>\n<p>Aici se vede clar o deficien\u021b\u0103 a instrumentului. Stilul documentului este de obicei configurat \u00een fi\u0219ierele &#171;.editorconfig&#187;, iar modific\u0103rile globale de stil, cum ar fi \u00eenlocuirea tabulatorilor cu spa\u021bii \u0219i adoptarea stilului black, a\u0219a cum s-a f\u0103cut \u00een &#171;b.py&#187;, sunt de obicei \u00eenso\u021bite de modific\u0103ri \u00een &#171;.editorconfig&#187;. Prin urmare, pentru a aplica mai corect astfel de modific\u0103ri, instrumentul ar trebui s\u0103 aib\u0103 o conceptie pentru stilul global &#171;implicit&#187; \u0219i s\u0103 fie capabil s\u0103 preia set\u0103rile din &#171;.editorconfig&#187;.<br \/>\n<br \/>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/www.opennet.ru\/opennews\/art.shtml?num=62402\">opennet.ro<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d \u0440\u0435\u043b\u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 mergiraf 0.4, \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0434\u043b\u044f Git \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u0440\u0451\u0445\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u044f. Mergiraf \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0432\u0438\u0434\u043e\u0432 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432 \u043f\u0440\u0438 \u0441\u043b\u0438\u044f\u043d\u0438\u0438 \u0438 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432 \u0444\u0430\u0439\u043b\u043e\u0432. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 mergiraf \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0445 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u043e \u0448\u0442\u0430\u0442\u043d\u044b\u043c Git, \u0442\u0430\u043a \u0438 \u0437\u0430\u043c\u0435\u043d\u0430 \u0432 Git \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0441\u043b\u0438\u044f\u043d\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[702],"tags":[],"class_list":["post-120981","post","type-post","status-publish","format-standard","hentry","category-news"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d \u0440\u0435\u043b\u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 mergiraf 0.4, \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0434\u043b\u044f Git \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u0440\u0451\u0445\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u044f.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/news\/mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47mergiraf \u2014 AST-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0442\u0440\u0451\u0445\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u044f \u0432 Git | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d \u0440\u0435\u043b\u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 mergiraf 0.4, \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0434\u043b\u044f Git \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u0440\u0451\u0445\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u044f.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/news\/mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2024-12-14T07:45:59+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2024-12-14T07:45:59+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47mergiraf \u2014 instrument orientat pe AST pentru fuziunea \u00een trei direc\u021bii \u00een Git | ProHoster","description":"A fost lansat\u0103 versiunea 0.4 a proiectului mergiraf, care dezvolt\u0103 un driver pentru Git cu implementarea func\u021bionalit\u0103\u021bii de fuziune \u00een trei direc\u021bii.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/news\/mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47mergiraf \u2014 AST-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0442\u0440\u0451\u0445\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u044f \u0432 Git | ProHoster","og:description":"\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d \u0440\u0435\u043b\u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 mergiraf 0.4, \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0434\u043b\u044f Git \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u0440\u0451\u0445\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u043b\u0438\u044f\u043d\u0438\u044f.","og:url":"https:\/\/prohoster.info\/ro\/blog\/news\/mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2024-12-14T07:45:59+00:00","article:modified_time":"2024-12-14T07:45:59+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"120981","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 08:54:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2026-01-23 08:54:19","updated":"2026-01-23 08:54:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/120981","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=120981"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/120981\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=120981"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=120981"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=120981"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}