Git-ing Started (with GitHub)

How about that title there? Yeah it’s rough.
The other day I went through the process of adding new code to a large commercial GitHub repository. I sort of stumbled through it, so I wanted to make a quick tutorial in case you’re lost too! Or in the much more likely event that I get lost doing it in the future — it’s pretty straightforward.

Local Git Flow

First of all let’s look at Git Flow, the process by which we add code to a website in Git. I’ll go through a pretty common branch model, but lots of people and teams run things a little differently. If you want to know more about this, Atlassian have a walkthrough with an interactive tutorial.

BASIC FOLDER STRUCTURE

I’ll run through the types of branches we can have to understand the flow of fixing an issue or adding a new feature.

  • Master — this is your ‘live’ branch, with your active code on it. Generally speaking we don’t push straight to this unless we’re deploying a hotfix.
  • Develop — we need a branch to push our features to. Somewhere that looks exactly like Master, but we aren’t in danger of our code breaking on the real website. We use develop, then, as an integration branch. We try a new feature on develop, then commit to master when we’re sure it works.
  • Feature — a feature is something that needs adding to the existing functionality of the site. Whether this is a new menu item or a colour change, we make a branch called feature/feature_name.
  • Hotfix — this is similar to Feature that it isn’t a ‘permanent’ branch. Where the Develop branch never moves, only gets amended, Hotfix and Feature branches are made, merged into Develop and removed often.
  • Release — Release is used to bridge the gap between Develop and Master. Let’s say we have a few features in develop, but we want to release them altogether. In that case we need a Release branch. We put all of our features from Develop into Release, test, then merge into Master.

CASE STUDIES

Let’s look at a few examples of this. First of all let’s say there’s a plan to release a single new feature. Here are the steps we take:

  • Firstly we’re going to want to pull develop down. We need to make sure our local copy of develop is up-to-date with the remote copy.
  • We have to create a feature branch off develop, let’s say we call it feature/new-feature. This means that our code isn’t affecting any live code just yet.
  • Then is the development work, we need to actually build the feature.
  • Next we push our local branch to a remote repository, creating the branch there as well as on our local.
  • It’s always a good idea to test new features. If you have a development environment for this, or a Docker container, they’re great resources to make sure our new code isn’t breaking anything!
  • When we’re happy that the new feature is working, we can merge our feature branch into develop.
  • It’s a good idea to test again, but then when we’re happy we can merge develop into master.
  • Don’t forget, if you have lots of other branches, they’ll all need syncing with develop as well to make sure they’re up-to-date. The new code on the live site needs to be in all branches now.

This is the basic process when using Git. There are some changes and extra features that are useful for different scenarios. Lets say, first of all, that we have a bunch of features we want to release all at once! This is normally the case in larger teams. In this case we add an extra step. We can merge all of our feature branches into one single branch: a release branch. Then when we test this branch we need to make sure that none of our different features cause issues with each other and that the rest of the site or app isn’t affected. Then, when we’re sure it’s all good, we can release this whole branch with all our new stuff!

What about a hotfix branch then? This workflow can follow exactly the same flow as the feature branch, but it’s recommended in the Git Flow Documentation that hotfix branches work off Master rather than Develop, so that the fix gets out sooner.

COMMAND LINE STEPS

In this part I’ll talk you through the actual git commands to get this done! Hopefully this post will become a nice little resource for all the different git actions (for you and for me!).

Cloning

Firstly we need to clone from our remote repository.

You can normally find the clone url on the repository page. In GitHub, it’s on the right when you click the big green button saying ‘Clone or Download’.

Fetching

When we have our repository cloned, we need to fetch all of the branches.

This will fetch all of the remote branches for your choosing.

Branching

When you want to look at one of these branches, we need to ‘checkout’.

Or if you need to you can create a whole new branch:

That -b flag is going to make sure we checkout the new branch immediately. We could leave this out and then run git checkout name-of-new-branch to the same effect.

Pulling

We’re now in our branch, but what if in this time the remote branch changes? Then you need to ‘pull’ the changes down.

Easy enough right? If not, these will all become second-nature to you as you start to use Git more.

Committing

Now we’ve done our work, we need to make sure it goes up to our repository, right? First thing’s first, we need to see what’s changed in our branch.

This is going to return a list of the changes you’ve made. You might also get an instruction saying some of your changes aren’t staged for commit. But we need to add those changes!

By now hopefully Git is starting to look pretty semantic. We can add individual files or whole folders, and we can add more than one file by leaving a space between them. Finally, all our changes are staged and ready, now we need to commit them.

