Alright – let’s wrap this thing up.

 

We’ve seen the algorithm for discovering merge history and written seen how to call QueryMerges and GetBranchHistory to determine merge contributors.  This all works fine until a rename or delete is involved.

 

Deleted items

 

When you have a deleted item you can’t query merge history on it – the deletion ID is not considered on the query (in fact the client won’t even parse the “;X#”).  So what you can do it something like this (the method tryGetMergeInfo_Internal is basically what is in the previous post)

 

static bool tryGetMergeInfo(Item source, Item target, VersionSpec version, out MergeInfo mergeInfo)

{

    mergeInfo = default(MergeInfo);

 

    // if the source was deleted we need to look at the previous version

    if (source.DeletionId != 0)

    {

        Item deletedItem = tfsClient.GetItem(source.ItemId, source.ChangesetId - 1);

        if (tryGetMergeInfo_Internal(deletedItem, target, version, target.ChangesetId, out mergeInfo))

        {

            return true;

        }

    }

 

    return false;

 

...

 

}

 

If the source item is deleted – get the item just prior to it and use that.  Seems hackish.  But it works.

 

Renamed items

 

Same type of story …

 

// if the target item has been renamed we need to find the previous name

Item renamedItem = tfsClient.GetItem(target.ItemId, target.ItemId-1);

if (VersionControlPath.StringComparer.Compare(target.ServerItem, renamedItem.ServerItem) != 0)

{

    if (tryGetMergeInfo_Internal(source, renamedItem, new ChangesetVersionSpec(renamedItem.ChangesetId), target.ChangesetId, out mergeInfo))

    {

        return true;

    }

}

 

If the item was renamed then use the latest name as the path to the query.  Why?  It’s a long story.  I’m don’t personally like it.  But its how v1 works.

 

The attentive reader is going to notice a problem here though …

 

What about round-trip renames (foo.cs -> bar.cs -> foo.cs)?

 

Yeah – this is the problem child.  You need to walk history and test every potential contributor until you find the right one.

 

The code I’ve shown you will find the merge contributor in almost every case.  It’s not perfect – and I’m not a huge fan of “good enough” – but for the purposes of a quick blog series – that’s what this is.

 

If you have questions – I’ll revisit it.

 

What do people want to see next?  If you are trying to use the TFS version control client OM and having trouble - let me know where and I'll try to blog it otherwise I'll pick a new topic.