Sunday, September 30, 2012

GIT Rebase on Remote branches

Ever finished up work on some code, commit it with git only to realize that you forgot to create you feature branch before you started?

If this has happened to you at some point you know that all your work is now on your local master brache while work on the remote master has continued at steady pace, with commits from other team members stacking up. You can not push because git wont let you. And if you pull you will end up with a fat ugly merge commit that is pretty far from the nice rebase your were aiming at that would make the commit history a joy to read.


What you want

Your usual modus operandi looks something like this:

1. Get to work in the morning, get current and branch off before starting today's tasks: 

git checkout master
git pull
git checkout -b work

(Throughout the text I will continuously checkout branches instead of writing which branch I am on.)

2. Finish up your nice coding work and then:

git commit -a -m "Finished cool feature"

3. Now, before pushing, you want to get current again and put your own commits "on top" of any other ones that were pushed while you where busy finishing up your feature. So:

git checkout master
git pull
git checkout work
git rebase master

4. And now that your commits will not cause a merge commit but instead can be fast forwarded, it is time to share with rest of the team:

git checkout master
git merge work
git push

5. Go for coffee.



What you have

But right now all that is Utopia. You forgot all about creating that work branch and all your nice code is committed on (what by now is) your outdated local master branch.
Your world looks like this:

git push

 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'some-repo'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details. 



How to fix it

There is still a chance to avoid ridicule if you remember that there is very little difference between local and remote branches it git. You ought to be able to rebase your local master on its remote counter part. Here is how:

1. If you are the slightest bit uncomfortable with the operation. Back up your repository!
It is dirt cheap and very simple.

cp -a your-repo-dir your-repo-dir.bak

2. Download the objects and refs from the remote repo

git checkout master
git fetch

3. Now that your index is in sync with the remote repository's you can rebase master on origin/master.

git checkout master
git rebase origin/master

4. After resolving any conflicts in the same way as you would normally to your ready to push.

git push

5. Go for coffee and forget all about this little mishap!

(There is also a short hand combining steps 3 and 4: git pull --rebase.)


Notes

I might be helpful to know that when you do a git pull it is actually a shortcut for doing a git fetch followed by a git merge.

git branch will list your local branches dy default. Use git branch -r to list remote branches or git branch -a to list all branches.

Sunday, May 15, 2011

Getting away without Time Boxing

I am not very good at time boxing the tasks I take on. I am not lousy, but I could definitely use some improvement.
When looking around at people I know fairly well and that I think are “high performing”, there are only a few that I would consider being good at time boxing their work.

More than often, time spent on a task is constrained by interruptions. The interruption might be external, e.g. a phone call making something else top priority for the moment, or internal like letting your mind wander off to something else, or even getting bored with the current task.

So, how come these high performers, but lousy time boxers, actually get cool things done?
Could it be the interruptions that saves them?
Without the interruptions, would they just continue the task until it was complete and thus putting more effort into something than the outcome would be worth?

It is like the interruptions would involuntarily make them follow some kind of 80/20-rule where 80 percent of the value comes from 20 percent of the work.
But what if their 20 percent of the time they spent are the wrong 20 percent, only making 60 percent of the value, or that they do 30 percent and the last third is more or less waste?

Would it be worth it the get better at time boxing to hit the right 20 percent of work, and reduce the risk of doing the lesser valuable work by doing less on a specific task?

I don’t know. And I time boxed this, and my bell just rang.

Thursday, April 28, 2011

Reading and Understanding, but not Writing, equals Wasting

Take a look at this very simple code snippet:


It is taken out of context of course, but the intent should be clear:

  • create an image 
  • place it within a cell 
  • make sure it vertically in the middle of the same cell
  • and all the way to the right

If the code does this right or wrong is not what I want to discuss. But hopefully it did not take you much time to understand the intent of the code.

Now, take a look at this snippet, which should express the same intent.
It should do the same thing. (Does it?)


Yes! It does to the same thing!
But I'm willing to bet that it took you less time to understand the first version.
Given I am very slow when reading code, my guess is that it would take me 15-20 seconds longer to understand the intent of the second version. (Maybe a few more extra seconds if I loose focus and double check that the algorithm was implemented correctly.)

This is of course very little extra time. Or is it?
Let's say three or four persons spend an extra 20 seconds on this very trivial piece of code. And if you think about what your projects are really about, the actual problems you are trying to solve, these kind of trivial code snippets are all over the place. Those seconds will add up.
Not to mention the risk of losing your trail of thought while you double check the algorithm when you are really chasing down a production bug.

- "Ok, so just refactor it!", you say.

- Yes! That's exactly what I should do. Change the second snippet so it looks like the first snippet!

I'm slow coder too so it might take me 60 second to do it (in addition to the extra 20 I already spent understanding it in the first place).

- But wait! If I make the change and make a mistake while copy-pasting, it might break. I need to run it before I check it in!

(And this is where the trouble starts.)
The code that I want to change is in a branch of an if-statement. The branch executes when a regular user logs in and that user doesn't have an email address registered.

- I only have a super user test account. I could register a new regular user account. That will take me 2 minutes, if the email server sending confirmation mails for the test environment is up....
- Maybe I should ask Bill if he has an account I could use....but he looks busy. Don't want to disturb him with such a trivial thing.

- Ah, never mind. I'll just leave the code the way it is. It's not that complicated. Too bad we never wrote those unit tests...

