Thursday, January 23, 2014

Getting started with GIT basics

Previously I've blogged about making a local SVN repository. This time I'm going to talk about GIT, another version control system. For many reasons, GIT has advantages over SVN (which I'm going to blog about some other time). It is also a little bit complex compared to SVN. For example, if you modify a file in SVN, then that modification persists in your local machine even without committing. Then later on you can commit that modification so the changes are also applied to the main repository. But it's a little different in GIT. In GIT you have the repository in your local machine (whereas in SVN your local copy acts just like a client). After modifying a file in GIT repository, you need to commit that change just to make sure that the changes persist in your local repository for the current branch (not in the original repository). If you modify a file but don't commit, then you can't push it to the original repository. If you want your modification to be available in other branches, then you'll need to merge the two branches. At last, you'll need to "push" your changes to the original repository.

There are plenty of graphical tools to manage GIT operations, you'll never have to think about the command line if you use those tools. But its good to know what commands are working in the background. I really like SourceTree as a git manager. If you use Eclipse as your IDE, then you can also install the EGit plugin which provides very nice GIT Team management.

Here are some very basic GIT commands to get you started with it, provided that you already have access to a GIT repository somewhere and you've installed GIT in your local machine. You might need to setup a ssh-key based authentication from your computer to the original repository (depending on the settings of the repository).

Let's say the remote repository exists at ssh://git-user@server01/git-test.git and you want to clone only develop branch (which is analogous to trunk in SVN) for now.

1. From command line (in windows, install the command line tool for GIT) put this command to create the local repository:
  • git clone -b develop ssh://git-user@server01/git-test.git
2. It will create a new folder named git-test. Enter the folder and you can create your own branch (and you'll be switched to this new branch):
  • git checkout -b rafis_branch
3. Now there are two branches in your local machine, namely develop and rafis_branch. You can see the branches with this command:
  • git branch -l
You'll see something like:
* rafis_branch

The * denotes the current branch you're in.

4. Modify or add a new file. Now at this point you still haven't committed your modification to any branches. So if you change the current branch without committing, you'll see the same changes in other branches (in your local repository) as well. You can check the current status with this command:
  • git status
5. If you've added a new file, then use this command to track this file:
  • git add new_file.txt
We still haven't committed the changes (we've merely added this file for tracking by GIT).

If you've modified a file, then the above command is not needed since the file is already tracked by GIT. commit the changes to the current branch (also needed for newly tracked file):
  • git commit -am "Added new_file.txt and modified file.txt"
The changes will now be committed to the current branch. So now if you change the branch, then you can't see the modifications made. For example, if you use graphical interface to see the file, then you must be in the branch (with terminal) where you've committed the changes. If you switch to other branch, then you can't see the new file or the modified file in the graphical interface. All these information are kept in the hidden folder called .git in the repository root.

6. Now lets make the changes available in other branch as well. Lets say you've committed the changes in rafis_branch. Now you want the change to be merged in develop branch. Then first switch to the develop branch:
  • git checkout develop
7. Before merging the changes from rafis_branch, make sure that you're upto date with the origin in this branch. So you'll need to pull from the origin develop branch:
  • git pull origin develop 
This will pull any new changes made in the develop branch in the origin repository. This is required to make sure you don't put any conflict in the origin. Rather merge in the local repository, fix conflicts if any, then push to the origin repository when you're convinced that there'll be not conflicts in the files.

8. Now you can merge the changes of rafis_branch to develop branch:
  • git merge rafis_branch
9. After merging and fixing any conflicts in the files, now its time to push your changes to the develop branch of the origin:
  • git push origin develop
Voila, you've just pushed your first GIT commit to the origin repository. Now when someone pulls from the origin repository, they'll get the changes you made.

10. You can continue working on your new branch (don't forget to switch to that branch "git checkout rafis_branch"). If you think that you no longer need the branch you created in your local machine, then you can delete it (and can create again later on):
  • git branch -d rafis_branch
Now that branch doesn't exist anymore. So the command "git branch -l" will not show that branch now.

Setting the locale in UNIX environment

Recently I upgraded from OS X 10.8 (Mountain Lion) to 10.9 (Mavericks), and noticed that my locale is set to (you can check this with command "locale"):


You'll experience some encoding problems with this locale. Also when you want to remote login to a Redhat machine, you'll encounter some warning. To set the locale to your preferred one (for me its "en_US.UTF-8"), you'll need to add these two lines in your ~/.bash_profile file:

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8

That's all, now you can open a new session (or just use this command within the running session: "source ~/.bash_profile" ) with your terminal and check the locale again. It should be now like this: