Version control systems, such as Git, offer a number of useful benefits to any software development team. If you're not already using one for your SuiteCommerce Advanced code, I'd highly recommend it — so much, in fact, that I figured I'd write a quick guide on getting started.
Some of the great things about version control are:
- Collaboration — if you have more than one developer, you'll instantly become aware of a problem where there are suddenly conflicts and overwrites. With version control, you can work concurrently and then merge in the changes.
- Accountability — ever wondered how and when things changed? What about a complete history of a particular file? VCSs track changes and associated metadata, giving you line-by-line details about how things changed at particular points.
- Freedom — ok, this is quite an abstract concept but VCS can act like a safety net: you can make radical changes, save in incremements and not have to worry because, in the end, all the changes are reversible.
I'll talk about the benefits and how to realise them in a bit, but first let's look at my preferred VCS, Git, and how you can set it up.
What is Git?
Git is the most widely used version control system. From a personal point of view, I find it does the job effectively, is easy to use, and, given its ubiquity, there's no shortage of resources and services available to help you and complement what you've set up.
When you initialize Git in a project, it begins tracking your changes. That directory becomes a 'respository'. This repository can then be distributed to other collaborators from a central place. This allows multiple collaborators to work at once, in sync with each other.
Get Git and Set It Up
I don't like to use any of the GUIs available, but that's just me: I like the CLI. In any case, head over to git-scm.com/download and get the latest version for your computer.
Once you've got it installed, it's time to head over to your SCA directory and set it up as a repository. This'll form the 'master' version of your SCA site, so make sure you're not doing this in the middle of any modifications or work. You want this to be clean.
When you're there, run
git init. You should see something like this:
$ git init
Initialized empty Git repository in /Users/sgoldberg/SCA/.git/
That means its ready to go. Then run
git status — this can be used at any time to give you feedback about what files have been modified but also add to files to be tracked by Git.
Until you tell Git to track some files, it won't monitor changes. I want to track all of my files in this directory, so I'm going to run
git add .. After that, run
git status again; you'll see a whole lot of files colored green — this means they're staged for committing.
The final bit of this is committing. Committing is where you tell Git to make a record of the changes you've made to the files in your repository. You see, while you're working nothing is actually 'saved' in version control until you commit it. Commits shouldn't happen constantly (like you would when saving a file in your editor) but rather at significant milestones. However, the granularity is up to you.
Anyway, let's commit the code we already have. Enter the following command:
git commit -m "Initial commit"
We've added a flag here: the
-m flag us add a message to what we're committing. This is pretty important as it's a useful way of giving a summary of your changes, which, in a collaborative workspace, is really important. For now, we're going with a message that marks the beginning of the project; in future, you should you write messages that describe the work you've done.
So that's it, for the basics. Except, there's two crucial things missing: distribution and collaboration.
If you're working solo then you'll be fine up to this point but you may want to do this stuff too.
In order to collaborate, you'll need a remote repository. For this there are two prominent services: Bitbucket and GitHub. Having used both, I'm a fan of Bitbucket so I'm going to use them in this example, but feel free to do your own research and look at the options best for you and your team. Note that adding users is a paid service on many sites but Bitbucket allows you to have five users for free — perfect for small teams.
Sign up for an account on Bitbucket. After that, create a private repository for your site. It's very important you set it to private, or else you'll be giving unfettered access to your code to anyone on the internet. Then, on the repository setup page, follow the instructions for an existing project. For me, they look like this:
git remote add origin email@example.com:sgoldberg/sca-mysite.git
git push -u origin --all # pushes up the repo and its refs for the first time
git push origin --tags # pushes up any tags
Make the necessary modifications to the commands (eg the repo location) and then run them. You'll get some feedback and, once it's done, head back to Bitbucket and check out your commits. You should see it pushed up.
From here you can get your teammates to create accounts and then pull down to get the 'master' code. It's very important that they don't try to follow the exact same steps as you've just done, as they won't be able to push up to the remote repository unless they first cloned it down.
To add new developers to your repo, they'll need to create an account first. After that, you can add them in the repo settings, under Access Management. After that, these developers will need to add in the remote repo and then pull down from it. For this, they'll need to use the
git clone command, eg:
git clone firstname.lastname@example.org:sgoldberg/sca-mysite.git
Anyway, once your repo is set up and you have your local code, you're ready to make changes and see how it goes.
In your local version of your SCA code, make a change. For example, I'm going to add a new class to an element in my header template. After saving the file, you can run
git status in your directory to see the changes.
You can also run
git diff to get a detailed look at the changes that have been made.
From here you can commit your changes and set an accompanying message, then push them up to the remote server. Thus:
git commit -a -m "Added new class to header templates"
git push origin master
After that, check Bitbucket to see your changes.
TIP: if you're going to make a change which adds new files then you'll need to run
git add ., or
git add [file name]. This adds the new files to list of files that Git tracks for changes.
Branching and Pull Requests
Branching is where you take the code off the master line temporarily. It's used for projects to create individual lines of development. Once development is done, the branch is merged into master using a pull request.
A pull request marks that development work is complete and is ready to be put back into the main line, for everyone to use and build on, and to deploy to the live site.
It triggers an opportunity for another developer (and/or QA) to review the work and test it, to make sure it us to your team's standards.
To make use of branching, you'll need to use the
git branch command. Typing that alone into the CLI will return all available branches in the repo which, at the moment, is just the master branch. Adding a string after the command will create a new branch by that name. So, for example, when making my header changes, I should have created a branch first. Luckily, I want to make some more changes to my header (I added a class but no styling) so let's do some branching.
In the CLI, run
git branch header-changes. Now, all that did was create the branch — we now need to move onto it, so run
git checkout header-changes. This command lets you switch between branches and Git will update the files in your working directory to match the version on the branch.
In _header.scss, I'm going to make a small addition:
Now if you save your changes and run
git diff you'll see one of two things: if you're running a local server in the background, and the Sass finished compiling, you'll see a massive print out of red text appear. Why? Because of the files we're tracking. Remember, when you edit Sass and it recompiles, it's recreating the entire CSS file for whatever application the Sass belongs to. Don't forget, too, that these CSS files are entirely one line: so you've just added three lines, but the entire file has changed. How can you fix this?
Well, you can run a selective diff, for example:
git diff Modules/ — this'll print out the changes just for the Modules directory and its subdirectories. If you're not running a local server at the moment, the diff you get from the above command will be similar to the one you would have seen already.
When you're happy, commit the changes.
Now, instead of pushing up to the master remote branch, push up to the name of the branch you're currently on. So, for example, I'm doing
git push origin header-changes.
Head back to Bitbucket and go to the page for pull requests. Click the Create a pull request button.
It'll try to work out what you're trying to create a pull request for, but seeing as this is your first one, it'll automatically select the change we just made. You can specify a title, description and reviewer if you wish. Typically it should be reviewed by someone else in your team, but let's not worry about that right now.
After creating the pull request, the page will reload and you'll be taken to the summary of the pull request. If you look at the files changed, you'll see individual diffs of each file that are, arguably, a lot more friendly than what you get in the CLI. Nonetheless, you should see your changes.
To merge in the changes, hit the Merge button. When it's merged in, the changes are put into master and the 'feature' branch is, optionally, deleted. If you're done working on the branch, then deleting is fine.
Now the change is merged in, do
git checkout master to head back to your main line and then run
git pull — this will pull down the changes from the remote master to your local master, ready for you to start your next project.
Finally, one bit of housekeeping: run
git checkout -d header-changes to remove the feature branch now we're no longer using it.
OK, so we've done a few things here, including making arbitrary changes. You may have noticed that we made changes to the core files, rather than creating overrides or new modules. So let's reset all of our changes for the day and revert back to the initial commit.
There are a number of commands that can help us: one is
git revert and the other is
git reset. Reverting your code undoes your changes by undoing what was done and then commit the old code as a new commit; in this sense, it preserves history while undoing it. Resetting your code, on the other hand, undoes the changes that were made and then removes the commit history, as if the changes never happened.
If you ever need to undo some commits,
git revert is usually the better command if the changes have already been pushed to the remote repo, and
git reset is better if they have not. This is simply because if the change history is already public, it's best there's a record of any changes; if it's not, and you're just working locally, it's best to get rid of the faffing about you did locally to get your code right.
As we've made some example changes to the repo that we want to get rid of (ie changes we don't want to keep nor keep a record of) we're going to use
git reset in this instance.
Head to the commits page on Bitbucket for your repo. Find the hash used for the initial commit and copy it; mine is
92e137f. Then run:
git reset --hard [commit hash]
git push -f
This will reset your local and remote versions of the initial commit.
Note that both of these commands are very serious, potentially dangerous commands. The first resets the repo and discards all unstaged changes; the second forces your changes up to the remote repo — you should rarely, if ever, do this once your repo has matured.
Should you ever find yourself in the situation that you need to rollback some changes, research the best solution for you.
And, with that, you're ready to get going.
Version control systems are a key tool during development. I hope now you see how something like Git can become an integral of your development process.
Git offers ways to improve your accountability, collaboration and freedom when working. For example, one common problem when working in a team is code is the worry about overwriting someone's work when you're working at the same time. With Git, you can both work concurrently, review each other's code on branches, and then merge together the changes when you're ready to deploy.
If you want to develop your Git skills, I would strongly recommend reading tutorials on the subject as Git can have a steep learning curve when you want to do something advanced, or things aren't going to plan. For this, I would recommend Atlassian's Git tutorials.
Do you use version control? What's been your experience with it?