版本控制:多版本地狱、文件同步
我想知道你通常如何处理这种情况:
我有一组实用函数。比如说..5..10 个文件。从技术上讲,它们是静态库、跨平台 - SConscript/SConstruct 加上 Visual Studio 项目(不是解决方案)。
这些实用函数用于多个小型项目(15+,数量随着时间的推移而增加)。每个项目都有一些文件或整个库的副本,而不是指向某个中心位置的链接。有时项目使用一个文件、两个文件,有些则使用所有文件。通常,实用程序函数作为每个文件和 SConscript/SConstruct 或 Visual Studio 项目的副本包含在内(取决于情况)。每个项目都有一个单独的 git 存储库。有时一个项目源自其他项目,有时则不然。 您以随机顺序处理其中的每一项。没有其他人(为了让事情变得更简单)
,当您在一个项目上修改这些实用函数文件时,就会出现问题。
因为每个项目都有一个文件副本,所以这会引入新版本,当您稍后(例如一周后)尝试猜测哪个版本具有最完整的功能时,这会导致混乱(即您在 a.cpp 中添加了一个函数)一个项目,并在另一个项目的 a.cpp 中添加了另一个函数,从而创建了版本分支)
您将如何处理这种情况以避免“版本地狱”? 我能想到的一种方法是使用符号链接/硬链接,但它并不完美——如果你删除一个中央存储,它就会完蛋。并且硬链接在双引导系统上不起作用(尽管符号链接可以)。 看起来我需要的是类似高级 git 存储库的东西,其中项目的代码存储在一个本地存储库中,但与多个外部存储库同步。但我不确定如何做到这一点,或者是否可以使用 git 来做到这一点。
那么,你觉得怎么样?
I would like to know how you normally deal with this situation:
I have a set of utility functions. Say..5..10 files. And technically they are static library, cross-platform - SConscript/SConstruct plus Visual Studio project (not solution).
Those utility functions are used in multiple small projects (15+, number increases over time). Each project has a copy of a few files or of an entire library, not a link into one central place. Sometimes project uses one file, two files, some use everything. Normally, utility functions are included as a copy of every file and SConscript/SConstruct or Visual Studio Project (depending on the situation). Each project has a separate git repository. Sometimes one project is derived from other, sometimes it isn't.
You work on every one of them, in random order. There are no other people (to make things simpler)
The problem arises when while working on one project you modify those utility function files.
Because each project has a copy of file, this introduces new version, which leads to the mess when you try later (week later, for example) to guess which version has a most complete functionality (i.e. you added a function to a.cpp in one project, and added another function to a.cpp in another project, which created a version fork)
How would you handle this situation to avoid "version hell"?
One way I can think of is using symbolic links/hard links, but it isn't perfect - if you delete one central storage, it will all go to hell. And hard links won't work on dual-boot system (although symbolic links will).
It looks like what I need is something like advanced git repository, where code for the project is stored in one local repository, but is synchronized with multiple external repositories. But I'm not sure how to do it or if it is possible to do this with git.
So, what do you think?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通常的简单方法是将库作为版本控制中的项目,如果有修改,则仅编辑该项目。
然后,其他需要该库的项目就可以从该库项目中获取所需的文件。
The normal simple way would be to have the library as a project in your version control, and if there is a modification, to edit only this project.
Then, other projects that need the library can get the needed files from the library project.
我并不完全清楚你想要什么,但也许 git 子模块可能会有所帮助: http://git -scm.com/docs/git-submodule
It is not completely clear to me what you want but maybe git submodules might help : http://git-scm.com/docs/git-submodule
在 Subversion 中你可以使用外部(我知道这不是 GIT,但这些技巧可能仍然有帮助)。它的工作原理如下:
您也可能拥有应用程序的版本。还引入了通用代码中的版本。因此,您的应用程序将在存储库中包含以下文件夹:
同样,使用版本号将版本添加到通用代码,如下所示:
或者使用日期,如下所示:
MYAPP\TRUNK 的外部应该指向 \COMMON\TRUNK,这是显而易见的。
尝试将common-code的版本与应用程序的版本同步,这样每次应用程序版本固定时,common-code也固定,应用程序版本将指向外部相关的common-code。
例如,\MYAPP\V1 的外部可能指向\COMMON\2010JAN01。
这种方法的优点是每个开发人员现在都可以扩展、改进、调试通用代码。缺点是应用程序的编译时间会随着公共代码的增加而增加。
另一种方法(将库放入版本系统中)的缺点是,公共代码的管理(扩展、改进、调试)始终与应用程序的管理分开进行,这可能会阻止开发人员编写通用的公共代码(每个人都开始编写自己版本的“通用”类)。
另一方面,如果您有一个明确且灵活的团队单独负责公共代码,那么在最后一种选择中,公共代码将受到更好的控制。
In Subversion you can use externals (it's not GIT I know, but these tips might still help). This is how it works:
You will also probably have versions of your application. Also introduce versions in the common code. So your application will have the following folders in the repository:
Similarly, add versions to the common-code, either using version numbers, like this:
Or using dates, like this:
The externals of \MYAPP\TRUNK should point to \COMMON\TRUNK, that's obvious.
Try to synchronize the versions of the common-code with the versions of the applications, so every time an application version is fixed, also the common-code is fixed, and the application version will point to the relevant common-code external.
E.g. the externals of \MYAPP\V1 may point to \COMMON\2010JAN01.
The advantage of this approach is that every developer can now extend, improve, debug the common-code. Disadvantage is that the compilation time of applications will increase as the common-code will increase.
The alternative (putting libraries in your version system) has the disadvantage that the management (extending, improving, debugging) of the common code is always done separately from the management of the applications, which may prevent developers from writing generic common code at all (and everyone starts to write their own versions of 'generic' classes).
On the other hand, if you have a clear and flexible team solely responsible for the common code, the common code will be under much better control in the last alternative.
在配置(一般)术语中,解决方案是拥有多个主干(分支):
发布
该主干/分支包含已通过质量保证并可以发布给客户的软件。发布后,所有文件都被标记为“只读”。它们被赋予一个标签来识别带有版本号的文件。
测试专家会定期或根据需要从集成主干获取最新(提示)版本并提交进行严格的质量测试。这就是集成版本升级为发布版本的方式。
集成
该主干包含最新的工作代码。它包含错误修复和新功能。在每个错误修复或新功能之后应对文件进行标记。
在错误通过质量测试或新功能完全开发(和测试)后,代码将移至集成分支。这里的一个好主意是在集成开发人员的代码之前使用临时标签来标记集成版本。
发展
这些是开发人员为了修复错误或开发新功能而创建的分支。这可以是移动到本地计算机上的所有文件的副本,也可以只是需要修改的文件的副本(包含所有其他文件的集成主干的链接)。
在干线之间移动时,代码必须通过资格测试,并且必须有移动到干线的权限。例如,未经授权不得将无根据的新功能放入集成分支。
在您的情况下,文件需要在修改后重新签入集成主干,或者如果代码与以前的版本差异太大(例如添加新功能),则需要重新签入整个新的分支或主干。
我一直在研究 GIT 和 SourceSafe 试图找出如何实现这个模式。该模式很容易在 PVCS 和 ClearCase 等大型配置管理应用程序中实现。看起来对于 GIT,重复的存储库是必要的(每个主干一个存储库)。 SourceSafe 明确指出,每个版本只允许一个标签,因此未更改的文件将丢失标签信息。
In Configuration (general) terms, a solution is to have multiple trunks (branches):
Release
This trunk / branch contains software that has passed Quality Assurance and can be released to a customer. After release, all files are marked as "read-only". The are given a label to identify the files with the release number.
Periodically or on demand the testing guru's will take the latest (tip) version from the Integration trunk and submit to grueling quality tests. This is how an integration version is promoted to a release version.
Integration
This trunk contains the latest working code. It contains bug fixes and new features. The files should be labeled after each bug fix or new feature.
Code is moved into the integration branch after the bug has passed the quality testing or the new feature is fully developed (and tested). A good idea here is to label the integration version with a temporary label before integrating developer's code.
Development
These are branches made by developers for fixing bugs or developing new features. This can be a copy of all the files moved onto their local machine or only the files that need to be modified (with links to the Integration trunk for all other files).
When moving between trunks, the code must pass qualification testing, and there must be permission to move to the trunk. For example, unwarranted new features should not be put into the integration branch without authorization.
In your case, the files need to be either checked back into the Integration trunk after they have been modified OR a whole new branch or trunk if the code is too different from the previous version (such as adding new features).
I've been studying GIT and SourceSafe trying to figure out how to implement this schema. The schema is easy to implement in the bigger Configuration Management applications like PVCS and ClearCase. Looks like for GIT, duplicated repositories are necessary (one repository for each trunk). SourceSafe clearly states that it only allows one label per version, so files that have not changed will loose label information.