Diff

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2022. március 14-én felülvizsgált verziótól ; az ellenőrzések 2 szerkesztést igényelnek .

A számítástechnikában a  diff egy fájl-összehasonlító segédprogram, amely megjeleníti a két fájl közötti különbséget. Ez a program soronként kiírja a fájlban végrehajtott módosításokat (szövegfájlok esetén). A modern megvalósítások a binárist is támogatják . A segédprogram kimenetét "diff"-nek, vagy gyakrabban patch -nek hívják, mert a javítóprogrammal együtt alkalmazható . Más fájl-összehasonlító segédprogramok kimenetét gyakran "diff"-nek is nevezik.

Történelem

A diff segédprogramot az 1970-es évek elején fejlesztették ki a Unix operációs rendszerhez , amely az AT&T Bell Labs munkája volt a New Jersey állambeli Murray Hillben. Az 1974-ben Unix 5-tel terjesztett végleges verziót teljes egészében Douglas McIlroy írta .

McIlroy munkáját Steve Johnson GECOS összehasonlító programja és Mike Lesk próbaprogramja előzte meg és befolyásolta. A Proof szintén a Unixból származik, és a diff-hez hasonlóan soronkénti változtatásokat hajtott végre, sőt szögletes zárójeleket (">" és "<") használt a programkimenetben a sorbeszúrások és -törlések ábrázolására. Az ezekben a korai alkalmazásokban használt heurisztikák azonban megbízhatatlannak bizonyultak. Az összehasonlító eszköz lehetséges hasznossága arra késztette McIlroyt, hogy kutasson és dolgozzon ki egy robusztusabb eszközt, amely számos feladatban használható, de jól működik a PDP-11 hardver feldolgozási és méretbeli korlátai között. A probléma megközelítése a Bell Labs munkatársaival, köztük Alfred Ahóval, Elliot Pinsonnal, Jeffrey Ullmannel és Harold S. Stone-nal való együttműködés eredménye volt.

Algoritmus

A diff működése a leghosszabb közös részsorozat ( LCS probléma) megtalálásán alapul .  Például két elemsorozat létezik:

abcdfghjqz abcdefgijkrxyz

és meg kell találnia az elemek leghosszabb sorozatát, amely mindkét sorozatban ugyanabban a sorrendben szerepel. Ez azt jelenti, hogy új szekvenciát kell találni, amelyet az első sorozatból egyes elemek törlésével, a második sorozatból pedig más elemek törlésével kaphatunk. Ebben az esetben a sorrend a következő lesz

abcdfgjz

A legnagyobb közös sorozat beszerzése után már csak egy kis lépés van hátra a diff-szerű kimenet elérése előtt:

ehikqrxy + - + + - + + +

Használat

A diff parancssorból meghívódik két fájl nevével argumentumként: diff original new . A parancs kimenete azok a módosítások, amelyeket az eredeti forrásfájlon kell végrehajtani, hogy az új fájl új legyen. Ha az eredeti és az új könyvtárak, akkor a diff automatikusan alkalmazásra kerül minden fájlra, amely mindkét könyvtárban létezik. A cikkben szereplő összes példa a következő két fájlt használja, az eredeti és az új fájlt :

eredeti:

A dokumentum ezen része változatlan maradt verzióról verzióra. Ha egy nincs változás benne nem szabad megjeleníteni. Különben nem segít az optimális következtetése előállított változtatások. Ez a bekezdés tartalmazza elavult szöveg. El lesz távolítva hamar. Ez a dokumentum lennie kell helyesírás-ellenőrzés. Másrészt a hiba egyszóval – nem a világ vége. A bekezdés többi része nem igényel változtatásokat. Új szöveg lehet add hozzá a dokumentum végéhez.

új:

Ez egy fontos megjegyzés! Ezért kellene található ennek elején dokumentum! A dokumentum ezen része változatlan maradt verzióról verzióra. Ha egy nincs változás benne nem szabad megjeleníteni. Különben nem segít az optimális következtetése az információ mennyisége. Ez a dokumentum lennie kell helyesírás-ellenőrzés. Másrészt a hiba egyszóval – nem a világ vége. A bekezdés többi része nem igényel változtatásokat. Új szöveg lehet add hozzá a dokumentum végéhez. Ez a bekezdés tartalmazza fontos kiegészítések ehhez a dokumentumhoz.

