Git
git add

git add command: cancel, all, file directory, -u, -i option

Following on from git init command, this post is about the git add command. We'll cover how git works from add to commit, options to increase productivity, and how to undo staged files and directories. We'll also summarize the inner workings at the end for those who want to know more.

1. Simple mechanics from add to commit

1.1 Understanding the git add and git commit flows

Before we dive into how git works, here's something to think about. If we needed to create and save a new document, how many steps would we go through?

The answer is simple: write -> save -> commit, and the document is saved. This is simple, but there's a problem. Because it's only one step, there's a good chance you'll save it incorrectly.

Git takes saving once very seriously. That's why it takes two steps to minimize the chances of making a mistake on a single save. These steps are as follows

When changes are made to any file, they are committed with the git add command. Then we run git commit, which commits all the changes currently in the staged state to history as a single commit.

When a new change is made to a file that has been committed, it becomes the subject of another git add command. This is how version control works: git add -> git commit -> file change -> git add.

Let's look at an example to understand.

1.2 Understanding git add and git commit by doing it yourself

First we prepare the directory where the 2 markdown files are stored and create a new repo. When we look at the current status with the git status command, we see 2 files that we haven't tracked yet.

untracked status before git add

We add one file, 1.md, to the staged state with the git add command. Tracking of the `1.md' file, shown in light green, has started and it is waiting to be committed.

Status after git add

After executing the commit with the command git commit -m "commit message", the changes to the file 1.md are registered as a new commit and disappear from the staged state.

Status after git commit

At this point, if there are any new changes to the 1.md file, it will return to staged status.

File with changes is in staged state

This is how the add and commit commands are repeated.

1.3 A little more detail

Git keeps track of all files or folders in a working folder in two main states

  • untracked: git is not tracking changes to the file.
  • tracked: git is tracking changes to the file. When you create a new repo with the git init command, all files are untracked. The git add command changes a file from untracked to tracked, and continues to watch for changes.

git keeps tracked files in one of three states

  • staged: The staged state is preparing to become a commit. When a file in the untracked state is first changed to the tracked state, it becomes staged. Files in the modified state are also put into the staged state by the git add command.
  • unmodified: A file in the staged state becomes unmodified when changes to it are committed using the git commit command. This state is maintained until no more changes are made.
  • Modified: A file in the unmodified state becomes modified when a change is made to it. Files in this state become the target of the git add command.

To summarize all the states, you can think of them as going from untracked --(git add)--> tracked/staged --(git commit)--> unmodified --(changes occur) --> staged.

2. Adding all files and folders using the git add -A or --all command

As shown in the example above, to stage a specific file or folder in the current working folder, use the following command

git add <file 1>, <file 2>, <folder 1>

If there are subdirectories in <folder 1>, Git will automatically add them all to the staged state together.

If you want to stage all files and folders in the current working folder, without having to select specific files or folders, use the following command. This will target all untracked and modified files.

$ git add -A

Or you can use

$ git add .

3. Adding only tracked files and folders with git add -u

To stage only all modified files and folders that Git tracks in the current working folder, use the following command. Compared to the command in Section 2, this excludes untracked files and folders.

$ git add -u

4. Easily add the files and folders you want with the git add -i command

If you start interactive mode with the following command, you can add only the files you want to stage, or remove them with a simple number.

$ git add -i

This is what interactive mode looks like

git add -i result

The interactive mode prints the commands along with the `git status' output. Depending on your choices, 4 is used to stage untracked files, and 2 is used to stage modified files. 3 is used to revert the files staged by 2 and 4.

5. undo git add

In addition to the interactive mode, there is a command to revert files and folders added by the git add command.

To revert specific files and folders within a working folder, use the command

git restore --staged <file 1>, <folder 1>

To restore all files and folders, use the command

$ git restore --staged .

6. Internal behavior of the git add command

Internally, Git uses a few key data structures and concepts to manage and track changes. Let's take a step-by-step look at what happens internally when you run the `git add' command.

  1. When you run the git add command, Git takes a snapshot of the contents of the specified file and creates a new blob object in Git's object database (located in .git/objects). The blob object represents the contents of the file, not the file itself.
  2. Git then references the blob object to add an entry to the file's staging area (in other words, index). This entry contains the path to the file, the mode (file type and permissions), and the SHA-1 hash of the blob object. If you add multiple files, Git will create a separate blob object and index entry for each file.
  3. You're now ready to commit your incremental changes. Running the `git commit' command creates a new tree object representing the directory structure and file contents of the new commit. It also creates a new commit object that points to the tree object, stores the commit metadata (e.g. author, date, message), and points to the parent commit.
  4. Finally, Git updates the branch reference (e.g. refs/heads/master for the master branch) to point to the new commit object, making it the latest commit in the branch's history.

In summary, when you run the git add command, it creates a blob object for the added file, updates the staging area with information about that file, and then prepares it for the next commit, and prepares it for the next commit. The commit itself is not created until you run git commit.

7. Final thoughts

The git add command is the heart of the git version control system, and there are many concepts that will give you a good understanding of how it works. I hope this article has given you a good understanding of the concepts behind the git version control system and the many options you have to make staging easier.

copyright for git add

© 2023 All rights reserved.