Welcome to MSDN Blogs Sign in | Join | Help

BUGBUG: poor title

Richard Berg's look at source control and life
SourceSafe 2005 Update is available for download!

I'm very pleased to announce that the wait is over.  Today the first official update for SourceSafe 2005 went live on the web.  Download away -- it's only 3.5MB.

To quickly bring new readers up to date: this update is a rollup of 64 VSS bug fixes.  We focused hard on customer pain points; almost 3/4 of these fixes came directly from people like you filing bugs on Connect and/or calling Customer Support.  The result is a variety of improvements to performance, stability, and reliability, plus a few long-time annoyances.  In addition, we focused on compatibility with VS 2008 and Vista.  I've gone into detail on those topics before so I won't repeat myself. 
VS2008
Vista part1 part2

On the other hand, if you've stayed up to date with our VSS releases and are currently running the CTP, there's still plenty here for you.

  • full support for all 6 languages (English, Japanese, French, Italian, German, Spanish)
  • no manual install step
  • 7 extra bug fixes, including some we thought were severe enough to push back this ship date twice :)
VS 2008 and SourceSafe Q&A

My post about VS 2008 and the SourceSafe CTP generated lots of questions.  I'll do my best to answer all of them.

Q: Why wasn't this information in the VS2008 README?
A: It should have been.  It was definitely in the Orcas Beta1 and Beta2 READMEs.  I haven't checked the RTM copy but if it was missing then that's a mistake and I apologize.

Q: Is VSS2005 the official product for VS2008, or is there a VSS2008 around the corner?
A: Yes, VSS 2005 is still the official source control product in the 2008 time frame.  (Along with TFS 2008 of course.)  There is no VSS 2008.  As you've probably noticed, VSS does not ship every time Visual Studio does.  For example, VSS 6.0 shipped way back in 1998 with the VB6/VC6 suite of products, and then shipped service packs (6.0c, 6.0d, etc.) with the next few Visual Studio releases.  Will there be another major revision of VSS?  That's too far away to forecast -- it depends on how the market looks in a few years.

Q: Does SourceSafe 6.0d work with Visual Studio 2008?
A: SourceSafe 6.0d is not officially supported with VS 2008, nor with VS 2005 for that matter.  However, it should be possible to get it working if you're willing to accept some limitations.  The quickest way is to run "regsvr32 ssscc.dll" from your VSS6\win32 folder.

Q: Where do I get VSS2005 anyway?
A: If you have a Team Edition of Visual Studio 2005 or later, then VSS2005 is included in your license.  It was included on the VSTS 2005 set of discs; you can also download it from MSDN.  If you have a Professional Edition of Visual Studio or lower then you need to purchase VSS separately.

Q: What's up with all the TLAs?
A: I agree "VSS GDR CTP" is silly.  In recent posts here and on the forums, I've taken to calling it simply "the SourceSafe CTP."  There's no danger of being ambiguous, because I'm never doing a CTP again ;) -- contrary to Joel's comment, it ended up requiring just as much testing as a real service pack, so there's not much point.  Ideally, I'd rather deliver fully-baked updates early and often than wait for another 64 bugs to pile up.  Hopefully the DevDiv Hotfix Availability program will keep us moving in the right direction.

As for the final GDR, its official name will be "SourceSafe 2005 Update."  Much better.  If we do another one, I'd like to see an even simpler naming scheme, such as "SourceSafe 2005b" -> "2005c" -> etc.  Internal processes will probably still force us to call them GDRs, but there's no reason to confuse the rest of the world.  What do you think?

List of SourceSafe bugfixes updated

Just a quick note to let you know that I've updated the list again. 

To recap: you can get fixes #1-57 today via the CTP build.  English only, I'm afraid.  The final GDR ships later this year in all supported languages (English, Japanese, French, Italian, German, Spanish).

VS 2008 users: remember to download the SourceSafe CTP

You've probably all seen Soma's announcement that the 2008 suite of products officially shipped this morning.  Good luck downloading -- our servers are pegged :) 

If you plan to use VS 2008 with SourceSafe, make sure to pick up the Update CTP too.  Without it, some features like "Open from Source Control" will not work at all.  Pay close attention to the install instructions as well.  As it says in the KB article:

