Advertisement

Git for Designers

by

You're likely familiar with tools, like Git and Subversion. But, as web designers, it's quite possible that, though you might say you leverage version control in your projects, the truth is that, more often than not, you simply don't.

If you fit this description, don't worry; you're not alone. In fact, it's this author's entirely unresearched opinion that the huge majority of web designer don't! The dilemma is that there's a common belief that version control is strictly for hardcore coders, who spend their days in darkness, and who rarely come up for air, except for when the microwave dings, signaling that the hot pocket is ready to be eaten.

In reality, if you code for the web, whether on the front-end or back-end, it's your duty to code responsibly: use version control.


5 Signs That You're Overdue for Version Control

  1. You have no concept of what version control is, or why it might be useful.
  2. You code locally, and have no backup system.
  3. You backup up your projects by sporadically duplicating the root directory.
  4. You accidentally deleted a file permanently, and had to recode from scratch.
  5. Upon making a number of edits, your application breaks, at which point you have to hold down Command + Z for a painful number of seconds, as you watch the editor reverse your changes.

Admit it: every developer has identified with one of the signs noted previously at one point or another in his or her career. But remember: the first step to recovery is to admit that you have a problem!


5 Immediate Benefits to Version Control

  1. Accidentally deleted that class or PSD? Run a single command in the terminal to revert to a previous state in the project. Disaster avoided!
  2. Ever gasped in horror, as your website somehow vanished from your desktop? It was there yesterday, but, today, it's gone! A free service, called GitHub, makes this a non-issue.
  3. Who the heck would write this bit of code that I now have to spend hours rewriting? No need to wonder who's to blame; Git will tell you!
  4. Code with abandon, while knowing that, with each commit, "snapshots" of your application are being saved, just in case you need to roll back to this state at some point in the future.
  5. If for no other reason, accept that developers who are likely much more seasoned than you have deemed it a best practice. It's helpful to mimic those to whom we admire.

Git?

Git is the most popular version control system available.

So how does Git factor into this whole version control thing? Well, the super nerdy definition is that Git is a distributed version control system, developed by Linus Torvalds, where each working directory is its own repository with the full history available at any point. Additionally, Git offers the ability to share code, and create multiple branches (or timelines) for your projects, making it particularly suitable for agile development teams.

A more understandable definition might be: Git is a command-line tool that you - and any other developers on your team - use to save frequent snapshots of your projects. At any given point, it offers the flexibility to roll back changes to previous states, with only a single command.

Scott Chacon's book, 'Pro Git,' is available in its entirety on the Git website.


Installing Git

Certainly, the first step to wreckless, "Cowboy Coding" recovery is to download Git from git-scm.com. Use either of the following URLs, depending upon your OS of choice.

  • Mac: http://git-scm.com/download/mac
  • Windows: http://git-scm.com/download/win

Next, we need to configure the installation just a touch, by associating a username and email address. Open your nearest console (Terminal on the Mac), and run:

$ git config --global user.name "Your Name"
$ git config --global user.email email@example.com

Don't worry; this only needs to be typed once, after you first install Git. Now, for every action that you take, Git will use these settings.

There are further configuration options, such as specifying which code editor should be used, when Git requires you to type in a commit message, but ignore that for now.

Congratulations, Git is successfully installed!


The Basic Cycle

As with any new technology, there's a small bit of learning required.

One of the most difficult aspects to learning Git is deciphering what the various jargon refers to. Commits? Staging? Branches? Logs? Huh?

As with any new technology, there's a small bit of learning required. Luckily, as complex as Git can be, particulary as a web designer, you'll find that a handful of commands will go a long way. For comparison, consider the English dictionary, and then the number of words that we realistically use in every-day conversations. The same is true for Git - at a much lower level. So don't feel overwhelmed. Take it one command at a time.

To knock out this confusing terminology, it's best to first think in terms of something tangible in the real world: a delivery truck.

Imagine that you've begun a new static website. You've created folders for JavaScript and CSS files, as well as an index.html file with a bit of boilerplate HTML. In fact, do that very thing right now! When finished, it's time to create the first commit.

Return to the Terminal, and type:

git init

This command, "initialize Git," informs Git that we desire version control for this project. Or, "start the ignition." It only needs to be executed once, at the beginning of a new project's life cycle.

Next, let's determine what the "status" is.

git status

If working along, you'll likely see something along the lines of:

# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   index.html
nothing added to commit but untracked files present (use "git add" to track)

Though somewhat confusing, if we take a moment, we'll see that, by default, we're working on a "branch," called "master." Next, we have one untracked file: index.html. From this, we're able to decipher that Git isn't magical; it must be told which files to keep an eye on, so to speak.

