避免在git合并期间覆盖文件

避免在git合并期间覆盖文件,git,Git,考虑以下场景。我有三个分支-Master,develope和Test。所有三个分支都有一个配置文件(比如JenkinsFile),其中包含特定于分支的配置。请注意,此文件中的配置对于所有三个分支都是不同的。现在,我从Master创建一个功能分支,进行一些更改,并将此功能分支与develope合并,然后与Test合并 问题是-如何防止任何合并覆盖JenkinsFile?我希望JenkinsFile保持完整,不受任何合并的影响。有没有办法“锁定”这些文件?在这种情况下,gitignore有效吗 干杯

考虑以下场景。我有三个分支-
Master
develope
Test
。所有三个分支都有一个配置文件(比如
JenkinsFile
),其中包含特定于分支的配置。请注意,此文件中的配置对于所有三个分支都是不同的。现在,我从
Master
创建一个功能分支,进行一些更改,并将此功能分支与
develope
合并,然后与
Test
合并

问题是-如何防止任何合并覆盖
JenkinsFile
?我希望
JenkinsFile
保持完整,不受任何合并的影响。有没有办法“锁定”这些文件?在这种情况下,
gitignore
有效吗


干杯

在分支之间保持一个不同的文件是非常困难的,尤其是一个经常变化的文件

更好的解决方案是让settings.environment.json文件包含不同环境的设置,并使您的软件根据运行位置使用不同的设置文件


话虽如此,最好不要将生产设置保存在git中。部署管道应该包含密码等,而不是您的版本控制系统。在这种情况下,所有分支中的设置文件都包含DEV设置(可以公开),管道在准备将包部署到目标环境时使用TEST和PROD值覆盖这些设置

在分支之间保持一个不同的文件是非常困难的,尤其是一个经常变化的文件

更好的解决方案是让settings.environment.json文件包含不同环境的设置,并使您的软件根据运行位置使用不同的设置文件

话虽如此,最好不要将生产设置保存在git中。部署管道应该包含密码等,而不是您的版本控制系统。在这种情况下,所有分支中的设置文件都包含DEV设置(可以公开),管道在准备将包部署到目标环境时使用TEST和PROD值覆盖这些设置

问题是-如何防止Jenkins文件被任何合并覆盖?我希望Jenkins文件保持完整,不受任何合并的影响。有没有办法“锁定”这些文件

没有

但是,有一种完全不同的方法来解决这个问题,它回避了整个问题。事实上,有多种方法,但我只展示一种。这是一个令人遗憾的问题,因为在这个状态下,所有的事情都按预期进行,但一旦你做到了,你就很好了。这里的最终目标是不要有一个名为
Jenkinsfile
(或
Jenkinsfile
,但我使用了下面的小写字母F拼写)的提交文件,该文件的内容依赖于分支。相反,只需要一个名称为
Jenkins[Ff]ile
且内容依赖于分支的未提交工作树文件。使提交的文件具有其他名称

背景 基本上,
git merge
是通过组合已完成的工作来工作的,即,从某个公共起点开始,组合对某些文件的更改。但Git不存储更改;Git存储快照。这给git merge带来了一个问题,解决方案要求您了解git的提交图是如何工作的

Git存储库中几乎每个提交都至少有一个父提交,这是该提交的直接前身。大多数人只有一个父母;“merge”类型的提交至少有两个,通常正好有两个。事实上,多个父级的存在将提交定义为合并提交。另一种常见的特殊情况是,存储库中的第一次提交没有父级,因为它不能有父级,因为它是第一次提交。(与三个或三个以上家长的提交被称为八达通合并,但它们不做常规合并所不能做的事情,因此它们主要用于炫耀。:-)

在这些链接中,提交存储其父级的散列ID—请记住,每个提交都是通过其唯一的散列ID找到的,当您使提交形成反向链时,Git分配给提交。这些反向链是存储库中的历史记录。历史是永恒的;这就是历史。分支名称仅标识我们希望声明为该分支一部分的(单个)最后一次提交:

... <-F <-G <-H   <--master
git checkout
分支意味着*从该分支的提示提交中提取快照
。因此
git checkout master
从提交中提取快照
H
,而
git checkout develope
git checkout test
依次提取这些快照。此外,对某个分支名称执行
git checkout
,会将特殊名称
HEAD`附加到该分支。这就是Git知道哪个分支和提交是当前分支和提交的方式

当您运行
git merge
时,您为git提供了其他提交的名称。这不一定是一个分支名称,提交的任何名称都会起作用,但是给它一个分支名称就可以了,因为它命名了该分支的提示提交。因此,如果您
git checkout master
,然后运行
git merge develope
,您可以从以下内容开始:

          G--H   <-- master (HEAD)
         /
...--E--F
         \
          I--J   <-- develop
              \
               K   <-- test
为了组合这些更改,Git从
F
中的所有文件开始,查看我们更改了哪些文件以及它们更改了哪些文件。如果我们都更改了不同的文件,Git会根据需要选择我们的或他们的文件。如果我们都更改了同一个文件,Git会尝试将我们的更改和他们的更改一起粉碎,假设如果我们碰了某个源代码行,而他们没有碰,那么应该是我们的,如果他们碰了某个源代码行,而我们没有碰,那么也应该是他们的。如果我们都接触了同一文件的同一行,那么要么我们没有
          G--H   <-- master (HEAD)
         /
...--E--F
         \
          I--J   <-- develop
              \
               K   <-- test
git diff --find-renames <hash-of-F> <hash-of-H>    # what we changed
git diff --find-renames <hash-of-F> <hash-of-J>    # what they changed
          G--H
         /    \
...--E--F      L   <-- master (HEAD)
         \    /
          I--J   <-- develop
              \
               K   <-- test
git rm --cached Jenkinsfile
git checkout --ours Jenkinsfile.master
git checkout --theirs Jenkinsfile.develop
git add Jenkinsfile.master Jenkinsfile.develop