Heim >Entwicklungswerkzeuge >Idiot >Detaillierte Analyse von Git-Merge (organisiert und geteilt)
Dieser Artikel bringt Ihnen relevantes Wissen über Git, das hauptsächlich die damit verbundenen Probleme von git-merge vorstellt. Ich hoffe, dass der Befehl git-merge zum Zusammenführen von den angegebenen Commits mit dem aktuellen Zweig verwendet wird.
Empfohlene Studie: „Git Tutorial“
Im Befehl git-merge gibt es die folgenden drei Parameter:
git merge [-n] [-- stat] [--no-commit] [--squash] [--[no-]edit] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>] ] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]
git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]
git merge <msg> HEAD <commit>...
git merge --abort
git-merge命令是用于从指定的commit(s)合并到当前分支的操作。
注:这里的指定commit(s)是指从这些历史commit节点开始,一直到当前分开的时候。
git-merge命令有以下两种用途:
那么git merge topic
命令将会把在master分支上二者共同的节点(E节点)之后分离的节点(即topic分支的A B C节点)重现在master分支上,直到topic分支当前的commit节点(C节点),并位于master分支的顶部。并且沿着master分支和topic分支创建一个记录合并结果的新节点,该节点带有用户描述合并变化的信息。
git merge <msg> HEAD <commit>...
命令该命令的存在是由于历史原因,在新版本中不应该使用它,应该使用git merge -m <msg> <commit>....
进行替代
git merge --abort
命令该命令仅仅在合并后导致冲突时才使用。git merge --abort
将会抛弃合并过程并且尝试重建合并前的状态。但是,当合并开始时如果存在未commit的文件,git merge --abort
在某些情况下将无法重现合并前的状态。(特别是这些未commit的文件在合并的过程中将会被修改时)
警告:运行
git-merge
时含有大量的未commit文件很容易让你陷入困境,这将使你在冲突中难以回退。因此非常不鼓励在使用git-merge
时存在未commit的文件,建议使用git-stash
命令将这些未commit文件暂存起来,并在解决冲突以后使用git stash pop
把这些未commit文件还原出来。
本部分用于介绍git-merge
命令中使用的参数
--commit
和--no-commit
--commit
参数使得合并后产生一个合并结果的commit节点。该参数可以覆盖--no-commit
。--no-commit
参数使得合并后,为了防止合并失败并不自动提交,能够给使用者一个机会在提交前审视和修改合并结果。
--edit
和-e
以及--no-edit
--edit
和-e
用于在成功合并、提交前调用编辑器来进一步编辑自动生成的合并信息。因此使用者能够进一步解释和判断合并的结果。--no-edit
参数能够用于接受自动合并的信息(通常情况下并不鼓励这样做)。
如果你在合并时已经给定了
-m
参数(下文介绍),使用--edit
(或-e
)依然是有用的,这将在编辑器中进一步编辑-m
所含的内容。
旧版本的节点可能并不允许用户去编辑合并日志信息。
--ff
命令--ff
是指fast-forward命令。当使用fast-forward模式进行合并时,将不会创造一个新的commit节点。默认情况下,git-merge
采用fast-forward模式。
关于fast-forward模式的详细解释,请看我的另一篇文章:一个成功的Git分支模型的“关于fast forward”一节。
--no-ff
命令即使可以使用fast-forward模式,也要创建一个新的合并节点。这是当git merge
在合并一个tag时的默认行为。
--ff-only
git merge <msg> commit>...
git merge --abort
1.2 Einführung in git-merge
🎜Der Befehl git-merge wird verwendet to Der Vorgang des Zusammenführens der angegebenen Commits in den aktuellen Zweig. 🎜🎜Hinweis: Die hier angegebenen Commits beziehen sich auf den Beginn von diesen historischen Commit-Knoten bis zur aktuellen Trennung. 🎜🎜Der Befehl git-merge hat die folgenden zwei Verwendungszwecke: 🎜
git merge topic
den gemeinsamen Knoten (E-Knoten) zusammen, der danach getrennt wird (d. h. die A-B-C-Knoten). des Topic-Zweigs) erscheinen bis zum aktuellen Commit-Knoten des Topic-Zweigs (C-Knoten) wieder im Master-Zweig und befinden sich oben im Master-Zweig. Und erstellen Sie einen neuen Knoten entlang des Hauptzweigs und des Themenzweigs, um die Zusammenführungsergebnisse aufzuzeichnen. Dieser Knoten enthält die Informationen des Benutzers, die die Zusammenführungsänderungen beschreiben. 🎜🎜1.3git merge <msg>...
-Befehl 🎜🎜Die Existenz dieses Befehls ist auf historische Gründe zurückzuführen. Er sollte in der neuen Version nicht verwendet werden Verwenden Sie git merge -m <msg> <commit>....
, um den Befehl 🎜🎜1.4git merge --abort
zu ersetzen. Dieser Befehl verursacht erst danach Konflikte Verwendung zusammenführen. git merge --abort
bricht den Zusammenführungsprozess ab und versucht, den Zustand vor dem Zusammenführen wiederherzustellen. Wenn jedoch zu Beginn der Zusammenführung nicht festgeschriebene Dateien vorhanden sind, kann git merge --abort
in einigen Fällen den Status vor der Zusammenführung nicht reproduzieren. (Vor allem, wenn diese nicht festgeschriebenen Dateien während des Zusammenführungsvorgangs geändert werden) 🎜🎜Warnung: Das Ausführen von🎜2. Parameter🎜🎜In diesem Abschnitt werden die im Befehlgit-merge
mit einer großen Anzahl nicht festgeschriebener Dateien kann leicht zu Problemen führen, die dazu führen Es fällt Ihnen schwer, in einem Konflikt zurückzuweichen. Daher wird dringend davon abgeraten, nicht festgeschriebene Dateien zu verwenden, wenn Siegit-merge
verwenden. Es wird empfohlen, den Befehlgit-stash
zu verwenden, um diese nicht festgeschriebenen Dateien vorübergehend zu speichern und die Konflikte zu lösen . Verwenden Siegit stash pop
, um diese nicht festgeschriebenen Dateien wiederherzustellen. 🎜
git-merge
verwendeten Parameter vorgestellt🎜🎜2.1--commit
und – Der Parameter no-commit
🎜🎜--commit
bewirkt, dass nach dem Zusammenführen ein Commit-Knoten des zusammengeführten Ergebnisses generiert wird. Dieser Parameter kann --no-commit
überschreiben. 🎜Der Parameter --no-commit
bewirkt, dass die Zusammenführung nicht automatisch übermittelt wird, um zu verhindern, dass die Zusammenführung fehlschlägt, und gibt dem Benutzer die Möglichkeit, die Zusammenführungsergebnisse vor der Übermittlung zu überprüfen und zu ändern. 🎜🎜2.2 --edit
und -e
und --no-edit
🎜🎜--edit
und -e wird verwendet, um den Editor aufzurufen, um die automatisch generierten Zusammenführungsinformationen vor der erfolgreichen Zusammenführung und Übermittlung weiter zu bearbeiten. Daher können Benutzer die Ergebnisse der Fusion weiter interpretieren und beurteilen. 🎜Der Parameter --no-edit
kann verwendet werden, um automatisch zusammengeführte Informationen zu akzeptieren (davon wird generell abgeraten). 🎜🎜Wenn Sie beim Zusammenführen den Parameter-m
angegeben haben (unten beschrieben), verwenden Sie--edit
(oder-e
) ist immer noch nützlich, wodurch der in-m
enthaltene Inhalt im Editor weiter bearbeitet wird. 🎜
🎜Ältere Versionen von Knoten erlauben es Benutzern möglicherweise nicht, Zusammenführungsprotokollinformationen zu bearbeiten. 🎜🎜2.3
--ff
-Befehl 🎜🎜--ff
bezieht sich auf den Schnellvorlaufbefehl. Beim Zusammenführen im Schnellvorlaufmodus wird kein neuer Commit-Knoten erstellt. Standardmäßig verwendet git-merge
den Schnellvorlaufmodus. 🎜 Eine ausführliche Erklärung des Schnellvorlaufmodus finden Sie in meinem anderen Artikel: Abschnitt „Über den Schnellvorlauf“ eines erfolgreichen Git-Zweigmodells. 🎜🎜2.4 --no-ff
-Befehl 🎜🎜Erstellen Sie einen neuen Zusammenführungsknoten, auch wenn der Schnellvorlaufmodus verwendet werden kann. Dies ist das Standardverhalten, wenn git merge
ein Tag zusammenführt. 🎜🎜2.5--ff-only
-Befehl🎜🎜Es sei denn, der aktuelle HEAD-Knoten ist aktuell (aktualisiert, um auf den neuesten Knoten zu verweisen) oder kann im Schnellvorlaufmodus zusammengeführt werden Die Zusammenführung wird abgelehnt und gibt einen Fehlerstatus zurück. 🎜--log[=<n>]
und --no-log
--log[=<n>]
和 --no-log
--log[=<n>]
将在合并提交时,除了含有分支名以外,还将含有最多n个被合并commit节点的日志信息。--no-log
并不会列出该信息。
--stat
, -n
, --no-stat
命令--stat
参数将会在合并结果的末端显示文件差异的状态。文件差异的状态也可以在git配置文件中的merge.stat配置。
相反,-n
, --no-stat
参数将不会显示该信息。
--squash
和--no-squash
--squash
当一个合并发生时,从当前分支和对方分支的共同祖先节点之后的对方分支节点,一直到对方分支的顶部节点将会压缩在一起,使用者可以经过审视后进行提交,产生一个新的节点。
注意1:该参数和
--no-ff
冲突
注意2:该参数使用后的结果类似于在当前分支提交一个新节点。在某些情况下这个参数非常有用,例如使用Git Flow时(关于Git Flow,请参考:一个成功的Git分支模型),功能分支在进行一个功能需求的研发时,开发者可能在本地提交了大量且无意义的节点,当需要合并到develop分支时,可能仅仅需要用一个新的节点来表示这一长串节点的修改内容,这时
--squash
命令将会发挥作用。此外,如果功能分支的多次提交并不是琐碎而都是有意义的,使用--no-ff
命令更为合适。--no-squash
的作用正好相反。
-s <strategy>
和 --strategy=<strategy>
-s <strategy>
和 --strategy=<strategy>
用于指定合并的策略。默认情况如果没有指定该参数,git将按照下列情况采用默认的合并策略:
-X <option>
和 --strategy-option=<option>
在-s <strategy>
时指定该策略的具体参数(下文介绍)。
--verify-signatures
, --no-verify-signatures
用于验证被合并的节点是否带有GPG签名,并在合并中忽略那些不带有GPG签名验证的节点。
(以下引用摘自一篇转载的文章,由于我没有找到原作者,因此无法提供原作者信息和原文链接,如果有所侵权请私信或者评论告知,我将删除以下引用内容。)
GPG是加密软件,可以使用GPG生成的公钥在网上安全的传播你的文件、代码。
为什么说安全的?以Google所开发的repo为例,repo即采用GPG验证的方式,每个里程碑tag都带有GPG加密验证,假如在里程碑v1.12.3处你想要做修改,修改完后将这个tag删除,然后又创建同名tag指向你的修改点,这必然是可以的。但是,在你再次clone你修改后的项目时,你会发现,你对此里程碑tag的改变不被认可,验证失败,导致你的修改在这里无法正常实现。这就是GPG验证的作用,这样就能够保证项目作者(私钥持有者)所制定的里程碑别人将无法修改。那么,就可以说,作者的代码是安全传播的。
为什么会有这种需求?一个项目从开发到发布,再到后期的更新迭代,一定会存在若干的稳定版本与开发版本(存在不稳定因素)。作为项目发起者、持有者,有权定义他(们)所认可的稳定版本,这个稳定版本,将不允许其他开发者进行改动。还以Google的repo项目为例,项目所有者定义项目开发过程中的点A为稳定版v1.12.3,那么用户在下载v1.12.3版本后,使用的肯定是A点所生成的项目、产品,就算其他开发者能够在本地对v1.12.3进行重新指定,指定到他们修改后的B点,但是最终修改后的版本给用户用的时候,会出现GPG签名验证不通过的问题,也就是说这样的修改是不生效的。
—summary
,--no-summary
和--stat
与 --no-stat
相似,并将在未来版本移除。
-q
和 --quiet
静默操作,不显示合并进度信息。
-v
和 --verbose
--log[=<n>]
Beim Zusammenführen und Senden enthält es zusätzlich zum Zweignamen auch die Protokollinformationen von bis zu n zusammengeführten Festschreibungsknoten. --no-log
listet diese Informationen nicht auf. 2.6 --stat
, -n
, --no-stat
Befehl 🎜🎜--stat
Parameter Der Status der Dateiunterschiede wird am Ende des zusammengeführten Ergebnisses angezeigt. Der Status von Dateiunterschieden kann auch in merge.stat in der Git-Konfigurationsdatei konfiguriert werden. -n
und --no-stat
diese Informationen nicht an. 🎜🎜2.7 --squash
und --no-squash
🎜🎜--squash
Wenn eine Zusammenführung erfolgt, verzweigen Sie vom aktuellen Zweig und dem Anderer Zweig Der andere Zweigknoten nach dem gemeinsamen Vorfahrenknoten und der oberste Knoten des anderen Zweigs werden zusammen komprimiert. Der Benutzer kann ihn nach der Überprüfung einreichen, um einen neuen Knoten zu generieren. 🎜🎜Hinweis 1: Dieser Parameter steht in Konflikt mit --no-ff
🎜
🎜Hinweis 2: Das Ergebnis der Verwendung dieses Parameters ähnelt dem Senden eines neuen Parameters der aktuelle Zweigknoten. Dieser Parameter ist in einigen Fällen sehr nützlich, beispielsweise bei der Verwendung von Git Flow (Informationen zu Git Flow finden Sie unter: Ein erfolgreiches Git-Zweigmodell. Wenn der Funktionszweig eine funktionale Anforderung entwickelt, kann der Entwickler eine große Anzahl lokal einreichen). Wenn bedeutungslose Knoten in den Entwicklungszweig eingefügt werden müssen, müssen Sie möglicherweise nur einen neuen Knoten verwenden, um den Änderungsinhalt dieser langen Knotenliste darzustellen. code> Befehl kommt ins Spiel. Wenn außerdem die mehrfachen Übermittlungen des Feature-Zweigs nicht trivial, aber sinnvoll sind, ist die Verwendung des Befehls🎜2.8--no-ff
besser geeignet.--no-squash
macht genau das Gegenteil. 🎜
-s <strategy>
und --strategy=<strategy>
🎜🎜-s <strategy>
und --strategy=<strategy>
werden verwendet, um die Zusammenführungsstrategie anzugeben. Wenn dieser Parameter nicht angegeben ist, verwendet Git standardmäßig die Standard-Merge-Strategie gemäß den folgenden Bedingungen: 🎜-X <option>
und --strategy-option=<option>
🎜🎜 in -s < ;strategy>
gibt die spezifischen Parameter der Strategie an (unten beschrieben). 🎜🎜2.10 --verify-signatures
, --no-verify-signatures
🎜🎜 wird verwendet, um zu überprüfen, ob der zusammengeführte Knoten eine GPG-Signatur hat und wird bei der Zusammenführung ignoriert Diese Knoten ohne GPG-Signaturüberprüfung. 🎜GPG ist eine Verschlüsselungssoftware. Sie können den von GPG generierten öffentlichen Schlüssel verwenden, um Ihre Dateien und Codes sicher im Internet zu verbreiten.🎜2.11
Warum sagen Sie sicher? Nehmen Sie als Beispiel das von Google entwickelte Repo. Jedes Meilenstein-Tag verfügt über eine GPG-Verschlüsselungsüberprüfung. Wenn Sie Änderungen an Meilenstein v1.12.3 vornehmen möchten, ist dies auf jeden Fall möglich Erstellen Sie ein Tag mit demselben Namen, um auf Ihren Änderungspunkt zu verweisen. Wenn Sie Ihr geändertes Projekt jedoch erneut klonen, werden Sie feststellen, dass Ihre Änderungen an diesem Meilenstein-Tag nicht erkannt werden und die Überprüfung fehlschlägt, was dazu führt, dass Ihre Änderungen hier nicht normal implementiert werden. Dies ist die Aufgabe der GPG-Verifizierung, die sicherstellt, dass die vom Projektautor (Inhaber des privaten Schlüssels) festgelegten Meilensteine nicht von anderen geändert werden können. Dann kann man sagen, dass der Code des Autors sicher verbreitet wird.
Warum besteht ein solcher Bedarf? Von der Entwicklung über die Veröffentlichung bis hin zu späteren Update-Iterationen eines Projekts wird es auf jeden Fall eine Reihe stabiler Versionen und Entwicklungsversionen geben (es gibt Instabilitätsfaktoren). Als Projektinitiatoren und -inhaber haben sie das Recht, eine stabile Version zu definieren, die sie anerkennen. Diese stabile Version erlaubt anderen Entwicklern keine Änderungen. Nehmen Sie als Beispiel das Repo-Projekt von Google. Der Projektinhaber definiert Punkt A im Projektentwicklungsprozess als die stabile Version v1.12.3. Nachdem Benutzer die Version v1.12.3 heruntergeladen haben, werden sie definitiv die von Punkt A generierten Projekte und Produkte verwenden. Auch wenn andere Entwickler v1.12.3 lokal neu spezifizieren und an ihrem modifizierten Punkt B angeben können, besteht das Problem, dass die GPG-Signaturüberprüfung fehlschlägt, wenn die modifizierte Version schließlich von Benutzern verwendet wird. Das heißt, dies ist der Fall Die Änderung wird nicht wirksam. 🎜
--summary
, --no-summary
🎜🎜 und --stat
und --no- stat
ist ähnlich und wird in einer zukünftigen Version entfernt. 🎜🎜2.12 -q
und --quiet
🎜🎜Betrieb geräuschlos, es werden keine Informationen zum Zusammenführungsfortschritt angezeigt. 🎜🎜2.13 -v
und --verbose
🎜🎜Detaillierte Informationen zum Zusammenführungsergebnis anzeigen. 🎜--progress
und --no-progress
--progress
和 --no-progress
切换是否显示合并的进度信息。如果二者都没有指定,那么在标准错误发生时,将在连接的终端显示信息。请注意,并不是所有的合并策略都支持进度报告。
-S[<keyid>]
和 --gpg-sign[=<keyid>]
GPG签名。
-m <msg>
设置用于创建合并节点时的提交信息。
如果指定了--log
参数,那么commit节点的短日志将会附加在提交信息里。
--[no-]rerere-autoupdate
rerere即reuse recorded resolution,重复使用已经记录的解决方案。它允许你让 Git 记住解决一个块冲突的方法,这样在下一次看到相同冲突时,Git 可以为你自动地解决它。
--abort
抛弃当前合并冲突的处理过程并尝试重建合并前的状态。
在合并外部分支时,你应当保持自己分支的整洁,否则的话当存在合并冲突时将会带来很多麻烦。
为了避免在合并提交时记录不相关的文件,如果有任何在index所指向的HEAD节点中登记的未提交文件,git-pull和git-merge命令将会停止。
通常情况下分支合并都会产生一个合并节点,但是在某些特殊情况下例外。例如调用git pull命令更新远端代码时,如果本地的分支没有任何的提交,那么没有必要产生一个合并节点。这种情况下将不会产生一个合并节点,HEAD直接指向更新后的顶端代码,这种合并的策略就是fast-forward合并。
除了上文所提到的fast-forward合并模式以外,被合并的分支将会通过一个合并节点和当前分支绑在一起,该合并节点同时拥有合并前的当前分支顶部节点和对方分支顶部节点,共同作为父节点。
一个合并了的版本将会使所有相关分支的变化一致,包括提交节点,HEAD节点和index指针以及节点树都会被更新。只要这些节点中的文件没有重叠的地方,那么这些文件的变化都会在节点树中改动并更新保存。
如果无法明显地合并这些变化,将会发生以下的情况:
MERGE_HEAD
指针被置于其他分支的顶部MERGE_HEAD
。节点树中的文件包含了合并程序运行后的结果。例如三路合并算法会产生冲突。git merge --abort
关于三路合并算法:
三路合并算法是用于解决冲突的一种方式,当产生冲突时,三路合并算法会获取三个节点:本地冲突的B节点,对方分支的C节点,B,C节点的共同最近祖先节点A。三路合并算法会根据这三个节点进行合并。具体过程是,B,C节点和A节点进行比较,如果B,C节点的某个文件和A节点中的相同,那么不产生冲突;如果B或C只有一个和A节点相比发生变化,那么该文件将会采用该变化了的版本;如果B和C和A相比都发生了变化,且变化不相同,那么则需要手动去合并;如果B,C都发生了变化,且变化相同,那么并不产生冲突,会自动采用该变化的版本。最终合并后会产生D节点,D节点有两个父节点,分别为B和C。
当合并一个tag时,Git总是创建一个合并的提交,即使这时能够使用fast-forward模式。该提交信息的模板预设为该tag的信息。额外地,如果该tag被签名,那么签名的检测信息将会附加在提交信息模板中。
当产生合并冲突时,该部分会以<<<<<<<
, =======
和 表示。在
=======
之前的部分是当前分支这边的情况,在=======
-S[<keyid>]
und --gpg-sign[=<keyid>]
GPG-Signatur. 🎜🎜2.16-m <msg>
🎜🎜Legen Sie die Commit-Informationen fest, die beim Erstellen von Zusammenführungsknoten verwendet werden. --log
angegeben ist, wird das Kurzprotokoll des Commit-Knotens an die Commit-Nachricht angehängt. 🎜🎜2.17--[no-]rerere-autoupdate
🎜🎜rerere bedeutet, die aufgezeichnete Auflösung wiederzuverwenden und die aufgezeichnete Lösung wiederzuverwenden. Damit können Sie Git bitten, sich zu merken, wie ein Blockkonflikt gelöst werden soll, sodass Git ihn beim nächsten Mal, wenn Sie denselben Konflikt sehen, automatisch für Sie lösen kann. 🎜🎜2.18--abort
🎜🎜Beenden Sie den aktuellen Prozess zur Bearbeitung von Zusammenführungskonflikten und versuchen Sie, den Zustand vor der Zusammenführung wiederherzustellen. 🎜🎜3. Weitere Konzepte zum Zusammenführen🎜🎜3.1 Erkennung vor dem Zusammenführen🎜🎜Beim Zusammenführen externer Zweige sollten Sie Ihre eigenen Zweige sauber halten, da es sonst bei Zusammenführungskonflikten zu großen Problemen kommt. MERGE_HEAD
Der Zeiger wird über anderen Zweigen platziertMERGE_HEAD
auf. Die Dateien im Knotenbaum enthalten die Ergebnisse der Ausführung des Zusammenführungsprogramms. Beispielsweise kann der Drei-Wege-Merge-Algorithmus zu Konflikten führen. git merge --abort
🎜Ungefähr drei verwenden Straßenzusammenführungsalgorithmus:🎜3.4 Tags zusammenführen🎜🎜Beim Zusammenführen eines Tags erstellt Git immer einen zusammengeführten Commit, auch wenn der Schnellvorlaufmodus verwendet werden kann. Die Vorlage der Übermittlungsinformationen ist auf die Informationen des Tags voreingestellt. Wenn das Tag signiert ist, werden außerdem Informationen zur Signaturerkennung an die Commit-Nachrichtenvorlage angehängt. 🎜🎜3.5 Wie Konflikte ausgedrückt werden🎜🎜Wenn ein Zusammenführungskonflikt auftritt, wird dieser Teil mit
Der Drei-Wege-Zusammenführungsalgorithmus ist eine Möglichkeit, Konflikte zu lösen. Wenn ein Konflikt auftritt, erhält der Drei-Wege-Zusammenführungsalgorithmus drei Knoten: den B-Knoten des lokalen Konflikts und den C-Knoten des anderer Zweig und der B-Knoten des anderen Zweigs, der gemeinsame nächste Vorfahrknoten A von Knoten C. Der Drei-Wege-Zusammenführungsalgorithmus führt die Zusammenführung basierend auf diesen drei Knoten durch. Der spezifische Prozess besteht darin, die Knoten B und C mit dem Knoten A zu vergleichen. Wenn eine Datei in Knoten B und C mit der in Knoten A übereinstimmt, liegt kein Konflikt vor, wenn sich nur einer von B oder C im Vergleich zum Knoten geändert hat A, dann übernimmt die Datei die geänderte Version; wenn sich B und C im Vergleich zu A geändert haben und die Änderungen nicht identisch sind, müssen Sie sie manuell zusammenführen, wenn sich B und C geändert haben und die Änderungen gleich sind , dann entsteht kein Konflikt und die geänderte Version wird automatisch übernommen. Nach der endgültigen Fusion wird ein D-Knoten generiert. Der D-Knoten hat zwei übergeordnete Knoten, nämlich B und C. 🎜
<<<<<<<
, ==== markiert == ==
und
. Der Teil vor ========
ist die Situation im aktuellen Zweig und der Teil nach =======
ist die Situation im anderen Zweig Seitenzweig. 🎜🎜3.6 So lösen Sie Konflikte🎜🎜Nachdem Sie den Konflikt gesehen haben, können Sie die folgenden zwei Methoden wählen:🎜git merge --abort
verwendet. git merge --abort
用于这种情况。git add
加入到index中,然后使用git commit
产生合并节点。git mergetool
将会调用一个可视化的合并工具来处理冲突合并。git diff
将会显示三路差异(三路合并中所采用的三路比较算法)。git log --merge -p <path>
将会显示HEAD
版本和MERGE_HEAD
版本的差异。git show :1:文件名
显示共同祖先的版本,git show :2:文件名
显示当前分支的HEAD版本,git show :3:文件名
显示对方分支的MERGE_HEAD
版本。Git可以通过添加-s参数来指定合并的策略。一些合并策略甚至含有自己的参数选项,通过-X<option>
设置这些合并策略的参数选项。(不要忘记,合并可以在git merge和git pull命令中发生,因此该合并策略同样适用于git pull)。
仅仅使用三路合并算法合并两个分支的顶部节点(例如当前分支和你拉取下来的另一个分支)。这种合并策略遵循三路合并算法,由两个分支的HEAD节点以及共同子节点进行三路合并。
当然,真正会困扰我们的其实是交叉合并(criss-cross merge)这种情况。所谓的交叉合并,是指共同祖先节点有多个的情况,例如在两个分支合并时,很有可能出现共同祖先节点有两个的情况发生,这时候无法按照三路合并算法进行合并(因为共同祖先节点不唯一)。resolve策略在解决交叉合并问题时是这样处理的,这里参考《Version Control with Git》:
In criss-cross merge situations, where there is more than one possible merge basis, the resolve strategy works like this: pick one of the possible merge bases, and hope for the best. This is actually not as bad as it sounds. It often turns out that the users have been working on different parts of the code. In that case, Git detects that it's remerging some changes that are already in place and skips the duplicate changes, avoiding the conflict. Or, if these are slight changes that do cause conflict, at least the conflict should be easy for the developer to handle
这里简单翻译一下:在交叉合并的情况时有一个以上的合并基准点(共同祖先节点),resolve策略是这样工作的:选择其中一个可能的合并基准点并期望这是合并最好的结果。实际上这并没有听起来的那么糟糕。通常情况下用户修改不同部分的代码,在这种情况下,很多的合并冲突其实是多余和重复的。而使用resolve进行合并时,产生的冲突也较易于处理,真正会遗失代码的情况很少。
仅仅使用三路合并算法合并两个分支。和resolve不同的是,在交叉合并的情况时,这种合并方式是递归调用的,从共同祖先节点之后两个分支的不同节点开始递归调用三路合并算法进行合并,如果产生冲突,那么该文件不再继续合并,直接抛出冲突;其他未产生冲突的文件将一直执行到顶部节点。额外地,这种方式也能够检测并处理涉及修改文件名的操作。这是git合并和拉取代码的默认合并操作。
recursive合并策略有以下参数:
该参数将强迫冲突发生时,自动使用当前分支的版本。这种合并方式不会产生任何困扰情况,甚至git都不会去检查其他分支版本所包含的冲突内容这种方式会抛弃对方分支任何冲突内容。
正好和ours相反。
theirs和ours参数都适用于合并二进制文件冲突的情况。
在这种参数下,git merge-recursive
花费一些额外的时间来避免错过合并一些不重要的行(如函数的括号)。如果当前分支和对方分支的版本分支分离非常大时,建议采用这种合并方式。
diff-algorithm=[patience|minimal|histogram|myers]
告知git merge-recursive
使用不同的比较算法。
ignore-space-change
, ignore-all-space
, ignore-space-at-eol
Konflikte lösen. Git markiert den Konflikt, indem Sie ihn mit git add
zum Index hinzufügen und dann mit git commit
einen Merge-Knoten generieren. git mergetool
ruft ein visuelles Zusammenführungstool auf, um widersprüchliche Zusammenführungen zu behandeln. Sehen Sie die Unterschiede. git diff
zeigt Drei-Wege-Unterschiede an (der Drei-Wege-Vergleichsalgorithmus, der bei Drei-Wege-Zusammenführungen verwendet wird).
git log --merge -p <path>
zeigt den Unterschied zwischen der HEAD
-Version und der MERGE_HEAD
-Version an. 🎜Sehen Sie sich die Version vor dem Zusammenschluss an. git show :1:File name
zeigt die gemeinsame Vorgängerversion an, git show :2:File name
zeigt die HEAD-Version des aktuellen Zweigs an, git show :3 :Dateiname
zeigt die MERGE_HEAD
-Version des Zweigs der anderen Partei an. -X<option>
festgelegt werden können. (Vergessen Sie nicht, dass das Zusammenführen sowohl in den Befehlen „git merge“ als auch „git pull“ erfolgen kann, daher gilt diese Zusammenführungsstrategie auch für „git pull“.) 🎜🎜In Situationen mit kreuz und quer verlaufenden Zusammenführungen, in denen es mehr als eine mögliche Zusammenführungsbasis gibt, funktioniert die Auflösungsstrategie So: Wählen Sie eine der möglichen Zusammenführungsbasen und hoffen Sie auf das Beste. Das ist eigentlich nicht so schlimm, wie es sich anhört. In diesem Fall stellt sich heraus, dass die Benutzer an verschiedenen Teilen des Codes gearbeitet haben dass es einige bereits vorhandene Änderungen erneut zusammenführt und die doppelten Änderungen überspringt, um den Konflikt zu vermeiden. Oder, wenn es sich um geringfügige Änderungen handelt, die tatsächlich Konflikte verursachen, sollte der Konflikt zumindest für den Entwickler leicht zu bewältigen sein🎜🎜 Hier ist eine einfache Übersetzung: Im Falle einer Cross-Merge, bei der es mehr als einen Merge-Referenzpunkt (gemeinsamen Vorfahrenknoten) gibt, funktioniert die Auflösungsstrategie wie folgt: Wählen Sie einen der möglichen Merge-Referenzpunkte aus und hoffen Sie, dass dieser der beste ist Ergebnis der Fusion. Das ist eigentlich gar nicht so schlimm, wie es sich anhört. Normalerweise ändern Benutzer verschiedene Teile des Codes. In diesem Fall sind viele Zusammenführungskonflikte tatsächlich redundant und wiederholen sich. Wenn Sie zum Zusammenführen die Auflösung verwenden, sind die erzeugten Konflikte einfacher zu handhaben und es gibt nur sehr wenige Fälle, in denen Code tatsächlich verloren geht. 🎜
git merge-recursive
etwas mehr Zeit, um zu vermeiden, dass unwichtige Zeilen (z. B. Klammern von Funktionen) fehlen. Wenn der Abstand zwischen den Versionszweigen des aktuellen Zweigs und des anderen Zweigs sehr groß ist, wird empfohlen, diese Zusammenführungsmethode zu verwenden. 🎜diff-algorithm=[patience|minimal|histogram|myers]
🎜🎜 weist git merge-recursive
an, einen anderen Vergleichsalgorithmus zu verwenden. 🎜ignore-space-change
, ignore-all-space
, ignore-space-at-eol
🎜🎜gemäß Geben Sie Parameter zur Behandlung von Leerraumkonflikten an. 🎜no-renames
no-renames
关闭重命名检测。
subtree[=<path>]
subtree[=<path>]
Diese Option ist eine erweiterte Form der Teilbaum-Zusammenführungsstrategie, die errät, wie sich die beiden Knotenbäume während des Zusammenführungsprozesses bewegen. Der Unterschied besteht darin, dass der angegebene Pfad zu Beginn der Zusammenführung entfernt wird, sodass bei der Suche nach Teilbäumen andere Pfade abgeglichen werden können. (Einzelheiten zur Teilbaum-Zusammenführungsstrategie finden Sie weiter unten.) 4.3octopusDiese Zusammenführungsmethode wird für mehr als zwei Zweige verwendet, verweigert jedoch die Zusammenführung, wenn Konflikte eine manuelle Zusammenführung erfordern. Diese Zusammenführungsmethode eignet sich besser zum Bündeln mehrerer Zweige und ist auch die Standard-Zusammenführungsstrategie für Zusammenführungen mehrerer Zweige. 4.4oursDiese Methode kann eine beliebige Anzahl von Zweigen zusammenführen, aber das zusammengeführte Ergebnis des Knotenbaums ist immer der widersprüchliche Teil des aktuellen Zweigs. Diese Methode kann beim Ersetzen älterer Versionen sehr effizient sein. Bitte beachten Sie, dass sich diese Methode vom ours-Parameter unter der rekursiven Strategie unterscheidet. 4.5subtreesubtree ist eine modifizierte Version der rekursiven Strategie. Wenn beim Zusammenführen von Baum A und Baum B B ein Teilbaum von A ist, passt sich B zunächst an die Baumstruktur von A an, anstatt denselben Knoten zu lesen. 4.5 ZusammenfassungBei Verwendung der Drei-Wege-Merge-Strategie (bezogen auf die standardmäßige rekursive Strategie), wenn sich eine Datei (oder eine Codezeile) sowohl im aktuellen Zweig als auch im anderen Zweig ändert, später jedoch in einem zurückgesetzt wird der Filialen, Dann wird sich diese Fallback-Änderung in den Ergebnissen widerspiegeln
. Dieser Punkt könnte einige Leute verwirren. Dies liegt daran, dass sich Git während des Zusammenführungsprozesses nur auf den gemeinsamen Vorfahrenknoten und den HEAD-Knoten der beiden Zweige konzentriert und nicht auf alle Knoten der beiden Zweige. Daher betrachtet der Zusammenführungsalgorithmus den zurückgesetzten Teil als „unverändert“, sodass das zusammengeführte Ergebnis zum geänderten Teil des anderen Zweigs wird. 5. Einige persönliche Meinungen zur Verwendung von Git
Ich habe immer geglaubt, dass Git ein sehr hervorragendes Tool zur Versionskontrolle ist, aber viele Leute im Unternehmen finden Git schwierig zu verwenden. Der Grund für diese Situation liegt zum großen Teil darin, dass die Trägheit, die der bisherige Einsatz von Subversion mit sich bringt, Auswirkungen auf die Akzeptanz neuer Technologien hat; andererseits nutzen viele Menschen Git nur über den GUI-Client. Die meisten Leute dachten lange, dass die Verwendung einer grafischen Benutzeroberfläche ein bequemerer Einstieg sei. Tatsächlich ist dies fraglich. Meiner persönlichen Erfahrung nach kann die Verwendung einer grafischen Benutzeroberfläche zu Trägheit führen, und Vorgänge können oft durch Klicken auf ein paar Schaltflächen abgeschlossen werden, was viele Leute denken lässt, dass das Erlernen von Git-Befehlen Zeit- und Energieverschwendung ist. Aber ohne ein klares Verständnis der Git-Befehle und -Ideen wird die Verwendung dieser einfachen Schaltflächen tatsächlich große Probleme verursachen: Viele Leute haben keine Ahnung, was nach dem Klicken auf die Schaltfläche passieren wird, und die GUI ist zu intelligent, um dieselbe Schaltfläche zuzulassen Das Klickereignis kann Befehlen mit unterschiedlichen Parametern entsprechen. Am Ende sind es die armen Benutzer, die wirklich verletzt sind, weil sie keine Ahnung haben, wo das Problem liegt.
Empfohlenes Lernen: „Git Learning Tutorial
“
Das obige ist der detaillierte Inhalt vonDetaillierte Analyse von Git-Merge (organisiert und geteilt). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!