Automerging in TFS

There’s an ongoing thread in my head on “what’s different in the land of Feature Branches”, but it hasn’t fermented into something postable yet.  However, there’s one low hanging fruit I can pluck: automatic merge between branches.

In the beginning, there was a branch…

First day hanging out with this team.  The client already has a stellar team of developers; we were discussing how we could work with them on this “other” feature that they don’t have time to handle. Overly dramatized:

  • We:  Pray tell, dear client, where shalt we code? 
  • Client:  Forsooth!  Thy code may be smelly as in fish; and perhaps thy project shalt be backburnered; thus thou shalt code here:  a subbranch from our development branch.
  • We: That shalt be wonderful, for we shall make this place our own, and be merry.

2 months go by.  The feature takes form, completely changes, and takes form again, and our code [B] is not so smelly.  However, we are also two months out of sync from their development branch; and we’re getting to the spot where we could think about releasing.  The problem:  They have had one release for feature [A], and then have another feature coming up [C] which is not ready to go.image

The painful merge

We ended merging our code [A] back into their code [C] … and then followed their normal release path up to QA and out.   Luckily, we were able to extract “just our feature” (plus a few extra styles) without moving their feature [C] (but that was luck, really).

That merge took a while:

  • 3 days: Dev1 to Dev2, code + database changes + 67 conflicts.  Dev2 now contains A+B+C. Merging sprocs outside of version control can be painful, thank you Beyond Compare for being wonderful.
  • 1.5 days: Dev2 back to Dev1, mostly dealing with merging (the same) stored procedures and schema, 4 (easy) code conflicts.   Dev1 now contains A+B+C.
  • Easy:  Parts of Dev1 (the “most recent commits”) to QA.  QA now has A+B and very little of C (a few styles crept in). 
  • Again: We were lucky that there was almost no overlap between B and C. 

Having no desire to redo that pain, we came up with a plan.

TeamCity Automerge script under TFS

We use TeamCity as our “easily installable build server”, so we set up a daily task at 5:30 in the morning to automatically merge anything new in our parent branch down to our branch:

$tf = get-item "c:\program files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\TF.EXE"
& $tf workspaces /server:http://TFSSERVER/tfs/defaultcollection
# Its very important that the right branch (source of automerge) be listed below. 
& $tf merge /candidate $/PROJECTNAME/Dev/A . /r
& $tf merge            $/PROJECTNAME/Dev/A . /r /noprompt
#if ($a -eq 0) { 
    & $tf checkin /comment:"automerge from A" /recursive /noprompt /override:"no workitem applies"
    # checkin with no changes yields a errorlevel 1
    if ($a -eq 1) { $a=0 } 
# move this out to a seperate build step to be sure it runs
& $tf undo . /r
exit $a
  • We had a problem with getting tf to recognize workspaces, hence the extra tf workspaces call.
  • the tf /merge candidate lists the possible items to merge – used for populating the build log with information for humans.
  • the actual merge yields a 0 if there were no conflict errors.  We save that to return later.  If there’s no changes, that’s a 0.
  • if there were no conflicts, do a checkin.   In this case, no changes is an error, so ignore that error.
  • finish up with a tf undo to “unlock” the files in tfs server. 
  • return the exit code that would indicate a conflict if there was one.
  • We are running Teamcity under one of our accounts, thus there’s no login information in the calls to TFS.  Most other VCS’s, we end up putting passwords in the script;  its not the best, but there are few alternatives.   Most companies that have a good build infrastructure usually have a build user for these kinds of things, which only the build admins know the password for, which once again would exclude us from using it.

Living with an Automerge

Most days it works fine.  But some days it has conflicts.   When it does have a conflict, it shows up as a failed build in TeamCity:


We started off with a 1-week rotation for dealing with conflicts, but that ended up being unfair to Tanner, he got 5 bad days in a row, so we switched to a round-robin “who has not done it recently” approach instead.

On the days that it did run green, opening the build log shows what got merged.  We hardly ever look at this:


New Branching Strategy

Learning something, and having now earned the client’s trust, our next branch is rooted at the QA level, so that our development branch is a peer to theirs.  This is a continuing experiment; there’s more to consider, hence the still-cooking post on Feature Branching.    

Till Later!

Tagged with: , , , ,
Posted in Code
5 comments on “Automerging in TFS
  1. Thank you for this post. I am going to implement Branch-Per-Feature and I will try out your script.

  2. klesky says:

    hi there, how do you run the scripts on team city?
    I’ve tried creating a build. with the runner type “Command Line” and running it. but it’s not working. please help

  3. Anindita says:

    how to do automerging in VSTS

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

.net 3d 3d-printing 4k abc15 algorithms ames android anonymous types audio editing aws backup basecamp beatunes biorhythm bittorrent blender blog boston marathon bpm c# caffeine campfire candycrush car carmax certification charity chiropractor cities-skylines clog clone codelouisville codepalousa coding coffee collaboration color run ComputerElbow ComputerVision configuration consulting cooking crash course crashplan crestwood cryptocurrency cycling dabda dan dapper DataSet ddl diabetes dictation dotnetcore dotnetmud downtown e-cycling elite excel exercise expiration facebook feature-branching firefall flipflops Flow FL Studio focus food forecastle fortresscraft franklinplanner gadgets game-design games git github google docs google maps gopro gps grandpa greenshot hack half marathon headless health heart rate hiren ignew integration testing interop inventory ios ipad itunes javascript jobs karma kdf keyboards keys kittens lamont laptop lavalamp leaf lego life lifehack linq linqtotwitter linux los angeles louisville mandelbulber massage therapy mastery-teaching maths merge metformin Minecraft miniature modeling monitor mud muhammad ali institute music mvc mycartracks netfabb nexus10 node nomanssky nostalgia nutrition nwipe oldham county grand slam opal openjscad openscad owin pacedj paper mockup pepakura performance photoscan politics pomodoro postgresql powershell premiere priorities prius process product-management project-management qa ReFS resharper review rmi roman road 5k RSI rubiks running samsung 700t sandals schedule scooter scribblelive selenium service shapeways sleep slic3r sneakersync snot software software-engineering solidoodle soylent spacegame speaking sql sqlite SSDT SSIS standing state-machine stayfocusd stonehearth studying sunset tablet teaching team teamcity teamtreehouse terraform tesla testing tfs time timelapse torque touch tracks trs80 Tuple tutor twitter ubuntu unit testing utilities video video editing visual studio vscode vsvim warp stabilizer windows 8 windows home server wordpress wpf xml
%d bloggers like this: