IT Share you

Team Foundation Server와 함께 Mercurial을 실제로 사용하십니까?

shareyou 2020. 11. 8. 11:35
반응형

Team Foundation Server와 함께 Mercurial을 실제로 사용하십니까?


내 가게는 TFS를 사용하며 일반적으로 로컬 저장소 커밋 / 복구가 없다는 점을 제외하고는 만족합니다. 저는 Mercurial을 로컬에서 직접 사용하여 소규모 변경 사항을 관리 한 다음 TFS에 게시하기 시작했습니다. Subversion에는 중앙 VCS가 Subversion 인 경우이를 자동으로 활성화하는 '브리지'구성 요소가 있습니다. Team System 용을 찾지 못했습니다. 이것은 다른 사람들이 DVCS를 CVCS 시스템과 통합함으로써이 길을 갔다는 것을 저를 격려합니다.

(1) 아는 사람 있나요? 나는 그것을 의심하고 있습니다 (빠른 검색은 아무것도 찾지 못했습니다).

(2) Mercurial / TFS를 이런 방식으로 사용하는 사람이 있습니까? 그렇다면 경험을 공유 할 수 있습니까? 저는 특히 Mercurial을 통한 중요한 활동 후 TFS에 대한 커밋과 관련하여 명확하지 않은 문제가 발생할 수있는 통찰력을 찾고 있습니다.

내가 며칠 동안 if를 사용하는 것만으로도 지금까지 완전한 윈-윈처럼 보이지만, 그렇게 쉽다고 생각할만큼 충분히 알고 있습니다.


이것이 여러분이 아직 모르는 것이 있는지 확실하지 않지만, 저는 지금 잠시 동안 로컬에서 수은을 사용해 왔으며 지금까지 두 소스 제어 시스템을 관리하는 추가 된 오버 헤드보다 이점이 더 크다고 생각합니다. 내가 일을해온 방법은 다음과 같습니다.

  1. TFS 체크 아웃을 "마스터"라고 생각하는 HG 저장소로 만들었습니다. TFS에서 업데이트를 받아이 리포지토리에 커밋하므로 여기에는 TFS에서 가져온 프로젝트의 최신 상태가 포함됩니다. 여기서 중요한 점은 TFS 업데이트 또는 Hg 병합 (2 부)과 관계없이 변경된 사항이 없다는 것입니다.

  2. 변경해야 할 때마다 "마스터"저장소를 복제하고 거기서 작업을 수행합니다. 기능 또는 스토리별로 클론은 실제로 관리하기가 매우 쉽고 깔끔한 느낌이 듭니다. 기능을 완료하면 모든 TFS 업데이트가 적용된 "마스터"리포지토리로 Hg 병합을 다시 수행합니다. 이를 통해 TFS가 코드를 병합한다고 주장 할 수있는 방법에 의문을 제기 할 때 TFS보다 훨씬 우수한 Mercurials 병합 기능을 사용할 수 있습니다. 병합이 완료되면 Hg에서 커밋 한 다음 해당 변경 사항을 TFS로 확인합니다. 가장 좋은 점은 TFS에 체크인 할 때 아무것도 병합 할 필요가 없다는 것입니다. 아주 아주 좋은.

이제이 접근 방식에서 발견 한 문제는 다음과 같습니다.

  1. 가장 큰 것은 TFS가 변경 사항을 찾기가 형편 없다는 사실입니다. 메이크업 쓰기 가능한 당신이 수정 된 파일들이 업데이트 될 때 / 의욕에 의해 합병 쓰기 가능하게하는 데 사용할 수있는 플러그인. 이에 대해 찾은 두 가지 옵션이 있습니다. TFS를 강제로 오프라인으로 전환하여 쓰기 가능한 모든 항목을 체크인해야한다고 가정하거나 소스 제어 도구의 비교 도구를 사용하여 변경된 파일을 선택하고 개별적으로 체크 아웃 할 수 있습니다. 둘 다 엉뚱한 IMO입니다.

  2. 소스 제어 바인딩은 hg 리포지토리에서 TFS 소스 제어 파일을 제외하더라도 여전히 프로젝트 수준에 있습니다. 이것은 솔루션에 파일을 추가 할 때까지 명확하지 않습니다. 그 시점에서 소스 제어에 추가하려고합니다. "Undo Pending Changes"를 사용하여 소스 제어 추가를 제거 할 수 있지만 정말 짜증납니다.

좋은 소식은 제가 TFS 도구를 사용하도록 강요 받았다면 어떤 형태의 강력한 약물을 사용하게 만들었을 것 같은 대규모 병합을 통해이 접근 방식을 사용했다는 것입니다.

