Source Control and Redesign - mercurial

I'm working on my own open-source project. I've recently released the first workable version but I doubt anyone is using it. I'm the only one working on it. I'm using mercurial and my question is I'm planing a pretty big redesign. Not many stones will remain unturned. How to I tackle this in term of source control? Just continue from current head or create a branch?
How often do I commit? Some classes might disappear (split into 2 or functionality moved elsewhere, interface changes).

I'd branch the new version if there were any current users of the code (including yourself) who should stay on that for a while. Merge it back in when the new version is (by whatever measure) equal or better to the old version.
Another consideration is "if a new user comes to look, would I want them to use the old version I am abandoning or try the version I'm making that'll be in even more flux". If they should stay on the old version then again branch off for the new one.
More likely though your choices are between
just continuing work on head ("nobody should ever get encouraged to use the old version") or:
branch off a "stable" or "release-1" branch ("use this if you want something that's old but feature complete/reasonably functional/...") and then doing the new work on HEAD.

Note: I don't know mercurial (I'm using git or svn...)
First, since you are the only one committing code on your project, it does not matter that much. It would matter if other people contributed code.
I would create a branch (at least under git), and I would also tag the state of your code before the redesign.
Do you intend to maintain the old version (with bug-fixes)? I suppose that not. If you do, you probably have to get two branches, one for the version 1 and another for the re-designed version 2.
Perhaps you want to make a branch of the old version, and continue the master branch with the new one.
Regarding frequency of commits, I always suggest doing it very often (e.g. at least each day you work on it, and probably fot each single major feature or bug fix you introduce.). But each commit should (in principle) stay compilable, and should work somehow (whatever that means for you).
It would be interesting if you did mention your open source project explicitly.
Regards

Related

Is restarting a branch a good idea?