You may receive error messages when you use Visual Studio 2008. This problem occurs because some compatibility fixes require the Tdnamespaceextension.dll file to be reregistered after you install Visual Studio 2008. To reregister the Tdnamespaceextension.dll file, type the following command at the [elevated - RB] command prompt:

regsvr32 "%programfiles%\Microsoft Visual SourceSafe\tdnamespaceextension.dll"

Sorry about the manual install step.  It sucks, I know.  The next Update won't have this requirement.  (We wanted to ship it before Orcas but ran into some last-minute delays.  Expect it before the end of the year.)

Why does SourceSafe need an update anyway?  Aren't VS plugin interfaces supposed to be backwards compatible?  Yes, they are.  In fact, there are no changes to the MSSCCI API in 2008; none of the fixes are related to MSSCCI.  (3rd party source control developers can now breathe a sigh of relief).  The changes come from the way SourceSafe implements Open from Source Control, Add to Source Control, and Share inside Visual Studio. 

Starting in VSS 2005, these functions let you browse the database inside VS's open/add dialogs instead of hanging off the File -> Source Control menu like most other source control providers.  It's a cool trick known as a namespace extension.  In VS 2008, as you may have noticed, those open/add dialogs got a facelift: like VSS 2005, VS 2008 now uses the standard Windows dialogs.  So Vista users in particular get a spiffy new one with integrated search & everything.  Unfortunately, that change broke us pretty badly, leading in one way or another to at least 10 of the bugs on my list.  Bottom line, you don't want to be caught without the Update linked above. 

Hopefully these fixes demonstrate our commitment to keep SourceSafe 2005 a viable option with VS 2008, Vista, and beyond!

'tf checkin' exit codes

All tf.exe commands return one of these:

public enum ExitCode
{
    Unknown = -1,
    Success = 0,
    PartialSuccess = 1,
    UnrecognizedCommand = 2,
    Failure = 100,
}

You should never see -1.  Code 2 is only for the very specific case where you mistype tf someboguscommand <...>.  The important exit codes are 0, 1, and 100

Unfortunately, the definition of PartialSuccess is kind of ambiguous.  Like the design decisions around tf.exe's path parameters, different commands ended up with slightly different behavior in v1.  For example, if you try to Checkout several files, "partial success" means "at least one edit was successfully pended."  Meanwhile, as we'll see, Checkin treats success as all-or-nothing, reserving the PartialSuccess flag for something else.  I'm not going to catalog all of these differences, especially since they might be harmonized in the future.*  Instead I'm focusing just on tf checkin because:

  • It's not intuitive.  Yet...
  • it's the command whose success or failure is most critical to build scripts & other common automation tasks.
  • I already looked up the answers for another customer today :)

As you probably know, Checkin is an all-or-nothing operation.  Conflicts, policy failures, etc. on any of involved files will halt the process.  This design is part of what allows us to guarantee so-called atomic checkins.  As such, we wanted exit code = 0 to unambiguously indicate that a checkin has occurred, with all that implies: new changeset metadata, a new systemwide version number, and so on.

So what in the world does exit code = 1 mean?  There are two places in the code where it's set:

  1. there were no pending changes in your workspace, and you didn't pass any filespec arguments
  2. all of the pending changes you tried to checkin were silently undone.  This in turn means:
    • they were all edits
    • none of the files had been modified

Situation #1 is pretty straightforward: you used syntax that means "checkin everything", then it turned out there was nothing to do.  Situation #2 arises because the server will not let you checkin unmodified files as edits.  As a courtesy, TFS removes the edit bit and continues.  [This is mildly interesting in the light of the guarantees discussed above.  Put simply, we don't consider this a failure.  We return 0 so long as at least one file is successfully checked in, no matter how many other files might have been reverted.]

As you can see, both of these situations are closer to "meaningless failure" than "partial success".  Was it worth separating them out from exit code = 100 cases?  Hopefully :)  In any case, you should now have all the info you need to write scripts that incorporate tf checkin commands intelligently.

*Disclaimer: this article merely describes behavior you might find helpful in v1; it does not imply a design contract.  Details like this are subject to change in future versions of TFS...though if they did the test team might riot ;-)

