Where did I come from?
One of the great questions of life and source control systems.
Today I needed to be able to look at the merge history of a file and figure out from where it was merged. I found it to be more difficult then I expected - so I thought I'd blog it.
Consider a branch tree that looks like this:
Described in words – there exists a main branch from which there are two child branches, team1 and team2. Team1 has two child branches, dev1a and dev1b, and Team2 has two child branches, dev2a and dev2b.
To make this concrete – this is the output of the branches command:
> tf branches $/teamproject/team1
>> $/teamproject/team1 Branched from version 3 <<
$/teamproject/devteams/dev1a Branched from version 31
$/teamproject/devteams/dev1b Branched from version 31
$/teamproject/team2 Branched from version 3
$/teamproject/devteams/dev2a Branched from version 31
$/teamproject/devteams/dev2b Branched from version 31
So when I do something like:
> tf merge $/teamproject/devteams/dev1a $/teamproject/team1 /r
merge, edit: $/teamproject/devteams/dev1a/foo2.cs;C32~C33 -> $/teamproject/team1/foo2.cs;C31
This was then submitted as change 34.
Let’s pretend a few weeks have passed and we forget what we merged in change 34. I’m just trying to remember if I merged dev1a or dev1b back to team1.
Let’s try and find out.
tf merges $/teamproject/team1/foo2.cs
Changeset Merged in Changeset Author Date
--------- ------------------- -------------------------------- ----------
23* 31 rhorvick 2/2/2006
26 31 rhorvick 2/2/2006
32* 31 rhorvick 2/2/2006
33 34 rhorvick 2/2/2006
Hmmm – not exactly what I wanted. But I can see that changeset 34 merged changeset 33 – so let’s look in there:
> tf changeset /i 33
Date: Thursday, February 02, 2006 3:42:21 PM
Ok – so it was dev1a that I merged. Good enough.
But it won’t always be as clear…
What happens if you made changes to both dev1a and dev1b in a single changeset and then merged only one of them back (since you can’t merge both in a single changeset) …
Look at our command output now:
>tf merges $/teamproject/team1/foo2.cs
35* 36 rhorvick 2/2/2006
>tf changeset /i 35
Date: Thursday, February 02, 2006 3:53:21 PM
Not as clear this time. There are two possible merge contributors here – either dev1a and dev1b could have merged. So which was it? Do you know? No – you don’t. You don’t have enough information yet.
To figure it out we need to look at the merge history for each potential contributor.
Query each one to see if they participated in changeset 36…
>tf merges $/orcas/devteams/dev1a/foo2.cs
31* 32 rhorvick 2/2/2006
34 33 rhorvick 2/2/2006
36 35 rhorvick 2/2/2006
>tf merges $/orcas/devteams/dev1b/foo2.cs
You can see that only one of them contributed to changeset 36 and therefore that is the one which was merged.
So to figure this all out you need to:
1) query the branch history to see what branches could be contributing to a merge
2) query the merge history to see what changesets could have contributed.
3) query the merge history for each item with multiple potential contributors until you find the right one
4) repeat for each file with multiple potential contributors
I don’t like how many steps this took. And since the client doesn’t make it much easier I wrote a tool to automate this.
In my next post we’ll start looking at that.