The coolest things to git
Ok I like git, I love it, and I use it from 100% of my source control. Even when clients require SVN or something else I still run a git repo to help version the source, It’s just better.
Now what I am not going to do in this article is go over the basics. If your not sure what git is or why its better then the others, or why you should be using it, then I suggest you read a good git tutorial. I am instead going to tell you about the most awesome solution to the biggest problem I have ever faced with code sharing. This is like finding out which came first the chicken or the egg, and having tangible proof to back it up.
How do you share a code base, on a project level between 2 or more sites so that changes to one, do not have to effect, but can effect, the others sharing the code base?
Ok, enough of that on with the story. A few years back, I worked on a website. Actually several websites for one client. These websites all looked basically the same and had basically the same features, except some times a new field on a form, or a slightly different workflow. We (I was working with a team of other developers at the time.) had created a base website with the hopes that it could be our template and that we could extend it for all the other websites. Normal developer inheritance stuff. And here is where the fun started. One day we would get asked for a feature is site 1, we would dev it, deploy it and it would be loved. Some people would ask for that feature in site 2 and site 4 but the owners of site 3 feared change and didn’t want that feature. Well obviously that can’t be included in the core/base without some kind of switch to turn it off. Repeat this about 900 times (this was over the several year lifespan of the product) and what you ended up with is three developers sitting around a table trying to figure out which bits of code to copy and paste into the new system to make it work the way the client wanted it. Then several config file switches and compile time….. It was a mess. A horrid mess, and even though we rewrote the code base 5 times, we never figured out a way to get it right. Closes we ever came was Class inheritance so deep that it would make your mind spin. And even then, if someone wanted some feature from a different chain of parent/child classes, back to copy in paste. but at least this time, it was all top level copy an paste. It didn’t take long before out superficial “top” classes were holding 90% of the logic and the bases classes we overloaded so much that they could almost not be there.
The passage of time
Well, I left that job, and started my own company. I have a few plugins I use to speed up development but I have not entered into that situation where clients wanted the exact same thing but just a little different, and when I do see something like that, I know now that linking up two code base for a small amount of shared code is a disaster and I avoid it. But the original problem remained, I am just able to avoid it better. The plugins are nice but any code placed there would mean that every site using that plugin would now use the new code. That was all find and dandy up until a few months ago.
The problem again
I have a client who does affiliate marketing. They are very good at what they do and make quite a bit of money doing it. They have several site, one of the most successful is Sports Betting Professor. Recently they have started gearing up development for a new 2.0 release with members areas, better affiliate marking integration, better payouts for their marketers, the whole nine yards. They also recently launched another product, 5 Days to Freedom. Their new product attempts to show people how to be successful at affiliate marketing, and does a pretty good job. However, for me, this is where is gets bad. I get an email from one of their head guys that states that they like the features that Sports Betting Professor has and that they want to have them in 5 Days to Freedom. Sports Betting Professor is no small project it’s been in active development and usage for years now, 5 Days to Freedom is no small work on it’s own ether. Now both sites need to benefit from code changes, big fixes, config changes etc. etc. but keep the ability to be two distinct websites. It’s the original problem all over again. My dev-sense tells me to “share code” but my experience tells me doing so will cost my clients an enormous amount of money, and leave me hairless, and twitching in a corner somewhere.
This is where git comes in and saves the day. Lets skip the “how I worked it up” and get right to the solution. Again, I don’t intend to tell you how to use git, you should know that already.
- Make a direcory for the “core” project
- git init it
- make a change
- git commit that change
- now leave that project directory and make a new project directory
- git init that directory
- create a git branch, name it something to remind you that, this new branch contains the shared code base.
- add a remote “origin” to both the core project and the project it’s based off of
- add a “core” remote repository to the new project (the one thats going to have the core code included into it.
- now add a remote repository linked directly to the new core branch. (something like git remote add core firstname.lastname@example.org:git.git)
- tell git what you want to pull where (git config branch.core.remote core and git config branch.core.merge master work nicely)
- go ahead and git pull (while your working on branch core) and your core branch will include stuff from the base project.
- git checkout master then git merge core and tada your 90% there you can add new code in core to your new project with ease.
- Now getting changes in the new project back to core.
- Limit what you push on your new branch or you will wish you never tried this. (git config remote.core.push refs/heads/core:master)
- now when you make a change you want to “share” with core, and thus all all branches of core, commit your changes (remember the ENTIRE COMMIT will be added to core so segment it well)
- git checkout core
- git cherry-pick master (this brings the last 1 commit back into core)
- git push
- when your in a good spot to do so you can git pull and git merge in your “sub-projects” to bring in the new code.
- Don’t forget to git checkout back to your working branch.
Was that awesome or what
As I said, those looking for a step by step tutorial need to look over the git man pages and git tutorials better. For anyone that uses git on a normal basis, this should do it.
What it’s not
Don’t go using this trick for evil, this is not class inheritance, this is more like project level inheritance. A well structured app and code base are absolutely essential even with this method. This just allows you to have two or more sites (or anythings) with some common code and some separate code. There are lower level solutions for this such as dlls in .Net, plugins in Rails and other things if you just need to share the same functionality. But if you need to sometimes share and sometimes not, then give this a try. Also if you get into changes where site1 site2 and site4 need a feature but site3 does not. Then you can add another branch. This keeps your “features” a set of git merges and not horridly overloaded, bloated feature sets that need to be in each place, but maybe turned on and maybe turned off.
Coteyr.net Programming LLC. is about one thing. Getting your project done the way you like it. Using Agile development and management techniques, we are able to get even the most complex projects done in a short time frame and on a modest budget.
Feel free to contact me via any of the methods below. My normal hours are 10am to 10pm Eastern Standard Time. In case of emergency I am available 24/7.
Phone: (813) 421-4338