强制 Git 在合并期间始终选择特定文件的较新版本?还是只提交特定的分支?

Posted

技术标签:

【中文标题】强制 Git 在合并期间始终选择特定文件的较新版本?还是只提交特定的分支?【英文标题】:Force Git to always choose the newer version of specific file during a merge? Or commit to only specific branch? 【发布时间】:2021-05-04 02:08:39 【问题描述】:

我是我的项目的单一开发人员。

在开发中,我使用一个文件 buildnumber.txt,尽管有分支,但我需要始终拥有最新的文件。

给定一个合并命令:

git merge featureBranch --no-ff

我可以在某处指定对于文件buildnumber.txt 或其他文件,Git 必须始终使用较新版本吗?

这类似于.gitignore,但用于解决此类合并冲突。

或者,有没有办法指定文件buildnumber.txt 将只存储在分支master 中?当我在master以外的分支中修改它时,它应该被忽略,所以我必须切换到master并在那里检查它?

【问题讨论】:

你能不能显示一个minimal reproducible example,它不能像你预期的那样工作? 您可以定义一个自定义合并驱动程序。驱动程序接收祖先版本、当前版本和另一个分支版本。实现逻辑来决定哪个版本是最新的,并用最新版本覆盖当前版本。 看看git rerere,它可以让你记录合并偏好。 git-scm.com/docs/git-rerere 【参考方案1】:

简短的回答是不,你不能这样做(这三件事中的任何一件,真的)。更长的答案仍然是否定的,但解释了为什么

您遇到的第一个问题是 Git 中的文件没有 日期。这可能不是什么大问题,因为 Git 最初并不存储文件:Git 存储 commits。提交 do 有日期,然后提交也有文件,因此您可以只使用 commit 日期作为提交中每个文件的伪日期。然后您可以选择最新的commit 版本的文件。合并由 commits 工作,因此具有日期的提交这一事实(在逻辑上)在这里应该不是问题(尽管请注意物理上访问提交日期将是一个大问题,一旦你降到这个水平)。

但这仍然不是你真正想要的——而且无论如何,Git 中没有内置的机制。 Git 对合并期间的日期不感兴趣。 Git 只对文件内容感兴趣。您可以尝试使用ElpieKay's suggestion 来应用merge driver(此链接转到gitattributes 文档,您将在该文档中看到合并驱动程序的描述),但事实证明这也不是一个好方法。请参阅.gitattributes merge strategy not working 了解为什么它不太好。 (TL;DR 部分是您的自定义合并驱动程序不使用,除非有需要完成一些合并,有时不需要进行任何合并。在一种情况下,这对您有利,而在另一种情况下,它会失败。)

事实上,最好的方法几乎肯定是根本不将构建版本号存储在 Git 中。如果您有一个名为version.txt 的工作树文件根本不在任何提交中,那么这将只是一个未跟踪的文件,您可以将其排除在所有提交之外。从一个提交更改到另一个提交不会触及该文件,因为它绝不是存储库的一部分。签出您正在使用的提交的分支更改,但由于该文件不在提交中,因此不会将其复制到您的工作树中。对已包含在现有提交中的文件执行此操作为时已晚,因为这些提交实际上无法更改,但您可以重写存储库历史记录,或仅更改文件名。

要使未跟踪的文件不被跟踪,将其名称列在.gitignore 文件中会有所帮助。请注意,如果该文件已被跟踪,即在 Git 的索引中,则在 .gitignore 中列出该文件无效。 (文件何时在 Git 的索引中的问题的答案相当长。)

【讨论】:

以上是关于强制 Git 在合并期间始终选择特定文件的较新版本?还是只提交特定的分支?的主要内容,如果未能解决你的问题,请参考以下文章

如果我强制用户更新到 appstore 上可用的较新版本,AppStore 会拒绝我的申请吗

如何在 Git diff 和 merge 期间忽略某些特定文件和文件夹

尝试上传我的应用程序的较新版本。存档时不显示应用名称。

Git - 如何在所选文件上强制合并冲突和手动合并

从 git 上的 master 更新了分支,但缺少新版本

Git放弃本地修改,强制拉取最新版