{:check ["true"], :rank ["lifecycles" "status" "add" "commit" "diff"]}

Index

Recording changes in timeline

https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository

Review of git anatomy

+------------+          +-----------+         +-------------+
|            |          |           |         |             |
| repository |  <---->  | staging   |         | working     |
|            |          | area      | <-----> | directory   |
+------------+          |           |         |             |
                        +-----------+         +-------------+
                                                     |
                                                     |
                                                     +--- we work here.

Files in the working directory

  • Untracked

    A file exists in working directory, but not anywhere else.

  • Unmodified

    A file exists in the HEAD of the repository and the working directory, and both versions identical.

  • Modified

    A file exists in the HEAD of the repo, and in working directory. But the newest version of the file only exists in the working directory (not in staging area, nor repository).

  • Staged

    The newest version of a file in the working directory has been placed in the staging area, ready to be included in a new commit.

Lifecycles

Lifecycle of new files

New files start as untracked, but can be staged, and then commited.

<untracked> -----> <staged> ------> <unmodified>

Lifecycle of existing files

  • Unmodified files can be modified, then staged and finally committed.
  • Unmodified files can also be removed from the repository, so they become untracked again.
<unmodified> ----> <modified> ----> <staged> -----+
   |    ↑                                         |
   |    |                                         |
   |    +-----------------------------------------+
   |
   +---> <untracked>

Status

Status

We may have hundreds or thousands of files in the working directory, and each of them can be in one of the following states:

  1. untracked

    if they should be part of the repo, we need to stage them.

  2. modified

    if the changes are worth keeping, we need to stage them.

  3. staged

    if there are enough changes in the stage, we need to create a new commit.

  4. unmodified

We need to understand which state each file is in order to determine the next course of action.

Git status

  • git status

    The git status command displays untracked, modified and staged files. By default, it will examine all files in the repository.

  • git status <directory>

    We can optionally limit the scope to just the directory specified in the argument.

$ git status .

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   anatomy_of_git/index.md
	modified:   index.md
	modified:   setup/index.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   introduction/index.md
	modified:   recording_changes/index.md
	modified:   versioning_filesystem/index.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	recording_changes/add.md
	recording_changes/commit.md
	recording_changes/diff.md
	recording_changes/lifecycles.md
	recording_changes/status.md

Actions to take

We will examine the specific actions individually later. But let's look at the output of the git status command. It actually provides some suggestions of the actions to take for each of the types of files.

$ git status .

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)  # <==== 
	modified:   anatomy_of_git/index.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)            # <====
  (use "git restore <file>..." to discard changes in working directory) # <====
	modified:   introduction/index.md

Untracked files:
  (use "git add <file>..." to include in what will be committed) # <====
	recording_changes/add.md

Add

Tracking New Files

Suppose we create a new file test.py in working directory. How do we add test.py to the staging area?

$ git add test.py

This adds a new file to the staging area.

Note:

The file test.py is not included in any commit yet in the timeline. For that, we need to perform commit.

Unstage a new file

We can remove the new file test.py from the staging area. It will still exist in the working directory.

$ git restore --staged test.py

Staging Modified Files

Suppose the HEAD has a file main.c, but a newer version exists in the working directory. How do we add the new version main.c to the staging area?

$ git add main.c

Note:

Observe that git add can be used to add new files and new versions of existing files. One can perform both at the same time:

$ git add main.c test.py

Unstage a modified file

We can add the new version of main.c into the staging area.

$ git reset HEAD main.c
             |     |
             |     +--- the file to be reset in the staging area
             |
             +--------- the commit to get the restored copy

Adding All Changes

This add all new or modified Python files.

$ git add *.py

This adds all new or modified files in the current directory.

$ git add .

This adds all new or modified files anywhere in the current repository.

$ git add --all

Making exceptions

We can instruct git to ignore certain files via the .gitignore file. The .gitignore file lists all patterns of file names that are ignored by git add.

__pycache__/
*.pyc
*.class
*.o

Commit

Committing Your Changes

When all the changes you want to make are added to the staging area, you can create a new commit in the current timeline.

$ git commit -m "... your message ..."

Note:

Every commit must have a short message associated with it. If you do not specify the git commit -m ... option, git will start your default text editor, and ask you to enter the message.

Amendments to last commit

If you have just committed the staging area as a new commit, then you have the option to make amendments to:

  1. the commit message

    $ git commit -m '... new message ...' --amend
    
  2. the files associated with the commit

    \$ git add ...
    \$ git add ...
    \$ git commit --amend -m '...'
    

Diff

Viewing Your Staged and Unstaged Changes

 +---------------+          +-------------+           +------------+
 | repository    |          | staging     |           | working    |
 | HEAD          |  <-----> | area        | <-------> | directory  |
 |               |          |             |           |            |
 +---------------+          +-------------+           +------------+

Recall that we can use git status to list the files at each of stages:

  1. untracked files
  2. modified files
  3. staged files

Here is an example:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

There is one modified file README that has been staged, but not committed.

How is README in the staged area different from the version in the HEAD of the repository?

$ git diff --staged README

diff --git a/README b/README          # compare HEAD vs staged > index 0000000..03902a1
--- a/README                          # - are unique to HEAD
+++ b/README                          # + are unique to staged version
@@ -0,0 +1 @@                         # position in the file
+My Project                           # unique to the staged version

There is one modified file CONTRIBUTING.md in working directory, but not staged yet.

How is CONTRIBUTING.md in the working directory idfferent from the version in the staging area.

$ git diff CONTRIBUTING.md

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
 Please include a nice description of your changes when you submit your PR;
 if we have to read the whole diff to figure out why you're contributing
 in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

 If you are starting to work on a particular area, feel free to submit a PR
 that highlights your work in progress (and note in the PR title that its

Summary

  • git diff --staged <file>

    Compares versions of files between staged and head.

  • git diff <file>

    Compares versions of files in working directory and the staged version.