SourceSafe Explorer: what does the "build tree" checkbox do?

When you run Get on a folder (aka project) in VSS Explorer, you're presented with these options:

image

(if you don't get this dialog, try holding Shift)

Most of the options are obvious, but not "build tree" -- at least not to me.  The online help explains it thusly:

Projects only. Overrides the working folders for the subprojects in a recursive operation and builds a project tree on your local computer that mirrors the database project organization. Working folder settings for individual subprojects are ignored. This option is available only when you select the Recursive check box.

Decent explanation -- but if frequent customer inquiries are any guide, it would really benefit from a concrete example.  Luckily, Patrick McCormick gave a great one last time the question came up.  I've dressed it up with screenshots for added clarity.  Let's start with a simple database.

image

If I run Get on the root ( $/ ), "build tree" will ensure that the file structure created on disk looks the same.

image

Ordinarily, the "build tree" checkbox is not necessary to get this result.  However, it's possible to set explicit working folders in SourceSafe.  Working folders might point to completely different locations on disk.  If you previously worked with our two WindowsApplications separately it's not likely they map to sibling folders (unless you were very careful).  Moreover, if you normally use the Visual Studio IDE, you would never notice because VS uses its own "bindings," not the mappings from VSS Explorer.  Thus, you might have inadvertently set up mappings such as

$/WindowsApplication1 -> c:\users\richard\documents\WindowsApplication1
$/WindowsApplication2 -> d:\vss\WindowsApplication2

So long as you're working with these projects independently, that's no big deal.  But if you're fetching both of them as part of the same Get operation, there's a good chance you intend to build them together, which means their relative path becomes important.  That's the scenario "build tree" intends to enable.

TFS Version Control Concepts 3: Item Versions and the two meanings of 'Changeset'

Let's recap Items one more time.

  1. Items are unique.  They have an ID that no other item does.
  2. Items are versioned.  Like all version control systems, TFVC is about making it easy to store successive versions of the same item and retrieve old ones when necessary.
  3. Items have names.  Yes, plural.  At a rudimentary level, there's a server path showing where it lives on the server and a local path showing where it lives on your filesystem.  More on this later.  Suffice to say names are not unique.
  4. Items have a type.  Either they are an ANSI, UTF-16, Binary, etc. file; or they are a directory.

I think #1 and #4 are self-explanatory.  We covered #3 in great detail last time.  Time to tackle #2.  Versions aren't nearly as tricky as names, but there are some historical and terminology issues to cover.

image

One way to look at the repository is to watch each "slot" over time.  ("Slot" is our slang for "server path in committed space.")  Every time you checkin a new version of an item, two things happen: a unit of work is recorded, and the new contents of that slot going forward is established

So far all of this is common to every version control system ever written.  In addition, modern version control systems support so-called "atomic checkins."  That's actually shorthand for a few related concepts:

  • Multiple files can be checked in during the same transaction.
  • If any files fail to checkin, the entire operation is aborted.
  • Version numbers - or at least some types of version numbers - are consistent across the repository.
  • Metadata is associated with the entire collection of files being committed.

Older systems like CVS and SourceSafe didn't have atomic checkins, so a version was a version (or "revision" in CVS terms).  Individual items in a modern version control system still have versions, but when we introduced atomic checkins to TFS we needed another word to encapsulate the all the new concepts above.  As you probably know, we picked "changeset."  Unfortunately, the word doesn't help distinguish between the "two things" (above in boldface) that happen to the repository upon checkin.  These two distinct meanings sometimes cause confusion:

  1. [adj] A point in time.  The state of the entire repository immediately after a unit of work was committed.  Whenever you specify a "changeset versionspec" in a TFVC command, it takes on this meaning.  In this sense changesets are equivalent to dates.  (Old posts from Adam and James have more details on versionspecs and date specs in particular.) 
  2. [noun] A unit of work.  The files you change during 1 checkin, plus any associated metadata.  Whenever you view the contents of a changeset (tf changeset /i, the Changeset dialog, the output of Checkin) you're seeing this meaning.  Same for work items: when you link bugs to changesets, you're linking them to that specific unit of work.  Unfortunately we don't have an easy way to specify meaning #2 in TFVC commands, except for the 'tfpt getcs' power tool. 

That's a lot of words for a really simple distinction.  Math terms to the rescue once again.  If you think of the repository as a 2D plane like the one pictured above,
meaning #1: all points on a line time = <constant>
meaning #2: a set of revisions that lie on a such a line

By now it should be obvious that a TFVC operation on "changeset versionspec 20" will affect both a.cs and b.cs, while "changeset #20" only contains b.cs.  Unfortunately I don't have a special trick for demarcating which meaning of the word I intend, so I'll try to be unambiguous in future discussions of changesets.

TFS Version Control Concepts 2b: Namespaces in practice

Command Line usage

In Source Control Explorer, you're always operating on pending space.  At the command line, it's less clear.  Consider the following setup: you're working in a directory $/project that's mapped to c:\project and contains two files a.cs and b.cs.  For the sake of argument, we'll say they have itemIDs 1 and 2.

c:\project>tf ren b.cs c.cs
c:\project>tf ren a.cs b.cs
c:\project>tf edit $/project/b.cs

Which item gets the edit pended on it?  I actually wouldn't know without trying it, because our syntax in TFS v1 is rather haphazard: different tf commands have different rules.  Regardless, we can use our new namespace terminology to frame the possible answers.  If 'tf edit <serverpath>' operates on pending space, then the answer is item #1.  If it operates on committed space, then #2 gets checked out.  Ambiguous. 

After v1 we tried to clean up this behavior.  The new guiding rule is that local paths passed on the command line will be interpreted as pending space, while server paths will be treated as committed space.  We feel this is the best compromise between user experience and predictability. 

Users usually expect to operate on names as they see them appear on disk.  That's pending space: added/branched/undeleted files are present, deleted files are gone, and renames are in effect.  You can copy/paste paths from Explorer and it will just work.  However, you can't do everything in pending space that you can in committed space.  You can't use a pending item as the source of a Branch or Merge; you can't combine a Delete with most other pending changes; and so on.  In v1 we allowed such considerations to inspire a plethora of rules like "branch always operates on committed space" that nobody can remember.  We were also very forgiving -- for instance, we might allow 'tf <change> $/project/c.cs' or 'tf <change> a.cs' to succeed so long as there was no ambiguity.

Going forward we think it's better to throw an error every now & then if it keeps things more consistent overall.  A full review of our APIs with this principle in mind probably won't happen before Rosario, though.  Feedback is welcome on this topic!

But wait, there's another wrinkle yet.

Unsynchronized working folder mappings

c:\project>tf workfold $/project/b.cs c:\project\a.cs
c:\project>tf edit a.cs

Which item gets the edit pended on it?  Recall that until you run Get, the new mapping does not take effect on disk.  That is, a.cs and b.cs are still in their original locations.  Yet $/project/b.cs unquestionably maps to a.cs according to our rules, and the server knows this.  If we wanted to be pedantic, we'd define another namespace called "unsynchronized local space" to capture the difference between the two viewpoints.

In the end, it comes down to implementation details.  When you call Edit, the server looks at the direct item <-> local space mapping that's cached in the LocalVersion table.  This is certainly the fastest way to resolve the mapping, and it also happens to coincide with the reality on disk: c:\project\a.cs has item #1's contents at the time you made the call, and item #1 is in fact checked out. 

'tf undo' is a special case: we have to perform a Get as part of the operation anyway, so we let you specify either local path.  

Clearly, if you combine this quirk with pending renames (or worse, pending parent renames) you could get your brain in quite a twist trying to figure out the correct syntax.  In all cases, running Get will clean everything up according to the new mappings.

Case Sensitivity

Our design here is "case-sensitive storage, case-insensitive lookup."  Put another way, outputs are case-sensitive while inputs are case-insensitive.  To meet that goal, we need these rules:

  1. You cannot have two items that differ only by case.  Sorry Unix folks.
  2. Thanks to #1, we can let you refer to existing items with the wrong case w/o ambiguity.  'tf edit a.cs' and 'tf edit A.CS' are guaranteed to have the same results. 
  3. Despite #2, we always preserve the case stored on the server unless the Rename bit is set (or Add or Branch, for an item’s very first checkin).  Committed space is case-sensitive; the only way to alter it is by checking in a Rename.*
  4. When we do store a new case-sensitive name (for the first time, or during a rename), we use the name specified during the Add/Branch/Rename, not the one passed to Checkin.  In other words, pending space is case-sensitive too.  Checkin works exactly like Edit did in #2: its inputs are case-insensitively compared against pending space, yet the output is always the same.

*I think this is the first time I've used the phrase "Rename bit".  Internally, we represent the various changetypes as bitflags that can be combined in a surprising # of ways.  I'll post the complete chart sometime.  Suffice to say that for our purposes, operations like 'tf undelete /newname', or a Merge that brings renames into the target, count because they set the Rename bit.

Edge Cases

  • Consider a workspace mapping $/FairlyLongPath -> d:\short.  What happens if you create a file under 'short' whose path is MAX_PATH long?  The server-side character limit would block your checkin, and the mapping would no longer be surjective!  In reality, we don't even let you pend this kind of change.  Sorry nitpickers.
  • That's not to say you can't break my generalizations; you just have to be more clever.  Consider the following set of workspace mappings:
    $/a -> c:\a
    $/a/b/c -> c:\a\b
    At this point your workspace mappings are no longer explicit: the server has to generate an "implicit cloak" for the folder $/a/b.
  • If you think hard enough about pending space, you'll realize it's not a transformation directly on committed space.  It's really a composition of three functions: committed space => local space => [local] pending space => [server] pending space.  The middle function is the one we care about.  The 1st and 3rd functions are basically inverses of one another, so we usually ignore them.  Likewise, we can work with local paths or server paths in pending space without ambiguity.

    However, if you read the preceding section carefully, you'll see they're not perfect inverses.  The 1st transform is case-insensitive, while the 3rd is case-sensitive.  Consider what happens when you create a workspace mapping with case that differs from committed space:
    c:\project>tf workfold $/PROJECT c:\project
    c:\project>tf edit A.CS
  • Committed Local Pending
    $/project/a.cs c:\project\a.cs $/PROJECT/a.cs
    I once wrote to a customer "committed space and pending space should have the same case unless the rename bit is set."  As you can see, I was wrong :)  It's true that pending the edit using the wrong name 'A.CS' has no effect, as you'd expect from the discussion above.  However, because the transform to pending space takes a roundtrip thru your workspace mappings, incorrect case there can bite you.  A pending parent rename would also invalidate my statement.

    For this customer, the fix was to alter their tool so it used case-insensitive comparisons throughout.  That's almost certainly good enough for any & all 3rd-party plugins, thanks to rule #1; if you're programming against TFS, I heartily recommend following suit.  Unless your job is actually testing TFS's correctness...
