“分叉” git 中自己的项目
我目前遇到以下情况:我需要维护一个存储库,其中包含本质上相同项目的多个版本作为子目录。让我们将开发/最重要的项目称为“main”,将其他项目称为“sub_1”,...,“sub_n”。
这些版本虽然不同,但基本相同:想想这样的例子:Android 2.1 的 Android 项目(而不是您开发的 2.2+)、针对 IE6 的修改后的 CSS 样式表、针对大型客户端的自定义构建等等。每个版本通常都有一个“主”文件的子集,并进行了较小的修改。
目前我正在使用以下方法来更改项目中的文件:
- 对于 0≤i≤n
- 查看 sub_i 使用的文件
- 用 main 中的正确文件覆盖 sub_i 使用的文件
- 比较更改,忽略属于 main 一部分的更改但重新应用 sub_i 对文件所做的“补丁”
显然这个过程是乏味且容易出错的。我已经搜索了几种方法来做到这一点,基本上有以下内容:
- 我现在正在做什么。由于上述原因不太理想
- 分支。这看起来确实是最有希望的,但我不知道如何仅分支存储库的一部分。 (如果我做了一个完整的分支,我仍然没有办法有效地合并文件)
- 子模块。这些可能有效,但据我了解,它们仅用于完全外部项目,而不用于同一存储库的副本
有谁知道执行此操作的正确方法吗?
请注意,维护 /main 和 /sub_i (git 存储库作为根)目录结构是可取的,因为更改它可能会破坏很多东西(不是软件本身,而是主要是构建工具等)
I currently have the following situation: I need to maintain a repository which contains multiple versions of essentially the same project as subdirectories. Lets call the dev/most important project "main" and the other projects "sub_1",...,"sub_n".
The versions are distinct, but largely the same: think of examples like an Android project for Android 2.1 instead of the 2.2+ your develop for, a modified CSS Stylesheet for IE6, a custom build for a large client, those sort of things. Each version usually has a subset of the "main" files with minor modifications.
Currently I'm using the following method to change the files in the project:
- For 0≤i≤n
- Look at the files sub_i uses
- Overwrite the files sub_i uses with the correct ones from main
- Diff the changes, ignore changes which are part of main but re-apply the "patches" sub_i did to the files
Obviously this process is tedious and error-prone. I have searched for a few ways to do this and essentially have the following:
- What I'm doing now. Less than ideal for described reasons
- Branching. This does look the most promising but I do not know how I would branch only a part of the repository. (if I do a full branch I still don't have a way of merging the files efficiently)
- Submodules. These might work but from what I understand they're only to be used for fully external projects and not for copies of the same repository
Does anyone know the correct way to do this?
Note that maintaining the /main and /sub_i (git repository as root) directory structure is desirable, since changing that could break a lot of things (not the software itself but mainly the build tools etc.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
子存储库方法
当我理解正确时,您的存储库看起来像这样:
其中 main 的作用类似于某种库或框架,而 sub_1..sub_N 或多或少是同一软件的不同分支。一种解决方案是将 main 作为 sub_1..sub_N 的子模块,因此最终树看起来像
这里所有 sub_1..sub_N 文件夹都是单个存储库的不同分支,并且您的 main/ 文件夹是不同的存储库。这是一种可能的方法,如果所有 sub_X 文件夹都是从公共基础派生的,并且很容易在此公共基础上进行开发,并从公共基础合并到 sub_X 分支以分发这些更改。但是这种情况有一个很大的缺点:它需要使用这种结构进行开发的每个人都确切地知道他在做什么,因为 sub_X 分支上的开发不容易通过合并分发到公共基础或其他 sub_Y 分支,因为合并操作不仅会将新的更改传输到其他分支,还会将导致 sub_X 分支不同于 base 或 sub_Y 的更改传输到其他分支。所以一般来说我会建议不要采用这种方法。
专业化
另一种方法是隔离 sub_X 更改,并创建一个基本版本,其中包含 sub_1..sub_N 中相同的所有内容,以便 sub_X 文件夹仅包含专用内容。如果这是一种可用的方式,这取决于您的开发/部署策略。
真正的分支
由于您写道 sub_X 文件夹是 main 的副本,因此看起来 main 已经充当所有 sub_X 文件夹的公共基础。如果是这种情况,您可以将不同的文件夹更改为分支。您可以通过
git checkout -b main
)commit
对于每个 sub_X 文件夹
git checkout -b sub_x main
)之后你有一个版本如下图:
然后你可以在主分支上开发新功能,并将这些功能合并到 sub_X 分支中。多分支设置的主要问题是,您始终需要决定新开发的正确起点,因为如果您没有使用正确的方法,合并操作将在分支之间传输不需要的更改起点。正确的起点是修订版,它是所有分支的祖先,新的更改应该去那里。如果你想开发一个影响所有 sub_X 分支的 bug 修复,你需要在 main 中开发这个 bug 修复,因为 main 是所有 sub_X 分支的共同祖先。 OTOH,如果您对 sub_23 有一些非常特别的东西,那么在 sub_23 分支上开发这些东西是正确的。
Subrepo approach
When I understand you right, your repo looks like this:
Where main acts like some sort of library or framework, and sub_1..sub_N are more or less different branches of the same software. One solution would be to place main as submodule of sub_1..sub_N, so in the end the tree would look like
Here all your sub_1..sub_N folders are different branches of a single repo, and your main/ folder is a different repo. This is a possible way, if all sub_X folders are derived form a common base, and it is easy to develop on this common base and do merges from the common base to the sub_X branches to distribute these changes. But there is a big drawback of this scenario: it needs that everyone who develops with this structure knows exactly what he does, since development on a sub_X branch is not easy to distribute to the common base or other sub_Y branches via merge, since a merge operation would not only transfer the new changes to the other branches, but also the changes which makes the sub_X branch different from base or sub_Y. So generally I would advise against this approach.
Specialization
Another approach would be to isolate the sub_X changes, and create a base version which consists all stuff which is same in sub_1..sub_N, so that the sub_X folders only consists of the specialized stuff. It depends on your development/deployment strategy if this is a usable way.
Real branches
Since you wrote that the sub_X folders are copies of main, it looks that main already acts as the common base for all sub_X folders. If this is the case, you can change the different folders into branches. You can achieve this by
git checkout -b main
)commit
for each sub_X folder
git checkout -b sub_x main
)Afterwards you have a version graph like this:
Then you can develop new features on the main branch, and merge these features to the sub_X branches. The main thing with a multiple branch setup is, that you always need to decide the correct starting point for a new development, since a merge operation will transfer unwanted changes between branches, if you did not used the correct start point. The correct starting point is the revision, which is the ancestor of all branches, where the new change should go. If you want to develop a bugfix for something which affects all sub_X branches, you need to develop this bugfix in main, since main is the common ancestor of all sub_X branches. OTOH if you have something very special for sub_23, it is correct to develop the stuff on the sub_23 branch.