FREELessons: 24Length: 3.1 hours

Next lesson playing in 5 seconds

  • Overview
  • Transcript

4.1 Diffing Files

So far, all of the Git tools we've looked at, have changed the state of our repository in some way. We've been staging files or committing files or ignoring files. However Git does have a couple of tools that are helpful when you just want to look at the state of your repository. Today, we're gonna look at one of those tools, which is the Git diff tool. You might be familiar with the Unix diff tool and that works like this. Let's say I have a file called file one. And we'll just put the content using diff, in here. And I'm gonna save this as file1. And then I add another line here. We're just gonna say, add some more. And I'm gonna save that as file2. And then I quit this. If I say diff file1 and file2, it's going to show me the difference between file1 and file2. As you can see, we have a bit of header information and then we have an arrow pointing to the right which means we added. And this is the one that was added in file2. If I open file2 up again and remove the first line and save this as file3. If I do diff file2 and file3, you can see that the arrow is pointing the other way. We have an arrow pointing to the left, which means this line was removed in file3. So the Git diff tools will work something like that. Let me remove those three files I just created and then clear our screen here. And we're ready to look at our project. If I do a git status, our working directory is clean, so let's make some changes. And I'm going to make some changes to the README. And down here at the bottom, we will just add the line, All rights reserved. Just something simple that sounds like it might go in a README file. So now if we do that and we run git status, we can see we have modified the README file. But let's say we've modified more than one file over the course of maybe half an hour or something. We don't remember what was it that we did to the README file. Or we come to our repository maybe after taking a break for a day or two. And we say, okay, I see that the README file has been modified. What has been modified? Well, if I open up the README file, there's nothing there that tells me what's changed. All I can see is it's current state. I can't see what it was, when it was last committed. So this is where the git diff command comes in. If I run git diff and I pass it the README file as the single parameter and I hit Enter. So as you can see, here is the output that we get from the git diff command. And there's a bunch of header information that can be a bit cryptic. And you'd really don't have to worry too much about that, if you remember what we're comparing here. We're comparing the current state of the README. Or the state of the README file in the working directory to the state of the README file in the index. Now the README file isn't in the index, so it's comparing it basically to what the README file last was in the index. Which is basically where our README file was at the last commit. So we can see since that since we have last committed or since we have last staged this README file. We have added these lines. And since we set color ui to true when we were configuring Git, you can see that these lines show up in green. And it have a little plus sign at the beginning, so you know that they have indeed been added. And the text that we have added to this file is written in green. Now if I was to write now, git add all our files. So we're just gonna add that to our staging directory or our staging area. And now if we run git status, you can see that changes to be committed. Those changes that we've made to the README file have been added to the staging area. If I now run git diff on README, you can see that we have no output. And that's because git diff by default, compares the working directory content to the staging area content. So now, what we have in the working directory and what we have in the staging area are the same, because we staged the file. Now of course, just because it's staged that doesn't mean it's committed. After all we will find in a later video, that even if you've staged a file, you can still unstage it before making your commit. So staging is kind of that intermediate stage as we've talked about before. But what if we wanted to compare what's in the staging directory with what our latest commit looked like? But well, we have to tell git diff that we wanna do this and we do this by passing in a flag. The flag we use is --staged. Now if I pass at README, you can see that we get the very same output we did before. Those two lines are gonna be added. These two lines are the difference between what is in the staging area and what is in the latest commit. Now I used the --staged flag like that. However, if you're looking at documentation or examples online, you may see the diff --cached version. Which is exactly the same thing, as you can see. In fact, they both are the same flag, just different names for the same flag. Staged is the newer version I believe, which just is more descriptive of what you're doing. You're actually comparing what has been staged to what has been committed. Cached is an older name. So I recommend you use staged just in case they deprecate or get rid of the cached flag. So now let's open up our README file again and let's remove this line 8. In fact, we'll remove line 6 and 7 as well. Let's remove and save that. Now if we run git diff README, notice what is different. The only changes that are showing up are these three lines that we just deleted. And notice specifically that they are in red because of our color configuration. They have a minus sign at the beginning, cuz they have been deleted. But like I was just saying, notice that All rights reserved. It's acting as if it's just normal content. And the reason is when you just run git diff without any flags, as we did right here, git diff README. When you run git diff filename with no flags, git is comparing what's in the working directory with what's in the staging area. Currently, that All rights reserved content is in the staging area. So it doesn't see that as something that's been added. Notice that if I run git diff --staged again on the README file, we don't see anything at all to do with those three lines we just deleted. Because this is staged. And we're comparing the staging directory and what has been committed into the git repository. Now, what if you want to run a diff between what is in the working directory and what is actually committed? And just kind of skip what's in the staging area? Well, think about this in a more general case. You want to compare what you have in the working directory with the content of the file based on a commit. Normally, you're gonna wanna just do this for the latest commit to compare it with what you last committed. However, you could do this through references to any commit. If you watched the theory video, you know the HEAD is actually a reference to the last commit on the current branch. So we can run git diff HEAD and then pass it the README file. And we're going to get a comparison between what's in the working directory in the README file and HEAD's version of the README file. Or basically, the last version of README that we committed. Now you can see that we have our two lines removed here and our one line added. And you might say, well up here, it shows that we added two lines and up here, it says that we removed two lines. Yes, that's true. But based on the whitespace, it all works out in the end. To have, as you can see, only one blank line of whitespace here above the line that we actually added. Although it's not exactly the same content that it's showing, it really is the same results in the end. So that's how you can compare what is in your working directory with what is either in your staging area or in the repository. Or even compare the staging area with the repository. It's often a good idea to do this just before you make a commit. So that you can see exactly what you're gonna commit. In fact, you actually don't even have to add the file names. If I just run git diff, I'm gonna get a diff of every file that I've edited and what the changes are between that and the staging area. And if I run git diff head, I'll again be shown the difference between what is in the working directory and what is in the git repository for every file that I've changed. In this case, I've actually only changed one file. But if I'd changed more than one file, then this would give us some more output. So that is the first of several tools that Git has for just looking at the state of your repository and not actually changing anything.

Back to the top