понедельник, 11 декабря 2017 г.

Fixing the 'repository has at least one unnamed head' error when converting a Mercurial repository to Git

I was following the "Migrating to Git" instructions and run into an issue while converting our Mercurial repository. The fast-export script displayed the message: "Error: repository has at least one unnamed head: hg r3419".

My first move was to check the revision 3419. The revision was a 'close branch' commit on a named branch. Nothing special and that was confusing.

It took me a while to realize: the error means there is a branch with more than one head. Now it seems pretty obvious :)

The following command produced me a list of branches along with the number of heads:

hg heads -c | grep branch: | uniq -c | sort

It turned out, there was an old, closed branch with two heads. Each head was closed with a separate commit. The solution was to merge these heads and close the branch once again.

I hope this post might help in case someone else runs into this issue.

среда, 19 декабря 2012 г.

Mercurial: an incident with "hg pull --rebase"

Our team uses Mercurial. Some time ago we started using rebase instead of merges to have clean linear timeline. The rebase approach seemed to be straightforward and almost automatic. But recently we run into an issue: a code from the development branch leaked into the stable branch, the branch that is indended for bugfixes only.

Below is a reconstruction of the incident. While it might appear to be a lot of text, it is actually just a couple of commits, so please don't be scared and read on.

Consider a team of two developers - Leo and Penny - working on a product. The product's repository has two branches: 'default' and 'stable'. New features are being developed on the 'default' branch. Bugs are fixed on the 'stable' branch. From time to time the 'stable' branch is merged back into the 'default'.


hg init repo
cd repo
@echo > product.cs
hg add
hg commit -u leo -m "initial version"
hg branch stable
hg commit -u leo -m "creating 'stable' branch"





1. Leo fixes a bug and pushes his changes:

hg clone repo repo-leo
cd repo-leo
hg up stable
@echo > bugfix-01.cs
hg add
hg commit -u leo -m "fixed: bug-01"
hg push

2. Penny fixes a bug and merges the 'stable' into the 'default':

hg clone repo repo-penny
cd repo-penny
hg up stable
@echo > bugfix-02.cs
hg add
hg commit -u penny -m "fixed: bug-02"
hg up default
hg merge stable
hg commit -u penny -m "merged bugfixes into the default branch"


3. Penny writes a new feature:

hg up default
@echo > new-feature.cs
hg add
hg commit -u penny -m "new cool feature"


Penny's repository: bug fixed, feature implemented.

4. Now Penny wants to push her changes:

hg push
pushing to C:\Temp\repo
searching for changes
abort: push creates new remote head 4fa702a0c723 on branch 'stable'!
(you should pull and merge or use push -f to force)

But the server aborts the push. Penny understands that someone has already pushed changes, so she does a regular routine: pull --rebase

hg up stable
hg pull --rebase

Damage is done!

Penny's repository before rebase

Penny's repository after rebase. A code from the development branch is now on the stable branch.
Look at the screenshots illustrating Penny's repository before and after rebase. Notice the "new cool feature" changeset that should be on the development branch. Now it is on the branch 'stable' and that should have never happen...

(to be continued)








среда, 12 января 2011 г.

WPF - create DataTemplate from FrameworkElement

Yet another code snippet for future reference.
I'm not quite sure if it works in all cases, but it does work for Canvas.


        DataTemplate GetElementAsTemplate(FrameworkElement element) {
            StringBuilder builder = new StringBuilder();
            builder.AppendFormat(
                "{0}",
                XamlWriter.Save(element));

            using(MemoryStream stream = new MemoryStream()) {
                using(StreamWriter writer = new StreamWriter(stream)) {
                    writer.Write(builder.ToString());
                    writer.Flush();

                    stream.Position = 0;
                    DataTemplate template = (DataTemplate)XamlReader.Load(stream);
                    return template;
                }
            }
        }

воскресенье, 14 ноября 2010 г.

