Committing

A commit is a pile of changes. For example, this commit changed two files in this guide: it deleted (red) and added (green) several things in getting-started.md, and added one line to run_commands.py.

Before doing anything else, let's run git status just to see what's going on. It doesn't show much yet, but its output will change as we make a commit.

$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

If you get an error saying fatal: not a git repository, you forgot to cd to the cloned repo as shown here.

We'll talk more about branches later, but the last line is relevant; it basically means you haven't done anything yet.

Now open README.md in your favorite text editor and write some text to it.

Change the content of README.md to this
# reponame
This is a better description of this repository. Imagine you just wrote it
into your text editor.

More text here. Lorem ipsum blah blah blah.

Remember to save it in the editor. Then run git status again:

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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:   README.md

no changes added to commit (use "git add" and/or "git commit -a")

Adding, also known as staging, means choosing what will be included in the next commit. This way it's possible to edit several files and commit only some of the changes. Adding a file doesn't modify it; it just makes Git remember the changes you did.

As the status message suggests, we will use git add <file>.... Here <file> means that you should put a file name there, and ... means that you can specify several files if you want. We will add only one file, the README.md:

$ git add README.md

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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

Notice that now modified: README.md shows up under Changes to be committed instead of the previous Changes not staged for commit. It also turned green, and in general, green output of git status means "this will be committed".

Before committing, let's look at what is going to be committed. According to git status, something changed in README.md, but let's see what exactly changed:

$ git diff --staged
diff --git a/README.md b/README.md
index a93665e..610acc2 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,5 @@
 # reponame
-The description of the repository is here by default
+This is a better description of this repository. Imagine you just wrote it
+into your text editor.
+
+More text here. Lorem ipsum blah blah blah.

The first line of the README is # reponame, and it was not changed. There was one line after that, The description ..., and it was deleted. The rest was added when editing the file in the editor.

Diffing is optional, and it does not affect the output of git status, but it may help you discover problems. If you notice that something isn't quite right, you can still edit the files, and then run git add again when you are done. Alternatively, if you don't want to commit any changes to README.md, you can use git restore as shown in git status output to undo the git add:

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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


$ git restore --staged README.md

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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:   README.md

no changes added to commit (use "git add" and/or "git commit -a")

$ git add README.md

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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

Without --staged, git restore undoes changes that you saved in the editor but didn't git add yet. This is useful when you realize that you wrote something stupid and you want to start over. The same goes for git diff: without --staged, instead of showing what will be included in the commit, it shows changes that aren't added yet.

When you have added the changes you want and checked with git diff --staged, you are ready to git commit, like this:

$ git commit -m "add better description to README"
Author identity unknown

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident name (for <>) not allowed

This error happens when you try to commit for the first time. To fix this, run the commands that the error message suggests, replacing Your Name with your GitHub username and you@example.com with the email address you used when creating your GitHub account.

$ git config --global user.email "you@example.com"

$ git config --global user.name "yourusername"

Now committing should work:

$ git commit -m "add better description to README"
[main 7b47314] add better description to README
 1 file changed, 4 insertions(+), 1 deletion(-)

The text after -m is a commit message. Enter something descriptive, such as "add better description to README" in this case; finding something from a long list of commits really sucks if the message of every commit is "files edited".

Now the file no longer shows up as modified in git status, because we committed the change:

$ git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

You can ignore the main part of origin/main for now, but when using Git with GitHub, "origin" means the repo on GitHub. So, the git status output is saying that there is one commit that you haven't uploaded to GitHub yet.

At this point you can create more commits if you want, but the commits are only on your computer. Run git push to upload the commits to GitHub:

$ git push
Username for 'https://github.com': username
Password for 'https://username@github.com':
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 184 bytes | 184.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/username/reponame
   50ec14e..7b47314  main -> main

Git will ask for your GitHub username and password. You won't see the password as you type it in, and that's completely normal. After pushing, you should immediately see your changes on GitHub.

Looking at previous commits

Run git log to get a list of all previous commits.

$ git log
commit 7b473143eaf1d261486537dcabd1f99c2c3c0dcf (HEAD -> main, origin/main, origin/HEAD)
Author: yourusername <you@example.com>
Date:   Thu May 27 16:40:26 2021 +0000

    add better description to README

commit 50ec14e1b733e35b9eb4af5b695a7a560391d900
Author: yourusername <you@example.com>
Date:   Wed Aug 25 10:45:17 2021 +0000

    Initial commit

Here Initial commit is what GitHub creates when you make a new repo, and add better description to README is the commit we just created.

As you can see, the latest commit is on top, and older commits are below it. If you have many commits, specify --oneline so you can fit more commits on the screen at once:

$ git log --oneline
7b47314 (HEAD -> main, origin/main, origin/HEAD) add better description to README
50ec14e Initial commit

Each commit has a unique commit hash, sometimes also known as commit ID or SHA. For example, the hash of our latest commit is 7b473143eaf1d261486537dcabd1f99c2c3c0dcf. The hashes are often abbreviated by taking a few characters from the beginning, so 7b47314 and 7b473143eaf1d261486537dcabd1f99c2c3c0dcf refer to the same commit.

Use git show to show the code changes of a commit:

$ git show 7b47314
commit 7b473143eaf1d261486537dcabd1f99c2c3c0dcf (HEAD -> main, origin/main, origin/HEAD)
Author: yourusername <you@example.com>
Date:   Thu May 27 16:40:26 2021 +0000

    add better description to README

diff --git a/README.md b/README.md
index a93665e..610acc2 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,5 @@
 # reponame
-The description of the repository is here by default
+This is a better description of this repository. Imagine you just wrote it
+into your text editor.
+
+More text here. Lorem ipsum blah blah blah.

If you don't specify a commit hash, it shows the latest commit:

$ git show
commit 7b473143eaf1d261486537dcabd1f99c2c3c0dcf (HEAD -> main, origin/main, origin/HEAD)
Author: yourusername <you@example.com>
Date:   Thu May 27 16:40:26 2021 +0000

    add better description to README

diff --git a/README.md b/README.md
index a93665e..610acc2 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,5 @@
 # reponame
-The description of the repository is here by default
+This is a better description of this repository. Imagine you just wrote it
+into your text editor.
+
+More text here. Lorem ipsum blah blah blah.

Commands in older versions of git

If you find that the git status output suggests different commands than in this tutorial, it's likely because you have an old version of git. You don't need to update it; just use the commands that your git status output suggests instead of the corresponding commands shown in this tutorial.

For example, if I git add a file on my computer and then run git status, it suggests this instead of git restore --staged:

  (use "git rm --cached ..." to unstage)

So on new versions of git, git restore --staged and git rm --cached do the same thing, and on my older version of git, only git rm --cached works. There's also a third way to do this, suggested by even older versions of git.

In short, the commands that git status suggests will always work, but they depend on the git version.