Posts Tagged ‘tools’

Core Dumps Rock

April 17, 2011 3 comments

So it’s been a while since my last post, and I find myself thinking about core dumps lately.

I won’t be wowing you with my awesome knowledge or teaching obscure implementation details regarding core dumps… I guess my bottom line message is “core dumps rock.”

Some of the more hard-core guys like Linus don’t believe in debuggers (real men don’t need ’em, eh?) but for the rest of us mere mortals debuggers are vital tools. And while I agree with Linus’s reasoning against debuggers, especially in the kernel — I guess I’m a pragmatist at heart. Use whatever tool helps you get the job done…

Anyways, core dumps are awesome. Especially if any of the following are true:
– you’re chasing an intermittent bug that only happens once in N runs or doesn’t reproduce with a debugger attached
– your code is running on an embedded device and there’s no JTAG (hence no realtime debugging/debugger)
– you want to save a snapshot of the system/app/problem for debugging later

Core dumps (and what triggers them) vary from OS to OS, but they generally contain some/all of the following:
– the page tables/memory for the crashing process, or a full RAM dump on some embedded targets
– the processor registers, including MMU configuration and other hardware configuration/state info

This info can be loaded into a debugger later on to construct a backtrace, examine variables, and can go a long ways towards solving the crash at hand.

I’ve used core dumps several times recently and it’s been a real lifesaver. The exact mechanics of using core dumps are already documented ad nauseum elsewhere, so I won’t repeat that info here. Just wanted to put in a plug for core dumps… Because when you need ’em, they… Rock.


Categories: Uncategorized Tags: ,

SVN to Git

September 10, 2010 1 comment

How to cleanly migrate from svn to git.

Git’s in, SVN’s out

Let’s face it, it’s 2010 and DVCS’s are in style. SVN and CVS are out, git and hg are in. All the cool kids (python & Ruby-istas alike) are jumping ship on SVN and git is the new cool tool.

So how do you jump on the bandwagon and kick your SVN habit to the curb?

How do you migrate from SVN to Git?

If you’re seriously considering a move from Subversion to a DVCS (and git in particular), please choose from the following options:

  1. You’re sick of subversion and have heard of git, but have no clue where to start
  2. You’re sick of SVN, but your team/job/friends are forcing you to stick with SVN
  3. You’re ready to move to git and leave SVN behind, but you need to port legacy code/repositories on your local server
  4. You’re ready to move to git and don’t have a place to host the code, or don’t care if it’s hosted in the cloud
  5. You think git is confusing and wish this article was about mercurial (hg)

If you answered #1 or #4, stop reading now and go over to Github and sign up for a free (or paid) account. Github will guide you every single step of the way, from setting up SSH keys to common git commands and gotchas. Not to mention the interface is very usable and downright helpful in many cases.

If you answered #2 (sick of SVN but stuck with it), you probably want git-svn to help bridge the gap. The ‘net is full of examples, tutorials, and quite frankly I’ve never had the patience to make it work right… but some people swear by it.

My biggest issue with using git-svn is you get some of the benefit of git (local commits, fast log access, etc) but none of the workflow changes that git inspires/prompts. Go read about the Integrator Workflow chapter on Pro Git. It looks like a lot of overhead to begin with, but it saves you SO much time in the long run, it actually improves code quality.

If you answered #5 (you don’t like git) — well, sorry, I haven’t used hg much. Best of luck, let me know how it works for you.

For the rest of you — those who are ready to migrate to git but don’t know how — read on!

First things first: install git.

If you’re on Windows, things have gotten better but are still a little clunky. Check out msysgit and TortoiseGit.

If you’re on Linux, you need to install the “git-core” package — assuming you’re on Debian or Ubuntu, try

$ sudo apt-get install git-core

If you’re unlucky and stuck on RHEL, CentOS, or Fedora — first of all, I’m sorry that you have to deal with yum. Cross your fingers, and try

$ sudo yum install git-core

If the mirrors aren’t down and the planets align correctly, yum will eventually install git.

Export your SVN repository to Git