In a software I develop I have a main stable branch (default or prod) from which I develop new ideas.
I believe that usual way to do that is to start a branch, work on it and either abandon it (leave it as it is, close it, delete it) or merge into the default one.
A lot of my development are small tests which I would be glad doing in a dev branch, which I would ultimately merge into default, then restart with new ideas in dev.
Are there major drawbacks with such an approach?
The main one I see is what to do in case of a "bad" idea which I would like to discard. I could leave the existing dev hanging, start a new dev branch and end up with several HEADs for one branch - which does not sound like a good idea (but objectively I dot know why).
In short: is restarting a branch, overall, a good idea and is having potentially multiple HEADs because of that a true problem?
I would describe your proposed course of action as having a non-linear dev branch, i.e., it may have unnamed heads that are never merged into the main line. (Repeatedly merging work from dev into default doesn't necessarily make it non-linear in this sense). Mercurial has no trouble managing configurations like this, so technically speaking it's not problematic.
But if you feel that this would make your history hard to navigate, you might want to use a richer set of branch names. A compromise solution would be to do all your experiments in dev, but use tags to distinguish and identify the different branch heads. I often do that when I put aside an idea (or abandon it for good).
There is no issue with having multiple heads at all. Besides you can close (thus in essence hide) old, abandoned heads, if you think they should vanish from plain sight.
On the contrary, I would start a separate head for each new idea or feature I code, so that I can follow different thoughts in parallel. It also allows to merge them into your main line separately.

Using Mercurial to maintain two versions of a program - clone or named branches?

We are using Mercurial to manage a project, but we now want to create a "Lite" version of the same project (ie a version with some of the functionality removed or simplified).
Since the Lite version will share most of its code with the Full version, we are considering whether it is better to either:
Create a clone of the original project and keep each project separate.
Use named branches to maintain both versions of the project within the same repository.
We are fairly new to version control software and this will be the first time that we have used named branches. Can someone please help outline the pros and cons of each approach. Which approach would make it easiest to maintain bug fixes between the two projects?
Thanks,
Andrew
You can use any of 4 methods - they have more or less the same amount of functionality and differ only in used commands for syncing codebase
For "Separate clones" solution "...keep each project separate" is Bad Thing (tm) and violation of DRY principle: re-used code (Lite version) must be maintained in single place and changes in core pulled from Lite repo to Full repo
Note:
When I wrote about 4 solutions, I had in mind, except clones and named branches also
MQ (Lite version is changesets in repository, Full version is MQ-patch(es) on top of Lie in the same repo
Subrepositories|Guestrepo (Lite version is superrepo, Full version functionality is one or more subrepositories in superrepository)
Having the same problem, I stumbled across this question. Now I found a solution which I'd like to share with you.
Suppose we have two devices, A and B, both having essentially the same firmware, but with certain differences which are supposed to be retained. Thus the two versions are retained in two branches - A and B.
If I make now a change at one of the versions, I can merge them over to the other one under certain conditions.
The condition is that the common precedessor (common base) must be of the "giving" branch.
In order to ensure this, you can do
hg debugsetparents . <other branch before the modifications>
After doing this, the current working set is like a merge of two branches, except that the data remains stable, i. e. "we" keep "our" stuff.
After this, you can do a "real" merge with the other branch after the modifications.
The result of doing so is that you get exactly the difference between the manually-created common base in the giving branch and the final state of the giving branch, resulting in exactly the modifications you want to get.

Handle and suggest version number in Mercurial using tags, How to handle Branches

I'm developing an extension for Mercurial that can handle version numbers using Mercurial tags. Currently, it checks if the version number specified is in the right order with the others version numbers in the repository and if it is not too far from the previous one.
However, for now it only work if the repository has only one branch. I'm trying to make it operational on repo with branches and more, on repo with divergent development line (kind of unnamed branch). One of the tricky part is to define what the user can do and what it cannot. For examples, if on branch A there is the version 1.1 and 1.0.1 on branch B I think the Branch B should always stay below 1.1. As I'm not familiar with lots of different way to manage version numbering in branch development, I want to gather use cases and how to handle it.
So, I want to know if someone have already done research on the subject or knows good sources to help me solve this problem. You can also submit use case to handle.
Obviously, I did some research but I cannot find anything really relevant. Probably because I don't know how to express the problem in a concise and search engine comprehensive way.
Edit: Here is what "rules" I figured out for now :
On each branch, the version number should be higher than the previous one (but not too higher)
When you create a branch you can put any version number you want higher than the previous one.
When the first version number is defined on each branch, that define the order for the entire branch. A branch can never overtake another one.
Those rules are inherited by all further branches.
When you merge two branches (actually it is the annoying part), the common mercurial attitude is to consider the result of the merge as a part of the local branch. In my case it seems not to be the right behavior. It's would be very strange if when you merge the 1.0.3 branch with the 1.1.0 version from 1.0.3 that you only can use version below 1.1.0 because this branch is below the other one. The solution I suggest here is always treat the merge as the part of the highest branch otherwise some branch will regress.
Can you tell me if this is consistent or if I miss some important use cases.
The first part of the question is still on topic. If you know any relevant information on the subject or if you know a similar problem please tell me.(after all, its only rules of numbering in a tree)

Mercurial: Class library that will exist for both .NET 3.5 and 4.0?

I have a rather big class library written in .NET 3.5 that I'd like to upgrade to make available for .NET 4.0 as well.
In that process, I will rip out a lot of old junk, and rewrite some code to better take advantage of the new classes and support in .NET 4.0 (like TPL.) The class libraries will thus diverge, but still be similar enough that some bug-fixes can be done to both in the same manner.
How should I best organize this class library in Mercurial? I'm using Kiln (fogbugz) if that matters.
I'm thinking:
Named branches in one repository, can then transplant any bugfixes from one to the other
Unnamed branches in one repository, can also transplant, but I think this will look messy
Separate repositories, will have to reimplement the bugfixes (or use a non-mercurial-integraded compare tool to help me)
What would you do? (any other alternatives that I haven't though of is welcome as well.)
Note that the class libraries will diverge pretty heavily in areas, I have some remnants of old collection-type code that does something similar to Linq that I will remove, and some code that uses it that I will rewrite to use the Linq-methods instead. As such, just copying the project files and using #if NET40..#endif sections is not going to work out. Also, the 3.5 version of the class library will not be getting many new features, mostly just critical bug-fixes, so keeping both versions equally "alive" isn't really necessary. Thus, separate copies of all the files are good enough.
Edit From #Rudi's answer here, I think what he's saying is this:
Create two branches (or keep one "default" and create another branch for the other path, which would be "default"=.NET 4.0, and "net35"=.NET 3.5 in my case)
Develop them along their diverging paths
When a critical bugfix is found, and this exists in both versions (ie. in both 3.5 and 4.0), and can be fixed in common code, since the 3.5 version won't accrue a lot of new functionality, it means the bug was most likely present in the original version (before I branched)
I thus create another branch, off of the original version (or very close to it), implement my bugfix, and then I merge this tip into both the 3.5 and the 4.0 branches to update them both.
I will have to think about this. It seems merging in Mercurial pulls in the files, not the changes, which means any changes done to the files that needs to be bugfixed, risks being "merged" back to an earlier stage, but I'll have to test it.
I would use two clones for the different environments (=basically two anonymous branches), maybe also with different branch names within each clone. Also I would use a new branch for each bug fix or interchangeable feature, starting as nearest to the branch point as possible, to make merges between the main branches easier. I would try to develop the bug fixes in the 3.5 branch, since it is more likely that bug fixes in the 4.0 tree would cause merge problems due to other changes there (I'm not saying that this approach does not cause any problems).

Best Practices for version control with multiple projects

I have several projects with a very large over-lapping code-base. We've just recently started using SVN so I'm trying to figure out how I should be using it.
The problem is that as I'm finishing a task on one project, I'm starting a task on another, with some overlap. Often there's a lot of interrupt driven development as well. So, my code is never really in a completely stable state that I feel comfortable checking in.
The result is that we're not really using the VC system, which is a VERY bad thing, we all know... so, suggestions?
Check out a personal branch of the code and merge in changes. At least you will have some version control for your own changes, in case you need to roll back. Once you are comfortable with the state that your branch is in, merge that branch back into the trunk.
You can also check out a branch for each task, instead of one for each individual. You can also merge changes to your branch from the trunk if someone changes the trunk, and you want your branch to reflect the changes.
This is a common way to use SVN, although there are other workflows. I have worked on projects where I was afraid to commit(I would break the build possibly) because we did not effectively use branching.
Branching is really powerful in helping your workflow, use it until you're comfortable with the idea of merging.
Edit: 'Checking out a branch' refers to creating branch in your branches folder, and then checking out that branch. The standard svn repository structure consists of the folders trunk, tags, and branches at the root.
So, my code is never really in a completely stable state that I feel comfortable checking in.
Why is that ?
If your branch is appropriate for your work (with a good naming convention for instance), everyone will know its HEAD is not always stable.
In this kind of "working" branch, just put some tag along the way to indicate some "stable code points" (which can then be queried by any tester to be deployed).
Any other version on that working branch is just made to record changes, even though the current state is not stable.
Then later you merge all on a branch supposed to represent a stable state.
In TFS, you are able to create 'Shelf Sets' (I'm not sure what they'd be called in other source control providers). When you shelve some code, you are saving it to your repository, but not checking it in.
The reason this is important is that if you are working on Bug XXXX, and you fix half of the code, but it's not stable and not 'check-in-able', but you get assigned to NewFeature YYYY, you SHOULD NOT continue working with the same code base. You should 'Shelf' your Bug XXXX code, then return your local codebase to the latest checked-in code, and implement NewFeature YYYY.
This way you are keeping your check-ins atomic. You don't have to worry about losing your work, because it is still held by the repository (so if your computer bursts into flames, you don't have to burst into tears), and you aren't mixing your fixes for XXXX with your new code for YYYY.
Then, once you are asked to go back to XXXX (assuming you've checked in YYYY) you can just unshelve your 'shelf set' and jump right back into it where you left off.
Either accept that the code in SVN is not in a completely stable state and check it in anyway (and reserve time for stabilization and refactoring every X days/weeks so the code doesn't degrade too much).
Or force your team to work in a more structured way with minimal interruption based development so you can check in good code.
The first option is not ideal (but better then no source control), the second is probably impossible - there is no third option.
If you don't have time to get the code to a stable state you defiantly don't have the time to branch and merge all the time.
In distributed sourcecontrol systems like GIT, you commit to your local repository. Only when you push your code, it's 'committed' to the remote repository.
In this way, its much easier to 'safe' your work in between.