LinkedIn add Twitter dribble to RSS Feed

OMG, WTF, LinkedIn developers in their lack of vision have added support for Twitter into LinkedIn, thus turning it from a business network tool, into a Facebook style pile of dung.

I’m ok with that, but what I’m not cool about is them adding this dribble to my RSS feed about my network.

If I wanted Twitter dribble from my professional peers, I’d follow then on Twitter… where’s the opt-in/opt-out…

ARRGGGGG!!!!!

Outliers

outliers
outliers

I purchased Outliers while in America this year.

Funny book buying story: there was a 20% off sticker of the jacket, but no price tag. All books in New Zealand have a price sticker on the back, as they are the US or UK print runs shipped to NZ. Thus I was looking for the price sticker, when it dawned on my that it might be the RRP (as I was in the USA).  I then had to search the book jacket for the RRP (it’s on the inside front cover). Felt a complete nob.

Anyway the book is good, I had read some reviews/out-takes that talked about the hockey/football teams, so I was hooked.

I found the rest of the book to be as insightful. The key idea being that success is not just the efforts of the successful, but also not completely up to fate, very much along the lines of: life is what we make of those chances we are presented. To be a true outlier you need both (fate and effort) to go your way in large doses.

It also showed once again that there is no get-rich quick, no magic formula. Just people becoming great via hard work.

Complex SVN repository conversion to GIT

When I converted our two Visual Source Safe (vss from now on) repositories into one Subversion (svn from now on) repository I did it in an ugly fashion. I dumped the file based history for the current live trees, then loaded these into svn one after the other. They both had their own root names, so I shuffled things around to make a single Trunk, Branch and Tags arrangement.

This did not matter at the time, as we had the history for the code we cared about, and you could do per-file blame, etc.

But when I tried to import this tree into Git, it was messy as the svn tree was not standard for all time, thus the default scripts didn’t know what to do with it.

The history timeline (names changed to protect the innocent, but revisions are not altered, otherwise I’d make editing mistakes)

  • Tree-A imported from vss (single branch) - rev 1 - 3163
  • Tree-B imported from vss (single branch) - rev 3164 - 5710
  • Rename of roots, Trunk, Branch etc - rev 5711 - 5713 (we want to skip this stuff)
  • Current Unified Tree (multiple branches) - 5714 - HEAD

1. Setup our repo

Create new directory

  • Run ‘git init’ - this will create the git directory

  • Git by default is setup for unix text files since most projects using git on windows are unix based projects. Thus we want to turn off the auto crlf -> lf conversion. We do this by adding the following to the .git/config file:

      [core]
      filemode = false
      symlinks = false
      autocrlf = false
      whitespace = nowarn
    
If on Windows, also add

    ignorecase = true
  • Add the authors file (.git/authors), this maps from svn users to git users (full email address)

      (no author) = Simeon Pilgrim <simeon.pilgrim@example.com>
      user1 = user one <user1@example.com>
      user2 = user two <user2@example.com>
      spilgrim = Simeon Pilgrim <simeon.pilgrim@example.com>
    
  • Setup git svn to use the authers file by adding this to .git/config (otherwise we have to mention it every time we do a fetch with the git svn -A .git/authors …, which is a pain)

      [svn]
      authorsfile = .git/authors
    

