2. Bewährte Patchingpraktiken

Die meisten Personen werden in Open-Source Software involviert durch das schreiben von Patches für fremde Software bevor sie selber eigene Projekte veröffentlichen. Angenommen du hättest ein Satz von Source-Code Änderungen für den Basiscode einer anderen Person geschrieben. Nun versuch dich in die Lage der anderen Person zu versetzen. Nach welchen Kriterien soll sie beurteilen, ob sie den Patch einbinden soll?

Die Wahrheit ist, dass es sich als sehr schwierig erweist die Qualität eines Stück Codes zu eruieren. Entwickler tendieren in der Evaluierung von Patches auf die Qualität der Übermittlung zu achten. Sie beurteilen den Übermittlungsstil und die Kommunikationseigenschaften des gegenübers, welche Aufschluss über die Erfahrung der Person in der Evaluierung und Integration von neuen Patches ermöglicht.

Dies ist eine ziemlich verlässliche Praktik für die Gewährleistung qualitativen Codes. Über viele Jahre hinweg habe ich Patches von hunderten von fremden Personen evaluiert und nur selten habe ich einen Patch gesichtet, welcher durchdacht und der Zeit gegenüber respektvoll präsentiert wurde; sie waren zumeist technische Enttäuschungen. Auf der anderen Seite, hat mich die Erfahrung gelehrt, dass Patches, welche ein nachlässiges Erscheinungsbild haben oder unsorgfältig und unbedacht gepackt worden sind, sehr wahrscheinlich in technischer Hinsicht nicht sehr hochstehend sind.

Hier nun einige Ratschläge wie ein Patch akzeptiert werden kann:

2.1. Sende Patches, keine ganzen Archive oder Dateien

Wenn die Änderung eine neue Datei beinhaltet, welche noch nicht im Code enthalten ist, dann muss natürlich logischerweise die ganze Datei mitgesandt werden. Wenn man eine bereits bestehende Datei modifizieren sollte, dann empfiehlt sich diese Praxis nicht - ein Diff kann stattdessen übermittelt werden; spezifischer ausgedrückt, sende die Ausgabe des diff(1) Befehls, um die baseline Version gegenüber deiner modifizierten Version vergleichen zu können.

Der diff Befehl und sein Vetter, patch(1) (welcher automatisch einer bestehenden baseline Datei ein Diff hinzufügt) sind wichtige Basisprogramme der Open-Source Entwicklung. Diffs sind besser wie ganze Dateien, denn der Entwickler dem man versucht den Patch zuzustellen, könnte die Baseline Version geändert haben seit man selber eine Kopie bezogen hatte. Durch die Zusendung eines Diffs erspart man ihm den Aufwand der Separierung der neu erfolgten Änderungen von seinen eigenen; dies bekundet Achtung vor seiner Zeit.

2.2. Sende Patches, die der aktuellen Version des Codes angepasst sind.

Es ist sowohl kontraproduktiv wie auch rüde Patches für eine Codeversion zuzustellen, die schon längst veraltet ist und anschliessend von dem Ursprungsautor zu erwarten, dass er die Arbeit betreffend der Feststellung, welche Änderungen seither von ihm selbst implementiert worden sind, auf sich nimmt oder beziehungsweise welche Codefragmente aus dem Patch wirklich neu sind.

Als ein Patchübermittler steht es in deiner Verantwortung den zurzeitigen Status der Quellen (oder: Sources) festzustellen und anschliessend nur einen "minimalen" Patch zuzustellen, welcher alle relevanten Änderungen der mainline Codebasis beinhaltet. Dies heisst, dass man ein Patch für die aktuelle Version zustellt.

2.3. Inkludiere keine Patches für generierte Dateien.

Bevor du den Patch übermittelst sehe ihn erneut durch und lösche jegliche Patchbindungen für Dateien, welche automatisch regeneriert werden, sobald der Patch angewendet und das Programm remake ausführt wird. Klassische Beispiele für diesen Fehler sind durch Bison oder Flex generierte C Dateien.

Heutzutage ist der häufigste Fehler dieser Art, dass ein Diff mit einem riesigen Band mitgesandt wird, der nichts beeinhaltet ausser den Änderungen zwischen deinem configure Script und seinem. Diese Datei wird durch autoconf generiert.

