Tuesday, December 21, 2010

Drools migrated to Git

We have joined many other open source projects (such as Hibernate, Seam, Infinispan, ...) and migrated Drools from Subversion to Git.
Subversion has served us really well, but the features such as pull requests, cherry picking, cheap branching and multitasking in isolation, which git brings to the table, are just to nice not to have at our disposal.

The reference repository is on GitHub: https://github.com/droolsjbpm/droolsjbpm
So go ahead, fork it and send us pull requests!

There is a bit of a learning curve though. The step from Subversion to Git is bigger than the step from CVS to Subversion was. Below is a short guide for SVN guys that don't know Git yet.

Git for SVN guys

Purpose

This document shows you how to use Git, just as you were using SVN in the past. It is to get you guys up and running with git as soon as possible by relying on your SVN knowledge and it is focuses on what you want to do in drools.
This document does not really teach you Git. Git is not just SVN++, it is much more and you should take some time to learn that too.

Terminology

SVN trunk is renamed to Git master. A branch is still a branch. A tag is still a tag.
Translation note: trunk == master

The SVN central repository is now the reference repository on github, see https://github.com/droolsjbpm/droolsjbpm.

Part 1: Need to know

Preparation

  • 1) Install git for your OS
  • 2) Install git in your IDE
    • 2b) Eclipse: Install the EGit plugin.
      • Menu Help, menu item Install new software.
      • Work with update site Helios, open Tree item Collaboration, tree item Eclipse EGit.
    • 2c) IntelliJ: Enable the git plugin (if not enabled):
      • Menu file, menu item Other Settings, menu item Configure plugins.
  • 3) Get a Github account: https://github.com/signup/free
  • 4) Configure git correctly (Github also tells you this):
    • $ git --version
    • git version 1.7.1
    • $ git config --global user.name "My Full Name"
    • $ git config --global user.email myAccount@gmail.com
    • $ git config --global -l
    • user.name=Geoffrey De Smet
    • user.email=ge0ffrey.spam@...
  • 6) Push your public key to github:

Getting the source code locally

First move your old SVN working directory aside, so you’re not confused that you shouldn’t work there any more:
$ cd projects
$ mv drools drools-oldsvn

Now you’re ready to get the sources with git. In SVN this is a svn checkout, but in Git this is called a git clone. Prefer the faster, stabler git protocol over the slower https protocol:
$ git clone git@github.com:droolsjbpm/droolsjbpm.git droolsjbpm
Next go into that directory
$ cd droolsjbpm

So what’s the command git checkout for? To switch to another branch, but in the same working directory. In SVN you also use svn checkout for that.
Translation note: svn checkout == git clone (new repository)
Translation note: svn switch == git checkout (change branch)

Follow the instructions in the README.txt to set up your Eclipse or IntelliJ again.

Getting changes from others

So Mark and Edson changed something in drools-core in the reference repository. How do I get those changes? In SVN this is svn update, but in Git this is a git pull.
Be aware, if you have local uncommitted changes, you 'll want to apply those changes after any changing coming from master, so it's better to add the --rebase argument.
$ git pull --rebase
If there's any output, read it: there might be merge conflicts.
Translation note: svn update == git pull --rebase

Making changes

While making your changes, do the same as in SVN: git add, git rm (instead of svn delete), git status.
Translation note: svn delete = git rm

After making your changes, you ‘ll want to do a git commit (when you’re done with a changeset) and a git push (to share those changes with the rest of the team). To recap: doing a git commit does not push your changes to the remote repository yet, you also need to do a git push.
$ git commit -m “JBRULES-123 fix testcase”
$ git push
Translation note: svn commit == git commit; git push
Important rule: On git push, never use the --force option (unless you know exactly what you’re doing)

If you want to see what you’ve committed but not yet pushed, use this command:
$ git log --branches --not --remotes

Part 2: Tell me more

Extra terminology

What is rebasing? A rebase is an alternative manner of merging: instead of merging your changes with the incoming changes, it takes the incoming changes and applies your changes on top of that. This gives a cleaner history. For example:
$ git pull --rebase
Important rule: Do not rebase commits that you have pushed to a public repository.
In this use case, this probably isn’t a problem (if you still use the same remote repository).

What is origin? Because git can work with multiple remote repositories (usually forks of the same project), the default remote repository is known as origin. If you’ve cloned the reference repository, then origin is the reference repository. If you’ve forked the reference repository as A and cloned A, then origin is A.

Branching

Usually we’ll have 2 types of branches: release branches and topic branches.
To switch to another branch, just use git checkout:
$ git checkout 5.1.x

To create a branch do:
$ git checkout -b 5.2.x

Release branching

A release branches is copied from the master branch and only receives bug-fixes. It is separated from the master branch so no unstable features or improvements (pushed by other developers) leak in.
For example: $ git checkout 5.1.x

Cherry picking is very interesting to pick bug-fixes from the master branch into the release branch.

Topic branching

A topic branch is copied from the master branch and is eventually merged back into the master branch. Its changes are to disruptive to other team members to be committed to the master immediately.
For example: $ git checkout trueModify

Rebasing is very interesting when you’re working on an experimental feature in a local topic branch for the last few weeks and you want to have the latest changes of master(=trunk) in there too (= sync up with master):
// on my the myTopic branch
$ git rebase master
Important rule: Do not rebase commits that you have pushed to a public repository. So don't use it on non-local topic branches. (Use git merge if you have pushed it to a public repository.)

After your topic branch is stable, you’ll merge it into the master branch:
$ git checkout master
$ git merge trueModify

Learn more

Do you want to really learn Git?
Read the Pro Git book (freely available online): http://progit.org/book/
You’ll easily gain the time you spend reading that book, because Git is more than SVN++.
Read that book, especially if you’re going to do branching and merging!
Other references: Hibernate git tricks (really interesting), SVN crash course, Git for Gnome developers, ...

1 comment:

  1. We decided to use use "git pull --rebase" instead of "git pull" as a replacement for "svn update" so our history is clean and there's less need for merging.

    ReplyDelete