2. Create three remotes for each of the three chunks.

  • Normally this would be done via git svn init, but doing it manually gives us more control.

  • Edit .git/config to add the three remotes

    Add:

      [svn-remote "Tree-A-Old"]
      url = svn://svn-server-url/repository
      fetch = Tree-A-RootName:refs/remotes/Tree-A-Old
    
      [svn-remote "Tree-B-Old"]
      url = svn://svn-server-url/repository
      fetch = Tree-B-RootName:refs/remotes/Tree-B-Old
    
      [svn-remote "svn"]
      url = svn://svn-server-url/repository
      fetch = Trunk:refs/remotes/svn/trunk
      branches = Branches/*:refs/remotes/svn/*
      tags = Tags/*:refs/remotes/svn/tags/*
    

This defines three svn-remotes, which we can fetch individually. The first two will fetch from svn://svn-server-url…/Tree-A-RootName or svn://svn…/Tree-B-RootName to the remote branches Tree-A-Old and Tree-B-Old. We fetch them by using ‘git svn fetch Tree-A-Old’ and ‘git svn fetch Tree-B-Old’. The last remote will fetch trunk from svn://svn…/Trunk to svn/trunk and all branches and tags from svn://nzc…/Branches and svn://nzc-…/Tags as git remote branches with the names svn/.

The former two can just be straight fetched without specifying a revision range (eg. ‘git svn fetch Tree-A-Old’), but the last requires a range to be specified. This is for two reasons:

  • git svn fetch with branches and tags seems to check every revision up to the start point
  • We actually don’t want to grab the first few revisions after the svn merge as I was purely renaming/moving directories. Otherwise files will randomly disappear and then reappear a commit later in the middle of the history.

Thus to grab the recent svn history we run fetch as ‘git svn fetch -r 5714:HEAD svn’

3. Merge the two old vss branches

We want to merge the two old vss histories together (in correct time order) so we replicate the svn merge in a nicer fashion.

  • First we check out one of the branches ‘git checkout -b merged Tree-B-Old’. This creates a new local branch ‘merged‘ which is a copy of the remote ‘Tree-B-old’, since we can’t edit remote branches directly.

  • We then merge the Tree-A-Old remote branch into ‘merged‘ by running ‘git merge Tree-A-Old’. This creates a merge commit (ie a commit with more than one parent). The message can be edited by using ‘git commit –amend’ but the existing is probably fine.

4. Grafting the branches together

The next step is to graft the branches. Essentially we take the start point and force it to have the merge commit as a parent.

  • Note that since git stores the state of the tree at each commit rather than the diff from the parents, we can essentially tell it that a given commit has a different parent commit and it will handle it fine.

  • Add a graft entry to .git/info/grafts. The format of this file is a series of lines with $parent_id $child_id. We thus add an entry with $merged_head_id $trunk_base_id. To get the ids we can run ‘git log merged‘ and take the head/top commit id, and run git log ‘svn/trunk’ and take the root/bottom commit id.

  • This is a temporary graft (ie the link will only remain whilst the grafts file is there), which most tools should adhere to, but we want to make it permanent. We do this by running git-filter-branch on each of the svn branches by running ‘git filter-branch svn/trunk svn/v3.0 …

5. Get git-svn to use the new remote branches

  • git-svn adds an entry of the form git-svn-id: svn://svn.../Trunk@40403 <UUID of svn serv> to each commit. It uses this to rebuild its cache in the event of corruption.

  • To force git-svn to use the new branches is quite easy. Remove the folder .git/svn and rerun ‘git svn fetch svn‘. git-svn will then rebuild its cache and start from where we left off.

B1. Cleaning history

The history can also be imported directly from a local copy of the svn data. This makes the svn import much faster, but the commits need some post cleanup for git-svn to sync up with the real svn server. Specifically the git-svn-id entries will come out as follows:

git-svn-id: file:///home/james/src/repo/Tree-A-Rootname@3161 1923097a-7eed-ce49-a323-f810e19527ea

but we need it in the form of:

git-svn-id: svn://svn-server-url/repository/Tree-A-Rootname@3161 1923097a-7eed-ce49-a323-f810e19527ea

This is where we use the git filter-branch command again. In particular its –msg-filter argument which takes a chunk of bash script that is run for every commit message with the current message given on stdin and the new message on stdout. In this case we use it as follows:

git filter-branch --msg-filter "sed -e 's#file:///home/james/src/#svn://svn-server-url/#g' " -f svn-trunk/trunk svn-trunk/v3.1 svn-trunk/v3.2 svn-trunk/v3.3 svn-trunk/v4.0

The other arguments given here are -f which forces filter-branch to run even if they are backups of previous filters (also seems to be needed on windows) and the names of the branches to be updated.

In my particular case I was also running an email/address fixup with the entire command being:

git filter-branch --msg-filter "sed -e 's#file:///home/james/src/#svn://svn-server-url/#g'" --env-filter 'export GIT_AUTHOR_NAME="$(echo $GIT_AUTHOR_NAME | sed -f /c/SG/authors)";export GIT_AUTHOR_EMAIL="$(echo $GIT_AUTHOR_EMAIL | sed -f /c/SG/emails)"' -f svn-trunk/trunk svn-trunk/v3.1 svn-trunk/v3.2 svn-trunk/v3.3 svn-trunk/v4.0

The env-filter lets you change environmental variables in this case GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL, which I updated using two sed scripts.

The contents of /c/SG/authors was:

s#^.\*no author.\*#Simeon Pilgrim#gi
s#user1#User One#gi
s#user2#User Two#gi
s#spilgrim#Simeon Pilgrim#gi

And /c/SG/emails:

s#^.\*no author.\*#simeon.pilgrim@example.com#gi
s#user1.*#user1@example.com#gi
s#user2.*#user2@example.com#gi
s#spilgrim.*#simeon.pilgrim@example.com#gi

This post was written by James, thus the /home/james/ paths, I just generalised the grammar, and removed work-place specific information.

Nant xmlpoke whole blocks

It took me awhile today to use the nant/xmlpoke/xpath to update our copyright message in our application so I’ll document it here.

The xmlpoke documentation explains whole to replace parameters but not children nodes. The simple answer is just define the parent in the xpath.

Thus to update/repalce the copyright string to have the correct current year, in a  resource file (strings.resx) which looks like:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- other stuff -->
  <data name="About_Copyright" xml:space="preserve">
    <value>Copyright © 2008-2009 Company Name.</value>
  </data>
  <!-- more stuff -->
</root>

You would want use this xmlpoke/xpath

<xmlpoke
file="${sourceDir}\Resources\Strings.resx"
xpath="/root/data[@name = 'About_Copyright']/value"
value="Copyright © 2008-${datetime::get-year(datetime::now())} Company Name." />

Simple really (the xpath), but until I got it, it wasn’t.

Feed Issues

There’s something wrong with Google Feed Sync (via FeedDemon) as compared to NewsGator’s deprecated service.

Over the last few months none of my own post have been showing up, so last week I logged into Google Reader and Ta-Da, 5 new posts, that were found “just now” in Google Reader, and then they appeared in FeedDemon.

But another issue with only using aggregation tools is that people keep changing there back-end blog engines and therefore break the feed link, thus they fall out of the news loop (Conor, Rowan), so once you discover this and change to the new feed URL, you’ve lost news.

Quite annoying.

Then there is sites that just disappear. Like Community Hacker, but while searching for it I found a new bot AI challenge site called hacker.org so its not all lost.

Cool Office Stuff

One of the things I’ve enjoyed about my current office, is all the neat stuff people have at their desks.

The Nixie tube clock

Nixie Tube Clock
Nixie Tube Clock

Or the Trimble GPS PCB clock

Trimble Gps Clock
Trimble Gps Clock

Or the great wall-of-cola

Wall of Cola
Wall of Cola

which was bigger until administration told him to go no higher… then there is also lots of Lego, all-n-all it’s a fun place to be..

Update: videos of the two clocks

Read the credits first

The other day James was showing me around QGit, how to do blames, review logs, etc and we were trying to get it to use Beyond Compare as an external diff tool (C:/Progra~1/Beyond~1/BComp.exe /ro %1 %2)

Things were behaving funky, after lots of trouble and lots of swearing I said “who wrote this sh#t” and then “maybe I should just check first”

James laughed as I press the about dialogue

git about dialogue
git about dialogue

Opps!

James said he only supplied a small patch, but it was pretty funny still.

The issue we were seeing was that sometime the difference would show the file as identical content, and sometime with differences.

It turned out that in one revision I would select file_a then after clicking on a different revision, pressing Ctrl-D would show the difference for the same file_a even if the second revision did not have changes for that file, therefore there was no difference to display. Took us a while to notice this.

Curse of the Azure Bonds - build 1.0.21

Build 1.0.21 has been released. Fixed in this version:

  • Issue 36, Fixed staff-sling weapon targeting
  • Issue 44, Fixed the modify player screen so edits to exceptional strength stay
  • Issue 45, Fixed the Order menu (found off Encamp, Alter), so you can select and place the party members
  • Issue 46, Fixed horizontal menu scroll via comma and dot keys

I also reworked how the combat engine builds target lists, and intend to change it to an A* system, but at this point it is a direct path cost based system, so I added a caching layer, and when all graphic’s and sounds turned off (non commented change) the combat is over in sub-second.

To do this  I hacked the game apart to dynamically turn graphics/sound/delays off, and then used the Red Gate Ant Performance Profiler to find the overworked code and it worked really well. I cheated and just used their 14-day trail version. But I did provide some feedback, and it has some really nice features like the ability to zoom to parts of the run history, and give guidance on hotspots, and you can drill down and see the code related to the CPU time. Check it out if your application is running a little slow.

As always, give the newer version a try, if you find any issues, even “old known” issues, let me know by: commenting here, email me directly, or add them to the issue list

Pictures from MineExpo

Here are some pictures of machines that the system I develop runs on, from MinExpo 2008:

CAT Truck 795F
CAT Truck 795F
CAT TTT D11T
CAT TTT D11T
Hitachi Front Shovel
Hitachi Front Shovel
Liebherr Truck T282B
Liebherr Truck T282B

Update: If you like big machine pictures, you might also like non-fatal big machine crashes, over at Mining Mayhem

Getting into Git

With the pending move to the US, I need someway to work detached from the main NZ network. So I was keen to try-out Mercurial or Git. I had heard more positive Mercurial stories, verse the real men use Git type stories. So had intended to go with Mercurial.

But our local linux/git hacker was appalled and spent some time showing me how well git and svn can co-exist.

So I started playing with Git, trying to clone my subversion repository, but was not having the best of luck, due to how the repository was formed when I moved and merged two VSS repositories.

Anyway showing James (yes he has a name) my odd clone behaviours, got him intrigued. Half an hour later he was back, telling me all about how the SVN repository history was all messed-up (aka Trunk was not always there, etc). Then offered to work some Git vodoo and fix it all for me.

A day later, he excitedly told me how he manually extracted the blocks of history, and using Git filters, that allow per entry rewrites (or paths) was rebuilding my Trunk and Branches into git, so they looked like they were always located like how the SVN tree currently is.

So it sounds like Git is quite powerful. Sounds like the type of stuff that would make great blog fodder. But I’ve not done any of it myself, so I can’t tell you how todo it, other than it can be done. The tools seem to have lots of flexibility, and when things go wrong, James will have to drop everything and fix it.

See I am becoming more manager like as the days roll by…

Also to make-up for steeling my blog post, he invited me to Google Wave.