Git - 合并期间忽略文件

Posted

技术标签:

【中文标题】Git - 合并期间忽略文件【英文标题】:Git - Ignore files during merge 【发布时间】:2013-02-20 08:06:48 【问题描述】:

我在远程 beanstalk 服务器上有一个名为 myrepo 的存储库。

我将它克隆到我的本地机器上。创建了两个额外的分支:stagingdev。 也将这些分支推送到远程。

现在:

 local                   remote                   server
 --------------------------------------------------------  
 master  ==> Pushes to  `master`  ==> deployed to `prod`
 staging ==> Pushes to  `staging` ==> deployed to `staging`
 dev     ==> Pushes to  `dev`     ==> deployed to `dev`

我有一个名为 config.xml 的文件,每个分支都不同。

我只想在合并期间忽略此文件。但我希望在我从 / 到 repo 分支结帐或提交时包含它。

我想要这个的原因是,我们有一个部署脚本,它可以拉出(签出)特定的分支并部署在相应的服务器上。因此,我们需要在部署时将该特定分支的config.xml 文件放入如上所示的特定服务器。

我猜.gitignore 不会工作。还有哪些其他选择?请注意,忽略的文件应该是签出和提交的一部分,这很重要。它应该只在合并期间被忽略。

谢谢!

【问题讨论】:

在默认模式下,git pull 是 git fetch 后跟 git merge FETCH_HEAD 的简写。所以你们的陈述有点相互冲突。 好吧,我想说,它的结帐。不拉。我将更新问题以明确。 Git: ignore some files during a merge (keep some files restricted to one branch)的可能重复 您找到解决方案了吗? git 属性仅适用于文件在被合并的分支之间存在冲突的情况,因此它并不总是足够的。 您是否查看了符号(不跟随 git)甚至是救援的硬链接? 【参考方案1】:

您可以从使用git merge --no-commit 开始,然后根据需要编辑合并,即取消暂存config.xml 或任何其他文件,然后提交。我怀疑你想在使用钩子之后进一步自动化它,但我认为至少手动完成一次是值得的。

【讨论】:

git attributes 是否提供任何直接的解决方案?我无法理解这一点。 git-scm.com/book/en/…【参考方案2】:

您可以使用.gitignoreconfig.xml 保留在存储库之外,然后使用post commit hook 将适当的config.xml 文件上传到服务器。

【讨论】:

我知道那是一种黑客行为。我正在尝试找到一个干净的解决方案。 git attributes 怎么样。知道它是如何工作的吗?我无法理解这一点。 git-scm.com/book/en/… 我没听说过这些,我正在尝试应用 merge=ours 属性,看起来很有希望。 Git 属性太棒了!你甚至可以告诉 git 如何区分非文本文件,这样你就可以使用 pdf2text 来区分 PDF!【参考方案3】:

我最终找到了 git attributes。试一试。工作至今。尚未检查所有场景。但这应该是解决方案。

Merge Strategies - Git attributes

【讨论】:

但我发现了这个git-scm.com/book/ch7-2.html#Merge-Strategies 这里是 git 属性文档的合并策略部分的正确链接:git-scm.com/book/en/v2/… 在一篇文章中找到了很好的解释medium.com/@porteneuve/… 如果没有冲突,这似乎是一个问题?文件还会合并吗?【参考方案4】:

我通过使用带有--no-commit 选项的 git merge 命令解决了这个问题,然后显式删除了暂存文件并忽略了对文件的更改。 例如:假设我想忽略对myfile.txt 的任何更改,我继续如下:

git merge --no-ff --no-commit <merge-branch>
git reset HEAD myfile.txt
git checkout -- myfile.txt
git commit -m "merged <merge-branch>"

如果您有要跳过的文件列表,您可以将语句 2 和 3 放在 for 循环中。

【讨论】:

如果您希望在快进策略中发生合并时不覆盖文件,我会添加“--no-ff”。 那么git reset HEAD myfile.txt 究竟做了什么?它对我们的目标有何帮助? 如何将第 2 行和第 3 行放在一个循环中? @androidDev 你可以这样做:for i in `ls myfile.txt myfile_2.txt`; do echo $i; git reset HEAD $i &amp;&amp; git checkout -- $i; done @Kid_Learning_C : git reset HEAD myfile.txt 取消暂存文件(在 --no-commit 合并后暂存)【参考方案5】:

