This is an e-mail conversation I wish I’d had somewhere more publicly. At the other end is a friend with TFS experience (whom I met at a Coaching Stance class with Lyssa Adkins and David Darst in Böblingen (Stuttgart)).
Oldest on top.
Hi Friend,
Did you see that Thoughtworks put TFS on “Hold” in their latest Radar?
- Fredrik Wendt
Hi Fredrik,
yes, I saw that and have actually been asked by customers about this. My “problem” with this is that there is no explanation whatsoever for this rating in the latest Radar. I have searched their website and found the following:
“We continue to see teams run into productivity problems attempting to use TFS as a version control system. Teams that want to practice frequent code checkins, a core part of continuous integration, have found its heavyweight approach significantly drains productivity. This often leads to teams checking in less frequently, causing more problematic merges. We recommend tools such as Git, Perforce, and Subversion instead.” (http://www.thoughtworks.com/radar/#/tools/307)
I really don’t see any significant differences between Subversion and TFS, when it comes to checkins.> What might be a little more “heavyweight” is the linking of Work Items to checkins, which other VCS just don’t provide.
If you dig a little deeper, you can find some Information, which might have influenced the rating in Martin Fowlers blog at http://martinfowler.com/bliki/VersionControlTools.html. Martin is one ot fhe authors of the Radar. This blog post, though, has two issues: first, it was written in early 2010, which means it can only talk about TFS 2008. We have come a loooong way since then and Team Foundation Version Control has been greatly improved. The second issue - in my opinion - is that Martin is speaking of “anecdotal evidence”, in other words hearsay. He didn’t use the tool himself.
And there is one last thing I want to mention: the Radar rating hasn’t changed since March 2013. On the other hand, Gartner has in November 2013 put Microsoft (i.e. TFS) into the top leader position of its Application Development Lifecycle Management Magic Quadrant.
I leave it to you to decide what to make of all that Information :-) Personally, I very much like TFS for its broad set of functionalities. It’s definitely not all perfect, but it delivers some great insights into the development process, which other tools are not able to provide with the same level of quality. But don’t trust me, just try it for yourself ;-)
Ciao, Friend
Hi Friend,
Well, for a small project with no auditing needs (no need to connect work items to commits etc) and no need for MS specific technologies, then TFS (self hosted) brings a lot of overhead. For TFS as a service, the overhead is lesser. So I can clearly see TFS as a big monster that needs to be tamed. I can absolutely see the other side of the spectrum too, where using lots of its features together with VS providing lots of information and an streamlined work flow. A colleague of mine is an MVP and we quite regularly discuss Continuous Delivery as this is something he’s been struggling with for the past 2 years at a client of ours. He’s made some progress but since they’re in the financial market, SOX stuff applies and the other party that is responsible for the production systems are close to dead dinosours … I’m just saying that I’ve seen the goodness of TFS too, and I was surprised to see that Thoghtworks put it under “Hold”. ANY tool could be misused in a way that it should be put under “Hold”.
While most of what they put on their Radar is pretty good and well thought through, I always find a thing or two that is really strange to me. This was one such thing.
/ Fredrik, a free-open source and Java-guy :)
From Friend to me:
Hey,
I can see that TFS might look like a big monster, but it actually is only as big as you allow it to be ;-) In other words, if you only use version control, there really isn’t much difference compared to Subversion, CVS or most other central version control systems. Of course, installation takes a little more time, since TFS has a more complex architecture, but it’s not much more than a “next, next, next” installation experience. This is why I cannot really understand, why Thoughtworks has put TFS on “Hold”, especially since they aren’t talking about the installation experience but the actual developer experience.
Btw: TFS is pretty good for Java development with Eclipse and Team Explorer Everywhere ;-P
Oh, and don’t take my words too serious. I’m not trying to sell TFS to you. After all, it’s only just a tool, and most teams should start looking at their process first, before they try to “install a silver bullet” :)
Ciao, Friend
From me to Friend:
No problem, I asked since I thought you’d have some valuable input - I wanted you oppinion. :-)
I don’t think I’ll ever find the time to try out Eclipse with TFS, but if I was, I’d go for TFS service though (as I have zero machines with Windows on).
Thanks for taking the time to share your views. I too believe someone at Thoughtworks was really put off by the fact that someone enforce a company policy of “this is how you should do it, because we’ve spent x hundred man hours with this TFS professional who have told us ‘this is how to do it properly’”.
TFS with git is what I’d use. TFS’ native (old) version system, I wouldn’t touch unless someone asked for help getting out of it :-) I really haven’t used CVS or subversion since 2007 when I left the company I was at back then. Git (and the lesser good but still OK Mercurial) is all I ever use and to be honest don’t see the need for anything else. TFS’ additions to Git is nice if you really need to search in history, or look at statistics for a repo.
/ Fredrik
From Friend to me:
Ah, so you’re a Git guy :) I have never really used Git but I can definitely see its value. What keeps most of our customers from Git is the lack of “true authentication” of the person who does a check-in. As far as I know, I can freely switch email addresses between check-ins and Git will happily use whatever personality I give it. When it comes to auditability in larger enterprises, this is a no-go.
Perhaps you can share some of your experiences: when you introduce Git to people who haven’t used DVCS before, how long do they struggle with the non-linear history and things like fast-forward merges vs. traditional merges vs. rebasing? I assume that this can be very confusing to people, especially when I take into account the problems I see customers having even with the linear history of a central VCS.
Friend
From me to Friend:
Whether you think so or not, as soon as you clone source code you’re really doing distributed development, right? You will have to merge changes that originate from the same version of some file. Git forces you to deal with this merge issue outside “the server”, ie at a place where the user can use whatever tool he/she wants.
Authentication - yes and no. I require all of my users (including Windows ones at work) to use SSH to push new commits into the repo at the central server (we use Gitlab, which adds a nice web GUI much like GitHub’s). SSH keys are tied to users so we can easily check who pushed which code. Git, in itself, doesn’t have any built in support for authentication. What you can do with vanilla git is add any checks you want in a post-push (called post-update) hook. This hook can be any executable, typically Python or shell scripts. You have access to all information about what’s being pushed, so you could for instance verify that all commits were commited by an address from white list. You can verify that all commits have been signed by someone on a white list. PGP key system has been used and tested for decades, is used by Red Hat for all (Enterprise) software installs so if the auditing doesn’t accept that, I’d be surprised if they accept anything that comes out of Redmond. :-) NASA uses this for flight control software, and this industry really usually has stringent requirements that I’d call enterprisy.
But, it’s not there out of the box. You’ll need to setup and configure this yourself (or buy a hosted service, such as Bitbucket or Stash from Atlassian.
Re-learning?
For MOST users, that don’t need to cherry-pick commits in history and create a new branch with just a select of commits - the learning is done in one hour. Really. This is what needs to be learned:
- commit is a LOCAL ACTIVITY IN YOUR REPOSITORY, if you want to share the code - PUSH it to the place you cloned the repo from
- at some point, every user’s PUSH will fail with some semi-cryptic error message: They’ll google it (or ask a peer) and find out that someone else beet it to them: someone has pushed new code that needs to be merged. They’ll understand the the server never will be as intelligent as a human and thus a human should fix the commit. It’s usually trivial which means:
- do a git fetch to get all the commits from the central repo
- do a git merge to merge your content
- this will make a new commit
-
do a git push again
=== or like most of us do: “git pull” which does the fetch-merge-commit in one go
But to be realistic, most people use an IDE with all of this integrated already (like VS), so the only thing they need to learn is that the push doesn’t always succeed - it may force you to handle a merge. Otherwise, from a normal user’s scenario it’s like most other VCS. You can compare, you can watch commit logs, watch the blame log etc. If you’re using an IDE, not much should be different, especially when it comes to the daily normal work.
Most people don’t need to bother with rebasing, but simply merge. And rebasing is really “checkout the latest version, which was newer than then one you have worked off, and apply you changes”.
Any linear-model is just a lie, or a simplification of what’s really happening. Any DVCS will force you to understand that the childish simplification provided by other tools was just this, a simplification. As grown ups, we can handle it and understand it. ;-D
/ Fredrik
From Friend to me:
Wow, now you’re trying to sell Git to me :-D
Question: does Git also support pre-push checks? Otherwise, what good is it to check something AFTER it has been committed? Or does the check actually run before the commit?
I know about the SSH integration, but isn’t it still possible to “fake” information? A push pushes all my history to a remote repository. So, while the push itself might be tied to my SSH key, I am still able to create ten local commits with ten different user identities, right? And those identities don’t change during the push, since that would invalidate the SHA1 hash that is being generated for each commit. In most situations that shouldn’t be any problem at all, but I already know customers from the financial sector that have officially stated that Git would never ever meet their auditability requirements. Although I have to admit that German companies are somewhat “special” regarding their requirements :)
And it’s not in the box, so that IS an advantage of TFS :-P
I asked about merging and rebasing since this seems to be a constant war amongst Git users. Some say that merging is bad (as in “never do this or the sky will tumble down and the gates to hell will open”) and everything has to be rebased, others say that merging is the way to go and rebasing is just injecting a bunch of lies into the history.
Oh, by the way: merging in TFS doesn’t much differ from merging in Git. Most of the time, the two create the exact same results. Merging in TFS is ALWAYS done on the client, never on the server.
I wouldn’t call linear history a simplification. It is more or less a constant rebasing. If I were Martin Fowler, I would say that only a center VCS can provide Continuous Integration, since working in isolation in my own repository does not integrate my changes with anything. And if I’m not disciplined enough to fetch or pull regularly, I risk developing stuff that is extremely hard to integrate (push), once I am done.
I like having both options in TFS since both have their pros and cons. It’s all about choice, isn’t it? :)
Btw: this is a cool thread. :D
Friend
My reply:
Selling it hard! :-)
According to my MVP colleague, you should really try Git backed TFS. He said “it’s like, when you get it, you’ll never look back (even though you may some times miss some of the locking features, but it’s really a smell of a poor process)” but like you said, it’s all about choice. Not every problem (screw) needs the same solution (hammer). :-)
But yes your right, SSH is just a transport protection measure, and could be replaced with HTTPS PKCS, or NTLM - the point being: this transportation and “system entry/access” protection will not guarantee repository integrity and in fact has nothing to do with git (git doesn’t do anything different). A black hat with stolen credentials (or simply terminal access) could still inject malicious code commits. For true integrity in Git, you need to sign commits. And THAT is where we have Pretty Good Privacy (PGP) which I’m sure even German authorities and corporations (and union) would accept.
Question: does Git also support pre-push checks? Otherwise, what good is it to check something AFTER it has been committed? Or does the check actually run before the commit?
Yes it does. The words “commit” and “push” have different meaning in various VCS. In git, a push consists of copying one branch of the non-cyclomatic tree from one repository (A) to another (B). In B, you can have several hooks that may or may not abort the entire push, or actually accept parts of it etc. So yes, you can absolutely do TFS style “pre-push” checks, with a but: the difference is that git keeps the client hanging while this hook is executed, and it’s essentially a global lock on the repo for the affected branch.
For disconnected/async “pre-push” checks (or post-commit whatever you want to call them) people typically either go with Gerrit (which is used by huge parts of the Android ecosystem) or similar solutions. What this does is essentially have two central servers: one that users push commits to (1), and another that Gerrit pushes “blessed” commits to (2). Users don’t push to 2 (but may clone from 2 to get the latest). Commits on 1 will only be pushed to 2 when: a human signs off on the commit; Jenkins or some other tool has run some automated processing and verified the results to be “good” (whatever that means in terms of coverage, code style, static code analysis, …).
Btw, push/pulls are many-to-many - I typically pull from my private Gitlab repos, but push to both public Github and my private Gitlab. (This can of course be automated but who has the time …)
Regarding rebasing - well, I’ve surely met people that think that it’s MUCH BETTER to have a commit tree with a single path: each commit has only one parent and no merge commits (merge by nature have two or more parents). If you ever find yourself in the need to cherry pick commits, then a culture where you rebase all the time is clearly beneficial. When the time comes and you need to pick certain commits only (say a hot fix, which may indicate that you’re not doing CI/CD well enough yet, but that’s another story), then it’s easier to have “one” history to pick from. Lots of small branches may make it harder to do this cherry picking (for the human trying to understand what he/she’s getting). In real life, I’ve never seen this as a real problem. With Mercurial (very similar to Git) we’ve had to pick single commits in parallell unnamed branches, where there were several surrounding commits in each branch. I’m sure it took us (mostly me) some extra time to get exactly what we wanted, but I wouldn’t suggest installing a “rebase only” policy just because of that. The real problem is not constant “rebase vs merging”, it’s a question of software development and delivery process (and possibly architecture). Rebasing just makes the pain from the poor process/architecture/delivery setup less painful. :-)
rebasing is just injecting a bunch of lies into the history
Well I guess I could argue this way - rebasing doesn’t reflect HOW you came to write the code the way you did. It’s a “convenient” way of applying code changes to another code base than the one you developed from. If you’d instead worked from the newer code base, perhaps you’d develop the code in another direction. As such, rebasing introduces “lies” as it looks like you developed code from a point where you actually didn’t. If you instead do a normal merge you keep the original history and show that the end result is a combination of two divergent paths, that now have been combined.
This is what I mean with “linear history” being a simplification - in real life, as soon as we have development in parallell, linear history introduces “lies”. ;-)
I completely agree with the CI argument (and I’ve made it myself several times) - there can only be one branch, or you have Eventual Integration. (This is why Git rejects pushes where you try to add a new path (unnamed branch) “head”/path on a branch - you have to merge before you can push so the branch always has exactly one leaf commit.) I have a few repositories where any commit also atomically forces a push (which does some rudimentary checks at the server before accepting the push) - ie it disallows local commits. (Can very easily be overridden locally, since it’s a local thing (the hook) to begin with, and well, any development on a local machine IS local so why lie about it …)
Another (mostly java) colleague of mine really praises the merge solutions in TFS, it has “saved my sorry ass soooo many times, having to cherry pick certain commits from various points in time in order to do a hot fix for some client”. (If I remember correctly, this is only available with TFS’ (old) VCS.) He also loath the same VCS because you can lock files and says “I can’t tell you how many times this has locked up completely, forcing me - as admin - to go in and remove locks because bla bla bla”. I’ve never really seen people lock files in my life, so I’ve never experienced the problem first hand.
One thing where I see TFS stand out compared to most other (semi-)open source based combinations is work flow integration. I can easily have all git commits also be indexed by JIRA (issue/task tracker), but I have to use specific language in the commit in order to have it close or progress work items in it’s work flow. I’ve never actually seen someone do that work flow automation. However, unless I have regulatory requirements to track commits to work items, I would never put work I do in sprints in any electronic system. Properly named Acceptance Tests, which express requirements as executable Scenarios (and Storys (and Tests)) plus paper and pen … - I just love the speed you get from this and hate any electronic tool that wants to track the same thing: “which code was meant for what requirement?”
Yeah, I like this thread too! I’m not really a Git expert and I guess you know TFS better than I know my stuff, but it’s still good information and value I get out of it. :-)
/ Fredrik