Sunday, April 10, 2011

Smelly mixins

Just recently I had to do some work on a good old LAMP stack. Yes, PHP coding.  Only a quick fix, so I will not dwell upon it, but it got me thinking about something I haven’t thought about for a while. Includes. The kind of include statements that pulls a body of text (e.i. code) into another body of text.
PHP has them; ASP and JSP have them as well.

This kind of include statements can obviously lead to very smelly code as the resulting “file” might become very long and you might not notice things like clashing names, or that part of an include is completely irrelevant in one context but crucial in another.

In the scripted languages mentioned earlier, these include statement is one tool to reuse code, reduce duplication and keeping the size of individual files small enough to work with. But applying this technique in other languages where you have a whole other set of options to keep chunks of code focused and reusable will result in in something really smelly.

You can achieve the same kind of include mechanism with Ruby modules and Objective-C categories; but when used as a way of splitting up what otherwise would be a large class, it is likely that you have lots of duplication in the included files and that there is a high coupling between individual include files. It will most likely also make it hard to follow basic rules like method-should-do-one-thing and having methods with a single level of abstraction in them.
Why? Because you are likely to have naming clashes as you are only working on a very small piece of what is essentially a very large class, with too many responsibilities.





So, should you stop using these constructs? Absolutely not!
All though Ruby modules and Objective-C categories share some similarities they are not equivalent.
They are both a way of adding behavior to other classes. In Ruby it can be a class that is unknown at the time of writing. In Objective-C you target a specific class that you do not have access to (e.g. a class provided by a library).
The constructs are a great tool when used with this purpose. But when they are just used to split a large class, they are only perfume sprayed on you code smell.

Tuesday, March 8, 2011

Talk on Mock Objects in Objective-C

Last night I held a short talk the cocoaheads stockholm meetup on using mock objects with Objective-C and OCMock.

Sample code can be found here.


Saturday, December 11, 2010

My bad code was perfect

Hi, 
I wrote the code below just a few days ago.
Is this good code? No! By most any standards, it sucks. Duplication, bad naming, tests give too little feedback, etc, etc.
Yet, during just a few moments, it was perfect!

To understand why I thought it was perfect I might have to give you some context.
This was the very first few lines of code I wrote in the Io language. Describing my Io skill level as Novice, would be pushing it; at the time it was more like Bambi-on-ice.
I hardly knew any of the language syntax, my experience of prototype based programming was limited and I wasn't even sure about which object my method would be associated with. Needless to say, plugging in a unit test library before I even knew how to make a for-loop was not even on the radar.

Still, the code above gave me just enough feedback, for just enough moments, to know that I was on the right track. And giving me a safety net (or training wheels :-) ) that let me commit, start refactoring, and apply new knowledge as I learned more.

While I can do pretty cool stuff with tools like RSpec or JUnit, it is helpful to remember that BDD and TDD is not about the tools. It's about focus. Focus, right now.

Saturday, December 4, 2010

Measure often to not trick yourself

Improvement is more that often something that is hoped to be achieved “over time”, “as a long term goal” or “continuously”. This goes for both individuals and for teams.

When trying to improve, you will need some kind of measurement to see if are moving in the right direction and if changes you make are improving the metric in the direction you desire. When dealing with subjective metrics, like some form of happiness metric or a feeling-of-fulfillment metric, this might only make sense when looked upon as a trend over a longer period of time.

There is a difference between hard facts (story points, bugs count, test coverage, stock quotes) that can be back tracked fairly easy; and softer metrics (attitudes, motivation, feelings etc) that are not as easy to recover after the fact.
I think the reason for this being so is because of the way our mind works. Our memories of passed experiences are not recorded in detail. We have fragments stored, and the rest is made up by our brain. Made up to the best of our knowledge. Our knowledge at the time we try to recall. The more time that has passed, the worse the quality of the metric.
Paraphrasing Daniel Gilbert, you could say that “The holes in our memories are filled with material from the present”.
(Psychologist Gilbert's “Stumbling on Happiness” is a very entertaining book on how the tricks our brain plays on us when we try to remember stuff from the past, are also played on us when we try predicting the future.)

However, I believe it useful measuring improvement using a softer (and more or less subjective) metric, as long as the samples are made often and analyzed over a longer period of time.

Taking samples often enough might be difficult. Retrospectives-like activities might be a good time for a team to do such activities unless your iterations are too long or, as I've noticed with some teams, retrospectives are only held after successful iterations. (I have also seen softer “satisfaction”-like metrics being taken during daily stand-up but not being recorded properly and thus of very little use.)

In his book “Drive”, Dan Pink recommends giving yourself a Flow Test รก la Mihaly Csikszentmihalyi, who coined the term “flow”. Csikszentmihalyi's test persons were asked about their (subjective) mental state around eight times a day, at random intervals, with the hope of minimizing the effect of the mind “filling in the blanks”. Pink states the obvious fact that we now have technology at our fingertips (e.g. cell phones with reminder features) to enable us to perform such tests easily.
And just recently, I saw that Sarah Gray and Corey Haines are working on something they call MercuryApp that seems to be a tool to enable you to set up and take these kinds of tests for later analysis of your trends. (I signed up for an invite but haven't gotten one yet, so I am not sure how well it works.)

In financial investment circles, more than often you will hear “the trend is your friend”. If you want to measure something your mind makes up, measure often and act on the trend!