Dies ist eine unüberlegte Handlung. Der Empfänger des Patches wird so gezwungen den wahren Inhalt von lauter, unnützen Blöcken zu separieren. Es ist ein zweitklassiger Fehler, nicht so wichtig wie andere Punkte, die folgen werden — aber er beeinträchtigt die Wahrnehmung deiner Kompetenz.

2.4. Sende keine Patchbänder, die nur die RCS oder SCCS $-Symbole verändern.

Einige Personen versehen ihre Sourcedateien mit speziellen Tokens, welche durch das Versionskontrolle System expandiert werden, sobald die Datei eingecheckt wird: das $Id: Software-Release-Practice-HOWTO.sgml,v 1.15 2002/02/04 19:24:34 esr Exp $ Konstrukt, welches von RCS und CVS verwendet wird, beispielsweise.

Sofern du eine lokale Versionskontrolle gebrauchst, könnten deine Änderungen diese Tokens modifizieren. Dies zieht keine drastische Schäden nach sich, da sobald der Empfänger nach der Anwendung des Patches seinen Code überprüfen wird, wird er zur Kenntnis nehmen, dass gewisse Änderungen aufgrund seines Status der Versionskontrolle verworfen worden sind. Aber diese zusatzlichen Patchbänder sind unnütz. Sie lenken ab. Es empfiehlt sich jene nicht zu senden.

Dies ist ein weiterer geringfügiger Fehler. Man wird dir verzeihen, sofern du keine andere grosse Untat begehen wirst. Aber er sollte ohnehin vermieden werden.

2.5. Gebrauche -c oder -u format, und nicht den Standard Parameter (-e) format

Das Standard (-e) format oder diff(1) ist sehr "spröde". Es beinhaltet keinerlei Kontext, sodass das Patchtool die Analyse, ob neue Zeilen in den baseline Code eingefügt oder bestehende gelöscht worden sind seit eine Kopie des Codes bezogen wurde nicht meistern kann.

Ein -e diff zu erhalten ist nervenaufreibend und impliziert, dass der Absender entweder ein ungeheurer Anfänger, unvorsichtig oder ahnungslos ist. Die meisten solcher Patches werden ohne einen zweiten Blick unverzüglich gelöscht.

2.6. Versehe deinen Patch mit einer Dokumentation

Dies ist sehr wichtig. Wenn dein Patch eine benutzerersichtliche Veränderung bewirkt oder gewisse Eigenschaften der Softwarefunktionen verändert, führe die Veränderungen in den entsprechenden Manualseiten (oder: manpages) und anderen Dokumentationsseiten innerhalb des Patches nach. Nimm nicht an, dass der Empfänger sich glücklich wähnen wird, den Code für dich auszukommentieren oder das sich undokumentierte Funktionen innerhalb seines Codes verbergen.

Die gründliche Dokumentation von Veränderungen bewirkt einiges. Erstens, ist es rücksichtsvoll betreffend der Person, die man zu überreden versucht. Zweitens, zeigt dies, dass du die "Verzweigung" deiner Veränderungen gut genug nachvollziehen kannst, um sie jemanden erklären zu können, der der Codeentzifferung nicht mächtig ist. Drittens, ist es ein Zeugnis dafür, dass du dich um die Personen sorgst, die schlussendlich die Software einsetzen werden.

Gute Dokumentation ist üblicherweise das sichtbarste Zeichen einer Differenzierung zwischen eines stabilen Beitrags und einem "quick & dirty" Hack. Wenn du mit der nötigen Sorgfalt versehen bist und dir die Zeit nimmst, um eine angemessene Dokumentation ins Leben zu berufen, wirst du erkennen, dass du beinahe 85% der Optionen, um dein Patch unter der Grosszahl von Entwicklern akzeptiert zu haben, bereits ausgereizt hast.

2.7. Versehe deinen Patch mit einer Erläuterung

Dein Patch sollte Notizen beinhalten, die erläutern, warum du den Patch als notwendig oder nützlich erachtest. Diese Erläuterung richtet sich nicht an die Benützer der Software, sondern an die Entwickler denen man den Patch zuzustellen versucht.

Die Notiz kann kurz sein — die höchst effiziente Notizen, die ich je gesehen habe, sagten nur "Konsultiere die Dokumentationsänderungen in diesem Patch" aus. Wichtig ist, das die richtige Haltung an den Tag gelegt wird.

