Skip to main content

Blog

Go Search
Home
  

Categories
Work
Personal
Other
Other Blogs
There are no items in this list.
Blog of Keith Craig, containing my thoughts, comments and questions.
Using SourceGear's DiffMerge as the merge tool in Microsoft Team System

In an earlier post, I discussed using and configuring WinMerge as a compare tool in Team System. Here I discuss using SourceGear's DiffMerge as a custom merge tool.

It all started recently when I had a tricky merge to do in Team System, and I realized that I wanted a bit of their changes and a bit of mine—all from the same block of changes. The problem is that the default merge tool in Team System renders the text change blocks as huge buttons—given this, it's not possible to select a chunk of text from one of them. (Trying to select the text simply clicks the button that is displaying the text.) In addition, the default tool does not display differences within a line—instead, it only shows which lines have differences. This can be very annoying if you are doing a merge and there's a very long line that is highlighted as being different, as it knows which characters are different, but it won't show the specific differences.

Given this, I backed myself out of the tricky merge, and installed the latest version of Sourcegear's DiffMerge. From some preliminary research, it seems to be the best free, three-way merge tool.

Things I really like about DiffMerge include:

  • You can select text from any of the panes and patch it together in the merge result window as necessary
  • It displays differences within a line, which can be a huge time-saver!
  • It does true three-way merges (it uses the common ancestor of a file to determine what it can merge automatically)
  • It is completely free for commercial or personal usage

The only thing that I don't really like about it is that it doesn't have the super-cool monitor-wide diff pane that WinMerge has—given this, I still use WinMerge as my compare tool, and I use DiffMerge as my merge tool. However, I can certainly understand this, as merging is quite different than comparing, and it wouldn't really make sense to have the wide pane at the bottom for merging.

Here's a screenshot of DiffMerge with some silly sample code:

Screenshot of DiffMerge window with sample files. Center file is the common ancestor.

This is the merge view. The center file is always the ancestor—the file that existed before any of the current edits started. Note the highlighting of changes within lines. Also notice the tabs at the bottom—they change the middle file display from the original ancestor and the merge result, which can be quite useful.

You can simply select text from any window and paste it into the Merge Result window, as well as directly editing the text in the Merge Result window.

One trick with this tool is that the auto-merge is called "merge to center"; it's the toolbar button on the far right that shows two green arrows pointing into the middle. This is the three-way merge—it uses the information about the common ancestor to figure out which changes it should keep and which it should not. (Without a common ancestor, it's impossible for the tool to tell what it should do, which is to keep everybody's changes as long as they don't collide.) If the tool detects conflicting changes to the same text block, the auto-merge will not do anything with the conflicts. It will display a dialog like this in the sample case above where the namespace is a conflict, because two different people changed it from the base (ancestor) file:

Merge conflicts dialog showing what the tool did, and that one merge conflict will need to be manually resolved.

Here's what the merge result looks like after auto-merging (note that the "merge to center" button is now grayed out):

Merge result after auto-merge: shows the center file modifications based on the auto-merge, and no changes to the conflict in the namespace

And here's the reference view showing the original ancestor file (bottom tab selection):

Reference view after auto-merge: shows the original ancestor in the center window 

Tip: The documentation suggests that, if you are going to use the auto-merge, you should do it before you do any manual merging, so that the auto-merge doesn't reverse or modify what you've already done. In addition, you can only use the auto-merge once—after that, the button is disabled.

 

Configuration of DiffMerge for Team System Merges

Once again, the web page with all the installation details for custom compare and merge tools is James Manning's blog post. Here is a walk-through for configuring DiffMerge as the merge tool.

First, in Visual Studio, click Tools, then Options. The options dialog appears—click the Source Control node, and then the Visual Studio Team Foundation Server subnode:

Options dialog with Configure User Tools... button

Click the Configure User Tools... button and the following dialog appears:

Configure user tools dialog with only compare tool configured

This list will be empty if you have the default tools configured. Here I have it already configured for WinMerge for the compare operation, but nothing for merge. Click Add... to add a new non-default tool. Here's the dialog when it first opens:

Configure Tool dialog with defaults

Enter the following data:

  • .* for the extension (this will use the merge tool for all extensions)
  • Merge for the operation
  • Browse to the DiffMerge.exe file in C:\Program Files\SourceGear\DiffMerge for the Command
  • Enter the following DiffMerge command line arguments from James Manning's incredibly useful post: /title1=%6 /title2=%8 /title3=%7 /result=%4 %1 %3 %2

It should look something like this when you are done:

