Neuformatierung und Versionskontrolle

23

Auf die Formatierung des Codes kommt es an. Auch Einrückungen sind wichtig . Und Konsistenz ist wichtiger als kleine Verbesserungen. In der Regel verfügen Projekte jedoch nicht über einen klaren, vollständigen, überprüfbaren und erzwungenen Styleguide ab dem ersten Tag, und wichtige Verbesserungen können jeden Tag eintreten. Vielleicht findest du das

SELECT id, name, address
FROM persons JOIN addresses ON persons.id = addresses.person_id;

könnte besser geschrieben sein als

SELECT persons.id,
       persons.name,
       addresses.address
  FROM persons
  JOIN addresses ON persons.id = addresses.person_id;

während Sie daran arbeiten, der Abfrage weitere Spalten hinzuzufügen. Vielleicht ist dies die komplexeste aller vier Abfragen in Ihrem Code oder eine triviale Abfrage unter Tausenden. Egal wie schwierig der Übergang ist, Sie entscheiden, dass er sich lohnt. Aber wie verfolgen Sie Codeänderungen über wichtige Formatierungsänderungen hinweg? Sie können einfach aufgeben und sagen, "Dies ist der Punkt, an dem wir von vorne beginnen", oder Sie können alle Abfragen im gesamten Repository-Verlauf neu formatieren.

Wenn Sie ein verteiltes Versionskontrollsystem wie Git verwenden, können Sie zum allerersten Commit zurückkehren und Ihren Weg von dort zum aktuellen Status neu formatieren. Aber es ist eine Menge Arbeit, und alle anderen müssten die Arbeit unterbrechen (oder auf die Mutter aller Verschmelzungen vorbereitet sein), während sie weitergeht. Gibt es eine bessere Möglichkeit, die Geschichte zu ändern, die die besten Ergebnisse liefert?

  • Gleicher Stil in allen Commits
  • Minimale Zusammenführungsarbeit

?

Zur Verdeutlichung geht es hier nicht um bewährte Methoden beim Starten des Projekts, sondern darum, was zu tun ist, wenn ein umfangreiches Refactoring als eine gute Sache erachtet wurde, Sie aber dennoch eine nachvollziehbare Historie wünschen? Das Umschreiben von Verlaufsdaten ist immer dann von Vorteil, wenn nur so sichergestellt werden kann, dass Ihre Versionen immer gleich funktionieren. Was ist jedoch mit den Entwicklervorteilen eines sauberen Umschreibens? Vor allem, wenn Sie Möglichkeiten (Tests, Syntaxdefinitionen oder eine identische Binärdatei nach dem Kompilieren) haben, um sicherzustellen, dass die neu geschriebene Version genauso funktioniert wie das Original?

l0b0
quelle
24
Warum würdest du die Geschichte umschreiben wollen? Es macht den Zweck der Versionskontrolle zunichte. Sie möchten sicherstellen, dass die Anwendung, die Sie vor 3 Monaten versandt haben, ohne den geringsten Zweifel mit der Revision xxxxxx übereinstimmt. Selbst eine triviale Neuformatierung ist nicht akzeptabel.
Simon Bergot
5
Ich möchte Kommentare abgeben, die ich mit "Reformat. No functional change" getaggt habe
Rig
3
Bei einem nicht verwandten Thema klingt es so, als würden Sie vorschlagen, den Git-Verlauf neu zu schreiben, indem Sie den gesamten Code neu formatieren. Gib den Leuten keine Ahnung, das Umschreiben der Git-Geschichte ist in 99,9% der Fälle schlecht. Eine Neuformatierung ist nicht der Fall mit einer Kante von 0,1%.
Andrew T Finnell
4
In einigen Sprachen (ich sehe YOU, Python) kann eine Neuformatierung die logische Funktionsweise des Codes ändern. Sie müssen in der Lage sein, alle in Ihrem VCS gespeicherten Sprachen zu analysieren, um Reformatierungen sicher zu verfolgen und zu ignorieren.
Joris Timmermans
3
Neuformate sind Codeänderungen und sollten als solche festgeschrieben werden.
David Cowden

