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.
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.
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
abcdfgjzA 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 + - + + - + + +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]
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.
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
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.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écA 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ábbA 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.cppA 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.
Unix parancsok | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
|
Verzióvezérlő rendszerek ( kategória ) | |
---|---|
Csak helyi | |
Kliens-szerver | |
Megosztott | |