Tools

Getting Started with Git: The Fundamentals

By Scott Danzig, September 02, 2013

The distributed SCM system that's taking the world by storm has its own unique way of doing things. This tutorial explains how things work and the basic commands for getting started and checking-in changes.

Git Log

A "commit" is a change recorded in your local repository. Type "git log," and you might have to press your space bar to scroll and type "q" at the end to quit displaying the file:

Figure 4: Output from git log.

Git's log shows that the potayto project has 3 commits so far, from the oldest on the bottom to the most recent on top. You see the big hexadecimal numbers preceded by the word "commit"? Those are the SHA-1 codes I referred to earlier. Git also uses these SHA-1 codes to identify commits. They're big and scary, but you can just copy and paste them. Also, you need to type only enough letters and numbers for it to be uniquely identified (five is usually enough).

Let's see how my first commit started. To see the details of the first commit, type: git show bfaa. Figure 5 shows the results.

Figure 5: Contents of commit.

At the bottom of Figure 5, you can see that I initially checked-in my Scala application as something that merely printed out "Tomayto tomahto," "Potayto potahto!" You can see that near the bottom. The main() method of the Potayto is executed, and there are those two print lines.

Earlier in Figure 5, you can see the addition of the .gitignore I provided. I'm making Git ignore my Eclipse-specific dot-something files (for example, Eclipse's .project) and also the target directory, where my source code is compiled to. Git's show command is showing the changes in this file, not the entire files. The +'s before each line mean the lines were added. In this case, they were added because the file was previously nonexistent. That's why you see the /dev/null there.

Now type git show 963e to get the output in Figure 6.

Figure 6: Commit message.

Here you see my informative commit message about what changed. These commit messages should be concise but comprehensive, so you're able to find the change when you need it.

After that, you see that I did exactly what the message says. I changed the order of the lyrics. You see two lines beginning with "-", preceding the lines removed; and two lines beginning with "+", preceding the lines added. You get the idea.

The .gitignore File, and Git Status

View the .gitignore file, which was dumped in Figure 5.

.cache
.settings
.classpath
.project
target

This is a manually created file in which I tell Git what to ignore. If you don't want files tracked, you add them here. I use the Eclipse IDE to write my code, and it creates hidden project files, which Git will see and want to add in to the project. Why should you be confined to using not only the same software as me to mess with my code, but also the same settings? Some teams might want to conform to the same development environments and checking-in the project files might be a time saver, but these days, there are tools that let you easily generate such project files for popular IDEs. Therefore, I have Git ignore all the Eclipse-specific files, which all happen to start with a "."

There's also a "target" folder in .gitignore. I've configured Eclipse to put my compiled code into that folder. We don't want Git tracking the files generated upon compilation. Let developers grabbing your source code compile it themselves after they make their modifications. You're going to want to create one for your own projects. This .gitignore file gets checked-in along with your project, so people who modify your code don't accidentally check-in their generated code as well. Other developers might be using IntelliJ IDE, which writes .idea folders and .ipr and .iws files, so they would add those to the .gitignore file.

Getting the Status

Now, let's try this. Type git status.

Figure 7: Status showing no new artifacts to commit.

It shows that there is nothing new to commit to your local repository. You also see in Figure 7 that you're on the main branch of your project, "master." Being "on a branch" means your commits are appended to that branch. Now create a text file named "deleteme.txt" using whatever editor you want in that potayto folder and type git status again:

Figure 8: Status with artifacts to commit.

Use that same text editor to add "deleteme.txt" as the last line of .gitignore and check this out (Figure 9).

Figure 9: Status with no changes to commit.

Other than its special treatment by Git, .gitignore is a file just like any other file in your repository, so if you want the new information saved, you have to commit the change just like you would commit a change to your code.

Staging Changes

One of Git's best features is that it offers a staging process. You can stage the modified files that you want to commit. Other version control systems await your one command before your files are changed in the repository — generally the remote repository for the entire team. When you commit files in Git, files are held in a staging area. You will later commit all the files from the staging area to the larger repository.

So, let's say you wanted to make a change involving files A and B. You changed file A. You then remembered something unrelated to do with file Z and you modified that. Then you went back to your initial change, modifying file B. Git allows you to add files A and B to staging, while leaving file Z "unstaged." Then you can push only the staged files to your repository. But you don't! You realize you need to make a change to file C as well. You "add" it. Now files A, B, and C are staged, and Z is still unstaged. You commit the staged changes only.

Read that last paragraph repeatedly if you didn't follow it fully. It's important. See how Git lets you prepare your commit beforehand? With a version control system such as Subversion, you'd have to remember to make your change to file Z later, and your "commit history" would show that you changed files A and B, then, in another entry, that you changed file C later.

We won't be as intricate. Let's just stage our one file for now. Look at Figure 9. Git gives you instructions for what you can do while in the repository's current state. Git is not known for having intuitive commands, but it is known for helping you out. "git checkout -- .gitignore" to undo your change? It's strange, but at least it tells you exactly what to do.

To promote .gitignore to "staged" status, type git add .gitignore.

Figure 10: Promoting to staged status.

The important thing to note here is that now your file change is listed under "Changes to be committed" and Git is spoon-feeding you what you need to type if you want to undo this staging. Don't type this: git reset HEAD .gitignore.

You should strive to understand what's going on (check out the Pro Git book I linked to for those details), but in this situation, you simply are given means to an end when you might need it (in case you change your mind about what to stage).

By the way, it's often more convenient to just type "git add <folder name>" to add all modifications of files in a folder (and subfolders of that folder). It is also very common to type the shortcut "git add ." to stage all the modified files in your repository. This is fine as long as you're certain that you're not accidentally adding a file such as Z that you don't want to be grouped into this change in your commit history.

It's also useful to know how to stage the deletion of a file. Use git rm <file> for that.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!