Skip to main content

Version Control--7 Rules to Soothe the Github Mind

When I started programming, I knew nothing of version control. My idea of tracking changes was saving a copy of a file or project, or keep notes on what I had changed (and you can guess how effective THAT was). It was pretty mindblowing when I was introduced to the idea that I could freeze my code in a given state and then branch off to make changes without risking what had been working before.
That being said, it takes a little bit of practice to do this without creating additional headaches, and following both the syntax rules of the platform and the unwritten ones that fit your work style are key. More than once I managed to break my repo in creative ways that left me losing hours of work. Through a series of mistakes and having to dig out of less-than-ideal situations, I've developed a handful of behaviors that have served to prevent many problems.

As they've served me well, I'd like to share them with you before we get into the actual coding of this project (it's happening soon, I promise!). If I can save you from having to nuke a repo even once, I'll call it a win.


Choose the Right UI

Git is at heart a command line system, and thus so is Github. If you are super comfortable with the command line, then you'll be able to work in Git Bash like a whiz and conduct most business more easily than I do. But, if you're like me and command line isn't really a natural skill for you, you might enjoy Github Desktop instead.

You can't do everything from Desktop (if you need to do advanced stuff, like rebasing, resolving conflicts, and certain compare and repair functions are still going to live in Git Bash) but the bulk of your routine can be done in a very friendly GUI. Better even than the Git UI you get when you download the tools in the first place.

If you're not comfortable with a tool, you won't use it. And you *want* to use version control, so take a lil time to figure out the most comfortable approach for you.

PS: Visual Studio has some very cool version control tools that will link right up with Github and make it just as easy (or easier) to navigate as Desktop, with better abilities to manage things like file conflicts in the app. It's what I use at work, and it's fantastic.

PPS: Github is not the only game in town for version control by a long shot--it's just what I was introduced to first and I've not run into a compelling reason to explore. The ideas are essentially the same, and if you want to use something else by all means--you do you without any shame from me.

Repo First 

A repo (short for repository) is the directory where your code lives. There's two parts of this: the Remote (that lives on the Github servers) and the Local. They're independent of each other but linked--think of the remote repo as the backup or master copy, and the local as your working copy. You can do whatever you want in your local repo, and only sync it with your remote when you deem it appropriate.

The "Repo First" rule means you set that repo up on Github, then clone it to your computer, long before you open Visual Studio and create the project. You *can* code your entire project and then move it into a repo directory...but don't. Trust me on this. Birds don't lay their eggs then move them to a nest; birds build a nest, THEN lay eggs. Your repo is the nest that keeps your code eggs safe.

This also applies to making sure VS is set to use the correct repo before you open a project and change a whole bunch of files--I find a combination of keeping Desktop open (so I can make sure the changes I expect are being recognized in the correct repo) and then checking that against what VS displays in the bottom right info bar will alert me to being out of whack pretty quick.

Branch Out

One of the coolest things about a Github repository is you can make branches. All repos start with a "master" branch, and while you *can* just have your code live here for all of time you'd be silly to do so. Allow me to share a screencap from one of my other repos to demonstrate what I'm talking about.

  • "Master" branch is the default--I typically use it for the most recent version of working code.
  • "Development" is branched off the "master" and is where the development happens--this leaves the code in "master" pristine so that if necessary I can revert back to a clean slate.
  • "Dev2" was a branch I merged the "master" and "development" code together to fix some issues--it was my first attempt at this move, and I didn't want to try it on either "development" or "master" in the event I screwed it up. Branches are safe places to experiment, you see.
  • "unitTesting-v1," "version1.8," and "version1.9" are all snapshots of the codebase at certain milestones--unitTesting was obviously after I implemented unit testing, while version1.8 and version1.9 were after implementing specific features
If you've ever completely changed your code to improve a small something, and then later realized you totally broke your program after hours of tweaks and cursed yourself for not being able to just "undo" or "restore" to just before when you had that bright idea you may already be having the "Ah-ha!" moment. Branching your code base is a lot like creating save points in a game--absolutely invaluable when you need to double back and change direction (or just start over).

Some further reading on how to create branches on the website, plus links to useful info on branches. Also, instructions on branch creation for Desktop.

Commit Complete Thoughts Early and Often

When making a commit, you have to write in a short description. "Added documentation" or "Defined entity classes" or "Implemented Account Controller" are examples. Those are complete thoughts, and when you look at the changes you made (in Github, one way or another) you'll be able to recognize them and remember how they all fit into that description.

This ties into bigger theories and practices about how to go about planning and writing your code which I don't want to get into just now. But the overall theory is, if a commit has 147 changes that span from the view for the "about" page all the way to the database connection service...if you need to roll that back, chances are you'll be rolling back way more than you need to and creating more work.

By the same token, you wouldn't save a game in the middle of a boss fight just because you fought it down to 95% health (unless it's a super hard boss fight, maybe). You'd be starting up in the middle of things, trying to recapture a train of thought that is long gone. That might be your MO, but I know I end up looking bad when I try it.

