-
Notifications
You must be signed in to change notification settings - Fork 1
The Four Areas Basic Workflow
-
You already know the basic workflow of Git, edit file, stage the file, and commit the file. Let's look at those commands again keeping the two questions in mind : How does this command move information across the four areas? and how does it impact the repository?
-
To begin, I will edit data in my working area in the
menu.txt
file and thegit status
tells us that the file has been changed, but not staged yet.
- Now I want to copy the updated file from the working area to the index using
git add
. There you are. The file has been copied from working area to the index overriding the previous version of the same file.
-
Now
git status
tells me that the file is modified and staged andgit diff
sees no difference. The working area and the index are aligned. But if I compare the index and the repository,git diff --cached
, then I can see the changes. They are ready to get into the next commit. -
So let's do this,
git commit
. And as soon as we commit, the updated file is copied from the index to the repository. And now everything is aligned again.
- So in the course of these few operations, we moved data from left to right so to say, from the working area to the index to the repository. And now, as a result, the three areas contain exactly the same data, no difference whatsoever. We're in the clean status again.
- Notice that the last command,
git commit
, did more to the repository than just copy in this file. It also created a new commit and other objects. It updated the current branch, all stuff that I'm not showing in this picture here. So commit moves data and also changes the repository. It's actually one of the most important commands that change the repository. By contrast, add just moves data and doesn't touch the repository.
-
git checkout
moves data in the other direction from the repository to the working area and the index. -
Checkout does two things essentially:
- In the repository, it moves the head reference generally to another branch. So it changes the current commit.
- It takes data from the new current commit and it copies that data from the repository to the working area and to the index, so it changes the repository first and moves data second.
-
Let's look at the lisa branch. I can see the differences between that branch and our current master branch by diff in there. In lisa, the menu file is different and other files in the recipes directory are also different. So what happens if we checkout the lisa branch? A couple things just happened.
-
There is a commit pointing at them and this is the current commit. It's the current commit because there is a branch pointing at it, which is master, and head is pointing at that branch.
-
Well the first thing that happened when we checked out is that head moved to the lisa branch. So the current commit changed. Where we are now, the files are different, it's not the data in the repository actually changed, it's just the head changed. So the current commit changed, so we're seeing different data.
-
The second the last thing it did is it copied the current data from the repository to both the working area and the index.
- So now, all the three areas have the same content and we are in the clean status again. So
git checkout
changes the repository because it moves the head pointer in there and it copies data from the repository to the working area and the index.
-
Now we have a new file in the working area. If I ask for a
git status
, I see this file marked as untracked - That means that the file is in the working area, but not in the index or the repository. Git doesn't know what to do with it yet. -
I'm planning to commit this file, so I will use
git add
to copy it to the index. And now thegit status
says that the file is new, which means that file is in the working area and the index, but it's not in the repository yet. It's not an official part of the project yet. -
If I commit it now, then the file would be copied to the repository, the three areas would be aligned, and I would be in the clean status again. But what if I change my mind instead? What if I want to remove the file from the index, say I want to keep this file in the working area, but I don't want it in the index anymore. Maybe I want to commit something else first and get back to this file later. In other words, I want to go back to the situation I was in before the last stat. I want the file in the working area, but not in the index.
-
I also have the option of removing the file from the index only, but not the working area with
git rm --cached
. The file is still in my working area, but I removed it from the index. That is, I unstaged the file.
- So to recap, in Git remove without arguments is not the opposite of add.
git add
only changes your index while the play remove changes both your index and your working area. You have to use thegit rm --cached
option to make a remove work as the opposite of add. To remove file permanently usegit rm -f
- Let's start for a clean status with the three areas containing the same data. I only visualize one of our files,
menu.txt
. I want to rename this file and give a markdown extension instead of a plain text extension. I will do that in my working area first.
(cmd)> move menu.txt menu.md
There, so now the file in my working area has changed. I made it in yellow in the picture to show it's changed. It's like a different file altogether.
-
What happens if I ask for
git status
? Git can see that there is a file in the working area that is not in the index. This yellow file here. So it says this file is new, I don't know about it, it's untracked (menu.md). And also Git can see another file that is in the index, but not in the working area, this orange file here(menu.txt). So it says this file is in the index. It's not in the working area. -
How can I tell Git, look this is actually the same file, only with a different name. Well the good news is I don't need to do that. I can just copy all the changes from the working area to the index. First, let me add new file.
$ git add menu.md
There, it's been added. And now, let's take care of the orange file by adding that one as well. I will admit that this looks strange, admitting something from the working area to the index, but that something is not in the working area in the first place.
$ git add menu.txt
- Well remember what add actually means. It means copy this data from the working area to the index. So if that data is nothing, as in this case, then Git will just override the data into index with nothing, which means it will remove that piece of data from the index.
-
So now we have the same data in the working area and the index. All of our changes have staged. And if we ask for the
git status
, It compared the content of the file in the working area and the index with content of the files in the repository and it noticed that the orange file and the yellow file have the same content, so they must be the same file with a different name. -
In most cases, it understands that you are naming or moving a file even if you change the content of the file at the same time. It just says these two files here look quite similar. It must be the same file.
-
Now, of course, you can confuse Git if you try really hard, for example, if you move a file and you also change most of its content at the same time, but I would argue that if you get to that point, then maybe you are doing too much stuff at once. Maybe consider moving and changing the file into separate commits. For simple changes, together with moves, it just works.
-
We have built-in command
git mv
, it basically just does the same things that we did. It moves the file in the working area and updates the index, only does it in a single shot. See I do need to rename the file first and that boosts the old and renamed file to the index later. I did all with a singlegit mv
.
$ git mv menu.txt menu.md
-
git add
copies data from the working area to the index and doesn't take back repository. -
git commit
copies data from the index to the repository and it also creates additional objects in the repository, particularly a new commit, and it moves the references in the repository. -
git checkout
copies data from the repository to the working area and the index and it moves the head reference in the repository. -
Remove (
git rm
) deletes files from both the working area and the index. It doesn't touch the repository though. -
git mv
, the move operation, moves the file in the working area and also updates the index. It doesn't touch the repository and you can actually ignore it and do the same things that it does with the other basic commands.