28

I have recently started putting my code under version control (in the lab I'm working, under SVN, and my own codes in github (obviously with git)). Before using version control, I used to do something like this. I had a folder with the name of the library, inside many folders with the version number. Every time I wanted to start working on a newer version, I would make a copy of the last version, change the name to the new version and start implementing.

This however seems way redundant when the folder is put under version control. Apart from redundancy, if someone wants to get the latest version, they would be downloading all versions if they just import/clone.

Now I see many ways to doing this with version control but since I'm new to it, I don't know which would be more maintainable.

Method 1: Using tags

If I understood tags correctly, you would have your main branch, you commit whatever change you got and tag them with a version. Then, when you want to get a working copy of it, you get the one with a certain tag. (correct me if I'm wrong)

Method 2: Branching versions

In this method, the main branch would be the development branch. Every now and then that a stable version is made (let's say v1.2.0), you create a branch for that version and never commit to it. That way, if you want to download a certain version, you get the code from that branch. Although I said you never commit to it, it may be possible to do bug fixes and commit to an old version's branch to keep the old version running. For example if the current version is v2.0, but there are people who want to use v1.2, you can get another branch from v1.2, namely v1.2.1 and commit the bug fixes, or just keep the version the same as v1.2 and just commit the bug fixes.

So the branches would look like this:

                  v1.2.1  v1.2.2
                 /       /
 v1.0.0   v1.2.0---------     v2.0.0
/        /                   /
-------------------------------------- dev

This way you have branches for every minor version update. (Note that in the graph above, v1.2.1 and v1.2.2 or created after v2.0.0 was released, so they were not part of the development between v1.2.0 and v2.0.0. Think of it as support for older versions)

Method 3: Branching development

This method is the opposite of the previous. The main branch would be the latest stable version. Whenever you are working on a new version, you create a branch (for development), work on your code and when it is stable, merge it with the main branch.

In this case, the branches would look like this:

 ________  ____  ________________  _____ dev
/        \/    \/                \/
---------------------------------- latest_version

Probably this one needs to be done in conjunction with tags right?

The question!

Anyway, my question is that based on your experience, which of these methods proves more practical? Is there a known best method out there (that possibly I didn't figure out myself)? How are these things commonly done?

0

4 Answers 4

20

Tags and branches aren't mutual, you can (and IMO usually should) use them both. Tags are there to mark milestones in development. E.g. you open a branch for version 1.2 of your product, and you mark v1.2 Beta, RC1, RC2, Final (and then, if needed, SP1 etc.) with tags on that same branch.

I personally prefer Method 2 as the default approach (although I try to avoid multiple levels of branches, to keep life as simple as possible). Method 1 is just not going to work in real life - tags aren't enough, you need branches. And method 3 is inflexible in that it has only a single stable version at all time, so (unless you combine it with Method 2), you can't maintain multiple (latest and older) versions in parallel. This is required for almost all projects in real life - while you are working on version 2, you should still be able to publish patches / upgrades for v1.9, and often even earlier versions. A lot depends on the type of application of course. We develop a web app, so there is only one production version at any given point in time, still we often juggle with 3 different versions (one in production, one is in UAT getting ready for deployment, one is the latest version on the trunk). It can get way more complex for a desktop/client app with multiple older versions being used - and maintained - in parallel.

3
  • Well, like I said Method 3 could come in combination with tags, so you have tags for stable commits. I'm not sure, if I got tags right, but you tag a commit and then you can get the repository with the commit that has that tag? If so, you do have many stable versions, but they are in the same branch (under different tags)
    – Shahbaz
    Commented Sep 29, 2011 at 14:19
  • @Shahbaz, yeah, but the point is that tagged versions are read only, you can't make changes on them. This means that you can't fix bugs in older versions while developing new features on the trunk. Commented Sep 29, 2011 at 14:39
  • 1
    Don't forget, you can use only tags and if you need to go back and fix something for an old version, you can convert that tag to a branch when you need it.
    – Chloe
    Commented Apr 13, 2016 at 22:06
8

I had a folder with the name of the library, inside many folders with the version number.

This is effectively, as you note, a wrong approach, since you have already the version control to... control the versions.

Now, different techniques you enumerate seem all equally right. You can read a very detailed article, Source Control Done Right, which includes information about tags and branches.

2
  • Yes, the first method was what I used to do before I got my code under version control. I will read your link and let you know
    – Shahbaz
    Commented Sep 29, 2011 at 14:20
  • The link was great. I got the feeling that Method 2 is better (at least for me, that am basically the sole developer of the libraries)
    – Shahbaz
    Commented Sep 29, 2011 at 14:57
5

The three methods are not mutually exclusive, and you should combine the three to get the most out of your version control.

For my part, I would use a combination of method 1 and 3 by default, that is, develop in a feature or development branch until a feature is production-ready and then merge back into trunk. This way, trunk always represents the current state of stable, to-be-used development and can safely be linked by svn:external projects. When you release a version, tag it.

I'd only branch on demand, that is, when older versions of your library have a bug that has to be fixed. You can easily create that branch from the tag of the broken version. By not branching unnecessarily, you keep the number of branches low and have a quick overview over the bleeding edges that have to be maintained (trunk and all branches).

4

I would use Method 2. I've used this and found it to be an effective way to manage and maintain multiple versions while still allowing current development to move forward. You can also use tags in conjunction with this method if you need them.

See my answer here for more information on using branching to maintain multiple release versions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.