How to Version Control Different Library Versions – Tags or Branches?

branchinggitrelease-managementsvnversion control

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?

Best Answer

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.

Related Topic