git - 如何从合并中排除文件

时间:2011-06-09 14:22:30

标签: git merge

我正在尝试将两个网站项目保存在一个存储库中。除了模板(html,css)文件和少量配置文件外,这些网站主要是相同的。 主站点(我说是Supersite)是分支机构的主人。第二个站点位于分支secondarySite中。每当我在master分支中开发一些新功能时,我想将它合并到secondarySite,但我想从合并中排除模板文件。

我在How do I tell git to always select my local version for conflicted merges on a specific file?找到了部分解决方案,但只有当我在两个分支中更改模板文件并且发生冲突时,它才有效。当没有冲突时,git只使用较新的远程版本的文件。

即使没有冲突,如何告诉git 始终保持指定的本地文件不变。

或许我使用完全错误的方法解决问题?

提前感谢您的帮助。

5 个答案:

答案 0 :(得分:7)

my answer on merge drivers所述,只有在发生冲突时才有用 那applies to a merge=ours in a .gitattributes file:见Merge strategies

  

一个非常有用的选择是告诉Git在发生冲突时不尝试合并特定文件 ,而是将合并的一方用于其他人的。

recent thread (2012)证实了这一点:

  
    

有没有办法从branchA合并到branchB和从branchB合并到     branchA,同时完全忽略对被跟踪文件的更改     并存在于两个分支中?

  
     

没有。从根本上说, git中的提交对象包含内容状态(即指向树对象的指针)和指向所有先前历史的指针(即零或更多“ parent“指向提交对象的指针”   提交对象的语义可以被认为是“我查看了所有父提交中的所有历史记录,并且我的树指针中包含的状态全部取代它们”。

     

因此,您可以将B合并到A,但保留A的文件副本(例如,使用“ours”策略)。但是,这就是说你考虑了A和B的状态,并决定A的版本取代B中发生的事情。如果您以后想要从A合并到B,则B的文件版本甚至不会被视为合并的结果。

     

通过不同的合并策略,没有一种聪明的方法可以解决这个问题;这是git存储历史数据结构的一个基本方面。

如果这些模板位于子目录中,最好将它们隔离在自己的git仓库中,以便将该仓库包含为子模块。

如果没有,那么你需要在提交之前恢复错误合并的文件(如在this thread中):

git merge --no-commit other
git checkout HEAD XYZ  # or 'git rm XYZ' if XYZ does not exist on master
git commit 

答案 1 :(得分:3)

您是否尝试过使用.gitignore? git文档here

中提供了详细信息

答案 2 :(得分:2)

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

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

实施例: -

  

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

在.gitignore中添加文件路径

答案 3 :(得分:2)

  

或许我使用完全错误的方法解决问题?

您使用完全错误的方法解决此问题:)

问题在于分支及其周围的工具旨在维护相同底层事物的不同版本

但是你的两个网站并不是真正相同的东西,它们是两个不同的东西,有一些共性,而且你不得不滥用git因为你对它撒谎他们的关系。

你理智的选择是:

  1. 让您的repo代表所有(好的,两个)网站 Universe。因此,它们在同一目录结构中都可见,并使用不同的路径名。他们可能具有单独的开发和发布分支,但它是可选的。如果这两个站点具有一些共性,则可以采用共享文件的形式。

    例如

    repo/supersite
    repo/secondsite
    repo/common
    
  2. 为每个站点单独制作一个repo,并复制公共文件。您只需复制更改

  3. 即可
  4. 为每个站点单独制作一个repo,为常见的东西制作第三个repo,并使用子模块在一个地方组合supersite + common,在另一个地方使用secondsite + common。

    例如

    super-repo/site    # super site content
    super-repo/common  # common repo as submodule
    second-repo/site   # second site content
    second-repo/common # same common repo as submodule
    

    请注意,子模块引用相同的repo,但每个实例当前可以位于不同的分支或提交

  5. 在某种程度上,正确的选择取决于两个站点独立变化的程度,共享位的变化频率,以及是否可以强制两个站点使用相同版本的共享位,以及共享总内容的多少部分与唯一等等。

答案 4 :(得分:1)

在每个分支中,在root中添加文件.gitattributes

对于每个分支,在合并时指定要忽略的文件:

filename merge=ours

并且不要忘记激活驱动程序:

git config --global merge.ours.driver true

尝试合并,您会发现在合并发生时,每个分支中.gitattributes中指定的文件都不会受到影响。