Tuesday, August 31, 2010

Hg vs. Git in the workplace

This post is based on the following mail I sent to the ALT.NET Israel list. I'm discussing a Windows development environment.

I'm much better at git than hg, and I use git a lot for real work, and it's great (no ifs or buts).
I also helped originate the move to git at work, because the transition plan was much better. I evaluated hg first and loved it, but the transition plan wouldn't have been half has smooth (a better hg-svn bridge may have been written since then).

Still, here are - in order - the reasons I thing hg would fit better at my workplace (and had we found a good transition plan we'd probably be using hg instead of git):

  1. Friendlier commands and interface. With git I feel like I need to research how to do straightforward things. Git is extremely powerful and I can do anything with it, and I'm strange so I like the arcane, but git requires more of an investment from people to use it effectively when they have other things to do. Some things are arguably easier to understand in git (rebasing, for example, vs. hg's patch queues - although that's debatable) but the whole package leans heavily to hg IMO. This is the least-loved aspect of git among the teams.
  2. In hg, commits remember the named branch they were committed to (see here). I would LOVE to have this in git, but no cigar - we're still playing with different schemes of approximating this.
    With many people working at times on several branches, and with merging done between branches, then given commit XYZ it's nontrivial in git to figure out which branch it belongs to.
    This is especially true in some scenarios we encountered - e.g. human error caused an older release branch to be fast-forwarded to the head of the latest devel branch - few traces are left in the repository itself of the previous state, and we had fun a few times fixing this (can take hours). Now we have a hook to prevent this.
    If we'd have cherry-picked between different branches instead of merged then this would be easy (and this is equivalent to svn's merging, only better), but we like git's merge and we want to use that.
  3. hg has less quirky Windows support. Points to consider:
    • msysgit gets sporadic releases and is usually months behind the stable git version, the latest hg versions just work.
      • This hit us a few times (bug has been fixed but not available in msysgit).
      • Current example: Git 1.7.2 has improved crlf handling but msysgit isn't there.
    • Being able to "hg serve" your repository is incredibly cool, but "git daemon" doesn't work with msysgit
      • Think continuous integration that watches your local repository and runs builds with your current code, giving up-to-date feedback
      • collaborating with someone without pushing a publicly-visible branch (I've actually wanted to do that a few times)
      • developing and testing on more than 1 machine simultaneously. There are workarounds, but "git daemon" would have been perfect.
    • automating hg, including hooks, run in a Windows environment (vs. git where it runs in mingw's MSYS environment)
What doesn't bother me much for the long run is tooling. Right now hg seems to have better tools for our scenarios (even including much better Trac support), but I think git's extreme popularity will cause better and better tools to be written. Some people were very sad to let go of their VisualSvn / Ankh plugins, but they manage with Git Extensions (mostly) and occasionally TortoiseGit. I was surprised at how few people use git from the command-line, I can't live without it.

submit to reddit Submit Story to Digg

Monday, June 28, 2010

jQuery Validate: Required If Visible

I needed a generic "required if visible" rule for use with the jQuery Validation plugin. This is the result:


// jQuery.validate.requiredIfVisible.js
// Copyright (c) 2010 Ori Peleg, http://orip.org, distributed under the MIT license
(function($) {
$.validator.addMethod(
"requiredIfVisible",
function(value, element, params) {
function isVisible(e) {
// the element and all of its parents must be :visible
// inspiration: http://remysharp.com/2008/10/17/jquery-really-visible/
return e.is(":visible") && e.parents(":not(:visible)").length == 0;
}

if (isVisible($(element))) {
// call the "required" method
return $.validator.methods.required.call(this, $.trim(element.value), element);
}

return true;
},
$.validator.messages.required
);
})(jQuery);

Notes:

  • Using required:"#myinput:visible" could have worked, but ":visible" doesn't check for hidden parents, and I didn't want to repeat the element selector.
  • ":hidden" is false for elements with the "visibility:hidden" CSS rule, so I couldn't use ":not(:hidden)" either.
  • Technique for checking element visibility from Remy Sharp's blog.

submit to reddit Submit Story to Digg

Sunday, April 25, 2010

MVC's RenderPartial in a WebForms page

We have a mixed ASP.NET MVC/WebForms application, slowly transitioning to all-MVC. Obviously, sharing components between MVC and WebForms is important to us.

Using WebForms controls in MVC views is easy enough (minus the postbacks), but when we rendered partial views in a WebForms page using Keith Henry's code we occasionally got evil "Validation of viewstate MAC failed" errors. Microsoft doesn't think hybrid WebForms / MVC apps are relevant, but then Mauricio Scheffer came to the rescue. Instead of having the partial views subclass ViewUserControl, we now subclass Mauricio's ViewUserControlWithoutViewState - problem solved.

submit to reddit Submit Story to Digg

Monday, April 12, 2010

TeamCity 5.0 upgrade - "out of memory" error

I upgraded JetBrains TeamCity to version 5.0 on Windows (for Git support, yay!). The previous version upgrades went smoothly, but this time I got an exception when loading the server:

java.sql.SQLException: out of memory

After some googling, I thought I had to:

  • Run ...\TeamCity\bin\tomcat6w.exe //ES//TeamCity
  • In the "Java" tab change the value for "Maximum memory pool"
  • Not set it too high
But no cigar. I realized that I probably had a corrupt HSQLDB database, and I ended up reinstalling and copying the config by hand (which was a little frustrating). I don't think there's a real reason why an embedded SQL database should be less dependable than one with a server (I know that from SQLite), so I'm guessing it's either TeamCity's or HSQLDB's fault. Even so, an "export configuration" button would be nice, and take the pain out of reinstalling TeamCity.

submit to reddit Submit Story to Digg

Sunday, February 14, 2010

Encoding usernames and passwords in FTP URIs

I want to encode the following into a single URI:

  • Username: 'jane+foo@example.com'
  • password: 'my password' (with a space)
  • ftp server: 'ftp.example.org'

The FTP URI that I expect:

ftp://jane%2bfoo%40example.com:my%20password@ftp.example.org

In .NET, HttpUtility.UrlEncode almost does what I need - it hex-encodes the special chars, but it also converts spaces to "+" which the FTP server interprets as a literal "+".

Final code that works with my tests using the FileZilla FTP Server:

string EncodeFtpUserInfoComponent(string s)
{
  // assume or assert s != null
  return HttpUtility.UrlEncode(s).Replace("+", "%20");
}

submit to reddit Submit Story to Digg

Tuesday, February 2, 2010

PowerResizer Keyboard Shortcuts

For some reason the keyboard shortcuts / hotkeys for Federico Bastianello's PowerResizer aren't on the web, only in the "Readme.txt" installed with it. So, as a public service, here they are (for version 0.95):

2.1 - Window Docking Features and Keyboard Shortcuts

 - Move Window + A: dock a window to the left-half of the screen.
 - Move Window + S: dock a window to the right-half of the screen.
 - Move Window + W: dock a window to the top-half of the screen.
 - Move Window + Z: dock a window to the bottom-half of the screen.
 - Move Window + 1: dock a window to the top-left corner of the screen.
 - Move Window + 2: dock a window to the top-right corner of the screen.
 - Move Window + 3: dock a window to the bottom-left corner of the screen.
 - Move Window + 4: dock a window to the bottom-right corner of the screen.
 
When you resize the inner border of those windows you docked to one of the four
corners of the screen or to one of the four screen halves, PowerResizer 
changes the windows' behavior during resize in a way that all docked windows
will follow the new size of their neighboors.
It is possible to mix docked windows in halves of the screen and in corners.

2.2 - Window Moving/Resizing Features and Keyboard Shortcuts

 - Resize Window + CTRL: resize a window mantaining fixed its center point.
 - Resize Window + SHIFT: move a window using its border.
 - Move Window + 5: center a window into the screen (1/16 screen size margin).
 - Move Window + 6: center a window into the screen (1/10 screen size margin).
 - Move Window + 7: center a window into the screen (1/6 screen size margin).
 - Move Window + 8: center a window into the screen (1/4 screen size margin).
 - Move Window + 9: center a window into the screen (1/3 screen size margin).
 - Move Window + 0: maximize a window.
 
2.3 - Screen window reposition Features and Keyboard Shortcuts

 - CTRL + ALT + PAGE UP: Rotate docked windows counter-clockwise.
 - CTRL + ALT + PAGE DOWN: Rotate docked windows clockwise.
 - CTRL + ALT + HOME: Reposition windows.
 
Note: the keyboard shortcuts in that section, are system-wide shortcuts and 
they will work on windows docked on the monitor containing active window.

submit to reddit Submit Story to Digg

Thursday, October 29, 2009

Console colors on Windows in .NET

Changing the console output color is easy on *nix terminals with escape sequences, but has a funky API on Windows (see the color support code from Testoob for a Python example with pywin32/ctypes).

It turns out that there's a very nice .NET API for it, though (there's a nice article by Sam Allen on the Dot Net Perls site). This would be awesome for Testoob's IronPython support.

submit to reddit Submit Story to Digg