Monday, August 30, 2010

How to Kick Off some knowledge meetings

I've gotten some questions about Knowledge Meetings after I presented them as one of our agile practices at FrOSCon some weeks ago. Here are some more ideas/thoughts on how to do them:

What are they?
One hour every week. Gather the whole team together, and learn something.

What should we learn about?
Anything that will be of interest to your team, work-related. Some examples:
  • This new open source library/project/technology we (can) use
  • New programming language
  • This cool testing technique
  • A certain module of the business application
  • The hardware architecture of our data-centers
  • Some applied computer science (algorithms and stuff)
What is the concrete contents of a Knowledge Meeting?
Anything that'll make you learn. Examples:
  • 10 minute lightning talks/ignites
  • Coding Katas, or Randoris
  • Longer presentations (try to not go over 30 minutes)
  • Lots of discussions!
  • Lots of live coding!
Remember:
  • Let people present the things they already know, but..
  • Give people time to prepare their presentations (1 hour per 10 minutes of presentation, as a rule-of-thumb, perhaps?)
How do I get started?
You need support from up top. You simply can't yank people one hour out of their working time every week.

If you don't get support from up top, you're gonna have to do it on a volunteer basis. I've written some strategy for this in my post about workshops. Over time, management will hopefully see value of the knowledge meetings, and start sponsoring them before people start leaving for companies that invest in people's knowledge.

Some tips

  • Give people plenty of time up front to prepare their presentation (one month)
  • Always have the knowledge meeting the same time, week after week
  • Point out a person to make sure the meetings go smoothly (prepare agenda).
  • Over time, let this "knowledge facilitator" role rotate.
  • If it gets hard using the internal knowledge to keep the meetings busy, increase budget: either give people more time to research/preparations, send them to conferences/courses, or hire in some externals to do the occasional gig with presentation.
  • If the knowledge meeting starts losing time to other activities, like retrospectives, try to get a new time appointed to it.
  • If you run out of content and discussion, cut the meeting short
So, I scribbled this together rather quickly, so let me know if I left something out, or if you've got any questions.

Thursday, August 26, 2010

Agile in a Year - Video available

You can now find the recording of the talk on the page for the Agile-in-a-Year presentation.

Note that it's missing the first few minutes with intro, but that wasn't so interesting anyhow, I'm sure regular readers know most of the background.

There's about 40 minutes of me talking, and 20 minutes of questions and discussion in the end. Sorry for not being so good at repeating your questions into the mike!

Tuesday, August 24, 2010

Why Distributed Revision Control increases Agility

I recently did a talk about practices we have introduced to make us more agile.

At the end of the presentation, I mentioned distributed revision control as one of the next practices we want to do. Now how on earth does using Git or Mercurial increase our agility?

The short answer is: Feature Branches.

The long answer is...

We have a defined agile as among other things, this value: Ship working software.

This value implies that we keep the mainline of the code (known to many as the stable branch) in a working state. A good way to keep it that way is by making sure that only safe changes make it into the mainline. If you've got developers continuously working on the mainline to create new features piece by piece, chances are the code is in a broken state every now and then.

In order to remedy this, lots of companies (including ours) have decided that the team should maintain two versions:

  • one experimental, where new features are developed, and 
  • one stable, which should always be in a working state. 

This is a bit of an expensive practice, because you end up with long rounds of verification before the experimental branch can be released, replacing the stable version. You also have to continuously merge back bugfixes from the stable branch to the experimental branch.

So, the idea of feature branches is to keep new development out of the way until it is ready to go out in the mainline. When the feature is complete, you test it well. You then merge the feature into the mainline, do some quick verification that it is still in a working state, and then you release. Much smoother (agile) than releasing an entire experimental branch.

So feature branches are agile. Why don't we do more of those?


The problem is Subversion, or whatever other centralized VCS you're stuck with. They do not allow easy/cheap merging between branches (and I don't want to hear about that half-assed merge-tracking svn-properties hack), and therefore feature branches are practically impossible.
.
You might argue that Subversion users can  keeping their changes locally in the workspace, but there's a major constraint: They can't collaborate on their feature. This means missing out on a lot of co-operation, creative process, ideas, code-review and refactoring before the feature ends up in the mainline. They could operate with sending patches around, but at some point it's time to ask how much hassle you have to take before you replace your malfunctioning VCS with a proper one.

