Real use of Mercurial with Team Foundation Server?

My store uses TFS and is generally happy with it, except for the lack of a local repository that commits / returns. I am starting to use Mercurial locally to help manage small snippets of changes and then send them to TFS. I see that Subversion has a “bridge” component to automatically enable this if the central VCS is Subversion. I did not find it for Team System. This encourages me to have other people take this path with DVCS integration with CVCS systems.

(1) Does anyone know about this? I kind of doubt it (a quick search did not find anything).

(2) Does anyone use Mercurial / TFS in this way? If so, can you share your experience. I am especially looking for any information about what problems might arise that are not obvious with respect to fixing TFS after a significant action through Mercurial.

It seems that at the moment I won only once, using only a few days, but I know enough to think that it is simple.

+67
tfs mercurial
Feb 25 '10 at 4:27
source share
8 answers

Not sure if this is something else you still don’t know about, but now I have been using mercurial locally for a while, and so far I think the benefits outweigh the additional overhead of managing the two version control systems. Here is how I did it:

  • I made my TFS checkout a repository of HG, which I consider my "master". I get updates from TFS and bind them to this repo, so it contains the most current state of the project from TFS. The important thing is that there is no change in this regardless of the TFS update or the Hg merge (which is part 2)

  • Anytime I need to make changes, I clone my "master" repo and do my work. I found that the clone for each function or story is actually quite easy to manage and looks pretty clean. As soon as I complete the function, I return Hg back to the "master" repo, in which all TFS updates have been applied. This allows me to use the capabilities of the Merurials merge, which still surpass TFS, to question how TFS can claim code merging at all. Once the merge is complete, I commit it to Hg and then check these changes on TFS. The best part of this is that when I do a checkin for TFS, I don't need to merge anything. Very very nice.

Now here are the problems I found with this approach:

  • The biggest is the fact that TFS is disgusting in its search for change. There is a make writable plugin that you can use to make modified files writable when they are updated / merged by Mercurial. There are two options for this. You can either force TFS to go offline, and at this point it will suggest that you need to write something, or you can use the comparison tool in the version control tool and select the modified files and individually inspect them. Both are crappy imo

  • Source control links are still present at the project level, even if you exclude TFS source control files from your hg repository (what you need to do). This is not obvious until you add the file to the solution, after which it will try to add it to the original control. You can “Undo Pending Changes” and get rid of adding a version control, but it is really annoying.

The good news is that I used this approach to work through a rather massive merger, which, I think, would lead me to turn into some form of hard drug if I were forced to use TFS tools for this.

I have not used this to update branches in TFS yet, but I assume that it will be much better than the options you give for merging in TFS. In a related note, since you can check pieces of working functionality at the same time, using a TFS merge would be less problematic just because all the changes needed for a function would be merged in one place.

One thing that I did not try to solve was the exchange of it throughout the team. Part of the reason is that it really is not necessary for the whole team. I work remotely, so having local storage is a big deal and saves a lot of time. Other members of my development team may or may not get the same benefit from this approach, but I find it pretty cool that I can without effect how they work.

Update I would like to update this answer for some time with additional information based on comments and some of my experiences with large TFS repositories.

First, as @ Eric Hexter points out in the comments, you can use the redirect extension to better integrate commits from your working repositories into the main TFS repository. Although, depending on how you want your commits to appear in TFS, you can use collapse the extension to clip your changes into a single commit (this can make rollbacks to TFS easier). There is also an “online team” from TFS PowerTools that can do the job of letting TFS know what has changed easier (thanks again to Eric for noting that on his blog )

