Programming involves change and managing that change is the only way to make sense of it.

You’ll learn about merging in this episode. With this knowledge, you can take your source code control system to a new level by going beyond just managing old versions. You’ll be able to try different things and incorporate just the pieces you want. And you’ll know how to work in a team.

Merging is not the same as how traffic merges together on the road. There are two separate streams of cars that have no relation to each other that merge on a highway. The cars find openings to fit in and hopefully the other cars will be nice enough to allow those openings.

Merging source code is different. You start out with something common. This is an older version of your file. That version of the file that’s common is what allows Git to figure out how to do the merging. Most of the time, you don’t have to do anything special.

Listen to the full episode or read the full transcript below for a simple example of merging files. And don’t forget to subscribe to the podcast on iTunes, Google Play, Stitcher, or almost any other podcast directory. Subscribing lets you receive new episodes as they’re released.

Transcript

You’ll learn about merging in this episode. With this knowledge, you can take your source code control system to a new level by going beyond just managing old versions.

You’ll be able to try different things and incorporate just the pieces you want. And you’ll know how to work in a team.

Merging is not the same as how traffic merges together on the road. There are two separate streams of cars that have no relation to each other that merge on a highway. The cars find openings to fit in and hopefully the other cars will be nice enough to allow those openings.

Merging source code is different. You start out with something common. This is an older version of your file. That version of the file that’s common is what allows Git to figure out how to do the merging. Most of the time, you don’t have to do anything special. Let me give you an example.

Let’s say you start out with a file containing three lines of text, a, b, and c. That just means you created this file by typing the letter a, then the enter key, then the letter b and the enter key, and then the letter c and the enter key. Each letter is on it’s own line. A very simple file. It’s not programming source code but I can describe this a lot better than real source code. Listen to the previous episode for more information about text files.

This file is going to form our starting point. You open the file and change the first line to aa instead of just a. You like that change, so you save the file and commit your changes in Git. I’ll explain what it means to commit your changes in another episode. For now, just know that committing your changes means that you let your version control software know that you’re done making changes and it can store the current version of the file where it’ll be kept safe.

Now maybe this change you did to the first line is going to take some time to test. When programming, it’s always a good idea to test your changes to make sure they work as expected. I know, this is not a real programming file I’m explaining. Just pretend for a moment that changing the first line to aa is a big deal and could have unintended consequences. That doesn’t mean it’s a bad change. It’s just going to take a while to make sure everything’s okay.

While you’re busy testing your changes, your manager lets you know about a critical bug affecting customers that has to be fixed right away. You need to drop everything and fix this new issue right away.

You eventually track the problem down to the third line in the same file and realize that it really should have been cc instead of just c.

Let me make one thing clear that may not be obvious right away. When you started working on the customer bug, what version do you think this file should be? It can’t be the one with the double a in the first line because that version was never released and is still in testing. You need to restore your files to the versions that were current at the time that the customer would be using. Let’s say this puts the file back to three lines with just a, b, and c on each line.

This older version of the file is the one that you need to use when trying to find the problem. And it’s also the version where you need to make the fix. So in this file, the correct lines are a, b, and cc. You test the changes and everything looks good. This new version is used to create a new version of your application that gets sent to the customer and everybody’s happy. You can also go back to working on that risky change.

But here’s where things get interesting, If that change was so important to the customer, then it may be important in the new version too. It would be really nice to be able to apply the same changes you made for the customer into your current work.

You might think, that’s easy, just open the file and change the third line to cc, right? Well, remember, this is a very simple example just so that I can explain the basics of merging over this podcast in a way that you’ll be able to understand. A real change might involve hundreds of changes spread across many files. You don’t want to be retyping all of this again. And not just because it could be a lot of work. If you try retyping everything, there’s always a chance that you’ll forget something and introduce another bug.

The real solution is to merge the two changes together into a new version of the file. Git is smart enough to be able to figure out all the changes that went into one file and all the changes that went into the other file. It can do this because it knows which version is common for both. Git knows that line one was changed in your new work and that line three was changed in the customer bug fix. Because these are different lines and not right next to each other, Git is able to merge this for you and you end up with a file containing aa, b, and cc.

What happens though when changes are made to the same lines? Or made to lines right next to each other? That’s when Git has to let you figure things out. This is called a merge conflict. The good news is that Git can detect these conflicts. So you can be sure that you won’t miss any. The bad news is that you have to figure out what the changes should be.

So let’s look at the same starting file with just a, b, and c on each line. You start working on you new feature and need to change a to aa. You file now reads aa, b, and c just like before.

This is when your manager lets you know about the critical customer bug. So you go back to the version with a, b, and c. This time, when fixing the bug, you need to change the second line to bb. You test the bug fix, it looks good, and you release a new version of your application to the customer based on a, bb, and c.

Now when you go back to your risky change, you have aa, b, and c. You’d like to merge the changes from the bug fix into your new version. Git sees that you changed line a to aa while the bug fix left line a alone. Then Git sees that in the other file, you changed the second line to bb.

Even though these are separate lines, because they are next to one another, there’s a big chance that one line could affect the other. And Git will of course notice if you changed the exact same line in both files.

Git is good, but it doesn’t know what these lines mean. There’s no way for it to know which is correct. So it marks the conflicting lines as a merge conflict and lets you figure out what to do.

You might decide that both changes are needed and resolve the conflict by accepting both changes. Or maybe you decide that your change is better than the change in the bug fix and you keep your change as is. Or maybe the bug fix is better so you go with it instead. Or maybe now that you can see both changes together, you realize that the whole thing needs to change. This is why Git can’t figure out merge conflicts. There’s just too many options.

Let me know what you think of this episode. I tried to keep things simple and I hope that you were able to follow along as I described all these changes. The important thing to know is that Git merges files line by line and lets you decide how to handle any conflicting changes. There’s just one more aspect of this I want you to know about though.

What if you have a more complicated file with more lines than just a, b, and c and change some line towards the end of the file. But in the bug fix version, you need to add some more lines near the beginning of the file. Will Git be able to merge these files? Or will it think that every line after the newly inserted lines has changed? That would be a huge merge conflict. Git can match the lines even when some of them have been deleted or new lines added. So while merging is always done line by line, just remember that Git can shift its focus to handle gaps due to deleted lines or new sections due to added lines.