我正在将 git 用于 PHP 项目,我认为它真的很方便。如果我让它发挥作用,有一件事会很棒。
我创建了一个分支,用于部署。它有一些差异,例如不同的配置文件和文档。
我不能忽略它们,因为那样它们将保留在两个分支中,而我想让它们在两个分支中保持不同。
问题是当我合并分支时,那些本来应该不同的文件也被合并了。
有没有方便的方法来完成这样的事情?这通常是如何完成的?
我正在将 git 用于 PHP 项目,我认为它真的很方便。如果我让它发挥作用,有一件事会很棒。
我创建了一个分支,用于部署。它有一些差异,例如不同的配置文件和文档。
我不能忽略它们,因为那样它们将保留在两个分支中,而我想让它们在两个分支中保持不同。
问题是当我合并分支时,那些本来应该不同的文件也被合并了。
有没有方便的方法来完成这样的事情?这通常是如何完成的?
2021 年 2 月更新:Git 本身仍然不太合适,但GitHub Action 环境可以提供帮助。
2009:我不确定 Git 是否应该以这种方式使用。
首先是一个快速的Linus 建议,总是“丰富多彩”且内容丰富;)
Git从根本上跟踪项目状态,而不是文件状态。这意味着您不能尝试“合并文件”。这是 git 中的一个毫无意义的操作,事实上,任何允许它的 SCM 都注定是一个彻头彻尾的 sh*t (*)。
(*) 我并不是因为 git 不这样做而这么说。它比这更根本。一旦你开始进行每个文件的分支和合并,你基本上就搞砸了,你将永远无法将项目作为一个“整个项目”来工作——你不再有一个定义明确的历史,实际上是整个项目的历史。
那里。
也就是说,您可以:
此线程中的其他解决方案涉及在部署服务器上处理“特定于服务器”的分支
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)
我做了一些愚蠢的把戏,比如:
config
config.development
和config.production
但不添加config
到存储库cp config.production config
这有任何意义吗?
它对我来说没问题。
这对我有用,我只对部署进行了较小的配置更改(配置文件中的 3 行)。
从 GitHub 或您保存它的任何地方克隆您的存储库。到您希望部署的位置。
运行git checkout -b deployment origin/master
。
进行更改(如果您愿意,请推动它们)。
每当您的 master(或您进行部署的任何分支)有您想要部署的更改时,只需git pull --rebase
.
这是一个简单的解决方案,它肯定对我有用,我不能说它是否像其他人建议的那样使它“shi*t”,但它肯定对我们的目的非常有用。
快速回答是,永远不要合并分支。事实上,您根本不需要合并它们,只需从开发(又名“主”)合并到部署以合并修复和通用更改。
如果您想保持历史记录良好,可以将部署文件保存在干净分支之上的一些提交中。然后,当需要部署新版本时,检查部署分支和“git rebase master”,将这些提交放在原始分支之上。
这样,您还可以轻松更改配置文件,并使用“git commit --amend”更改顶部提交。
我之前提到过补丁文件。我现在已经取消了这个,而是维护部署分支。
即,我使用一个名为“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
我遇到了类似的问题,并创建了一个名为 config-magic 的小项目来帮助管理它。
Config-magic 允许您创建模板 conf 文件,然后为每个 dev/staging/production 创建数据配置文件。然后运行“cfg dev”来生成“dev”配置文件,“cfg staging”来生成登台配置等。
然后我将它与脚本连接起来,这样当我部署到登台时,我在本地运行“cfg 登台”,然后在从 git 更新代码库后对所有配置文件进行 scp。
“实际”配置文件设置为被 git 忽略。到目前为止,这对我来说非常有效。
我正在考虑针对我的情况的所有这些解决方案,但似乎没有一个适用。我在我的实时服务器和开发服务器上进行编辑。如果您不需要重新发布该分支,Rebase 效果很好,但是我在我的部署分支上进行了更改并将这些更改发布回主存储库。仅当您的文件位于单独的子目录中时,子模块方式才有效,我的配置文件位于多个位置。合并我们的方法也不能很好地工作,因为我必须先拉那个分支,然后再拉大分支。如果仍然有他们的合并可能会起作用,并且我可以在需要时拉入正确的配置分支。现在 .gitignore 有效,我只是手动上传文件。
在做了更多研究之后,我发现我的解决方案是在实时站点上没有 git repo,而是使用暂存站点通过暂存/实时配置文件将最新更改拉入我的分支。然后通过 git archive 部署并将文件提取到我的实时站点上。
cherry-pick 似乎为此工作(以稍微污染日志为代价)。
git checkout -b testing 进行更改并提交 git checkout master git checkout -b deploy 进行更改并提交 git checkout master
在 master 和 git cherry-pick testing 或 git cherry-pick deploy 下执行所有操作,以应用从当前系统切换到测试或部署版本所需的差异。
目前我签入了几个补丁文件,构建服务器将这些补丁应用于相关版本。虽然我现在对此有第二个想法
这既简单又干净。
您将创建一个部署分支,例如:
> 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 期间产生冲突。如果这些合并是手动的,那没关系。但是如果你需要自动合并,我最好能防止这种系统冲突。因此,我创建了一个脚本,可以应用和撤消特定于部署的更改。然后更改本身不需要在存储库中,而是出现在存储库中的是该脚本。