아직 TFS 내에서 분기를 업데이트하는 데 이것을 적용하지는 않았지만 TFS에서 병합하기 위해 제공되는 옵션보다 훨씬 낫다고 생각합니다. 관련 메모에서 작업 기능의 청크를 한 번에 확인할 수 있기 때문에 기능에 필요한 모든 변경 사항이 한곳에 함께 있기 때문에 TFS 병합을 사용하는 것이 문제가 적습니다.

내가 다루려고하지 않은 한 가지는 팀 전체에서 이것을 공유하는 것입니다. 그 이유 중 하나는 팀 전체가 될 필요가 없다는 것입니다. 저는 원격으로 일하기 때문에 로컬 저장소를 갖는 것은 큰 일이며 많은 시간을 절약합니다. 내 개발 팀의 다른 구성원은이 접근 방식에서 동일한 이점을 얻거나 얻지 못할 수도 있지만, 작업 방식에 영향을주지 않고 할 수 있다는 것이 꽤 멋지다는 것을 알았 습니다.

업데이트 코멘트를 기반으로 한 추가 정보와 대규모 TFS 리포지토리 작업 경험 중 일부를 사용하여 잠시 동안이 응답을 업데이트하고 싶었습니다.

먼저 @ Eric Hexter 가 주석에서 지적했듯이 리베이스 확장사용 하여 작업 리포지토리의 커밋을 기본 TFS 리포지토리로 더 잘 통합 할 수 있습니다 . 하지만 커밋이 TFS에 표시되는 방식에 따라 축소 확장사용 하여 변경 사항을 단일 커밋으로 스쿼시 할 수 있습니다 (이는 TFS에서 롤백을 더 쉽게 만들 수 있음). 또한 TFS에 변경된 사항을 쉽게 알 수 있도록하는 작업을 수행 할 수있는 TFS PowerTools 의 "online"명령도 있습니다 (그의 블로그 게시물 에 언급 한 Eric에게 다시 한 번 감사드립니다 ).

이제 제가 처음이 글을 썼을 때 저는 개발자들이 사용하는 TFS 브랜치가 하나 뿐이고 상당히 작은 프로젝트를 작업하고 있었기 때문에 리포지토리 복제는 별 문제가 아니 었습니다. 나중에 나는 체크 아웃 후 약 1.5GB의 리포지토리가 있고 빌드 후 훨씬 더 큰 프로젝트에서 작업하고 있으며 TFS에서 분기 간 전환이 자주 포함되는 것을 발견했습니다. 분명히이 접근 방식은이 환경에 적합하지 않습니다 (특히 한 지점에서 임의의 디렉토리에 솔루션을 빌드하는 것이 불가능했기 때문에).

크기 문제는 저장소를 새 디렉토리로 복제하는 대신 gits 주제 분기와 유사한 기술을 사용하여 가장 잘 처리됩니다. 이에 대한 몇 가지 옵션이 있습니다. 실제로 북마크 확장 을 사용하는 것이 가장 좋습니다.그리고 주제 분기보다는 주제 "책갈피"를 만듭니다. 명명 된 브랜치를 사용할 수도 있지만 영구적이고 클론을 가지고 여행하는 약간의 단점이 있습니다 (멋진 TFS-Hg 하이브리드를 동료와 공유하려는 경우). 북마크는 리포지토리에 로컬이며 효과적으로 커밋을 가리키고 헤드와 함께 이동합니다. Hg가 개정 (병합, 업데이트 등)을 예상하는 모든 장소에서 사용할 수 있도록 구현됩니다. 이를 사용하여 TFS에서만 업데이트를 가져오고 주제 작업에서 병합하는 기본 "분기"로 TFS 책갈피를 만들 수 있습니다. 각 항목에는 고유 한 책갈피가 있으며 TFS에 다시 커밋 한 후에는 삭제할 수 있습니다. 명명 된 분기를 사용하려는 경우 정확히 동일한 기술을 적용 할 수 있으므로 편리합니다.

이제 다중 분기 문제는 더 까다 롭습니다. 특히 TFS "분기"는 실제로 원래 분기의 모든 파일의 복사본이므로 TFS에서 분기를 가져올 때마다 리포지토리가 훨씬 더 커집니다. 이를 처리하는 한 가지 가능한 방법은 명명 된 Hg 분기와 책갈피의 조합을 사용하여 각 TFS 분기에 대한 분기를 만든 다음 해당 분기에서 작업에 대한 책갈피를 만드는 것입니다. 이러한 시나리오의 진짜 골칫거리는 실제로이 모든 것을 통해 TFS 작업 영역을 처리하는 것입니다. 작업 공간에서 매핑을 제거하고 꽤 멀리 갈 수 있지만 작업 디렉토리로 다시 매핑하면 파일에 대한 TFS 스톰 핑에주의해야합니다 (실제로 TF PowerTools가 유용한 곳입니다). 분기를 전환하는 동안 작업 공간을 연결된 상태로 두려고하면 추악해질 수 있습니다. 도구 벨트에 있으면 좋은 몇 가지 도구는 Hg입니다.퍼지 확장 및 TF PowerTools "scorch"명령. 둘 다 버전 제어에없는 파일을 효과적으로 제거합니다 (기술적으로 "스코치"는 TFS와 로컬 작업 디렉터리가 일치하는지 확인하므로 파일도 업데이트 할 수 있음).

