Results for tag "git"

I moved to Git SVN

posted by Roberto Cortez on
tags: ,

For the last couple of years, I’ve been working with a company that uses Subversion. Yes, you are probably pointing now that we should have migrated to Git by now. Let’s not discuss that. Until now, Subversion didn’t get much in my way while performing my development tasks, but that slowly started to change. Probably a lot of people went through this as well.

My SVN Problems

My main problems with Subversion at the moment are:

  • Working with multiple Subversion branches at the same time. I usually checkout each branch that I need in a separate folder. Yes, I could use svn switch, but it’s harder to isolate new feature development from bug fixing with only one source.
  • Our Subversion repository is quite big now. You feel the pain (slowness) when comparing files in the history or annotating a file.
  • Multiple commits relating to the same feature. I like to commit the several stages of a feature development. This helps to establish baselines on what’s working and what’s not in a timeline. But it’s a pain to look into the multiple commits of that feature when you are searching the history.

Solution

I’m also a Git user, and I know that Git solves these problems for me. Branches are cheap to create and you can stash your changes for easy switching between branches. Since you have a local copy of the repository, everything is faster. Using squash will combine all your feature development commits into a single commit for a cleaner history.

Instead of nagging the organization to move to Git (I’m doing that anyway), you can jump right away to Git, by using git svn. It ships with the standard Git installation and allows you to have a bidirectional connection between Git and Subversion.

This isn’t something new. It’s been around for a few years, but this is my first time using it. I have to say that it was not easy to setup thing the way I wanted. So I’m writing this post to remind myself of the steps I have followed in case I need them in the future. Of course, I also hope that these could help other people experiencing the same problems.

Setup

You’re mostly going to use the command:

git svn

Assuming the following information:

SVN Repository URLhttp://svn-repo/myProject
SVN Trunk URLhttp://svn-repo/myProject/trunk
SVN Branch URLhttp://svn-repo/myProject/branches

Init the Repository

Let’s start by creating our local repository. Type the following command:

git svn init --trunk=trunk http://svn-repo/myProject myProject

This will initialize a local Git repository. This command will not checkout anything yet. My Subversion repository follows a standard directory layout and I could use the -s argument instead of manually indicating the trunk. I choose to manually indicate the trunk with --trunk argument because I only want to check out the trunk. If you use the -s everything sitting on branches and tags will be checked out. In my case I want to control exactly which branches , or tags I’m checking out.

If we want to include branches we can type:

git svn init --trunk=trunk --branches=branches http://svn-repo/myProject myProject

Better yet, if we only want the branch B1 and the brach B2 we can do it like this:

git svn init --trunk=trunk --branches={B1,B2} http://svn-repo/myProject myProject

Now look into the .git folder and file config. It should look like this:

You can always change the settings by manually editing this file.

When fetching specific branches there is a trick here. Notice that the generated file has a * after the branches definition of {B1,B2}. This means, that git svn will fetch all subdirectories of the branches folder B1 and B2 and track each individual subdirectory as a remote branch. It’s a bit weird. Maybe I’m doing the original command wrong, but I had to manually remove the * to track the branches properly. Make sure that you have this in the file:

This Stackoverflow question: How do I tell git-svn about a remote branch created after I fetched the repo? explains in a more detailed manner how to deal with branches.

Fetch the Code

To actually fetch the code from the Subversion repository type:

git svn fetch --no-follow-parent

In same cases, Git can create additional branches with the format {B1}@-{0-9}. You usually don’t need this and you can prevent their creating by adding the --no-follow-parent parameter. For a full explanation please check this Stackoverflow question: git-svn clone | spurious branches.

By the way this operation can be VERY VERY SLOW, depending on the size of your repository, it can take several hours to complete. If you are short on time, execute the commands before you go to sleep and you should have them ready when you wake up. To speed it up, you can use the parameter --revision and specify a Subversion revision number. The fetch will only be performed from that point forward. The downside is that you don’t have the historical data before the specified revision.

Update the Code

When you need to update your Git repository with the Subversion one, execute:

git svn rebase

Push the Code

You don’t use push to send your local changes to the Subversion repository, instead use:

git svn dcommit

Final Thoughts

You can now enjoy all the benefits of using Git even if you are stuck with a Subversion repository. There are also a few limitations, but you can work around them. You cannot directly map multiple Subversion repositories to a single Git repository. This may be relevant depending on your Subversion structure. Also, committing your changes to Subversion may be a bit slow.

Anyway, I’m happy with the change. I feel that it increased my productivity, but that’s something you have to figure out by yourself. Just give it a try and see if it works for you. If not, you can always use your old Subversion repository.

Maven Git Release

posted by Roberto Cortez on
tags: ,

I need to start this post by stating that I’ve only started to work seriously with Git within the last year. Unfortunately, a lot of the projects that I work on are still using SVN or CVS, but I’m now finally starting in a few that use Git.

During the last few years, I’ve done a lot of software releases using Maven Release Plugin. I still remember that I’ve took a full week just to setup the plugin in one of my projects. It worked well most of the times, but if something went wrong you could spend the next few hours fixing the problem. Oh boy, what a nightmare!

Recently, I wanted to do the same operation with a Git project and I came across with the Maven JGit-Flow Plugin and I have to tell you that this is fantastic! Very easy to setup and worked flawlessly on the first try!

This plugin is based on the development model described in the post A successful Git branching model by Vincent Driessen. Take your time to read it, since it’s very interesting.

I’m going to show you how to perform a release using this plugin. I’ll use the project from my latest post about Spring Batch as Wildfly Module.

Setup

Setup is very easy, just add the following to your pom.xml:

I’ve just added the noDeploy configuration, because I’m not releasing to a Maven repository. That’s it!

Release

Let’s look at my project branches and version:

Now, just run mvn jgitflow:release-start:

You get an interactive menu to pick the version numbers you want to release, the same way as Maven Release Plugin. I’m developing on the master branch, but during this process a release branch is created with the release versions and development branch with the new development versions.

Now the cool thing about this, is that everything is still in your local environment! If you are not happy with the changes, you can get rid of the branches and start over. No build was performed at this point.

If we want to release, just run mvn jgitflow:release-finish:

In this step, the release branch is going to get merged as described in A successful Git branching model and create the tag. Remember, nothing has been pushed yet, so you can always revert the process.

Let’s have a look into the branches and tags now:

Now you’re a push away to complete your release and ready to keep developing in your new updated development branch. How easy was that?

Conclusion

Looking into some differences between the original release plugin and jgitflow:

  • You don’t have to worry about stage commits. Everything is local until you push.
  • No more problems with other people changing pom.xml during the process.
  • Your project is only built once, saving release time.
  • Very easy to setup. Everything is picked from your Git configuration.

When I was investigating / writing, I’ve found this very interesting post, about an alternative way to perform the release. It’s worth reading: http://axelfontaine.com/blog/final-nail.html by Axel Fontaine