TFSLABELFIX

In TFS a label has a scope which may be different from where you set the label. Specifically, if you set a label through Source Control Explorer in Visual Studio, the scope is always the team project. For instance, if you use Source Control Explorer to set the label L4.10.0050 on the path $/TeamProj/Module-A/4.10, and later use the same label name for $/TeamProj/Module-B/4.10 that is the same physical label as far TFS is concerned. Only if you use the TF command-line utility you can specify the scope of the labels to make them distinct from each other.

This does not fit well with the philosophy of AbaPerls, and you should use the tool NEWLABEL to apply AbaPerls labels (i.e. labels on the form LetterMajor.Middle.Minor).

Nevertheless, someone may set a label from Visual Studio out of casualty. Also, if you migrate from SourceSafe, the VSSConverter will migrate all labels with the scope set to the team project. To correct such scope errors, you use the tool TFSLABELFIX. Command-line syntax:

tfslabelfix [-update] VC-path [label]
VC-Path Path to a folder in TFS which is the scope for one or more labels for which you want to correct the scope. Typically, VC-path is a team project, that is a folder that lies directly below $/.
labelA label to move. This argument is optional. If you leave out label, TFSLABELFIX moves all AbaPerls labels with the given scope.
‑update Instructs TFSLABELFIX to actually perform the move. Without this option, TFSLABELFIX runs read-only and only lists the changes it would make.

TFSLABELFIX changes the scope of a label so that the scope is the top-level folder for which the label was set. If there is more than one top-level folder, TFSLABELFIX creates one label per top folder. Assume that you in SourceSafe at different points in time applied the label L4.10.0050 to the projects $/MyProduct/4.10/Component-A, MyProduct/4.10/Component-B, MyProduct/4.10/Component-C/SQL, MyProduct/4.10/Customer/BigWhiz1 and MyProduct/4.10/Customer/SmallComp2. Later you decide to migrate the SourceSafe database to TFS. The VSSConverter will create a single label in TFS with the scope $/MyProduct. When you run this command:

tfslabelfix TFSRV/$/MyProduct L4.10.0050

TFSLABELFIX will create five labels, one for each original SourceSafe project. With TFS notation the labels are:

L4.10.0050@$/MyProduct/4.10/Component-A
L4.10.0050@$/MyProduct/4.10/Component-B
L4.10.0050@$/MyProduct/4.10/Component-C/SQL
L4.10.0050@$/MyProduct/4.10/Customer/BigWhiz1
L4.10.0050@$/MyProduct/4.10/Customer/SmallComp2

Note that if you specify TFSSRV/$/MyProduct/4.10 as VC-path, the label would be unaffected as VC-path specifies the exact scope for labels to be moved.

If there is a label that is not set for any folder at all, but only on an individual file, TFSLABELFIX removes this label.

TFSLABELFIX only moves label downwards in the tree, never upwards.

Observe that TFSLABELFIX only operates on AbaPerls labels on the form LetterMajor.Middle.Minor. TFSLABELFIX ignores labels that do not adhere to this format.

Under the hood, TFSLABELFIX moves a label in two steps. In the first step, TFSLABELFIX creates one temporary label for each top-level directory it has identified and with the directory as the scope. All labels have the same name, formed by replacing the letter in the source label with a hash mark (#) in place of the letter in the label, for instance #4.10.0050. Once these labels have been set, TFSLABELFIX removes the original label, and then replaces the temporary labels with labels with the original name. If TFSLABELFIX for some reason is interrupted before the original label is removed, you need to remove the temporary labels before you run TFSLABELFIX again. If TFSLABELFIX is interrupted after the original label has been removed, you will have to sort it out manually, or live with the temporary labels. TFSLABELFIX operates one label at a time, so you can only get this situation with one original label.

After the label has been moved, you will find that the comment for the label will have been prepended with the time for the original label (unless the comment already had such a time string). AbaPerls uses this date to determine which label of a subsystem is the most recent relative to the label of a config-file.