Configure Tool dialog with DiffMerge configured

Next, click OK. You should now see your merge tool in the tool list:

Configure User Tools dialog with both custom merge and custom compare tools configured

Click OK, and then OK again to save the settings, and you should be all set!

Thanks to SourceGear for making this tool available to everyone for free! I think it's a winner!

PS: If you try using a custom compare/merge tool and don't like it, it's super easy to undo this process. To go back to the default tool, simply return to the Configure User Tools dialog, select the desired tool under file extensions, and click Remove. (If nothing is configured here, then it uses the default tools.)

Scrum and feedback in process optimization

Scrum has a direct and timely feedback loop built in for optimizing the software development process—the retrospective. Here are some of my thoughts about feedback and optimization of process in software development.

Development in large organizations

Many large organizations tend to have significant amounts of process around their development efforts—so much that sometimes, the development efforts slow to a crawl. By process I mean various rules and procedures where forms need to be filled out, steps need to be taken, checklists need to be followed, approvals need to be obtained, emails need to be sent, people need to be informed, tests need to be performed, etc. Speaking with the developers in such situations often reveals a similar story—they spend much of their time following complex procedures that don't add directly to development productivity or quality. It's not unusual to hear stories where it takes ten hours to complete one hour's development work due to nine hours of process overhead or delays. For example, one client told us a true story in which removing a single misplaced hyphen from a web page cost the organization nearly $100,000. The cost included time to schedule resources, develop project plans, consider and analyze the impact, do a risk assessment, do the actual development (delete the hyphen in a text editor), and then test, retest, and deploy the solution to a variety of staging systems, and finally to the production system. Despite everyone agreeing that the hyphen was a mistake, it took much more time to complete the process required than to delete the comma.

How do things get this way?

I suspect that this is partially related to hierarchical management—as managers become more separated from the developers, less communication occurs. And, when mistakes are made (which is nearly inevitable due to the complexity of modern software), management's response is often to create a new procedure or process to try to prevent future problems. This is completely well-intentioned, but by adding a bit of process each time something goes wrong, eventually process itself becomes part of the problem. And if the issue was a rare issue, then the process may consume thousands of hours in subsequent years to attempt to prevent something that would likely not happen again even without the process.

How to avoid this?

I think one way to avoid this type of problem is by using Scrum. In Scrum, you develop in short iterations (sprints), and at the end of each iteration you have a retrospective. In the retrospective, the dev team reviews what they liked and didn't like, and creates improvements. Often these improvements involve new process  or changes to process. So why is this any better than what was described above? In Scrum there is feedback from the dev team.

The importance of feedback

From my experiences with Scrum, the retrospectives will push the team in one of two directions—if they are lacking in process, then the team will create new process to assist it. But if the team has too much process, the team will recognize this and remove some of the less-effective processes. It's the feedback from the dev team every sprint (ie, every month or so) that keeps things from getting too far from an optimum state.

To make an analogy, the best way to drive a car down a freeway is to continually look out the windshield, see where you are, and based on that immediate, direct feedback, adjust course and speed. (This is analogous to the development team creating and removing process as they experience how everything is going.) On the other hand, imagine trying to drive a car blindfolded based on telephone instructions from someone who has driven down the same freeway a few years ago, and is watching your car from a nearby hill as you drive by. This is somewhat analogous to management creating process without being directly involved in the current design process. (I actually think this overstates the issues a bit, but it was the best analogy I could think of...) The feedback over the telephone may work, but the feedback is much less direct and timely than simply looking out the window and driving. To be effective, feedback needs to be timely and direct.

Consider the following hypothetical plot of the amount of productivity of a team as a function of amount of process. Just to be clear, it is not based on any measurements of productivity or process—I just made it up. It is just a general guess of what this curve might look like:

Hypothetical plot of productivity as a function of amount of process. On the left, too little process leads to low productivity due to chaos. At the right, too much process causes low productivity (due to not much work being done). In the middle is the optimal level of process. The productivity curve starts at zero, peaks at the optimal amount of process, and then declines in productivity with additional process.

The sketch attempts to communicate the following points:

  • If you have too little process (the far left side of the curve), your overall productivity declines—things become chaotic and error-prone, and less useful work gets done (and sometimes the work that does get done causes a lot of damage!) In the extreme, with no process (no planning, no guidance, no direction, etc), you don't get anything useful done because the work being done isn't the right work, so productivity is zero.
  • If you have too much process (the right side of the curve), your overall productivity declines—the team spends too much of its time doing process, which often does not add directly to productivity, especially beyond a certain point. In the extreme of infinite process, no real work is ever done, so productivity is zero.
  • For a given combination of project, team, situation, etc, there is an optimum amount of process where productivity is at a maximum—add more and productivity declines, but remove process and productivity also declines.

