2011-01-11 3 views
2

Was ist der beste Weg, um eine Geschichte von funktionierenden Versionen Ihres Git-Repository zu pflegen?git Workflow: eine Geschichte von funktionalen Commits pflegen

Es ist so einfach zu verzweigen und in Git zusammenzuführen, dass wir es die ganze Zeit tun. Ich habe mich im Allgemeinen mit Themenzweigen beschäftigt, die erst dann zum Master werden, wenn eine Funktion abgeschlossen ist. Dies funktioniert gut, aber nach mehreren Iterationen ist der Verlauf Ihres Master-Zweigs ein verschachteltes Diagramm und es wird sehr schwierig, Commits zu identifizieren, die eine korrekt funktionierende Version Ihrer Anwendung zu einem beliebigen Zeitpunkt darstellen.

Ich bin auf der Suche nach einem Ratschlag für einen Workflow, der es mir ermöglicht, eine funktionierende Kopie meines Repos, die einem bestimmten Datum am nächsten ist, einfach wiederzufinden (d. H. Nicht in der Mitte der Entwicklung eines Features). Eine weitere nützliche Funktion wäre das Abrufen einer Liste von Commits, die ein funktionierendes Repository repräsentieren, das sich im Laufe der Zeit ändert.

Ich weiß, dass dies manuell erledigt werden könnte, d. H. Das Commit-Protokoll und die Nachrichten untersuchen, um das letzte Commit zu finden, bevor das nächste Feature gestartet wurde, oder indem die Testsuite für jedes Commit und Filter ausgeführt wird. Diese Methoden wären einigermaßen zuverlässig, aber ich suche nach einer weniger willkürlichen Methode.

+0

Letztendlich bist du es, der git sagt, ob ein Commit funktioniert oder nicht; Sie könnten Hooks verwenden, um zu versuchen, sich daran zu erinnern, diese Informationen in Commit-Nachrichten aufzunehmen, vielleicht? Aber irgendwann wirst du es notieren müssen. (Sie könnten auch Notizen verwenden, wenn Ihnen das besser gefällt.) – Cascabel

Antwort

4

Sie können git log --first-parent master verwenden, um einen Verlauf des Masters zu sehen, der nur dem ersten Elternteil jedes Commits folgt. Das bedeutet, dass bei einer Zusammenführung nur der erste übergeordnete Code (der die vorherige Festschreibung im Master sein sollte) gefolgt wird und der zweite übergeordnete Code (der letzte Festschreibung in der Zweigverzweigung) ignoriert wird. Bei Ihrem Workflow wird dies wahrscheinlich hauptsächlich aus Zusammenführungen bestehen. Der wichtige Punkt ist, solange ein Commit (oder ein Merge), das auf dem Master gemacht wird, als eine funktionierende Version betrachtet wird, dann ist jedes einzelne Commit in diesem Protokoll eine funktionierende Version.

+1

+1 für die Wartung des Masters, wie immer funktioniert. Etwas wie Gerrit könnte dazu beitragen, das sicherzustellen. – Thilo

+0

Scheint wie eine Teillösung. Bei der Zusammenführung hat es oft keine Commits in der Hauptzweig seit der letzten Zusammenführung gegeben, so dass es überhaupt kein Merge-Commit geben wird. Aber diese Lösung ist besser als keine. –

+0

In diesem Fall können Sie eine Richtlinie für die Verwendung von "--no-ff" beim Zusammenführen erzwingen, um immer ein Zusammenführungs-Commit zu erzeugen. –

0

Ich bin Super froh, Sie zu hören Feature Zweig mit - gehen Sie

Danach :) gibt es zwei Möglichkeiten, die Dinge ordentlich zu halten, und eine Sache, die Ihr Gehirn besser arbeiten hilft nur.

1) Erstellen Sie für jede Zweigstelle, an der Sie aktiv arbeiten, eine lokale Zweigstelle. Sie möchten dies tun, weil Sie in der Lage sein möchten, das, was alle anderen tun, neu zu setzen. Ohne die Rebase haben Sie eine Reihe von Commits, die Merges darstellen, die dem Verlauf nichts hinzufügen. Sie können die Verzweigung, die remote ist, neu erstellen, aber dies wird abgeraten, da das Umbasieren den Verlauf neu schreibt, und sollten es zwei Personen gleichzeitig tun - es wird haarig und wirklich schwer zu folgen. Früh in Projekten arbeite ich normalerweise nur von master. Also erstelle ich eine master_local, die nichts verfolgt (git branch master_local). Wenn Leute Änderungen vornehmen, die ich will oder brauche (git pull), während ich master_local ausgecheckt habe, nur Rebase (git rebase master).