A diff eredeti új parancs a következő normál diff kimenetet hozza létre :

0a1.6 > Ez egy fontos megjegyzés! > Ezért kellene > elhelyezkedni > ennek elején > dokumentumot! > 8.14c14 < előállított mennyiség < változások. < < Ez a bekezdés tartalmazza < elavult szöveg. < Törölve lesz < a közeljövőben. --- > információ mennyisége. 17c17 < meg kell tenni --- > tenni kell 24a25.28 > > Ez a bekezdés tartalmazza > fontos kiegészítések > ehhez a dokumentumhoz.

Ebben a hagyományos kimeneti formátumban az a jelentése hozzáadva (az angol  add szóból ), a d azt jelenti , hogy törölve , a c azt jelenti , hogy megváltozott . Az a, d vagy c betűket a forrásfájl sorszámai előzik meg, majd a célfájl sorszámai. Minden hozzáadott, eltávolított vagy módosított sort szögletes zárójelek előznek meg .

Alapértelmezés szerint a forrás- és célfájlok közös sorszámai nincsenek megadva. Az áthelyezett sorok új helyükre hozzáadva és az előző helyükről eltávolítva jelennek meg. [egy]

Opciók

A legtöbb diff implementáció külsőleg változatlan maradt 1975 óta. A módosítások közé tartozik a fő algoritmus fejlesztése, új parancsbillentyűk hozzáadása, új kimeneti formátumok. Az alapalgoritmust Eugene W. Myers [2] An O(ND) Difference Algorithm and its Variations , valamint Webb Miller és Myers [3] A File Comparison Program című könyve vázolja fel . Az algoritmust egymástól függetlenül fedezte fel és írta le E. Ukkonen Algorithms for Approximate String Matching című könyvében [4] . A diff program első verziói a szövegfájlok sorainak összehasonlítására készültek, sorelválasztóként az újsor karaktert használva. Az 1980-as években a bináris fájlok támogatása változásokhoz vezetett a program működésében és megvalósításában.

Szkript szerkesztése

A szerkesztési szkriptet a diff modern verziói is előállíthatják az -e kapcsolóval . Példánk eredménye így fog kinézni:

24a Ez a bekezdés tartalmazza fontos kiegészítések ehhez a dokumentumhoz. . 17c lennie kell . 8.14c az információ mennyisége. . 0a Ez egy fontos megjegyzés! Ezért kellene található ennek elején dokumentum! .

Ahhoz, hogy az eredményül kapott szkriptet az eredeti fájl új fájlállapotba konvertálásához használjuk , két sort kell hozzáadnunk a szkript végéhez: az egyik a w (írás), a másik - q (kilépés) parancsot tartalmazza. Például így . Itt elneveztük a diff fájlt mydiff . Az átalakítás akkor megy végbe, amikor kiadjuk a parancsot . printf "w\nq\n" >> mydiffed -s original < mydiff

Kontextus formátum

A BSD 2.8-as verziója (kiadva 1981 júliusában) bevezette a kontextusformátumot ( -c ) és a fájlrendszer-könyvtárfa rekurzív bejárásának lehetőségét ( -r ).

Kontextus formátumban a megváltozott sorok a módosított töredék előtt és után nem érintett sorokkal együtt jelennek meg. Tetszőleges számú érintetlen sor beszúrása kontextust biztosít a javításhoz. A nem érintett sorokból álló kontextus referenciaként szolgál a módosítandó töredék helyének meghatározásához a célfájlban, még akkor is, ha a módosított sorok sorszáma a forrás- és célfájlban nem egyezik. A környezeti formátum jobban olvasható az emberek számára, és megbízhatóbb javítások alkalmazásakor, a kimenet pedig a javítóprogram bemeneteként jelenik meg .

A módosított töredék előtti és utáni érintetlen sorok számát a felhasználó beállíthatja, és ez akár nulla is lehet, de általában az alapértelmezett három sor. Ha a töredékben lévő érintetlen sorok kontextusa átfedésben van egy szomszédos töredékkel, akkor a diff elkerüli a nem érintett sorok másolását, és a szomszédos töredékeket egyesíti.