Client HTTP Stack: HttpWebRequest and non-ASCII characters in HTTP response headers

Client HTTP Stack in Silverlight seems to bee too strict sometimes. I have an OOB application that uses HttpWebRequest object to get data from external web service.

Unfortunately, HTTP response from the service includes header that contains non-ASCII characters. And it turns out to be a problem. See code snippet below:

void GetResponseCallback(IAsyncResult ar) {
    HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
    WebResponse response = request.EndGetResponse(ar);
    // code continues …
}

EndGetResponse() call results in System.ArgumentException: Specified value has invalid Control characters. Parameter name: value.

I’m not sure whether it is a bug or designed behaviour. But it’s a pity that invalid header prevents application from obtaining response at all. In fact I don’t even need that header, so my workaround was to switch to browser http handling so that I can move on.

And just for the record: the same code works fine in WPF application.

среда, 10 ноября 2010 г.

Silverlight OOB applications and HTTP handling

With Silverlight, you can specify whether the browser or the client provides HTTP handling for your Silverlight-based applications. By default, HTTP handling is performed by the browser and you must opt-in to client HTTP handling.

Surprisingly, despite of what your intuition might suggest, Silverlight out of browser applications use browser HTTP handling by default. At least for WCF service calls :)

вторник, 22 июня 2010 г.

WinDbg: dumping the target object of a WeakReference

The following example demonstrates how to dump the target object of a WeakReference.

1. Find WeakReference’s object address. In my example it is 0bb9a878.

2. Use !dumpobj to print content of the WeakReference:

0:025> !dumpobj 0bb9a878
Name:        System.WeakReference
MethodTable: 5ec0d7ec
EEClass:     5e7eacd8
Size:        16(0x10) bytes
File:        C:\Program Files\Microsoft Silverlight\4.0.50524.0\mscorlib.dll
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
5ec0c5a0  4000522        4        System.IntPtr  1 instance  7631528 m_handle
5ec007e4  4000523        8       System.Boolean  1 instance        0 m_IsLongReference

3. The m_handle member is a pointer to the target object. The member is value type (System.IntPtr), so we use !dumpvc command to print its content:

0:025> !dumpvc 5ec0c5a0 7631528
Name:        System.IntPtr
MethodTable: 5ec0c5a0
EEClass:     5e7e9f00
Size:        12(0xc) bytes
File:        C:\Program Files\Microsoft Silverlight\4.0.50524.0\mscorlib.dll
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
5ec0d720  4000353        0                  PTR  0 instance 0bb9a86c m_value
5ec0c5a0  4000354      50c        System.IntPtr  1   shared   static Zero
    >> Domain:Value  0b670f20:NotInit  0b675a40:NotInit  <<

4. The address of the target object is 0bb9a86c. Now we can use !dumpobj command to print it:

0:025> !dumpobj 0bb9a86c
Name:        HelloSl.FooBar
MethodTable: 07625428
EEClass:     07621cd8
Size:        12(0xc) bytes
File:        HelloSl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Fields:
None

среда, 16 июня 2010 г.

Debugging Silverlight 4 application with Visual Studio 2010 and Google Chrome

Debugging Silverlight application on a system with Google Chrome installed as default browser, I run into an issue: breakpoints were not hit. I got the message: “The breakpoint will not currently be hit. No symbols have been loaded for this document”.

BreakpointWillNotBeHit

What happens? It looks like Visual Studio 2010 doesn’t play well with Chrome browser.

When Silverlight application is started for debugging, Visual Studio launches web browser and attaches debugger to it. Chrome runs in multiple processes (process per tab?) and most of the time Visual Studio attaches debugger to the wrong process, the process that doesn’t host Silverlight application. That’s why symbols are not loaded and breakpoints are disabled.

The only workaround I know at the moment is to manually attach the debugger to correct chrome.exe process, the one that hosts the application being debugged.

Step-by-step illustration.

