Git-在合并过程中忽略文件

我在远程 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的文件,它在每个分支上都是不同的。

我只希望在合并期间忽略此文件。但是,我希望在结帐或从/向回购分支提交时包含这一点。

我之所以需要这样做,是因为我们有一个部署脚本,它可以拉出(签出)特定的分支并部署到各自的服务器上。因此,我们需要该特定分支的 config.xml文件进入特定服务器,如上所述,当部署时。

看来 .gitignore不行了。还有别的选择吗?注意,被忽略的文件应该是签出和提交的一部分,这一点很重要。只有在合并过程中才应该忽略它。

谢谢!

173367 次浏览

您可以从使用 git merge --no-commit开始,然后按照您喜欢的方式编辑合并,即通过取消 config.xml或任何其他文件的登台,然后提交。我怀疑您会希望在使用钩子之后进一步自动化它,但是我认为至少应该手动执行一次。

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

最后我找到了 git attributes。试试看。目前还行。还没有检查所有场景。但这应该是解决办法。

合并策略-Git 属性

我通过使用带有 --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 循环中。

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

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

例子:-

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

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

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

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

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

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

     <pattern> merge=foo
    

    让我们以 config.xml为例

     config.xml merge=foo
    
  3. 然后定义一个虚拟的 foo合并策略:

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

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

参考资料: Merge _ Strategies 合并策略

例如:

  1. 你有两个分支: masterdevelop
  2. 您在 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

正如许多人所评论的那样,应该注意到 接受的答案和它的副本(对特定文件使用自定义合并策略) 只有在存在实际合并冲突的情况下才有效

2个不会导致合并冲突并因此提交合并的简单情况:

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

要么使用 merge --no-commit,如 Unesh-gurjar所示,要么简单地单独提交到 master。当然,后者相当麻烦,还有一些其他的缺陷(新的 SHA1 ID 等等)

考虑使用 git hook:

当你运行一个成功的 git 签出之后,后签出钩子就会运行,你可以使用它来为你的项目环境正确地设置你的工作目录。这可能意味着移动大型二进制文件,您不希望这些文件受源代码控制、自动生成文档或类似的内容。

资料来源: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#:~:text=After%20you%20run,along%20those%20lines

您可以将这些文件放在一个单独的目录中,如果需要,可以选择通过 .gitignore从存储库中排除这些文件。

根据被切换到的分支的名称,来自 post-checkout钩子的脚本可以获取该分支的正确文件(可能在子目录中) ,并将它们复制(覆盖)到正确的位置。这些特定于分支的独立文件需要在 .gitignore中。

.git/hooks中的 post-checkout脚本示例:

#!/bin/sh


BRANCH=`git reflog | awk 'NR==1{ print $8; exit }'`


cp "./configs/$BRANCH/config.json" "./config.json"


exit 0