LPIC-1 Exam 101 Study Plan

I’ve worked almost exclusively with Windows machines for the past years. However, this is changing rapidly (by circumstance, mostly) at the moment. So the time was never better to start a deep dive into Linux.

As you can see from my past Study Plans, I’m a big fan of “breadth-first” learning. I’ll go into a focused, meticulous, relentless grind starting at the very beginning. I plan to do the same for my Linux studies.

Certification Downsides

I will mention two major problems with certifications though:

  1. The certificates are near to worthless.
    Cheating your way through is commonplace, especially at companies that care only about being able to charge more for an employee because they’re certified. The only “worth” of a certificate lies in the fact that it reminds you that you’ve passed it fair and square.
  2. They tend to test a lot of silly or unimportant knowledge.
    Experts will tell you that many things you need to know to pass an exam are things they will in reality actually have to look up. Knowing whether method so and so returns an INT or BIGINT is useless, in real scenarios you’ll have an IDE or documentation to tell you this.

But for me striving to pass an exam is worth it nonetheless. Following exam objectives closely gives me confidence that I’ve got a solid basis, and frees me of having to spend any mental-cpu-time on monitoring that. I want to cover as close to 100% of the important topics as possible, and I guess covering 130% worth of material is one way of doing that.

Here’s a visualization of what I mean:

Venn diagram of Study Plan Coverage
Venn diagram of Study Plan Coverage

The blue area covers the green area for the most part, and it takes zero time to use it as a study guide. The red area is a plan I would probably create myself composing it from various resources. But creating it would cost me many hours, and is more likely to leave serious gaps.

So I’ve decided that going with exam objectives as a guide is a sane choice for me.

The Actual Plan

So how about the actual plan? Isn’t that basically the objectives from the website then? Well: yes and no. I also like to publicly share my plan, for two reasons:

  1. The main reason: it gives me confidence I’ve got a solid plan.
  2. Secondary reason: others might find it useful.

In addition, as a side effect, I guess it motivates me: feeling that “others” are watching my progress makes me want to complete everything. Regardless of whether there are such “others”.

This time around I tried something different from the previous Study Guides. I’ve used Trello to catch the study plan. You can check out the public board yourself. Here’s a screenshot:

LPIC-1 101 Study Guide Trello Board
LPIC-1 101 Study Guide Trello Board

Personalizing The Plan

Finally, you can easily copy this board and use it as a starting point for your own studies. This is quite easy to do:

Copy Trello Board
Copy Trello Board

It’s exactly what I have done, and you can follow my progress on Trello.

And now that I’ve told you about this, dear reader, I will have to complete my studies…

Using SourceTree’s Pageant with git in Powershell

I’m trying to use these tools in conjunction:

  • Powershell 5 on Windows 10
  • Git version 2.13.0.windows.1
  • Keepass 2.35 with the KeeAgent plugin to fire up Pageant
  • Putty 0.69
  • I also have SourceTree version 2.1.2.4 installed

I’ve generated a public/private key pair, loaded the public key in GitLab, GitHub, Bitbucket, and other places. I’ve loaded the private key in Pageant via KeeAgent successfully and I can see the fingerprint is correct.

Now, if I try to do git pull from Powershell I get this:

However, if I place id_rsa (an OpenSssh file generated with Putty) in my user’s .ssh folder then git pull works, but it will ask for the passphrase *every time*.

Now if I use SourceTree I can pull changes just fine! So what was the problem?

Apparently, this solution by user @CTS_AE works just fine: you have to add a System Environment Variable called “GIT_SSH” that points to “plink.exe”. For me:

GIT_SSH System Variable

Restart your Powershell session and voila: pulling in changes from the command line works again!


Footnote: If you get stuck at “Store key in cache? (y/n)” with no input from the keyboard being registered then this solution by @cambunctious might work. Just open Putty, try to SSH into bitbucket.org, and use the GUI to add the fingerprint. Silly, stupid, but it works.

AutoMapper: Missing type map configuration

While trying out AutoMapper I stumbled on this generic error:

Message: AutoMapper.AutoMapperMappingException : Missing type map configuration or unsupported mapping.

