Git - 合并期间忽略文件
Posted
技术标签:
【中文标题】Git - 合并期间忽略文件【英文标题】:Git - Ignore files during merge 【发布时间】:2013-02-20 08:06:48 【问题描述】:我在远程 beanstalk
服务器上有一个名为 myrepo
的存储库。
我将它克隆到我的本地机器上。创建了两个额外的分支:staging
和 dev
。
也将这些分支推送到远程。
现在:
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】:
您可以使用.gitignore
将config.xml
保留在存储库之外,然后使用post commit hook 将适当的config.xml
文件上传到服务器。
【讨论】:
我知道那是一种黑客行为。我正在尝试找到一个干净的解决方案。 gitattributes
怎么样。知道它是如何工作的吗?我无法理解这一点。 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 && 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
是一个内置的合并策略。但似乎可以先写<pattern> merge=foo
,然后再写git config --global merge.foo.driver true
,也一样。【参考方案7】:
示例:
-
你有两个分支:
master
,develop
您在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 - 合并期间忽略文件的主要内容,如果未能解决你的问题,请参考以下文章