Showing posts with label git svn tutorial. Show all posts
Showing posts with label git svn tutorial. Show all posts

Friday, January 28, 2011

How to rewrite history with GIT - Part - 2

This is the second post in the series of two posts to show how easily we can re-write history using GIT.  In the previous post we saw
  • How to change the message of one of the previous commits
  • Removing a commit
  • Merging or squashing two or more commits.  
In this post we are going to look at
  • How to re-order the commits
  • Editing the previous commit to include/remove files.  
Lets not waste any more time.  Lets look at how is it done!

How do they do it?

As in the previous post, lets start by doing some mistakes, by making a few erroneous local commits.

The current situation is that I have synced up with my remote or the public repository and there are no local commits.

git log shows that, I have pushed all my commits to SVN. Although in my example, I am using GIT over SVN. But the rewriting history feature can be used with pure GIT setup as well.

Lets say I had to write a script to insert dummy records in the user table

Committing the new file

After committing this file, I remembered that, the script to create the USER table itself is not yet checked in. Lets create the create user table script and check it in.

Committing the create user script.

Heres a problem, we have the insert user script committed before the create user table script.

The table should exist before we can insert data into it right! We will have to reorder the two commits. But before we fix this issue, lets make some more mistakes.

Lets say, we want to create the role table.

Committing the file.

Note that I have not assigned any primary key to the role table. This again is a problem. We should have a primary key associated any table. Lets do one final commit and insert a ROLE_ADMIN in the role table.

Committing the file.

I realize that we have made enough mistakes, its time to correct them.

Looking at what we have so far.

We have made 4 local commits which have not been pushed to the remote repository. Before we push them to the remote repository we would like to do the following changes
  • The insert user script commit (fded92599c04f70c17a40695d1dfd2c54fa5efe2) should come after the create user table script commit (7f4288ea82a69001f3872630ab05672a54730558).
  • There is no primary key assigned to the role table in the create role table commit (d1f9d2df72ff3470d971a6d7f00b9d35caf59ee6).
To fix the second point, we could make another commit to alter the role table and add a primary key.  But lets edit the commit and make the "id" column as the primary key in the create table statement itself.  This way the create role script will be complete and bug free.

Lets use the command, git rebase -i remotes/trunk (we learned in the previous post) to fix our mistakes.

Please note that we have not yet pushed those commits to the remote repository.  Rewrite history should be used only in this case.  If we have already pushed our changes to the remote repository this feature should be avoided!

The fixup:

This command tells git to do an interactive rebase.  The remotes/trunk tells git that it has to do the rebase on the commit that is currently the HEAD on the remote repository. Basically its the commit that was last pushed to the remote repository. In this example its the commit 88e33ddc9c7b139bb89cbd206e838fe453978e2f - SOMEPROJECT-1| User is able to register on the site - Deep. With this explanation its obvious that we could also re-write the above command as

This command will open up your favorite text editor. The data in the text edit should look something like this

We have seen this message in the previous post. Short recap of the options we have:
  • p, pick -> To pick the commit or use the commit as is.  We used this in the previous post.
  • r, reword -> To reword the commit message.  We used this in the previous post.
  • e, edit -> To edit the commit.  We want to edit the create role table script to add the primary key.  Hence we will edit the commit SOMEPROJECT-2| The create role table script to create the role table - Deep (d1f9d2d)
  • s, squash --> It practically means to squash!  It merges the commit with the previous commit.  Saw that in the previous post
  • f, fixup --> This one is just like squash but discards the current commits log message.
  • It also tell us that if we remove any commit line, that commit will be removed.
To re-order the commits we simply need to change the order of the lines in this text message.

Summarizing what we want to do:
  • Edit the commit d1f9d2d SOMEPROJECT-2| The create role table script to create the role table - Deep
  • Reorder the commits fded925 SOMEPROJECT-1| The create user script to create the batman user - Deep and 7f4288e SOMEPROJECT-1| The create user table script to create the user table - Deep
  • Pick the commits 8745c7b SOMEPROJECT-2| The insert roles script to insert the role values - Deep
