What is Git? Taking Control of Source Control

Let’s say you’re working on a big project – your final paper for a class at school, or a report for your boss. The project is long and complicated, you chip away at it over a period of months, and go through many many revisions of editing. 

Then you save your last copy, Big Project Final Version and hand it to your trusted friend to look over. They find 100 more little typos, so you fix those, then Save As: Big Project Final Version 2

Just to be safe you read over it one more time, and decide you actually want to go back to what you had before in a few places. Hmmm… how exactly was that worded again? 

Save As: Big Project Final Version Final. 

Save As: Big Project For Real Last One. 

Save As: Big Project FINAL. 

Then your trusted friends trips over your dog and spills coffee on your computer and you lose everything.

Does any part of this sound familiar?

What is Source Control?

Source control is a solution to this problem. Source control is basically a “saving” system. It is a program you can use to organize your saved copies, easily look back at past versions, keep multiple versions in parallel, and back the whole project up on multiple computers.

Some consumer software also includes systems that do some parts of this job – Microsoft Office and Google Docs have the ability to look at your Version History, for example.

In the programming world, the most commonly used source control system is Git. Other major ones include Subversion and Mercurial. I’ll focus my description on Git, since this is the only system I’ve ever been exposed to.

Git Commits

When you want to save a project in Git, you create a git repository (“repo”). A repo is just a folder with a couple of hidden files in it to help keep track of things.

You can add anything you want to this folder – code, images, copies of other entire programs – whatever! And git can keep track of it.

All you have to do is periodically “commit” your work. This puts a “bookmark” or a “save point” into the history, and allows you to come back to this version later if you want to.

Every time you get your work to a point you want a snapshot of you “make a commit”. This is probably a few times a day, depending on what you’re working on.

Git Branches

The most basic use of Git is as described above. You just keep a linear history of your work, and you can go backwards and forwards in time through these revisions. This is a Git history with only one branch. Customarily, this branch is given the name master, though that’s just a convention – there’s nothing special about that name.

But many projects are more complicated than this, and require keeping multiple, slightly different, versions at the same time. Some of these versions may even be mutually exclusive from each other. Take a plumber’s resumé, for example – they might keep two copies up-to-date – one for getting a job actually doing plumbing, and another version for getting a job teaching plumbing.

These projects have multiple branches. Perhaps one named plumbing, and another branch named teaching.

In Git, we choose a point in the history we want to start from (which is often just the most recent commit), and branch off from there.

Another common use of branches is to use them to work on some new feature or aspect of your project while leaving the master branch unchanged. This keeps master “clean”, and also allows you to have multiple tasks in-progress, without having to finish one before moving on to the next.

Maybe you’re storing the code for a note-taking app in a Git repo. Your next task is to add a “Share” button in your app. So you create a branch called addShareButton. Now when you make a commit, the master version doesn’t change. Instead, only this addShareButton branch has these new commits.

Once you’ve finished working on your new task in this task branch, you can merge it into the master branch, and then your master version has these changes too! You don’t need that task branch anymore, and you can delete it. Again you now only have one master version to keep track of.

Local vs Remote Repos

So far we’ve basically assumed that you’re working alone on this project, but in a work environment that’s rarely the case. You’ll likely have colleagues that work in the same codebase, and want to make changes to the same files as you – often at the same time as you. So how do you do this without tripping all over each other?

Well first lets back up a second to talk about how git is a distributed version control system. This means that everyone can have a copy of the full project history. If you and one colleague are working on a project together, you can both have a copy of the Git repo, and Git will allow you to keep those copies in sync with each other. But neither of those copies is technically “the primary copy” – they are equal. The project has just been distributed between multiple machines.

Now with that said, it is still useful to pretend that one copy of the repo is the main copy – especially when working with teams – and most teams do this.