Die richtige Haltung sollte hilfsbereit, Achtung betreffend der Zeit des Entwicklers bezeugend, vertrauensvoll aber unerwartend sein. Es hilft, das Verständnis für den Code, den man zu patchen versucht, auszuführen. Überdies hilft es, wenn man sich mit den Problemen des Entwicklers identifizieren kann. Zudem bewährt es sich, wenn man ehrlich gewisse Zweifel bezüglich dem Restrisiko eines Patches kundtut. Hier führe ich einige beispielhafte erläuterende Kommentare auf, welche ich betreffend Notizen als nützlich erachte:

"Ich habe innerhalb des Codes zwei Probleme determiniert, X and Y. Ich konnte zwar das Problem X lösen, aber ich wagte mich nicht an das Problem Y, da ich befürchte, dass ich nicht den Teil des Codes verstehe, der involviert ist.

"Ein Coredump, der durch einen zu langen eingegebenen String erzeugt werden könnte, habe ich behoben. Während mit der Lösung dieses Problems beschäftigt war, entdeckte ich einen ähnlichen Overflow anderswo. Ein möglicher könnte in blarg.c, unmittelbar in der Nähe von Zeile 666, enthalten sein. Seid ihr euch gewiss, dass der Absender nicht mehr wie 80 Zeichen pro Übertragung generieren kann?"

"Habt ihr schon den Gebrauch des Foonly Algorithmus für dieses Problem in Erwägung gezogen? Eine gute Implementierung ist unter <http://www.somesite.com/~jsmith/foonly.html> vorhanden."

"Dieser Patch behebt das unmittelbare Problem, aber ich befürchte, dass es die Speicherallozierung in unnötiger Weise verkompliziert.
Für mich mag es seinen Zweck erfüllen, aber ich denke es sollte unter erhärteten Bedingungen getestet werden, bevor es veröffentlicht wird. "

"Dies mag ein wenig wirr erscheinen, aber nichtdestotrotz stelle ich euch diese Änderung zu. Vielleicht seid ihr imstande, ein bessere Methode verwenden, um diese Funktionalität zu implementieren."

2.8. Versehe deinen Code mit nützlichen Kommentaren

Als ein Entwickler, der seine Software wartet, möchte ich zuerst starkes Vertrauen in meine Fähigkeit haben, dass ich deine Veränderungen, die der Patch impliziert, verstanden habe bevor ich sie miteinander fusionieren werde. Dies ist keine invariable Regelung; wenn du mir bereits mehrfach gute Arbeit übermittelt hast, werde ich wahrscheinlich nur einen kurzen Überblick über die Veränderungen haben wollen bevor ich sie integriere. All deine Bemühungen deinen Code en detail verstehen zu können und Ungewissheiten betreffend des Verständnisses zu vermindern erhöht gleichzeitig die Möglichkeit, dass dein Patch akzeptiert werden wird.

Nützliche Kommentare innerhalb des Codes erhöhen das Verständnis; schlechte hingegen nicht.

Ein Beispiel eines schlechten Kommentares:

/* Norman Newbie behob diesen Fehler am 13 August 2001 */

Dies überbringt keinerlei Informationen. Es ist nur ein dreckiger Fussabdruck, den du inmitten des Codes sähst. Sofern dein Patch inkludiert werden sollte (die Möglichkeit dzbgl. wurde nun unweigerlich geschmählert), wird dieser Kommentar mit Gewissheit entfernt werden. Wenn du eine Erwähnung beanträgst, dann inkludiere ein Patchband für die Dateien NEWS oder HISTORY des Projektes. Jene werden sicherlich gegenüber erwähntem Kommentar den Vorzug gegeben.

Ein Beispiel eines nützlichen Kommentares:

/*
 * Die Bedingung bedarf spezieller Beachtung, sodass der Funktion crunch_data()
 * niemals ein leerer NULL Zeiger übergeben wird.  <norman_newbie@foosite.com>
 */

Dieser Kommentar bezeugt nicht nur, dass du den Code verstanden hast sondern auch die Art von Information, die benötigt wird damit ich Vertrauen in die von dir getätigten Änderungen habe. Diese Sorte von Kommentar bestärkt mein Vertrauen in deine Änderungen.