Below is the initial Stack Overflow question I wrote, after struggling for at least 25 minutes with this problem. The solution however was shamefully simple: if you call Mapper.Initialize twice, the latter will overwrite the first.

Full Description

So why am I writing an entire post about this? Simple: to ingrain this solution into my brain, may I never make the same mistake again.

Basically, I was trying to understand a more specific version of this generic question on AutoMapperMappingException, getting the same kind of error message:

Message: AutoMapper.AutoMapperMappingException : Missing type map configuration or unsupported mapping.

Here’s a way to repro my scenario:

  1. Using VS2017, create new “xUnit Test Project (.NET Core)” project (gets xUnit 2.2 for me, targets .NETCoreApp 1.1)
  2. Run `Install-Package AutoMapper -Version 6.0.2
  3. Add the following code
  4. Build
  5. Run all tests
  • Expected result: green test.
  • Actual result: error message:

    Message: AutoMapper.AutoMapperMappingException : Missing type map configuration or unsupported mapping.

    Mapping types:
    FooEntity -> FooViewModel
    XUnitTestProject3.FooEntity -> XUnitTestProject3.FooViewModel

If I uncomment the line marked as “culprit” the test turns green. I fail to see why.

I also placed a Mapper.Configuration.AssertConfigurationIsValid() call right before the Map call but that will run without error.

As far as I can tell, the other question, specifically its top answer talks about forgetting the initialization, but that’s explicitly there. I’ve also looked through the other answers but none of them helped me.

Another top question’s answer to this same problem tells me to add ReverseMap(), but that’s not applicable for my scenario.

Solution

Only after writing the entire above question on Stack Overflow, specifically while perfecting the minimal repro, did I realize what was causing the error: the line marked as “Culprit!”. Then, buried deep in Google’s search results (okay, okay: on page 2; but who looks on page 2 of search results?!) I find this answer that has the solution. Multiple initializations should be done like this:

I guess that teaches me for disregarding the advice to use Profiles for proper AutoMapper configuration.

Learning to Linux: the Road to Becoming a Power User

Let’s first set the scene: I’m participating in an Infi study group and would have to present to colleagues about “WTF is Linux?”. Interestingly, I am a total Linux beginner, and they were ranging from intermediate to advanced skill levels. Joy!

So, what’s on the to-do list? Three things:

  1. Understand history and context of Linux;
  2. Get to know what you don’t know yet;
  3. Learn what the tools to learn more are;

Basically, I’m looking for all the things I need to get started and to keep going. Note that all this is aimed at folks that are at least to some degree a power user.

History and Context

First there was Unix, which was great, but it was closed source and not very portable. So Richard Stallman set to create a clone: GNU. However, the kernel “GNU Hurd” didn’t work out so well at the time. So Linus Torvalds wrote the Linux kernel in the 1990s, and together they now form the Operating System “GNU/Linux”, often referred to as just “Linux”. History has by now shown that GNU/Linux was far more popular than GNU/Hurd.

Before we dive into Linux itself, let’s consider its place amongst other Unix-like OSes. There are both open source ones such as Minix and FreeBSD, and closed source ones like Solaris. All of them are fully or partially compatible with “POSIX“: a standard for OSes. You can get the full picture at Wikipedia, but here’s a simpler version:

Unix-like OSes overview

Zoom in on the green “GNU/Linux” box, there turn out to be very many Distros. A distro being the Linux kernel, GNU tools, a package management system, and possibly a window system and desktop manager. Again, there’s a full picture at Wikipedia, but I made a more condensed overview:

Linux Distros Overview

The top ten distros for 2016 according to DistroWatch are as follows:

Rank Distro Package Manager Default Desktop(s) Comments
1. Mint dpkg Cinnamon, MATE, Xfce, KDE community-driven spinoff from Ubuntu with a lot of out-of-the-box multimedia stuff
2. Debian dpkg Gnome reliable Linux distro that can be used plain, but is also the ancestor for many other distributions
3. Ubuntu dpkg Unity (moving to Gnome 3) beginner-friendly spinoff from Debian, both for desktop and server environments
4. openSUSE rpm None, Gnome, KDE community program sponsored by SUSE, to promote use of Linux everywhere
5. Manjaro pacman XFCE, KDE, Gnome power and flexibility of Arch, but with a friendly installer and some more GUI stuff added
6. Fedora rpm Gnome latest and greatest features that will also go into Red Hat Enterprise Linux
7. Zorin dpkg Gnome 3 spinoff from Ubuntu for newcomers accustomed to the Windows GUI
8. elementary dpkg Pantheon spinoff from Ubuntu with the look and feel from Mac OSX with a few custom apps
9. CentOS rpm None, Gnome, KDE basically Red Hat Enterprise Linux without the enterprise license and support fees
10. Arch pacman CLI very minimalistic Linux distro, requiring the user to take control of the OS

There is also a pretty good Youtube video that gives some context about this same list.

Oh, and obviously I also have to do an honorable mention for the weirder, more “clickbaity” Linux distros: Satanic Ubuntu, Christian Ubuntu, Damn Vulnerable Linux, LinuxBBQ, Slackintosh, and Stresslinux. For the most part I have no clue what they do (if anything at all), I’ll leave that as an exercise to the reader.

What to Know

First thing to do when getting started with a new technology is finding out how much you don’t know yet. Thinking about the Dunning-Kruger effect…

Dunning-Kruger effect

… I would like to start at the Valley of Despair right away. And I’d like a clear path of that slope ahead of me. Please.

Now obviously you can’t start from zero; even reaching the Valley requires some knowledge. So investing some generic startup time seems good. Here’s a few suggestions:

But where to go from there? What is there to know? Well, there’s a few obvious resources that serve as very natural check lists:

In addition, it seemed helpful to try to do one or two nontrivial in-depth tasks in a VM, and see what you encounter. For example setting up a LAMP stack to host WordPress in a VM, or cloning a cool project and getting all dependencies (like Java, ugh!) up and running.

At the end of my research, and with help of my study-buddies, I conclude these are the few essential skills that I’m missing to be productive with Linux as a developer or sysadmin:

  1. Command Line. Without solid knowledge here you’ll feel lost for any nontrivial task in Linux. Some “introduction to Linux” articles tell you it’s not really needed (depending on the distro you choose), but I disagree, and think you’d get frustrated unless you learn to use it.
  2. SSH. Related to the Command Line, knowing how secure shell works is essential to managing a remote Linux instance (e.g. a VM in the cloud). This includes knowledge on managing SSH keys.
  3. Nano or Vim or similar. Also related to the Command Line. Often you’ll have to edit a config file from the command line, and being able to do that confidently is quite helpful.
  4. File System Hierarchy and Permissions. Knowing where to find stuff (and who has access to it) is essential to be productive. On a specific note, it seems important to know where things will be logged (e.g. where does a package install or server software keep its logs).
  5. Package Management and Installing Software (and troubleshooting that when it goes awry). Most interesting tasks on Linux require installation of libraries and software, and quite often this can go awry. You need to learn how to debug this.

My advice, at least to myself, is to sit down and carefully master these first. At least to some degree. Only then will other tasks on Linux (e.g. managing an NGINX server) not be a frustrating job anymore.

Learn to Learn

So how do you most efficiently climb this learning curve? Discoverability of essential info on Linux can be a bit of a problem. But here’s a shortlist we came up with:

  • man can be used with any other command as an argument, and it will explain all about it
  • info is GNU’s answer to man, intended to be more fully-featured (hyperlinks and such) and comprehensive
  • The “bropages” is like man but more succinct and example-based
  • locate, find, and which are commands for finding stuff on the file system
  • aptitude in Debian distros, or a similar tool for your set of distros, to help understand the package system
  • unix.stackexchange.com can be a great generic resource for Linux (and other *nix OSes)
  • https://askubuntu.com/ is quite a vibrant community should you choose to use that distro
  • LPIC (or similar) exam objectives can be a great study guide
  • read shell scripts before executing to learn
  • and as a final trick, you could do git init in a certain folder (e.g. /var/log) and use diffs to check how things change following your actions

However, perhaps unsurprisingly, the most common piece of advice when asking experts “How to learn?” is…. practice. Practice, a lot!


PS. This was cross-posted to Infi’s blog.

Beginnersplaining Linux to Experts

Working at Infi I’m involved in several study groups, one of which is about Linux. When we started the group it turned out we had six people and six different levels of experience. And I was the absolute newbie of the group.

We decided to set up a program divided in weeks, with one subject for each week, and a “Lead” for each subject. The Lead would research a lot about his or her main topic, and ask the rest of the group to merely do some light recommended reading. This is to get everyone at a base intro level for each topic. Every week we’ll have a session where the Lead would talk about his or her research, along with some open discussion.

Obviously, the first topic would be a “Linux Basics” session. It also seemed logical that the newbie (me!) would pick up this topic, because I’d have most to gain from researching the hell out of it.

Seems legit, right!? Except I now realize this means I’ll be presenting on Linux Basics to five colleagues that know a lot more about this topic than I do. Oh, and because it’s the first week’s topic I have only a week to prepare. Whelp!

I’ll just have to focus on learning a lot from all this. No progress without failure, and no progress without taking risk, I guess.


Foot Note: The Programme

We composed the Study Plan based on whatever the group members individually found interesting enough to research. This means it’s a bit of a weird assembly, but interesting nonetheless:

  • Week 1: WTF is Linux?
  • Week 2: Command Line
  • Week 3: File Systems
  • Week 4: Screen
  • Week 5: Web Servers (Apache & NGINX)
  • Week 6: Ansible
  • Week 7: .NET Core
  • Week 8: Logging & Smart Monitoring
  • Week 9: KVM, Virtualization, Containers

Privileged

I’ve been privileged, both directly (with financial and material support from family) and indirectly (in that I’ve been able to work to earn some extra cash). I’ve used those resources for the great credo:

Spend your money where you spend your time

And so I’ve spent significant amounts of money on PCs. I find it enjoyable to keep a record of my previous rigs, so here it is. Older entries were constructed from memory, newer ones are more reliable as they’re created from a “paper” trail.

  • 2017: Intel Core i7-7700K + 32GB RAM + GeForce GTX 1080
  • 2013: Intel Core i7-4500U (Laptop – Dell XPS-12)
  • 2012: Intel Core i5-2500K + 16 GB RAM + GeForce GTX 560 Ti
  • 2009: Intel Core 2 Duo E8400 + 4GB RAM + Radeon HD 4870
  • 2005: Intel Pentium M740 (Laptop – Acer Aspire 1692)
  • 2001: AMD Athlon XP + ?? RAM + GeForce 2
  • 1998: AMD K6-2 + ?? RAM + 3Dfx Voodoo2
  • 1994: Unknown brand 486 (66 MHz) with co-processor + 16 (?) MB RAM
  • 1990: Tulip 286 (10 MHz) + 1 (?) MB RAM

My most recent (2017) build was actually the trigger for this post: I’m very pleased with how it turned out and how well it works (and I’m hoping it will continue working so well).

If you care about the details of the various builds, and some of the backstories: check out my extended PC List.

And you, dear reader? Do you remember your old rigs too?

Entity Framework: Cascading Delete of Optional Related Entity

After several years of NHibernate, and a couple of years Dapper and NoSQL, I’m now working on a project that uses Entity Framework as its ORM. It’s a mature ORM at this point. However, it does give me a headache as I’m struggling to find ways to do certain things. I’ll admit that I’m trying to dive in without sitting down and doing a few hours of learning first; for sure I’ll be on Pluralsight some time soon.

Fair warning: what comes next is a highly specific, rather technical, and possibly stupidly uninformed dump of a problem I ran into. Feel free to skip this one: no hard feelings, and I’ll see you on my next post!

The main problem: I’ve got a repro, but it’s extremely similar to various other questions on Stack Overflow. Except… that my code contains the accepted (and often highly upvoted) answers’ code as well, but still doesn’t work as advertised!

What I’m trying to do is make sure that EF will delete a “Child” property (i.e. the database row) automatically when its “Parent” is explicitly deleted via the DbContext. Note that the Child is optional in my scenario.

Here’s the repro. Create a new class library and install EntityFramework (I used 6.1.3) and NUnit (I used 3.6.1). Then drop in one namespace these entities:

And then this DbContext:

And finally this TestFixture:

Make sure the “TestDb” database is available on your “(LocalDb)\cascades” instance (or use another Sql Server instance and database). Then run the tests, and you’ll get:

Test Failed – Delete_will_cascade.
Message: “Child”.
Expected: 0, but was: 1.

All I want is that a “Child” is deleted with its “Parent” once that is deleted. I know I can use a Sql CASCADE, and I know I could manually remove the Child from the context, but I want EF to handle this automatically, damnit!

For sure I’ve missed the obvious solution. I was somewhat hoping it would come to me while writing this. But perhaps I just need a good night’s rest.


References:

Job Hunting Checklist

Having recently switched jobs, now is probably the best possible time for me to write about the applicant’s side of vacancies and job searches in IT. Specifically, I want to give my take on maximizing the chance you’ll land a job at a place you’d want to work at. Put differently, below is (mostly) my own plan for finding a new job.

But wait: that’s not specific enough for a blog post yet! There’s a lot to job hunting. So let me narrow it down to the asynchronous ways to communicate with prospective employers.

What I mean here by “asynchronous“? Well, that includes just about everything that’s not real-time (face-to-face or phone conversations, chat, etc.). I will run down these “channels” one by one, including specific tips for each.

By the way, I hear you thinking: “But that sounds like just a big check list!?”. It is. But hey: check lists are great! Use this one to your advantage. Let’s get started with the basics.

General tips

Several things are important for all of the async channels. Remember:

  • Choose a great avatar you’ll be happy with for a long time to come, and stick with it. Everywhere! This will take a few years to settle in, but after a while it’ll help people recognize you across the board.
  • Be smart about your e-mail addresses. Preferably, you’d get your own domain, use addresses like some-org@yourname.com and github@yourname.com. Alternatively, use the + sign lifehack to differentiate. This will help you separate incoming mail reliably, lets you know who’s leaked or sold your e-mail, and gives you a minor edge with tech orgs because they’ll notice you’ve given things some thought.
  • Do or do not, there is no try. To put it in my own words: either do something right, or don’t do it at all. For example: it’s better to have no LinkedIn profile than an out-of-date one.
  • Try to do as many of the list below as possible, but consider this tip strictly lower priority than the previous tip!
  • Use language correctly, or at least as correct as possible. It’s easy to use a spell checker, proofread, do some proofreading, and do some more proofreading. Tip: read your writing (semi) aloud to yourself to find bugs in your writings.

Okay, so enough with the generic mumbo jumbo. Off to specifics!

Your CV

A lot has already been written about this, so I won’t repeat the basics. But I will make a few important additional points:

  • Decide: short or long. Both are fine. If you go short: try to fit everything on one single page. This is really hard (I could never do it!), but if you can manage it’ll demand respect and it’ll be useful to the reader. If you go long: use “scannable” text and styles (tables, bullet lists, emphasis, and so forth).
  • Use a (non-default) theme. The theme (and sticking strictly to it) will help prevent your CV from becoming ugly. Only try to make a “beautiful” CV if you know how to design or have help in this department.
  • Read “The Non-Designer’s Design Book. It’s a “Must-Have” if you insist on tweaking styles (like me), and when you’re also (like me) not a great designer. It’ll at the least help you prevent your CV from becoming ugly.
  • Use serif fonts. Sans-serif might look nicer on (non-retina) screens, but most of the time folks will read a print of your CV. On paper, a serif font is easier to read.

Open Source platforms (Github, Gitlab, etc)

This one’s not for everyone. Whatever you do or don’t do: be conscious about your choices. That doesn’t mean everything has to be perfect, but do mind the things that are easy to get right. Think about cleaning up utter garbage repos, using correct language when commenting on issues, etc.

If you do decide to work on open source, note that you don’t necissarily need to become a maintainer of a high esteemed project to be noticable. Here are some easier ways to get started:

  • Pet projects are something to put online. Place a big disclaimer that the code should be viewed as such, and you’re fine putting out non-production-worthy code.
  • Create a demo project that shows off how you prefer to code. It’s fine to “reinvent the wheel” or even create yet another “To Do App”, as long as you focus on the code being in “your” style. Place a big disclaimer that the code should be viewed as such, and you’re fine.
  • Create Issues for other projects. Creating an issue with a good repro is usually well-received, and displays qualities very important in day-to-day tech work.
  • Find up-for-grabs issues in a project you’d like to contribute to. Or even open your own (most projects will welcome improvements to documentation, for example).

On a side note, it can also be good to spend some time looking at the source code of open “famous” source projects in your tech stack. It hones your code-reading skills, and demystifies the black boxes they tend to be. Although this isn’t directly visible to prospective employers, it does have intrinsic value and might be a gateway to your own contributions some day.

Community Forums and Q&A (Stack Overflow, etc)

On the one hand I see this different from the previous point (Open Source), on the other hand it kind of isn’t. Specifically Stack Overflow (of which I’m somewhat a fan, as they distribute all content freely, for one because the data is licensed by users at least under CC-By-SA.

Asking questions is probably the easiest way to get started. Note that exemplary questions are a great way to show off your skill: being able to grasp and neatly summarize a reproducible problem is perhaps the number one skill a developer can have. I’ve asked multiple questions I’d proudly show off as part of my resumé.

Answering questions is a lot harder. This is another whole topic on itself so let me just sprinkle some basic advice. First, the “gamefication” can be fun but should not be your primary motivation. Instead, answer to learn about topics. Choose a low(ish) traffic tag to answer questions in, or you’ll get frustrated by the fastest gun in the west: other people will answer extremely fast so you don’t seem to have a chance. And finally: keep at it.

My first few questions and answers on Stack Overflow were pretty bad, but practice makes perfect! For every ten answers with even one upvote there’s at least one that turns out to help a lot of other folks. Seeing a small “+1” trickle in on an old question is a great, warm feeling.

A personal website

Get a personal domain, preferably something with your name in it. Make it a single page with at least:

  • A very basic bio: one or two lines of text about who you are.
  • A generic e-mail address (one that doesn’t matter if it gets a bit of spam).
  • Links to any social media accounts, e.g. Twitter, LinkedIn, but also Meetup, Goodreads, or other media that are professionally relevant.
  • Links to open source profiles, e.g. your GitHub profile or Stack Overflow flair.

Then, optionally, you could do any of these:

  • Link to your blog (see next section).
  • List of your projects, e.g. pet projects, portfolio stuff, your master’s thesis, etc.
  • Link to interesting other sites, e.g. tech blogs you enjoy.
  • A short occupation history if you’re inclined to make that public.
  • Some schema.org info and meta tags for SEO and generally showing off mad skills with details.
  • Ninja-counter-recruitment in your source code, just as organizations do.

A personal blog

Also not for everyone, but it certainly does help showing off enthusiasm, writing skills, and really whatever you want to show off. Blogging about tech is great, but mixing with non-technical posts works even better.

And in addition to exposure, there’s a far more compelling reason to blog: writing helps you organize your thoughts. Having to clearly express your thoughts or opinion about something should also make you think really hard about that thing.

Gaining a bigger audience is a challenge on its own, not usally directly related to the writing itself. So think long and hard before you decide to go down that road, because you’ll have to double down on community-building to get somewhere. But then again: I feel you can get a lot out of a blog without a big audience, too, by just writing to organize your thoughts.

Social Media

Warning: only do this if you enjoy it! The days of “needing” to be on social media to fit in are gone with Gangnam Style and the rest of 2016. Having said that, social media can be helpful in building your online profile.

First up: be consistent. Be consistent with your tag line, title, etc. Be conscious about what you make public and what you keep private. Don’t be afraid to create only a simple account that just links through to another platform; for example, you could create a LinkedIn profile that just tells folks to check your own website.

For the rest this comes down to personal preference. For me, Twitter and a wee bit of LinkedIn are primary professionally used social media. Google+ I find useless for most things, and Facebook is purely a thing for friends and family for me.

As a footnote it’s also worth noting that there are outliers. Goodreads is something I only use because I find the platform interesting, and I keep my professional bookshelf there. Also, Meetup.com has been popular the last two years, so I guess that also counts as a medium to be conscious about.

In closing

Bear with me while I digress a bit. Suppose you want to set up a perfect romantic date with someone. To maximize chances of success, you prepare all the things that can be reasonably prepared. You make sure there’s food, drinks, music, but also toilet paper, running water, etc.

Now let’s zoom in on the food. If you’re a chef or if you like cooking you might go out of your way a bit to cook something fancy, though you probably shouldn’t go too risky (unless that’s part of your charm…). If you hate cooking dinner you might order in something nice, and focus more on other things. In other words:

  • Do or don’t do! There is no “try”.
  • Min-Max All The Things™ that you do.

Back to the point. Maximizing your chances for a perfect job works the same as setting up that perfect date night. Be conscious about what you focus on. Be smart about what you do or don’t do. And whatever you decide you will do: do it right!


Footnote: his was also cross-posted to the Infi company blog.

New Beginnings

In less than two weeks, I’ll be starting a fresh challenge at Infi. I hope (and think) I will bring things to the table, but I’ve also already noticed that there will be a lot of new things for me to learn. I honestly feel that a large portion of your skills and knowledge can be best gained from other people (online, or in real life, doesn’t matter), which is why I’m very excited about this new beginning!

I’m pretty sure that this fresh start will influence what I’ll be writing about on my blog. I’ve got some ideas, but even more so I think additional concrete ideas will start to flow in the coming months.

But first, before we get to that, there will be (a) a very short vacation, and (b) a short period of silence while I get settled. After that, you can expect the reports to flow in again here. See you then!

Git intro for TFVC users

So, you’re using Team Foundation Version Control (TFVC). You know about Team Projects and Collections, have a “stable” and “dev” branch for most projects, know how to do basic merges, and know how to shelve and unshelve changes. But you only have superficial knowledge of Git.

Well, then you’ve come to the right place: my Git intro for TFVC users.

Disclaimers

Here’s a heads-up about this particular post:

  • It is not in-depth;
  • It will oversimplify things to the point where not every statement is technically true;
  • It does not teach you actual Git skills or commands;
  • It is somewhat subjective.

Oh, and in my humble opinion: Git has a crazy learning curve. So buckle up!

And, as a final disclaimer: I’m writing this because I want to be able to explain the basics of Git, and certainly not because I’m an expert. In fact, I know more about Mercurial than about Git, I have worked mostly with TFVC in the past year, and would have to look up nearly every Git command when using the command line (I prefer GUI tools most of the time). Just so you know.

Disclaimers done, let’s get started!

On “TFS” vs “TFVC”

First, let’s get the TF* terminology right. These terms are different but related things:

  • “TFVC” stands for Team Foundation Version Control, and is the actual system for keeping history of your codebase;
  • “TFS” stands for Team Foundation Server and is the “environment” (if you will) in which source control features come together.

Many people, myself included, often use the acronym “TFS” when we actually mean “TFS with TFVC”. This is probably because TFS is very often used with TFVC as the version control system; but note that you can also use Git with TFS.

This blog post focuses on TFVC (which almost always implies you’re using TFS too).

Why Learn about git?

The personal reasons for learning Git are quite simple: it’s the de facto standard for version control. Knowing about Git is:

  • crucial for your career (your new employer is likely to use Git);
  • crucial for talking to new hires (who will very likely know Git);
  • crucial for efficiently navigating open source.

The intrinsic reasons for learning Git all come down to the fact that it is insanely powerful (which also accounts for the steep learning curve). After having worked with TFVC in a 12 person team for over a year, I’d like to highlight the following main- and most direct advantages over TFVC:

  • Cheap branching;
  • Small repository size;
  • Local commits;
  • Better options for “shelving”;
  • Speed;
  • Better “offline” support.

Beyond these advantages, which you’ll get if you’re using a “central” Git repository, there are even more goodies if you tap into the distributed nature of Git, as well as the more powerful commands (e.g. to rewrite history).

Basic differences

Git is a lot like TFVC, in that it is also a Version Control System (VCS). It is also quite different. Here’s how they compare when managing the code base and doing changes:

TFVC Git
There is a central, server-hosted Team Project and you’ll have one or more local workspaces containing a copy of all the code. For now, let’s assume that there is a central repository hosted somewhere on a server. You’ll have one or more local “clone” repositories containing a copy of all the code and also all of its history.
check in is a command to send your pending local changes to the server where they will be committed to the version control history. You commit changes locally which creates a “change set” private to your “clone”. You can do this multiple times. You push one or more change sets at once to the central repository.
You can Get the Latest Version from the server which directly tries to merge with your current state. You fetch changes from the central repository and merge with your current state (or do both at once by doing a pull) possibly creating a new commit.

The fact that a TFVC “check in” is multiple separate commands in Git gives several advantages:

  • You can build history in small, individual steps (commits), which you can undo individually in several ways, and you can apply individual commits to other branches.
  • Your changes are “safe” in commits when you want to send your changes to the central repository and find out others have conflicting changes, by default they won’t get “lost” if merges go bad. With TFVC, you’re required to resolve conflicts as you try to check in, which can screw up “unsaved” changes.

Our next set of differences would be about branching, but before that it’s good to talk briefly about “shelving” changes.

Setting changes aside

With TFVC you can shelve changes you currently have to safeguard them, optionally reverting those changes in your local workspace. You don’t necessarily need to do this when switching work to another branch, because the branch is typically a sibling folder of the main branch. More on that later.

With Git, you can stash changes you currently have, reverting changes in your local clone. You have to do this before switching to another branch. In order to see how that works, let me move on to the next topic: branches.

Branches

A typical setup in TFVC starts like this (with a local workspace matching the Team Project 1-on-1 in this example):

Inside the project folder for the Team Project, there immediately is a sub folder called “main”. This is done so that it is easy to branch off the entire codebase for that project into this:

The folder “dev” is now a complete copy of “main”. This also means you could be working on two branches simultaneously, and you can check in files to both branches at ones if you so desire. You could even have “main” and “dev” at different points in your version control history.

Git is different.

With Git, the “main” folder as you’d have it in TFVC would be pointless. Instead, there is just:

You can “branch off” any state of “project-x” at any point in time. Your folder “project-x” will point at a certain state, de facto having the code for a specific branch.

If you would like to have both branches “ready for action” on your disk, you would typically have multiple “clones” of the repository. One would be at the most recent state of the “main” (typically called “master”) branch, and another might be at the most recent state of another branch.

As a summary, Git branches relative to TFVC branches:

  • Are light-weight and can be used to “switch context” for example to work on a feature;
  • Are a top-level thing, as opposed to the “path-based” branches in TFVC;
  • Allow for more precise merges and “cherry picking” of commits;

These differences allow for completely different workflows with Git. This is a topic for another post though, if you’re interested I’d recommend research things like “Git Flow”, “GitHub Flow”, and “GitLab Flow”.

Other differences

While there are many other differences, both small (e.g. specific commands) and big (e.g. the “distributed” nature of Git), this post will keep it at the above. Mentioned differences are in my opinion the most “direct” and eye-catching differences. If you want to learn about the other differences I recommend you first get started with some practical skills, e.g. by following a tutorial.

Conclusion

TFVC is a mature, decent version control system. But personally, having worked with both centralized and distributed version control, in TFVC I’m misssing:

  • Ability to do commits locally;
  • Cheap, more powerful branching;
  • Great “shelve” options;

Those three, in addition to its “distributed” nature enabling online platforms like GitHub to flourish, are likely the reasons Git is so popular nowadays. In my opinion those are great intrinsic reasons to learn Git when you’re currently using TFVC (even if you cannot switch on the short term), and if not for those reasons then because it’s crucial for your career.

So ready yourself for a bad-ass learning-curve climb, and start learning more about Git!


Resources & Further Reading

Here are some links to continue your journey: