2010-02-25 3 views
67

Мой магазин использует TFS &, как правило, доволен им, за исключением отсутствия локального репозитория. Я начинаю использовать Mercurial локально, чтобы помочь управлять небольшими фрагментами изменений, а затем отправлять их в TFS. Я вижу, что Subversion имеет компонент «bridge», чтобы автоматически включить это, если центральный VCS является Subversion. Я не нашел его для Team System. Это побуждает меня, чтобы другие люди пошли по этому пути с интеграцией DVCS с системами CVCS.Использование Mercurial в реальном мире с помощью Team Foundation Server?

(1) Кто-нибудь знает об этом? Я как бы сомневаюсь в этом (быстрый поиск не нашел ничего).

(2) Используется ли кто-либо с помощью Mercurial/TFS? Если да, можете поделиться своим опытом. Я особенно ищу информацию о том, какие проблемы могут возникнуть, которые не очевидны в отношении фиксации TFS после значительных действий через Mercurial.

Похоже, что общий выигрыш до сих пор используется только для меня, если на несколько дней - но я знаю достаточно, чтобы подумать, что это просто так просто.

ответ

53

Не уверен, что это все, о чем вы еще не знаете, но я использую ртуть локально в течение некоторого времени, и до сих пор я думаю, что преимущества перевешивают дополнительные накладные расходы на управление двумя системами управления версиями , Вот как я делал вещи:

  1. я сделал TFS проверку репозитория HG, который я считаю своим «хозяином». Я получаю обновления от TFS и привязываю их к этому репо, поэтому он содержит самое текущее состояние проекта из TFS. Важно то, что никаких изменений в этом нет, независимо от обновления TFS или слияния Hg (которое является частью 2)

  2. В любое время, когда мне нужно внести изменения, я клонирую свое «мастерское» репо и делаю моя работа там. Я обнаружил, что клон для каждой функции или истории на самом деле довольно прост в управлении и выглядит довольно чистым. Как только я завершаю функцию, я возвращаю Hg обратно в «master» репо, в котором были применены все обновления TFS. Это позволяет мне использовать возможности Merurials merge, которые до сих пор превосходят TFS, чтобы подвергнуть сомнению, как TFS может претендовать на слияние кода вообще. Как только слияние завершено, я фиксирую его в Hg, а затем проверю эти изменения на TFS. Лучшая часть этого заключается в том, что, когда я делаю checkin для TFS, мне не нужно что-либо слить. Очень очень хорошо.

Теперь, вот те вопросы, которые я нашел с этим подходом:

  1. Крупнейшим из них является тот факт, что TFS паршивый при обнаружении изменений. Существует плагин make writable, который вы можете использовать для внесения изменений в файлы, когда они обновляются или объединяются Mercurial. Для этого есть два варианта. Вы можете либо заставить TFS выйти в автономный режим, и в этот момент он предположит, что нужно что-либо записывать, или вы можете использовать инструмент сравнения в инструменте управления версиями и выбирать измененные файлы и индивидуально проверять их.Оба являются crappy IMO

  2. Связи с контролем источника по-прежнему находятся на уровне проекта, даже если вы исключаете файлы управления источником TFS из своего hg-репозитория (что вы должны делать). Это не очевидно, пока вы не добавите файл в решение, после чего он попытается добавить его в исходный элемент управления. Вы можете «Отменить ожидающие изменения» и избавиться от добавления контроля источника, но это очень раздражает.

Хорошая новость заключается в том, что я использовал этот подход к работе через довольно массивное слияния, которые я думаю, что бы заставил меня обратиться к какой-либо форме твердых препаратов, если бы я был вынужден использовать инструменты TFS, чтобы сделать это ,

Я еще не применял это для обновления ветвей в TFS, но я предполагал, что это будет намного лучше, чем параметры, которые вы даете для слияния в TFS. В соответствующей заметке, поскольку вы можете одновременно проверять куски рабочих функциональных возможностей, использование слияния TFS было бы менее проблематичным только потому, что все изменения, необходимые для функции, были бы объединены в одном месте.

