
{"id":637,"date":"2010-10-25T00:18:10","date_gmt":"2010-10-25T04:18:10","guid":{"rendered":"http:\/\/www.ikriv.com\/blog\/?p=637"},"modified":"2010-10-25T00:18:10","modified_gmt":"2010-10-25T04:18:10","slug":"tfs-and-the-kiss-principle","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=637","title":{"rendered":"TFS and the KISS principle"},"content":{"rendered":"<p>How do you copy an SVN label to a folder?<\/p>\n<p><code>svn <b>serverpath<\/b>\/tags\/<b>label<\/b> <b>destdir<\/b><\/code><\/p>\n<p>How do you copy a TFS label to a folder? Watch my hands:<\/p>\n<p><code>mkdir <b>destdir<\/b><br \/>\ncd <b>destdir<\/b><br \/>\ntf workspace \/server:<b>mytfsserver<\/b> \/new <b>myworkspace<\/b> \/noprompt<br \/>\ntf workfold \/map <b>tfspath<\/b> .<br \/>\ntf get <b>tfspath<\/b> \/version:L<b>label<\/b> \/recursive<br \/>\ntf workspace \/delete <b>myworkspace<\/b> \/noprompt<br \/>\ncd ..<\/code><\/p>\n<p>Why such a striking difference? SVN is built around &#8220;all parameters are explicit&#8221; principle. Export this to that. End of story. TFS on the other hand uses multiple levels of &#8220;invisible&#8221; server stored settings.<\/p>\n<p>1. <b>The <code>tf get<\/code> command does not accept the destination.<\/b> It takes the destination folder from a list of mappings from a TFS workspace.<\/p>\n<p>2. <b>It does not take workspace name as a parameter either<\/b> (well, it may, but then you can&#8217;t use label syntax). Instead, it relies on some mysterious algorithm to find &#8220;implicit&#8221; or &#8220;current&#8221; workspace. I could not find exact description of this algorithm during casual browsing of MSDN, but it seems to derive current workspace from current directory &#8212; another hidden and unreliable dependency.<\/p>\n<p>3. <b>If current workspace cannot be determined, <code>tf<\/code> just exists<\/b>, proudly saying something like &#8220;unable to determine workspace&#8221;.<\/p>\n<p>4. <b>There is no explicit way to &#8220;switch to&#8221; a workspace.<\/b> You just create it and it becomes tied to the directory current at the time of creation. Or something like that. Not really fully documented (or I could not find where). Then you need to add any mappings you want to it.<\/p>\n<p>5. <b>When you are done, don&#8217;t forget to delete your workspace<\/b>, so the global namespace is not polluted with temporary stuff. I would not even ask what happens if some other process on the same machine tries to get the same project into another directory at the same time.<\/p>\n<p>6. <b><code>tf workspace \/delete<\/code> command would ask are you really sure<\/b> to delete the thing. You can give it a \/noprompt switch to shut up, but <b><font color=\"red\">this switch is not documented<\/font><\/b> at the time of writing <a href=\"http:\/\/msdn.microsoft.com\/en-US\/library\/y901w7se%28v=VS.80%29.aspx\">(MSDN documentation)<\/a>.<\/p>\n<p>7. <b><code>tf workspace \/new<\/code> is even more interesting &#8211; by default it would open <font color=\"red\"><b>A GUI DIALOG!<\/b><\/font><\/b>. Dear Microsoft people! Opening GUI dialogs from command line tools is a bad, bad, bad idea. Command line tools tend to run in batch modes on computers that nobody looks at. There will be no one there to enter the data and click &#8220;OK&#8221;. Mixing the GUI world and the command line world is inconvenient at best.<\/p>\n<p><b>Bottom line:<\/b> this is the first line I had to deal with the <b>tf<\/b> utility and I am appalled by the design of the whole thing. You can finally get what you need, but it is very, very painful. <a style=\"display:none\" href=\"http:\/\/www.codeproject.com\/script\/Articles\/BlogFeedList.aspx?amid=1181663\" rel=\"tag\">CodeProject<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How do you copy an SVN label to a folder? svn serverpath\/tags\/label destdir How do you copy a TFS label to a folder? Watch my hands: mkdir destdir cd destdir <a href=\"https:\/\/ikriv.com\/blog\/?p=637\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[2,5],"tags":[],"class_list":["entry","author-ikriv","post-637","post","type-post","status-publish","format-standard","category-misc","category-dev"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/637","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=637"}],"version-history":[{"count":0,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/637\/revisions"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=637"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=637"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=637"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}