TFS Version Control Concepts 2: Item Names

Last time we learned that the principle objects in the source control system are called Items, and a few of their basic properties.  That was awhile ago so let's recap:

  1. Items are unique.  They have an ID that no other item does.
  2. Items are versioned.  Like all version control systems, TFVC is about making it easy to store successive versions of the same item and retrieve old ones when necessary.
  3. Items have names.  Yes, plural.  At a rudimentary level, there's a server path showing where it lives on the server and a local path showing where it lives on your filesystem.  More on this later.  Suffice to say names are not unique.
  4. Items have a type.  Either they are an ANSI, UTF-16, Binary, etc. file; or they are a directory.

Today's topic is #3.  Names (aka paths) are what users usually see when they interact with Items.  Rarely do you know in advance that you want to operate on ItemID #12345.  However, since names are not first-class objects in the system, we need a way to translate them back to Items.  As it turns out, there are several ways to do this. 

 

Namespaces

We call each consistent class of item names a namespace.  The rules for translating a name within a certain namespace to an Item - or to another namespace - we call mappings, aka functions or transformations.  It's easiest to describe mappings using terms borrowed from math.  Some mappings are injective (aka "one-to-one") or surjective.  Sometimes an explicit set of rules defines the mapping; sometimes the mapping is more of a side effect.

