Git: a distributed version control system

Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. The entire Pro Git Pro Git book by Scott Chacon is available to read online. This book is translated into a number of other languages, i.e. dutch.

Git comes with built-in GUI tools for committing (git-gui) and browsing (gitk), but there are several third-party tools for users looking for platform-specific experience. This post is a summary of the Code School – Try Git tutorial.
Configure Git:

git config --global user.name "your name"
git config --global user.email "youremail@domain.com"

To initialize a Git repository here, type the following command:

git init

Use the git status command to see what the current state of our project is:

git status

Add a new file called test.txt. Use the git status command to see what the current state of your project is. Notice how Git says test.txt is untracked. That means Git sees that test.txt is a new file. To tell Git to start tracking changes made to test.txt, we need to add it to the staging area (a place where you can group files together before you commit them to Git) by using git add:

git add test.txt

You can also type git add .. The dot represents the current directory, so everything in it, and everything beneath it gets added. You can use git reset to remove a file or files from the staging area.

Run git status again to see the current status. Notice how Git says changes to be committed. The files listed here are in the Staging Area (files are ready to be committed), and they are not in your repository yet. You could add or remove files from the stage before you store them in the repository. To store your staged changes you have to run the commit command with a message describing what you’ve changed:

git commit -m "Add test file"

A commit is a snapshot of your repository. This way if you ever need to look back at the changes you’ve made, you will see a nice timeline of all changes. Commit etiquette: you want to try to keep related changes together in separate commits.

You also can use wildcards if you want to add many files of the same type (i.e. text or binary). Add a bunch of .txt files into your directory. Put some in an test directory and some others in the root. You can add all the new files using a wildcard:

git add '*.txt'

You’ve added all the text files to the staging area. Now you can commit all changes.

git commit -m 'Add all the tesdt txt files'

You can use git log to browse the commited files. Git’s log is like a journal that remembers all the changes you’ve committed so far, in the order you committed them.

git log

Use git log --summary to see more information for each commit. You can see where new files were added for the first time or where files were deleted. It’s a good overview of what’s going on in the project.

To push your local repo to the GitHub server you’ll need to add a remote repository. This command takes a remote name, i.e. origin and a repository URL, i.e. http://github.com/project.git. Git doesn’t care what you name your remotes, but it’s typical to name your main one origin.

git remote add origin http://github.com/project.git

The push command tells Git where to put your commits when you’re ready. The name of our remote is origin and the default local branch name is master. The -u tells Git to remember the parameters, so that next time you can simply run git push and Git will know what to do. To push your local changes to your origin repo:

git push -u origin master

You can check for changes on your GitHub repository and pull down any new changes by running:

git pull origin master

Sometimes when you go to pull you may have changes you don’t want to commit just yet. One option you have, other than commiting, is to stash the changes. Use the command git stash to stash your changes, and git stash apply to re-apply your changes after your pull.

To take a look at what is different from your last commit you can use the git diff command. I.e. in case you want to the diff your most recent commit, you can refer to by using the HEAD pointer.

git diff HEAD

The HEAD is a pointer that holds your position within all your different commits. By default HEAD points to your most recent commit, so it can be used as a quick way to reference that commit.

Another great use for diff is looking at changes within files that have already been staged. Remember, staged files are files we have told git that are ready to be committed. Run git diff with the –staged option to see the changes of staged files:

git diff --staged

You can unstage files by using the git reset command:

git reset documents/test.txt

Notice that test.txt is still there. It’s just not staged anymore. Files can be changed back to how they were at the last commit by using the command: git checkout -- :

git checkout -- test.txt

The -- is simply promising the command line that there are no more options after the . This way if you happen to have a branch named test.txt, it will still revert the file, instead of switching to the branch of the same name.

Branches

Branches are what naturally happens when you want to work on multiple features at the same time. You wouldn’t want to end up with a master branch which has feature A half done and feature B half done. Rather you’d separate the code base into two snapshots (branches) and work on and commit to them separately. As soon as one was ready, you might merge this branch back into the master branch and push it to the remote server.

When developers are working on a feature or bug they’ll often create a copy (aka. branch) of their code they can make separate commits to. Then when they’re done they can merge this branch back into their main master branch. I.e. to create a branch called test_cleanup, where you’ll can do some file cleanup:

git branch test_cleanup

If you type git branch you’ll see two local branches: a main branch named master and your new branch named test_cleanup. You can switch branches using the git checkout command. To switch to the test_cleanup branch:

git checkout test_cleanup

You can use git checkout -b new_branch to checkout and create a branch at the same time. This is the same thing as doing:

git branch new_branch
git checkout new_branch

You can remove files by using the git rm command which will not only remove the actual files from disk, but will also stage the removal of the files for us. You can use a wildcard to get all the files in one sweep:

git rm '*.txt'

If you want to remove an entire folder you can use the recursive option on git rm. This will recursively remove all folders and files from the given directory:

git rm -r folder

After this you can commit your changes:

git commit -m "Removed some files"

If you happen to delete a file without using git rm you’ll find that you still have to git rm the deleted files from the working tree. You can save this step by using the ‘-a’ option on git commit, which auto removes deleted files with the commit.

git commit -am "Removed some files"

You can switch back to the master branch so you can copy (or merge) your changes from the test_cleanup branch back into the master branch. To checkout the master branch:

git checkout master

You can now merge your changes from the test_cleanup branch into the master branch. You’re already on the master branch, so you just need to tell Git to merge the test_cleanup branch into it:

git merge test_cleanup

Merge Conflicts can occur when changes are made to a file at the same time. They aren’t that scary, you just need to decide which code to keep. If you’re interested in reading more, take a look the section of the Pro Git book on how conflicts are presented.

You can use git branch -d to delete a branch:

git branch -d test_cleanup

What if you have been working on a new branch and you decide you really don’t want this branch anymore? You’ll notice that git branch -d new_branch doesn’t work. This is because -d won’t let you delete something that hasn’t been merged. You can either add the --force (-f) option or use -D which combines -d -f together into one command.

You can now push everything you’ve been working on to your remote repository:

git push

Leave a Reply