Home
Setup
Committing
Eclipse and Git
FAQ

Committing your changes

Recall that the purpose of Git's index is to serve as a place to put changes that are ready to be committed. This page explores how to manipulate the index and turn it into a commit once you're happy with its contents.

Overview of working with the index
Overview of working with the index
(Image credit: Pro Git by Scott Chacon)

Querying status

When using Git, if you are ever unsure of the state of your working directory relative to the master branch, the status command can be extremely informative.

For example, at this point in the project, nothing has been done. Let's do a small experiment to demonstrate the usefulness of the status command!

  1. To create a file for our commit (in this case, the generic file file1.txt), run:
    $ touch file1.txt
  2. To ensure the file was successfully created, run:
    $ ls
    You should find file1.txt in the list of files.
  3. Now that we have a file for our first commit, let's first check the status of our repo:
    $ git status
  4. This should yield the following output:
    # On branch master
    # 
    # Initial commit
    # 
    # Untracked files:
    # 	(use "git add <file>..." to include in what will be committed)
    # 
    # 	  file1.txt
    nothing added to commit but untracked files present (use "git add" to track)
  5. Notice the Untracked files header: it indicates that file1.txt's history is not being tracked in our repository. In order for such files to be included in our next commit, we will have to learn how to stage/track files.

Tracking files

Before we can make any commits, we need to tell Git which files we want to include. To do this, for each file that we want to be version-controlled, we must add it to the holding area for ready-to-commit files (aka the "index" or staging area).

  1. We want to commit our new file called file1.txt, so let's add it to the commit! You can do this with the following command:
    $ git add file1.txt
  2. To check if it worked, we will use the status tool again:
    $ git status
  3. This time, the output generated is different:
    # On branch master
    # 
    # Initial commit
    # 
    # Changes to be committed:
    # 	(use "git rm --cached <file>..." to unstage)
    # 
    # 		new file:	file1.txt
    # 
  4. Note that Git now sees our "newly-added" file.
  5. But wait! I actually want to change the contents of file1.txt, but I already added it to the commit! We can fix this issue after we make the desired changes to the file, simply by "updating" the version of the file that has already been added to the commit.

Updating files

When working with version-controlled files, it is common to suddenly remember something you wanted to do to a file before committing it, but you already added it to the commit! Worry not; this is a very easy fix.

We want to make a slight change to file1.txt and then make a commit with the most up-to-date version.

  1. Open file1.txt in your favorite text editor, and add some text of your choice. Save the file and return to the terminal window.
  2. Now what? The status command can give us a hint:
    $ git status
  3. Now we see that there are two different versions of file1.txt that have not been committed: the version in the stage (unchanged) and the one in our current working directory (changed).
    # On branch master
    # 
    # Initial commit
    # 
    # Changes to be committed:
    # 	(use "git rm --cached <file>..." to unstage)
    # 
    # 		new file:	file1.txt
    # 
    # 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:	file1.txt
    # 
  4. We must decide whether we want to include these new changes in our next commit:
    1. If we do want to commit these changes with our earlier ones, we must update the version in the stage to reflect the new ones:
      • To re-add the file to the stage:
        $ git add file1.txt
    2. If we only want to commit the first set of changes we made, we should just skip re-adding the file.
    3. If we no longer want the new changes at all, we can permanently discard them:
      • To discard the changes made to file1.txt after it was last added to the stage:
        $ git checkout -- file1.txt
  5. Just to double check that everything is as it should be:
    $ git status
  6. Observe the following output:
    # On branch master
    # 
    # Initial commit
    # 
    # Changes to be committed:
    # 	(use "git rm --cached <file>..." to unstage)
    # 
    # 		new file:	file1.txt
    # 

