DVCS (Mercurial) 不适合我吗?
我在一家公司工作,我们创建了许多特定于客户的小型应用程序。 我们有几个开发人员,但大多数时候每个项目只有一名开发人员。
Customer1
ProjectX
App
Tests
ProjectY
App
Tests
Customer2
Project2
Products
Product1
Common
如今,所有内容都存储在一个存储库中。
过程很简单。
- 开发人员为客户承担一个新项目 为该项目
- 创建一个新文件夹
- 新项目中的代码
- 在另一个项目中进行一些维护
- 签入维护项目的更新
- 新项目中的更多工作
- 签入新项目
- 交付给客户
没有标记,也没有分枝。早期版本是根据日期签出的。
这个过程多年来一直运行良好,但当前工具 (CVS)
- 速度缓慢,存在一些痛点。即使没有任何改变,结账也需要几分钟。历史记录存储在服务器上,因此差异需要很长时间
- 添加新项目。如果您使用过 CVS,您就会知道它就像:添加文件夹、在文件夹中添加文件、添加下一个文件夹...
- 无法消除明显的错误(签入二进制文件等)
- 。不支持重命名,这使得必要的重构更加痛苦。
我私下使用 Mercurial 一段时间了,并希望将其扩展到所有开发人员。
我可能全都错了,但有一些事情我不明白如何在我们的组织中实施。
CVS 提交仅适用于当前文件夹,但在 Mercurial 中,它们是存储库范围内的。 在我们的例子中,这意味着在一个文件夹中提交维护工作也会在另一个文件夹中提交尚未完成的内容。 (我假设我们可以在更改的文件夹中执行 hg ci ./**
但合并时不允许这样做,至少文档是这么说的如果您要提交合并的结果,不要提供任何文件名或 -I/-X 过滤器。
)
Mercurial 中的常见做法是每个项目有一个存储库。
每个项目一个存储库对我们来说是可以的,但它会产生一些其他问题,例如:
如何管理中央服务器上的多个存储库?
如果开发人员创建了一个新项目,他最终需要推动他的更改。 只是执行
hg Push http://localhost:8000/Customer1/NewProject
崩溃hg-webserver 具有丑陋的堆栈转储并挂起客户端。
我的理解是,开发人员需要访问服务器 shell 将新存储库添加到配置文件并重新启动 hgweb
另一种方法是使用 SSH 或共享 (使用 SSH 代替文件共享有好处吗?)
cd Customer\NewProject
hg init
hg clone --noupdate --pull . //mercurialshare\Customer\Project
echo "[paths]" >.hg\hgrc
echo "default=//mercurialshare\Customer\Project" >>.hg\hgrc
hg push
可行,但对于某些开发人员来说有点复杂
所有开发人员都需要拥有所有项目。
(并非所有项目都是链接的,但许多项目都是链接的,因此它们需要存在,并且最简单的是拥有所有项目)
由于许多现有项目和每周添加的新项目,我们需要一种方法来一次性拉出所有项目并克隆新项目。
我认为子存储库可以解决“全球”拉力,但以下 文档中的一行是一个精彩的
“当我们提交时,Mercurial 将尝试创建整个项目及其子存储库状态的一致快照。 它通过首先尝试在所有修改的子存储库中提交,然后记录所有子存储库的状态来实现这一点。”
回到全局提交的单一存储库问题。
(尝试了 hg ci .hgsub .hgsubstate
但 .hgsubstate 似乎只在完全提交时更新,如果项目文件夹中没有明确的 hg pull --update
,其他用户将看不到项目更改)
我目前的想法是根目录中提取所有项目的批处理文件有关
如何在我们的组织中使用 Mercurial 的任何其他想法吗?
编辑
感谢您的回复,我目前正在评估每个项目的一个存储库如何为我们工作。将批处理文件放在顶层
FOR /F %%x IN (repolist.txt) DO (
If EXIST .\%%x\.hg (
ECHO Pull %%x
hg pull --update --repository .\%%x
) ELSE (
ECHO Clone %%x
mkdir .\%%x
hg clone --pull %1\%%x .\%%x
)
)
I work in a company where we create a lot of small customer-specific applications.
We are a few developers but most of the time there is only one developer per project.
Customer1
ProjectX
App
Tests
ProjectY
App
Tests
Customer2
Project2
Products
Product1
Common
Today everything is stored in a single repository.
The process is simple.
- A developer takes on a new project for a customer
- Create a new folder for the project
- Code in new project
- Do some maintenance in another project
- Check in updates to maintenance project
- More work in new project
- Check in new project
- Deliver to customer
There is no tagging nor branching. Earlier versions are checked out based on date.
This process has served well for many years but there are a few pain points with the current tool (CVS)
- Slow. Checkout takes minutes even if nothing has changed. History is stored on the server so diffs takes too long time
- Adding new projects. If you worked with CVS you know it is like: add folder, add files in folder, add next folder...
- No way to back out obvious errors (checking in binaries etc)
- No support for renaming which makes necessary refactoring even more painful.
I have used Mercurial privately for some time and would like to extend it to all developers.
I might have got it all wrong but there are a few things that I don't understand how to implement in our organization.
CVS commits are current folder only but in mercurial they are repository wide.
In our case it means that committing maintenance work in one folder will also commit yet unfinished stuff in another folder.
(I assume we could do hg ci ./**
in changed folders but that is not allowed on merge, at least that is what the documentation says If you are committing the result of a merge, do not provide any filenames or -I/-X filters.
)
The common practice in Mercurial is to have one repository per project.
One repository per project is OK for us but it creates some other issues like:
How to manage multiple repositories on the central server?
If a developer creates a new project he eventually need to push his changes.
Just doing
hg push http://localhost:8000/Customer1/NewProject
crashes the hg-webserver with an ugly stack dump and hangs the client.
The way I understand it is that the developer need access to the server shell to add the new repository to a configuration file and restart hgweb
The alternative is to use SSH or a share
(are there benefits using SSH instead of a file share?)
cd Customer\NewProject
hg init
hg clone --noupdate --pull . //mercurialshare\Customer\Project
echo "[paths]" >.hg\hgrc
echo "default=//mercurialshare\Customer\Project" >>.hg\hgrc
hg push
Works, but is a bit to complicated for some developers
All developers need to have all projects.
(Not really all but many projects are linked so they need to be present and it is easiest to just have all)
With many existing projects and new ones added weekly we need a way to pull all projects in one go and also clone new ones.
I was thinking that subrepos could solve the "global" pull but the following
line in the documentation is a showstopper
"When we commit, Mercurial will attempt to create a consistent snapshot of the state of the entire project and its subrepos.
It does this by first attempting to commit in all modified subrepos and then recording the state of all subrepos."
Back to the single repository problem of global commits.
(Tried a few variants of hg ci .hgsub .hgsubstate <subrepo>
but .hgsubstate seem to only be updated on full commits. Other users will not see project changes without an explicit hg pull --update
in the project folder)
My current thinking is to have a batch file in the root that pulls all projects
Any other ideas on how to use mercurial in our organization?
Edit
Thanks for the reply. I am currently evaluating how one repository per project will work for us. I put a batch file at the top level
FOR /F %%x IN (repolist.txt) DO (
If EXIST .\%%x\.hg (
ECHO Pull %%x
hg pull --update --repository .\%%x
) ELSE (
ECHO Clone %%x
mkdir .\%%x
hg clone --pull %1\%%x .\%%x
)
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您有权说 Mercurial 是为每个存储库的一个项目而设计的。当您像这样工作时也会好得多,因为不同项目的历史记录是分开的。
尝试在 DVCS 存储库中包含多个项目只会带来痛苦。
就我个人而言,我更喜欢通过 SSH 而不是 HTTP 来服务项目。原因之一是能够...
如果您通过 HTTP 提供服务,则这不起作用(正如您所发现的)。我很惊讶它会导致严重崩溃:-/
获取所有项目的子存储库方法并不完全像您所描述的那样。并不是说你回到了全局提交(项目可以单独开发),而是超级项目存储了它所依赖的子项目的版本。如果您(例如)有一个库作为子项目,那么这正是您想要的,但版本取决于特定版本。实际上,子存储库链接是特定版本另一个存储库的书签。
但这并不是你真正想要的。
也许,通用的东西应该是需要它的项目的子存储库。然后,每个项目可能会被冻结在相同代码的不同版本上,并且您不会遇到任何问题。这需要稍微考虑一下。
否则,脚本的想法可能是最简单的。
Your right in saying that Mercurial is designed for one project per repo. It's also a lot nicer when you work like this because the history of different projects are kept separate.
Trying to have multiple projects in a DVCS repo just causes pain.
Personally I prefer serving projects via SSH rather than HTTP. One reason is the ability to...
If you're serving via HTTP this doesn't work (as you've found out). I'm surprised it causes a hard crash though :-/
The sub-repos method of getting all projects isn't quite as you describe it. It's not that you're back to global commits (projects can be developed individually), but that the super-project stores the version of the sub-projects it depends on. This is exactly what you want if you have (for example) a library as a subproject, but the release depends on a specific version. Effectively a sub-repo link is a bookmark into another repo at a specific version.
Not really what you're after though.
Possibly, the common stuff should be a sub-repo of the projects that need it. Each project might then be frozen on a different version of the same code and you've got no problems. That would need a little thinking about.
Otherwise the script idea is probably easiest.