Tuesday, April 12, 2011

Git and Subversion :- Bringing others on board...

In the previous post, Pulling a Subversion Repository into Git Locally, I shared the process that I went through in order to pull Subversion into Git so that I can start using Git locally with Subversion as my remote repository. Since that time, I have been trying to figure out the best way to get Git to Subversion repositories set up for others on my team. I have gone through a lot of trial and error and now I believe that I have finally come up with an easy step-by-step solution.

Before I begin, let me first say that you probably want to follow these instructions for two main reasons:

Cloning a Subversion Repository is very time consuming
If you have never cloned a Subversion repository using Git, you will be amazed at how long this process can take (depending on how much history you want in Git). I typically chose 1000 revisions in the past, and that could take up to an hour or more. This is no fault of Git, instead, Subversion is to blame. With this process, only one person has to incur that time investment. Everyone else, can just reap the benefits without the hassle

Fetching too much data
This was the problem that has stumped me for months. While I was able to alleviate the first challenge of the time investment for everyone, I could not figure out why Git was trying to retrieve so much history from Subversion. This amount of history was even earlier than the 1000 revisions of the initial clone. Finally, I figured out that it has to do with a property called branches-maxRev. Through the use of this property, we can make sure that when you perform git svn fetch, that it will not attempt to retrieve any more history than necessary. So, let's get started