Und der Tipp, um Ihr Gehirn gut funktionieren zu lassen - fusionieren Sie Ihren lokalen Zweig oft in den Tracking/Remote-Feature-Zweig. Je länger Sie die Dinge getrennt halten, desto mehr müssen Sie sich erinnern, je größer Ihre Zusammenführung sein wird, desto mehr beschweren sich andere darüber, dass Sie nicht arbeiten, usw.;)

2) Wenn Sie große Funktionen haben und viele Leute, Sie werden Tonnen von Commits pro Feature-Zweig haben. Sobald diese Funktionen bereit sind, Sie zu meistern, müssen Sie nicht alles sehen. Und wenn Sie die Funktion zurücksetzen möchten, möchten Sie nicht mehrere hundert Patches wiederherstellen. Die Antwort auf all das ist, Ihre Commits auf 1 Single Commit zu reduzieren. Auf diese Weise ist Master eine nette und kurze Liste der darin enthaltenen Features. (http://www.gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html)

+0

Ihre Antwort ist also immer Squash Commits, also kein Commit in der Geschichte von Master verlässt die App in einem nicht funktionierenden Zustand *? –

+1

Squash-Commits sind nicht als normale Methode zum Zusammenführen in Zweigstellen geeignet. Was damit zu tun hat, ist die Geschichte des Themenzweiges komplett wegzuwerfen. Eine solche Geschichte ist nicht nur interessant, sondern kann später auch sehr nützlich sein, besonders wenn Sie einen Fehler finden müssen oder wenn Sie einen Konflikt mit einem anderen Themenzweig haben. –

+0

Übrigens, # 1 scheint das Rad neu zu erfinden, git hat bereits Unterstützung für lokale Niederlassungen, die entfernte verfolgen. h. Sie haben 'Master', das lokal ist, und' origin/master' wird automatisch eingerichtet, um den entfernten Zweig zu verfolgen. 'git fetch' aktualisiert die Remote-Zweige,' git rebase origin/master' refinanziert Ihren lokalen Master auf den Remote-Zweig. –

0

Ich denke, die beste Lösung (langfristig) wäre, Ihren Workflow anzupassen, um Ihre Master-Filiale von Zwischen-Checkpoint-Commits sauber zu halten. Benjamin Sandofsky details a workflow scheint am ehesten der Art und Weise zu entsprechen, wie Git entworfen wurde.

Der Kern des Artikels:

Denken Sie an Filialen in zwei Kategorien unterteilt: öffentlich und privat.

Öffentliche Zweige sind die maßgebliche Geschichte des Projekts. In einer öffentlichen Zweigstelle sollte jedes Commit kurz und bündig sein und über eine gut dokumentierte Commit-Nachricht verfügen. Es sollte so linear wie möglich sein. Es sollte unveränderlich sein. Öffentliche Zweige umfassen Master- und Release-Zweige. Eine private Niederlassung ist für Sie. Es ist Ihr Scratch-Papier, während Sie ein Problem lösen.

Die No-ff-Band-Hilfe, gebrochene Halbierung, und Schuld Mysterien sind alle Symptome, dass Sie einen Schraubenzieher als Hammer verwenden.

Sie sollten niemals eine private Niederlassung direkt in eine öffentliche Niederlassung mit einer Vanilla-Zusammenführung zusammenführen. Bereinigen Sie zuerst Ihre Branche mit Tools wie Reset, Rebase, Squash-Merges und Commit-Änderung. Wenn Sie Ihre öffentliche Geschichte als unverfälscht behandeln, sind schnelle Zusammenführungen nicht nur sicher, sondern auch vorzuziehen. Sie behalten die Revisionshistorie linear und einfacher zu verfolgen.

Behandeln Sie die öffentliche Geschichte als unveränderlich, atomar und leicht zu folgen. Behandle private Geschichte als wegwerfbar und formbar.

Die beabsichtigte Workflow ist:

  1. Erstellen Sie eine private abzweigen einem öffentlichen Zweig.
  2. Verpflichten Sie regelmäßig Ihre Arbeit zu dieser privaten Niederlassung.
  3. Sobald Ihr Code perfekt ist, bereinigen Sie seine Geschichte.
  4. Verbinden Sie den bereinigten Zweig wieder mit der öffentlichen Verzweigung.