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.

Tuesday, April 13, 2010

Pulling a Subversion Repository Into Git Locally

Over the past month, I have really enjoyed using Git with Subversion. However, when I was thinking about how I got Git all setup to access Subversion, I realized that I can't remember exactly how I did it. So in the interest of remembering how to get Git setup to work with Subversion, I am writing this post for myself and anyone else who is interested in using Git in a Subversion environment.

After installing Git, you are going to want to determine the URL of the Subversion repository that you are going to want to integrate with. For our purposes, let's use the Open Source project AppFuse, whose Subversion repository is hosted at https://appfuse.dev.java.net/svn/appfuse/trunk.

First thing to do is to clone the repository to your machine. This process of cloning is what is going to convert the Subversion repository into a local Git one. At this point, I am not interested in cloning the entire repository (all of the branches, tags). I am also not interested in cloning all of the revisions (at the time of this blog post, their Subversion repository is on revision 3333). Instead, I only want to clone the trunk with the past 100 revisions. Here is the command necessary to do just that:


git svn clone https://appfuse.dev.java.net/svn/appfuse -r3330:HEAD --prefix=svn/ -T trunk -b branches -t tags appfuse.git

(You can choose to omit the -T, -b, and -t options, if you so desire. We can always add those details later.)

If you are prompted for a user id and password, use the account 'guest' without a password.

During the cloning process you are going to notice that git is actually mapping the 100 commits in Subversion to a Git commit object in your local repository. As you might imagine, this process could take a very long time, depending on how many revisions you are cloning into your local repository.

After your clone has completed, you should have a directory called appfuse.git. Move to that directory and type the following

git log -3 --stat


This will show the last three revisions that have been made to this source code. The first commit looks like this:

Author: mraible 
Date:   Sat Feb 27 15:54:03 2010 +0000

    Turn off EhCache update checking.
    
    git-svn-id: https://appfuse.dev.java.net/svn/appfuse/trunk@3333 2aeb74e6-0f1c-0410-991c-92d95bb9df37

 web/common/src/main/resources/ehcache.xml |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
The most interesting thing about this log is the fact that you can tell what Subversion revision it came from by the line that begins with git-svn-id. You can see that it comes from the revision 3333. There are many other features of git log that I am not going to talk about, but do encourage you to look into.

Congratulations, you have successfully pulled the Subversion repository into Git locally. In the next couple of blog posts, I will spend some time discussing how to commit changes back to the repository, as well as how to track and commit to branches in Subversion.

Happy Coding.

Monday, April 12, 2010

Git Interactive Adding...now you tell me...

First off, major thanks to Scott Chacon and his video post on how to do Interactive Adding in Git. Unfortunately, I am only now getting a chance to review this video, since it was crunch time at work today...

I spent most of the day today hunting down a defect. This defect was a good one. You know the kind. The kind that really stretches your brain and gives you a chance to flex your skills as a Software Developer. Of course, as always, there was a logical explanation for the erroneous behavior that we were seeing, however, it took quite a lot of time, and a lot of Tracer Bullets, in order to find the problem. After finding the problem, we made the appropriate code changes...I love team coding...and then I wanted to commit those changes. This is where Interactive Adding in Git would have helped out a ton...

I wasn't interested in committing all of those tracer bullets, instead, all I wanted to commit was the actual fix. Using interactive adding, I could have staged the changes that actually fixed the issue in one commit, and then I could have added the Tracer Bullets as another commit. Since these were separate commits, I could have then switched back to my master branch, and cherry picked the commit that had the fix in it. (Remember, I do not develop on the master branch and instead choose to merge in changes from other branches once I have completed development and testing). This would have resulted in a very nice and clean fix to the master branch.

Unfortunately, since I am not yet the git slinger that I aspire to be, I had to commit the tracer bullets and the fix underneath the same commit and merge all of those changes down to the master branch. So, I have a little code clean up to do...doh!!!

After watching Scott's video, I am more confident in my interactive adding git skills, and I look forward to using them the next time I want to selective commit a portion of my changes.

Happy Coding...

Thursday, April 8, 2010

Distributed Version Control Systems.....how I love thee...

Today, I was working with a developer at his station and we made some changes to some code. I asked if he could commit those changes, and he told me that he was not ready to commit those changes because he had made changes elsewhere in the system and those other changes were not yet ready. This reminded me of why I have made the switch to using Distributed Version Control.

You see, when you are using Distributed Version Control Systems, you can adjust your workflow in such a way that you do not run into these types of scenarios. With the advantage of creating branches of code locally, you can work on completely different efforts simultaneously. Currently I have 7 different branches that reside locally for one of my customers. This allows me to switch between different efforts that are currently underway. More than that, since I am using Git, I am able to synchronize with my customer's Subversion repository and delivery the changes that I want to delivery and retain the ones that I don't.

To illustrate the advantage of using DVCS, let's take the scenario I mentioned earlier. A developer approaches me and asks me for some help and would like to pair program a specific feature. I am smack dab in the middle of working on something (I mean the code doesn't even compile). Since I am using Git, I am able to commit this code that doesn't compile and create a new local branch based on the trunk of the source code that is in Subversion. I realize committing code that doesn't compile is a big NO-NO, but I believe that helping your co-workers / customers is much more important (besides, I would only be committing those changes locally, and not pushing them to Central repository anyways). Now the code that resides on my machine looks exactly like the code that is in the repository. We make the necessary code changes, I commit them locally to my local repository and push them back up to Subversion. My co-worker / customer goes on his merry way, and I switch back to the branch that I was working on when they came over for assistance.

DVCS...it is a beautiful thing...

Wednesday, April 7, 2010

I Love the Library...

Yet another reason why I love the library...


Kent District Library has added Mango Languages to its growing list of patron resources. Mango is free to all KDL cardholders, and is an easy, effective way to learn to speak a foreign language. Mango is available in two versions

Read complete story

Friday, April 2, 2010

Coming back to my senses...

In case someone happens upon my last post not realizing that it was April Fools Day, I just want to take a quick moment to clear the air...

I think that Java/JVM is one of the most fascinating language / technology of today. There is an incredible amount of innovation happening in the arena, and I don't forsee this changing anytime soon. There has been plenty of other languages out there whose claims of being the "Java Killer", has been proven false over time. I am not knocking those other languages - there are some very attractive features of those languages. I am just acknowledging the fact that after those claims, Java/JVM is still around. Not to mention there are plenty of companies who have an incredibly amount invested in the Java/JVM technology.

For these reasons and more, I think that Java is going to be around for quite a while.

Thursday, April 1, 2010

Goodbye Java....

That's right. I am done. Finished. The game is over.

I have finally decided to put my Java "badge of shame" down. I mean, let's face it, Java is not the Mercedes of Programming Languages anymore. There hasn't been a lot of innovation going on in the Java / JVM space for years now. I need to start working in a technology that is more relevant to the needs of my customers of today and tomorrow.

I just can't believe that I have wasted this much time of my career in Java. So to all, wish me luck as I venture on a new path in development, away from Java...