Committed space

Committed space is the closest thing we have to a canonical namespace.  It's what you see when you browse Source Control Explorer: the server paths of the items checked in to source control.  The mapping between items and committed space is one of the fundamental properties we track with each revision, although there is no API to perform the transform explicitly.  In addition, the mapping is injective: at any given point in time, each item has exactly one name in committed space.  It's not surjective: there are zillions of $/bogus or c:\bogus names that don't map to any item.  The only tricky part is variation over time, as users commit renames.

Local space

Local space is where local filesystem paths live.  It is defined relative to committed space by workspace mappings, which are explicit and readily exposed to the user.  This mapping is surjective: every item in your local workspace maps back to an item in committed space.  It is usually not injective, unless you map the entire repository ($/) and don't have any cloaks.

(On the server, there is also a mapping directly from items to each local space.  As you might guess it's injective.  We won't spend time on it because it's really just an optimization - part of the performance boost you get by tracking local version info - not conceptually important.)

Pending space

Pending space is also a property of a local workspace.  It represents the server paths of items as they would look in committed space after you checked in all of your currently pending changes.  In other words, it is defined implicitly, by transforming committed space according to any pending renames you have in that workspace.  Like local space, this mapping is usually surjective only -- items in pending space map back to committed space, but not vice versa.

We sometimes talk about the pending space of local paths, too.  Since the mapping between server & local paths is straightforward, and the idea is the same, it doesn't deserve its own section :)

Target space

Target space is a reflection of committed space from one branch onto another.  The Merge operation must generate a mapping between items in the source branch (committed space) and items in the target branch (target space) in order to determine the correct target items to pend changes on.  The mapping is implicitly defined by the history of the two branches: any renames that have occurred, whether they were merged, and if so how they were resolved.  In the general case the mapping is neither injective nor surjective, because items can be moved in & out of the two branches at will.

 

Examples

That was all pretty abstract.  Let's give an example. 

Changeset Action
10 add $/project/branch1/foo/bar.cs
20 branch it to $/project/branch2/foo/bar.cs

We now have two items under consideration.  Their itemIDs don't really matter except to say that they'll stay the same throughout this exercise.  Their names in committed space are trivial: exactly what is shown in the history chart.  We'll create a workspace with these mappings:
$/project -> c:\myProj
$/project/branch2 -> c:\myProj2

After we synchronize our workspace to changeset 20, we see clearly that our two items have local names c:\myProj\branch1\foo\bar.cs and c:\myProj2\foo\bar.cs.  Edits are the simplest kind of pending change in this context.  If we pended an Edit on them, their names in pending space would simply be the same server paths as found in committed space.

Committed Local Pending
$/project/branch1/foo/bar.cs c:\myProj\branch1\foo\bar.cs $/project/branch1/foo/bar.cs
$/project/branch2/foo/bar.cs c:\myProj2\foo\bar.cs $/project/branch2/foo/bar.cs

Pending a namespace operation (Add, Branch, Delete, Undelete, or Rename) is a little more interesting.  For example, if we created a 3rd branch, it would have a local path and a server path in pending space (c:\myProj\branch3 and $/project/branch3) but would not exist in committed space.  Add and Undelete work similarly; Delete is essentially the reverse.  Rename is the most complex, so let's checkin one and pend another:

30 rename $/project/branch1/foo => $/project/branch1/foo-ren
40 merge branch1 => branch2.  Resolve the rename conflict as AcceptYours (aka keep the target name unchanged)
[pending] rename $/project/branch2/foo/bar.cs => $/project/branch2/foo/bar-ren.cs

At this point, our original two items have the following names:

Committed Local Pending
$/project/branch1/foo-ren/bar.cs c:\myProj\branch1\foo-ren\bar.cs n/a
$/project/branch2/foo/bar.cs c:\myProj2\foo\bar-ren.cs $/project/branch2/foo/bar-ren.cs

A couple things to note.  First of all, the downstream affect of recursive operations: our first item has changed names even though it has never been renamed.  To answer the question "what was item X's name at time T" it's not enough to look at that item's history.  You have to consider the history of its parent folder, grandparent folder, etc. as well as any parent folder it was ever part of.  While the changeset that became #30 was still pending, a similar process had to be followed in order to compute its name in pending space.

Second, note that the names of related items have diverged between the two branches.  Target space arises because we need to preserve that relationship.  To demonstrate, let's checkin our 2nd rename and pend another merge.

50 rename $/project/branch2/foo/bar.cs => $/project/branch2/foo/bar-ren.cs
[pending] merge branch2 => branch1.  Resolve the rename conflict as AcceptMerge

Merge sees that there has been a rename to bar.cs in the source (branch2), and needs to pend the equivalent change in the target (branch1).  By looking at the merge history, it determines which target item is related to branch2/foo/bar-ren.cs, i.e. its name in target space.  During the first merge, it was straightforward: it just substituted the branch root ($/project/branch2).  This time it's more complex:

Committed Local Pending Target
$/project/branch1/foo-ren/bar.cs c:\myProj\branch1\foo-ren\bar-ren.cs $/project/branch1/foo-ren/bar-ren.cs n/a
$/project/branch2/foo/bar-ren.cs c:\myProj2\foo\bar-ren.cs n/a $/project/branch1/foo-ren/bar.cs

Note again that names in target space correspond to names in the other branch's committed space. 

Did you know? How to bring up old-style dialogs in SourceSafe 2005

One of the changes made between VSS 6.0 and 2005 was to replace ancient file dialogs with common dialogs from the Windows Shell wherever possible.  Check out the 6.0 version of Set Working Folder:

image

It just screams "Win 3.1", complete with floppy diskette icon in the dropdown.  By contrast, if you install VSS 2005 on Vista, we can give you a shiny new dialog with no extra work:

image

There's a secret though: all the old dialogs are still around (in ssgui.dll to be exact).  To access them, hold the Shift key as you click the appropriate icon or menu item.

Why should you care?  Maybe you have lots of nontechnical users and no training budget.  (You devs out there would be surprised how many executive admins, paralegals, HR reps, etc. use VSS to store documents.  There was no SharePoint in 1995.)  Maybe you rely on UI automation to perform repetitive source control tasks.  (As you've probably noticed, not all VSS Explorer functionality is available from the command line and/or IVSS.)  Or maybe you're just nostalgic.

Actually, I picked Set Working Folder for a reason.  The Windows Browse For Folder dialog has one limitation that the baked-in original did not: you must select a valid folder before the OK button is enabled.  Using the old dialog, you can erase the text box and press OK to remove the working folder from your mappings.  If you only had the 2005 functionality, you'd be forced to hand-edit the sparsely-documented ss.ini file (yuck).

This post is dedicated to Sara Ford's awesome VS2008 Tip of the Day series.

Binding Outlook macros to a keyboard shortcut

When I updated Buck's TFS macros for Outlook 2007, I neglected to demonstrate how they were installed.  Enough has shifted around in '07 that the question has come up a few times.  Let's burn some bandwidth.

1) go to Tools -> Macro -> VB Editor.  Doubleclick "ThisOutlookSession" and paste in the code from the previous blog post.  Save.

image

2) bring up a message window.  Click the Quick Access Toolbar's dropdown and choose More Commands...