There are at least two popular ways to import from SVN to git. You can use git-svn (git svn clone -s SVN_URL LOCAL_DIR), but I haven’t had a lot of luck getting this to work right. Last I checked it leaves some annoying metadata and requires some extra hackery.

I personally have found the best success using svn2git. Github has some details on svn importing page — but the main svn2git page spells it out pretty clearly.

$ mkdir my_local_dir && cd my_local_dir
$ svn2git http://my.svn.server/path/to/repo/and/subdir

That’s pretty much it, after svn2git runs you will have all of branches/tags/trunk imported into your local directory as a git repository. You may have to fiddle around with the options, and if you’re behind a proxy (why do corporations think this is useful or somehow more secure?!!! proxies cause SO many issues… sigh) then you may have to fiddle with $http_proxy.

Oh, and before I forget, you’ll probably want to create a “git authors” file — this provides a mapping between subversion-style user IDs (like abaker) and git-style IDs (Adam Baker <>). This isn’t important for a dry run, but when you do migrate your code in the end, you’ll definitely want this to be working correctly.

Sharing your changes

Last but not least, chances are you’ll want to push all these commits to a bare repository on a central server somewhere. Git doesn’t require you to have a “trunk” or official repository, but most people generally designate one repository as the official / blessed / trunk repo. It just makes logical sense to have one spot where are the good code is, where everything’s clean/tested/reviewed and thereby ‘blessed’.

I’m assuming my_local_dir is on your personal dev box — I would highly recommend following something similar to the Integrator Workflow, in which case you’ll do the following

# initialize the bare repository which will be considered 'pristine' or 'blessed' (aka SVN trunk)
[user@main_server:/path/to/repo] $ git init --bare

# add the bare repository as a 'remote' (something you can push changes to)
[user@dev_box:/path/to/my_local_dir] $ git remote add origin user@main_server:/path/to/repo
[user@dev_box:/path/to/my_local_dir] $ git push --all

At this point, you've imported from your Subversion repository into a local git repo, initialized a 'blessed' (trunk) on your main server (which presumably everyone has SSH access to - or you've set up Gitorious, Github:FI, or gitweb) and you're ready to start coding!

If you've made it this far, you're definitely going to want to read the Pro Git book. Consider it the complete reference on git, and an invaluable asset on your way to becoming a git master.

The short answer is someone new to your team/project/etc will clone the blessed repository one or more times, make some local changes, commit them locally. Later, someone will pull those changes into the main repository when they're stable/reviewed/tested and otherwise considered ready for merging.


Git is a very powerful but often confusing DVCS. If you're new to git, I highly recommend you start with Github or Gitorious. They both provide a nice interface with tips and hints to help you with common workflow tasks, and they provide/require/strongly promote changeset review on every merge. It feels awkward at first, but it changes your life... seriously.

So what're you waiting for? Go 'git' started! (ha ha ha)


Categories: Uncategorized Tags: , , ,

Cloning a clone: Hg vs Git

May 12, 2010 13 comments

I’m in the progress of learning about git and mercurial (Hg), and so you’ll probably see a number of posts from me about this subject.

I know, I know, cue the “git rawks!”, “Hg is da bomb!”, and “they’re both lame, stick with SVN!” debates… anyways, I’m coming at this from a total newbie’s perspective. In the past I’ve written about TortoiseGit and some of the issues I had, so I decided to skip the GUI and go commando command line only.

The first experiment I’ll try where I pit one DVCS against the other is the “cloning a clone” scenario. In the mercurial tutorial, this is described as the “blessed” way of doing things – see the section Making and Reviewing Changes. Whenever you have an experimental change to make, you should clone your local repo (which is itself a clone of someone else’s) and push changes up to your primary cloned repo when they’re stable. Then push them up to the place you cloned them from later. Also, this is described/required by the Integrator workflow in the Pro Git book, specifically Chapter 5.1 – Distributed workflows.

Cloning a Clone: Hg

In the spirit of brevity, I’ll just stick to a terse command line dump. I’m working on Ubuntu 9.10 with Hg 1.3.1, which is installed via

sudo apt-get install hg

First things first… let’s clone someone’s public repo. Heck, how about hgsubversion?