Given these assumptions, how do you optimize the amount of process? Feedback. The development team needs to be told what the priorities of the organization are, and then the team needs to be given the freedom to control the amount of process it uses. Usually management—especially if they are significantly removed from the development process—does not have as good an understanding as the team of what will really be useful process and what simply impedes development without adding much value.

To describe the feedback process in terms of the curve, when the team finds themselves in a chaotic and random environment, they will notice and, as part of the retrospective, create new process to assist in controlling the chaos. On the other hand, if the team notices that they are spending most of their time on process, they can remove the least-valuable of these processes and then see where they are. Eventually, after several sprints, the development team will hopefully be somewhere near the optimal point of the curve, and as the situation evolves from this point, they can continue to adjust to maintain the optimal position.

Some people might argue that the development team inherently doesn't like process and therefore will remove it regardless of whether it is useful or not. (It's only management that doesn't mind processes and therefore has the will to add them, because they will not be directly affected by them.) However, I've seen the opposite in many cases—for example, early in my current project, testing was very chaotic, because we had not defined much process around it. The team did not like this—it was chaotic and stressful for them. In the retrospectives, the team brought up that testing was chaotic and stressful, and the improvement they arrived at was more process. In addition, they defined the process—and it worked incredibly well. The process has since been fine-tuned and adjusted many times during subsequent retrospectives.

Will the team sometimes add too much process, or remove a valuable bit of process? Of course—but within a sprint or two, assuming there's a significant impact, they'll notice and correct. Constant correction via feedback is the key to optimizing the process. And Scrum includes the retrospective as a way of building feedback into the process at the most basic level.

One additional point that may not be obvious—in some cases, maximum productivity may not be the goal. For some organizations, reliability and stability or something else may be more important than pure productivity, but this is basically just a redefinition of what productivity is. (For most organizations reliability and stability are important, but so is the rate at which new features are added, so the definition of productivity needs to take balancing these various priorities into account.) The bottom line is that these priorities need to be communicated clearly to the development team—they are the ones who are steering the car down the freeway.

Retrospectives: a key part of the Scrum process

The retrospective is a key and often overlooked part of the Scrum process. I believe one reason for the success of my Scrum team in the past few years is related to our consistency in doing retrospectives at the end of each sprint.

I've seen other teams sometimes skip over retrospectives, for a variety of reasons:

  • Retrospectives don't seem that important
  • The team is too busy to take time to retrospect
  • They believe that doing retrospectives won't improve anything

Having done a lot of retrospectives, from my experience, the retrospective serves a number of purposes:

  • It provides a structured environment for the entire team to brainstorm ways to improve things
  • It helps the team to bond—they have a time specifically to discuss their feelings and experiences, and to listen to each other
  • It provides the team a sense of closure at the end of each iteration
  • It allows team members to voice grievances and annoyances in a supportive environment
  • Simply scheduling the time for the retrospective communicates to the team that their feelings and opinions are important and valued

The most obvious purpose of the retrospective is making improvements to the process. It may seem that making a few small process improvements each sprint won't really add up to much, but this has not been my experience. Although the individual improvements can seem very small, the cumulative effect can be quite surprising.

 

Thoughts and suggestions about retrospectives

