{"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\/da\/blog\/news\/mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git","title":{"rendered":"mergiraf \u2014 AST-orienteret v\u00e6rkt\u00f8j til tredobbelt sammenfletning i Git","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Udgivelsen af projektet mergiraf 0.4, der udvikler en driver til Git med implementeringen af muligheden for tredobbelt sammensmeltning, er offentliggjort. Mergiraf underst\u00f8tter l\u00f8sning af forskellige former for konflikter ved sammenfletning og kan anvendes til forskellige programmeringssprog og filformater. Det er muligt b\u00e5de at kalde mergiraf separat for at h\u00e5ndtere konflikter, der opst\u00e5r ved brug af standard Git, samt at erstatte Git's sammenfletningsbehandler for at udvide funktionerne i kommandoer som merge, revert, rebase og cherry-pick. Koden distribueres under GPLv3-licensen. I den nye version er der tilf\u00f8jet underst\u00f8ttelse af spr\u00e5kene Python, TOML, Scala og Typescript, samt optimering af ydeevnen.    <\/p>\n<p>Nedenfor er en detaljeret beskrivelse af de problemer, der l\u00f8ses ved hj\u00e6lp af mergiraf:    <\/p>\n<p>Software is a vivid example of an extremely complex system. Complex systems share one common property \u2014 they are COMPLEX \u2014 and you cannot expect the desired complex behavior to emerge on its own by chance. Instead, these systems evolve over time, step by step, with each mutation being carefully checked 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', representing a specific set of functions and anti-functions. Any change to this set is considered a mutation, forming an edge in our directed acyclic graph. These functions are inherently abstract; they do not directly reflect how physical systems operate, but rather demonstrate how intelligent agents perceive the utility of these systems. To translate ideas into real-world implementations, one must roll up their sleeves and dive into *sufficiently* low-level details, in a language that can express and explain exactly how everything works. In software development, these low-level details are typically represented by source code.    <\/p>\n<p>For gradually bringing the source code to a state that exhibits the required behavior and documenting how they achieved it, programmers represent their work in terms of snapshots and changesets. A snapshot represents a specific state of the product with all low-level details, while a changeset signifies the transition between snapshots. Typically, snapshots are generated from individual changesets to their parents, which is why these snapshots almost always mark what the changesets that created them do, making these terms frequently interchangeable.     <\/p>\n<p>Sometimes there are snapshots created as a result of several transitions \u2014 merging commits. These are difficult to work with, so they are usually avoided. Modern open-source version control systems, such as 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>Denne funktion g\u00f8r det muligt for udviklere at skrive en semantisk betydningsfuld historie om projektet, hvilket er afg\u00f8rende for fejlfinding og svar p\u00e5 sp\u00f8rgsm\u00e5l som \"Hvorfor blev denne lavniveau detalje (f.eks. variabel) introduceret?\", \"Hvor stor en procentdel af projektet er min omtrentlige bidrag?\", \"Hvorn\u00e5r blev der indsat en bagd\u00f8r, og hvem gjorde det?\", \"Hvilken lavniveau \u00e6ndring br\u00f8d denne funktion (selvom det ikke burde have v\u00e6ret muligt, vi har tjekket alt!?)\".    <\/p>\n<p>Versionskontrolsystemer supplerer dette med konceptet gren \u2014 et lavniveau begreb, der blot betyder et kontinuerligt fragment af projektets lavniveau historie, som er semantisk betydningsfuld for udvikleren. Grene bruges typisk til specifik implementering af funktioner, og der oprettes undertiden flere grene til forskellige kandidater til implementeringen af den samme funktion. Ved at bruge arbejdsgange med grene (som faktisk er mainstream og standard inden for udvikling, anvendes overalt), kan hver enkelt udvikler effektivt h\u00e5ndtere mange konfliktende grene af projektet, hvor hver skiller sig ud med hensyn til beredskab eller kvalitet. Dette g\u00f8r det muligt for udviklere at kombinere resultaterne af deres egne og andres arbejde uden at skulle genkode alt manuelt hver gang.     <\/p>\n<p>Der laves normalt en hovedgren, der repr\u00e6senterer det \"officielle\" produkt, fra hvilken sidegrene for hver funktion forgrenes, som regelm\u00e6ssigt (ideelt set \u2014 efter hver commit) synkroniseres med hovedgrenen, hvilket g\u00f8r det muligt for udviklere at arbejde med den nyeste version af produktet og samtidig implementere funktioner, de i \u00f8jeblikket udvikler, ved at opdage problemer, der opst\u00e5r som f\u00f8lge af andres handlinger s\u00e5 tidligt som muligt.    <\/p>\n<p>N\u00e5r man fors\u00f8ger at kombinere funktioner fra forskellige snapshots (som blot er at finde en f\u00e6lles forfader og anvende de \u00e6ndringss\u00e6t, der genereres, sekventielt oven p\u00e5 den anden, kaldes denne operation rebase, mens merge n\u00e6rmest er som rebase, men strukturerer commit-grafen p\u00e5 en anden m\u00e5de, hvilket g\u00f8r det vanskeligt at manipulere med dem, derfor fors\u00f8ger man at undg\u00e5 merges til fordel for rebases) opst\u00e5r der problemer. Moderne versionskontrolsystemer (VCS) bruger interne algoritmer til at kombinere \u00e6ndringer, som simpelthen opdeler filer i individuelle linjer, betragter hver linje som et tegn og filer som deres sekvenser, og anvender derefter algoritmer til at kombinere dem, som stammer fra bioinformatik.     <\/p>\n<p>Desv\u00e6rre har s\u00e5danne linje-for-linje repr\u00e6sentationer af kildekoden intet at g\u00f8re med dens indhold. Den eneste fordel ved det er, at det er simpelt og universelt. Uoverensstemmelser f\u00f8rer til konflikter og er en konstant kilde til hovedpine for udviklere. At l\u00f8se konflikter kr\u00e6ver, at udvikleren n\u00f8je unders\u00f8ger begge versioner af koden, ikke kun de sektioner, der er markeret som '\u00e6ndrede' eller 'konflikterende' af den linje-for-linje sammenligningsalgoritme, men m\u00e5ske ogs\u00e5 hele projektet.     <\/p>\n<p>Udvikleren skal forst\u00e5 \u00e6ndringerne, manuelt skrive en sammenflettet kode og afhj\u00e6lpe eventuelle uoverensstemmelser. Problemerne for\u00f8ges, n\u00e5r linjev\u00e6rkt\u00f8jet forkert identificerer \u00e6ndringer, hvilket ofte sker ved store \u00e6ndringer, inklusive trivielle s\u00e5som omformatering af koden. Hvis efterf\u00f8lgende \u00e6ndringer ikke kan anvendes p\u00e5 den manuelt sammenflettede kode, bliver situationen en komplet mareridt. P\u00e5 trods af skr\u00e6mmende tilf\u00e6lde fungerer linje-algoritmen i de fleste tilf\u00e6lde, is\u00e6r hvis udviklerne aktivt fors\u00f8ger ikke at skabe problemer for den. En m\u00e5de at minimere s\u00e5danne problemer p\u00e5 er at stille krav om behandling af kilder med kanoniseringsv\u00e6rkt\u00f8jer som black.    <\/p>\n<p>Selvf\u00f8lgelig er den rette l\u00f8sning p\u00e5 skr\u00e6mmende tilf\u00e6lde (og ikke kun dem, linje-for-linje algoritmen \u2014 det er en heuristik, der p\u00e5 trivial m\u00e5de kan f\u00f8re til brugerkode, for eksempel hvis en udvikler omd\u00f8ber en variabel, mens en anden skriver et stykke ny kode, der bruger den variabel, der vil ikke v\u00e6re nogen sammenfletnings- \/rebasekonflikt, men resultatet vil blive ikke-funktionelt) \u2014 det er at anvende den rigtige interne model.     <\/p>\n<p>P\u00e5 trods af at forskningen p\u00e5 dette omr\u00e5de har v\u00e6ret i gang i n\u00e6sten 30 \u00e5r og har f\u00f8rt til udviklingen af flere propriet\u00e6re kommercielle produkter, var denne forskning indtil for nylig ikke blevet omsat til praktisk anvendelige produkter med \u00e5bent kildekode. St\u00f8rstedelen af open-source l\u00f8sninger begyndte at udvikle sig i begyndelsen af 2010'erne og var prim\u00e6rt fokuseret p\u00e5 Java.    <\/p>\n<p>Den mest fremtr\u00e6dende frie implementering fra denne periode, GumTree, blev skabt af en forsker med en akademisk baggrund. Den er skrevet i Java, har sin egen abstrakte interne repr\u00e6sentation, der g\u00e5r forud for treesitter, og har backend-l\u00f8sninger, b\u00e5de baseret p\u00e5 treesitter og andre v\u00e6rkt\u00f8jer til at parse kildekode til abstrakte repr\u00e6sentationer. Dette system kan kun generere (i form af tekstlogfiler over begivenheder, og der er ogs\u00e5 en API, der kan kaldes trivielt fra ethvert programmeringssprog, der har bindings til Java) og visualisere \u00e6ndringer. Dog er det ikke anvendeligt til at sammenflette \u00e6ndringer, ligesom det ikke kan bruges til at se de genererede diff-filer ud af boksen (det er dog sandsynligt, at upload af diffs kan implementeres via API'en).    <\/p>\n<p>En nyere og mere praktisk implementering af difftastic er skrevet i Rust, er baseret p\u00e5 treesitter og fokuserer p\u00e5 at generere fremh\u00e6vede diffs i konsollen. Dette system er ogs\u00e5 rettet mod visualisering af diffs og sigter overhovedet ikke mod at sammenflette \u00e6ndringer eller anvende patches.    <\/p>\n<p>For nylig er projektet mergiraf dukket op og er under aktiv udvikling. Dette v\u00e6rkt\u00f8j, der er skrevet i Rust (optager 21 MiB!), er ogs\u00e5 baseret p\u00e5 treesitter, som allerede er blevet en standard for parsere af kontekstfrie grammatikker i udviklingsv\u00e6rkt\u00f8jer, ligesom LLVM er for optimering af lavniveau repr\u00e6sentationer af instruktioner. I mods\u00e6tning til konkurrenterne giver mergiraf funktioner ikke til at generere diffs, men til automatisk at l\u00f8se sammenfletningskonflikter. Under h\u00e6tten bruger mergiraf til generering af patches implementeringen af algoritmen, der anvendes i GumTree, og til anvendelse \u2014 implementeringen af algoritmen, der anvendes i spork, tilpasset til strukturer af treesitter.     <\/p>\n<p>Desv\u00e6rre er serialisering af patches til filer, der senere kan anvendes, ikke implementeret (men det er sandsynligt, at det kan implementeres ved at parse de eventlogs, der genereres af GumTree). En anden lovende metode til anvendelse af forskellene kan v\u00e6re at anvende forskellene ikke gennem patches, men gennem refaktoriseringens funktionalitet fra LSP-servere, hvilket kan hj\u00e6lpe med at opdage konflikter p\u00e5 projektets overordnede niveau. Visualisering underst\u00f8ttes kun for konflikter.    <\/p>\n<p>Eksempel p\u00e5 arbejde:  f\u00e6lles forfader \u00abbase.py\u00bb (indrykning med tabulatorer, ekstra linje i starten) foo = 1 def main(): print(foo + 2 + 3) \u00aba.py\u00bb (indrykning forts\u00e6tter med tabulatorer, 2 ekstra linjer i starten i stedet for \u00e9n, til fejls\u00f8gning anvendes biblioteket icecream, klassen \u00abbaz\u00bb tilf\u00f8jes: from icecream import ic foo = 1 def main(): ic(foo + 2 + 3) class baz: def __init__(self): \u00ab\u00bbbaz\u00ab\u00bb \u00ab\u00ab\u00ab \u00abb.py\u00bb (variabel \u00abfoo\u00bb er omd\u00f8bt til \u00abbar\u00bb, behandlet med \u00abblack\u00bb efter \u00e6ndringer, s\u00e5 indrykningerne \u2014 er med mellemrum og ekstra linjer sk\u00e5ret v\u00e6k): bar = 1 def main(): print(bar + 2 + 3) Kald . \/mergiraf merge . \/base.py . \/a.py . \/b.py -x a.py -y b.py -s base.py -o . \/res.py giver f\u00f8lgende resultat from icecream import ic bar = 1 def main(): ic(bar + 2 + 3) class baz: def __init__(self): \u00ab\u00bbbaz\u00ab\u00bb \u00ab\u00ab\u00ab (til fejls\u00f8gning anvendes biblioteket \u00abicecream\u00bb, variabel \u00abfoo\u00bb er omd\u00f8bt til \u00abbar\u00bb, behandlet med \u00abblack\u00bb efter \u00e6ndringer, s\u00e5 indrykningerne \u2014 er med mellemrum og ekstra linjer sk\u00e5ret v\u00e6k, blanding af tabulatorer og mellemrum til indrykning, men en tilladt form).    <\/p>\n<p>Her ses manglen ved v\u00e6rkt\u00f8jet. Dokumentets stil konfigureres normalt i filerne &#171;.editorconfig&#187;, og globale \u00e6ndringer i stilen, s\u00e5som at skifte fra tabulatorer til mellemrum og vedtage black-stilen, som det blev gjort i &#171;b.py&#187;, ledsages typisk af \u00e6ndringer i &#171;.editorconfig&#187;. Derfor b\u00f8r v\u00e6rkt\u00f8jet have et koncept for global stil &#171;som standard&#187; for mere korrekt anvendelse af s\u00e5danne \u00e6ndringer og v\u00e6re i stand til at hente indstillinger fra &#171;.editorconfig&#187;.<br \/>\n<br \/>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/www.opennet.ru\/opennews\/art.shtml?num=62402\">opennet.ru<\/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.3 - 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\/da\/blog\/news\/mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\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\/da\/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 AST-orienteret v\u00e6rkt\u00f8j til tredobbelt sammensmeltning i Git | ProHoster","description":"Udgivelsen af projektet mergiraf 0.4 er offentliggjort, som udvikler en driver til Git med implementeringen af tredobbelt sammensmeltning.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/news\/mergiraf-ast-orientirovannyj-instrument-dlya-tryohstoronnego-sliyaniya-v-git","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","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\/da\/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\/da\/wp-json\/wp\/v2\/posts\/120981","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=120981"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/120981\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=120981"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=120981"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=120981"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}