Last modified: January 27, 2025

This article is written in: 🇺🇸

Staging, Committing, and Undoing Actions

At the core of Git are a few fundamental actions: staging changes, committing those changes, and, when necessary, undoing certain actions. These notes provide a clear overview of these basic operations and some common scenarios where they are used.

Understanding these actions is important for effective version control. Proper staging ensures that only the desired changes are included in a commit, committing records the project's state at specific points, and knowing how to undo actions allows for correcting mistakes during development.

Staging Files

To prepare changes for a commit, we "stage" them. Staging involves selecting which changes in your working directory you want to include in your next commit. The staging area, also known as the index, acts as an intermediary between your working directory and your repository (commit history).

Staging is a critical step because it allows you to organize your changes logically before recording them. By carefully selecting which changes to stage, you can create more meaningful and manageable commit histories, making it easier to track and understand project evolution.

+--------------+    +--------------+     +-------------------+
|              |    |              |     |                   |
| Working      |    | Staging      |     | Repository        |
| Directory    |    | Area (Index) |     | (Commit History)  |
|              |    |              |     |                   |
|  (Changes)   | -> | (Changes to  | ->  | (Commits)         |
|              |    | be committed)|     |                   |
+--------------+    +--------------+     +-------------------+

Here's how to stage files:

I. Stage a Specific File:

To stage a specific file, use the git add command followed by the file name. This tells Git to include the changes made to this file in the next commit.

git add filename

Example: If you modified a file named index.html, you would stage it with:

git add index.html

Staging individual files is useful when you want to commit changes selectively, ensuring that unrelated modifications are kept separate for clarity.

II. Stage All Changed Files:

If you want to stage all the changes you made across multiple files, you can use the git add . command. The period . is a wildcard that tells Git to stage changes from the current directory and all its subdirectories.

git add .

Example: If you modified several files and you want to stage all of them at once, simply run:

git add .

Staging all changes at once is efficient when you're confident that all modifications are related and should be committed together.

Unstaging Files

If you've staged changes but haven't committed them, you can unstage them. This can be useful if you change your mind about what should be included in the next commit.

Unstaging allows you to refine your staged changes, ensuring that only the appropriate modifications are recorded. It provides flexibility to adjust your commits before finalizing them.

I. Unstage a Specific File (but Keep Changes):

To unstage a specific file but keep the changes in the working directory, use the git reset command followed by the file name. This removes the file from the staging area.

git reset filename

Example: If you previously staged index.html but now want to unstage it, run:

git reset index.html

This is helpful when you realize that a particular file shouldn't be part of the current commit and needs further modifications.

II. Revert Everything to the State of the Last Commit:

If you want to discard all changes and revert everything in the working directory and staging area to match the last commit, use the git reset --hard command. This will remove all uncommitted changes, so use it with caution.

git reset --hard

Example: To discard all changes and revert to the last commit, run:

git reset --hard

This command is useful when you need to completely abandon your current work and return to a known good state.

Committing Files

Commits in Git are akin to saving the state of your project at a particular point in time. A commit captures the current state of your project and associates it with a message that describes the changes made since the last commit. Each commit is uniquely identified by a SHA-1 hash, and you can use the git checkout command to revert to a previous state of your project.

Commits form the backbone of your project's history, allowing you to track progress, understand changes, and collaborate effectively with others.

+----------+
|  commit  |
|   hash   | A unique identifier (SHA-1 hash) for the commit.
+----------+
|  author  | The person who authored the commit.
|  date    | The date and time the commit was made.
+----------+
| message  | A brief description of the changes made in the commit.
+----------+
| changes  | The actual changes made to the files.
+----------+

Here's how to commit files:

I. Commit All Staged Files with a Message:

To commit the changes you have staged, use the git commit command with the -m option followed by a descriptive message. This message should succinctly describe what changes have been made.

git commit -m "Your descriptive commit message"

Example: If you added a new feature, you might write:

git commit -m "Added new feature to enhance user interface"

A clear commit message is essential for maintaining a readable and understandable project history, especially when collaborating with others.

II. Push Your Commits to a Remote Repository (like GitHub):

After committing your changes locally, you often need to push them to a remote repository to share them with others or back them up. Use the git push command to accomplish this.

git push

Example: To push changes to the main branch of your remote repository:

git push origin main

Pushing commits ensures that your work is stored remotely, enabling collaboration and safeguarding against data loss.

III. Go Back to a Previous State Captured in a Specific Commit:

If you need to revert your project to a previous state, use the git checkout command followed by the commit ID. This command allows you to explore the project as it was at that specific commit.

git checkout commit_id

