Updating Semantic Version between multiple developers - version-control

I've been thinking about semantic versioning recently and thought of a hypothetical situation that I can't quite seem to reconcile.
My understanding of the Semantic Versioning Scheme is as follows:
A particular unique state of computer software can be identified with a 3-part version number of the form:
M.m.p
Where
M = Major #
m = Minor #
p = patch #
A major change is any change to the software such that the new version with the change is no longer compatible with the previous version before the change. A minor change is any feature added or removed from the software that does not compromise compatibility with its previous version before the change. and any change that fixes a bug or error is just a patch change. Whenever a major change occurs M is incremented and m and p are reset back to 0. Similarly when a minor change occurs m is incremented and p is reset back to 0. and patch changes merely increment p
(I know there are additional components of semantic versioning like -alpha, -beta and so on but for now I am keeping it simple and constrained to the above)
The Hypothetical situation that is confusing me is this:
Suppose a software project exists in a certain state X.Y.Z in a repository of a version control system (for the sake of the hypothetical lets assume this is Git/GitHub). Suppose there are two developer A and B for the software project. Each clones down a copy of the software project in state X.Y.Z in order to work on some change for it, both are working on a different change (they may be of the same type - M/m/p but the content is different).
Now suppose that developer A finishes their change (whether it be major, minor or patch) and pushes it to the repository (thereby changing the state of the software project to (X.Y.Z)+1 [again we don't know the nature of the change here]). And suppose they do this before developer B is finished with their changes.
How should this influence the work flow of developer B?
if A's change was just a patch should developer B just ignore the update and continue working on their change as if nothing happened (especially if their change was major)?
if A's change was minor or major should developer B scrap whatever progress they've made on their change and start over on the assumption that A's change will have influence on theirs (B's)?
With the nature of problem outline above how should updating semantic versions be handled between multiple developers?

Usually, this is handled by communication. Major versions are rare and planned, so they are overwhelmingly planned and communicated ahead of time.
For the difference between minor and patch versions, there's often some sort of branching scheme. For example, Git LFS uses a branch like release-3.1 for the 3.1.x branch and main for minor versions. All code goes into main, and then if a patch release needs to be done, the changes are cherry-picked into the release-* branches. The core team discusses the plans for the next release and whether they'd like to do a periodic minor release next or whether they think a patch release is necessary.
Of course, there are many other ways to handle this and this is just one. But communication among developers about expectations for the project and plans is going to be important anyway, so it's an ideal approach to decide the way the project would like to deal with managing this kind of issue.

This conundrum only arises as a product of a common misunderstanding about how versioning actually works. Ask yourself "what am I versioning here?".
It was a long standing practice to maintain the version number in a revision controlled file, where it could be modified by developers. In hind sight, it's a terrible practice, but actually made sense to us at the time. But let's stop and think about what it is we are versioning and look at how all the various artifacts are tracked in modern development systems.
One best practice today, that wasn't very common a couple decades ago, is to use a revision control system to automagically track changes to files. Developers no longer have to remember to bump a revision number at the top of each source file when they make changes. Instead, the RCS tracks file version when they are committed (not on every change!). Still most of the various RCS's offered a means to automatically update the source file header, but that practice is rarely used today because it's redundant/wasteful and does not scale well.
Another best practice today is to use some form of semantic versioning on publication artifacts, and there's a lot of variation in the tooling that supports that, but most of it is embedded in a handful of packaging tools and package archive services/feeds. Note that not every change in the source code requires a version bump here. The RCS tracks individual changes committed by developers and the release/publication management system determines the appropriate version to apply to the packaging artifacts.
The primary best practice today is the use of build pipelines. Modern DevOps best practice is to build the product on managed servers for all forms of publication. You typically have separate internal and external publication requirements, but they are all built in controlled, non-developer environments.
Add something like semantic commits (Brk, NB, NIB, and many other notations) to commit messages, automated test results and publication/release policies, and the appropriate version number to apply to any artifact can be derived automatically.
Suggested policies are:
No single developer can publish an artifact to a public facing feed.
Developer builds are versioned based on highest release version available for the repo hash they forked from, plus a -a.Dev. prerelease tag.
No -a.Dev. prerelease artifact shall be shared beyond the developers own workstation.
Continuous integration builds shall be published internally as YYYY.MMDD.Increment-a.Integration
Etc.
Note that the possible variations are endless and determined by your organizations internal needs and commitments to customers.
Circling back on your conundrum, it should be obvious by now that it is a fallacy that the version number should be changed for every change in the source code. Modern tooling and best practices negate the need for it, and it is no longer desired.
If you look through my history of answers here, you should find several rants on why the RCS is not the correct place to track version numbers, but the primary reason is, we just don't use the RCS to store the artifacts we publish. It's okay to add publication tags to specific RCS states for developer convenience, but for CI/CD environments, the best place to keep the product version number, is in your publication feed system or an independent database.

Related

Choosing version control work flow

I have been tasked with researching how to improve the way my company handles version control.
Background
Currently we use Borland StarTeam, which has some issues. Apart from often being difficult to use, the number of tools (IDE support, code review, ...) which support it is very low.
Our company has something like 40 developers but we work with a lot of different projects. A given project usually has something like 3-6 software developers working together.
Our projects range from (mostly) embedded systems and FPGA development to desktop applications.
The current work flow is heavily centralized with one "view" (which is close to a branch in StarTeam language) that everyone in the project works on.
One of the projects use multiple views in the following way:
There is a platform view where no development is done. This view then has two sub views for two specific products that share most code (via the platform view) but is dissimilar enough to be kept apart.
All development is made in the two product views and sometimes code from a product view is promoted to the platform view (which is then automatically available for the other product).
Another project seems to use a main view and a feature view when there was a major feature addition.
We usually have to support software for a long time and provide software updates.
Some of our products have a large number of different versions. The different versions will share most code but some parts are and must be distinctively different.
Developers use both Windows and Linux on their development work stations.
Idea
My idea is to switch over to use a modern DVCS. The work flow I am considering is where each project has a number of public branches which each developer can clone and work on. Each project could then determine if everyone can commit freely, or if we should have some kind of gate keeper system where code needs to pass a human or automated build system before being committed to the public branch.
My idea on the branching setup is to use release and feature branches as in the following scenario:
Let's say we start with development and finally ship version 1.0 of our product. We then find that we want some more features so we aim for a 2.0 release and start a new branch for this. While working on the 2.0 release branch we can still do maintenance on the 1.0 branch leading to the release of version 1.1, and so on.
While working on the 2.0 branch we discover a security problem which is fixed. Since it is available in the 1.0 branch as well that code is backported to the 1.0 branch as well.
Sometime in the 2.0 branch it is discovered that some parts of the system really needs to be completely redone to be able to create feature X. A new public 2.0-feature-X branch is created and worked on. When done, the work in that branch is merged back into the main 2.0 branch.
Actual questions
Hopefully you are still reading at this point :)
Is the above work flow (release and feature branching) a viable option? Are there pit falls to look out for?
In the scenario where a product has a platform branch and multiple product branches, what is the best way to handle this? Would creating a master branch and the product branches work? Is there a problem when two product branches diverge? How much can they diverge?
Have I missed something? I mostly see VCS from a developer perspective so I might be missing stuff that is important from the perspective of a configuration or release manager.
For your second question, I think you can SHARE the platform related code and "most code" shared by different products, and only BRANCH the source code which makes the products "dissimilar". With Share, if an item is modified in one project, the changes will be reflected in other projects simultaneously. With Branch, the file and its counterparts are independent.
So, the two product branches can be diverged as much as you need.

Managing Custom Client Releases

As an alternative to this question what is the best way to manage custom versions of software for a particular client?
Most of the differences between client releases is changes to the user interface to customize the software to look like it is owned by the client. More often then not, this is a simple logo change. Occasionaly the color scheme will change as well. But there are occassions where features will be enabled or disabled based on the client. What is the best way to keep all of these releases up to date and make them easily available to the users of a particular client?
At this point we have five different clients and each has their own build of the software and their own installer (complete with their logo in the installer). This is becoming a pain to manage, and it will only get worse as more and more clients start using our software.
So assuming the linked question isn't the way to go, what is the best way to manage these releases?
"This is becoming a pain to manage,
and it will only get worse as more and
more clients start using our
software."
The only way to really solve this part is to make sure your software has an architecture that supports the customizations as a layer on top of your core product. Ideally, they would simply be runtime configuration options (colours, logos and enable/disable are perfect for this). If you get (or want) a very large number of clients, push the configurability right into the core product and enable the clients to do the customizing themselves.
When updating, you build (and test) the core product once, and build the custom versions by simply linking to (referencing) the already-built core product as a library. You could have each client in a separate build, or you could have a single build process that generates updates for all the currently-maintained client builds (the latter is probably better for a larger number of clients). If you have a "vanilla" version, you could build that as part of the core or along with the client versions, it would depend on your particular case.
Depending on your technology, it might be possible to have the customization layer be built independently from the core product. In this case, client rebuilds will rarely be necessary (perhaps only for certain significant changes) -- you can simply link to the updated core product at runtime. For deployment to the client, you would only need to deploy the updated core, if you have a deployment method that supports this.
It's hard to say more detail without knowing your platform, but you've graciously kept this question agnostic.
Separate the common and the custom parts in your source tree. This can eliminate the great majority of merges, depending on your testing and release policies. There is always a way to abstract out and customize a build resource, even if your build process has to invoke script to rewrite some file.
Judicious use of branching in a good Source Code Management system. These aren't called "Configuration Management" systems for nothing. They are the tools optimized for precisely this task, so you're probably not going to get anything better without building on top of one.
Subversion is good at setting up multiple branches, but last I checked it could only do the 3-way merge on a single file at a time. Perforce is awesome in this department because it tracks your branching history on a file-by-file basis and uses this to automate merging of whole sets of changes between whole branches. It really is the cat's pajamas here.
Git and darcs may have similar power, but I haven't used them. They seem to be based on the idea that each working checkout tree will have a copy all changes ever since the beginning of time. That sounds impractical to me since I need to keep some large and changing SDKs under SCM control.
Arguably, the only difference needs to be a branch of whatever release you have, with the customer-unique changes in it. So for example:
/project
/trunk
/branches
/release-v1
/customer-branches
/release-v1-google
/release-v1-microsoft
....
Where your client releases are branches of your customer releases. Since these branches won't ever get rolled up into trunk or another release branch, don't pollute the regular development /branches tree.
I guess it depends on the level of customization you need for each client, but could you make your base app "customize" itself based on a config file?, so you could have the trunk being the full app and then have special config files for each customer that control the look & feel, as well as features that are enabled, and your release process would take the correct config files to deploy in your installers.
Seems that if you are always delivering custom(ish) versions of your app for each client, it would be worth the time to extend the app in this way.
I set up a header file called branding.h which contains a bunch of #ifdefs like the following example to change whatever bits need changing. In Visual Studio, it is easy to set up multiple builds with the appropriate client symbol defined.
#if defined BRAND_CLIENT1
# define COMPANY_NAME "Client 1"
# define PRODUCT_NAME "The Client 1 Widget App"
# define LOGO_FILE "res/logoClient1.ico"
#elif defined BRAND_CLIENT2
# define COMPANY_NAME "Client 2"
# define PRODUCT_NAME "The Client 2 Super Widget App"
# define ENABLE_EXTRA_MENU
# define LOGO_FILE "res/logoClient2.ico"
#endif
This is all assuming C++ of course.