Lets edit the commit lines and now they should look like this

Note that we have changed the order of create user table and insert user script commits and we are editing the create role script commit.

Save and quit from the text editor.  After this, GIT will stop at the create role table commit and show some output like this

It clearly tells us that we can now amend the commits using the git commit --ament command and when we are satisfied we can do a git rebase --continue. Lets see what git log shows us

It shows that
  • Currently the top most commit i.e. the HEAD commit is SOMEPROJECT-2| The create role table script to create the role table - Deep
  • The commit SOMEPROJECT-2| The insert roles script to insert the role values - Deep is missing
Where did the SOMEPROJECT-2| The insert roles script to insert the role values - Deep commit go?

Relax! do not worry. We are in the middle of a rebase and we had asked GIT that we want to edit the SOMEPROJECT-2| The create role table script to create the role table - Deep commit. We wanted to add the primary key to the role table. Hence, while doing the interactive rebase, git has stopped at the desired commit and given us a chance to edit/amend it.

We can do the required changes for adding the primary key to the role table and then amend the commit.  After this if we continue our rebase we will get back the SOMEPROJECT-2| The insert roles script to insert the role values - Deep commit!  How awesome is that!
Lets edit createRoleTable.sql file 

Lets amend the commit.

While amending the commit git will open up your favorite text editor and lets you edit the commit message. We do not want to edit any message, lets just save and quit the text editor.

If you do a git show now you will see that the createRoleTable.sql has been successfully updated in the commit SOMEPROJECT-2| The create role table script to create the role table - Deep

Lets continue to rebase and get back the last commit.

This command finishes the interactive rebase and we have achieved the desired result. Doing a git log now, will show that we have successfully re-ordered the commit as well.

Rewriting history is one of the best features offered by GIT! The elegance with which git achieves this is amazing!

Still not using GIT? Do no waste any time. Go GIT it!

Wednesday, January 19, 2011

How to rewrite history with GIT - Part - 1

One of the truly awesome feature of GIT is rewriting history.  This is one of the best and most useful feature that GIT has to offer.  Other distributed version control systems (read Mercurial(HG)) do not offer this feature out of the box (additional extensions are needed to achieve this in Mercurial).  Over and above that, with Mercurial the process of rewriting history is pretty painful.  But when it comes to GIT the support to rewrite history is build right in the core.  The elegance with which GIT performs this task is amazing!

What does rewriting history mean?

Rewriting history could mean many things.

  • Changing the message on one of the previous commits
  • Removing the commit completely
  • Merging two or more commits in one commit.
  • Re-ordering the commits
  • Editing a previous commit to include/remove files

All of these are extremely useful features.  When used correctly could save you from a lot of trouble!

Why should I use it?

For people who are used to central version control systems (like SVN, CVS etc), rewriting history feature is unheard of.  Initially it might feel that you do not need this feature.  What is the user of it?  Take my word on this, its really really helpful feature.  It gives you the power to correct your mistakes even after you have committed!  Isn't that awesome!

Like it already?  

Show me how to do it.  How do they do it?

In this post we will look at how to do the first three points.  In the next post I will cover remaining two points.

Lets start, the current situation of my GIT repository is that, I have synced up with my remote or the public repository and there are no local commits.  

git log shows that I have pushed all my commits to SVN. Although in my example, I am using GIT over SVN. But the rewriting history feature can be used with pure GIT setup as well.

OK, lets start by making some local commits.

I hate to remember those ugly admin passwords.  Lets add a password.properties file that holds the administrator password.

Lets commit this file

Never do this! Never every commit administrator password to your repository. This is a mistake (Yes, I realize that!), we will correct this later.

Let go on for now, lets make more local commits.  Lets say there is a long pending bug we wanted to fix.  Lets fix it!

Lets commit our bug fix.

