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
)
)