1. Create Silverlight application, start debugging.

Processes

Notice that the debugger is attached to the chrome.exe with PID=4132 and breakpoint is disabled.

2. At the same time Process Explorer displays that there are two another chrome.exe processes running: 5816 and 3876.

ProcessExplorer 

3. In Visual Studio open “Attach to Process” dialog:

ManualAttachTo

Notice that chrome.exe process with PID=3876 has “Silverlight” in the “Type” column. Select it and press “Attach” button.

Voila: debugger output prints “'chrome.exe' (Silverlight): Loaded 'AgDemo', Symbols loaded.”, and breakpoints are resolved.

Sure, manually attaching debugger is not convenient. This is just a workaround – I’m looking forward for better solution.

DispatcherTimer memory leak in Silverlight 4

A colleague of mine found what seems to be a bug in Silverlight 4. Once started, DispatcherTimer object is never garbage collected. The following code snippet demonstrates the issue:

public partial class MainPage : UserControl {
    public MainPage() {
        InitializeComponent();
    }
 
    private void start_Click(object sender, RoutedEventArgs e) {
        DispatcherTimer timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Tick += timer_Tick;
        timer.Start();
    }
 
    void timer_Tick(object sender, EventArgs e) {
        DispatcherTimer timer = (DispatcherTimer)sender;
        timer.Stop();
        timer.Tick -= timer_Tick;
    }
}
 
Start application, attach WinDbg. Initially there is no DispatcherTimer object instances:

0:028> !dumpheap -type DispatcherTimer
Address       MT     Size
total 0 objects
Statistics:
      MT    Count    TotalSize Class Name
Total 0 objects

Then click “Start” button. Wait a couple of seconds – the timer object fires, stops and unsubscribes from event handler. Now break into the debugger once again:

0:003> !dumpheap -type DispatcherTimer
Address       MT     Size
08ff5df8 629c4ba0       20    
total 0 objects
Statistics:
      MT    Count    TotalSize Class Name
629c4ba0        1           20 System.Windows.Threading.DispatcherTimer
Total 1 objects
0:003> !gcroot -nostacks 08ff5df8
DOMAIN(07F1AE30):HANDLE(Pinned):43b12f8:Root:  09f74260(System.Object[])->
  08fa5f64(System.Collections.Generic.Dictionary`2[[System.IntPtr, mscorlib],[System.Object, mscorlib]])->
  08feafc4(System.Collections.Generic.Dictionary`2+Entry[[System.IntPtr, mscorlib],[System.Object, mscorlib]][])->
  08ff5df8(System.Windows.Threading.DispatcherTimer)

As you can see, the timer object is “rooted” in Dictionary entry and it will prevent it from being garbage collected.

среда, 9 июня 2010 г.

WCF Message Logging

Quick entry for future reference.

Incorporating WCF into apps requires learning new debugging techniques. 404 errors occur when almost anything goes wrong, which can make debugging a guessing game. You have tools at your disposal, but they're new and they require some time and experimentation.


The most important tool is service tracing. There are two parts of service tracing: setting up the trace and reading the trace result. You define your tracing request in web.config. You can change web.config directly, but this offers little help, validation or support. To make these edits easier, open web.config in the Service Configuration Editor. The graphical interface includes configuration-specific help for common tasks. The summary page under the diagnostics tab lets you set common values, including turning on tracing and logging, and specifying the file for trace output.
 
Full article: Adding WCF Services to Silverlight
 
See also:
http://rsdn.ru/forum/dotnet/3792395.1.aspx
http://msdn.microsoft.com/en-us/library/ms730064.aspx

среда, 17 марта 2010 г.

Hosting WCF in IIS 7.5: HTTP Error 404.17 - Not Found

Another quick entry. I’m hosting WCF service in IIS 7.5 (Windows 7 x32) and getting the following error:

HTTP Error 404.17 - Not Found
The requested content appears to be script and will not be served by the static file handler.