Antworten:

26

Führen Sie die Neuformatierung als separate Commits durch. Dies beeinträchtigt den Verlauf nur minimal, und Sie sollten auf einen Blick erkennen können, welche Commits nur eine Neuformatierung darstellen und welchen Code tatsächlich ändern. Es könnte schief git blameund ähnlich sein, aber wenn es auf ein reformat-only Commit verweist, ist es ziemlich einfach, vorher nach der vorherigen Änderung zu suchen.

harald
quelle
Ich habe wochenlang Projekte entgleist gesehen, weil einer der Entwickler dies für eine gute Idee hielt. Wenn Sie dies tun, müssen Sie die Risiken im Voraus verstehen und genau entscheiden, wie weit Sie mit der Formatierung gehen werden. Ich denke mjfgates hat die richtige Antwort.
Johntron
1
Klingt so, als hätte das betreffende Team größere Probleme als die Formatierung von Code. Aber ja, ich empfehle das nicht, es sei denn, Sie müssen es tun. Wenn Sie Änderungen neu formatieren möchten, ist es immer noch besser, sie als separate Commits auszuführen, als sie mit funktionalen Änderungen zu mischen.
harald
Ja, viele Probleme: PI möchte neue Entwickler nur darauf hinweisen, dass es nicht so einfach ist, wie es sich anhört. Tools für die Massen-Neuformatierung sind riskant (insbesondere, wenn Sie sie selbst mit Regex erstellen - verwenden Sie zumindest AST), und wenn Sie sich für Codeüberprüfung und Fehlerverfolgung interessieren, kann dies Ihren Prozess erheblich beeinträchtigen. Persönlich schreibe ich meinen Code so, dass er mit dem Stil jeder Datei übereinstimmt, obwohl es mir nichts ausmacht, den Code zu überprüfen, wenn einige Funktionen neu formatiert werden. Viele Entwickler hängen am Code-Stil und vernachlässigen die größeren Probleme wie Architektur, Prozess, Tooling usw.
Johntron
Bei der Programmierung ist nichts so einfach, wie es sich anhört :)
harald
13

VCS-Verlauf nicht umschreiben: Er verstößt gegen die VCS-Prinzipien.

Versuchen Sie nicht, das Korrigieren der Formatierung zu automatisieren: Es behandelt die Symptome, nicht das eigentliche Problem (= Entwickler halten sich nicht an Codierungsstandards).

Definieren Sie den Kodierungsstandard und die Best Practices für die Formatierung in einem gemeinsamen Dokument und lassen Sie alle Entwickler zustimmen.

Sie erwähnen Git, was großartig ist, weil es verteilt ist. Mit einem DVCS ist es sehr einfach, Best Practices über den Gatekeeper-Workflow durchzusetzen . Gatekeeper lehnen Zusammenführungsvorschläge ab (= Pull-Anforderungen in Git), die nicht den allgemeinen Richtlinien entsprechen. Und ich meine ablehnen , in fetten Buchstaben, sonst wird der Codierer in Verletzung nicht die Mühe machen, die Regeln zu befolgen und weiterhin die gleichen Fehler zu wiederholen.

Diese Technik funktioniert gut für mich. Die Programmierer möchten, dass ihre Arbeit zusammengeführt wird. Nach ein paar Fehlern am Anfang folgen sie den Regeln.

Bezüglich der Behebung der vorhandenen Codebasis ... Ich empfehle, dies schrittweise zu tun, möglicherweise Modul für Modul, oder wie es für Ihr Projekt sinnvoll ist. Bei jedem Schritt sorgfältig testen. Es mag sich dumm anhören, aber selbst bei geringfügigen Änderungen wie der Formatierung können Fehler auftreten. Seien Sie also auf ein paar kleine Unebenheiten gefasst.