atto@zues:~$ hg clone
destination directory: hgsubversion
requesting all changes
adding changesets
adding manifests
adding file changes
added 608 changesets with 1432 changes to 181 files
updating working directory
144 files updated, 0 files merged, 0 files removed, 0 files unresolved

So far, so good. I now have a clone of hgsubversion. Now, let’s clone the clone.

atto@zues:~$ hg clone hgsubversion my-hgsubversion
updating working directory
144 files updated, 0 files merged, 0 files removed, 0 files unresolved

Yawn. This works so flawlessly, it is actually boring me to sleep.

What happens if I now make conflicting changes in each of the repos, then try to mash those conflicts together into an unholy mess?

Edit line 42 in both repos, commit, etc.

atto@zues:~/hgsubversion$ hg status
atto@zues:~/hgsubversion$ hg commit -m "Conflict in remote"
atto@zues:~/hgsubversion$ cd ../my-hgsubversion
atto@zues:~/my-hgsubversion$ gvim (make changes)
atto@zues:~/my-hgsubversion$ hg commit -m "Conflict in clone clone"

Ok, it took longer to type this post than it took to make these changes. Boring so far…

At this point, I have two conflicting changes – one in my clone of hgsubversion, and one in my clone-clone of hg-subversion. Now, a sensible thing to do would be to push changes from the clone-clone up to the clone (pretend it’s an integration branch in SVN speak, or a testing playground of sorts).

atto@zues:~/my-hgsubversion$ hg outgoing
comparing with /home/atto/hgsubversion
searching for changes
changeset:   608:5776ac5c7b12
tag:         tip
user:        Foo Bar
date:        Wed May 12 21:25:09 2010 -0700
summary:     Conflict in clone clone

atto@zues:~/my-hgsubversion$ hg push
pushing to /home/atto/hgsubversion
searching for changes
abort: push creates new remote heads!
(did you forget to merge? use push -f to force)
atto@zues:~/my-hgsubversion$ hg incoming
comparing with /home/atto/hgsubversion
searching for changes
changeset:   608:45a0d7d3e796
tag:         tip
user:        Foo Bar
date:        Wed May 12 21:24:40 2010 -0700
summary:     Conflict in remote
atto@zues:~/my-hgsubversion$ hg pull
pulling from /home/atto/hgsubversion
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

So, I tried to push up some changes, but doing so would’ve created a two-headed monster, so Hg told me “did you forget to merge? use push -f to force”. That’s actually pretty friendly, maybe I should do a merge.

atto@zues:~/my-hgsubversion$ hg merge
QFSFileEngine::open: No file name specified
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
atto@zues:~/my-hgsubversion$ hg stat
atto@zues:~/my-hgsubversion$ hg diff
diff -r 5776ac5c7b12
(cut diff)
atto@zues:~/my-hgsubversion$ hg commit -m "Fix merge issues. Bad developer, no pizza"

The odd message about QFSFileEngine::open: was the point in time where Kdiff3 popped up to help me resolve the merge. No surprises here, the merge went off flawlessly as expected, cool.

Now I can push my changes (dumb as they are) up to the original clone:

atto@zues:~/my-hgsubversion$ hg outgoing
comparing with /home/atto/hgsubversion
searching for changes
changeset:   608:5776ac5c7b12
user:        Foo Bar
date:        Wed May 12 21:25:09 2010 -0700
summary:     Conflict in clone clone

changeset:   610:b333c539af3d
tag:         tip
parent:      608:5776ac5c7b12
parent:      609:45a0d7d3e796
user:        Foo Bar
date:        Wed May 12 21:29:59 2010 -0700
summary:     Fix merge issues. Bad developer, no pizza

atto@zues:~/my-hgsubversion$ hg push
pushing to /home/atto/hgsubversion
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files

Cool. That just… worked. I don’t think I was confused for even a second, things just worked as I would expect them to. I created a conflict I knew Hg couldn’t automatically resolve, it told me what to do, and it took <5 min total to run the experiment.

How about git?

Cloning a Clone: Git

Here I’m installing git-core and git-svn, git-svn isn’t strictly necessary but if I get time I’d like to experiment with pulling (and hopefully pushing) to an SVN repo. If it works, then I can use git all day long and seamlessly push to SVN when my changes are stable.