Again note that, commit messages like "Fixing bug" are hardly helpful. Please please please, always put informative commit message. This not only helps others but it will help you as well.  Providing informative commits message helps get an idea of why the commit was made and what to expect in it. Its just common sense!

We have made another mistake (by not providing informative commit message), but will fix it later.

Moving on, making more changes.

Committing the refactored file

Writing a test case to prove that the performance of the app has actually improved.

Committing

Lets stop at this point and have a look at what we have done so far.

Basically we have made 4 local commits which have not been pushed to the remote repository. We suddenly realize that we have done a few blunders!

  • Committing the administrator password to the repository is definitely not a good idea --> We need to get rid of this commit
  • Fixing Bug --> What is this commit for.  We need to reword the commit message
  • Refactoring --> The refactored file and its test case should be one single commit.  We should not have separate commits for them.  We need to merge these two commits.
GIT gives us a second chance!  Its not too late yet.  We can fix our mistake.

Please note that we have not yet pushed those commits to the remote repository.  Rewrite history should be used only in this case.  If we have already pushed our changes to the remote repository this feature should be avoided!

The fixup:

There are multiple ways of doing this but I will show the easiest.  To rewrite history use the following command

This command tells git to do an interactive rebase. The "remotes/trunk" tells git that it has to do the rebase on the commit that is currently the HEAD on the remote repository. Basically its the commit that was last pushed to the remote repository. In this example its the commit "88e33ddc9c7b139bb89cbd206e838fe453978e2f" (SOMEPROJECT-1| User is able to register on the site - Deep). With this explanation its obvious that we could also rewrite the above command as

This command will open up your favorite text editor. The data in the text editor should look something like this.

It shows the list of commits that will be rebased. It sows some pretty informative comment below that. It tells us to use:
  • p, pick --> To pick the commit or use the commit as is.
  • r, reword --> To reword the commit message
  • e, edit --> To edit the commit.  We will look at this in the next post
  • s, squash --> It practically means to squash!  It merges the commit with the previous commit
  • f, fixup --> This one is just like squash but discards the current commits log message.
  • It also tell us that if we remove any commit line, that commit will be removed.

Pretty neat!  We want to do the following
  • Remove the commit be6628d SOMEPROJECT-2| Adding the administrator password to the repository - Deep
  • Reword the commit b63e0c3 Fixing bug 
  • Merge the commits 62c2f81 SOMEPROJECT-3| Refactoring the file to improve performance - Deep and 95a929a SOMEPROJECT-3| Test case to prove that performance has actually improved - Deep
Lets edit the commit lines and now they should look like this

Note that we have removed the commit line for "be6628d SOMEPROJECT-2| Adding the administrator password to the repository - Deep". We have informed GIT that we want to reword a commit and squash two commits.

Save and quit from the text editor

After that, GIT will open up your favorite text editor.  This time should have information like this

Lets edit the commit message like this


Save and quit the editor. GIT will open up the text editor again. This time it will look like this

Look at the beautiful message GIT has given us. It tells us, this is a combination of 2 commits and give us the two messages. If we want we can edit the messages. But for the sake of this example lets keep the messages as is. Save and quite the editor. It prints some messages like this

Now, lets take a look at how our local commits look like after the rebase.

From the log its evident that we have successfully

  • Removed the commit be6628d SOMEPROJECT-2| Adding the administrator password to the repository - Deep
  • Reword the commit b63e0c3 Fixing bug to SOMEPROJECT-2| Fixing the programing error because of which a deadlocak situation could arrise - Deep
  • Merge the commits 62c2f81 SOMEPROJECT-3| Refactoring the file to improve performance - Deep and 95a929a SOMEPROJECT-3| Test case to prove that performance has actually improved - Deep.  The new merged commit id is 555cb8f
Its needless to say that GIT has an awesome support to rewrite history!  

Still not using GIT?  Do no waste any time.  Go GIT it!

Sunday, December 26, 2010

How to tell GIT about a new remote SVN branch

If your GIT over SVN repository is setup up correctly, then you might not need to do anything mentioned in this post.  GIT can work with both Standard and Non-Standard SVN repositories.