Hör auf, Monica weiter zu schaden
quelle
1
Abgelehnt, weil der Autor klar feststellt, dass dies im Zusammenhang mit Projekten steht, die nicht mit "... einem klaren, vollständigen, überprüfbaren und erzwungenen Styleguide von Tag 1 an" begonnen haben. Er kann das eigentliche Problem nicht behandeln, weil es bereits passiert ist. Ich stimme dir allerdings zu :)
Johntron
2
Zurückweisen bedeutet, dass es einen Kampf zwischen den Menschen und dem Roboter geben wird. War dort. Früher oder später wird der Roboter ein wirklich komplexes Stück Code benötigen, um auf unlesbare Weise formatiert zu werden. Beispiele: Eine Java-Zeichenfolge ist in der Tat eine SQL-Anweisung, der Roboter weiß dies jedoch nicht. Leerzeichen vor dem Schließen von Parens enthalten möglicherweise Informationen über die Struktur des Codes für den Menschen, nicht jedoch für den Roboter. Funktionsparameter werden auf sinnlose Weise auf mehrere Zeilen aufgeteilt ...
18446744073709551615
9

Die Antwort auf Ihre eigentliche Frage lautet: "Tun Sie nicht." Ich kenne kein aktuelles SCM-Tool, das Änderungen in der Logik von Code, der auf eine Weise formatiert wurde, über eine wichtige Formatierungsänderung und weitere Änderungen nach der neuen Formatierung des Codes nachverfolgen kann. Und Sie wissen, dass es nicht gut ist, den Verlauf eines Codeteils zu verlieren.

Dementsprechend werde ich Ihrem ersten Satz ein wenig widersprechen. Code - Formatierung spielt keine Rolle , dass viel. Schön ist schön, aber dafür sind wir nicht da. Ich verstehe genauso wie jeder andere, der in den alten, höllisch seltsamen K & R-Variantencode mit den zwei Leerzeichen eingetaucht ist (1), aber ... die Formatierung ist eigentlich kein Hindernis für das Verständnis dessen, was vor sich geht, es sei denn, es handelt sich um etwas Außergewöhnliches pathologisch. Und in diesem Fall werden Sie ohnehin Probleme haben, den Code zu ändern, und sollten es nicht stören.

Daher lohnt es sich nicht, Änderungen am etablierten Code STRICTLY vorzunehmen, um ihn neu zu formatieren. Ändern der Variablennamen, Aufbrechen langer Funktionen, all das gute Refactoring-Zeug, das den Inhalt ändert, ja, aber nicht NUR Neuformatierung.

1) - Ich besaß einmal den Windows Clipboard Viewer für eine Weile. Das Ganze war ein 150k C-Modul. Ich fand eine Stelle, an der verschiedene Leute, glaube ich, fünf verschiedene Klammerstile innerhalb von dreißig Zeilen voneinander verwendet hatten. Aber dieser Teil der Dinge hat funktioniert. Ich habe zehn Jahre lang einen Ausdruck dieses Codeblocks mit mir herumgetragen, aber ich habe ihn nicht durchgesehen, weil diese Geschichte von Bedeutung war und dieser Code sich in mindestens drei Quellbäumen befand (Windows 3.x, NT, Future 95), die alle lebten in verschiedenen Gebäuden.

mjfgates
quelle
In der Vergangenheit habe hgich mit Merge-by-Parts ein unschätzbares Werkzeug gefunden, um mit kniffligen, großen Re-Factor-Merges fertig zu werden. Normalerweise würde ich die Commits vor dem großen Re-Faktor zusammenführen, dann den großen Re-Faktor selbst und schließlich die Commits seit dem Re-Faktor zusammenführen. Jede dieser drei Zusammenführungen für sich ist viel einfacher als der Versuch, das Durcheinander zu entwirren, das sich aus der Durchführung aller Zusammenführungen auf einmal ergibt.
Mark Booth
Ich bin völlig einverstanden! Darüber hinaus haben viele Entwickler beim Neuformatieren und beim Codestil über Bord gegangen (eine jüngere Version von mir eingeschlossen), und sie haben am Ende Fehler eingeführt. Ein fehlendes Komma / Semikolon, variable Deklarationen, die an die Spitze der Funktionen verschoben wurden, for-Schleifen, die in for-eachs geändert wurden - alle können subtile Fehler verursachen. Es erfordert täuschende Fähigkeiten, um diese Änderungen sicher durchzuführen.
Johntron
4

