Version Control – Best Practices for Using Source Control in Small Projects

gitMySQLversion controlworkflows

So my partner and I are working on a practice management system and at first we didn't use any version control, then I persuaded him to use git. At the moment our system is that we have three branches: develop, master and release. Our git repo is on an external server, which has Apache, MySQL, etc. We do our daily coding on the develop branch (commits) and then we we have done some testing to make sure it's (semi) bug-free we merge it into the master branch. If we want to do something radical we just make a branch of master, mess around and if it works, good, we merge it back in, if not, we delete the branch.

Finally when we go for our weekly release we merge to the release branch to make sure we have a copy of the project as it was when we released. Unfortunately we don't track all files in git as it slows down git too much (e.g. images, especially since this is on an old server with a single-core 1.4 GHz AMD Sempron), as a git status usually changes from around 3s to about 1 minute; or because we can't (mysql databases). For us the slowdown is not workable so we just leave them out, and this has never seemed to be a problem because we haven't deleted any images, but we may start to soon as we start to optimize. So when we checkout previous commits sometimes the files aren't there and so it is broken (a big problem is we can't use version control on the database (because we don't know how), so because the schema has changed it is also broken if we go back).

And that's pretty much our workflow.

So after my background, my question is: Do you think that there are any improvements we could make to the above?

And on a side note: Does any know a reliable and easy-medium difficulty (i.e. not too hard) way to track mysql databases in git?

Best Answer

With distributed SCMs like git or mercurial (which is what bitbucket uses), branching is still possible but often unnecessary. What you do instead is (basic workflow):

  • Set up a repository in a location that is accessible for all developers (a network share, a server that people can ssh into, a third-party service like github or bitbucket). This will be your authoritative repository.
  • Clone this repository onto each developer's machine, and do whatever you have to to create a suitable development environment.
  • Work on your local copy; commit whenever you want to. Commits are local, so you won't hurt anyone. Be sure to pull from the central repo from time to time, so that your local copy doesn't go out of sync.
  • When you have something you think is ready for production, push from your local clone to the central repo.
  • On the central repo, whenever you have a version you want to mark as release candidate, tag it. This way, you can update any given clone to that exact version later on.

Since distributed SCMs allow unlimited clones to your repository, and each clone can serve as the master, you can build more complex workflows from this base. For example, you can have several central repositories: one for development, one for QA, one for production. You can use a dedicated clone just for a build server. You can use more than one clone locally; instead of branching, you just create another clone, and if it doesn't work out, you simply delete it.

Another nice benefit is that if the central repository breaks beyond repair, you'll still have several copies around; all you need to do is clone one developer's repo back to the central server and all is good (you do lose uncommitted changes on the central server though, but ideally, nobody should make changes there directly anyway, so the only thing left to do is for everyone to push their latest changes again).

Tracking databases is hard; normally, you want to track the structure, but not the data - data changes a lot, isn't really relevant for the code, and may contain sensitive information you better not make accessible that way. A common approach is to make a script that sets up the database in its current form, and maybe another that populates it with typical test data. Alternatively, you keep track of incremental change scripts - you'll have one script that creates the database as designed on day one, and then a bunch of scripts that, if applies in order, modify the database until you finally end up with the current state of things. Those are less reliable than tracking code changes though, and they require more manual work, so whatever you do, you want to have a good backup / restore plan for your production database.

Related Topic