image

[you could also get here via Glowing Office Button -> Editor Options -> Customize]

3) Choose "Macros" from the dropdown and press the Add button 3X.

image

4) Hit OK enough times to get back to the main OL screen.  Navigate to Tools -> Macro -> Security.  Select "no security check for macros."  Restart Outlook.

image

If you don't make this change, your macros will be disabled next time you restart Outlook.  (The other option is to digitally sign your macros.)

Disclaimer: turning off macro security is not in any way an official recommendation of Microsoft or the Outlook team.  It worked for me and I feel safe about it due to the way I use Outlook and the environment it's in.  The Help page for this dialog has a very lucid description of the tradeoffs.  Make your own decision.

5) Compose an email.  Note the macro icons in the Toolbar.  You can now access them via the mouse or keyboard.  To view keyboard shortcuts for the Toolbar, as with any Office 2007 ribbon, simply press & release Alt:

image

The way I have my Toolbar configured, the macros are Alt+4 thru Alt+6.

Back from Brazil

I've been on vacation the last two weeks, and was silent for several weeks before that.  Lots of things from that time stretch I want to share.  Most notably, we wrapped up the promised "VSS GDR CTP".  Brian Harry was kind enough to announce its RTW in my absence (including an all-too-necessary jab at its TLAs):

Along with the VS2008 wave of products, we are providing an update to Visual SourceSafe 2005 called a GDR.  GDR stands for something like General Distribution Release and it is very much like a service pack.  The differences are subtle and I won't try to explain them right now.  This GDR contains over 57 fixes and includes all customer requested hot fixes and many internally found and fixed issues.  It is also designed to make sure that VSS 2005 works well with the VS 2008 wave of products.  The update is available for free to all licensed VSS 2005 customers.

