Wie wähle ich eine einzelne Revision in Mercurial aus?

70

Was ist in Mercurial / TortoiseHg anhand des folgenden Beispiels der einfachste Weg, die Revision "G" in Repo A zusammenzuführen, ohne D, E und F zu nehmen (Angenommen, G ist nicht von D, E oder F abhängig).

Repo A: A - B - C

Repo B (Clone of A) A - B - C - D - E - F - G

Ist ein Patch die beste Wahl?

Tom Hubbard
quelle
36
Es ist keine Verschmelzung, es ist eigentlich Kirschernte, das beste Werkzeug dafür ist meiner Meinung nach eine Transplantation. Aber Patch würde auch funktionieren.
Tonfa
9
Tonfa, du solltest deine Kommentare beantworten. Sie haben immer Recht und niemand kann Sie jemals abstimmen.
Ry4an Brase
5
@ Ry4n Ich habe manchmal nicht die Zeit, es macht mir nichts aus, nicht upvoted zu werden, wenn es der nächsten Person hilft zu antworten :)
tonfa

Antworten:

78

Tonfa hat recht. Was Sie beschreiben, ist nicht "verschmelzen" (oder "drücken" oder "ziehen"); es ist "Kirschernte". Durch Drücken oder Ziehen werden alle Änderungssätze von einem Repo zu einem anderen verschoben, die noch nicht in diesem Repo enthalten sind. Eine 'Zusammenführung' nimmt zwei 'Köpfe' und führt sie zu einem neuen Änderungssatz zusammen, der die Kombination aus beiden ist.

Wenn Sie G wirklich verschieben müssen, aber möglicherweise D, E, F dort nicht aushalten können, sollten Sie G aus Repo A 'hg exportieren' und dann in Repo A 'hg importieren'. Die Transplant-Erweiterung ist ein Wrapper Export / Import mit einigen Feinheiten, um zu vermeiden, dass derselbe Änderungssatz mehrmals verschoben wird.

Der Nachteil bei der Verwendung von Import / Export, Transplantation und Kirschernte im Allgemeinen ist jedoch, dass Sie sich ohne seine Vorfahren nicht wirklich über G bewegen können, da in Mercurial der Name eines Änderungssatzes sein "Hashid" ist, das die Hashids seiner Eltern enthält . Unterschiedliche Eltern (Gs neuer Elternteil wäre C und nicht F) bedeuten ein anderes Hashid, also ist es nicht mehr G - es ist die Arbeit von G, sondern ein neuer Änderungssatz mit Namen.

Sich als etwas Neues über G zu bewegen, nennen wir es G '(Gee prime), ist für einige Anwendungen keine große Sache, für andere ist es eine große Pita. Wenn Repo B bald ein neues Änderungsset erhält, ändert sich H, und Sie möchten es über das übergeordnete Element verschieben, von G zu G ', die unterschiedliche Hashes haben. Das bedeutet, dass H als H '- 100 Änderungssätze auf der ganzen Linie übergeht und Sie für alles verschiedene Hashhids haben, weil Sie es nicht ertragen konnten, D, E, F in Repo A zu haben.

Die Dinge werden noch schlimmer, wenn Sie Sachen von Repo A nach Repo B verschieben möchten (die entgegengesetzte Richtung Ihres früheren Zuges). Wenn Sie versuchen, einen einfachen 'hg-Push' von A nach B durchzuführen, erhalten Sie G '(und H' und nachfolgende Nachkommen), die Duplikate der Änderungssätze sind, die Sie bereits in Repo B haben.

Was sind dann Ihre Optionen?

  1. Ist mir egal. Ihre Daten sind immer noch da. Sie haben nur die gleichen Änderungssätze mit unterschiedlichen Namen und arbeiten mehr am zukünftigen Austausch zwischen den beiden Repos. Es ist nicht falsch, es ist vielleicht nur ein bisschen ungeschickt, und einige Leute kümmern sich nicht darum.
  2. Verschieben Sie alle D, E und F auf Repo A. Sie können alle Änderungssätze verschieben, wenn sie harmlos sind, und den ganzen Ärger vermeiden. Wenn sie nicht so harmlos sind, können Sie sie verschieben und dann ein "hg backout" durchführen, um die Auswirkungen von D, E und F in einem neuen Änderungssatz H rückgängig zu machen.
  3. Geben Sie G zunächst eine bessere Abstammung. Es ist gemein für mich, dies zu erwähnen, weil es zu spät ist, diesen Weg zu gehen (ohne den Verlauf zu bearbeiten ). Was Sie hätten tun sollen , bevor Sie an Änderungssatz G gearbeitet haben, war zu hg update C. Wenn G sich nicht auf die Änderungssätze D, E und F verlässt oder diese benötigt, sollte es nicht ihr Kind sein.