What version number scheme for poorly planned, branched, and schizophrenic application

I'm looking for a version numbering scheme/pattern/system for an application that is currently branched into several versions with shell game style release dates. This has made versioning a nightmare. I'd like to just use the typical Major.Minor.Revision however this will break down for me quickly the way things are presently run around here.
Here is my inventory...
1.0.0 - Production version.
1.0.1 - Production revision version with bug fixes.
1.1.0 - Production minor version with new features due in July (regulations compliance, must be done).
1.2.0 - Production minor version with new features to integrate with not-yet-released-still-under-development System A.
2.0.0 - Development major version "2.0" of the product (code migrated to newer platform, usability improved).
And to make it more fun, they are planning another project (new features) for integration with a different system.
1.3.0 - Production minor version with new features integrating with System B.
Adding to the complexity is the fact that we don't know exactly when (read: the order in which) these will "go live". If one of the systems we are integrating with gets delayed, then management changes the release schedule. So version 1.2.0 today could get delayed and then the build we tagged as 1.3.0 would drop first. Coordinating with QA is difficult enough already without changing version labels at the end of the cycle.
Questions? Thoughts? Small furry animals?
peace|dewde
Sounds to me like you don't want to use version numbers specifically.
You can use codenames, (Windows did this with each of their releases before they were released).
You basically need something more than numbers to distinguish in house which branch you are talking about. As the versions are released you can slap a Major.Minor.Revision stamp on them, but until then you need to name them in a way that will be recognizable.
Split them into branches and sub-branches.
Make sure that anything dependant on a higher branch has a derivative name.
So, you could call a branch ProductionMac, and a branch ProductionWindows, and that way you would know instantly that they are not to be merged, and that they both derive from production.
The most important thing to maintain is the structural hierarchy. Version numbers do this fairly well, but you have to keep adding "." for each new layer, which is annoying and completely undescriptive (much like naming your variables variableOne,variableTwo,variableThree) So, make sure that however you choose to label each branch, it is still obvious which branches are related to which other branches.
Sounds like numbers aren't going to help much, I'd go with naming the releases after small furry animals.
Or, name each release after the project that spawned it ('UI overhaul', 'June maintenance' etc), and then only assign it a version number when it goes live?
I'd use a dictionary to map between internal development numbers and external "release" numbers, then use the internal development numbers internally and only expose the "release" numbers when you're ready to release it out of development.
Bonus points if you use an intermediate map using irrational numbers. "How is development on release 3.14159 going?" "Oh, not bad, but I'm still fixing a bug we found in release 2.71828183." "What? That bug? That was supposed to be fixed with minor release 1.73205!" :-)
As others have suggested, use a non-numeric codename internally, and apply a number as each component is released.
Appending a revision/build number to your versioning can help you match this internal codename to the external version number (and can aid in communication with QA).
For example:
RegulationCompliance r1234 corresponds to the release 1.1.0.1234.
Based on what you describe, I agree with the first couple of posts. Meaningful, unique names relevant to the scope/feature-set are probably the way to go for each branch. Numbered versions seem reasonable within each named branch.
What you really need... is Gmail-style labeling... for your versioning!
nth-ing the previous posts.
We have our build system increment the build # after each build (whether or not it is to be released) which is what dev/QA uses to identify builds. The final version # is ONLY exposed to the outside world when QA releases. So there are really multiple builds of 1.3.0.x, but only one true 1.3.0.
Here is another alternative I considered while churning on this yesterday. Perhaps I need to rethink what is considered major. Integrating with another system may be a small quantity of work, but if it impacts the scheduling and release dates and version in such a significant way, as it does for me here, maybe that alone is a large enough impact to bump the branch up to major status. Then some of my headache would be minimized.
The most likely scenarios for releasing versions out of order revolve around the minor iterations. The major ones take a coordinated, cross-departmental effort. You can see them on the horizon. The minor ones sneak up on you and fork everything up.
"Here are the new compliance
regulations. If they don't go live by
July 15th, we will be fined $500,000.
Per day."
"What? When did you get these?"
"Last July. Weren't you CC'd on the
distribution?"
** facepalm **
I still think Devinb's answer is best. But I wanted to throw this out here for others in this dilemma.
peace|dewde

Why should my team adopt source control? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have the opportunity to give a formal presentation to my boss about anything that benefits the company. My idea is to adopt source control in my workplace. I have been using Mercurial to manage my own project at work, but the rest of the team does not have a formal source control system in place. Unfortunately, I'm not very good at presenting ideas.
So, can you guys tell me why developers MUST use source control? Additionally, why would you choose any tool except Visual SourceSafe? I don't have experience using VSS, but he is likely to ask why we wouldn't just use Microsoft's tools.
I want to hear opinions from the many smart programmers here! My preferred options are SVN or mercurial. Both seem to have good support for their Windows versions, and both are less archaic than CVS. Also, as a self-declared open source disciple, I would prefer to suggest an open-source tool. :)
Thank you!
Edit: To make it short, generally, current practice for other developers is copying folder, tag with date and maybe record on their own. You get the picture. What if my boss says "if it works, why fix it?"
Let's compare two examples, one development environment that uses source control, and one that doesn't.
A: Does Use
B: Does not Use
Scenario 1: A project is requested, completed, and rolled out
A + B) Programmers develop the project internally, when it's completed, push it out to testing, and then deliver to the client (whoever that may be)
Not much difference, in the big picture
Scenario 2: After a project is released, the client decides that they don't want feature X
A + B) Developers remove the code that the client doesn't want, test, and deliver.
Again, not much difference.
Scenario 3: Two weeks later, the client decides that they actually DO want feature X
A) Developers reintegrate the code they took out in 2 back into the normal development tree, test, and deliver.
B) The developers search for the old code on their personal machines, the file server, and backups. If they find the code, they must manually reinsert each file. If they do not, they probably have to recode that entire feature.
It's easy to get old code that you took out for one reason or another
Scenario 4: There's a strange bug in the system where a function is supposed to return a boolean result, but always returns false. It wasn't like that two weeks ago.
A) Developers examine all the old versions of the software, and figure out that a return false directive isn't in the proper scope - it's executing inside a loop instead of outside.
B) Developers spend weeks trying to figure out what the problem is. Eventually, they notice the return on the wrong line, and fix it. Not having source control means they had to examine each and every file that was executed, rather than finding the differences from when it was working and now.
Scenario 5: Someone breaks the build. It gets past testing and is only noticed weeks later.
A) The team examines the commit history, finds out who broke the build, makes that person fix it and buy the team dinner.
B) The team has to go back through the entire project to find the error, but can't figure out who put that code in. Developers blame each other, and the team dynamic fails.
It's easy to see who committed what, when, and why.
Use source control because neither you nor your team are perfect. The primary function of source control is to ensure that you have a complete historical record of your development process. Having this record, you have the ability to confidently branch out with "experimental" versions, knowing that if the experiment fails, you can back up to an earlier version.
In addition, a good source control system like svn will permit multiple developers to work on the same file and provide powerful tools for reconciling the differences that each introduces.
Simply - so you have a true history of the code - to investigate changes (reasons for bugs), revert to versions, audit, etc. Backup isn't enough - you simply have a copy of the current picture. Ever change a file and wish you could remember what you did?
You have to use Source Control for these reasons
1) You can rollback to any version
2) Different developers can work on the same files
3) All developers, will have access to the same code base
4) You can track changes
5) You can rollback changes that don't work
6) Source control is the basis of continuous integration and helps massively with TDD
7) If you don't use source control, you will slowly go mad as files get lost/overwritten and nothing works as it should
VSS is not the worst SCC application, I used it for years and grew to hate it, but it does work, is simple, and many people know it.
Here's a simple real-life example.
A few years ago, my boss says, "Feature XYZ used to work, and now it doesn't. No one knows what happened. Can you fix it?"
Now I've never worked with feature XYZ before. So fixing it would involve a lot of flailing around trying to figure out what it does.
But we have source control! So I do this:
Create a test script to test feature XYZ: "Click here, type this, click there, etc."
Get current version. Build. Test. Feature XYZ is broken.
Get version from a week ago. Build. Test. Feature XYZ works.
Get version halfway between those two. Build. Test. Feature XYZ works.
Get version halfway between previous one, and current one. Build. Test. Feature XYZ is broken.
I kept doing this binary search until eventually I hit the point of change: version 145 (we'll say) had the feature working, but version 146 had it broken. Then I just did a compare between those two versions to see what changed. Turns out our technical lead (sigh) had checked in code that changed functionality, but also introduced a side effect that broke feature XYZ.
So I removed the side effect, tested...and lo and behold, feature XYZ worked again.
Without source control, you can never do this. You'll have to flail around, changing one thing or another, hoping to magically hit on the thing that makes feature XYZ work again.
With source control, you just test your way through the versions, pinpoint the exact code that caused the problem, and fix it.
Microsoft (MSDN) has a good article on the benefits of source control.
http://msdn.microsoft.com/en-us/library/ms173539.aspx
There are also lots of good questions here on SO as to the pros and cons.
What are your pros and cons of git after having used it?
Subversion is very popular, but Git is going to be the "next big thing" in the source control world.
It seems to me that most people have covered the major feature of source control but one of the biggest positives is skipped over. These are:
Branches
Without a source code repository it is impossible to create branches (or copies/stream/etc.) of your code for particular purposes. Not being able to create and merge branches is one of the biggest things that disqualifies VSS from being a real source code control system. Some of the purposes of a branch include:
Bug Fix
Sometimes you need to resolve a bug and do it in a place away form the mainline or trunk version of your code. This may be to resolve a problem in the testing environment or any number of reasons. If you have a version control tool you should be able to easily make a new branch (something VSS sucks at) to fix the bug and be able to merge it back into the mainline code if necessary
Maintenance Release
This could be much the same as a bug fix but done after code has been released to production. Examples would be for fix packs, service releases, etc. Again, you want to be able to merge the changes back into the trunk if necessary
New Feature
Sometimes you need to start development of a new version while maintaining your current code. For example you release and maintain v1.0 but need to start work on v2.0 while maintaining v1.0. Branches help resolve this situation
Tagging/Labeling
Another thing source code control systems do is make snapshots of the source code at a particular point in time. These are called labels in VSS, tags in subversion, etc. By creating these on a regular basis and linking them to some substantial milestone in your project it then becomes possible to determine what exactly has changed in your code between releases. This can be important for auditors but also in tracking down the source/scope of an issue. VSS also gets a fail here because VSS only versions the files, not directories. This means it is impossible to re-create a previous version of the system if you rename/move/delete files or directories in the repository (something that happens a lot if you refactor). Good source code control systems like Subversion do just this.
I suggest using SVN, because:
Source control gives you excellent history. You can see where what changes have been made, thus providing a great way to see what's changed over time (even better if you fill out the submit summary each time)
To the developer, it provides an excellent fallback if something goes horribly wrong. You can revert changes to a file back to any point in its history, so you can try out that mod you wanted to make, and if it doesn't work, roll it right back easily.
It provides a central repository that is much easier to back up than running around to different developers' computers.
It allows you to branch a project off in a different direction - useful for specializations and customizations.
It enables more than one developer to work together on the same project, and the same source, by letting you merge and otherwise manipulate changes to one central copy.
I suggest NOT using VSS - see this page for reasons:
http://www.highprogrammer.com/alan/windev/sourcesafe.html for more reasons.
If the current process is copying a folder and giving it a date, isn't that so that you get some sort of development history, so isn't that basically a simple form of source control?
So to answer any criticisms about source control, you're already doing it. Now you just need to point out the weaknesses in the current system and suggest a better one.
Why do you need to re-invent the wheel when people have really thought about a lot of the complex scenarios which can occur during development and developed the tools which let them handle them.
What you're currently doing is very fragile and will fall over if any sort of complex scenario comes up, at which point you'll have to expend a lot of energy working out how to do something that the tools already do. VSS is better than what you're doing, but doesn't have the very useful conventions that SVN, git or mercurial has which allows multiple projects to live together in a well organised manner - I'm talking branches, tags and merging, both of which are fragile and basically a nightmare under vss.
SVN does have plugins for visual studio. Some are free. But I find that tortoise-svn just eclipses anything else. The only benefit I find with a plugin is that new files get added to svn automatically.
So, weaknesses of your current system:
If you have to make a change to a file, you are likely to overwrite or be overwritten by the other dev's changes. You may not even notice this.
If you have to remember which files you've changed to copy them over some 'master' copy, you're likely to miss one at some point.
Good luck ever finding any documentation about when you made a change and why.
How could you ever build a stable automated build system on your current system? Cruise control and hudson work really well, you're hobbling yourself
VSS doesn't group changes to multiple files together very well. Everything modern does this extremely well and with atomic consistency.
VSS branch and merge support is awful. When we used it we ended up bracketing every change with comments in source code and manually copying code around rather than relying on VSS merge.
It's going to be very hard, near impossible in your current system, to have some version of the code in live maintenance and some other, later version, in heavy development. Think about what's needed to keep two projects in sync like this, you'll need a good tool. SVN can do it, git can do it really well.
That might be enough to go on with, can do more.
Having some version control system helps in any, many cases:
Single developer, single branch
The most basic task that each version control system has to perform perfectly if it wants to call itself version control is to be able to go back to specified version of a project. If you made mess of things, you can got to previous version. You can examine some previous version to check how it was done then (for example how it was before refactoring, or before removing some code/file).
Version control systems take much less disk space compared to simply saving backup copies with specified date, because they use deltaification (storing only differences from previous version) and compression. Usually backup systems are means to store last N versions of a project, sometimes with N=1 (only previous version) while version control systems (VCS) store all the history of a project. Knowing Murphy a while after deleting Nth last version you would realize that was the version you want to examine.
Additionally going back to some last version is easy and automated. You can also examine how single file looked like at some past version, and you can get differences (in diff format) between current state and some past version. You can also tag (or 'label') versions, so you can refer to past version not only by date, or by being nth version from current one, but also by symbolic name, for example v1.2 or v1.2-rc0.
With version control system you can examine history to remind you why (and how) some piece of code (some part of a given file) arrived at current state. Most VCS allow to examine line-wise history of a file, i.e. annotating each line of a file when it was changed, in what commit, and by whom (the command is named annotate, blame or praise depending on VCS). In some VCS you can search history for a version (revision) which introduced given fragment of code (e.g. called 'pickaxe search' in Git, one of VCS).
For this feature to be really useful you have to maintain some discipline: you should describe each new version (each new revision / each new commit) writing down why the change was made. Such description (commit message) is very useful, but it doesn't have natural place in backup system.
This feature of course is even more useful if you are not the only developer...
Using version control system allows for alternate way to find bugs in the code, namely by searching history to find version which introduced bug: bisectiong history. When you find revision which introduced bug, you would have limited (in best case: very limited) area to search for bug, because bug has to be in the difference betwen last working version and first version with a bug. Also you would have description of a change (a commit message) to remind you what you wanted to do. This feature is also called sometimes diff debugging. Modern version control systems (VCS) have support for automated (or semi-automated) searching the history by bisecting it (dividing history in half, finding which part contains bug, repeat until single responsible version is found), in the form of bisect (or similar) command.
For this feature to be really useful you have to maintain some discipline: you should commit (save changes / put given state in version control system to remember) single change, dealing with only one feature, with only small difference from the previous version; i.e. commit often.
Most version control systems offer various hooks which allow for example for automated testing, or automated building of a product... or simply reminding you that you do not follow coding standard (coding guidelines).
Single developer, multiple branches
Version control systems allow to create multiple alternate parallel lines of development, called branches (or streams, or views). Common case is having development branches, i.e. having separate branch for unstable development (to test new features), separate branch for stable (main, trunk) version which is (or should be) current working version, and one on more separate maintenance (fixup) branches.
Having maintenance branches allow you to do bugfixes and generate service packs / minor version with corrections to some released version, without need to worry about interference from the new development. Later you can merge maintenace branch into stable, or pick bigfix from maintenance branch into stable and development branches (if further/other development didn't fix bug independently).
Modern VCS (here modern means that both branching and merging branches is easy) allow to go a bit further, i.e. generate separate branch for working on a separate feature (so called topic branches). This allow you to switch between working one one feature to working on other feature (and not only switch from eveloping new feature to working on urgent requested bugfix).
If you are developing your product based on source of some other (usually third party) product, you really should use vendor branches to be able to easy integrate new version of a product from vendor with the changes you made. Admittedly this is no longer purely "single developer" case.
Multiple developers
Using version control systems brings even further advantages if there are more than one developer working on the same project. VCS allow for concurent (parallel) development without worrying that somebody would overwrite your changes, or does not take your changes into account. Of course using version control system is no substitute for communication.
All of the above features are even more important in the multiple-developer case: examining who generated given change, who last changed the code (aka. who broke the build), finding a bug in code not written only by you.
Simple: If the code is not in source safe, it doesn't exist
Subversion is free and better than VSS but VSS is definitely better then nothing.
Before you say anything, find out why your company is not using source control.
Once you know why, it is easy to come up with scenarios where source control can help.
Long discussion on why you should absolutely have source control:
Is Version Control necessary for a small development group (1-2 programmers)?
My comments from that thread:
You always, always want to have some
sort of Source Control even if you are
working on a project by yourself.
Having a history of changes is vital
to being able to see the state of a
codebase at any given time. There are
a variety of reasons for looking back
in a project history which range from
just being able to rollback a bad
change to providing support for an old
release when the customer just wants a
patch to fix a bug rather than
upgrading to a newer version of the
software.
Not having some sort of source control
is pure insanity.
As far as VSS goes - it's certainly better than nothing. It's definitely not the best source control and it's very dated, but the fact it that it continues to do the job for an awful lot of companies out there.
If your boss is determined to stick with Microsoft tools, go for Team Foundation Server instead of VSS. It's a much better system than VSS and it has nice features like integrated bug tracking.
Take it from me, VSS blows. It's basic file storage w/ history. Anything is better than VSS and VSS is better than nothing :)
So, can you guys tell me why
developers MUST use source control?
It provides one method for an entire
team to use; everybody operates under
the same 'ground rules'.
Changes are
orderly vs. chaotic, saving
development time.
The ability to track
changes promotes accountability and
makes it easier to find the right
persom to solve problems in the
materials maintained.
A list of exact
changes made can be generated quickly
and easily, making it easier to
advise users of the information on
how it has changed from version to
version.
It is easy to 'roll back' to
an earlier version of the
information, if a serious mistake was
made during a change.
Source Control is like insurance! You hope you never need it, but are glad you have it when you do!
Why do a formal presentation?
Assuming the team size is at least two, do a real-world example: Let two (or more, the more the better) people get the code, make their changes and show what it takes to integrate all those changes using whatever non source control means you use.
Then do the same scenario using the source control.
The amount of time and pain you save by using source control will speak for itself.
Stick to the bottom line, explain how it relates to money and your boss will probably listen.
If you are only one programmer, I'd say the main argument is the reduced chance that you will waste time (and therefore money) fixing simple mistakes, trying to rollback code that turned to be the wrong idea etc.
If you are more than one programmer then the above goes twice plus it's the only sane way to be able to work together on the same codebase without wasting even more time waiting for eachother,
Visual Source safe is better than nothing but there are free options that are better in almost every respect. If your boss needs a presentation to understand why source control is essential he might not care what tool you use once he has been enlightened. That you have experience with other tools and not vss again relates to the bottom line so that might suffice.
Why shouldn't your team adopt source control?
Even as a solo developer, I use source control. In a modern software development environment, I can think of few if any reasons why you would not use source control. It is more surprising that you don't already have it. The question strikes me as something like house painters asking "Why should we adopt the use of ladders. You know, ladders don't get the house painted - brushes do."
I'm really sorry but if you actually have to argue for [the formalization of] source control in a development environment, you're in a hopeless situation. If your boss actually needs to be convinced that source control is a worthwhile endeavor, your boss is simply not suitable to be a manager of a group of software developers. In order for someone to effectively manage, they really need at the very least a basic understanding of the landscape. I can't even imagine what's going to happen when you actually need to argue for something that's worth having an argument and doing a presentation over.
Developing without source control is like driving a car without breaks. You lose the ability to do seamless concurrent development, you lose your code getting backed up in working copies, you lose the ability to do historic research via code annotations, you lose the benefit of seeing the context and comments that accompany discrete changes, you just lose, period. Using source control is so obvious and has so many benefits, it's shocking that you'd have to justify it.
At work, we use subversion, but some developers (myself included) use Git locally via the git-svn bridge. For personal work, I use Git.
Because:
It will reduce costs - Developers will have to spend less time checking an item in/out of a real VCS than their current ad-hoc approach.
It will protect the organization's intellectual property - this should be the most important consideration for any software company (other than data...). You are payed to create software - shouldn't it be accessible in its entirety?
It will provide quicker, more reliable and straightforward backup mechanisms - all VCSs have built in dumping capabilities. These tend to be more mature than a simple file copy.
It will act as a communication mechanism between developers - depending on the version control system you may use comments/labels/checkout status to determine if someone else has worked on a file, if it has been promoted to production, if it has a corresponding support ticket number etc.
It streamlines development - the ability to compare versions of files as well as the other mechanisms will be beneficial to your company period.
The main reason we use version control is consistentency.
If the projects are not consistent then problems are going to occur and code is going to be lost.
Make sure you have buy in for the rest of the team. Maybe you can test your presentation on them? Hopefully, they see the need as well.
Nice to see good practices being initiated from the bottom up. Maybe everyone will be more likely to adopt the practice if it comes from one of their own instead of some management mandate.
To avoid things like
"Hey! What happens ? It worked yesterday."
The easiest way to convince management to invest Time in a SCCS is focus on backup and archival. By utilizing something like Subversion (SVN), you can restore any project to any point in time instantly. There is no need to have someone look through backup tapes or worry about tracking multiple versions in an obtuse directory structure.
There are obviously many other advantages (i.e. 2 people working on the same file at the same time), but backups are what quickly sold my company many years ago.
Others have mentioned the specific benefits of source control elsewhere, but I wanted to explicitly address the "VSS" portion of the question.
If your boss wants to use a Microsoft tool, Team Foundation Server with Team Suite is a very nice combination. It also has other tools included, such as bug tracking, documents, and reporting capabilities, which makes a nice platform on which to later improve your process. We are quite happy with it where I work, and my coworkers have told me horror stories about VSS.
Keep TFS in mind as a response to the 'Microsoft Tools' question.

Preferred Version Control Methodology

I am a novice in the world of source/version control and I have been doing as much reading as physically possible to get my head around the different techniques that people use for their own source/version control.
One thing that I have noticed is a pretty distinct break in the methods of developers into two (possibly more?) groups: one group prefers to keep their trunk in an always-stable state and performs all maintenance and future development in the branches, while others prefer to do all of their development in the trunk and keep it in a not-so-stable state.
I am curious as to what the community here at StackOverflow prefers or if you have your own methods.
Note: If it would help tailor the answers, I should note that I am a single developer (at most there would be two or three others in the same project) who works primarily in ASP.NET and SQL Server 2005
As I'm sure you've noticed from searching the web for answers on this topic, this is one of those things where the best answer is "It depends.", and as most of the responses have indicated, it's a trade-off between how easy do you want to be able to commit/merge new code vs. managing an extensive version history that you can easily roll back for support or debugging purposes.
I work for a small company, which means that at any given time, we could have 3 or 4 different versions of code on developer machines that have not yet been committed to the repository. We use TortoiseSVN for our version control system, which gives us the ability to branch/merge without too much difficulty, as well as being able to view the update log or revert our local copies to an earlier revision pretty easily.
Based on your question, I suppose we would fall under the group of developers who attempts to keep, at all times, a stable Trunk, and we branch new code and test it before merging it back into the Trunk. We also make an effort to keep "snapshots" of each version release so that, if necessary, we can easily check out an earlier version and re-build it, without incorporating any new features intended for a future release (This is also a great mechanism for tracking down bugs, as you can use earlier versions of code to help determine when a particular bug was first introduced into your code. However, one thing to be careful of is if your application references common code that is maintained separately from your version-ed code, you will need to keep track of that too!).
On the repository, it ends up looking something like this:
Trunk
v1.0.1.x Release
v1.0.2.x Release
v1.0.2.x Bug-Fix A <-- (These get merged back into Trunk, but remain on the repo)
v1.0.2.x Bug-Fix B
v1.1.1.x Release
v1.2.1.x Development <-- (This will get merged back to Trunk, and replaced by a Release folder)
v1.2.1.x New Feature A <-- (These get merged back into the Development branch)
v1.2.1.x New Feature B
When I first started at the company, our version structure was not quite as sophisticated, and in my experience, I would say that if you have any need whatsoever to keep track of earlier versions, it is will worth the effort to put something like this together (like I said earlier, it doesn't have to look exactly like this, so long as it fits your individual needs), keep it well documented so that all contributors can maintain it (the alternative is that the creator ends up "babysitting" the repo, which quickly becomes an incredible waste of time), and encourage all your developers to follow it. It may feel like a lot of effort in the beginning, but you'll appreciate it the first time you need to take advantage of it.
Good luck!
I do all my development in the trunk. I'm a single developer and don't want to deal with the hassle of branching. When my code is stable I just tag that current version. For example I'd tag version 1.0, 2.0 beta, 2.0 release candidate 1, version 2.0, etc. Branching would probably a better alternative if you’re maintaining old versions for bug fixes and support but since I don't do this I don't worry about it.
The differences may have to do with how painful merging is or isn't in a given version control system.
With git, branching and merging is practically effortless, so it's a common workflow for me to keep my master clean and do all my work in branches. Branching and merging in svn, particularly in previous versions, isn't quite so cheap and easy, so when I was using svn I tended to work directly on the trunk.
Always stable. Even if I'm a single developer -- almost especially if I'm a lone developer.
Having a broken tree to me means one less way to know what I should be doing.
Big changes go in branches, as well as stable releases, and do the smallest unit of changes possible at any given point so as to keep moving forward at a good pace.
This is the methodology which we follow:
Any stable release should be taken from the trunk. Any further work or modifications should go inside the working branch and should be merged with trunk when ready to release.
If have multiple independent developments, each group should have there on branch which they should sync with trunc periodically and merge it back to trunk when ready.
I've always used the main trunk as head of code. Generally new development code goes in there.
We branch for releases and we may branch for a "big" destabilizing experiment.
When we make bug fixes they go into in main first and then they get merged (back-ported) into the appropriate version branch if required.
If the big experiment works out it get's merged back into main.
We use tags for build numbers in the version branches and the main. That way we can get back to a specific version and build if we have to.
I'm in for the always-stable trunk. You need to be able to rebuild the latest stable version at any time...
In your case, I'd strongly recommend avoiding a lot of branching. It's really a fairly advanced process and not necessary for small projects and small teams.
Try and keep it simple to start with, I always try to have a known working build that can reproduced for testing and deployments etc. Depending on your repository you could use revision number (SVN), or just label the known working versions as they are required.
If you find you have multiple people touching the same files then you will need to consider a branching strategy, other than that for such a small dev team it will just be un-necessary overhead...(IMO)
One aspect is how long will the changes be in an unstable state.
When a change I make might affect other people, or the nightly build, then I do my work on a branch, and merge when stable.
When the changes I make won't affect other people (because it is my private code at home, rather than code at work), then I'm OK with checking in non-working intermediate states if that's what I want. Sometimes, I'll make a few checkins in a row which are not stable; that's OK for me when it is just me who is affected and the workflow will be continuous. It's if I come back in a few years time (as opposed to just a few days) and things aren't working that it gets problematic (one disadvantage of having been around as long as I have - I do have some projects that are still in development and maintenance that are old enough to vote).
I use a variant of tagging to achieve repeatable builds - so if I need to go back to a stable version for a bug-fix, I can use the tag information to do that. It is crucial to be able to get a stable version on demand.
One key distinction is how big files tend to be on average. Big files (1000 lines +) tend to have many independent changes that are trivially automatically mergeable. So the fact that someone else is actively changing a file you are about to start work on is probably uninteresting, so it is ok if the system makes that hard to discover.
So you tend to end up a VC strategy that has a lot of branches, and easy merges. New functionality is written in new branches.
If you are working with the smaller, highly-cohesive files typical of an OO design, in a language like Java, such accidental conflicts are a lot rarer. Even as an artificial example, it is pretty hard to come up with two sets of changes that can be made to a class (and corresponding JUnit test cases) that can sensibly be made in isolation and then automatically weaved back together by a text merge tool.
If you do a lot of refactoring (renaming and splitting files) then that stresses out the merge tool even more.
So you tend to be best off with a VC strategy that has an identifiable and usable stable trunk and minimal branches.
In the first approach, new functionality is written in new branches, and merged when complete. In the second, it is written in new files, and enabled when complete.
Of course, if you do the second, you definitely need strong protection from the baseline becoming unusable for any length of time (i.e. continuous integration and a strong automatically-run test suite).