We have just released a Community Technology Preview (CTP) for the GDR - ok, the TLAs are getting out of hand now :)  You can read about some of the issues it addresses in the following Knowledge Base article: http://support.microsoft.com/kb/939808.  And you can download the CTP here if you want to try it out: http://www.microsoft.com/downloads/details.aspx?FamilyID=faf41edd-924d-449f-aefc-9c86dd499720&displaylang=en

The official release of the VSS 2005 GDR will come this fall.

You can find a longer explanation of the terminology and the complete list of bugs among my previous posts.  Still, I have quite a blogging backlog from "going dark."   First order of business: update said bug list.  (edit - done)

 

List of bugs fixed in SourceSafe 2005 GDR

I'm a big fan of the work Brian Harry has done to make our processes more transparent.  Nevertheless, to badly misquote one of my other bosses, "transparency for the sake of transparency is soo 2006."  I chuckled again writing this, because there's a grain of truth there: telling you I produced 4 widgets per furlong yesterday doesn't make your experience with Microsoft dev tools any better.

With that principle in mind, I want to broadcast details about the GDR I just announced.  More than that, I want it to be useful.  To that end:

  • I'm including an ID with each bug.  This should allow you to easily refer to bugs among yourselves and when asking us questions.  I considered using the internal bug IDs, but
    • They would be huge numbers, since it's developed in the same TFS team project as all of Orcas.  Huge numbers are meaningless to you, and possibly offensive to the Orcas folks ;-)
    • They would be ordered by Creation Date.  I want my IDs ordered by Resolved Date so that I can easily append to the list as more bugs are fixed.
  • I'm including all bugs regardless of source: DTS bugs, bugs opened on Connect, and bugs opened internally.  (DTS bugs are what get created when a case bubbles up from calls to Customer Support.  Read Brian's post for more details & caveats.)
  • I'm including KB article numbers wherever possible.  All DTS bugs that result in a hotfix eventually get a KB article.  We may write articles for other bugs too depending on time & interest...no promises though.

