【问题标题】:How to realise a deployment branch in Git如何在 Git 中实现部署分支
【发布时间】:2010-10-04 00:25:48
【问题描述】:

我正在使用 git 进行 PHP 项目,我认为它真的很方便。如果我让它发挥作用,有一件事会很棒。

我创建了一个分支,用于部署。它有一些差异,例如不同的配置文件和文档。

我不能忽略它们,因为那样它们将保留在两个分支中,而我希望它们在两个分支中保持不同。

问题是当我合并分支时,那些本来应该不同的文件也被合并了。

有没有方便的方法来完成这样的事情?这通常是怎么做的?

【问题讨论】:

    标签: git deployment branch


    【解决方案1】:

    2021 年 2 月更新:Git 本身仍然不太合适,但 GitHub Action environment could help

    2009:我不确定 Git 是否适合以这种方式使用。

    首先快速Linus advice,总是“丰富多彩”和信息丰富;)

    Git very 从根本上跟踪项目状态,而不是文件状态。这意味着您不能尝试“合并文件”。在 git 中这是一个毫无意义的操作,事实上,任何允许它的 SCM 都注定是一个彻头彻尾的 sh*t (*)。

    (*) 我并不是因为 git 没有这样做。它比这更根本。一旦你开始进行每个文件的分支和合并,你基本上就搞砸了,你将永远无法将项目作为一个“整个项目”来工作——你不再有一个定义明确的历史,实际上是整个项目的历史。


    那里。

    也就是说,你可以:

    • 将这些 config/doc 文件管理为单独的 git 子项目(注意:use of submodules has been discussed here
    • 或记录部分合并(对我们不想合并的文件使用“我们的”策略),然后 -- 修改它。

    此线程中的其他解决方案涉及在部署服务器上处理“特定于服务器”的分支

    Development        Deployment
    
    #origin/master:
    x--x               $ git clone
    
                       # master
                       x--x
    
                       $ git checkout -b deployment origin/master
    
                       x--x
                           \ 
                            -- #deployment
    
                       $ .... #makes changes for config files
                              #or other specific deployment files
    
                       x--x
                           \
                            --d1--d2 # no need to push that branch ever.
    
    #new developments
    x--x--x--x
    
                       $ git pull --rebase #pull origin/master and 
                                           #replay current branch on top of it
                       x--x--x--x
                                 \
                                  --d1'--d2' #SHA1 rewritten in deployment branch
                                             #not important since this branch 
                                             #is not pushed (published)
             
                  
    

    【讨论】:

      【解决方案2】:

      我做了一些愚蠢的把戏,比如:

      • 让应用程序读取文件config
      • config.developmentconfig.production 但不添加 config 到存储库
      • 让您的部署脚本不仅克隆存储库,还克隆cp config.production config

      这有意义吗?

      对我来说没问题。

      【讨论】:

      • 我真的没有部署脚本,但我已经解决了它来制作一个 config.template.php 和一个 config.php 然后让 git 忽略 config.php
      【解决方案3】:

      这对我有用,我只对部署进行微小的配置更改(配置文件中的 3 行)。

      1. 从 GitHub 或您保存它的任何地方克隆您的存储库。到您希望部署的位置。

      2. 运行git checkout -b deployment origin/master

      3. 进行更改(如果您愿意,请推送)。

      4. 每当您的 master(或您进行部署的任何分支)有您想要部署的更改时,只需 git pull --rebase

      这是一个简单的解决方案,它肯定对我有用,我不能说它是否像其他人所说的那样使它“shi*t”,但它肯定对我们的目的非常有用。

      【讨论】:

      • 再想一想,我会避免这样做,因为它不必要地复杂。而是在您的 .conf 文件中使用 SetEvn 来设置影响/确定您的配置的环境变量。例如,在我的开发服务器上,我的站点的 DATABASE_URL='mysql:root@localhost/bla' 而在生产环境中,它可能是 DATABASE_URL='mysql:app@localhost/appdb'。
      【解决方案4】:

      快速回答是,永远不要合并分支。事实上,您根本不需要合并它们,只需从开发(也称为“主”)合并到部署以合并修复和通用更改。

      【讨论】:

      • 我不太明白。不要合并,而只是合并。你的意思是只合并一种方式吗?
      • 我认为他的意思是:将特定于部署的文件保存在分支 B,将本地配置文件保存在分支 A,在 master 分支中进行开发。从master合并到A进行测试,从master合并到B进行部署;永远不要从 A 或 B 合并到 master。
      • 确切地说:我的意思是,不要将分支合并在一起,合并分支之间的单个变更集。
      【解决方案5】:

      如果您想保持良好的历史记录,可以将部署文件保存在干净分支之上的一些提交中。然后,当需要部署新版本时,检查部署分支和“git rebase master”,将这些提交放在原始分支之上。

      这样,您还可以轻松更改配置文件,并使用 'git commit --amend' 更改顶部提交。

      【讨论】:

        【解决方案6】:

        我遇到了类似的问题,并创建了一个名为 config-magic 的小项目来帮助解决这个问题。

        Config-magic 允许您创建模板 conf 文件,然后为每个 dev/staging/production 创建数据配置文件。然后运行“cfg dev”生成“dev”配置文件,“cfg staging”生成暂存配置,等等。

        然后我将它与脚本连接起来,这样当我部署到 staging 时,我在本地运行“cfg staging”,然后在从 git 更新代码库后对所有配置文件进行 scp。

        “实际”配置文件被设置为被 git 忽略。到目前为止,这对我来说非常有效。

        https://github.com/apinstein/config-magic/tree

        【讨论】:

          【解决方案7】:

          我正在考虑针对我的情况的所有这些解决方案,但似乎没有一个适用。我在我的实时服务器和开发服务器上进行编辑。 如果您不需要重新发布该分支,Rebase 效果很好,但是我在我的部署分支上进行了更改并将这些更改发布回主存储库。 仅当您的文件位于单独的子目录中时,子模块方式才有效,我的配置文件位于多个位置。 合并我们的方法也不能很好地工作,因为我必须先拉那个分支然后再拉大分支。 如果仍然有他们的合并可能会起作用,并且我可以在需要时拉入正确的配置分支。 现在 .gitignore 有效,我只是手动上传文件。

          在进行更多研究后,我发现我的解决方案是在实时站点上没有 git 存储库,而是使用暂存站点通过暂存/实时配置文件将最新更改拉入我的分支。然后通过 git archive 部署并将文件提取到我的实时站点。

          【讨论】:

            【解决方案8】:

            cherry-pick 似乎为此工作(以稍微污染日志为代价)。

            git checkout -b 测试 进行更改并提交 git结账大师 git checkout -b 部署 进行更改并提交 git结帐大师

            在主人和 git cherry-pick testing 或 git cherry-pick deploy 应用从当前系统切换到测试或部署版本所需的差异。

            【讨论】:

              【解决方案9】:

              我之前提到过补丁文件。我现在已经取消了这个,而是维护部署分支。

              即,我用一个名为“master-deployed”的新分支从 master 分支,并在该分支上进行更改,我只需要在构建服务器上的测试版本中进行更改(即添加一个警告,这不是实时版本,以及 web.config 中的不同数据库服务器)。

              在构建前沿版本时,构建服务器会检出 master-deployed,并在执行通常的构建之前将其重新定位到 origin/master。如果没有人做出任何有冲突的更改,那么一切都很好。如果他们有,那么我看不到任何系统在没有人工干预的情况下处理这个问题。

              qa 的提示也是如此,它有一个分支 'qa-deployed'

              我使用 --onto 标志来确保如果整个分支被重写,那么补丁不会带走所有旧的提交。

              所以在构建服务器上,qa 构建看起来像

              git reset --hard
              git clean -xfd
              git checkout -f qa-deployed
              git rebase --onto qa HEAD^ qa-deployed
              build-script
              

              【讨论】:

                【解决方案10】:

                目前我签入了几个补丁文件,构建服务器将这些补丁应用于相关版本。虽然我现在对此有第二个想法

                【讨论】:

                  【解决方案11】:

                  这既简单又干净。

                  您将创建一个部署分支,例如:

                  > git checkout deployment-1234
                  

                  现在您可以进行特定于部署的更改。完成后,提交:

                  > git commit -as
                  

                  回到你的主分支。

                  > git checkout master
                  

                  立即合并部署分支。这将使用这些特定于部署的更改来修改您的主分支,但不要担心,我们会还原它。

                  > git merge --no-ff deployment-1234
                  

                  要恢复更改,只需在合并前签出文件并修改提交即可。

                  > git checkout HEAD^ .
                  > git commit --amend
                  

                  就是这样。现在git将deployment-1234的第一次提交中的文件更改视为master已经考虑并发现不合适。因此,即使您尝试将整个 deployment-1234 分支合并到 master,它也永远不会将这些更改添加到 master 分支。 (试试看!)

                  我还在需要更好控制的项目中使用了另一种方法。上述不利之处在于,您可能会在未来从部署 1234 合并到 master 期间产生冲突。如果这些合并是手动的,那没关系。但是如果你需要自动合并,我最好能防止这种系统冲突。因此,我创建了一个脚本,可以应用和撤消特定于部署的更改。然后更改本身不需要在存储库中,而出现在存储库中的就是那个脚本。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2019-01-27
                    • 2016-06-21
                    • 2013-02-27
                    • 2019-06-08
                    • 2017-10-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多