For a software, I have two different branches, that only differ in using different library versions of a package, that my software uses. The API of this library has changed between the versions in a non-compatible way.

I am currently developping using both versions with the identical functionality in different branches, the only difference exists during building and loading of shared libraries.

Should I release these packages with different version names using Semantic Versioning? In my opinion, yes, but what about the naming of these different versions?

Currently I am using the "normal" numbering using the new version of the third-party library, e.g. 1.0.0, and a suffix for the version using the older third-party library, e.g. 1.0.0-json-c-0.10, see https://github.com/residuum/PuRestJson/releases

  • 1
    Do you plan on forking? If not, then why not name the version with the older dependency 1.0.0, and the one with the newer dependency 1.1.0?
    – bstempi
    Commented Dec 19, 2013 at 21:00
  • I will support the older version for a longer time, so the next release would be 1.2.0 and 1.3.0. In my opinion, this is not the way semantic versioning is defined.
    – Residuum
    Commented Dec 19, 2013 at 22:52
  • @Residuum: If you are not satisfied by my answer, I would be glad to enrich it and make it more precise.
    – jhominal
    Commented Jan 3, 2014 at 14:50
  • are you exposing the API of the package library?
    – miraculixx
    Commented Jan 3, 2014 at 23:44
  • @miraculixx No, I do not expose the API.
    – Residuum
    Commented Jan 4, 2014 at 10:31

4 Answers 4


Should I release these packages with different version names using Semantic Versioning? In my opinion, yes, but what about the naming of these different versions?

You should not change the version unless your code changes. However, your current approach of appending the library version works fine under the rules of Semantic Versioning, but you have to use a + sign to add the library dependency:

  • 1.0.0
  • 1.0.0+json-c-0.10

For realeasing, and assuming your package name is purestjson this gives:

  • purestjson-1.0.0
  • purestjson-1.0.0+json-c-0.10

Rationale: Semantic Versioning states in rule 10:

Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata SHOULD be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85.


There are two cases:

  • If you are sure that you will never release a backwards-incompatible version of the older dependency library, and if the implied reduced visibility of the older dependency version does not bother you => use 1.x for the older, 2.x for the newer;
  • All other cases: use a different package name, do not disambiguate by version;

However, if I was confronted with such an issue, I would refactor the code to a "provider-based" model, where the client code calls into an abstract provider, and I would provide "provider implementations" both for the old, and the new versions of the dependencies. That is the model that is used by JDBC or ADO.NET for example, in order to support any kind of SQL database. Of course, it is more work, but if you have both customers that need the older dependency and other customers that need the newer dependency, that is in my opinion the more rational way to handle and support that.


I'm not a C developer, so please excuse the terminology errors.

Semantic Version and code branches (including 3rd party code)

From a Semantic Versioning perspective I think there are a few ways your can approach the version naming and its really up to you how you might like to approach it from within a GIT repo for a C project.

  1. In your case, the API reached version 1.0.0, and it looks like your creating a different build option for allowing the users to use previous editions of some of your library code. Your in a spot, where your offering a regression to an older edition or code. I see that as a minor change as per rule 7:

    Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced to the public API. It MUST be incremented if any public API functionality is marked as deprecated. It MAY be incremented if substantial new functionality or improvements are introduced within the private code. It MAY include patch level changes. Patch version MUST be reset to 0 when minor version is incremented.

  2. Rule 10, implies that you should include '+Alpha', '+Beta', '+RC' or '+RTM' or [BLANK] rather than the 'json-c-0.10' you have chosen in your Git Repo. Further more if you were to continue to use 'json-c-0.10' approach and you have multiple other libraries within your API, you could end up with a really long file name. I've also seen '+Dev', '+Nightly', '+Stable' included in names to help developers testing the code.

  3. Have a look at using your MakeFile that configures the output to generate various folders that represent how the API file is compiled with various options. Notice the output file name is the same, just stored in a different folder. For example:







    Folder Definition examples

    You can then provide the API community which MakeFile Target for the Custom 3rd party code combinations.

    Nightly - Might include all the raw code Git pushes from all the 3rd party libraries.

    Stable - Code from the 3rd party library current releases.

    Old - Code from the 3rd party library previous releases.

    Custom - Allows the user to pick and choose which edition of a 3rd party library they would like to use.

  4. Review how your using Git with branches, feature, releases and bug fixes. There is a git extension you might find useful called GitFlow and an popular approach by Vincent Driessen discussed in his 'Successful GIT Branching model' article. Atlassian provide a GUI for Windows/Mac that includes GitFlow called SourceTree.

  5. One thing you might also want to think about is using a Continous Integration server to compile the software and include "+IncrementalBuildNumber' or '+YYYYMMDD' to help with unit testing.

Breaking API Changes

This is a common issue for API developers. I've seen a few solutions to the issue.

  1. Let it break by removing the old methods. Not very community friendly
  2. Create compiler warnings for obsolete API methods. In the .NET World you can include information for the software developer explaining how to migrate the old methods to new methods or links to web pages explaining it. This will help your API community to understand what to change from/to.
  3. Where possible, retain the old methods and use the new API calls within those obsolete methods, while warning the developer via compiler warnings that the code will be remove at a future time (recommend at the next major release). This allows the developers a "Major" version release cycle to get there code in order. Essentially your giving your API Community a chance to remove redundant API calls without breaking there builds immediately. Optimal solution that allows warnings without compile failures but at the expense of code bloat.

In my company we are use Git tagging for that http://git-scm.com/book/en/Git-Basics-Tagging

This command lists the tags in alphabetical order; the order in which they appear has no real importance.

You can also search for tags with a particular pattern. The Git source repo, for instance, contains more than 240 tags. If you’re only interested in looking at the 1.4.2 series, you can run this:

$ git tag -l 'v1.4.2.*'

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.