我在一个PHP项目中使用git,我认为它非常方便。但有一件事情如果能实现就更好了。
我创建了一个用于部署的分支。它具有一些不同之处,例如不同的配置文件和文档。
我不能简单地忽略它们,因为那样它们将保留在两个分支中,而我希望在两个分支中保持它们的不同。
问题是当我合并这些分支时,那些要求不同的文件也会被合并。
有没有什么方便的方法来实现这个目标?通常怎么做呢?
我在一个PHP项目中使用git,我认为它非常方便。但有一件事情如果能实现就更好了。
我创建了一个用于部署的分支。它具有一些不同之处,例如不同的配置文件和文档。
我不能简单地忽略它们,因为那样它们将保留在两个分支中,而我希望在两个分支中保持它们的不同。
问题是当我合并这些分支时,那些要求不同的文件也会被合并。
有没有什么方便的方法来实现这个目标?通常怎么做呢?
2021年2月更新:Git本身仍不适合,但GitHub Action环境可能有所帮助。
2009年: 我不确定Git是否应该以这种方式使用。
首先快速提供一下Linus的建议,总是“丰富多彩”的和有信息量的;)
Git非常根本地跟踪项目状态,而不是文件状态。 这意味着您不能尝试“合并文件”。 在Git中这是没有意义的操作。 实际上,在任何允许此操作的SCM中都注定会成为一个彻底的**东西。
(*)我之所以这么说,并不仅仅是因为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
。
进行更改(如果需要,可以推送更改)。
每当您的主分支(或您从中进行部署的任何其他分支)有您要部署的更改时,只需运行git pull --rebase
。
这是一个简单的解决方案,对我非常有效,但我不能确定它是否像其他人所说的那样“糟糕”,但对于我们的目的来说确实非常有用。
简短回答是,永远不要合并分支。事实上,你根本不需要合并它们,只需从开发(也称“主”)合并到部署以合并修复和通用更改。
cherry-pick 看起来对此很有效(代价是有点污染日志)。
git checkout -b testing 进行更改并提交 git checkout master git checkout -b deploy 进行更改并提交 git checkout master
在主分支下完成所有操作, 使用 git cherry-pick testing 或 git cherry-pick deploy 应用所需的差异,以从当前系统切换到测试或部署版本。
我之前提到过补丁文件。现在我不再使用它们,而是维护部署分支。
也就是说,我从主分支(master)创建一个名为“master-deployed”的新分支,并在该分支上进行更改,这些更改仅需要在构建服务器上的测试版本中(例如,在web.config中添加警告,说明这不是实时版本,并且使用了不同的数据库服务器)。
当构建 bleeding edge 版本时,构建服务器会检出 master-deployed 分支,并在执行常规构建之前将其 rebase 到 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允许您创建模板配置文件,然后为每个开发/暂存/生产环境创建数据配置文件。然后运行“cfg dev”生成“dev”配置文件,“cfg staging”生成暂存配置文件等。
然后我将其与脚本连接起来,这样当我部署到暂存环境时,我会在本地运行“cfg staging”,然后从git更新代码库后,将所有配置文件scp过去。
“实际”的配置文件被设置为被git忽略。到目前为止,这对我非常有效。
目前我有几个补丁文件已经提交了,并且构建服务器会为相关版本应用这些补丁。尽管此刻我有些犹豫。