If you have followed the instructions properly, any new remote SVN branch would be fetched by running the following command

But if your setup is different from the once mentioned in the earlier post then, continue reading ahead.

You are a cool developer/QA/BA (or simply a cool person), who uses GIT over SVN.  Someone created a new SVN branch.  You want to checkout this new SVN branch and do some commits on it.  But wait!  When you setup your GIT SVN repository this branch did not exist.  Hence, GIT does not know anything about this new remote branch!  How can you say,

Hey Mr. GIT, here is a new SVN branch.  Could you please start tracking it for me?

How do they do it?

Actually, turns out, its very simple.
  • Do some edit in the .git/config file
  • Do a git svn fetch of the new remote branch
  • Create a local branch pointing to the newly added remote branch
  • Start hacking the code on the new branch!
The key here is only the first step.  Without wasting anymore time lets dive into the solution.

Step - 1:

Open the "config" file in the .git directory in your favorite text editor. 

Lets say that the new SVN branch is called "branch1".  Its located at http://non-standard-repository.googlecode.com/svn/branches/module1/branch1  

Add the following entries to the .git/config file

Almost there!

If you do not feel comfortable editing the .git/config file manually then use the following commands to achieve the same effect

Step - 2:

The setup is done.  All we now need to do is execute the following command

This will get the version history from the "branch1" SVN branch into the local GIT repository. By now you should have a remote branch "branch1" created in your git repository

Step - 3:

Crete a local branch from the newly added remote branch is simpel enough

You are now all set to start hacking the code on the local_branch1!

Step - 4:

No explanations required here!

That's it!  With GIT there are always multiple ways of solving any problem!  Go GIT it!

Thursday, December 9, 2010

How to work on multiple streams of work with GIT over SVN

In the last few posts, I have mentioned several times that working on multiple streams of work using GIT is childs play.  In this post, lets actually look at the actual steps, to work on multiple streams of work.

Lets say that Deep is working on the next generation Math package.  He aims to write the next generation Factorial program (yea yea! I know, how hard could that be).  This program would be the highly optimized and best performing Factorial program ever!

He is currently on the master branch i.e. the default branch.

Lets start:

Deep starts of with the simplest solution first.  He writes the code to find the factorial of zero.  Here is what it looks like.

Deep decides that, he is at a logical point (the point at which all his tests are passing and code is in a good shape)

He has achieved the unthinkable, the factorial of Zero is found!  Wow! what a discovery!  Lets commit this change to GIT.

He moves on, adds more code to find the factorial value of 1.

Again, a logical point. Time to commit.

Next, he adds code to find the factorial of any given number

Thats quite some progress. Lets commit again.

At this point, Deep thinks, he has developed the ultimate algorithm to find factorial of any number! He decides to push his changes to SVN and make them public (so that other people can appreciate the awesome code!)

Pushing changes to SVN

World has one less problem to solve! Deep decides to take up another challenge, he decides to write the code for Fibonacci series!

He starts off in the simplest possible way. Fibonacci value of numbers less than 2 is 1.

Logical point, need to commit to GIT.

Turning point:

At this point, Deep's boss, comes over and tells Deep, you moron, dumb a**, @#$#, you don't know that, the Factorial of zero is not zero its 1!  Fix it! And fix it now!  Deep is all terrified!  He has to fix this goof up as soon as possible!  After the initial hysteria!  He says to him self Aal izz well!

Current git log looks like this:

As you can see there is one commit on the top, which is not yet pushed to SVN. He does not want to push the Fibonacci commit to SVN but still wants to fix the issue. He does not want to lose the Fibonacci change either!

Basically he wants to work on two things, Factorial bug fix and Fibonacci series!

GIT has awesome support for working on multiple streams of work! Let see how GIT enables Deep to deal with this situation.

How do they do it?

He decides to create a bug_fix local branch. This branch will have the code that points to the current code in the SVN repository. This branch will not have the Fibonacci commit. This is how its done