하지만 저에게는이 프로세스가 상당히 부담스럽고 ​​오류가 발생하기 쉽습니다. 저는 최근에 git-tfs 와 함께 git 을 사용하는 것으로 전환 했습니다. TFS 작업 영역을 관리하고 그 측면과 관련된 많은 부담을 덜어주기 때문입니다. 안타깝게도 "hg-tfs"가 어디에도없는 것처럼 보이거나 아마도 그것을 선택했을 것입니다.


mercurial에 갇혀 있지 않다면 git-tfs라는 달콤한 git / tfs 통합 프로젝트가 있습니다. git-svn과 매우 유사하지만 대신 TFS에서 푸시 / 풀링합니다. http://github.com/spraints/git-tfs 에서 확인하십시오.


@Eric,에서 게시물 lostechies가 가장 도움이되었다. VS2010 에서는 푸시 스크립트 tftp 온라인 명령에 / diff/ deletes 옵션을 추가 하여 변경 및 삭제 된 파일을 TFS에 체크인해야했습니다. 처음에는 hg 업데이트" FileXyz 를 제거 할 수 없습니다 : 액세스가 거부되었습니다" 라는 파일이 삭제되었을 때 푸시에서 오류가 발생했습니다 . MakeWritable.py 확장 프로그램을 설치했지만 파일이 삭제되지 않고 열릴 때만 작동합니다. 그래서 attrib 에 대한 호출을 추가 하여 프로젝트의 모든 파일에서 READ-ONLY를 제거한 다음 나중에 복원합니다 (.hg 폴더 제외). / diff 도 추가했습니다.

옵션을 사용하여 READ-ONLY 속성에 의존하는 대신 MD5 체크섬으로 차이를 감지합니다. 이제 잘 작동하는 것 같습니다.

=====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로 /에서 밀기 / 당기기를 한 번의 클릭으로


일부 사람들은 Subversion 브리지와 함께 hgsubversion을 사용했습니다. 얼마나 잘 작동했는지 모르겠고 TFS를 사용할 필요가 없었습니다.

내가 아는 한, TFS-> Subversion Bridge-> hgsubversion을 사용하는 것보다 "더 많은 기본"브릿지는 없지만 꽤 잘 작동한다고 들었습니다. TFS에 대한 나의 극히 제한된 이해는 내부 모델이 hgsubversion과 같은 것이 실제로 잘 작동하기 위해 Subversion과 충분히 유사해야 함을 시사합니다.


DVCS 및 TFS로 작업 할 수 있도록하려면 가장 좋은 방법은 TFS 용 SVNBridge 를 설치하고 Bazaar를 사용 하는 것입니다. 즉, AFAIK는 SVN과 쉽게 통합되는 유일한 DVCS입니다. SVN처럼 보이며 마법처럼 Bazaar / TFS 통합을 얻습니다.


다음은 TFS 및 hg 작업에 사용한 powershell 스크립트입니다. 사용하려면 TFS 폴더에 hg 리포지토리를 만들고 (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

저는 Mercurial과 TFS 저장소를 동기화하는 목표를 달성하려는 작은 도구 인 HgTfs를 모았습니다. 정말 간단하고 클론, 풀, 푸시의 세 가지 명령 만 있습니다. 내 Bitbucket 저장소는 다음과 같습니다.

https://bitbucket.org/thepretender/hgtfs

워크 플로 및 사용 시나리오를 설명하는 블로그 게시물도 있습니다 (실제로 위키 페이지는이 블로그 항목의 일부일뿐입니다).

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

The code is hacky, but it seems to get the job done. I would really appreciate any feedback or forks :)


I had a good try at getting it working. I could get Git and TFS playing together (link) via svnbridge, but I couldn't get mercurial to work via svnbridge which frustrated me no end. If you manage to get it working let me know, because I personally prefer mercurial over git (though both are great)

참고URL : https://stackoverflow.com/questions/2331636/real-world-use-of-mercurial-with-a-team-foundation-server

반응형