Making commits

  1. We have already made sure that the stage accurately represents everything that we want to include in our commit, so we are ready to go.
  2. To make the commit, use the following command:
    $ git commit
  3. If you are working in the terminal, you will automatically be taken to your default text editor. Enter the commit message "init commit", save the file, and exit.
  4. The output produced will look something like this (possibly with a few small deviations):
    [master (root-commit) 949b9f1] init commit
    1 file changed, 1 insertion(+)
    create mode 100644 file1.txt
  5. For the sake of knowledge, let's check our status again, now that the commit is complete:
    $ git status
  6. Observe the following output:
    # On branch master
    nothing to commit (working directory clean) 
  7. Success!
  8. Note: Now that we've created a commit, we're at a good stopping point to leave the project and come back to it later. Just after making a commit is also when we might submit our work for grading once we've finished an assignment.

Renaming/Moving tracked files

Now that we have successfully made a commit, what happens if we need to rename a tracked file?

  1. To find out, let's rename our file1.txt file to the more descriptive name readme.txt:
    $ git mv file1.txt readme.txt
  2. Now check the status again:
    $ git status
  3. Observe the following output:
    # On branch master
    # Changes to be committed:
    # 	(use "git reset HEAD <file>..." to unstage)
    #
    # 		renamed:	file1.txt -> readme.txt
    # 

If you simply relocate a file within your repository, you can use the mv command to update Git in the same way.

  1. For example, let's move our readme.txt into a new directory called documentation:
    $ mkdir documentation
    $ git mv readme.txt documentation/readme.txt
  2. Now check the status again:
    $ git status
  3. Observe the following output:
    # On branch master
    # Changes to be committed:
    # 	(use "git reset HEAD <file>..." to unstage)
    #
    # 		renamed:	file1.txt -> documentation/readme.txt
    # 
  4. Note that Git understood that the two changes were referencing the same original file, file1.txt.

Removing tracked files

It turns out that we do not need our readme.txt file after all. We want to delete our working copy, and also tell Git that we deleted it. To accomplish this, we will use the rm command.

  1. First things first: we need to delete the readme.txt file:
    $ rm documentation/readme.txt
  2. Now check the status to see what happens:
    $ git status
  3. Observe the following output:
    # On branch master
    # Changes to be committed:
    # 	(use "git reset HEAD <file>..." to unstage)
    #
    # 		renamed:	file1.txt -> documentation/readme.txt
    #
    # Changes not staged for commit:
    #	(use "git add/rm <file>..." to update what will be committed)
    #	(use "git checkout -- <file>..." to discard changes in working directory)
    #
    #		deleted:	documentation/readme.txt
    # 
  4. To make sure the deletion is included in our next commit, follow the directions from the output:
    $ git rm documentation/readme.txt
  5. This should result in the following output:
    rm 'documentation/readme.txt'
  6. Now check the status again:
    $ git status
  7. The output shows that the file has been successfully deleted and is no longer being tracked:
    # On branch master
    # Changes to be committed:
    # 	(use "git reset HEAD <file>..." to unstage)
    #
    # 		deleted:	file1.txt
    # 
  8. Note that when the file was deleted, any other uncommitted changes to that file were also discarded. (In this example, the fact that we renamed and move the original file1.txt no longer matters.)

Viewing your commit history

If at any point in the progression of your project, you want to take a look at a history of all of your commits so far, Git has the perfect tool for you!

Exploring old versions

Sometimes it's helpful to experiment with an older version of your codebase, either for nostalgia or because you're trying to determine when you introduced a bug. This is where the checkout tool comes in handy.

  1. First, check your status to ensure you do not have any uncommitted changes:
    $ git status
    If you do, commit them before continuing.
  2. Examine the output of your most recent log (see the previous section for more details) and find the hash of the commit you want to work with.
  3. Checkout the version of the code corresponding to the hash value <hash>:
    $ git checkout <hash>
  4. Read, build, and experiment with this older version of your code, but DO NOT make changes you want to keep or attempt to commit anything.
  5. Once you're ready to return to the latest version of your code, execute this command:
    $ git checkout master

Viewing diffs

If you ever reach a point where you would like to see the differences between two different states of your repository, the diff tool can be quite useful. One important thing to note is that the <path> parameter can be either a path to a specific file, or an entire directory. Specifying a directory allowed you to get the diff for all files under that directory.