GIT log will show that this branch does not have the Fibonacci commit

This is because we have created the bug_fix branch to point to the current code in SVN.

Next, Deep fixes his goof-up like this

Committing,

Since boss wanted this fix checked-in asap, pushing to SVN

The GIT log will show that we have pushed only the bug fix to SVN

Boss is happy! The goof-up is fixed!

Back to work! Lets continue coding on the Fibonacci series. Remember? That code is still in the master local branch. Hence, to continue working on the Fibonacci series we need to switch to the master branch.

Before moving any further, lets get the latest from SVN

GIT log will show that, we have received the commit that fixed the goof-up, and the Fibonacci commit is placed right on top of it!

End result:
  • Boss is happy because Deep fixed the goof-up pretty fast
  • Deep is happy because he did not have to revert, patch or do any kind of circus to work on multiple streams of work!
  • World is happy because, optimized Factorial program is available :)
Thats all folks!  Is this example enough?  Do not waste any more time Go GIT it!

Friday, November 26, 2010

How to use GIT with non standard SVN repository layouts

In my previous post I had explained the commands necessary to work with GIT on a standard SVN repository.

But, life is not always that simple!  What if you wanted to work with a repository that has non standard svn layout?  Super GIT to the rescue!

What do I mean by non standard SVN layouts?  Basically, it means that your repository does not follow trunk/, branches/ and tags/ directory structure.

An example of that would be something like this

Note that the brances and trunk of module1 is located under http://non-standard-repository.googlecode.com/svn/branches/module1/ url and tags are located under http://non-standard-repository.googlecode.com/svn/tags/module1/

Lets say that, 90% of the time, I will be working on module1's trunk which is located at http://non-standard-repository.googlecode.com/svn/branches/module1/trunk/

Lets see how we can use GIT over SVN, for such weird SVN repository.

Setting up the GIT repository:

You might be tempted to think that executing the following command should do the trick.

But, anyone who has tried this earlier would know that, this does not work!  GIT checks out branch1, branch2 and trunk as separate folders.  Thats not what we want.  What is the right way to do this?

How do they do it?

Well you need to split the task of cloning the repository in three steps
  1. Do a git init to the root of the repository i.e. http://non-standard-repository.googlecode.com/svn
  2. Do some edits in the config file under .git directory.  What edits?  Have some patience, we will see this shortly
  3. Do a git svn fetch to get all the trunk and branches
You must have realized by now that the key here is the Step - 2.

Lets see them one after the other.

Step - 1:

Lets first init an empty git repository using the following command

Please note, I am using the root URL of the SVN repository to init the git repository.  The URL is only till /svn.

At this point you should have a directory called non-standard-git created.  If you go inside this directory you should see the empty git repository i.e. the .git directory created.  Step - 1 is done.

Step - 2:

Open up the .git/config file in your favorite text editor.  It should look something like this

Change it to look something like this
Note that the fetch, branches and tags properties have been modified.  The key here is to use the relative path of module1's trunk, branches and tags in the config file.  Step - 2 is done.

Step - 3:

The configuration changes have been made now lets fetch the trunk and branches.  Use the following command

After the fetch is done you should be all set!  All your branches, tags and trunk will be pointing to the right location.  And you are good to go!

Tip: If you do not want to fetch the entire history right from the very beginning, that could be easily done.  Lets say you wanted to fetch all the revisions from revision 1000, then use the following command

That's it!  We can now work with SVN repositories with non-standard layouts.  The support provided by GIT for SVN is nothing but, awesome!

Tuesday, November 23, 2010

How to use GIT with SVN repositories

In the previous series of post, I narrated the real incident that made us move to GIT.  By now, its must be obvious to you guys that, GIT is an integral part of any project that we execute from now on.

Most of the client projects we execute use Subversion (SVN) as their central repository.  There are various reasons because of which they will not move to pure GIT repositories in near future.  But this should not stop us from reaping the benefits of GIT right!