Wenn Sie stattdessen zuerst auf C aktualisieren, erhalten Sie ein Diagramm wie das folgende:

A - B - C - D - E - F
          \
            G

dann wäre die ganze Antwort auf diese Frage einfach hg push -r G ../repoAund G würde sauber übergehen und den gleichen Hash verbergen, und D, E und F würden nicht dazu passen.

AKTUALISIEREN:

Wie in den Kommentaren ausgeführt. Bei modernen Mercurials ist der hg graftBefehl der perfekte Weg, dies zu tun.

Ry4an Brase
quelle
4
Die Verwendung von Rebase ist eine Form der 'Bearbeitung des Verlaufs'. Es verändert die Hashids, was absolut cool ist, wenn Sie sie noch nicht in die Welt hinausgeschoben haben. Wenn Sie dies getan haben, werden alle zweimal die gleichen Änderungssätze usw. sehen
Ry4an Brase
7
Ich möchte darauf hinweisen, dass seit Mercurial 2.0 das Transplantat nach Möglichkeit anstelle der Transplantation verwendet werden sollte, da es die interne Zusammenführungsmaschinerie verwendet, anstatt Konflikte abzulehnen. Siehe auch stackoverflow.com/a/8010738/67988 .
Helgi
Bin ich der einzige, der der Meinung ist, dass der Ton dieser Antwort darauf hindeutet, dass das Pflücken von Kirschen etwas ist, das niemals getan werden sollte? Was sollen Sie tun, wenn Sie zwei Commits im falschen Zweig ausführen und diese Commits verschieben müssen? Das Kirschpflücken ist genau dafür ausgelegt. Es ist nicht falsch.
Jason McCarrell
3
Der Ton sagt "Kirschernte sollte nicht Teil Ihres normalen Arbeitsablaufs sein". In Ihrem Beispiel beheben Sie einen Fehler ("auf dem falschen Ast"), also auf jeden Fall Kirschpickel. Aber Leute, die komplexe Workflows erstellen, in denen der Plan lautet "und dann die Fehlerbehebungen von der Standardeinstellung in den stabilen Release-Zweig auswählen", tun die Dinge auf die harte Tour und werden ihre zukünftigen Zusammenschlüsse noch schwieriger machen. Eine Antwort mit dem Hinweis "Was Sie fragen, wie es zu tun ist, ist normalerweise eine schlechte Idee" ist wertvoll, bevor sie Ihnen sagt, wie es geht.
Ry4an Brase
dort solltest du G aus Repo A 'hg exportieren' - @ Ry4anBrase meinst du aus Repo B?
crazyGuy
43

In Bezug auf den Titel, der sich mit Kirschernte im Allgemeinen befasst, gebe ich das Beispiel der Arbeit in einem Repo, da Internet-Suchmaschinen Leute hierher bringen könnten, um Kirsche zu pflücken. Wenn Sie in einem Repository arbeiten, geschieht dies mit hg graft:

hg update C
hg graft G

Das Ergebnis ist:

            G'
          / 
A - B - C - D - E - F - G

Zusätzliche Warnung: Die beiden Änderungssätze werden als unabhängige, parallele Festschreibungen für dieselben Dateien behandelt und können zu Zusammenführungskonflikten führen. Aus diesem Grund sollte das Kirschpflücken für die Zweigstellenverwaltung generell vermieden werden. Zum Beispiel, wenn Gein Bug - Fix auf einen stabile Version Zweig angewandt merkten wie 1.0.1, sollten Sie eher fusionieren den freezeZweig mit ihm, und von Zeit zu Zeit merge den masterZweig mit der freezeFehlerbehebung Niederlassung.

Iodnas
quelle
Mit der Ausnahme, dass 'hg transplant G' viele der Änderungen in D, E und F mit sich bringt. Das Exportieren von Patches und Import-Patches funktioniert so, wie man es von Transplantaten erwarten würde.
LovesTha
'hg transplant G' auf C erzeugt einen neuen Kopf / Zweig. Warum kann es Ihrer Meinung nach zu Änderungen in der D ... G-Branche kommen?
Iodnas
Weil ich es mehrmals versucht habe und es tut. Ich möchte wirklich, dass es nicht so ist, aber es tut es.
LovesTha