“Layering”git存储库
我现在每天都在使用git,而这次我遇到了一个我可以这样描述的问题。“Layering”git存储库
我有一个存放整个网站结构的仓库,web根目录位于仓库的根目录。一切都很好,直到这是一个单一网站的存储库。然而,同一个回购现在用于几个网站 - 基本上是相同的网站,用不同的语言,小模板调整,不同的图形等等。这些东西自然是版本化的。
有一个主分支,它拥有该网站的原始源代码,并且我想让主(或其他分支)拥有在所有网站中通用的代码,因为最终会发生变化特定于特定场所以包含在回购的通用部分中。
接下来,每个使用此源代码的站点都有一个分支。所有这些分支(例如,站点1,站点2和站点3)都是从主分支创建的,并且每个站点都克隆了正确的分支。
嗯,这似乎是一个好主意,直到我开始到处进行更改。
如果我在site1分支上进行了更改,并且我需要将该更改复制到site2分支,我会从一个分支挑选提交到另一个分支。合并不存在,因为site1分支上有其他更改,它们不属于site2分支。对于这种情况还有其他更优雅的解决方案,还是樱桃采摘正是为了这个目的?
现在,我真正的“问题”是当我改变主人,然后我想将所有这些改变复制到所有分支。当然,考虑到所有分支都是主人的后代,而我做想要在所有网站*分支的变化,我切换到每个分支和合并主人。
这会为所有分支创建一个非常讨厌的历史。每一轮合并的相当复杂图形,这使我得出两个结论:
- 分层分支机构只要我看我的步骤,并且没有做任何愚蠢的可以工作的这种方式,而不是试图让任何意义在所有分支机构的历史图表中。或..
- 必须有一些更好,更合适的方式来做到这一点。
为了说明我的“问题”,我将给出一个创建这些分支后得到的图形图像,添加了很少的分支特定提交,挑选其中的几个,添加和合并来自主机的一个提交到所有分支,提交或两个特定的分支,然后再进行一次主合并。
我不知道,我喜欢简单,也许我不习惯看到难以遵循这样一个图表(这只会在复杂每以下合并长大,我'我害怕)。
我想我可以一路做樱桃采摘,并有整洁的历史图,但这听起来也不对,因为我可能会连续做几次提交,然后忘了选择其中一个所有其他分支...
所以...任何想法,经验,建议,你不介意分享?
更新:我在接受的答案的评论中选择了一个解决方案。感谢所有贡献的人!
更新2:即使它不是密切相关的这个问题,recently I stumbled upon this model of branching这似乎是适用于几乎任何有组织的开发周期,以GIT作为基本DVCS。这是一个非常好的阅读。推荐的。
备选答案:
您可以将分支级别的抽象级别移动到存储库级别。用主分支创建一个主库。为每个站点克隆这个存储库。在主分支上进行更改时,请将这些更改拖入每个站点回购站。这样你就只需要每个回购一个主分支。
原来的答复:
当主分支已经改变,你可以变基的其他分支到更新的主分支。假设您有pl_site基于掌握一些承诺和主人发生了变化:
o---o---o---o---o master
\
o---o---o---o---o pl_site
已重订pl_site后,它看起来像:
o---o---o---o---o master
\
o'---o'---o'---o'---o' pl_site
注意上衍合版本提交pl_site是新的。现在,pl_site包含对主设备所做的更改。
命令:
$ git checkout pl_site
$ git rebase master
这只能让你到目前为止。一年之后,这种变化可能行不通,而且为了达到这个目的,你最终可能会毁掉历史。 (也就是说,第一次提交超过'master'的pl_site'的'并不一定总是适用于master'的的'任何将来的版本。) – Cascabel 2011-05-12 12:23:12
这并不解决实际问题,'rebase'只是破坏提交历史等等它看起来很漂亮。 – 2011-05-12 12:28:24
@Dietrich:它的历史,那相貌丑陋,所以无论你容忍,它被破坏,或者你把它丑陋的(或者你找到一个工具,只是打印它漂亮:d) – KingCrunch 2011-05-12 12:30:24
我没有给你一个很好的答案,因为你的问题是复杂的,有复杂的解决方案。
选项1:重构
你说的是不同的网站是“基本相同的网站”。因此,将它们移到不同的项目中,并将main_site
保存在一个项目中。其他网站将包括main_site
作为子项目。
所以,横幅......
en_site/
en_site/images/banner.jpg
en_site/master/
en_site/master/images/banner.jpg
您的网站代码,配置脚本,部署脚本,或任何将确保images/banner.jpg
选择了master/images/banner.jpg
。也许当你部署网站master/images
首先被复制,然后images
被复制,也许你做更复杂的事情。
这可能是很多工作。然而,当你看看历史,你会得到这样的事情:
en_site: A -> B -> C -> D
de_site: E -> F -> G -> H -> I
main_site: J -> K -> L -> M -> N -> O
选项2:使用的darcs
在的darcs,你可以从分支移动补丁分支。一些商业VCS也可以做到这一点。所以,你的分支应该是这样的:
master: patch1 patch2 patch3 patch4
en_site: patch1 patch2 patch3 patch4 en1 en2 en3
de_site: patch1 patch2 patch3 patch4 de1 de2 de3
假设你想将补丁en2
德国网站。
de_site: patch1 patch2 patch3 patch4 de1 de2 de3 en2
Voila。但是,这并不像看起来那么干净。 Darcs爱好者会指出,这个补丁模型与我们的“将补丁移动到另一个分支”的概念模型相匹配,但是,这掩盖了事实,即您仍然需要测试以确保en2
补丁不会破坏所有内容当你把它放在de_site
。
例如,如果en2
将代码的相同部分更改为de1
会怎么样?然后怎样呢?无论您使用的是什么VCS,您都必须手动合并。对于每一个这样的明显情况,VCS都不会检测到另一个案例,您必须自己检查。
我的经验
当我使用git
第一次开始,这似乎是git merge
是神奇的。但是,没有任何VCS技巧会掩盖事实,即您的网站存在一些非常复杂的相互依赖关系。您可以重构您的站点以消除相互依存关系,或者希望您的VCS历史不会变得如此复杂以至于无法再理解它。
新枝,新项目,重构事物之间的权衡成库是一个微妙的权衡。维护大量的补丁集比维护大量使用公共库的大量项目工作要多得多,重构所需的(大量)工作量可能会很快得到回报。或者它可能不会。
我在十字路口上正确地描述了您所描述的内容。因此,无论我要以某种合理的方式重构并实施这些每个站点的具体内容,以便他们可以相互覆盖,或者我将选择不那么简单但可维护的基于VCS的解决方案,同时保持代码完整。感谢您的想法。 – 2011-05-12 12:41:55
太少时间的答案,但看看'rebase'。 – KingCrunch 2011-05-12 11:39:15
合并可能并不像您想象的那么糟糕。从根本上说,合并意味着“将另一个分支的所有东西都合并到这个分支中” - 这听起来像是你想要做的。你可能想使用'git merge --log'在合并提交消息中包含合并提交的主题列表,然后使用'git log --first-parent'(或'gitk --first-parent ')查看siteX分支上的历史记录。 – Cascabel 2011-05-12 12:30:14