In this post, I am going to demonstrate the basic set of commands required to use GIT with SVN repositories.

Introduce your self to GIT:

Its just good manners to introduce ourselves to people who we are going to work with, isn't it!  So lets introduce ourselves to GIT

The above config values tells GIT that,
  • User name is for all the git repositories on this machine is Deep Shah 
  • Email address for all the git repositories on this machine is  deep@gitshah.com
This step is not required, but is considered good practice.

Next, lets bring some color in our dull lives.

These configs will show some colors on the git prompt.  Don't execute the above commands, if you hate colors.

Thats about all the configs you need.  All set!  Lets get some code!

Getting the code:

In this step, we will get the code from SVN and create a local GIT repository.  There are two types of SVN repositories.
  • Repositories with the standard layout.  Standard layout repository, is a repository that has trunk, tags and branches folders at its root.  As the name suggests, these folders hold the trunk, tags and branches of the repository.  Pretty straight forward!  Look at this link https://play-with-hg-svn.googlecode.com/svn for an example of standard layout SVN repository
  • Repositories that do not use standard layout.  Non standard repositories could have any weird layout.  I have seen repositories having, trunk somewhere nested under the branches!  In short layout could be absolutely anything.  Have a look at this link http://non-standard-repository.googlecode.com/svn/branches/ for an example of non-standard layout SVN repository.
GIT supports both types of SVN Repositories equally well.  But, for the sake of simplicity we will look at standard layout SVN repositories in this post.  In the next post we will look at non-standard SVN repositories.

To get the code you will need to clone the repository at https://play-with-hg-svn.googlecode.com/svn.  This can be done using the following command.

The above command will create a git repository locally on your machine.  The repository will be created under the folder called play-with-hg-svn-git.

If you open that folder you will see, a folder named .git is created.  This is the only folder that GIT needs.  It does not create any other folder anywhere else.

Comparing this with SVN, SVN keeps the information littered around in countless .svn folders.  For each directory/sub-directory in the project there will be a .svn folder.  Man that is a lot of .svn folders!

The -s option tells GIT that, the SVN repository follows a standard layout (trunk/, tags/ and branches/).

GIT will download the information from revision 1 to the current or the HEAD revision.  The entire revision history is kept on the local machine.

What? What did I just say?  The revision information from revision 1 to the current or the HEAD revision will be kept on my local machine?  Man! that will take my entire hard disk.  

Actually, it wont!  GIT keeps all the history in the compressed format.  I have tried cloning very big repositories (once that have around 1 GB of content).  The entire .git directory (which holds information about all the revisions) was around 350 MB.  Wow!  That's incredible!  The entire history (of a very big repository) is on my local machine and is packed in under 350 MB!

If you still feel that, downloading so much history is just pure waste of bandwidth, don't worry, GIT has an alternative for you as well.  For e.g. lets say that, you are going to need the history form revision 20 onwards only, then use the following command

The above command will start downloading history from revision 20 onwards.  For your project substitute 20 with any other revision number.

The clone command my take some time to finish for bigger repositories.  Be patient.  Grab a cup of coffee or play a game on XBox while it finishes.


After clone finishes, you will see that we have got all he code checked out.  Got the code, lets start hacking it!

Ignoring files:

All serious projects generate a few binary files.  We do not intent to commit those files.  Hence, we must ignore them.

To ignore files in a GIT repository we have to create a file called .gitignore directly under your root directory (i.e. in this example under play-with-hg-svn-git).  This file accepts ant like path expressions.  Any path or file name you put in this file would be ignored and will not be shown while you commit your changes.


Its a good idea is to commit the .gitignore file itself to SVN.  This will help other developers who are using GIT on the same repository.

To generate this file automatically using the SVN ignores, use the following command

Remember, when you are working with GIT, you will always be working on a local branch.  By default GIT creates a local branch called master.  It might feel that this branch has special meaning, but its simply a default name chosen by the GIT folks.  It could have been named anything for e.g. servant, batman, robin or absolutely anything else.