sudo apt-get install git-core git-svn

Now, let’s clone a public repo so we can experiment and have a little fun.

atto@zues:~$ git clone
Initialized empty Git repository in /home/atto/hg-git/.git/
got f5493088320f5587bcbcf701bd82ce6625a50e27
walk f5493088320f5587bcbcf701bd82ce6625a50e27
(cut 200+ lines of debug-type info)
walk 01bddec68dab48693af40968567ce4cff535f269

OK, it’s a little verbose – I mean, come on, do I really need to care about each and every changeset and it’s hash? But hey, at least it worked with no issues.

Now let’s clone the clone…

atto@zues:~$ git clone hg-git my-hg-git
Initialized empty Git repository in /home/atto/my-hg-git/.git

Fast forward a bit, I’m gonna skip the part where I make conflicting changes and commit them to the two different clones. BTW, don’t forget to do a “git add” before committing, which is annoying but probably a useful feature somehow.

Now, how do we tell what changes are ready to go out without actually pushing them?

There is no “git outgoing”, but after fishing around a bit I discovered that “git status” has some useful information:

atto@zues:~/my-hg-git$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
# Untracked files:
#   (use "git add ..." to include in what will be committed)
nothing added to commit but untracked files present (use "git add" to track)

Hmmm OK so I’ve got one commit that needs pushing, still not sure which one but I’ll leave that be for now.

Of course, doing a “git push” isn’t smart enough to figure out where to push to or what branch to push… so I finally ended up with

atto@zues:~/my-hg-git$ git push origin master
To /home/atto/hg-git
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to '/home/atto/hg-git'

Well, this error mesage looks annoyingly familiar… is this git’s unique way of telling me that I need to pull and merge first?

atto@zues:~/my-hg-git$ git pull origin master
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/atto/hg-git
 * branch            master     -> FETCH_HEAD
CONFLICT (content): Merge conflict in
Automatic merge failed; fix conflicts and then commit the result.

Cool, that did something useful-ish. It didn’t pop up kdiff3, or any editor for that matter – but perhaps that’s a matter of configuration? Anyways, off I go to gvim and resolve the conflict by hand.

atto@zues:~/my-hg-git$ git add
atto@zues:~/my-hg-git$ git commit -m "Fix for conflict in clone clone"
[master fabff96] Fix for conflict in clone clone

With any luck, now I can finally push my two changesets (the conflict and the conflict fix) to origin master:

atto@zues:~/my-hg-git$ git push origin master
Counting objects: 10, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 730 bytes, done.
Total 6 (delta 4), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
warning: updating the current branch
warning: Updating the currently checked out branch may cause confusion,
warning: as the index and work tree do not reflect changes that are in HEAD.
warning: As a result, you may see the changes you just pushed into it
warning: reverted when you run 'git diff' over there, and you may want
warning: to run 'git reset --hard' before starting to work to recover.
warning: You can set 'receive.denyCurrentBranch' configuration variable to
warning: 'refuse' in the remote repository to forbid pushing into its
warning: current branch.
warning: To allow pushing into the current branch, you can set it to 'ignore';
warning: but this is not recommended unless you arranged to update its work
warning: tree to match what you pushed in some other way.
warning: To squelch this message, you can set it to 'warn'.
warning: Note that the default will change in a future version of git
warning: to refuse updating the current branch unless you have the
warning: configuration variable set to either 'ignore' or 'warn'.
To /home/atto/hg-git
   be73d6a..fabff96  master -> master

Well, that’s downright confusing, but at the end of the barf message, it looks like something happened. Trotting over to the original clone and checking the log, I can see that I now have three new commits – one in the clone, two in the clone-clone.

So… I think it worked.

Just to be sure, I opened and checked the line in question… and it’s not been updated.

Well, in SVN and Hg you do an “update” command to bring the working copy into latest state… does that work for git?

atto@zues:~/hg-git$ git update
atto@zues:~/hg-git$ git help
(nothing useful)

Argh. I know this one. It’s somewhere in my brain…. processing…. processing… the lights are on but nobody’s home.