Curious why the JavaScript and CSS directories aren't included in the list of untracked files? Git tracks files, not folders. A common technique, though, to include empty directories in a commit is to add a .gitignore file to each subdirectory. More on that later!

Tracking Files

To track files, we must first add them to the staging area - or, put them on the truck.

git add index.html

Now, if we check the status again, we'll see:

On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   index.html

Excellent; Git is watching this file for changes. In this case, we've only added a single file. If, instead, we'd prefer to add all files to the staging area, we can use the period symbol.

git add .

Keep in mind that the truck hasn't yet left; we've merely loaded a couple of boxes (or files) into the back. To perform the snapshot, and save a copy of the project in its currently tracked state, a commit must be performed.

git commit -m 'First commit'

Above, we've created a new commit, and provided a message of "First commit." With that, our first commit has completed, and the truck has left for the factory, with a copy of the project in the back.

To verify your work, use a new command: "log."

git log

commit 02c934fcaf3de7677273b74d8ad3ed5041066986
Author: Jeffrey Way <jeffrey@envato.com>
Date:   Wed Dec 19 15:07:23 2012 -0500

    First commit

Perfect, a new commit has, in fact, been created, and it also seems that the commit has a unique reference id. File that away for now.

If you, again, check the status.

git status

Because no changes have been made since the last commit, Git tells us as much:

# On branch master
nothing to commit (working directory clean)

Success! 90% of your Git usage will follow this cycle.

  • Make changes
  • Add files to the staging area
  • Perform a commit with a message describing the action that took place

Rinse and repeat!

Let's move on to the next step. As an easy example, perhaps we want to include a simple reset stylesheet in our project. We'll write the most basic (perhaps ill-advised) of resets.

/* css/reset.css */
* {
    margin: 0;
    padding: 0;
}

Now, return to index.html, and include a reference to this file:

<!doctype html>
<html>
<head>
    <title></title>
    <link rel="stylesheet" href="css/reset.css">
</head>
<body>

</body>
</html>

As a basic rule of thumb, if you can describe to the person sitting next to you what change you just made to a project, then it likely deserves a commit. Commit often. Let's do that now; back to the Terminal!

git add .
git commit -m 'Add and include reset stylesheet.'

When writing commit messages, it's generally considered to be best practice to write in the present tense. So, "add file" instead of "added file."

Fast-forward to tomorrow, and now your boss tells you that they don't want to use your simple reset file. Instead, they'd prefer to use the popular Normalize stylesheet, by Nicolas Gallagher.

No problem; with Git, this is an easy fix. Let's revert the previous commit, and make the necessary modifications.

git revert HEAD

With Git, the rule is, "never rewrite history."

This command will reverse all of the changes that you made in the most recent commit. Essentially, it's a commit that does the exact opposite of what the previous one did. Why revert, instead of undoing the commit entirely? Again, because we're following best practices. With Git, the rule is, "never rewrite history." Revert the changes, but never erase and undo them.