Found solution in this thread: it looks like the script maps for the .svc extension are not registered. To register the script maps run the following command:

%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe -i

вторник, 9 марта 2010 г.

What I really hate about Silverlight

Silverlight is feature incomplete, but I can live with what’s available. Some features are incompatible with WPF counterparts, but I can workaround incompatibilities. What I really hate about Silverlight is the way it reports runtime errors.

Example. Debugging custom templated control I got the following message:

Error: Unhandled Error in Silverlight Application
Code: 2012   
Category: ParserError      
Message: Unknown attribute Text on element TextBlock.    
File:     
Line: 2    
Position: 41

The message is confusing to say the least (unless I miss something, Text attribute is perfectly valid on a TextBlock element). And I had to use trial and error method just to find out silly mistake: there was a TemplateBinding to CLR-property in a control template. I should have declared that property as DependencyProperty. What a waste of time :(

пятница, 26 февраля 2010 г.

WCF services asynchronously in Silverlight without generated proxy

Just found a very interesting post by Ayende Rahien on using WCF services asynchronously without generated proxies. And Mark J. Miller in his blog shows how to use the approach in Silverlight application.

воскресенье, 14 февраля 2010 г.

Binding to custom attached property

This is a quick post on an interesting binding issue I came across the other day.

In most cases it is possible to omit the name of the Path parameter in the binding markup. But if you binding to a custom attached property, you may encounter a problem. See the code snippet below:

<Window
x:Class="BindingIssueDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BindingIssueDemo"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<TextBlock DockPanel.Dock="Top"
Text="{Binding (DockPanel.Dock), RelativeSource={RelativeSource Self}}" />
<TextBlock local:CustomProperties.Description="Custom attached property"
Text="{Binding (local:CustomProperties.Description), RelativeSource={RelativeSource Self}}" />
</DockPanel>
</Window>

When you run the program, only the first TextBlock has text, the second one remains empty. And debugger output window prints the following error message:
System.Windows.Data Error: 39 : BindingExpression path error: '(local:CustomProperties.Description)' property not found on 'object' ''TextBlock' (Name='')'. BindingExpression:Path=(local:CustomProperties.Description); DataItem='TextBlock' (Name=''); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
I Googled a bit and found that the problem occurs when binding to attached properties in a non-default XML namespace. To workaround the issue you have to explicitly specify Path= in binding markup:
 
<TextBlock local:CustomProperties.Description="Custom attached property"
Text="{Binding Path=(local:CustomProperties.Description), RelativeSource={RelativeSource Self}}" />
 
Seems like this issue has been fixed in Visual Studio 2010 RC / .NET 4.0.

воскресенье, 7 февраля 2010 г.

DXPrinting: using DataTemplateSelector with SimpleLink

Printing data with a SimpleLink is straightforward: define a DataTemplate that represents a data item layout, specify the number of items and call the CreateDocument method.

But what if your data consists of objects of different types? How do you print them when each type has its own layout? This is where DataTemplateSelector comes to help.

Consider that we have a collection of CalendarEntry objects:

CalendarEntryClassHierarchy
Let's start with creating a DataTemplate for each calendar entry type. To keep things simple, I'm using a very simple layout:

<DataTemplate x:Key="anniversary">
  <Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Margin="0,0,0,5" Background="LightBlue">
    <StackPanel Margin="5">
      <TextBlock Text="{Binding Date, StringFormat='Date: {0}'}" />
      <TextBlock Text="{Binding Occasion, StringFormat='Occasion: {0}'}" />
    </StackPanel>
  </Border>
</DataTemplate>
<DataTemplate x:Key="todo">
  <Border BorderBrush="Black" BorderThickness="1" CornerRadius="0" Margin="0,0,0,5" Background="LightGray">
    <StackPanel Margin="5">
      <TextBlock Text="{Binding DueDate, StringFormat='Due Date: {0}'}" />
      <TextBlock Text="{Binding Subject, StringFormat='Subject: {0}'}" />
    </StackPanel>
  </Border>
</DataTemplate>
<DataTemplate x:Key="meeting">
  <Border BorderBrush="Black" BorderThickness="1" CornerRadius="0" Margin="0,0,0,5" Background="LightGreen">
    <StackPanel Margin="5">
      <TextBlock Text="{Binding Subject, StringFormat='Subject: {0}'}" />
      <TextBlock Text="{Binding Location, StringFormat='Location: {0}'}" />
      <TextBlock Text="{Binding Start, StringFormat='Start: {0}'}" />
      <TextBlock Text="{Binding End, StringFormat='End: {0}'}" />
    </StackPanel>
  </Border>
</DataTemplate>

Now when we have our data templates, let's create a data template selector. Instead of writing an ad-hoc selector simply for this example, I've built a reusable DetailTemplateSelector class. It provides the Type and DataTemplate properties, which allows you to configure it as follows:

<local:DetailTemplateSelector x:Key="calendarEntryTemplateSelector">
  <local:DetailTemplateSelector.Templates>
    <DataTemplate x:Key="{x:Type local:ToDoNote}">
      <!-- ToDoNote template definition -->
    </DataTemplate>
    <DataTemplate x:Key="{x:Type local:Anniversary}">
      <!-- Anniversary template definition -->
    </DataTemplate>
    <DataTemplate x:Key="{x:Type local:Meeting}">
      <!-- Meeting template definition -->
    </DataTemplate>
  </local:DetailTemplateSelector.Templates>
</local:DetailTemplateSelector>

And now the final trick: the SimpleLink class doesn't have any property to set a data template selector. We use a workaround: our detail template is a ContentPresenter and its ContentTemplateSelector property is set to the DetailTemplateSelector object:

<DataTemplate x:Key="calendarEntry">
  <ContentPresenter ContentTemplateSelector="{StaticResource calendarEntryTemplateSelector}" />
</DataTemplate>

Now we can use a link to build a document and show its print preview:

UsingDataTemplateSelectorWithSimpleLink

Easy enough, isn’t it?

среда, 20 января 2010 г.

Получаем PropertyDescriptor: использование выражений вместо строк с именами свойств

Есть у нас несколько тестов, в которых создаются PropertyDescriptor для свойств объекта. Выглядело это так:

   1: [Test]
   2: public void SomeTest() {
   3:     FooBar foo = new FooBar() { SimpleString };
   4:     PropertyDescriptor property = TypeDescriptor.GetProperties(foo)["SimpleString"];
   5:     // code continues ...
   6: }

Кодировать имена свойств в строковые константы - как-то не айс. Вдохновленный использованием expressions в moq, asp.net mvc и других фреймворках, я добавил вспомогательный метод FooBar.GetProperty:

   1: class FooBar {
   2:     public static PropertyDescriptor GetProperty<T>(Expression<Func<T>> propertyExpression) {
   3:             MemberExpression body = (MemberExpression)propertyExpression.Body;
   4:             PropertyDescriptor property = TypeDescriptor.GetProperties(body.Member.DeclaringType)[body.Member.Name];
   5:             Debug.Assert(property != null);
   6:             return property;
   7:     }
   8: }

Теперь в коде тестов можно избавиться от строковых констант с именами свойств, заменив их на выражения. Новый код показан ниже:

   1: [Test]
   2: public void SomeTest() {
   3:     FooBar foo = new FooBar() { SimpleString };
   4:     PropertyDescriptor property = FooBar.GetProperty(() => foo.SimpleString);
   5:     // code continues ...
   6: }

В плюс: подсказки Intellisense при наборе, более тесная интеграция с инструментами рефакторинга (так, Find All References теперь выдает не пустой результат для свойств FooBar).

Random thoughts, ideas and questions on .NET development

Постоянные читатели