At this point, you are all set.  The SVN repository has been cloned, code is checked out and ignores have been setup.

Viewing History:

You still do not believe that you have entire history on your local machine, do you?  OK, its time for some demonstration!  Disconnect from network, turn off your WiFi connection, remove the network cord and type in the following command

This command will show you the graphical representation of all your commits at lightning fast speed.  You have no network connection, but still you can view the changes made in the first revision!  With SVN this was never possible!

Next, try this command 

This command shows the text representation of your commit history in the less format.  To navigate to the next/previous pages use the keys "<space>/b" respectively.  To quit from this view use the key "q"

Local Commits:

The best thing about GIT is, ability to create cheap local branches.  These branches reside on your local machine.  This feature helps a great deal.  This feature makes it possible for us to work on multiple streams of work.  Will explain in detail how this is done in future posts.

To view what branches you have currently use the following command

This command should show you something like the above image.


See the "*" besides the master branch, that means currently you are on the master branch.  The branches shown in red color are the remote branches.  They correspond to the actual SVN branches.  We always work on the local branch and never ever on the remote branch.  Currently we are working on the master  local branch.

Lets make some code changes.

At this point if you type the following command

This shows some information on the screen which looks cryptic.

Actually its very simple.  Things that are in red color (with a "-" prefix) have been removed and things that are in green color (with a "+" prefix) have been added to the first.txt file.  As simple as that!

This command shows you the current status of the master branch.



It give some important information to us.  First it says that we are on branch master (as if we didn't know).  Next, it says changed but not updated.  This means, one file first.txt has changed but it has not been staged yet.

GIT has a concept of staging the files before committing.  For now just remember that to commit the file first.txt you will have to stage it first.  Here's how you could do it

Above command will stage only one file first.txt.  To stage all files, use the following command.


You can do the same thing using the git gui command.

Now we need to commit our changes.  But wait we have no network connectivity!  How can we commit without having any network connectivity?

Offline/local commits are single most important advantage of using GIT.

To commit your changes use the following command

At this point, if you look at the log (git log), you should see a brand new commit at the top with the comment First commit from GIT.



Reverting commits and files:

Strange looking 40 char long alphanumeric strings in your git log, are nothing but git commit ids.  Although its 40 char long, each commit can be uniquely identified by using the first 7 or 8 chars.

After full days of hard work you find out, the commit you have made will not work and it might break some functionality.  You want to revert that commit.  To revert a commit, use the following command



This will open up your favorite text editor.  Lets you edit the revert message, shows you what files will be reverted.  Save and quit from the editor would revert your changes.

If you now do a git log, you will see two commits on the top.  One that you created and one that you reverted.

Reverting a file:

To revert a file that has not been staged, use the following command

Read this command as, checkout the last committed version of the file over your changes

To revert a file that has been staged, you will first have to un-stage it using the following command

Then you can revert the first.txt using the checkout command

Updating from and Committing to SVN:

Time has come!  Time has come to commit our changes to SVN.  But before that, its always a good practice to take the latest from SVN.

To get the latest changes from SVN use this

This command will take the latest changes from SVN and apply your local commits on top of those changes.  This means that, all your local commits will appear on top of the latest changes we received from SVN.  This is exactly what we want!

All the commits that we have made so far are only in your local repository.  They are not visible to other developers.  To push your commits to SVN do this

Each of your local commits, will now be committed to SVN as a separate commit.

There is an obvious advantage with this strategy, you can keep making local commits as often as you want, i.e. at every local point, without effecting other developers.  When you are ready with the feature you were developing, make those commits public by pushing local commits to SVN.  This enables developers to go back in time and see how a feature evolved, when it was under development.  The version history of every logical point in the feature development is maintained!  This was not possible when we used only SVN.

That's all folks!  This much information is enough for you to get started with GIT.  Initially it might feel like too much work, but trust me on this, it pays off!

The advantages are far too many.  Do not waste any more time, go GIT it!
Have some Fun!