At this point, I would like to outsource the illustration of how you can do feature branches in practice to the very fine illustration from Vincent Driessen. He has really nailed it, I think. In his model, what I've called mainline, or stable, he calls "master", and what I've called experimental, he calls "develop". The release branches also serve as nice points for setting up Continuous Integration (cause you probably don't want to set up CI for every single feature-branch).

So, summary: 


Distributed Revision Control allows you to do feature branches, keep the software in a working state, and ship one feature at a time. In other words, more agile.

Saturday, August 21, 2010

Agile in a Year @ FroSCOn 2010

Just a few hour ago, I did a talk called Agile in a Year at FrOSCOn 2010. Great conference, as it was last year. Hopefully going back tomorrow for day 2!

I've put the "slides" and references from the talk on my homepage.

Hopefully, a recorded video of the talk will be online soon. Unfortunately, I botched it a bit by forgetting to put on the microphone at first, but got it on about 5 minutes into the talk. Will post back here when the video is ready.

And if you were in the audience: Thank you so much! Full house, great discussion and questions afterwards.

Friday, August 06, 2010

Git and Subversion summary

This post is part of a series on Git and Subversion. To see all the related posts, screencasts and other resources, please click here

This post is part of a (slightly chaotic) series on Git + Subversion. Unfortunately, due to my problem with editing posts in Blogger, they've ended up a bit scattered and poorly organized. So here's a summary of the posts with more fitting titles:

  1. A big rough introduction to distributed source control and Git
  2. Why and how clone of a Subversion repo into a Git repo (aka SVN mirror)
  3. Sharing a Git SVN mirror in a team
  4. Sharing a Git SVN mirror in a team clarifications
So, if you just want to get into using Git, take a look at 1. If you want to port an existing Subversion repo, 2nd post is the thing. The 3rd and 4th are for those of you who need to stick with Subversion for a while longer. The illustration below illustrates an example workflow for the last case.



Ref GitFaq. Note that devs *might* have to run update-refs before running dcommit back to Subversion. All changes pushed to Subversion will come back to the other developers through pulling from the fetch repo.

Thursday, August 05, 2010

Some clarifications on living with Git and SVN

This post is part of a series on Git and Subversion. To see all the related posts, screencasts and other resources, please click here

I'm afraid I exaggerated in my previous posts, and given the impression that living with Git and Subversion in parallel is easy. I would update it, but Blogger is refusing to edit the post without screwing it up. So here it is in clear text:

Be prepared to face some major constraints in using Git against a Subversion repo, compared to how it using Git standalone.


The manual says it best:
The git svn tools are useful if you’re stuck with a Subversion server for now or are otherwise in a development environment that necessitates running a Subversion server. You should consider it crippled Git, however, or you’ll hit issues in translation that may confuse you and your collaborators. To stay out of trouble, try to follow these guidelines:
  • Keep a linear Git history that doesn’t contain merge commits made by git merge. Rebase any work you do outside of your mainline branch back onto it; don’t merge it in.
  • Don’t set up and collaborate on a separate Git server. Possibly have one to speed up clones for new developers, but don’t push anything to it that doesn’t have a git-svn-id entry. You may even want to add a pre-receive hook that checks each commit message for a git-svn-id and rejects pushes that contain commits without it.

As you can understand, this takes some of the fun out of using Git (although it's still a much better SVN client than SVN). Another clarification:


In the previous post, I stated that you have to manually enter a value into .git/refs/remotes/git-svn. It appears that you have to have to repeat this every time new changes come into the SVN-fetching repository. Fortunately, there's an easier way to update the ref:

git update-ref refs/remotes/git-svn refs/remotes/origin/master

You have to do the above after pulling from the SVN fetching repo, and before you run git svn dcommit (found this here).  This seems a bit awkward, and you'd wonder why this isn't built into git-svn. I asked about it on the #git IRC channel, and they said that the "recipe" configuration doesn't support a single url tracking branch. It has to be a standard -s layout. I should test this though, currently I'm just syncing with one branch in SVN. In the mean time, I dcommit with a little script that runs update-ref first, and then does the dcommit.

Some more resources:

Monday, August 02, 2010

Syncing your Git repo with the Subversion repo

This post is part of a series on Git and Subversion. To see all the related posts, screencasts and other resources, please click here

This is a follow-up to the previous post on how to live with Git and Suversion in parallel. It's really trivial stuff for any experienced user, but was worth noting down somewhere for my own sake.

I've cloned a project called "fudge" from Subversion:

>git svn clone https://scm.mycompany.com/svn/fudge

So my local repo has the correct svn-remote configuration and all that to go with it inside fudge/.git/svn. This is done automatically when you svn-clone.

The bad thing is that all my Git-mates at work have to wait for me doing svn-rebase before they can pull the latest code from Subversion from my repo into theirs.

I want to get rid of this responsibility. I'll put something similar to my svn-rebasing repository on a server, have it run svn-rebase regularly, and push the changes to a centralized git repository, that everyone can pull from whenever they want. Here's how:

First, I'll init a repo on the build server called "builder". It has a designated place for the git repos in the directory /scm/git/

>cd /scm/git
>git init --bare fudge.git

The --bare means a git repo with no local checkout, i.e. just the compressed stuff inside .git.


Back on my own machine, I register the above repo as a remote for my own. I'll call it origin (this may sound confusing as my local repo is actually the origin here, but it's kind of a git convention to name the centralized repo like that):

>git remote add origin ssh://tfnico@builder/scm/git/fudge.git

The above should add the following to my fudge/.git/config:

[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = ssh://tfnico@builder/git/java/ips.git

Now, I can push my local repository to the build server. I have to specify which branch in the remote repo I'll push to (master oughta work):

>git push origin master

So, centralized repo is ready. Now, we want a second repository on builder that can do the svn-rebase action. You could probably do this in the same repo as the first one, but I think it's cleaner to do it separately. Besides, in order for svn-rebase to work, you need to have a repo with a local checkout.

We'll create this repo just like any other developer would: By cloning from the central repo (still on builder). I'll pretend there's a user on builder called "worker" designated for this kind of action:

cd /home/worker/projects
git clone /scm/git/fudge

If we try just running svn-rebase right away, something like this might happen:

>cd fudge
>git svn rebase
Migrating from a git-svn v1 layout...
Data from a previous version of git-svn exists, but
.git/svn
(required for this version (1.7.1) of git-svn) does not exist.
Done migrating from a git-svn v1 layout
Unable to determine upstream SVN information from working tree history

You'll see that Git created the .git/svn/refs/remotes/git-svn/  folder on its own, but there's not much in there. We have to make the repo aware of the remote Subversion repo in two steps:

First, copy the svn-remote config from your original repo (the one you svn cloned) .git/config into the worker's config:

[svn-remote "svn"]
url = https://scm.mycompany.com/svn/fudge
fetch = :refs/remotes/git-svn


While imagination would allow us to think that git-svn now could figure out the rest by itself, we still need to add a pointer to the git-svn remote. Look inside the original repo's references, and you should find a file .git/refs/remotes/git-svn with a SHA in it. You have to copy this file into the worker's repo as well (or just paste the SHA into a new file with that name).

Now, try svn-rebase again:

>git svn rebase
Rebuilding .git/svn/refs/remotes/git-svn/.rev_map.901b3fc1-1df5-aa1e-233f-0cced8b7b346 ...
r123 = 38aada9c84fdb74f2271706c2a4be768334b0cc1
....
Done rebuilding .git/svn/refs/remotes/git-svn/.rev_map.901b3fc1-1df5-aa1e-233f-0cced8b7b346
Current branch master is up to date.

That's it! So, let's recap what we had to do:
  1. Create a central repo (bare)
  2. Clone the repo 
  3. Add the svn-remote to .git/config
  4. Add a pointer/SHA in .git/refs/remotes/git-svn
Now, we can set up a process that regularly does svn rebase and svn push to have it continuously update the central repo with the latest changes from Subversion. You can do it in your CI-server, as a cron-job, or maybe trigger it with a Subversion post-commit hook.

Note: When you go back to work and want to push commits back to the Subversion repo, you have to use git svn dcommit. Pushing your changes to a central git repo and then having some automated job dcommitting back is a bad idea, I think. Please let me know if you any thoughts on what workflow to use, especially when multiple people are working with Git/Subversion repos.