Я уже как-то писал, что “изобретатель” shelves в TFS – по всей видимости человек, одаренный особыми, неподвластными нам, простым смертным, качествам. По сути наличие в системе контроля версий “возможности” временно сохранить что-о не в репозитории, а в каком-то странном четвертом измерении противоречит самой идее системы контроля версий. Какой такой идее, спросите Вы? Да очень простой – изменил код – коммить изменения. Если коммитить нельзя (кто сказал, что нельзя? Плюнь ему в рожу!), все равно коммить. Займи, но выпей, то есть, создай свой бранч, но коммить!
Отступления от этого правила, впрочем, обычно ни к чему плохому не приводят. Однако, вы видели хоть один программный проект, который протекал бы как обычно? Нюанс, как говорится в анекдоте.
Зарисовка с натуры – продукт ушел в печать, код заморожен. Релиз уже завтра (или позавчера), и тут тестеры находят баг. Или бажище. Или Баг Шредингера, который проявляется только в 50% случаев, если его искать специально. Как бы то ни было, баг есть. Исправить его – тоже “есть”. А вот теперь тот самый нюанс – коммитить изменения в основное дерево низзя! Особенно если проект большой и тяжелый, решение о том, как и в каком виде подавать багфикс, может приниматься на самом верху – то ли хотфикс выпустить, то ли сервис-пак готовить, то ли забить и ждать новой версии. Пока политки играют в свои игры, программисты у себя в подвале решили изменения в shelve положить, дабы собрать-протестировать-провести code review. Сказано – сделано. А тут, не прошло и полгода, большие боссы постановили – сервис-паку быть!
Недолго думая, сделали бранч. И… обломались очень жестко. TFS позволяет делать unshelve’ код только в ту же ветку, откуда ему сделали shelve. И никак иначе. С SVN все проще, чем два байта переслать – svn copy, svn switch и следующий коммит будет уже в новую ветку. TFS же, к счастью, предлагает возможность сделать unshelve в другую ветку. Если установлены TFS power toys (как? У Вас еще не установлены?), без которых в TFS 2005 даже банальнейшего tree difference нет, то можно из командной строки сделать tfpt unshelve /merge. К несчастью, это не всегда работает – в моем случае попытка завершалась маловразумительным сообщением вроде “Cannot determine workspace”.
Решать проблему пришлось дедовским методом – доставать beyond compare и тупо сравнивать каталоги на диске. Кстати, если кто рискнет повторить сей трюк – сделать зарание Check-out всего дерева в той ветке, куда собираемся коммитить – очень, очень хорошая идея.