Fra*_*rot 1 git merge git-merge git-rebase maven
我正在寻找一种方法,使 git对特定文件使用特定的合并策略(我们的/他们的) ,具体取决于我是合并还是重新调整我的功能分支。
让我解释一下:假设我有一个功能分支“fb”,其中更改了文件“.mvn/maven.config”。如果我将 master 合并到“fb”中,我想保留我的文件,因此使用“我们的”策略(我可以在 .gitattributes 文件中定义它)。但是,如果我将“fb”重新设置为 master(而不是合并),我仍然想保留“fb”分支的“.mvn/maven.config”,所以我应该使用“他们的”策略,因为据我了解,merge 和 rebase 之间策略的含义是相反的。
问题是:有没有一种简单的方法来定义智能合并策略?
我已经看到了“git merge driver”的概念,但据我所知,合并驱动程序无法判断它是合并还是变基,因此无法推断是否使用我们的 VS 他们的。
我是否必须告诉我的队友没有解决方案,迫使他们每次都小心谨慎,手动手动选择合适的策略?
注意:我添加了“maven”标签,因为任何使用 git 和 maven 的人在保留 .mvn/maven.config 文件时可能会遇到同样的问题
确实,在变基期间您需要“他们的”。这是因为变基操作实际上是一系列的cherry-pick,并且每个cherry-pick都是一个合并操作,其中您的HEAD
(当前提交)位于目标分支(正在构建)上,而不是指向原始分支上的提交(现在正在复制)。
也就是说,正常的合并如下所示:
\n\n...--o--o--*--o--o <-- yourbranch (HEAD)\n \\\n o--o--o <-- theirbranch\n
Run Code Online (Sandbox Code Playgroud)\n\n你跑git merge theirbranch
; Git 将提交*
\xe2\x80\x94 合并基 \xe2\x80\x94 与您的最终提交进行比较,以了解您做了什么,然后*
与它们的最终提交进行比较,以了解它们做了什么。然后 Git 组合这些更改,将它们全部应用到*
,以生成合并:
...--o--o--*--o--o---M <-- yourbranch (HEAD)\n \\ /\n o--o--o <-- theirbranch\n
Run Code Online (Sandbox Code Playgroud)\n\n如果您提供了.gitattributes
定义的合并驱动程序,则可以让 Git 获取您的.mvn/maven.config
\xe2\x80\x94 版本,但这里有一个巨大的警告;见下文。
然而,当你变基时,你会从以下开始:
\n\n...--o--o--*--o--o <-- theirbranch\n \\\n A--B--C <-- yourbranch (HEAD)\n
Run Code Online (Sandbox Code Playgroud)\n\n您运行,Git 会找到自\xe2\x80\x94git rebase theirbranch
以来的提交,这些是您的, , 并在上面\xe2\x80\x94 上提交,并将它们的哈希 ID 列出到临时文件中。(如果您使用交互式 rebase,您将看到一系列使用这些哈希 ID 的命令。)现在 rebase 有了 ID,它首先检查它们的分支(作为分离的 HEAD)来开始真正的工作:*
A
B
C
pick
...--o--o--*--o--o <-- theirbranch, HEAD\n \\\n A--B--C <-- yourbranch\n
Run Code Online (Sandbox Code Playgroud)\n\n然后,Git 根据需要运行尽可能多的git cherry-pick
调用来复制所有提交\xe2\x80\x94(在本例中为三个)。每个cherry-pick都是一种特殊的合并,执行合并操作而不进行合并式提交。合并的结果是精心挑选的提交的副本。因此,第一次合并*
像以前一样作为合并基础进行操作,HEAD
一如既往地将提交作为当前提交,并将提交A
作为要合并的“他们的”提交!
因此,在这种情况下,您希望自定义.gitattributes
驱动程序采用“他们的”版本.mvn/maven.config
,因为“他们的”版本(在 commit 中A
)实际上是您的版本。不过,我之前提到的那个巨大警告现在变得更大了!
假设A
复制成功,你现在处于这样的状态:
A\' <-- HEAD\n /\n...--o--o--*--o--o <-- theirbranch\n \\\n A--B--C <-- yourbranch\n
Run Code Online (Sandbox Code Playgroud)\n\nGit 现在运行第二次cherry-pick,这意味着第二次合并操作:这次的合并基础是 commit A
;你的HEAD
提交是你自己的副本A\'
;而“他们的”提交就是您的提交B
。现在,只要您在第一个选择中选择了正确的一个,就 可以安全地选择其中一个。.mvn/maven.config
rebase 也会在提交时重复此操作C
,以构建C\'
在 之上B\'
。这次的合并基础将是 commit B
。与复制 commit 的过程一样B
,您可以在这里使用其中之一.mvn/maven.config
。完成此副本后,您将拥有:
A\'-B\'-C\' <-- HEAD\n /\n...--o--o--*--o--o <-- theirbranch\n \\\n A--B--C <-- yourbranch\n
Run Code Online (Sandbox Code Playgroud)\n\nyourbranch
现在,Git 通过从commit 中剥离名称C
并将其粘贴到最后一个副本上来完成变基C\'
,并在此过程中重新附加您的 HEAD:
A\'-B\'-C\' <-- yourbranch (HEAD)\n /\n...--o--o--*--o--o <-- theirbranch\n \\\n A--B--C [no longer needed]\n
Run Code Online (Sandbox Code Playgroud)\n\n.gitattributes
这种使用来控制使用哪个文件的特殊想法.mvn/maven.config
,至少部分地从一开始就因为不同的原因而注定要失败:当 Git 进行合并时,Git 首先查看三个文件中每个文件的原始哈希 ID。提交(合并基地、我们的和他们的)。这里一共有5种可能:
所有三个哈希ID都是相同的:合并的文件是基础文件,这是他们的文件和我们的文件。此时一切都非常美妙:您甚至不需要合并驱动程序!
基本文件与他们的相同,但与我们的不同:Git 只获取我们的文件。Git 完全忽略你的合并驱动程序。使用合并驱动程序的想法失败了(好吧,除非您想要“我们的”,但即使没有合并驱动程序也会发生这种情况)。
基本文件与我们的相同,但与他们的不同:Git 只是获取他们的文件。Git 完全忽略你的合并驱动程序。与前面的情况一样,使用合并驱动程序的想法失败了。
基本文件与我们或他们的不同,但我们和他们的相同:Git 只是获取我们的文件(它已经就位,因此对 Git 来说更容易)。Git 完全忽略你的合并驱动程序。这对于我们的情况来说是可以的,因为我们双方(我们的和他们的)都做了相同的更改,但是要保留基本版本的合并驱动程序在这里会失败。
最后,基本文件与我们的不同,我们的也与他们的不同:Git 使用您的合并驱动程序。您的合并驱动程序成功了!好吧,只要你弄清楚你想要哪个版本(“我们的”或“他们的”)就可以了。
浏览该列表,您会发现您的.gitattributes
驱动程序仅在五种可能情况中的一种情况下工作。另外两种情况不需要它。在被忽略的五个中,有两个是需要它的!因此,当您希望使用合并驱动程序时,有两种(总共五种)情况不会使用您的合并驱动程序。
归档时间: |
|
查看次数: |
698 次 |
最近记录: |