Oh yeah, the log above said something about running “git reset –hard”. That sounds a bit scary, but these are dummy test repos so who cares if I blow them away by accident?

atto@zues:~/hg-git$ git reset --hard
HEAD is now at fabff96 Fix for conflict in clone clone

Oooooooh yeah, now that’s what I’m talking about… suddenly, has the new, updated, correct information.

Why does that take a 2-page error/warning message?

So, at this point, I’ve successfully cloned a clone, and pushed conflicting changes up from the clone-clone to the clone – just the same as in Hg.


It doesn’t take a genius to see two things right off the bat:

  1. git’s error mesages range from confusing to overly verbose to completely useless
  2. git required more time reading help files and guessing which commands to run

Sure, #2 could be explained quite simply by my lack of understanding, my complete idiot self not reading enough documentation and manuals, me being a typical user. And… guess what? That’s correct.

I didn’t read any documents, manuals, tutorials, or howtos. And I shouldn’t have to, not for simple things like conflict resolution and cloning (aka checkouts in SVN speak).

Either way, git’s apparent lack of useful error messages makes it critically apparent that git wasn’t designed for ease of use or to ease the transition from any other SCM. Git was designed by Linus as a change/patch management tool for serious kernel hackers, and even now, years later… it’s just not easy to switch.

And Hg?

Well, there are other issues with Hg (like HTTPS behind a corporate proxy, for example) that are well known and documented. But for now, as I sit here writing this incredibly long and boring post… Hg just works for me.

I didn’t have to read the manual, I just started typing commands. What little bit I remembered about Hg is floating around from reading the Hg book several months ago, and so I’m starting basically at ground level.

I want to like git… I’ve read of good things about git… but the barriers to entry are significantly higher, such that I’m having a hard time learning how to use it. Trying to teach a team of other developers to use git? Wow, I’m not even sure I want to think about that. My head is spinning just imagining how to explain to someone why they have to “git add” before a “git commit”, much less what “origin” and “master” are and why you have to “git reset -hard” whenever you push.

So I guess that’s the bottom line… as a newbie idiot user, git confuses the heck out of me, and Hg just works.



Categories: Uncategorized Tags: , , ,

Saving Time with Hudson CI

I ran across the following blog post about Hudson CI, it makes the ridiculous claim that you can install and configure Hudson in less that 5 minutes. So, I decided to give Hudson a shot, if nothing else just to prove them wrong. Everyone knows software doesn’t ever just work and always takes 10x as long to install as you think it will.

Boy, was I wrong.

From the command line in my Ubuntu server:

$ sudo echo deb binary >> /etc/apt/sources.list
$ sudo apt-get update
$ sudo apt-get install hudson

It automatically installed the correct dependencies, then installed and started hudson. Within a few minutes, I was pointing my browser to http://localhost:8080 and configuring Hudson.

Surprised but still skeptical, I clicked through a few pages and within a few minutes Hudson was happily building and running our integration tests.

I was stunned.

I’ll admit, I’m not the world’s expert when it comes to validation or agile methods, but I’m no dummy either. And I’ve had some bad experiences with other validation platforms, bad enough to scare our whole team away from them for a while.

Our testing methodology hasn’t changed much – we still run the sanity tests by hand before each checkin, and we still run longer stress tests periodically… but Hudson has simplified our validation and made it… almost fun to find bugs.

After getting the sanity checks to run after every checkin, I set up our stress tests to automatically run every night, with longer validation runs over the weekend. No more nagging team members, no more “did you run the stress tests?”. Just checking the dashboard to find out how the tests ran.

It was so easy to configure, I went ahead and ran the sanity tests in a tight loop 100 times. That’s something I never would have done normally… but Hudson made it all too easy. And guess what? Hudson found a bug for me. When we run the sanity tests 100 times in a loop, they crash intermittently. Could be a test setup issue, could be a real bug, not sure yet. But we never would’ve found it without Hudson. Could we have found the bug by hand? Duh, of course… but we probably wouldn’t have. Having a CI tool like Hudson makes you step back and look at your validation holistically, and that’s a good thing.