We do this with the command git commit, which has a bunch of useful parameters. Firstly, make sure all of our changed and added files are included with -a, which is shorthand for — all. Then we need to add a message to tell other people working on the project what we did at a glance. We add a commit message with -m”Message about the commit”. This is actually shorthand for — message””, so you can use either! There’s a lot of these shorthands about in command line stuff.

Finally our full commit command should look a bit like this:

And it’s committed!

Pushing

So far we’ve only changed our local repository. That’s great if we have local test environments and want to look at our fixes before pushing them to the remote, but when we’re ready for that we need to get the local code up to the remote repo!

Normally your remote-name will be origin and your branch name the same as your local branch! If you created your branch locally then your push is going to have trouble — it won’t be able to find the remote branch to push to. In that case we simply need to add the -u parameter, or — set-upstream, and git will know to create this branch in the repo.

That’s all of the basic git commands covered. There are a lot more out there and they all have lots of flags or parameters to adjust them in some way.

Handy Git Links

If you’re starting out, a great resource is the Atlassian’s git tutorials. These articles from the creators of BitBucket and SourceTree are clear and well-laid out, and they even compare different git workflows — there’s no wrong answer!

Extras

Here’s some other stuff I’ve found useful in my time with Git, maybe they’ll be handy for you too:

Cherry Picking

“Oh no! Something looks broken on this branch. But didn’t I just fix this on a different branch?”

That’s where cherry picking comes in. You can take any commit from any branch and inject it into your code. If there’s a fix for a bug on another branch, you can take it and add it to your branch easily!

You can find the git commit ID in your repository history, either on GitHub/BitBucket or you can run git log to see all the commits for the current branch.

Errr Handling

“Oh no! We just committed some super janky code to develop, totally by accident!”

It happens, right? Luckily all we need to do here is find the ID of the commit before our broken one, then we can ‘reset’ the branch to there. Firstly, checkout develop and run git log to get the IDs, then we can run this:

We used the — hard parameter here to tell git that we don’t care about our outstanding changes — they can be ignored. If we need to keep our current changes we can change this to — soft.

Stashing Changes

“I need to do a hotfix real quick, but I’m not finished building my feature!”

I do this all the time. I’m halfway through one thing but I need to do another urgently, so what do I do? I can actually save my current changes for later.

But when we want it back, we can do that really easily too.

So we can stash our feature-in-progress, do a hotfix, then pop them back in to continue. If you use SourceTree — Atlassian’s Git Client — you can also handle this easily from the UI.

Deleting Branches

“I’ve been doing this for a while now, and I’m clogged up with all these branches”

After some time you’re going to realise that when branches get merged and deleted on the repository, they don’t get deleted on your local. Every now and then I like to do a cleanup of my local branches, getting rid of anything I’m not going to need.

As you can see this is similar to the command used to create a new branch, but that -d flag in there means this branch gets deleted instead.

Using GitHub

That’s a pretty neat roundup of some basic and some more intermediate git commands in a workflow, but now I’m going to show you how to apply them to a project on GitHub that you don’t own. Fixing a bug for someone or adding a feature to a plugin is a great way to learn and get your code out there. In fact, some teams like to look at a candidate’s GitHub activity during the hiring process — to see if the person is curious to learn and help others. It’s a little different using someone else’s project, and there are a few gotchas that might trip you up.

FORKING

When we see a GitHub repository, we first need our own copy. We could just clone it as we did earlier, but unless we’re a contributor of the repo, we won’t be able to commit and push any new stuff! We need to take our own copy, make changes there and request that our copy be merged into the original. Making our own copy is called ‘forking’. This creates a repository on our GitHub account identical to the original.

EDITING

The next steps are the same as above. We create a branch to do our changes on, make the changes, commit and push them. This will update our copy of the repo on GitHub. Now we need to politely ask the original owners to accept it.

REQUESTING A PULL

Luckily on the original repo there’ll be a little button that said “New pull request”. It’ll show you the differences between the original and your branch and you can check to make sure the code looks fine. Then you can submit your request and the contributors of the original repo will be able to review it.

EDITING YOUR REQUEST

Sometimes the feedback comes back with some changes, and they’re really easy to make! In the same way as we did on our local, make another change, commit and push it. Now the pull request will automatically update with your change. GitHub has a handy timeline of comments etc, and your change will appear there. Then finally if approved, your code will be visible on the original repository!

I hope this has been helpful in some way if you’re just getting started in Git, or if you need help with GitHub’s workflow. I’m no expert on this, but I do know you need to find a way of using Git that works for you and your project. In bigger teams it might be that this exact flow doesn’t work for you and that’s fine, there’s no wrong answer! If you do work in a different way I’d love to hear about it! Be sure to leave a comment or tweet me!

You can find me on Twitter and Instagram, and check out my other posts!

Written by

Web Developer. Into podcasts, punk music, movies and video games.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store