Now that I originally wrote this, I was working on a project that had only one TFS branch that the developers used and was pretty small, so cloning the repositories was unimportant. Later I discovered that I was working on a project that had a repo that was about 1.5 GB after verification, and a lot more after build, and often included switching between branches in TFS. Obviously, this approach is not suitable for this environment (in particular, since at some point it was impossible to create solutions in an arbitrary directory.

The size problem is best handled using a technique similar to branches of gits branches, rather than cloning repositories into new directories. There are a couple of options for this. I believe that it’s best to use the extension and create a bookmark theme rather than a topic thread. You can also use named branches, but they have a slight drawback - being persistent and traveling with any clones you can do (if you want to share your great TFS-Hg hybrid with a colleague). Bookmarks are local to your repo and effectively indicate commit and move with your head. They are implemented so that they can be used anywhere where Hg is awaiting revision (therefore merging, updating, etc.). You can use them to create TFS bookmarks as the main "branch", which receives only updates from TFS and merges with the work of the theme, each of which has its own bookmarks, and you can delete it after you return to TFS. If you prefer to use named branches, then you can use exactly the same methods that are convenient.

Now the problem with multiple branches is more complicated, especially since the TFS branches are actually copies of each file from the original branch, which means that every time you pull branches with TFS, your repo is going to get a lot more. One possible way to handle with this, use a combination of the named Hg branches and bookmarks, so that you have a branch for each TFS branch, and then bookmark your work from these branches. The real headache in these scenarios is actually related to the TFS workspaces through it all. You can remove the mappings in your workspaces and get pretty far, but as soon as you get back to your working directory, you should be careful with TFS stomping files (this is actually useful when TF PowerTools comes in handy). Trying to leave the workspace when connected when your switch branches get ugly. A couple of tools that are nice to have in your toolbox are the Hg cleaning extension and the TF PowerTools scorch command. Both effectively delete files that are not in version control (technically, "scorch" ensures that TFS matches your local working directory, so it can also update files).

For me, however, this process has become quite onerous and error prone. I recently switched to using git with git-tfs , since it manages the TFS workspaces for me and removes the heavy load associated with this side. Unfortunately, there is no "hg-tfs" anywhere, otherwise I would choose this.

+53
Feb 28 '10 at 16:45
source share

If you are not stuck with mercurial, there is a sweet git / tfs integration project that I used called git-tfs. It is very similar to git-svn, but instead presses / pulls from TFS. Check it out at http://github.com/spraints/git-tfs

+9
Jun 24 '10 at 17:16
source share

@Eric, your post in lostechies was most helpful. Since VS2010, I had to add the / diff and / remove options to the tftp online command in the push script to get the modified and deleted files to check in TFS. Initially, I got an error from clicking when the file was deleted (from -working) that hg update is msgstr "cannot delete FileXyz: access is denied".
I installed the MakeWritable.py extension, but this only works when opening files that have not been deleted. So I added an attrib call to remove READ-ONLY from all the files in the project and then restore it (excluding the .hg folder). I also added / diff , so the differences are detected by the MD5 checksum instead of depending on the READ-ONLY attribute. It seems to be working fine now.

=====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 

I had a little learning curve with PowerShell scripts that I hadn't used before. For others like me, scripts run with a shortcut as follows:

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

I click on the taskbar push and pull, so push / pull to / from TFS is one click

+5
Jun 01 2018-11-11T00:
source share

I know that some people used hgsubversion with the Subversion bridge. I don’t know how well this works, and I never had to use TFS.

As far as I know, there is no "more native" bridge than using TFS -> Subversion Bridge -> hgsubversion, but I also heard that it works quite well. My extremely limited understanding of TFS suggests that its internal model needs to be matched enough for Subversion for things like hgsubversion to work very well.

+3
Feb 27 '10 at 17:45
source share

If you want to work with DVCS and TFS, I think the best way is to install SVNBridge for TFS and use Bazaar , which is AFAIK, the only DVCS that integrates easily with SVN, and since your TFS now looks like SVN, you will magically get integration Bazaar / tfs

+2
Jun 08 '10 at
source share

This uses the powershell script that I used to work with TFS and hg. To use, you need to create an hg repository in your TFS folder (commit files from TFS to it), clone this repository and work in a new repository. Once you are happy, you can run "hgtfs.ps1 push" to revert the changes to TFS from your mercury storage.

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 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 
+2
May 29 '12 at 15:05
source share

I just put together a small HgTfs tool that tries to achieve the goal of synchronizing Mercurial and TFS repositories. It is very simple and has only three commands: clone, pull and click. Here is my Bitbucket repeater:

https://bitbucket.org/thepretender/hgtfs

There is also a blog post describing a workflow and usage scenario (in fact, wiki pages are only parts of this blog post):

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

The code is hacked, but it seems to be doing its job. I would really appreciate any feedback or forks :)

+2
Jul 28 '13 at 11:07 on
source share

I had a good attempt to make it work. I could get Git and TFS by playing together ( link ) via svnbridge, but I could not get mercury to work through svnbridge, which upset me There is no end. If you manage to get it working, let me know, because I personally prefer mercurial over Git (although both are great)

+1
Mar 11 '10 at
source share



All Articles