The bottom line for me, what has me tickled pink and uber excited is the time I’m saving. And not just the few minutes of hassle nagging people to run the tests, or the collecting of log files and reports… no, that’s nice and every minute of development time saved is money in the bank. But Hudson now has us testing our software 24/7, continuously integrating… and my gut tells me this will add up in much larger savings down the road. The earlier we detect and fix bugs, the more money we save. And that makes me happy.

Now to be fair, there are still some things I haven’t gotten working – parallel builds elude me for the time being, and email notifications don’t work behind our proxy server (yet) – but today, so far, I’m loving Hudson. Are there other CI servers that would work fine? Probably, but who cares! Hudson is good to me so far.

It. Just. Flipping. Works.

So go download it and start using it. You’ll wonder why you waited so long.



TortoiseGit – round 2, fight!

April 22, 2010 2 comments

For some odd reason, I’ve gotten my head wrapped around TortoiseGit and hence this follow-up post.

Cloning a public repository successfully is neat… but not exactly useful.

So, for this post I’m going to try a couple of tricky things in rapid succession:

  1. creating conflicting changes in a clone that I have to resolve when I push
  2. create two radically different changesets consistent with two sparring developers

And if I get really creative, maybe I’ll try to clone an SVN repository just for the heck of it.

First things first.

Cloning my local repo was trivial, and not worth detailing. I created two conflicting changes, one in the master and one in the cloned repo. Committed in the clone with no issues, then hit the “push” dialog.

I was expecting some kind of error, or perhaps a merge dialog to pop up – but instead I got the following very confusing error message.

git.exe push “origin” master:master

To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again. See the ‘Note about
fast-forwards’ section of ‘git push –help’ for details.
To C:\Users\foo\Downloads\hg-git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to ‘C:\Users\foo\Downloads\hg-git’

As a complete and total git newbie, I found this error message very confusing. What is a fast-forward update? I actually missed the “merge the remote changes” message the first time through. This dialog is not very useful – why not list the log message of the remote changes that need to be pulled? This would be much more user friendly. At the very least, it should pop up with a button to pull & merge.

Hmmm… what to do next.

The dialog says I need to merge, but I seem to remember reading something about pulling before a merge.

How about TortoiseGit->Pull?

The result is shown below in the following image.

Wow, that is not only confusing, but downright useless.

Unless I completely missed something, there’s no easy “edit conflicts” button that pops up the 3-way merge tool. I actually had to search around for a bit to figure it out. You can either right click on a file and then select TortoiseGit->Edit conflicts, or you can use the “Check for modifications” link to show a list of all changed (and conflicting) files.

OK, so I edited the conflicts, then committed them to my local clone. Now what happens if I push?

git.exe push “origin” master:master

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require ‘git reset –hard’ to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set ‘receive.denyCurrentBranch’ configuration variable to
remote: error: ‘ignore’ or ‘warn’ in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: ‘receive.denyCurrentBranch’ configuration variable to ‘refuse’.
To C:\Users\foo\Downloads\hg-git
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to ‘C:\Users\foo\Downloads\hg-git’

Wow, this is so lame I’m almost ready to give up on git.

At this point, git is zero for two on the user friendliness scale. So far my googling for the many error messages in this git-barf just turn up more of the same – I can’t push from master -> master on a local repository. Which is completely and totally not helpful, and doesn’t make any logical sense.

It’s getting late, so I’ll post back when I git this figured out (ha ha very punny).


Categories: Uncategorized Tags: , , ,

First Impressions of TortoiseGit

April 21, 2010 Leave a comment

This will be a really short post, I recently installed TortoiseGit and wanted to post my first impressions.

I’ve been a long time SVN user, with a fair amount experience using TortoiseSVN. TortoiseSVN is about as good as it gets when it comes to getting out of the way and letting you get your actual work done. I have a lot of good things to say about TortoiseSVN, but let’s face it – it’s just a GUI front-end for SVN.

I’m going to skip the debate about centralized vs distributed revision control — the ‘net is full and overflowing with opinions, debates, misinformation, and evangelism on both sides. At the end of the day, SVN (darcs, Mercurial, git, bazaar, perforce, etc) are just tools to manage changes to source code. Each has it’s own strengths and weaknesses, so I won’t bore you by repeating these pros/cons here.