A diff -c eredeti új parancs kimenete :

*** /útvonal/eredeti ''időbélyeg'' --- /út/új ''időbélyeg'' ************** *** 1,3 **** --- 1,9 ---- + Ez egy fontos megjegyzés! + Tehát ennek a + dokumentumnak az elején + kell lennie ! + A dokumentum ezen része változatlan maradt verzióról verzióra. Ha egy ************** *** 5,20 **** nem szabad megjeleníteni. Különben nem segít az optimális következtetése ! gyártott mennyiség ! változtatások. ! ! Ez a bekezdés tartalmazza ! elavult szöveg. ! El lesz távolítva ! hamar. Ez a dokumentum ! lennie kell helyesírás-ellenőrzés. Másrészt a hiba egyszóval – nem a világ vége. --- 11.20 ---- nem szabad megjeleníteni. Különben nem segít az optimális következtetése ! az információ mennyisége. Ez a dokumentum ! lennie kell helyesírás-ellenőrzés. Másrészt a hiba egyszóval – nem a világ vége. ************** *** 22.24 **** --- 22.28 ---- nem igényel változtatásokat. Új szöveg lehet add hozzá a dokumentum végéhez. ++ Ez a bekezdés fontos kiegészítéseket tartalmaz + ehhez a dokumentumhoz.

Univerzális formátum

Az univerzális formátum (vagy unidiff ) magában foglalja a kontextusformátumban végrehajtott technikai fejlesztéseket, de tömörebben jeleníti meg a régi és az új szöveg közötti különbséget. Az univerzális formátum általában az " -u " parancssori kapcsolóval hívható meg . Ezt a kimenetet gyakran használják a programok javításaként . Sok projekt kifejezetten kéri, hogy a "diff"-eket általános formátumban küldjék el nekik, így az általános formátum a leggyakoribb csere a szoftverfejlesztők között.

Az univerzális kontextusdiff-eket először Wayne Davison dolgozta ki 1990 augusztusában ( az unidiff a comp.sources.misc 14. fejezetében található). Stallman egy hónappal később hozzáadta az univerzális formátum támogatást a GNU Project diff segédprogramjához, és ez a funkció az 1991 januárjában kiadott GNU diff 1.15-ben debütált . A GNU diff azóta általánosította a környezeti formátumot, hogy lehetővé tegye a különbségek tetszőleges formázását.

Az általános formátumú fájl ugyanazzal a két sorral kezdődik, mint a környezeti formátum, azzal a különbséggel, hogy az eredeti fájl " --- " karakterrel kezdődik, az új pedig " +++ " karakterrel kezdődik. Ezeket egy vagy több módosított részlet követi , amelyek soronkénti módosításokat tartalmaznak a fájlokon. A változtatás nélküli sorok szóközzel, a hozzáadott sorok pluszjellel, a törölt sorok mínuszjellel kezdődnek.

A töredék tartományinformációkkal kezdődik, és közvetlenül követi hozzáadott sorok, törölt sorok és tetszőleges számú kontextussor. A tartományinformációkat kettős @ jel veszi körül, és egyetlen sorban van összefűzve, szemben a ( kontextusformátum ) két sorával. A tartomány információi a következő formátumúak:

@@ -l,s +l,s @@ opcionális szakaszfejléc

A tartományinformáció két részből áll. Az eredeti fájl része mínuszjellel kezdődik, az új fájl része pedig pluszjellel. Az egyes részek l, s formátumúak , ahol l  annak a sornak a száma, amellyel kezdjük, és s  azoknak a soroknak a száma, amelyek megváltoztak az aktuális töredékben minden egyes fájl esetében (vagyis a első esetben ez a szóközzel és mínuszjel kezdődő kimeneti sorok összege, a második esetben a szóközzel és pluszjel kezdődő sorok összege). A GNU diff sok verziójában a vessző és a zárójelek elhagyhatók minden tartományból. Ebben az esetben az s alapértelmezés szerint 1. Ne feledje, hogy l egyedüli hasznos értéke  az első tartomány sorszáma, a többi érték a különbségből számítható ki.

Az eredeti fájl tartománytöredékének a töredék összes kontextusának és törölt sorainak (beleértve a módosított) sorainak összegét kell képeznie. Az új fájl tartománytöredékének tartalmaznia kell az összes kontextus és a töredék hozzáadott (a módosított) sorainak összegét.