Одна вещь, которую я не пытался решать, - это обмен ею по всей команде. Отчасти причина в том, что это действительно не обязательно для всей команды. Я работаю удаленно, поэтому наличие локального хранилища - это большое дело и экономит много времени. Другие члены моей команды разработчиков могут или не могут получить такую ​​же выгоду от этого подхода, но я нахожу это довольно крутым, чтобы я мог не работать так, как они работают.

Update Я давно хотел обновить этот ответ на какое-то время с дополнительной информацией на основе замечаний, и некоторые из моих опытов, работающих с большими хранилищами TFS.

Во-первых, как следует из комментариев Eric Hexter, вы можете использовать rebase extension, чтобы лучше интегрировать фиксации из ваших рабочих репозиториев в ваш основной репозиторий TFS. Хотя, в зависимости от того, как вы хотите, чтобы ваши коммиты появлялись в TFS, вы можете использовать collapse extension, чтобы выровнять ваши изменения в один фиксатор (это упростит откаты в TFS). Существует также команда «онлайн» от TFS PowerTools, которая может заставить работу TFS узнать, что изменилось легче (еще раз спасибо Эрику за упоминание, что в его blog post)

Теперь, когда я изначально написал это, я работал над проект, который имел только одну ветвь TFS, которую использовали разработчики, и был довольно маленьким, поэтому клонирование хранилищ не было большим делом. Позже я обнаружил, что работаю над проектом, у которого было репо, которое составляло около 1,5 ГБ после проверки, и намного больше после сборки, и часто включало переключение между ветвями в TFS. Очевидно, что этот подход не очень подходит для этой среды (в частности, поскольку в какой-то момент невозможно было создать решения в произвольном каталоге.

Проблема с размерами лучше всего обрабатывать, используя технику, похожую на ветви ветвей gits, а не на клонирование репозитории для новых каталогов.Есть несколько вариантов для этого.Я думаю, что лучше всего на самом деле использовать bookmark extension и создавать темы «закладки», а не темы ветвей. Вы также можете использовать именованные ветви, но у них есть небольшой недостаток: быть постоянным и путешествовать с любыми клонами, которые вы можете сделать (если вы хотите поделиться своим отличным гибридом TFS-Hg с коллегой). Закладки являются локальными для вашего репо и эффективно указывают на фиксацию и перемещение с головой. так что они могут использоваться в любом месте, где Hg ожидает ревизии (поэтому объединяет, обновляет, e дц). Вы можете использовать их для создания закладки TFS в качестве основной «ветки», которая получает только обновления от TFS и сливается с работой темы, каждая из которых имеет свои собственные закладки, и вы можете удалить ее после того, как вы вернетесь в TFS. Если вы предпочитаете использовать именованные ветви, то вы можете применять точно такие же методы, что удобно.

Теперь проблема с несколькими ветвями сложнее, тем более что «ветви» TFS являются фактически копиями каждого файла из исходной ветви, а это означает, что каждый раз, когда вы тянете ветви с TFS, ваше репо собирается получить столько больше. Один из возможных способов справиться с этим - использовать комбинацию названных ветвей Hg и закладок, так что у вас есть ветвь для каждой ветви TFS, а затем создайте закладки для вашей работы из этих ветвей. Настоящая головная боль в этих сценариях фактически связана с рабочими пространствами TFS через все это. Вы можете удалить сопоставления в своих рабочих пространствах и получить довольно далеко, но как только вы вернетесь в свой рабочий каталог, вы должны быть осторожны с TFS, топая файлами (на самом деле это полезно, когда TF PowerTools пригодится). Попытка оставить рабочую область при подключении, когда ваши ветви переключения становятся уродливыми. Парой инструментов, которые приятно иметь в вашем наборе инструментов, являются Hg purge extension и команда TF PowerTools «scorch». Оба эффектно удаляют файлы, которые не находятся в контроле версий (технически «scorch» гарантирует соответствие TFS и вашей локальной рабочей директории, поэтому она также может обновлять файлы).

Для меня этот процесс стал довольно обременительным и подверженным ошибкам. Недавно я переключился на использование git с git-tfs, так как он управляет рабочими пространствами TFS для меня и снимает с себя большую нагрузку, связанную с этой стороной. К сожалению, там нигде нет «hg-tfs», иначе я бы выбрал это.

+0

Я сделал аналогичный подход, за исключением того, что он был благословенным центральным репо. И перечисленные вами проблемы существуют и там. Я пытаюсь настроить свой рабочий процесс на функции сфокусированные и функциональные возможности патчей до сих пор, я был очень доволен этим. –

+2

Слияние с TFS при использовании встроенного инструмента. У Джеймса Мэннинга есть хорошая статья о том, как поменять его на что-то гораздо лучше (мне нравится DiffMerge от SourceGear) http://blogs.msdn.com/b/jmanning/archive/2006/02/20/diff-merge-configuration- in-team-foundation-common-command-and-argument-values.aspx – StingyJack

+13

Я рассказывал о своем опыте использования этой установки. http://www.lostechies.com/blogs/hex/archive/2010/06/22/using-mercurial-as-a-local-repository-for-team-foundation-server-start-front-n.aspx Я добавил несколько сценариев powershell для автоматизации использования hg и TFS powertools. Другое расширение, которое я использовал, было hg rebase, чтобы слияние на стороне HG было очень простым. Я знаю, есть две простые команды powershell. push и pull, которые делают тяжелый подъем работы команд hg и tfs команд в правильном порядке. –

3

Я знаю, что некоторые люди использовали hgsubversion с мостом Subversion. Я не знаю, как хорошо это работает, и мне никогда не приходилось использовать TFS.

Насколько мне известно, нет «более родного» моста, чем использование TFS -> Subversion Bridge -> hgsubversion, но я также слышал, что он работает достаточно хорошо. Мое чрезвычайно ограниченное понимание TFS предполагает, что его внутренняя модель должна быть достаточно подобна Subversion для таких вещей, как hgsubversion, чтобы работать очень хорошо.

1

У меня была хорошая попытка заставить его работать. Я мог бы заставить Git и TFS играть вместе (link) через svnbridge, но я не мог получить меркурий, чтобы работать через svnbridge, что разочаровало меня в этом. Если вам удастся его запустить, дайте мне знать, потому что я лично предпочитаю меркурийный над git (хотя оба они замечательные)

+0

Разве вы не могли использовать биты Codeplex? http://blogs.msdn.com/bharry/archive/2010/01/27/codeplex-now-supports-mercurial.aspx –

+0

Насколько мне известно, поддержка mercurial - это полностью отдельный сервер из TFS. Это не мостовая компоновка, как с поддержкой Subversion. –

2

Если вы хотите иметь возможность работать с DVCS и TFS, я считаю, что лучший способ - установить SVNBridge для TFS, а также использование Bazaar, что, AFAIK единственных DVCS, который легко интегрируется с SVN, и так как ваш TFS теперь выглядит как SVN, вы волшебным образом получить интеграции Bazaar/TFS

+0

Вы также можете использовать Mercurial перед SVN, подробнее здесь: http://abdullin.com/journal/2010/3/22/use-tortoisehg-mercurial-with-svn-repository.html –

9

Если вы не застряли на mercurial, есть проект интеграции git/tfs, который я использовал, называемый git-tfs. Он очень похож на git-svn, но вместо этого нажимает/тянет от TFS. Проверьте это в http://github.com/spraints/git-tfs

+0

Спасибо, Джон, я проверю это из. – Maggie

5

@ Эрик, ваше сообщение в lostechies было наиболее полезным. С VS2010 мне пришлось добавить опции /diff и /удаляет в tftp online команда в сценарии push, чтобы получить измененные и удаленные файлы, подлежащие проверке, в TFS. Первоначально я получал ошибку от нажатия, когда файл был удален (из -working), что hg update is
«не удалось удалить FileXyz: доступ запрещен».
Я установил расширение MakeWritable.py, но это работает только при открытии файлов, которые не были удалены. Поэтому я добавил звонок в атрибут, чтобы удалить READ-ONLY из всех файлов проекта, а затем восстановить его (исключая папку .hg). Я также добавил опцию /diff, так что отличия обнаруживаются с помощью контрольной суммы MD5 вместо зависимости от атрибута READ-ONLY. Кажется, теперь он работает нормально.

=====FILE: push.ps1===== 
$projName = "TicTacToeCMMI" 
$tftp = "C:\Program Files\Microsoft Team Foundation Server 2010 Power Tools\TFPT.exe" 
$tf = "C:\Program Files\Microsoft Visual Studio 10.0\Common7\ide\tf.exe" 

hg push 
cd ..\$projName-tfs 
"Syncing -tfs workspace with TFS server" 
&$tftp scorch /noprompt /exclude:.hg',_Resharper*',*.user 
"Making all files in -tfs writable" 
attrib -R /S /D * 
"Updating -tfs with latest push from Mercurial" 
hg update -C -y 
attrib +R /S /D * 
attrib -R /S /D .hg\* 
"Resyncing Mercurial changes with TFS Server" 
&$tftp online /adds /deletes /diff /exclude:'.hgignore,.hg,bin,obj,*.ps1,_Resharper*,*.lnk,*.user,*.suo,*.vspscc' 
"Checkin" 
&$tf checkin 
cd ..\$projName-working 
cmd /c pause 

====FILE: pull.ps1===== 
$projName = "TicTacToeCMMI" 
$tf = "C:\Program Files\Microsoft Visual Studio 10.0\Common7\ide\tf.exe" 
$username = cmd /c set USERNAME 
$username = $username.SubString($username.IndexOf("=")+1) 

function pull { 
    cd ..\$projName-tfs 
    &$tf get 
    hg commit -A -m "from tfs" --user $username 
    cd ..\$projName-working 
    hg pull --rebase 
} 
pull 
cmd /c pause 

У меня была небольшая обучающая кривая с сценариями PowerShell, которые я раньше не использовал.Для других, как мне скрипты запускаются с ярлыка, как это:

TARGET: C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe C:\dev\TicTacToeCMMI-working\push.ps1 
START IN: C:\dev\TicTacToeCMMI-working 

Я положил толкать и тянуть ярлыки на моей панели задач так Тяни/Толкай в/из TFS является одним нажатием кнопки

2

Вот PowerShell сценарий, который я использовал для работы с TFS & hg. Для использования вам нужно создать hg-репозиторий в вашей папке TFS (зафиксировать в нем файлы из TFS), клонировать этот репозиторий и работать в новом репозитории. После того, как вы счастливы, вы можете запустить «hgtfs.ps1 push», чтобы вернуть изменения в TFS из вашего ртутного хранилища.

hgtfs.ps1:

param([parameter(Position=0, Mandatory=$true)][string] $action) 

$HGDirectory = Get-Location 
$TfsDirectory = @(hg paths | where-object { $_.StartsWith("default = ") })[0].SubString(10) 

# Pull from TFS 
function pull 
{ 
    # Todo pull changes one by one brining who did it and the comment into HG 
    # tf history . /recursive /format:brief /noprompt /version:300~1000 /sort:ascending 
    # tf properties . /recursive 

    # Add the changes from TFS into the TFS HG repository 
    Set-Location $TfsDirectory 
    tf get . /recursive 
    hg commit -A -m "Update from TFS" 

    # Pull/merge the changes from TFS's HG repository 
    Set-Location $HGDirectory 
    hg pull 
    hg merge --tool internal:fail 
    hg commit -m "Merged from TFS" 

    "" 
    "The you have the following conflicts which need resolving" 
    hg resolve -l | write-host -foregroundcolor "red" 
    #thg commit 
} 

# Push to TFS 
function push 
{ 
    Set-Location $HGDirectory 
    hg push 
    Set-Location $TfsDirectory 

    $FilesModified = @() 
    $FilesRenamed = @{} # Key: old file name .... Val: new file name 
    $FilesRemoved = @() 
    $FilesAdded = @() 

    # Work out what changes have taken place 
    "Calculating the changes which have been made in HG..." 
    tfpt scorch /exclude:.hg,*.user | out-null 
    $AllChanges = hg status --rev .:tip -A 
    for($i = 0; $i -lt $AllChanges.length ; $i++) 
    { 
     $type = $AllChanges[$i].SubString(0, 2) 
     $fileName = $AllChanges[$i].SubString(2) 

     switch($type) 
     { 
      "M " # Modified files 
       { 
        $FilesModified += $fileName 
       } 

      "A " # New Files 
       { 
        $nextType = $null 
        $nextFileName = $null 
        if($AllChanges.length -gt ($i+1)) 
        { 
         $nextType = $AllChanges[$i+1].SubString(0, 2) 
         $nextFileName = $AllChanges[$i+1].SubString(2)     
        } 

        if($nextType -eq " ") 
        { 
         # we have a rename 
         $FilesRenamed[$nextFileName]=$fileName 
         $i++ 
        } 
        else 
        { 
         # we're adding the file 
         $FilesAdded += $fileName 
        } 
       } 

      "R " # Removed 
       { 
        if($FilesRenamed.ContainsKey($fileName)) 
        { 
         continue 
        } 

        $FilesRemoved += $fileName 
       } 

      "C " # Same 
       { 
        continue 
       } 

      default 
       { 
        "Unknown HG status line: "+$AllChanges[$i] 
        return -1 
       } 
     } 
    } 

    # perform the TFS operations 
    "Renaming files in TFS..." 
    foreach($file in $FilesRenamed.Keys) { 
     tf checkout $file | out-null 
     tf rename $file $FilesRenamed[$file] | out-null 
    } 

    "Checking out for edit in TFS..." 
    foreach($file in $FilesModified) { tf checkout $file | out-null } 

    "Removing files from TFS..." 
    foreach($file in $FilesRemoved) { tf delete $file | out-null } 

    # perform the Mercural update 
    "Pulling changes out of HG...." 
    hg update --rev .:tip --clean 

    # perform any POST TFS operations 
    "Adding new files to TFS..." 
    foreach($file in $FilesAdded) { tf add $file } 

    "Cleaning up..." 
    tfpt uu /noget 
    tf checkin 
} 


if ($action -eq "push") { push } 
elseif ($action -eq "pull") { pull } 
else { "Unknown action ... please supply 'push' or 'pull'" } 

# return to our starting point 
Set-Location $HGDirectory 
+0

Насколько хорошо работает этот скрипт Powershell? У кого-нибудь есть опыт использования этого? --James –

2

I'he просто собрать небольшой инструмент, HgTfs, который пытается достичь цели синхронизации Mercurial и TFS репозиториев. Это очень просто и имеет только три команды: клонировать, тянуть и нажимать. Вот мой Bitbucket репо:

https://bitbucket.org/thepretender/hgtfs

Существует также блог описания рабочих процессов и использования сценариев (на самом деле, вики-страницы только части этой записи в блоге):

http://www.olegtarasov.me/Post/2013/07/Mercurial-to-TFS-bridge-(hgtfs)

Код взломан, но, похоже, он выполняет свою работу. Я был бы очень признателен за любые обратные связи или вилки :)

+0

Приятно, я буду использовать это, когда мы перейдем от ClearCase к TFS (/ sigh) [Ищем «Стреляй меня с опцией рельсотрона» ... совершенно необходимо, чтобы: p] –

Смежные вопросы