如何在 Git 中实现部署分支

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/487753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 03:33:56  来源:igfitidea点击:

How to realise a deployment branch in Git

gitdeploymentbranch

提问by Ikke

I'm using git for a PHP project, I think it's really handy. There is one thing that would be great if I get it to work.

我正在将 git 用于 PHP 项目,我认为它真的很方便。如果我让它工作,有一件事会很棒。

I have created a branch, meant for deployment. It has some differences, like different configuration files and documentation.

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

I can't just ignore them, because then they will stay in both branches, while I would like to keep them different in both branches.

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

The problem is that when I merge the branches, those files that are meant to be different are merged too.

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

Is there any convenient way to accomplish such a thing? How is this normally done?

有没有什么方便的方法来完成这样的事情?这通常是如何完成的?

采纳答案by VonC

I am not sure Git is meant to be used this way.

我不确定 Git 是否应该以这种方式使用。

First a quick Linus advice, always "colorful" and informative ;)

首先是一个快速的Linus 建议,总是“丰富多彩”且内容丰富;)

Git veryfundamentally tracks project state, not file state. Which means that you very much can NOT try to "merge a file". It is a senseless operation in git, and in fact, any SCM that allows it pretty much is doomed to be a total piece of sht ().

(*) And I'm not saying that just because git doesn't do it. It's much more fundamental than that. Once you start doing per-file branching and merging, you've basically screwed yourself, and you'll never be able to work on the project as a "whole project" any more - you no longer have a well-defined history that actually is the history of the whole project.

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

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



There.

那里。

That said, you could:

也就是说,你可以:

  • manage those config/doc files a separate git sub-projects (note: the use of submodules has been discussed here)
  • or record partial merge (using "ours" strategy for files we don't want to merge), then --amend it.
  • 将这些 config/doc 文件管理为单独的 git 子项目(注意:子模块使用已在此处讨论
  • 或记录部分合并(对我们不想合并的文件使用“我们的”策略),然后 --amend 它。


Other solutions in this thread involve working on a "server-specific" branch on your deployment server

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

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)

回答by arbales

This works for me, and I make only minor configuration changes to deploy (3 lines in config files).

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

  1. Clone your repository from GitHub or wherever you keep it. To where you wish to deploy.

  2. Run git checkout -b deployment origin/master.

  3. Make your changes (push them if you like).

  4. Whenever your master (or whatever branch you made the deployment from) has changes you want to deploy, simply git pull --rebase.

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

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

  3. 进行更改(如果您愿意,可以推送它们)。

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

It's a simple solution and it certainly works for me, I can't speak to wether or not it this makes it "shi*t" as others suggest, but it is certainly very useful for our purposes.

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

回答by elliot42

I do some silly tricks like:

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

  • Have the app read file config
  • Add config.developmentand config.productionbut not configto the repository
  • Have your deploy script not only clone the repository, but also then cp config.production config
  • 让应用读取文件 config
  • 添加config.developmentconfig.production但不添加config到存储库
  • 让您的部署脚本不仅克隆存储库,而且 cp config.production config

Does that make any sense?

这有任何意义吗?

It works okay for me.

它对我来说没问题。

回答by Keltia

Quick answer is, don't ever merge the branches. In fact you don't need to merge them at all, just merge from development (aka "master") to deployment to merge fixes and generic changes.

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

回答by Pieter

If you want to keep your history nice, you can keep the deployment files in some commits on top of your clean branch. Then, when it's time to deploy a new version, you check out the deployment branch and 'git rebase master', to put those commits on top of the original branch.

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

That way, you can also make easy changes to the configuration files, and change the top commit with 'git commit --amend'.

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

回答by Tim Abell

I mentioned earlier patch files. I've gone off this now, and instead maintain deployment branches.

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

ie, I branch off master with a new branch named 'master-deployed', and make changes on that branch that I need to be only in the test version on the build server (i.e. adding a warning that this is not the live version, and different db server in web.config).

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

The build server when building the bleeding edge version then checks out master-deployed, and rebases it onto origin/master before performing the usual build. If no-one has made any conflicting changes then everything is fine. If they have then I can't see any system handling this without manual intervention.

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

Same goes for tip of qa, which has a branch 'qa-deployed'

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

I use the --onto flag to make sure if a whole branch is rewritten then the patch doesn't take all the old commits with it.

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

So on the build server the qa build looks something like

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

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

回答by apinstein

I had a similar problem and created a tiny project called config-magic to help manage this.

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

Config-magic lets you create template conf files and then profiles of data for each of dev/staging/production. You then run "cfg dev" to produce the "dev" config files, "cfg staging" to produce the staging config, etc.

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

I then have this wired up with scripts, so that when I deploy to staging, I locally run "cfg staging" then scp over all of the config files after updating the codebase from git.

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

The "actual" config files are set to be ignored by git. This has worked really well for me so far.

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

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

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

回答by kzap

I was thinking about all of these solutions for my situation but none of them seem to apply. I edit both on my live and development servers. Rebase works well if you dont need to republish that branch, but I make changes on my deployment branch and publish those back to the main repository. The submodule way only works if your files are in a seperate subdir, my config files are in several places. The merge ours method wouldnt work so well also since i'd have to pull that branch first and then the big branch. Maybe it would work if there was still a merge theirs and I could pull in the proper configuration branch when needed. For now a .gitignore works and I just manually upload the files.

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

After doing more research I've found my solution to not have a git repo on the live site but use a staging site to pull the latest changes into my branch with the staging/live config files. and then deploy by git archive and extracting the files onto my live site.

在做了更多的研究之后,我发现我的解决方案在实时站点上没有 git repo,而是使用临时站点通过临时/实时配置文件将最新更改拉到我的分支中。然后通过 git archive 部署并将文件提取到我的实时站点上。

回答by David

cherry-pick seems to work for this for this (at the expense of polluting the logs a bit).

樱桃挑选似乎为此起作用(以稍微污染原木为代价)。

git checkout -b testing make changes and commit git checkout master git checkout -b deploy make changes and commit git checkout master

git checkout -b testing 进行更改并提交 git checkout master git checkout -b deploy 进行更改并提交 git checkout master

do everything under master and git cherry-pick testing or git cherry-pick deploy to apply the diffs needed to switch from the current system into the testing or deployment version.

在 master 和 git cherry-pick testing 或 git cherry-pick deploy 下做所有事情,以应用从当前系统切换到测试或部署版本所需的差异。

回答by Isaac To

That's easy and clean.

这很简单,也很干净。

You'd create a deployment branch like:

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

> git checkout deployment-1234

Now you can make the deployment specific changes. Once that is done, commit it:

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

> git commit -as

Go back to your master branch.

回到你的主分支。

> git checkout master

Immediately, merge the deployment branch. This will modify your master branch with those deployment-specific changes, but don't worry, we will revert it.

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

> git merge --no-ff deployment-1234

To revert the changes, just checkout the files before the merge and commit it with amend.

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

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

That's it. Now git treats that the file changes in the first commit of deployment-1234 as already considered by the master and found to be unsuitable. So it will never add those changes to the master branch even if you try to merge the whole deployment-1234 branch to master. (Try it!)

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

I also use another method in a project that requires better control. The bad thing of the above is that you might create a conflict during a future merge from deployment-1234 to master. That is okay if those merges are manual. But if you need automatic merges, it is better if I can prevent this systematic conflict. So instead, I created a script that can apply and undo the deployment-specific changes. Then the changes themselves do not need to be in the repository, instead what appears in the repo would be that script.

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