If I pause in the middle of coding and think it might be time to refill my coffee, usually that's a natural break in the process and a good time to commit changes before moving onto the next piece. Not always--sometimes you just gotta walk away from the screen. But usually

Hit The Save-All Button As Often As You Breathe

Github will only capture changes that are SAVED.

Let me say that again, for the girl in the back who hasn't finished her coffee yet. Github will only capture changes that HAVE BEEN SAVED TO YOUR HARD DRIVE.

If you create a class, save it, and then add 14 methods and twelve properties, then commit your changes Github will commit an empty class. If you create a class, save it, add a comment about how you will someday finish this class body, save it, and make a commit your class with the comment will be committed.

I once knew a guy who swore Github was the most useless thing in the world, because it never captured all the changes to his code. He would commit changes to his repo, then reload his solution a few days later and have to start from scratch or damn near. Eventually, it came to light that he was not saving his files in Visual Studio, since he was "making commits to his repo anyway."

Save all your changes, all the time. Whenever the "Save All" button un-greys itself, click it. Whenever you stop typing, hit ctrl-s. Github will do amazing things for you, but asking it to see changes to a file that haven't been saved is like expecting your blind date to order your favorite dish before you even meet.

Sync With the Remote At the End of the Day--and 

Only Make Changes in One Place at a Time

It does not cause problems for your remote and your local repo to be a little different. One could easily say that if your remote and your local are exactly the same at all times, you're not doing the thing correctly. But if your local repo gets drastically different from the remote, you may run into a situation where they can't be synced or merged without manual intervention-- *not* something an anti-command line guy like myself wants to deal with.

Much easier to keep the two repos fairly closely aligned, and I found this works best by syncing my changes at the end of the coding session, when I've made my last commit for the time being. This not only ensures my repos are fundamentally the same, it makes sure I don't lose the day's work if something catastrophic happens.

If, however, you have changed your remote repo AND your local repo since the last sync, you may run into some trouble. This is especially a problem when you have team members who may have pushed changes to the remote while you were working (team control is outside the scope of this post, but I have thoughts on that too). So be mindful to only make changes to one version of the repo at a time--and if you have other people who may have pushed changes while you weren't looking, save yourself some hassle by checking before you hit that sync button.


So there you have it, a few handy rules I follow to keep my experience with Github in happy alignment land:
  • Choose the Right UI
  • Repo First 
  • Branch Out
  • Commit Complete Thoughts Early and Often
  • Hit The Save-All Button As Often As You Breathe
  • Sync With the Remote At the End of the Day
  • Only Make Changes in One Place at a Time

 

Comments

Popular posts from this blog

Use Cases: The Theory

They told me in my CSCI-1275 Systems Analysis and Design course there's a tendency for programmers to just start coding stuff without thinking, and this was nigh on tantamount to total catastrophe. I didn't fully understand this until a little later in the semester. We had just learned about arrays and collections in my CSCI-1630 C# Programming I course, and I found this to be a perfect excuse to write a little application that would synthetically divide polynomials . (That's a really great way to master synthetic division, actually, if you're interested in brushing up on that skill. Although my wife still insists the time would have been better spent putting more time into my algebra homework. Two types of people...). At any rate, long story short: I made the program work perfectly, for 3rd degree polynomials that divided evenly. Then I realized it broke when I tried a polynomial of the 4th degree. And then again when the 3rd degree polynomial had a remainder. ...

Sequence Diagrams: Theorizing

The activity diagram is all well and good, and can even be super useful in a lot of cases. But for my money, so far in my limited experience, the sequence diagram is where you really start to get a handle on what you need to do as a programmer. Before the sequence diagram, you're dealing with steps in a process. What needs to happen, in what order, and you could just as easily be talking about employees or way stations or widgets or nothing at all. They're really about systems analysis--that high level, what needs to happen kind of stuff. Really important work, but totally dull from a programmer standpoint. The sequence diagram is where we start seeing method names and parameters being laid out. The interaction between classes and layers. You start to see what methods you'll need, in what classes, and get a feel for what properties those classes will need. You can see the flow of the data from the start of the operation to the end, note the inputs and the outputs. I...

Activity Diagram: Theory

So I've got use cases figured out. Not all of them--only a fool or a genius thinks he can sit at a desk away from the end user and think he's got all the use cases figured out (and a genius would never truly believe it). But you can't sit around trying to anticipate every possible use case before you start, so once we have enough to cobble together a complete program or part of one we can move on for a bit. Side note, this is the beauty of the agile approach: "Yeah, we know we gotta go to the moon. But we have to do it in 10 years, so we can't spend 5 years thinking up every problem we might need to solve before we start solving them. How about we start with 'design a rocket that reaches orbit without killing anyone' and build on that when we finish?" That's called an iteration, but more on that later. Fleshing out what that use case needs is the next step, and there are a couple tools I remember being taught. One of them is the activity diagra...