In addition to everyone having a copy of the repo on their development computers, there is also a copy on a server that is accessible to everyone. This centralizes and organizes your work – everyone can agree to treat that as the “master copy”. When an individual developer finishes a task, they commit their work, and push their branch it to this remote server (usually just called “the remote” or “origin”. Then this branch can be merged into the master branch.

There are a couple key benefits of having your work on the shared remote, and having everyone push to the same centralized repo:

  • It is easy for everyone to keep up-to-date with everyone else’s work by simply pulling the latest changes from that central repo into their copy on their machine. Without this you would have to separately push your work to each of their machines individually!
  • Work is less likely to be lost if your machine dies unexpectedly
  • It is clear when work is done – it is done when it has been merged into the master branch on the remote.

There is also one other key benefit, which is immensely powerful and makes life much easier:

  • The centralized repo can be managed through GitHub or Bitbucket or other similar software.

Pull requests, code review, feedback sessions

Github has many capabilities. It provides a nice interface for browsing all of the commits and branches in the repo, lets you look at a history of how those changes relate to each other, and is also a directory of millions of projects.

But perhaps the most useful feature it provides is the ability to create Pull Requests.

A pull request is a way of requesting that your branch get merged into the master branch (or any branch). It shows a summary of the changes (which you call the difference (or “diff”) between the branches, and allows your peers to review your work and leave feedback on it before it gets merged.

A reviewer can leave comments/questions, mark their approval, decline your pull request (which temporarily rejects it while you address their feedback), or merge your pull request.

This tool will dramatically improve the average code quality in a repository – partly because people’s feedback will yield useful suggestions, and partly because you try harder when you know someone will be looking over your code with a fine-toothed comb. If you cut corners or do things you know are the lazy way or just plain wrong, someone will probably find those mistakes.

So it holds you accountable for your work, but also is a safeguard around you. Your work is no longer your sole responsibility – you can rely on your team to help spot the mistakes you missed.

Of course this also means that there is more work for you to do – you need to review other people’s code too. And let me tell you – this is often harder than writing the code yourself. You need to try to understand what that code is doing from what little context you can see in the pull request. This is often impossible, or just a waste of time, and a better approach may be to have a real-life conversation with the code’s author, or sit down together to go over the changes.

This can also help ease tensions if you think that the code in the pull request has some fundamental flaw, or you’ve spotted so many errors that writing them all down will overwhelm, discourage, or publicly embarrass the author. These are all bad things to do to a person – and you need to remember to be kind when reviewing someone’s work. They wouldn’t have submitted it for review if they thought it was awful.

Let’s Git This

Git is a powerful tool for managing work shared across a team. It lets you look back in time, see what each other are doing, and make a clear path for how to call something done.

Add Git to your repertoire – it will make you an attractive job candidate, and a better developer. With no need for saving your file versions in separate folders, it will make you more organized. 

And some day it might just save you from a world of hurt when you spill coffee into your computer.

A Day in the Life of an iOS Developer

An iOS developer probably has a similar day to most other kinds of developers – it includes reading and writing code, discussions with teammates, and maybe some meetings. But what exactly does that look like?

Well here’s a rundown of a typical day for me (if I’m not working from home):

7:00 – Alarm goes off. Get up, eat breakfast and make coffee.

7:30 – Leave the house. Head to the train station and start the commute. I live pretty far from work, but taking the train allows me to make use of the travel time and avoid sitting in traffic. I also bicycle from the train station to my office, so I get some exercise in as well. While I’m on the train I read or write, or get an early start on my work for the day.

Read More

The Art of Cautious Self Improvement

Recently I’ve been spending a lot of time thinking about self improvement. Some of this has been about creating better habits and making better or healthier decisions in my personal life, and most of this has been concentrating on work – how do I become a better developer, a better leader, a better professional.

But as I’ve been going through this, I’ve found that on the basis of aiming for self improvement, you first accept that there are things to be improved. And when you make this acknowledgement, not all the feelings that come out are positive, growth-y, or productive.

Starting Somewhere

My first instinct on self improvement is very literal – get better at something by educating myself and practicing that new skill.

So over the past year I spent time reading Robert Martin’s famous programming books: Clean Code, Clean Architecture, and The Clean Coder. These make up a portion of what Prentice Hall publishing calls “The Robert Martin Series” (clever naming pattern, eh).

And honestly, these books are fantastic resources, as advertised. Like, truly will make you better at your job, guaranteed.

The more I read these, the more I feel they are articulating a summary of critical feedback I’ve received over years of code review sessions, but packaged in an accessible and useful way!

The Dark Side

But there’s a downside to having these deep mysteries of the software universe articulated in such a way that they feel obvious.

Now that I’ve been exposed to the light and “know better” than to make the mistakes I made last year, I feel like following these rules should be as simple as reading them – and its not.

The Clean Coder is a book about being a “software professional” – not a technical programming book. So the arguments Martin makes are about how to differentiate between being a “good” employee/teammate/professional and being a “bad” employee/teammate/professional. How to make the optimal decision in a range of situations.

He makes it seem that there is a right and a wrong solution to every problem – like math, or software. A true professional finds that optimal solution, and executes it – and if you behave in any other way, you are being bad (at your job, or to other people).

I’ve found these lessons in The Clean Coder really hard to convert to real life in a constructive way.

And I think there’s a major piece missing in the book – the piece where you take the time to actually make these self-improvements.

Making Commitments – a study in failure

Martin devotes an entire chapter to the differentiation of estimates from commitments, for example.

He cautions that you should make sure that when asked for an estimate you make it clear that its an estimate, and then provide that estimate in the form of a probability distribution (it is an “estimate” after all). But “commitments” are different. It’s a powerful word, that should only be used sparingly and carefully.

“Professionals don’t make commitments unless they know they can achieve them

The cost of missing those commitments, to [colleagues and the business], and to your reputation, is enormous. Missing a commitment is an act of dishonestly only slightly less onerous than an over lie.”

Robert Martin, The Clean Coder

How are you supposed to read this and not feel like a dishonest professional, and a liar? I’m sure everyone can name countless times where they made “commitments” they’ve failed to follow through on, and I am no exception here.

Even after reading this chapter, and after making a big deal in a meeting about the difference between an estimate and a commitment, I still don’t have the hang of this – I failed to meet my very next commitment because an external force came up. But that was supposed to be the point of the “commitment” – you only commit when you’ve accounted for all those things”.

So what does this mean?

It’s ok

Well, honestly, I don’t think it means I’m unprofessional, or dishonest, or a liar (even though those feelings are super palpable and vivid). I think it means I’m recognizing this as a problem now, and opening the window to make the change in that behaviour. I’ve spotted it, in the wild, in its natural habitat (the infamous sprint planning meeting).

I think this recognition phase is where we need a little sprinkle of grace, and to allow oneself the opportunity to fail – a few times if necessary. Probably many times.

Applying the lessons from The Clean Coder requires us in some cases to break deep-seated habits, or fight our instinctive and emotional reactions. That’s super freaking hard. Especially when we’re under pressure, annoyed about something else, or over-tired.

So I’m not saying you shouldn’t read The Clean Coder – you absolutely should. It will make you better at your job, and a more professional software craftsperson.

But you shouldn’t expect to get to the end, mind-meld the information into your life and immediately be better.

Instead, take the lessons from this book, and give them prime real-estate in your brain. Then let them guide you in these situations, and point you in a direction that is better than you would’ve gone yesterday. Then do the same thing again the next day.

Over weeks and months, you will become a better employee/teammate/professional – just as long as you give yourself the chance to fail along the way.

New Year, New Goals

Happy New Year, folks.

The new year is a time for reflecting on how the last year has gone and how the next year might be better, and so like many of you I’ve set myself some goals.

These are goals that are supposed to help me improve some aspect of myself or my life, and by writing them here I hope to provide some inspiration for you, or at least some accountability for me.

These aren’t entirely programming-related, so this post diverges from what many of my other posts are about, but if you take a more holistic approach to work and life, you will already know that these things aren’t really separate. Your personal life and health affect your quality of work and your relationships with your colleagues, and vice-versa.

So here are my goals for 2019.

  1. Start each day with 30 mins of self-improvement. The key rule is that this time isn’t spent on something for work. Instead, this can be one of: working out, reading, or writing. Today I chose writing.
  2. Buy a house I love. Toronto’s effing expensive, so this move will result in a pretty major change for us. We’re looking in Toronto’s nearest neighbouring city, Hamilton, Ontario – home of the Tiger Cats and Tim Horton’s.
  3. Buy a car I love. We’ll need this when we move. We might be leaving the city but our friends and family aren’t. The car will help us keep those relationships healthy and strong, which is super important. Don’t under-value your support network.
  4. Read 5 fiction and 5 non-fiction books. I used to read all the time as a kid, but as I grew up I spent more and more of my time using technology, and less and less time reading. Since I finished school in 2014, I’ve only read a handful of books, and I think its making me dumber. So I’m getting my reading back on track this year.
  5. Be a mentor at work. I don’t intend to really formally start mentorship. At least not to the extent that some others I’ve seen online doing. But I want to spend more time helping other people learn and grow, just as other people helped me learn. I wouldn’t be where I am without their help, and I want to pass it along. But also, teaching is the best way to learn – if you can’t teach something do you really know it? So this goal helps others, and also myself.
  6. Lead Lunch & Learns at work. This relates to both of the previous two goals. I think a good way to start here is to present what I learn from reading. Specifically, I’ll start with something from one of Robert Martin’s books. In 2018 I read both Clean Architecture and The Clean Coder, and I find them both super inspiring and full of important lessons. So this is probably a good place to start.
  7. Write a daily agenda every day. Many people already do this, and to some extent I’m already accomplishing the cataloging of my work via our team’s daily standup. But sometimes I’m just not very good at remembering what I did yesterday when it comes to my turn, or staying focused on the one important thing I need to get done each day. So I think that I can improve this by writing in an agenda each morning. At the end of 2018 I started using Agenda for this, and that’s where I’ll be continuing with this as 2019 starts.
  8. Have a Regular Date Night. This is something I picked up from my own parents, but then more recently I was reminded of it listening to Rachel (& Dave) Hollis. Sometimes we’re insanely busy, and you can go weeks without spending quality time with the most important person in your life – your spouse. So this year we’re pre-scheduling date night and prioritizing it. Every Tuesday is blocked off for something together – maybe we go out for dinner, or just play a board game at home, but we commit to spending time focused on each other.
  9. Quit Scrolling. One of my friends did a masters thesis describing how smartphones affect your brain – as it turns out, the act of scrolling triggers the release of endorphins, and so you can be literally addicted to “getting a hit of” scrolling. And while I might learn a few important things here and there by scrolling, I also waste an exorbitant amount of time doing it. So no more.
  10. Build something for our new home. I love working with my hands and building things. This past year I built a shoe rack, which will be coming with us when we move. I started this project with a vision of what I wanted, but I didn’t yet have the skills to pull it off. In the process I learned how to weld, used new tools for the first time, and collaborated with friends and family to get it done. And I’m super happy with it! So this year I want to do something similar. I’m not sure what yet I’ll build yet, but probably something of a similar scope.
  11. Finish writing a draft of a book. This one is the most nebulous of my goals, mostly because I’m not sure if what I’m writing is really a book, or if it would be better as a series of blog articles. Getting a book in people’s hands is really hard, but writing a blog is easy (look at me go!). But in any case, the goal is to commit to a large-scale writing project.

So off we go! Here’s to a year of fulfillment and accomplishment.

Clean Architecture – SOLID Design Principles Summary

Clean Architecture is a book by “Uncle Bob” Robert Martin as a followup to his popular Clean Code. It includes a brief section about the SOLID principles, which are the touchstone of his programming philosophies, and have been described in his other books.

This summary is a cheatsheet to help you remember the SOLID principles in your day-to-day work.


The SOLID Principles

  • Single Responsibility – each module should only have one reason to change
  • Open-Closed – Design software so its behaviour can change by adding code – not changing the existing code.
  • Liskov – Use interfaces/protocols to separate interchangeable parts
  • Interface Segregation – Dont depend on things you don’t use
  • Dependency Inversion – High-level code shouldn’t depend on low-level implementation

Solved – Safari can’t load page but Chrome can through VPN

I ran into an issue a few days ago where I couldn’t get through to my work’s git server from Safari, but Chrome was able to access it fine.

I assumed the problem was in Safari, and tried resetting Safari preferences and clearing caches, but that didn’t work. I also edited my hosts file recently, which has been a cause of this complaint for other users, but nothing in that was out of the ordinary either.

The culprit: Charles Proxy.

I use Charles Proxy regularly for work. Charles is a great tool and all, but it makes changes to your computer’s network settings and doesn’t always clean up after itself. It functions by operating a proxy server on your local machine so that you can observe traffic and debug your networking code.

Specifically, it sets up a global proxy in macOS’s native System Preferences > Network. It’ll go into whichever network is currently active, go to the Advanced options and enter the details.

In order to maintain access to the internet after the proxy stops, these values need to be removed. In its normal shutdown process, Charles will usually switch these back. But if it crashes they don’t get cleaned up. Just go in and uncheck the proxies that are enabled.


These proxies can also be set on VPN networks that are listed in the System Preferences.

Font Awesome Doesn’t Work with Firefox – SOLVED

Font Awesome is awesome, except that it doesn’t work with Mozilla Firefox or Google Chrome out of the box (see what I did there?). So if you’re seeing little squares instead of the icons you’re expecting, here’s the solution.

Open the .htaccess file for your site and add the following code:

<FilesMatch ".(ttf|otf|eot|woff)$">
  <IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"

This is a great snippet that I found here.

If you don’t already have an .htaccess file, create one in the root directory of your site. It is a plain text file and must be called exactly “.htaccess” (no that’s not just the file extension). I’m using WordPress so this is what my .htaccess file looks like now:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

<FilesMatch ".(ttf|otf|eot|woff)$">
 <IfModule mod_headers.c>
 Header set Access-Control-Allow-Origin "*"
# END WordPress

Refresh your browser and your icons should now appear.

If this doesn’t work, make sure you don’t have another copy of font awesome installed. This could happen, for example, if you are using WordPress and you installed a fontawesome plugin, or if you tried uploading a newer version in some previous frustrated attempt to fix this.

Auto Increment Build Number in Xcode

This is a great Copy-Paste solution for every solo iOS Developer. It automatically increases the build number of your Xcode project every time you Run your program.

Two Facts:

  1. You now have a reason to have a build number.
  2. You will spend less than a minute on this. And never worry about it again.

Go to your Project’s Build Phases tab, and click the + button. Choose New Run Script Build Phase then drag the Phase to be second (after Target Dependencies).

In the space after the shell’s /bin/bash, copy this:

bN=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
bN=$(($bN + 1))
bN=$(printf "%X" $bN)
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $bN" "$INFOPLIST_FILE"</code>


Works like a charm. Just make sure your build number starts as “1″ and not “1.0″. This great solution was originally posted by RobertL on Stack Overflow but I liked it so much I’m sharing it!

I think this would be particularly powerful if cleverly extended to work with version control.

SOLVED – iMessage Activation error: “An error occurred during activation. Try again.”

While going through the process of migrating to the iPhone 5c, I got the error message: “iMessage Activation An error occurred during activation. Try again.”

iMessage Activation error after restoring iPhone Backup - An Error occurred during activation. Try Again.

I was also missing incoming iMessages that I could see coming into another device.

My situation is unique in that I am not recovering lost data or a corrupted iPhone. I backed up my old iPhone to iTunes on my computer, and then restored the iTunes Backup onto my new iPhone. There were also errors installing many of the Apps onto my phone. But if you’ve received this error while trying to restore your iPhone backup, this confirmed solution will work for you!

Read More

Powered by WordPress & Theme by Anders Norén