What I really wanted to write about was my first impressions with using TortoiseGit, which is a Tortoise clone for git. I’m coming at this from a complete newbie’s perspective – I’ve only cloned one git repository before, and it’s been a while.

First things first: install TortoiseGit. No issues here, the installer runs and within a minute or so I’ve got explorer integration working. An annoying artifact of running Windows is the constant reboots – sure enough, TortoiseGit wants me to reboot before it’s fully working. Argh. I didn’t want to reboot, so I put this on hold or a day or two until my next natural reboot.

Now, let’s clone a repo.

Right click in windows explorer, click on “Git Clone” — oops! Got a dialog box of death, looks like I forgot to install msysgit. A download/install later, and now TortoiseGit pops up the clone dialog.

The SVN checkout and git clone dialog look pretty much the same, nothing really interesting to see but I’ve included a screenshot here.
svn checkout vs git clone

I cloned, and the clone worked perfectly without any issues. It’ll be interesting to see how well this works from a corporate network, behind a proxy and all that.

Of course, showing the log files works perfectly and gives me all the changesets from initial import.

One thing I really like about the git log is the graph running along the left side – it looks like a depiction of the branching & merging, but I’d have to check into it more to be sure:

I have yet to try anything actually useful, committing / branching / etc — but at first glance, it looks fully capable and functional and I’m excited to get more into it as time permits.

Categories: Uncategorized Tags: , ,

ack is better than grep

April 16, 2010 Leave a comment

Disclaimer – this post will probably only make sense if you’re a Linux/UNIX command line freak. So if you’re a Windows .NET programmer or a Web coder or not a coder at all – you might wanna skip this post.

If you spend much time at all working with source code (C, C++, Java, Ruby, Perl, Python, whatever), you quickly come to realize that navigating through code is tricky. Visual Studio users don’t really appreciate this because IntelliSense hides most of this trouble from you (most of the time), but any good UNIX geek knows what a nightmare grep can be and what an unholy combination of pipe magic is required to find your way around code.

I’ll post soon about ctags, cscope and maybe even code bubbles, and how you can use them in combination with the world’s best text editor (vim of course) to write some rockin’ good code.

However, these and other tagging based tools usually require integration with an editor, and there are times where it’s just not convenient to launch or configure an editor. Or setup a project in an IDE. Sometimes you just want to find out what file function Foo is defined in, or who all the callers of Bar are, and you want the answer now.

A naive grep based approach starts out like this:

$   grep "Foo" *
Binary file stuff.o matches
foo.c:247      Foo(bar, car, star);
(5 pages of irrelevant garbage cut)

Usually, you pick up some garbage coming from Binary files in the same directory, and you forget to specify a recursive search so it doesn’t find the file you really wanted.

So, you monkey around some more, use find to limit your search to source files, and you get this:

$   find . -name "*.c" -or -name "*.h" | grep Foo
foo:c:247    Foo(bar, car, star);
subdir/proj/main.c:17    bar = malloc(sizeof(Foo));
.svn/blah/foo.c.blah   Foo(NULL, car, bar);
(Cut 10 pages of irrelevant SVN metadata)

Oops, looks like we got some subversion working copy junk mixed in with useful results. Blasted revision control always clutters up a grep chain. After a few more iterations, my grep command finally ends up looking like this:

$   find . -name "*.c" -or -name "*.h" | grep Foo | grep -v .svn | grep -v otherstuff

It’s honestly a flipping nightmare.

A few months back, I stumbled across another command line tool (well, perl script really) that hides all the warts of grep, and helps me do the one task I really care about doing: finding everyone who uses Foo so I can add a new parameter to the argument list, or some other similar code maintenance task.

Now, instead of typing a monstrous, iterative grep session – I just type

$   ack Foo

And ack searches for the regular expression Foo in all source-code-like files in all subdirectories, displaying line numbers and highlighting in red the matching patterns.

ack really is better than grep.

ack rocks. Save yourself a lot of grief and kick your grep habit to the curb, you will never look back.



Categories: Uncategorized Tags: , ,