(If you are unfamiliar with Scrum or the retrospective, I encourage you to read the excellent book Agile Software Development with SCRUM by Ken Schwaber and Mike Beedle. I strongly recommend this book—I think it is the best book I've seen about Scrum.)

First of all, I always refer to it as a “retrospective”, not a “postmortem” or anything else. Postmortem has the smell of death around it—I can understand people not wanting to go talk about how the iteration (and/or team?) “died” over the last few weeks. This word also implies a sense of hopelessness—the iteration or the team is dead and cannot be resurrected—instead we’ll just talk about how it died. On the other hand, the word “retrospective” gives the process a more hopeful tone—that you will look back in order to learn something that can make the process more pleasant going forward.

We start our retrospectives by making two lists on the whiteboard:

  • What we liked in the previous iteration
  • What we did not like in the previous iteration

We usually draw it with a plus sign at the top of the column for things we liked, and a minus sign at the top of the column for things we didn't like, for example:

Starting point for retrospective: a column for what we liked as a team (on the left with a plus sign), and a column for what we didn't like as a team (on the right with a minus sign) 

Note that the second list is NOT defined as a list of mistakes that we made in the last iteration! This may be a subtle point, but it's important--not many people enjoy going to a meeting where they have to confess their mistakes over the past month. The list consists of things that we (members of the team) did not like. This can include mistakes we made, but the scope is much larger than that.

Note that, as the ScrumMaster for the team, I try to encourage and write down items in both areas, without adding too many of my own, or doing any editing or censorship of items. For the most part I just write items down—I don’t want to hijack the meeting so that it ends up being all about me.

In addition, I don't try to make the two lists “balance out” or be equal in some way—this is not a zero-sum game. If we had an unpleasant iteration, it’s likely that we'll have more items on the minus side than the plus side—and that’s fine! On the other hand, a really smooth iteration it may be the other way around, and that’s fine too.

I do what I can to encourage everyone to be honest—for example, if there is an event I recall that people didn’t like but nobody is bringing up, I’ll ask about it. Honesty is important—the more honest everyone is, the better the whole thing works. Sometimes this means taking social risks—we’ve had several retrospectives with people getting frustrated or angry and saying things like “I didn’t like how Bob would criticize my code!” If people are feeling it, this is probably the best time to talk about it, and it certainly makes the process a lot more interesting! Not talking about it just means that it likely won't change. In my experience, most of these types of interpersonal team issues were greatly improved after being brought up in a retrospective, and this greatly added to the team moral and productivity.

When we start running out of items, we prioritize the top few items that we didn't like. The prioritization is based on the importance of improvement in that area to us as a team. Usually the top priority items are the biggest pain points of the iteration for the team, and fairly easy to agree upon. Again, as ScrumMaster, I usually leave my own opinions out of the prioritization—I’ll sometimes add a bit, but I really don't want to control the prioritization.

Finally, we take the top two or three priority items from the minus side, and brainstorm as a team how we could improve the situation going forward. In my experience it's important to not select more than 2 or 3 items to improve, because they tend to be too many and some get forgotten, which makes the whole process seem pointless and frustrating.

It’s during the brainstorming about possible improvements where the real magic happens—the team is smarter as a whole than any individuals on the team. Issues that at first seem impossible to improve (items that you seem to just be stuck with) can often be improved in some way when the whole team focuses on them. Note that this means it often makes sense to spend some brainstorming improvements time on a painful item that everyone initially believes they cannot change. It is only in the brainstorming that the possibilities emerge. These improvements may not resolve it entirely but improve things incrementally—the tricky bit is that these possibilities can be difficult to see in advance. In my experience, the improvements sometimes involve more communication with someone (the product owner, users, someone on the team, etc), more training, new procedures, different tools, or a technical task for the next iteration to improve something. But there are no limits to the types of improvements you can brainstorm into existence.

And, as I said above, it’s important to follow through with the improvements—otherwise it undercuts the whole process.

In summary, if you are using Scrum but skipping retrospectives, I encourage you to try doing retrospectives seriously and consistently! From my experience, it may improve your team’s productivity and moral.

LINQ and n-tier architecture: choices, choices, choices...

One question when architecting an n-tier application using LINQ to SQL or LINQ to Entities is how far to commit to using LINQ. In other words, how deeply should you let the database LINQ technologies permeate the layers of the application. I've seen two general approaches:

  1. Commit fully to LINQ, and have the entire application use the objects that are being tracked for changes by the DataContext or ObjectContext. If you're using stateful model objects with stateless layers, this conceptually looks something like this:

    N-tier application with LINQ objects used in all layers

  2. Commit partially to LINQ, and have the business and presentation layers of the application use non-tracked objects. Confine LINQ to SQL or LINQ to Entities to the data access layer (DAL) only. This means you have two sets of objects: one for the data access layer, and another set for the other layers:

    N-tier application using LINQ objects in the data access layer, and another set of objects in the other layers

There are several reasons to commit fully (option 1 above):

  • You get a lot in return: objects are automatically tracked by the context for changes, and then all changes can be saved with only a single method call.
  • The context automatically ensures that you don't accidentally load two instances of the same object. (If you do, it quietly hands you another reference to the original object in memory.)
  • This is also less code than option 2, as you only have one set of stateful objects, and you don't need to write code to go back and forth between the LINQ and non-LINQ objects.

Some reasons to not commit fully to LINQ (option 2 above) include:

  • It makes it much easier to remove LINQ later--it's confined to the DAL, and there are no LINQ dependencies in the business or presentation layers.
  • Committing fully to LINQ (option 1) makes the n-tier architecture a bit less clean--for example, any lazy loading that happens in the business logic can be considered data access logic that has escaped from the DAL. By confining LINQ objects to the data access layer (option 2), there won't be any LINQ objects to cause lazy loading in the business layer or presentation layer.
  • If you are using LINQ to SQL, then it allows the business and presentation layers to use objects that are not identical in structure to the database tables. (This is more of a reason to use LINQ to Entities than to not commit fully to LINQ.)
  • Due to the way LINQ to SQL is designed, it can be difficult to use in an n-tier architecture. For example, it's not currently possible to set the DataLoadOptions after the DataContext has been used to return data. One possibility is to forgo using DataLoadOptions entirely, but it depends on the application if that's a viable option. Another option is to organize the DataLoadOptions by page, and set the DataLoadOptions specific to a given page in the OnInit event handler of the page. However, these are a bit strange.

Choices, choices--what to do? Here are my thoughts/guidelines:

  • If the application is fairly complex, tend toward option #1 (commit fully to LINQ to SQL/LINQ to Entities). By complex, I mean that you have object graphs with collections and/or many objects. In this case, the object change tracking from LINQ is great when you are adding, removing, and altering objects, and saves a huge amount of effort--enough to make it easily worth committing to LINQ fully.
  • On the other hand, if you generally are working with a single object or a very few objects at a time in the code, object change tracking is much less valuable--you know which objects you've changed in this type of code. In this case, option #2 becomes less unattractive.
  • Generally, tend toward LINQ to Entities (and the Entity Framework) rather than LINQ to SQL. There are many benefits to LINQ to Entities over LINQ to SQL, including the fact that it fits into an n-tier architecture more easily.

Personally, I like option #1--you get a lot of benefit from going "all in" with LINQ. And I enthusiastically suggest using LINQ to Entities rather than LINQ to SQL--you get a lot more flexibility.

Note that, if you are converting an existing application to use LINQ, it might make sense to restrict the LINQ objects to the data access layer if it simplifies the conversion. (This will of course vary depending on the existing application's architecture.)

Using invalid addresses to avoid accidental emailing, a.k.a. "the Outlook oops!"

I use Microsoft Office Outlook 2007 as my email client program. As part of my project management duties, I send a lot of emails. For the most part I really like Outlook, but I have had one issue: occasionally I have sent emails accidentally while I was still in the process of composing them.

The keyboard shortcut for sending an email is Alt-S:

Outlook email window (Alt-S is the shortcut for Send)

Part of the problem is that the keyboard shortcut for snoozing a reminder is also Alt-S:

Outlook reminder dialog (Alt-S is the shortcut for Snooze)

Other ways of accidentally sending emails are:

  • Saving an email is Ctrl-S--accidentally pressing Alt rather than Ctrl will send it
  • Ctrl-Enter can send the email (if it's configured that way)
  • Clicking Send on the wrong email window
  • Other random mistakes

Several years ago I was rushing to finish an email to a client in the minutes before a conference call with them, and the reminder for the meeting popped up. I instinctively pressed Alt-S to snooze it, but as it was popping up, I had been Alt-tabbing between applications, and my email message window ended up with the focus. The email window immediately vanished--it took me a second to realize I'd just sent my incomplete email. Fortunately, I reviewed the email and it actually made sense and was reasonably complete.

After this, I thought a bit about how to avoid this in the future. A solution I came up with is to enter something into the To or CC line of the email that Outlook can determine isn't a valid email address. Since Outlook can figure out it isn't a valid email address, it will refuse to send. At my company, I use "xxx" as the invalid address:

Incomplete email with the "xxx" invalid address

If I accidentally press Alt-S (or click Send for that matter) the email is not sent, and I get the Check Names dialog instead:

Outlook Check Names dialog: "Microsoft Office Outlook does not recognize 'xxx'."

This is my emailing safety net--I can have a number of emails I'm in the process of composing, and I'm not at risk of accidentally sending any of them. This has saved me from "premature emailing" several times.

Note that this only works if the invalid address is not a valid email, and not something that Outlook is able to auto-complete into a valid email! For example, if I just used a single "x", we have an email list at my company that starts with an x, and Outlook will automatically complete it and send it. To test an invalid address, open a blank email, type in the invalid address, and click Check Names. If it resolves, it's not usable for blocking. If you get the Check Names dialog above, it works.

Once you are ready to send the email, just delete the invalid address and press Alt-S.

The only trick to this is to get into the habit of adding the "xxx" to the email when you start composing it.

Configuration of IE Trusted Sites in Windows Vista

In my work, I commonly use an internal SharePoint web site that is exposed to the internet. This site uses Windows Integrated authentication, which is really handy, as it means I generally don't need to type my user name and password repeatedly, which is great!

When I switched to Vista, I noticed that I always had to type my username and password--I'm guessing that this has to do with the fact that I access the SharePoint site using its external URL, so IE can't tell that it's really an internal site. (I had also had to do some configuration on Windows XP to get that working correctly.) One way to solve this is to add the site to the list of IE trusted sites, and tell IE to automatically send your user name and password. In case you're having the same issue, here are the steps to configure a trusted site to automatically authenticate.

First, navigate to the site you wish to trust. Next, open the Internet Options dialog in Internet Explorer (click Tools, then click Internet Options.)

Internet Options dialog from IE 7

Click Security to display the security tab, and then click the Trusted sites zone:

Security tab of Internet Options dialog, with the Trusted sites zone selected

Next click the Sites button to display the Trusted sites dialog:

Trusted sites dialog

(Note that you had to navigate to the site you want to trust first.) Click Add to add the site, and make sure that the checkbox to require server verification is checked. Click Close.

At this point, you've added the trusted site, but it will likely still require you to enter your credentials on each visit. To change this, click the Custom level... button on the Security tab to configure the security settings for the trusted sites zone:

Security Settings - Trusted Sites Zone dialog

Now scroll down to the bottom of the settings list, and change the setting for User Authentication to Automatic login with current user name and password:

Security Settings - Trusted Sites Zone dialog with User Authentication set to "Automatic logon with current user name and password"

Now click OK, and then OK to save the settings.

Interestingly, when I tried this, I had one issue--I could not navigate to my trusted site reliably. Often the browser would seem to get stuck while downloading the content, and IE would just "sit and spin". (Occasionally it seemed to work okay--it was just really slow in those cases.) Someone suggested that I try deleting my browsing history (I used the Delete all... option) and that worked! For some reason, having old cached data confused IE--not quite sure why, but it works fine now!

In a partially related note, the IE 7 authentication dialog in Vista can be a bit tricky:

Connect to... dialog from IE, with ineffective "Remember my password" checkbox

There's a Remember my password checkbox in the dialog, but it doesn't appear to do anything. If you check it and then enter your user name and password, the next time you visit the site, it will just ask again. This is Paul Thurrott's favorite IE inconsistency (search for "remember my" on the linked page.) According to Paul, Microsoft says that this is by design. Perhaps that's true, but if so, I really don't understand why they left the checkbox there--it seems like some sort of strange UI decoy.

Sonicare Battery Recycling Challenge

I recently was doing some cleaning-up around the house, and needed to get rid of an old Sonicare electric toothbrush that had provided many years of distinguished service. As it has rechargeable batteries with hazardous materials, you should certainly not simply throw it away.

After looking on the web, the manufacturer described what sounded like a very simple process. Here's the (somewhat optimistic) quote from their website:

If you wish to personally recycle your Sonicare toothbrush handle at the end of its life, insert a flat-head screwdriver in a slot between the 2 halves of the handle at the threaded end, and then break apart the 2 halves. Remove the batteries from the inside of the handle and dispose of them properly in accordance with your local recycling program.

It sounded quite easy and a bit fun, so I decided to do it myself. The plastic in the handle was very old and brittle--after doing some prying, it started to break off in little bits, rather than splitting the entire handle in half. As more bits came off, it became harder and harder to find anywhere to pry it apart.

After about twenty minutes of prying, all the plastic I could pry apart had come off in bits, and I had no way to make progress with more prying. Feeling a tad frustrated and misled, I decided to get a mallet and some safety glasses and give it a good wacking so see if that would "free it up".

After several solid hits, the handle did indeed come apart in half, but at this point it became clear that the batteries were epoxied in place--it was not a simple matter of "removing the batteries" as the manufacturer had described. After a bit of snipping of leads to remove a circuit board that was in the way, I figured that I'd had enough success with the mallet that I should continue using it as my "precision instrument of choice". Within a few minutes, I had smashed the circuit boards and most of the case. Unfortunately, I had also demonstrated that the epoxy was pretty strong stuff--I had smashed nearly everything else, but a small amount of the plastic case was still firmly epoxied to the batteries. Here are a few photos I took:

Top view of batteries and a bit of the case  

Side view of case with batteries beneath. The green stuff between the case and batteries is the epoxy.         Another view of the batteries, with the case on the right. The green between is the epoxy.  

As you can see, very little of the case remained, but it was firmly attached to the batteries. (The green stuff between the batteries and the case is the wonder epoxy.) Note that the repeated blows from the mallet had also destroyed part of the battery casing.

At this point, I "declared" victory and decided that this entire chunk was good enough to recycle. And I had indeed had some fun. But in general, unless you're up for a bit of a challenge, I'd encourage you to take Phillips up on their offer and have them recycle it for you. And be sure to wear safety glasses if you do it yourself and end up resorting to the mallet!

Using WinMerge with Microsoft Team System

I like Microsoft's Team System for source control--I especially love the shelving functionality, that has gotten my agile team out of some complex little workflow tangles. However, I'm not such a fan of some of the client-side tools.

One of my least favorite tools in Team System is the diff tool. The things I really dislike about it are:

  • It won't show me the specific differences in a long line--it simply highlights the entire line. This is surprisingly annoying for long lines of code where you know something is different because the line is highlighted (and therefore the tool knows what the difference is but won't tell me!) Given this, you have little choice but to visually scan each version of the line character by character to try to notice differences--and hope you don't miss anything! Forgive me, but isn't this what the diff tool was supposed to do?!
  • You cannot change the font size. Given that the split-pane display effectively divides the monitor into two halves, I'd really like to use a smaller font size to allow more text to be visible in the panes, but this isn't possible, which is a surprising limitation.

Here's a sample screenshot of the diff tool from Team System exhibiting these issues:

Standard diff tool from Team System, with large font and no diffs inside a line

Note that on line 307, it's not immediately clear what has changed in the method signature: partially because only the line is highlighted, and partially because the font is so large that the whole line cannot be seen without horizontal scrolling.

Given these issues, I looked into other diff tools. To its credit, Team System is fully extensible in terms of merge and diff tools. James Manning of Microsoft has a great post describing how to configure Team System with a different merge or diff tool. Another nice touch is that you can independently configure the diff and merge tools--I haven't found a better merge tool yet, but I do like WinMerge better for diff. (One of my criteria is perhaps a bit unfair, but I wanted something that was no cost to use.) Since I diff much more frequently than merging, a better diff tool is a clear win for me.

Specifically, the things I like about WinMerge are:

  • It highlights the differences within the line rather than the whole line--this makes looking at diffs much easier, because the tool is actually doing much more of the work.
  • It has a cool "Diff Pane" at the bottom of the window that displays a full-width version of the currently selected difference block--again, this makes things so much faster than having to horizontally scroll back and forth for each change.
  • I can change the font to something a bit smaller to fit more code on the monitor (it's the little things sometimes!)

Here is the same diff as above in WinMerge:

WinMerge diff tool, with smaller font, diffs within a line, and handy full-window-width Diff Pane

Note that the Diff Pane at the bottom allows you to see the currently highlighted difference at the full window width--I cannot say how useful this is in everyday work. In addition, notice that the coloring in the Diff Pane makes it very clear that the only part of the line that changed was the method visibility (private changed to public.) Again, this makes it much less likely that you miss some other change, and it saves a lot of mental work to manually diff the characters yourself.

 

Configuration

So how do you configure it? It's fairly well explained in the blog post above, but here are some screenshots of how I set mine up. In Visual Studio 2005, first click Tools, then Options to bring up the Options dialog:

Visual Studio 2005 Options dialog, showing Source Control: Visual Studio Team Foundation Server property page

On the tree control on the left, expand Source Control, and then click Visual Studio Team Foundation Server. Click Configure User Tools... to display the Configure User Tools dialog:

Configure User Tools dialog without any rows (default setting to use Team System diff and merge tools)

As the Team System tools are the default, nothing is shown in this dialog. Click Add... to display the Configure Tool dialog to add a custom tool mapping:

Configure Tool dialog (initial unpopulated state)

Fill this out for WinMerge according to the post above. It should look something like this when complete:

Configure Tool dialog populated with WinMerge configuration

Click OK, and the Configure User Tools dialog will now show that WinMerge is configured for Comparison (diffs):

Configure User Tools dialog with WinMerge configured to diff

Click OK, and then OK to complete the setup.

Note that the blog post above includes a long list of both merge and diff tools--you may want to do a bit of experimenting to see what works best. Note that a certain amount of caution should be exercised, especially with the merge tool, as an unfamiliar merge tool could be used incorrectly and create a lot of chaos!

Digital SLR cameras and Sensor Dust: A Quick Summary

What's the issue?

Digital SLR cameras allow many advantages over less sophisticated cameras--they allow different lenses to be used, they are much faster, work much better in low light, and offer much more control over the details of photography. However, as the lenses are removable, dust can get inside the camera and get onto the sensor, causing spots to appear on the images under certain conditions.

First of all, this issue only affects you if you shoot with small aperture (ie, large f number)—smaller than f/9 or f/11 or so. At larger apertures (like f/3 or so), the aperture is large enough that light is entering at a wide enough range of angles that it can go around the dust on the sensor and not leave a clear mark. Only at small apertures does the light become collimated enough that it casts a clear shadow on the sensor.

Do I have an issue?

If you want to see if you have a dust issue, set for the smallest aperture you can (likely f/22), and take a picture of the blue sky or white paper. Likely take a couple of pictures—if you use white paper, you might not want to focus. Look at the images at 100% on the computer--if you have sensor dust, you will see dots or specks in the image from the sensor dust. Use auto-levels in Photoshop to make the spots more visible if necessary.

How to prevent it?

Limit lens changes, especially in dusty conditions. (Apparently it's dustier outside than inside usually.) Get a good-quality hand-blower, and blow out the sensor chamber and the lens end each lens change. Keep everything clean.

Note that the cameras themselves create dust internally when the shutter operates and the mirror moves. Unfortunately, my understanding is that the sensor develops a static electrical charge during operation, so any dust in the sensor chamber will quickly be sucked onto the sensor.

In addition, it really isn’t an issue if you shoot with large apertures. I rarely (if ever) shoot with small apertures—usually the smallest I go is around f/6 or so.

I've heard that cameras usually come from the factory with a dusty sensor.

How to clean the sensor?

There are a bunch of ways to do this:

  • Blow off the sensor with a hand blower: there should be instructions for this in the camera manual. You need to activate a special mode where the sensor is exposed, and then blow dust off it with the hand blower. Don’t use compressed air from a can—it’s too strong and can contain chemical residue. This is the only officially approved Canon way to clean the sensor yourself. When I do it, I usually orient the camera facing downwards so that gravity is on my side in helping to get the dust out of the chamber, rather than just moving it around in the chamber. One warning: don’t expose the sensor to strong light (aka sunlight) when it’s in cleaning mode—it will be damaged.
  • Send it in for cleaning by the manufacturer: this costs $25 to $100, can take many weeks, and sometimes the camera is returned with the same number of dust spots, just with them moved around. My understanding is that Canon uses a Kimwipe (a special lint-free tissue) and alchohol and wipes off the sensor.
  • Buy sensor cleaning supplies and use them to clean your sensor yourself. This is a bit expensive, and a bit risky—all sorts of bad things can happen to your sensor. See http://www.visibledust.com/ for some examples of products. You can either clean dry or wet—dry is supposed to be a bit safer, but apparently some dirt only comes off with wet.
  • Use a certain type of Scotch tape to clean the sensor—apparently you stick the tape to the sensor and peel it off. Some people swear by this approach, but I thought it was a joke when I first heard it.
  • There are also other ways, many of them risky.

Note also that many of the newest DSLR cameras have self-cleaning modes which are very helpful but apparently may not completely eliminate the need for sensor cleaning.

What did I do?

I try to not change lens often, shoot with large aperture, and mainly not worry about it too much. You can always PhotoShop the dirt out of photos, but it’s time consuming.

If you’re interested in more general details, I’d suggest you do an online search for something like "sensor dust" or "sensor cleaning" and see what you find. But I warn you, there’s lot of conflicting and frightening information out there—it can become a bit of a perverse hobby if you aren’t careful!

Amusing Outlook 2007 Message

I got this message the other day when trying to dismiss an Outlook calendar reminder:

Outlook dialog: "Cannot turn off the reminder. You may be reminded again. Could not open the item. Try again."

I'm not sure quite what I find funny about this, but here are some reasons:

  • The four sentences are very short and staccato.
  • It has an almost desperate quality--especially the "You may be reminded again" part. (Oh goodness--not only did it not work, but I might actually be reminded again!)
  • It adds "Could not open the item." which must be something it needs to do internally before it can turn off the reminder, but conveys no useful information to me as a user.
  • I like that after all this, it hopefully adds "Try again."

Just to be clear, I've written (and continue to write) my fair share of wacky dialog messages. I usually end up writing something like this when I'm almost positive that it will never actually happen, and therefore don't need to spend a lot of time polishing the content. Writing this type of failure message can be a bit difficult and time consuming to do well. However, when one of these pops up, it's pretty amusing!

1 - 10 Next

 ‭(Hidden)‬ Admin Links