我正在寻找一种使git使用特定合并策略(我们/他们的)用于特定文件的方法,具体取决于我是合并还是重新定位我的功能分支。
让我解释一下:假设我有一个功能分支'fb',并且对文件“ .mvn / maven.config”进行了更改。 如果我将master合并到'fb'中,我想保留我的文件,所以请使用'ours'策略(我可以在.gitattributes文件中定义它)。 但是,如果我将重新设置为主服务器(而不是合并),则我仍然希望保留“ fb”分支的“ .mvn / maven.config”,因此应使用“它们的”策略,因为据我了解,策略的含义在合并和重新设置之间是相反的。
问题是:有没有一种简单的方法来定义智能合并策略?
据我所知,“ git合并驱动程序”概念已经存在,但是合并驱动程序无法判断是合并还是变基,因此无法推断是否使用我们的VS他们的。
我是否必须告诉队友没有解决方案,并且每次他们都被迫谨慎并手动选择合适的策略?
注意:我添加了“ maven”标签,因为使用git和maven的任何人在保存.mvn / maven.config文件时可能会遇到相同的问题
答案 0 :(得分:2)
的确,在重新定级期间您将需要“他们的”。这是因为rebase操作实际上是一系列的Cherry-pick,而每个Cherry-pick是一个合并操作,其中HEAD
(当前提交)在 target分支上(正在构建) ),而不是指向原始分支(现在正在复制)上的提交。
也就是说,普通合并看起来像这样:
...--o--o--*--o--o <-- yourbranch (HEAD)
\
o--o--o <-- theirbranch
您运行git merge theirbranch
; Git将提交*
(合并基础)与您的最终提交进行比较,以查看您的所作所为,然后将*
与他们的最终提交进行比较,以查看其所做的事情。然后,Git合并这些更改,并将其全部应用于*
,以产生合并:
...--o--o--*--o--o---M <-- yourbranch (HEAD)
\ /
o--o--o <-- theirbranch
如果提供了.gitattributes
定义的合并驱动程序,则可以让Git使用您的.mvn/maven.config
版本,但是这里有一个巨大的警告;见下文。
但是,当您变基时,您将从以下内容开始:
...--o--o--*--o--o <-- theirbranch
\
A--B--C <-- yourbranch (HEAD)
您运行git rebase theirbranch
,并且Git查找自*
以来的提交(这些是您上面的A
,B
和C
提交)并列出了它们将ID散列到一个临时文件中。 (如果使用交互式变基,您将看到一系列使用这些哈希ID的pick
命令。)现在,变基具有ID,它首先通过检出它们的分支来开始实际工作。 ,作为独立的HEAD:
...--o--o--*--o--o <-- theirbranch, HEAD
\
A--B--C <-- yourbranch
Git然后运行所需的git cherry-pick
个调用以复制所有提交,在这种情况下,其中三个。每个cherry-pick是一种特殊的合并,无需进行合并样式的提交即可执行合并操作。合并的结果是精心挑选的提交副本。因此,第一次合并将像以前一样以*
作为合并基础,以HEAD
提交作为当前提交,并以A
作为“其”提交进行合并!
因此,在这种情况下,您希望您的自定义.gitattributes
定义的驱动程序使用.mvn/maven.config
的“他们”版本,因为“他们”的版本(在提交A
中)实际上是您的版本。不过,我之前提到的巨大警告现在变得越来越大!
假设A
复制成功,您现在处于这种状态:
A' <-- HEAD
/
...--o--o--*--o--o <-- theirbranch
\
A--B--C <-- yourbranch
Git现在运行第二个Cherry-pick,这意味着第二个合并操作:这次合并的基础是commit A
;您的HEAD
提交是您自己的副本A'
;而“他们”的提交就是您的提交B
。现在,只要您在第一个摘樱桃中选择了正确的一个,就可以选择同时使用 .mvn/maven.config
。
rebase也将针对提交C
重复此操作,以在C'
之上构建B'
。这次的合并基础将是提交B
。与复制提交B
的过程一样,您可以在此处使用.mvn/maven.config
之一。完成此副本后,您将:
A'-B'-C' <-- HEAD
/
...--o--o--*--o--o <-- theirbranch
\
A--B--C <-- yourbranch
并且Git现在通过将名称yourbranch
从提交C
上剥离下来并将其粘贴到最后一个副本C'
上来完成重新基准化,在过程中重新附加HEAD:
A'-B'-C' <-- yourbranch (HEAD)
/
...--o--o--*--o--o <-- theirbranch
\
A--B--C [no longer needed]
这种使用.gitattributes
控制使用哪个.mvn/maven.config
文件的特殊想法从一开始就注定要失败,原因是:Git进行合并时,Git首先查找在三个提交(合并库,我们的库和他们的库)中的每个文件的原始哈希ID 中。这里总共有5种可能性:
所有三个哈希ID都相同:合并的文件是基础文件,即它们的文件和我们的文件。此时一切都很繁琐:您甚至不需要合并驱动程序!
基本文件与他们的文件相同,但与我们的文件不同:Git只是获取我们的文件。 Git完全忽略您的合并驱动程序。使用合并驱动程序的想法失败了(嗯,除非您想要“我们的”,但是即使没有合并驱动程序,也会发生这种情况)。
基本文件与我们的文件相同,但与他们的文件不同:Git只是获取他们的文件。 Git完全忽略您的合并驱动程序。与以前的情况一样,使用合并驱动程序的想法也失败了。
基本文件与我们或他们的文件不同,但是我们和他们的文件是相同的:Git只是获取我们的文件(它已经存在,因此对于Git来说更容易)。 Git完全忽略您的合并驱动程序。对于我们的情况,这是可以的,因为我们两个人(我们和他们两个人)都做了 相同的更改,但是要保留基本版本的合并驱动程序将在此处失败。
最后,基础文件与我们的文件不同,我们的文件也与它们不同:Git使用您的合并驱动程序。您的合并驱动程序成功!好吧,只要您确定想要哪个版本(“我们的”或“他们的”),它就可以执行。
在列表中,您将看到.gitattributes
驱动程序仅在五种可能情况中的一种起作用。在另外两种情况下不需要。在忽略的五分之二中需要 !因此,在两种(总共五种)情况下,当您希望使用合并驱动程序时将不使用它们。