Code is difficult to write, easy to break, and constantly changing. To help developers concentrate on the code tasks at hand we should strive for the following goals
- Code is readable and verifiable with an emphasis on maintenance and clarity for other developers.
- Developers reduce technical debt whenever possible
- Make decisions based on the goal of easiest to maintain moving forward is the immediate goal instead of an easiest to make a change with respect to the time deadline
- All code developed (excluding scripting) is maintained for a time that dwarfs the time spent creating it and as such maintenance, simplicity, and consistency are paramount and reducing complexity which makes new features easier to build/switch/maintain
- Deployments are structured, repeatable, and automated
Trust in tools that can deploy in a reliable manner reduces an enormous amount of stress and confusion as actions or events that occur rarely lead to hesitation and mistakes by the developer unintentionally, therefore eliminating these pitfalls builds confidence in deployments and the codebase in general
- Code is structured as a robust, reliable, and adaptive instead of the human organization. This provides a solid base for the organization reflect and improve process as needed in a proactive instead of reactive mindset
- Deployments have the ability to rollback or revise to any applicable version in a reliable and automated way
- To avoid human error mistakes and to have failed deployments fallback to last or chosen version when needed
Currently we use subversion to control and manage source code. This system works present, but it is stagnant in features and deficient in support and reliability due to the current self-management of the system.
A prominent development issue in a Subversion system is because of the inherent design and how changes are merged together. A sequential master branch that pulls all changes together makes branches and feature isolation difficult to separate and decompose into testable independent modules.
Subversion is designed as a central repository that flattens all changes into a single branch in this case the trunk which means that changes eventually must be aligned into the master branch and placed in an appropriate order. Branches and changes that exists outside of the main trunk are intended to be transient and not kept in permanence.
This is why when updates to base libraries are made putting the update in means finding a place to put this ordered change into the history of the current trunk branch it also means that when a bug or patch is necessary it must be decided if that patch order is before the current updates or placed at the end and after the all previous changes were incorporated.
There exists a tagging structure that creates bookmarks of particular versions of the files at one time, but tags are designed to be isolated and held as read only as making changes to a tag after it has been created will give you a prompt and warning that you are now going against the design of subversion and management will become difficult and unpredictable.
- Code is developed that works and is tagged as feature complete at that time with tag name AllDone-Date1
- A base library GreatLibrary1 that is referenced is updated to GreatLibrary2 with new features that make the code easier to use and more reliable. As this code is great and works all previous versions are deprecated and not supported. The main trunk branch is updated to keep pace with the libraries and full support.
- In use code of AllDone-Date1 is requested to do the new feature WonderfulThing1.
- Decision A – Use latest trunk code with the GreatLibrary2 and the WonderfulThing1 feature
- Decision B – Take tag code and try to make feature WonderfulThing1 using GreatLibrary1 code
This decision may seem not that difficult, but it is a tricky decision as the cost is insidious and sneaky as each decision to support an older out of support library increases the mental capacity to understand, visualize, and analyze the code as well as increases the cognitive load that developers and users must be aware of to put themselves in the appropriate frame of mind for debugging, use, and testing.
Secondly creating changes to an older out of support system increases the range or area that the code must support as adding features to old code implies that this new feature is present it will now be present in future versions, but you have coded in a particular manner for the old code as temporary patch which will then need to be redone later in a different manner for newer support when you do eventually move to GreatLibrary2.
You have incurred “technical debt” by making what appears as a straightforward decision bound by time that later when the entire time/effort spent on the feature is evaluated is an order of magnitude higher than simply moving to the newer codebase and accepting the manageable, but acceptable time spent on updating to the latest supported.
Example from above:
WonderfulThing1 change can be achieved in GreatLibrary1 it takes 10 significant steps and can be error prone if you are not aware of limitations. Errors are arcane and not consistent as the base technology is no longer the same due to other system wide changes. When errors occur developers must think back to how things used to be or if they are new must learn an entire obsolete frame of reference to understand what is happening and how to fix it.
WonderfulThing1 change can be achieved in GreatLibrary2 in 2 steps and assumes a modern environment that is by default the current developer’s environment. All errors are commonly experienced on a daily/hourly basis and at the front and present part of the developers mind when creating
Fortunately there are development options, practices, and plans that can be used to remedy this situation that numerous software development groups are using regularly, reliably, and reduce cognitive load on the developer. This means more focus and energy can be dedicated to the focus of the particular code functionality at the present moment.
These options depend on the flexibility of multiple parallel and equal distributed branches of code that exists at the same time in the same space from the Git system. A simple example of say the equivalent SVN and GIT code libraries can be visualized as below.
In Git branches exist in parallel and all are valid at the time and changes are moved around and merged as desired and the branch continues to exist as an amalgamation that is constructed by the developer for the particular deployment. As the developer is actively selecting the branches and features they wish to incorporate the potential issues and versions are at the forefront of their minds at creation time.
In subversion you would take the trunk and create a tag, but if base library changes had been made earlier in the trunk these are in the background of the developers mind at the time as they are not forced to deal with them at creation time as they simply inherit from the trunk to the particular tag and must explicitly go back in the history of the trunk to validate and verify if hotfixes/features/patches might conflict or overwrite each other.
Recommendation: Move to GitHub https://github.com/features from Subversion
Git in itself is insufficient because the GitHub community and infrastructure built up around it is incomparably to any other software community that any organization can create.
Finishing with a few metaphors to think about what GitHub brings in my perspective all of these are rough and have some drawbacks as models.
- Before the invention of writing humans lived in smaller groups and learning was dependent on the size of your community and who was alive that could teach you what you needed to learn for life and if they cared to help you (Subversion). After the invention of writing if you were literate you could learn from the vast stored knowledge of every person who contributed to a document irrespective of your community size or who was alive at the time of your own life. Skills and knowledge that were serializable to the written word could now be transmitted to the future without data loss and be available on demand (GitHub).
- The horse was the preeminent form of rapid transportation for thousands of years (Subversion). When the automobile (Git) was introduced horses became obsolete even though automobiles required new knowledge and materials and even infrastructure (Mechanics/Gas Stations/Paved roads/Learning to drive. All of this combined with the car is GitHub in this case) because they were
- Nonstandard in temperament. Horses have personalities and some will bite and kick you while others will let you ride without issue. Automobiles go when you press the gas and stop when press the brake.
- Finicky and unreliable (animals get sick, feel pain, and age)
- Limited production
- When you build a house (an application) in a rural area (Subversion) you will need to
- Build a road to the site
- Dig a well + plumbing to house site
- Setup a fence
- Put up electricity hookups to a main line which means digging holes for electrical pole lines as many as needed plus putting them in (if you want modern conveniences)
- Dig another separate hole for a septic system + plumbing to house site
- Then start building your house
- Finally maintain all of the above
- Also note here that since you are doing this yourself you might have to start with only your hands, maybe you have a shovel, or if you have enough money you can rent a backhoe. Hopefully you know how to use the backhoe as they are powerful and dangerous (This is the size and depth of your organizations infrastructure knowledge in this case). Each step up in tooling requires more specialized knowledge and things that could break, and the wiring of the electrical system can lead to death if done improperly.
- When you build a house (an application) in a suburban/city area (GitHub) you can
- Build your house with connections to the infrastructure grid of your community covering all of the above, but the fence. Why, because all of the other people in your community have encountered and already built reliable and maintainable interfaces to the above. You can concentrate on decorating your house and filling it with specialty items (Application features) instead of house site maintenance.