ID

Bug Title

KB article #

1

DTS:SSuser: SSService.exe fails on Windows 2000 server

916688

2

DTS SSAFE : hotfix request - analyze 2005 -D removes valid items from database

917491

3

DTS : Taking much time (over 30 mins) when checking in 20 M bytes excel file.

 

4

DTS : Failed to open *.pdf files which are registered on Visual SourceSafe 2005

925234

5

VSS2005: lost internet accounts listed for file security property after web project file merged change from multiple developer

927004

6

Analyze reports corruption on database with root labeled

923842

7

DTS Binary_Mask is not respected during operations like Checkin, Diff, etc  result ing corrupting pDF files

923434

8

DTS : Visual SourceSafe 2005 doesn't change the past history contents file format.

924702

9

VSS Merge Changes File Permissions

927004

10

DTS: VSS2005 - Crash on preview of report from History dialog

925275

11

comment template only allow 2 lines

928392

12

DTS: SourceSafe 2005 - Checkin corrupts XML file with diff chain size mismatch error

927887

13

The VSS button in places toolbar doesnt show when running as normal user

 

14

Get Binary file in 2005 results in different file content than retrieving the file in 6.0 (corrupted file)

930573

15

VSS and Vista:  The SCC provider is not functioning

 

16

Switching file filters when looking at VSS database causes the DB logging dialog to comeup and doubles all items

 

17

VSS and Vista returning "No such interface supported" when trying to navigate to a VSS database

 

18

VSS namespace extension doesn't respect filter (legacy dialogs only)

 

19

VSS2005 explorer crash when generate report with "include difference" checked at show history dialog

930573

20

Vista: Clicking on ">" and then selecting a VSS item in the drop down list on Vista address bar causes another drop down list to appear

 

21

Add Existing Item dialog should not remember VSS opened paths

 

22