A tartománytöredéket megelőzheti annak a szakasznak vagy funkciónak a címe, amelynek a töredék része. Ez általában magának a részletnek az olvasásához hasznos. Amikor GNU-val diff-et hozunk létre, a diff fejlécet a [5] reguláris kifejezés határozza meg .

Ha egy sor megváltozott, az eltávolítottként és hozzáadva is megjelenik. Mivel a törölt és hozzáadott sorok szomszédos töredékekben vannak, ezek a sorok egymás mellett jelennek meg [6] . Például:

- ellenőrizze ezt a dokumentumot. Tovább +ellenőrizze ezt a dokumentumot. Tovább

A diff -u eredeti új parancs a következő kimenetet adja:

--- /útvonal/eredeti ''időbélyeg'' +++ /út/új ''időbélyeg'' @@ -1.3 +1.9 @@ +Ez egy fontos megjegyzés! +Ezért + a dokumentum +elején kell lennie ! + A dokumentum ezen része változatlan maradt verzióról verzióra. Ha egy @@ -5,16 +11,10 @@ nem szabad megjeleníteni. Különben nem segít az optimális következtetése - a végrehajtott változtatások mennyisége. - -Ez a bekezdés elavult szöveget tartalmaz. -A közeljövőben eltávolítják . + információ mennyisége. Ez a dokumentum - meg kell tenni + meg kell tenni helyesírás-ellenőrzés. Másrészt a hiba egyszóval – nem a világ vége. @@ -22,3 +22,7 @@ nem igényel változtatásokat. Új szöveg lehet add hozzá a dokumentum végéhez. ++ Ez a bekezdés +fontos kiegészítéseket tartalmaz ehhez a dokumentumhoz.

Vegye figyelembe, hogy a tabulátorok a fájlnevek és az időbélyegek megfelelő elkülönítésére szolgálnak. Ez láthatatlan a képernyőn, és a konzolról történő másolás/beillesztés során elveszhet.

Számos módosítás és kiterjesztés létezik a diff formátumokhoz, amelyeket különféle programok használnak és megértenek. Például egyes verziókezelő rendszerek , mint például a Subversion , megadják a verziószámot, a "munkapéldányt" vagy bármilyen más megjegyzést a diff fejlécében lévő időbélyeg mellett.

Egyes programok lehetővé teszik, hogy több különböző fájlhoz diff-eket hozzon létre, és egyesítse őket egy fejléc használatával minden módosított fájlhoz, ami így nézhet ki:

Index: elérési út/fájl.cpp

A nem újsorral végződő fájlok speciális fajtái nem támogatottak. Sem az unidiff segédprogram, sem a POSIX diff szabvány nem határozza meg az ilyen fájlok kezelésének módját (sőt, az ilyen típusú fájlok nem "szöveg" a POSIX [7] definíciójában ).

A javítóprogram semmit sem tud a diff parancs speciális kimenetének megvalósításáról.

Lásd még

Jegyzetek

  1. David MacKenzie, Paul Eggert és Richard Stallman. Fájlok összehasonlítása és egyesítése a GNU Diff és  Patch segítségével . – 1997.
  2. E. Myers. Egy O(ND ) különbségi algoritmus és annak változatai   // Algorithmica : folyóirat. - 1986. - 1. évf. 1 , sz. 2 . - P. 251-266 .
  3. Webb Miller és Eugene W. Myers. Fájl-összehasonlító program // Szoftver – gyakorlat és tapasztalat. - 1985. - T. 15 , 11. sz . - S. 1025-1040 .
  4. E. Ukkonen.  Algoritmusok a hozzávetőleges karakterlánc - illesztéshez  // Információ és számítás : folyóirat. - 1985. - 1. évf. 64 . - P. 100-118 .
  5. 2.2.3 A szakaszok közötti különbségek archiválása 2013. május 26-án, a Wayback Machine , GNU diffutils  kézikönyvben
  6. Unified Diff Format archiválva : 2013. április 5., a Wayback Machine , Guido van Rossum ,  2006. június 14.
  7. http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_205 Archiválva : 2013. április 29. a Wayback Machine Section 3.205-ben 

Linkek