112 Stimmen

Alle Übertragungen aus einem Zweig ziehen, bestimmte Übertragungen in einen anderen Zweig verschieben

Ich habe die folgenden Zweige:

  • master
  • production

und die folgenden entfernten Zweige:

  • origin/master
  • origin/production

Ich habe ein Skript, das die origin/master Zweig und erhält die Differenz der Änderungen gegenüber dem letzten Fetch ( log -p master..origin/master ). Dann führe ich origin/master .

Die gefundenen Übertragungen werden an ein Code-Review-Tool weitergeleitet.

Ich möchte die erfolgreichen Übertragungen - und nur diese - in den Produktionszweig verschieben, und dann natürlich in origin/production .

Wie kann ich das tun?

Außerdem habe ich 2 Skripte laufen: das eine holt von origin/master und die andere, die ich gerade schreibe und die die erfolgreichen Commits pushen soll.

Ich würde gerne diese 2 Skripte laufen lassen und dabei Race Conditions/Fusionskonflikte vermeiden. Da ich nur mit bestimmten Commits arbeiten möchte, gibt es vielleicht eine Möglichkeit, die Commits, die ich nicht möchte, loszuwerden?

347voto

bdonlan Punkte 213545

Ich glaube, der Begriff, den Sie suchen, ist "Rosinenpickerei". Das heißt, man nimmt einen einzelnen Commit aus der Mitte eines Zweiges und fügt ihn einem anderen hinzu:

A-----B------C
 \
  \
   D

wird

A-----B------C
 \
  \
   D-----C'

Dies kann natürlich auch mit dem Befehl git cherry-pick geschehen.

Das Problem bei diesem Commit ist, dass Git bei Commits die gesamte Historie vor dem Commit mit einbezieht - wenn Sie also drei Commits wie diesen haben:

A-----B-----C

Wenn Sie versuchen, B loszuwerden, müssen Sie eine völlig neue Übergabe erstellen, etwa so:

A-----------C'

Wobei C' eine andere SHA-1 ID hat. Ebenso beinhaltet die Auswahl eines Commits von einem Zweig zu einem anderen die Erstellung eines Patches und die anschließende Anwendung, so dass auch auf diese Weise die Historie verloren geht.

Dieses Ändern der Commit-IDs macht unter anderem die Zusammenführungsfunktion von Git kaputt (obwohl es bei sparsamer Verwendung Heuristiken gibt, die dies überspielen). Noch wichtiger ist jedoch, dass funktionale Abhängigkeiten ignoriert werden - wenn C tatsächlich eine in B definierte Funktion verwendet, werden Sie es nie erfahren.

Vielleicht wäre es besser, wenn die Zweige feiner gegliedert wären. Das heißt, anstatt nur einen "Master" zu haben, haben Sie "FeatureA", "BugfixB", usw. Führen Sie die Codeüberprüfung jeweils an einem ganzen Zweig durch - wobei sich jeder Zweig nur auf eine Sache konzentriert - und führen Sie dann diesen einen Zweig zusammen, wenn Sie fertig sind. Das ist der Arbeitsablauf, für den Git konzipiert ist und den es gut kann :)

Wenn Sie darauf bestehen, die Dinge auf der Ebene von Patches zu behandeln, sollten Sie sich darcs ansehen - es betrachtet ein Repository als eine Menge von Patches, und somit wird Cherry Picking zur grundlegenden Operation. Dies hat jedoch seine eigenen Probleme, wie z.B. sehr langsam zu sein :)

Edit: Ich bin mir auch nicht sicher, ob ich Ihre zweite Frage zu den beiden Skripten verstehe. Vielleicht könntest du sie genauer beschreiben, vielleicht als separate Frage, damit es nicht zu verwirrend wird?

1voto

MattJenko Punkte 1198

Ich weiß, dass dies eine alte Frage ist, aber es wird hier darauf verwiesen: Wie man einen bestimmten Commit in Git zusammenführt

Daher eine neuere Antwort: Verwenden Sie Feature-Zweige und Pull-Requests.

So sieht das aus, wobei fA eine Übertragung mit Merkmal A und fB eine Übertragung mit Merkmal B ist:

            fA   fC (bad commit, don't merge)
           /  \ /
master ----A----B----C
                \  /
                 fB

Pull-Requests werden mit der Funktionalität von GitHub in Verbindung gebracht, aber eigentlich meine ich damit nur, dass jemand die Verantwortung hat, die Feature-Zweige in Master zusammenzuführen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X