Aber wie verfolgen Sie Codeänderungen über wichtige Formatierungsänderungen hinweg?

Formatierungsänderungen sind Codeänderungen. Behandeln Sie sie wie jede andere Änderung an Ihrem Code. Jeder, der an einem bedeutenden Projekt gearbeitet hat, wird wahrscheinlich Fehler und andere Probleme gesehen haben, die entstanden sind, als jemand beschlossen hat, "nur" einen Code neu zu formatieren.

Aber es ist eine Menge Arbeit, und alle anderen müssten die Arbeit unterbrechen (oder auf die Mutter aller Verschmelzungen vorbereitet sein), während sie weitergeht.

Warum müssen Sie alles gleichzeitig neu formatieren? Vor allem, wenn die Neuformatierung die Bedeutung des Codes nicht ändert, sollten Sie in der Lage sein, Dateien einzeln neu zu formatieren und sie im Laufe der Zeit einzuchecken. Besser, Sie veranlassen alle in Ihrem Team, sich auf einen Stil zu einigen (andernfalls ist eine Neuformatierung ohnehin sinnlos), und lassen sie sich alle im Verlauf ihrer anderen Arbeit um die Neuformatierung kümmern. Nach einer Weile haben Sie den größten Teil des Codes abgedeckt, ohne den Rest des Projekts zu stören.

Caleb
quelle
1

Es gibt zwei mögliche Ansätze, die ich dafür gesehen habe.

1. Formatieren Sie den Code beim Festschreiben neu

Das Ändern von Code nach dem Einreichen ist zwar anfangs haarsträubend, aber wenn Ihr Neuformatierungsverfahren (z. B. Stil ) den Code nicht beeinträchtigt , ist es eine sichere Operation. Mit der Zeit wird das gesamte Team zu schätzen wissen, dass der gesamte Code letztendlich gleich aussieht. Umfassende Unit- / Automatisierungstests stellen sicher, dass nichts kaputt geht.

2. Einmalige Neuformatierung des gesamten Codes

Dies ist meiner Erfahrung nach gefährlicher und erschwert die Verfolgung von Problemen über den gesamten Urknall hinweg, ist aber möglich. Das anschließende Ausführen aller Tests ist unerlässlich. Bei der Codierung dreht sich der Großteil der Unterschiede um die Verwendung von Leerzeichen - Einrückungen oder Zeilenumbrüchen. Einem anständigen Merge-Tool sollte gesagt werden können, dass es alle Whitespace-Unterschiede ignorieren soll. Dies hilft also beim Zusammenführen.

JBRWilkinson
quelle
1
Würde Option 1 beim Einschalten nicht schnell über den größten Teil der Codebasis wellen, was zu dem gleichen großen Knall führen würde, dass jede Datei geändert wird?
Unterzeichnen Sie den
@Sign: Genau mein Punkt - Wenn sich der Commit-Haken ändert, kann sich Ihr Verlauf in etwas fast Nutzloses verschlechtern. Eine Formatierung, die die Funktionalität nicht ändert, sollte kein Commit sein, sondern im gesamten Codeverlauf transplantiert werden.
l0b0
1
Wenn die IDE es unterstützt, gibt es auch 3) das IDE-Autoformat beim Speichern. Verwenden Sie dann überall die gleichen Einstellungen. Dies ist am einfachsten, wenn Sie die Standardeinstellung für die IDE verwenden.
Ich habe beide Ansätze gemacht. Der erste Ansatz ist sehr aufdringlich, da sich jedes Mal, wenn eine neue Datei zum ersten Mal festgeschrieben wird, eine Menge Änderungen ergeben. Der zweite Ansatz ist für das Team besser, als würde man einen Pflasterstein schnell abzocken.
Druska