Upon hitting enter, you'll be brought to a new screen with the text, "Revert "Add and include reset stylesheet." At this point, you're in Vi mode (though you're free to configure Git to use any code editor that you wish.) For now, go with the defaults, save, and exit. Accomplish this by typing, :wq (Write and Quit).

And with that single command, the changes have been reverted. Go ahead and check to make sure. The style.css file has been removed, and there is no longer a reference to the stylesheet within index.html. This is the power of Git! Because we adopted a development style of committing often, when placed in situations, where edits need to be reversed, it only takes a single command. No more pressing Command-Z for enternity!

Following the boss's request, let's update the project to use Normalize.css, which we've downloaded and placed within css/normalize.css.

Within index.html, reference it:

<link rel="stylesheet" href="css/normalize.css">

And, finally, we commit the changes.

git add .
git commit -m "Include Normalize in project"

Though this was certainly a simple example, imagine how useful this technique can be for larger changes, which span multiple files within your application. By grouping all related changes into a single commit, we achieve maximum flexibility and security.


Room to Experiment

Ever been at a point in a project, when you want to experiment with an idea that may or may not make it into the finished application? While it's true that you can always revert the commit if things don't go according to plan, it's a smarter idea, for a variety of reasons, to instead leverage branching.

The best way to illustrate the concept of Git branches is to reference Back to the Future 2.

On that note, if you're a nerdy developer and haven't watched the Back to the Future trilogy, stop what you're doing and watch them!

Continuing on, remember the part in Back to the Future 2, after Marty and Doc return to 1985 from the future, but find that everything is different? Upon meeting at Doc's, now destroyed lab, Doc draws a diagram, describing how, at some point, "the timeline skewed into this tangent, creating an alternate 1985." This is just like branching!

Consider our current demo project; right now, there's one timeline: a straight line. As soon as we create a branch to work on our idea, we break away from this timeline, and create another one. At this point, both timelines exist, and can contain their own respective commits, without interfering with one another.

How is this useful? Consider an agile development cycle - one where you or your team deploy updates multiple times each week. If you stick with the "single timeline" approach, deploying, for example, a simple typo fix, would not be possible until you finished working on your idea as well. With branching, however, we have the flexibility to take as long as we need on our idea, while still freeing the master branch (the default and primary one) for deploying the typo fix.

To create a new branch, run:

$ git branch idea
$ git checkout idea

Alternatively, combine these two commands into one.

git checkout -b idea

This translates to: create a new branch, called "idea" (replace this to be more descriptive of what you're working on, of course), and switch over to it.

From this point on, any modifications and commits that you make will not be referenced within the master branch. Go ahead, try it out. Edit index.html and make a small change:

<body>
    <h2>My Idea</h2>
</body>

Then, commit your work.

git add index.html
git commit -m 'First draft of my idea'

We've now made our first commit in this new timeline. Our fictional idea still needs work, but we're on our way! But, now, a customer just reported a typo that we need to fix as soon as possible. Because we're correctly using branches, we can return to the master branch, fix the typo, and deploy it.

git checkout master
# fix typo
git add index.html
git commit -m 'Fix small typo'
git push

Once our idea feature is finished, it's time to merge it back into the master branch.

git checkout master
git merge idea

If all goes according to plan, your feature branch will successfully be merged back into the master branch, resolving the alternate second 1985 timeline!

That said, you'll undoubtedly come across situations, when Git seemingly plants its feet into the ground, and refuses to continue as asked. In these cases, Git isn't being a jerk for no reason! Most likely, the problem relates to some conflict that first needs to be resolved, before Git can proceed. Imagine attempting to merge a file back into the master branch; the only problem is that, since the branch was created, the file has been edited in both the feature branch, as well as the master. In situations such as this, how could Git possibly know which version of the file should take precendence, when merging the two? It doesn't, and this is what we call a conflict.

Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Before Git can proceed, you must resolve the conflict, by editing index.html.


Ignoring Files

There will likely come a point, when you determine that it's best to not track certain file types with Git. Examples might include the common .DS_STORE (which Mac users will be familiar with), build directories, and temporary compiled assets.

Easily enough, Git, via a .gitignore file, allows us to ignore certain file types. To make use of this, create a new .gitignore file in the root (but not limited to) of your project. Within it, provide a list of files or file types to ignore. Here's a basic example:

.DS_STORE
build/
*.log
*.sql
*.exe

Social Coding

GitHub makes social coding possible.

So far, you've learned how to commit your code locally. But, how can these modifications be shared with either your team, or the rest of the world? Enter GitHub.

GitHub allows you to share your code with the world. It's the largest open source community in existence.

Once you signup for a new account at github.com, you'll need to follow a few steps to generate a special key, in order to associate your computer with your GitHub account. Don't worry; if you follow the steps, you shouldn't have any problems.

At this point, we can create a new repository, and push our little project, to share it with the world. Once logged in, click the "New Repository" button, give your repo a name, and click "Create Repository." Next, you'll be presented with a few commands that can be pasted into the Terminal. As we already have an existing repo, we need the second option:

git remote add origin https://github.com/USERNAME/project.git
git push -u origin master

This instructs Git to add our new remote repository, and alias it as "origin." Next, we push the master branch (not the idea one) to the remote with the alias of "origin."

That's it! Return to the browser, refresh the page, and you'll find your fresh new repository, waiting to be shared with the rest of the world.

When other members of your team wish to pull in the changes that you've made, they only need to run:

git pull

This command will pull in the latest updates that have been pushed to GitHub! In addition to sharing code, GitHub also offers the ability to track and contribute to popular open source projects, as well as an issue tracker for bugs and feature requests. It's social coding at its best!


Closing Thoughts

Though we've only scratched the surface of what Git is capable of, the truth is that, again, for 80% of your Git usage, the techniques referenced in this article will suffice. Create a feature branch, write some code, add it to the staging area, and commit it with a message. When ready, merge it back into the master branch, and deploy! Next, rinse and repeat!

Don't forget: when stumped, StackOverflow is your best friend. Whatever the problem may be, others have been in the exact same situation. Search there first.

TryGit offers an interactive experience for learning Git.

Further Learning

Advertisement