Git is a great distributed version control system that I am getting to like more and more everyday. We don't use git where I work, but for me, git works just as well as a super-powered subversion client.

I like to have git integrated with the rest of my (cmd) shell, so I use the MSysGit found here. This is as close as you can get to native git on windows. Using this, I am able to use git in powershell, cmd scripts, build scripts, or in lots of other places, without having to invoke it through something like the bash.exe that comes with cygwin.

Unfortunately, as of this writing, msysgit does not include git-send-mail (here's the issue). As I wrote before, I sometimes need to manually push patches around between the various computers I work on, and e-mail would work great for this.

Fortunately, powershell community extensions has a Send-SmtpMail cmdlet that can do the same things git-send-mail did - even more actually.

I use pobox.com for my e-mail and their smtp relay will relay mail for me, but only if I authenticate properly. As far as I know (I haven't actually tried this) git-send-mail isn't able to authenticate with my e-mail provider.

Anyway, here is what I do, in powershell, to e-mail my patches:

git format-patch -M origin

Then, to send it off:

mail -To cbilson@whereheworks.com `
     -From cbilson@pobox.com `
     -SmtpHost sasl.smtp.pobox.com `
     -Credential (get-credential) `
     -AttachmentPath *.path `
     -Bcc cbilson@pobox.com `
     -Body "Please apply this patch. KTHXBY"
     

I get the patches as attachments, save them to a folder somewhere, and just use git-am to apply them at work.

The kind of weird thing about this is that all the patches are in my gmail account and I have a folder for them. Given the baseline I started using git from, I could re-apply all those patches and get back to HEAD (I would likely want to use powershell to automate that!) So Gmail is my repo.


 
Categories:

Due to various network obstacles between my work and personal machines, I often find it necessary and convenient, when using git, to use skydrive, thumbdrives, or some other low-tech means to pass around patch files. Git has really nice integration with common unix mail utilities that make it really sweet to do this on unix.

But I am using windows.

I had to overcome a couple of annoying but obvious hurdles to get this to work. Here's my current process for cloning a project in an svn repo at work, then passing patches around:

1. clone the svn repo. Let's call this clone':

git svn clone -s http://svn-server/MyProject

Actually, I am lying. I use this command because our projects are not in the canonical git layout in our repository:

git svn clone http://svn-server/svn --trunk=trunk/MyProject --branches=branches/MyProject --tags=tags/MyProject

2. Make sure your repo has core.fileMode false (this takes care of many of the other problems I had with git too):

git repo-config core.fileMode false

3. For some reason my life is easier with core.autocrlf false. Or maybe that's why I always have to --whitespace nowarn when I apply patches. I don't know. This is just the way I am doing it and it works.

git config --global core.autocrlf false

4. Clone that repo to take home or wherever. Call this clone''. Remember that the real magic in cloning is that it creates tracking branches:

git clone --no-checkout C:\Projects\MyProject.git E:\ToTakeCome\MyProject.git

5. Say I am home on clone''. I branch, work, commit. Do the dance, now I want to takes these changes back to the mother ship. Machines aren't connected. Don't want to bring laptop to work:

git format-patch -M origin; cp *.patch E:\TakeToWork

6. At work, in clone':

git am -3 --whitespace nowarn E:\FromHome\*.patch

That's basically how I am doing it, after many blind alleys and false starts. My process is a work in progress, so I will update when it changes.


 
Categories:

We use Wix to build installers at my work. I've blogged about this before.

Wix comes with custom actions to create IIS App Pools and Virtual Directories. Up until today, my wix scripts all WebVirtualDirs and WebAppPools in the same component:

	<Component Id='WebApp_WithAppPool' 
		   Guid='$(var.IIsWithAppPoolSettingsComponentId)'>
        	<Condition>Not IISMAJORVERSION="#5"</Condition>
                <WebAppPool Id='MyAppPool'
                            Name='$(var.AppPool)' />
                <WebVirtualDir Id='MyVDirWithAppPool'
                               Alias='IMR/$(var.InstallDirectory)'
                               Directory='INSTALLDIR'
                               WebSite='Default'
                               DirProperties='AppDirProps'>
                    <WebApplication Id="MyAppWithAppPool" 
				    Name='[ProductName]' 
				    WebAppPool='MyAppPool'>

We recently changed the security model of this application to use a service account, but the above installer would uninstall the app pool when the application was uninstalled. When they went to install an upgraded version they would have to find someone that knew the password for the service account to enter it in the app pool settings after installing.

A little searching led me to this mailing list thread, where they recommend adding a Permanent='yes' attribute (which I didn't realize existed.)

This worked, but then my vdir doesn't get uninstalled, so I just created a new component for the app pool, made it permanent, and voila:

  • When installing
    • If the app pool doesn't exist it's created
    • If it exists we leave it alone but still put the app in it.
  • When uninstalling
    • The vdir is deleted, but the app pool is left alone.
	<Component Id="WebApp_AppPool"
		   Guid="$(var.IIsAppPoolComponentId)"
		   Permanent="yes">
       		<Condition>Not IISMAJORVERSION="#5"</Condition>
                <WebAppPool Id='MyAppPool'
                            Name='$(var.AppPool)' />
	</Component>
	<Component Id='WebApp_WithAppPool' 
		   Guid='$(var.IIsWithAppPoolSettingsComponentId)'>
        	<Condition>Not IISMAJORVERSION="#5"</Condition>
                <WebVirtualDir Id='MyVDirWithAppPool'
                               Alias='IMR/$(var.InstallDirectory)'
                               Directory='INSTALLDIR'
                               WebSite='Default'
                               DirProperties='AppDirProps'>
                    <WebApplication Id="MyAppWithAppPool" 
				    Name='[ProductName]' 
				    WebAppPool='MyAppPool'>

 

It actually took me a little while to find out about Permanent='yes', hence this blog post.


 
Categories: installer | tool | wix

April 26, 2008
@ 08:27 AM
  • It takes me around 30-90 minutes to prepare a blog post - I'm not a good writer and kind of shy and afraid of looking stupid, so I usually got through lots of revisions. (update: even this short post took me 30 minutes, between editing, answering 5y old questions, and moving baby to new less boring place to sit.)
  • We've got a new baby in the house. Every two hours while I'm awake and not at work, I have a little 15 - 20 minute process I need to do. This is enough time to obliterate whatever concentration I had. I'd really forgotten how much there is to do with a baby - it's not so hard (especially after having already done it once) but it's just kind of...a lot. My concentration is always on the edge of a huge gaping void, ready to fall in.
  • Battlestar Gallactica is back on. A few other good shows I've gotten turned onto: New Amsterdam, Breaking Bad. Time sinks all.
  • Twitter. Before I'm even done thinking a thought, it's on the internet.
    • Works really well with having a baby.
    • Works on phone
    • Can do it while my mind is otherwise unoccupied, like during boring meetings at work.

 
Categories: bs

April 19, 2008
@ 07:20 AM

Last night at the opening of #altdotnet seattle, we had a fishbowl about polyglot programming. I felt several times I wanted to run up and grab a chair but...well...when Martin Fowler, Scott Hanselman, Scott Bellware, Ted Neward and other "celebrity programmers" are all jockeying for the one open chair, what I want to say seems a little less important, relatively.

Not so here on my blog, the desert of the real!

So I have been doing polyglot programming for a while: first basic+assembly (atari 800, apple //), then clipper + c, vb + c++, javascript+c++ (MFC app with embedded web browser control), perl + anything (perl's a slut), vb classic + javascript + c++, c#+javascript, vb.net + javascript...oh, and SQL with all those.

One combination notably missing is c#+vb. Why? There is 99.9% overlap between what I would do in c# and vb. For the vast majority of .net applications in the world, it's either in c# or it's in vb. There are a very few edge cases where it makes sense to have both c# and vb in the same application (using vb for office interop, where methods have craploads of optional parameters comes to mind.) So there is basically no/little value mixing c# and vb. It's like mixing sugar with equal. Just pick one, use it, and be happy.

One combination that's in there several times is <<something>> + javascript. Why? Javascript+DHTML is for a totally different purpose than the other languages. It's specially designed for working with browsers. When I am in browserland, I like to talk browser-ese. I find I have to use fewer words to accurately communicate what I want to say.

Being a polyglot is a big investment. You need to get familiar with the languages. You need to keep up on them and use them, lest they atrophy. Some people don't want to do that. In the web programming space, there are lots and lots of tools that let you use one language and generate another. Some of the helpers in monorail come to mind. Most of ASP.NET, and especially, all of asp.net ajax comes to mind. Commercial tools like Iron Speed definately come to mind. These tools and libraries are like machine translation. whazattchickendrive

I really, really want to know what this web page about some funky USB thing that looks like a chicken foot says. Problem is, it's in japanese. No problem, just use translate.live.com or translate.google.com. This will help me kind of understand what the idea is, but it's no where near as informative as the source page, provided you can understand and read Japanese.

I think a lot of tools that hide/generate/translate from a high level language to javascript/html are like machine translation. It's best if you can just learn the language where you are working - javascript for the web, for example - and tools that translate for you are a cheap substitute.

When deciding to watch a Jackie Chan movie, here in the states, I can chose to watch it in dubbed english sans subtitles, or in Chinese. Jackie Chan's movies often have lots of little puns and side jokes going on. Most of this gets lost when the translate/dub it. To really get a Jackie Chan movie, you've really got to understand Chinese (not just the language, but the culture too.) The translated version sounds like the javascript that GWT generates looks.

Source code is, number one, a tool for programmers to express ideas. Working in the right language for the domain you are in improves your ability to accurately and succinctly express your intent to other programmer and the computer. Treat source code as generate-only gobbleygook, and that's what you'll get.


 
Categories: