Wenn Sie jemals an einer großen Codebasis mit einem verteilten Entwicklungsmodell gearbeitet haben, haben Sie wahrscheinlich schon Leute sagen hören wie „Sue hat gerade einen Patch geschickt“ oder „Rajiv prüft den Unterschied“. Vielleicht waren diese Begriffe neu für Sie und Sie haben sich gefragt, was sie bedeuten. Open Source hat sich hier ausgewirkt, da das Hauptentwicklungsmodell großer Projekte vom Apache-Webserver bis zum Linux-Kernel während ihrer gesamten Lebensdauer „Patch-basierte“ Entwicklungsprojekte waren. Wussten Sie eigentlich, dass der Name Apache aus einer Reihe von Patches stammt, die gesammelt und mit dem ursprünglichen Quellcode des NCSA-HTTPd-Servers abgeglichen wurden?
Sie könnten denken, dass dies Folklore ist, aber eine frühe Aufnahme der Apache-Website behauptet, dass der Name von dieser ursprünglichen „Patch“ -Sammlung abgeleitet wurde; daher APA tCH y-Server, der dann zu Apache vereinfacht wurde.
Aber genug Geschichtstrivia. Was genau sind diese Patches und Unterschiede über die Entwickler sprechen?
Nehmen wir für diesen Artikel zunächst an, dass sich diese beiden Begriffe auf ein und dasselbe beziehen. „Diff“ ist einfach die Abkürzung für „Unterschied“; Ein gleichnamiges Unix-Dienstprogramm zeigt den Unterschied zwischen einer oder mehreren Dateien. Wir werden uns unten ein Diff-Utility-Beispiel ansehen.
Ein „Patch“ bezieht sich auf eine bestimmte Sammlung von Unterschieden zwischen Dateien, die mit dem Unix-Dienstprogramm diff auf einen Quellcodebaum angewendet werden können. Wir können also Diffs (oder Patches) mit dem Diff-Tool erstellen und sie mit dem Patch-Tool auf eine ungepatchte Version desselben Quellcodes anwenden. Nebenbei bemerkt (und gegen meine Regel, dass es keine historischen Trivia mehr gibt), kommt das Wort „Patch“ von der physischen Abdeckung von Lochkartenlöchern, um Softwareänderungen in den frühen Computertagen vorzunehmen, als Lochkarten das Programm darstellten, das vom Prozessor des Computers ausgeführt wurde. Das folgende Bild, das sich auf dieser Wikipedia-Seite befindet und Software-Patches beschreibt, zeigt dieses ursprüngliche „Patching“-Konzept:
Nachdem Sie nun ein grundlegendes Verständnis von Patches und Diffs haben, wollen wir untersuchen, wie Softwareentwickler diese Tools verwenden. Wenn Sie noch kein Quellcodeverwaltungssystem wie Git oder Subversion verwendet haben, werde ich die Voraussetzungen dafür schaffen, wie die meisten nicht-trivialen Softwareprojekte entwickelt werden. Wenn Sie sich das Leben eines Softwareprojekts als eine Reihe von Aktionen entlang einer Zeitachse vorstellen, können Sie Änderungen an der Software visualisieren – z. B. das Hinzufügen eines Features oder einer Funktion zu einer Quellcodedatei oder das Beheben eines Fehlers – die an verschiedenen Stellen auftauchen die Zeitleiste, wobei jeder diskrete Punkt den Zustand aller Quellcodedateien zu diesem Zeitpunkt darstellt. Wir werden diese Änderungspunkte „Commits“ nennen und dabei dieselbe Nomenklatur verwenden, die das heute beliebteste Tool zur Quellcodeverwaltung, Git, verwendet. Wenn Sie den Unterschied zwischen dem Quellcode vor und nach einem bestimmten Commit oder zwischen vielen Commits sehen möchten, können Sie ein Tool verwenden, um uns Unterschiede oder Unterschiede anzuzeigen.
Wenn Sie Software mit demselben Tool zur Quellcodeverwaltung, Git, entwickeln, haben Sie möglicherweise Änderungen in Ihrem lokalen System, die Sie anderen zur Verfügung stellen möchten, um sie möglicherweise als Commits zu ihrem eigenen Baum hinzuzufügen. Eine Möglichkeit, anderen lokale Änderungen bereitzustellen, besteht darin, ein Diff der Änderungen Ihres lokalen Baums zu erstellen und diesen „Patch“ an andere zu senden, die am selben Quellcode arbeiten. Dadurch können andere ihren Baum patchen und den Quellcodebaum mit Ihren angewendeten Änderungen sehen.
Linux, Git und GitHub
Dieses Modell des Teilens von Patch-Dateien ist, wie die Linux-Kernel-Community in Bezug auf vorgeschlagene Änderungen heute vorgeht. Wenn Sie sich die Archive für eine der beliebten Linux-Kernel-Mailinglisten ansehen – LKML ist die primäre, aber andere umfassen linux-containers, fs-devel, Netdev, um nur einige zu nennen –, werden Sie feststellen, dass viele Entwickler Patches posten, die sie enthalten andere überprüfen, testen und möglicherweise irgendwann in den offiziellen Linux-Kernel-Git-Baum einbringen möchten. Es würde den Rahmen dieses Artikels sprengen, Git, das von Linus Torvalds geschriebene Quellcode-Kontrollsystem, ausführlicher zu erörtern, aber es ist erwähnenswert, dass Git dieses verteilte Entwicklungsmodell ermöglicht, indem es Patches ermöglicht, getrennt von einem Haupt-Repository zu leben und zu pushen und in verschiedene Bäume ziehen und ihrem spezifischen Entwicklungsfluss folgen.
Bevor wir fortfahren, können wir den beliebtesten Dienst, für den Patches und Diffs relevant sind, nicht ignorieren:GitHub. Aufgrund des Namens lässt sich wahrscheinlich erahnen, dass GitHub auf Git basiert, aber es bietet einen web- und API-basierten Workflow rund um das Git-Tool für die verteilte Open-Source-Projektentwicklung. Patches werden in GitHub hauptsächlich nicht per E-Mail geteilt, wie beim Linux-Kernel, sondern durch Erstellen einer Pull-Anforderung . Wenn Sie Änderungen an Ihrer eigenen Kopie eines Quellcodebaums festschreiben, können Sie diese Änderungen freigeben, indem Sie eine Pull-Anforderung für ein gemeinsam genutztes Repository für dieses Softwareprojekt erstellen. GitHub wird heute von vielen aktiven und beliebten Open-Source-Projekten verwendet, darunter Kubernetes, Docker, das Container Network Interface (CNI), Istio und viele andere. In der GitHub-Welt neigen Benutzer dazu, die webbasierte Schnittstelle zu verwenden, um die Diffs oder Patches zu überprüfen, die eine Pull-Anforderung enthalten, aber Sie können immer noch auf die Roh-Patch-Dateien zugreifen und sie in der Befehlszeile mit dem Patch-Dienstprogramm verwenden.
Zur Sache kommen
Nachdem wir nun Patches und Diffs behandelt haben und wie sie in beliebten Open-Source-Communities oder -Tools verwendet werden, sehen wir uns einige Beispiele an.
Das erste Beispiel enthält zwei Kopien eines Quellbaums, und eine enthält Änderungen, die wir mithilfe des Dienstprogramms diff visualisieren möchten. In unseren Beispielen werden wir uns „vereinheitlichte“ Diffs ansehen, da dies die erwartete Ansicht für Patches in den meisten modernen Softwareentwicklungswelten ist. Weitere Informationen zu Optionen und Möglichkeiten zum Erzeugen von Unterschieden finden Sie auf der man-Seite von diff. Der ursprüngliche Quellcode befindet sich in sources-orig und unsere zweite, modifizierte Codebasis befindet sich in einem Verzeichnis namens sources-fixed. Verwenden Sie den folgenden Befehl, um die Unterschiede in einem einheitlichen Diff-Format in Ihrem Terminal anzuzeigen:
$ diff -Naur sources-orig/ sources-fixed/
... was dann die folgende Diff-Befehlsausgabe zeigt:
diff -Naur sources-orig/officespace/interest.go sources-fixed/officespace/interest.go
--- sources-orig/officespace/interest.go 2018-08-10 16:39:11.000000000 -0400
+++ sources-fixed/officespace/interest.go 2018-08-10 16:39:40.000000000 -0400
@@ -11,15 +11,13 @@
InterestRate float64
}
+// compute the rounded interest for a transaction
func computeInterest(acct *Account, t Transaction) float64 {
interest := t.Amount * t.InterestRate
roundedInterest := math.Floor(interest*100) / 100.0
remainingInterest := interest - roundedInterest
- // a little extra..
- remainingInterest *= 1000
-
// Save the remaining interest into an account we control:
acct.Balance = acct.Balance + remainingInterest
Die ersten paar Zeilen der Ausgabe des diff-Befehls könnten eine Erklärung gebrauchen:Die drei ---
Zeichen zeigen den ursprünglichen Dateinamen; allen Zeilen, die in der Originaldatei, aber nicht in der verglichenen neuen Datei vorhanden sind, wird ein einzelner -
vorangestellt zu beachten, dass diese Zeile von den Quellen „abgezogen“ wurde. Der +++
Zeichen zeigen das Gegenteil:Die verglichene neue Datei und die in dieser Datei gefundenen Ergänzungen werden mit einem einzelnen +
gekennzeichnet Symbol, um anzuzeigen, dass sie in der neuen Version der Datei hinzugefügt wurden. Jeder „Hunk“ (das sind Abschnitte mit dem Präfix @@
aufgerufen werden) der Differenz-Patch-Datei hat kontextabhängige Zeilennummern, die dem Patch-Tool (oder anderen Prozessoren) helfen zu wissen, wo diese Änderung anzuwenden ist. Sie können an der Referenzfunktion des Films „Büroräume“ sehen, dass wir die Gier eines unserer Softwareentwickler korrigiert haben (indem drei Zeilen entfernt wurden), der die abgerundete Zinsberechnung zusammen mit einem Kommentar zu unserer Funktion etwas hinzugefügt hat .
Wenn Sie möchten, dass jemand anderes die Änderungen dieses Baums testet, können Sie diese Ausgabe von diff in einer Patch-Datei speichern:
$ diff -Naur sources-orig/ sources-fixed/ >myfixes.patch
Jetzt haben Sie eine Patch-Datei, myfixes.patch, die mit einem anderen Entwickler geteilt werden kann, um diesen Satz von Änderungen anzuwenden und zu testen. Ein anderer Entwickler kann die Änderungen mit dem Patch-Tool anwenden, vorausgesetzt, sein aktuelles Arbeitsverzeichnis befindet sich in der Basis des Quellcodebaums:
$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go
Jetzt ist der Quellbaum Ihres Mitentwicklers gepatcht und bereit, die Änderungen zu erstellen und zu testen, die über den Patch angewendet wurden. Was wäre, wenn dieser Entwickler Änderungen an interest.go separat vorgenommen hätte? Solange sich die Änderungen nicht direkt widersprechen – ändern Sie beispielsweise genau dieselben Zeilen – sollte das Patch-Tool in der Lage sein, zu lösen, wo die Änderungen zusammengeführt werden sollen. Als Beispiel wird eine Interest.go-Datei mit mehreren anderen Änderungen verwendet die folgende beispielhafte Ausführung des Patches:
$ patch -p1 < ../myfixes.patch
patching file officespace/interest.go
Hunk #1 succeeded at 26 (offset 15 lines).
In diesem Fall warnt patch, dass die Änderungen nicht an der ursprünglichen Stelle in der Datei angewendet wurden, sondern um 15 Zeilen versetzt wurden. Wenn Sie Dateien stark verändert haben, gibt Patch möglicherweise den Versuch auf, herauszufinden, wo die Änderungen passen, aber es bietet Optionen (mit den erforderlichen Warnungen in der Dokumentation), um die passende „Unschärfe“ aufzudecken (die den Rahmen dieses Artikels sprengen würde). .
Wenn Sie Git und/oder GitHub verwenden, werden Sie die Diff- oder Patch-Tools wahrscheinlich nicht als eigenständige Tools verwenden. Git bietet viele dieser Funktionen, sodass Sie die integrierten Funktionen zum Arbeiten an einem gemeinsam genutzten Quellbaum mit Zusammenführen und Abrufen der Änderungen anderer Entwickler nutzen können. Eine ähnliche Möglichkeit besteht darin, git diff zu verwenden, um die vereinheitlichte Diff-Ausgabe in Ihrem lokalen Baum oder zwischen zwei beliebigen Referenzen (einer Commit-ID, dem Namen eines Tags oder Zweigs usw.) bereitzustellen. Sie können sogar eine Patch-Datei erstellen, die jemand, der Git nicht verwendet, nützlich finden könnte, indem Sie einfach die Ausgabe von git diff in eine Datei umleiten, vorausgesetzt, dass sie das genaue Format des diff-Befehls verwendet, den der Patch verwenden kann. Natürlich nimmt GitHub diese Funktionen in eine webbasierte Benutzeroberfläche auf, sodass Sie Dateiänderungen bei einer Pull-Anforderung anzeigen können. In dieser Ansicht werden Sie feststellen, dass es sich praktisch um eine vereinheitlichte Diff-Ansicht in Ihrem Webbrowser handelt und GitHub es Ihnen ermöglicht, diese Änderungen als Roh-Patch-Datei herunterzuladen.
Zusammenfassung
Sie haben gelernt, was ein Diff und ein Patch sind, sowie die gängigen Unix/Linux-Befehlszeilentools, die mit ihnen interagieren. Sofern Sie kein Entwickler in einem Projekt sind, das noch eine auf Patchdateien basierende Entwicklungsmethode verwendet – wie den Linux-Kernel –, werden Sie diese Funktionen hauptsächlich über ein Quellcodeverwaltungssystem wie Git nutzen. Aber es ist hilfreich, den Hintergrund und die Grundlagen von Funktionen zu kennen, die viele Entwickler täglich durch übergeordnete Tools wie GitHub verwenden. Und wer weiß – sie können sich eines Tages als nützlich erweisen, wenn Sie mit Patches von einer Mailingliste in der Linux-Welt arbeiten müssen.