By this time, I am already assuming that you have followed the directions from Pulling a Subversion Repository into Git Locally, and you already have a Git repository with the amount of history from Subversion that you desire. From that point:

  1. Navigate to your git repo. Not the .git folder, but the folder containing that folder
  2. Open your browser to the git svn man page
  3. Scroll to the bottom section titled Basic Examples, and look at the third example
  4. Locally, start the git daemon server by typing: git daemon. This will start a git server on your local machine that will allow others to pull from you.
  5. Follow the instructions from the Basic Example starting with mkdir all the way to the end. Please note that the line that section that says server:/pub/project must be replaced with a valid git url (for instance git://jdcarlflip.blogspot.com/path/to/git/repo)
  6. Once you have finished those instructions, in your newly created repo, open the file .git/svn/.metadata
  7. Inside of there, you want to put a line under the uuid similar to the following branches-maxRev = 11111 where 11111 is the revision number that you do not want to go past. If you don't know what to put in there, look back at your original repo that you cloned from, and use the same number.
  8. After you have done this, type in git svn fetch, and it should not attempt to retrieve any revisions that are older than the ones you have already

If there are any questions, please let me know.....Enjoy.

Thursday, February 24, 2011

Mobile Dev Day :- iOS Development

This past weekend, I had the wonderful experience of going to MobiDevDay Conference that was held in my hometown, downtown Detroit. It was an amazing conference, and a big thank you to all of the work and effort that went into making it such an excellent and wonderful experience.

Since I am familiar with the concepts of Android development, I decided to spend some time looking at what it takes in order to develop an iOS application. I have never, ever seen what Objective-C even looks like, before this conference, and I am glad that I made the decision to look at it.

....fast forward to yesterday....
I was having lunch with a friend of mine, who is a polygot programmer. He told me about a wonderful FREE series on iTunesU from Stanford University that really helped him learn how to develop Objective-C.

If you are interested, here is the iTunes link.

Enjoy....

Friday, July 9, 2010

Git feeling a little sluggish....?

So after working in my Git repository for the past couple of months, I started to notice that things are starting to run slower. I remember the days when I first started using Git, it was lightening fast. Now, it is still fast....but I have been missing the lightening.

That is until I was told about the command

git gc --aggressive

This command has brought the lightening back to fast in git.

Share and Enjoy.

Wednesday, April 28, 2010

Git and Removing Empty Directories

So, I encountered a very interesting annoyance yesterday with Git.  I can't say that it was a problem since it is working as designed, and there is a solution. 

I am tracking 7 different branches of Subversion in Git.  What is really interesting, is that I actively work on most, if not all of those branches.  When switching back and forth between branches, as you can imagine, there are some branches that has folders and code that other branches do not.

Git, by design, does not track folders.  The side effect of this is that when I am working on Branch A that has a folder F, then I checkout Branch B, which does not have folder F, that folder F still remains.  This is minor but it can quickly become very annoying especially when working in Java and there are a ton of empty packages (folders) in your source directory.  So what do you do...?

There is a command that will clean up all of the files that are not part of your git repository - including the folders.  This command is:

git clean -fd

Keep in mind, that any files or folders that are not part of the git repository will be removed when you issue this command.  If instead, you would like to do a dry run and see what exactly would be deleted prior to actually deleting them, you can run

git clean -fdn

Happy Coding...

Monday, April 26, 2010

Git / Subversion :- Retrieving an Old Branch

When I first started using Git and Subversion together, I decided that I didn't want the entire Subversion repository on my machine. Instead of cloning the entire Subversion repository, I cloned the last 1000 revisions. This has been working very well for me until today.

Today, we discovered a defect on a branch that was created and deployed well before the starting point in Subversion that I decided to clone from. If instead, the branch was created within the last 1000 revisions, I would have had that branch in my local Git repository. I could have checked that branch out, created a tracking branch, made the necessary code changes, merged it back into the master and sent it upstream to Subversion. But, this was not the case. The Subversion branch that needed code change was not in my local Git repository. How would I get it in there?

After doing some browsing on the internet, I think I came up with a solution that was inspired by a blog post titled Complex SVN repository conversion to Git, by Simeon Pilgrim. While Simeon was not dealing with the same problem that I was dealing with, the solution that he used for his situation could easily be molded to help me with mine.

What I ended up doing was hand modifying the config file that is located within the .git directory in the repository. I added another remote Subversion repository entry. This entry was just going to be used to track the one branch. Here are the details of that entry:


[svn-remote "0.5.0"]
url = http://subversion.sagetech.com/svn/somethingReallyCool/branches
fetch = 0.5.0:refs/remotes/svn/0.5.0

This entry above is telling Git that I have a remote Subversion repository that will be aliased as 0.5.0. It also tells Git the URL of the repository as well as the path that should be used for fetching. The fetch actually specifies two paths separated by a colon in the following format "origin:destination". This line is saying that it will pull the code that resides in...

http://subversion.sagetech.com/svn/somethingReallyCool/branches/0.5.0

and put it into the Git remote branch at refs/remotes/svn/0.5.0.

After this entry was made into the .git/config file, all that was left to do was to fetch the code. That was done with the following command:

git svn fetch -r1200:HEAD 0.5.0

This fetched from the Subversion branch 0.5.0 into my Git Remote branch all of the revisions starting at 1200, and allowed me to fix the defect and publish back to the 0.5.0 branch.

Happy Coding

Monday, April 19, 2010

Git Revert to the Rescue...

Once again, Git has saved yours truly.

One of my current responsibilities is to merge a branch within Subversion to the main code line (trunk). Usually, this doesn't require a lot of effort in order to complete. For this merge, since there were relatively few changes, I decided to perform the merge using the command line.

I specified my range of revisions that I would like merged down to the trunk, resolved all of the conflicts, and then committed the merge to Subversion. Later, I realized that I did not specify the correct range of revisions, and therefore, the merge was incomplete. I was just about to revert my changes in the Subversion repository, when I realized that there had been some commits done to the trunk after my merge. Doh!!!

Why is this such a problem? Well, it is a problem because if I was to roll back the Subversion repository to the point right before the incomplete merge that I performed, then I would also be removing the commits of my teammates. That would not make me too popular amongst my co-workers.

At this point, what could I do? One option would be to take the commit that occurred after my incomplete merge and save it off somehow using a patch tool, then roll back the subversion repository, then reapply those changes. Another option would be to figure out all of the changes that I made as part of my incomplete merge, and roll each file back one by one to the previous version. Both of these options sounded horrible and time consuming. Luckily, I could use Git in order to solve this problem.

Git Revert to the Rescue

Git has a great feature called revert. In a nutshell, the revert feature of Git allows you to specify any commit, create a reverse-patch for that commit, and commit it to the repository using one command. In other words, it backs out the changes of a commit. For example, let's say that your repository has the following 4 commits:


A-B-C-D

You realize that there is a bug in the commit titled 'B', and you would like to roll the code back. You can do that using Git by typing


git revert B

which would change your repository to:


A-B-C-D-E


The commit titled 'E', is actually a reversal of the commit B.

Needless to say, this little trick saved me a lot of time and effort. All I did was revert the merge commit, and attempted the merge again, this time making sure that I specified the correct range of revisions. For this little feature alone, I am grateful that I am using git.

Happy Coding

Friday, April 16, 2010

Git :- Unrealized Productivity Gain

After showing a co-worker my workflow using Git integrated with Subversion, he pointed out a productivity gain that I am getting that I have been taking for granted.

When I was using Subversion, I would have multiple directories that would represent different code lines. I had a directory for the trunk, and a directory for each of the branches of code for our code base. On top of that, when I wanted to work in one of the other code lines, I would have to restart my IDE, and then point it to the correct code line. This did not take too long to do, however, considering the amount of times I jump between code lines, it was definitely time that was not well spent.

Using Git, I now only have one directory with all of my code. If I want to switch to a different branch, then all I have to do is perform a checkout of that branch, and refresh the code in my IDE. Simple, elegant, fast and effective.

Yet another reason why I am loving Git.