GIT explained for Subversion users

This guide shows the most common procedures usually performed by SVN users, but using GIT.
Why this guide should be better than the others already on-line? There isn't a particular reason ;) . I'm now a SVN user and I'm just migrating to GIT, so I'm going to find a way to perform with GIT all the operations that I usually do with Subversion: this will be useful for Subversion users who want to start using GIT quickly.

Git is a distributed revision control (DVCS) and source code management (SCM) system with an emphasis on speed. As a distributed VCS, every Git working directory is a full-fledged repository with complete history and full version tracking capabilities, not dependent on network access or a central server.

This is the most substantial difference with SVN where there is a central repository. With subversion, the developers working in a team used continuously exchange their code. This is deeply different with GIT because there is no a main central repository; so developer should use a given remote repository, and use it as the central one.

No more talk, I don’t like to talk: let’s start with GIT by examples.

We have two developers, obviously their user-names are Alice and Bob.

GIT – Create a repository

Alice wants to create a new project named “lemon”. She simply creates an empty directory and then launch the command ‘git init’:

That’s all! Alice has now a brand new repository locally (note that this is more than a working copy). The main branch is called “master”. The shell prompt has the capability to detect and print the name of the current branch (this is the zsh shell default behaviour).

GIT – Your first commit

Let’s prepare our first file commit. Lemon has one simple file ‘hello.js’ containing the source code.

Also we have a package.json configuration file.

As many of you know, in this type of application, we have to ignore the node_modules directory. So we have to create the .gitignore file containing the ignore-list.

To see the status of our branch, you should use the command ‘git status’

The file for now are all in the ‘untracked’ status, that is the first state. To track these files we have to add them to the repository index.

Check the status again

The added files are now ready to be committed (aka tracked-file). The commit command resembles that of SVN.

Note that the number ‘7046414’ is equivalent of the SVN revision number. Actually it is a commit hash and in this context is truncated to the first 7 characters. To see the entire commit identified we can print the commit log.

Use the ‘git log’ command to see this:

GIT – Share your commit with the team

What about the remote repository? Actually GIT doesn’t need a main remote repository, but can track several distributed repositories.

For this example I’m borrowing to Alice this remote repository. She should set this uri in her local repository, and then verify with the command ‘git remote -v’.

Nice… a remote (by default called ‘origin’) to share our branch!

Yes, you’ve got it right. With GIT we always share branches. Alice now have to push her master branch to the origin repository.

In a team, were developer used to often share their code with SVN, this operation should be performed after every commit.

Only the first time we share a branch we should use the -u flag, in order to set the upstream. In a nutshell an upstream is a tracking reference, in order to set Alice’s master branch to track the remote master branch (we can refer to it as origin/master or remotes/origin/master).

The ‘git branch -a’ command prints out the entire lists of branches.

GIT – Create a branch

Now Alice want to write down a killer feature… maybe it can be a custom message not only for lemons, but also for all kinds of citrus fruit. The first thing to do is to create a branch…

The branch citrus is created only locally. That means that the origin (aka remote repository) doesn’t have this branch. Alice can share this branch with others by pushing it to origin.

GIT – Switch to a branch

But Alice can’t start working because is still using the master branch. The ‘git checkout’ command is launched to change the current branch.

Yes poor SVN users… with GIT the checkout command doesn’t means ‘create a brand new working copy’, but has now a new meaning: now checkout is used to switch branch or revert a modified file or directory.

Let’s start by simply change the current branch:

GIT – Clone an existing repository

Bob, a team mate of Alice, awakens, and start working at the project lemon. The first thing is to clone an existing repository by using the given uri.

GIT – Share a commit on an existing file

Ops… there is a minor bug! The ‘hello’ string doesn’t contains the point. Bob choose to treat it as a hot bugfix, and to commit this change directly on the master branch.
He first edit the hello.js file, and then:

GIT – Create a tag

Bob want to freeze the current master version to a given tag. We’re familiar with tags since we currently are SVN users :) but in the GIT case there isn’t a folder that contains all the tag. Tags are treated like commits, and refers to a snapshot of the source code.

The ‘git tag’ command is used here. After the tag is created, there is need to push it in order to share it with the team.

GIT – Check if a branch is rebased

Alice is working on branch ‘citrus’ and in the meanwhile Bob committed a fix on the master branch. How Alice can check if the branch she is currently working on has to be rebased? The first thing to do is to ‘fetch’ updates from origin.

Now Alice’s repository has information about Bob’s commits and tags. In order to know if the current branch is rebased with master Alice can use the ‘git cherry’ command. Another option are the more powerful commands:

gitk citrus..origin/master

git log citrus..origin/master

The range notation “citrus..master” means “show everything that is included in master but is not included in citrus”.

GIT – Rebase a branch with master

Expected surprise! There is a commit (c6538cc3b3fed65bd5c9cfe708961f1f5f2e1616) not included in the current branch. Now is very important to note all the branches present in Alice’s repository:

There are two local branches (citrus and master), and two remote tracked branches (origin/citrus and origin/master). At the moment origin/master is updated, but master isn’t updated yet. That’s because ‘git fetch’ only download new information but doesn’t perform any merge operation.

The choice is to work with remote branches, or update local branches and work with locals. Alice choose to work with the remote ones.

Examining the log (with git log or gitk) we can see that now citrus and origin/citrus branches have exactly the commit c6538cc3b3fed65bd5c9cfe708961f1f5f2e1616 in their log. That means that this commit is now in common with the master branch.

GIT – Reintegrate a branch

Alice worked hard on her branch, and a the end commits the killer feature.

Ops… she forgot something :( . Another commit is necessary:

Bob wants now to integrate Alice’s commits in the master branch. So the first thing to do is to fetch the updates.

Now Bob has to merge all the Alice’s commit in the master branch. The following command ‘squash’ these commits into one commit, and add the change-set to the GIT index:

The working branch of Bob now has all the changes introduced by Alice. To see the difference Bob should use the command ‘git diff –staged’.

Finally to reintegrate the branch:

GIT – Delete a branch

At the end Bob can delete the branch he previously integrated on master. The ‘git branch -d’ command is used.

Note that the command ‘git branch -d’ ensures that the changes in the citrus branch are already in the current branch. If not, you should use the option -D instead.

What’s next…

Time is over :/ . Next operation I usually perform with SVN are:

  • GIT – Return to a revision
  • GIT – Return to a tag
  • GIT – Reverse merge
  • GIT – Undo a wrong commit (or a list… remeber the order)
  • GIT – Create a diff-file and perform a patch
  • GIT – Stash
  • GIT – Export

Asap I’ll write about these operation. In the meanwhile I suggest you these manual page: ‘man gittutorial’ and the very interesting ‘man gittutorial-2’

Goodbye and happy versioning :)

Leave a Reply

Your email address will not be published. Required fields are marked *