这里 git-update-index - 将工作树中的文件内容注册到索引。

git update-index --assume-unchanged <PATH_OF_THE_FILE>

例子:-

git update-index --assume-unchanged somelocation/pom.xml

【讨论】:

推的时候很好,但拉的时候仍然抱怨可能会覆盖文件。 您是否尝试在 .gitignore 文件中添加您的文件条目。 @Rolf【参考方案6】:

.gitattributes - 是存储库的根级文件,用于定义子目录或文件子集的属性。

您可以指定属性来告诉 Git 对特定文件使用不同的合并策略。在这里,我们希望为我们的分支保留现有的config.xml。 我们需要在.gitattributes文件中将merge=foo设置为config.xml

merge=foo 如果发生合并冲突,告诉 git 使用我们的(当前分支)文件。

    在存储库的根级别添加.gitattributes 文件

    您可以在.gitattributes文件中为confix.xml设置一个属性

     <pattern> merge=foo
    

    我们以config.xml为例

     config.xml merge=foo
    

    然后定义一个虚拟的foo 合并策略:

     $ git config --global merge.foo.driver true
    

如果您合并 stag 表单 dev 分支,而不是与 config.xml 文件发生合并冲突,则 stag 分支的 config.xml 会保留您最初拥有的任何版本。

更多参考:merge_strategies

【讨论】:

但是如果没有冲突呢?如何在合并过程中始终保留某个文件? @IgorYalovoy:如果没有冲突......好吧,这有点棘手,因为它实际上可以通过哈希 ID 工作,但是:如果 config.xml 完全不变从合并基础到任一分支提示版本,Git 只采用更改后的版本,而不查看 merge.ours.driver 设置。所以你的担心是正确的。 从 Git 文档复制粘贴:合并策略 - Git 属性。 Link 这个方法每次都会导致“合并提交”。 "ours" 似乎是正在引入的新策略的任意名称。我发现这很混乱,因为theirs 是一个内置的合并策略。但似乎可以先写&lt;pattern&gt; merge=foo,然后再写git config --global merge.foo.driver true,也一样。【参考方案7】:

示例:

    你有两个分支:masterdevelop 您在develop 分支中创建了文件,并希望在合并时忽略它

代码:

git config --global merge.ours.driver true
git checkout master
echo "path/file_to_ignore merge=ours" >> .gitattributes
git merge develop

您也可以忽略具有相同扩展名的文件

例如所有带有.txt 扩展名的文件:

echo "*.txt merge=ours" >> .gitattributes

【讨论】:

这仅适用于有冲突的情况!【参考方案8】:

正如许多人所评论的,应该注意accepted answer 及其副本(对一个或多个特定文件使用自定义合并策略)仅在存在实际合并冲突的情况下才有效强>.

不会导致合并冲突并因此提交被合并的2个简单案例:

您有一个 config.xml 文件在功能分支中,而不是在 master 中。您想在合并期间排除它 您在两个分支中的config.xml 文件基于相同的提交。新代码已添加到功能中的文件中。

要么使用merge --no-commit,正如unmesh-gurjar 所展示的那样,要么简单地将cherry-pick 个人提交到master 中。后者当然相当繁琐,并带有其他一些陷阱(新的 SHA1 ID 等)

【讨论】:

解决方法是什么? @Gabriel:可悲的事实是,没有像将文件添加到 .gitignore afaia 那样简单的一劳永逸的解决方案。您需要使用上述解决方法之一(恕我直言),或者不幸的是与其他 VCS 一起使用。

以上是关于Git - 合并期间忽略文件的主要内容,如果未能解决你的问题,请参考以下文章

git合并时忽略某个文件

git合并时忽略某个文件

Xcode 项目的 Git 忽略文件正在忽略 .swift 文件

sourcetree .git 强制忽略指定文件不提交

git合并分支时禁止合并特定文件

Unity Git - 忽略库