Using git add

The command git add stages a file. In terms of Git’s file classifications, if a file is untracked, git add converts that file’s status to tracked. When git add is used on a directory name, all of the files and subdirectories beneath it are staged recursively.

Let’s continue the example from the previous section:

$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       .gitignore
#       data

# Track both new files.
$ git add data .gitignore

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file: .gitignore
#       new file: data
#

The first git status shows you that two files are untracked and reminds you that to make a file tracked, you simply need to use git add. After git add, both data and .gitignore are staged and tracked, ready to be added to the repository on the next commit.

In terms of Git’s object model, the entirety of each file, at the moment you issued git add, was copied into the object store and indexed by its resulting SHA1 name. Staging a file is also called “caching a file”[10] or putting a file in the index.

You can use git ls-files to peer under the object model hood and find the SHA1 values for those staged files:

$ git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0       .gitignore
100644 534469f67ae5ce72a7a274faf30dee3c2ea1746d 0       data

Most of the day-to-day changes within your repository will likely be simple edits. After any edit and before you commit your changes, run git add to update the index with the absolute latest and greatest version of your file. If you don’t, you’ll have two different versions of the file: one captured in the object store and referenced from the index, and the other in your working directory.

To continue the example, let’s change the file data so it’s different from the one in the index and use the arcane git hash-object file command (which you’ll hardly ever invoke directly) to directly compute and print the SHA1 hash for the new version:

$ git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0       .gitignore
100644 534469f67ae5ce72a7a274faf30dee3c2ea1746d 0       data

# edit "data" to contain...
$ cat data
New data
And some more data now

$ git hash-object data
e476983f39f6e4f453f0fe4a859410f63b58b500

After the file is amended, the previous version of the file in the object store and index has SHA1 534469f67ae5ce72a7a274faf30dee3c2ea1746d. However, the updated version of the file has SHA1 e476983f39f6e4f453f0fe4a859410f63b58b500. Let’s update the index to contain the new version of the file:

$ git add data
$ git ls-files --stage
100644 0487f44090ad950f61955271cf0a2d6c6a83ad9a 0       .gitignore
100644 e476983f39f6e4f453f0fe4a859410f63b58b500 0       data

The index now has the updated version of the file. Again, The file data has been staged, or, speaking loosely, The file data is in the index. The latter phrase is less accurate because the file is actually in the object store and the index merely refers to it.

The seemingly idle play with SHA1 hashes and the index brings home a key point: think of git add not as Add this file but more as Add this content.

In any event, the important thing to remember is that the version of a file in your working directory can be out of sync with the version staged in the index. When it comes time to make a commit, Git uses the version in the index.

Tip

The --interactive option to either git add or git commit can be a useful way to explore which files you would like to stage for a commit.



[10] You did see the --cached in the git status output, didn’t you?

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.99.174