Example: If the commit ID is a1b2c3d4, you would use:

git checkout a1b2c3d4

This is useful for reviewing past versions or recovering specific states of your project.

Undoing Commits

Mistakes happen, and Git provides several ways to undo commits:

Being able to undo commits is vital for maintaining a clean and accurate project history. Whether you need to correct errors or remove unintended changes, Git's undo capabilities offer the necessary tools to manage your commits effectively.

I. Undo the Last Commit but Keep All Files Staged:

If you want to undo your last commit but keep the changes staged, use the git reset --soft HEAD~ command. This is useful if you realize you need to modify your commit message or make additional changes before committing again.

git reset --soft HEAD~

This approach allows you to adjust your last commit without losing any work, providing a chance to refine your changes.

II. Undo the Last Commit and Unstage the Changes:

To undo the last commit and unstage the changes (but keep them in the working directory), use the git reset HEAD~ command. This will make the changes appear as if they were never staged or committed.

git reset HEAD~

This is helpful when you need to reorganize your commits or exclude certain changes from the previous commit.

III. Erase All Changes Made in the Last Commit:

If you want to completely undo the last commit and discard all changes made, use the git reset --hard HEAD~ command. This is a more destructive action, so use it with caution.

git reset --hard HEAD~

Use this command only when you are certain that you want to remove the last commit and its changes permanently.

Editing Commit Messages

Sometimes, after committing changes, you realize that your commit message could be clearer or more descriptive. Fortunately, Git allows you to amend your commit messages. Here’s how to do it:

Clear and accurate commit messages enhance the readability of your project's history. Editing commit messages ensures that each commit accurately reflects the changes made, which is especially important for collaborative projects.

Edit the Message of the Most Recent Commit

To change the commit message of the most recent commit, use the git commit --amend command followed by the new message. After amending the commit message, you need to force push the changes to the remote repository.

git commit --amend -m "New, improved message"
git push --force

Example: If you want to update the most recent commit message to "Fixed bug in user authentication," you would run:

git commit --amend -m "Fixed bug in user authentication"
git push --force

Amending commit messages is straightforward but requires caution, especially when working with shared repositories.

Modify an Older Commit Message

If you need to change the message of an older commit, follow these steps:

I. Start an Interactive Rebase for the Last n Commits:

Begin by initiating an interactive rebase. Replace n with the number of commits you want to go back from the current head.

git rebase -i HEAD~n

Example: To modify the last 3 commits, you would run:

git rebase -i HEAD~3

Interactive rebasing allows you to selectively edit, reorder, or squash commits, providing granular control over your commit history.

II. Change "pick" to "reword" for Commits You'd Like to Modify:

In the interactive rebase interface, change pick to reword for the commits whose messages you want to edit.

III. Save and Close:

Save the changes and close the editor. Git will then prompt you to provide new commit messages for each commit marked with reword.

IV. Push the Changes:

After editing the commit messages, you need to force push the changes to the remote repository.

git push --force

This process ensures that your commit history remains clean and that older commits have accurate and meaningful messages.

Removing Commits

If you need to undo one or more commits, Git provides commands to help you do so safely:

Removing commits can help maintain a tidy and relevant project history. Whether you're removing erroneous commits or cleaning up your commit log, Git offers tools to manage and refine your commits effectively.

I. Remove the Last N Commits:

To remove the last N commits, use the git reset command followed by the number of commits you want to go back. Then, push the changes to the remote repository.

git reset HEAD~N
git push origin +HEAD

Example: To remove the last 2 commits, you would run:

git reset HEAD~2
git push origin +HEAD

This method allows you to eliminate recent commits while preserving the underlying work in your working directory.

Cleaning Up Your Commit History

If you need to remove sensitive data or a large file from your commit history, use the git filter-branch command. This command rewrites the commit history, so use it with caution.

Cleaning up your commit history is essential when dealing with sensitive information or optimizing repository size. By removing unwanted files or data, you can ensure that your repository remains secure and efficient.

I. Remove a File from the Commit History:

To remove a specific file from the entire commit history, use the following command:

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch file_to_remove' HEAD

Example: To remove a file named secret.txt from the commit history, you would run:

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch secret.txt' HEAD

This command effectively erases the specified file from all past commits, ensuring that it is no longer part of the repository's history.

Table of Contents

    Staging, Committing, and Undoing Actions
    1. Staging Files
    2. Unstaging Files
    3. Committing Files
    4. Undoing Commits
    5. Editing Commit Messages
      1. Edit the Message of the Most Recent Commit
      2. Modify an Older Commit Message
    6. Removing Commits
    7. Cleaning Up Your Commit History