DEV Community

Trevor Zabar
Trevor Zabar

Posted on

Understanding the Git Workflow: Working Directory, Staging, Commit, and Push

When I first started learning Git, commands such as git add, git commit, and git push seemed like separate steps that were easy to confuse. After practicing the Git workflow, I understood that each command moves changes to a different stage.
The complete workflow is:

Working Directory → Staging Area → Local Repository → Remote Repository
Enter fullscreen mode Exit fullscreen mode

In this article, I will explain each stage using a simple website project.

What Is Git?

Git is a version control system that tracks changes in a project. It allows developers to save different versions of their work and review or restore earlier versions when necessary.

GitHub is an online platform where Git repositories can be stored and shared. Git works on your computer, while GitHub stores a copy of your repository online.

The important difference is that saving a commit locally does not automatically upload it to GitHub. You must push the commit separately.

The Working Directory

The working directory is the project folder on your computer. It contains the files you are currently creating or editing.

For example, imagine a website project with the following files:

my-website/
├── index.html
├── style.css
└── script.js
Enter fullscreen mode Exit fullscreen mode

If I open index.html and change the heading, the change first exists in the working directory.

At this point, Git knows that the file has changed, but the change has not been prepared for saving yet. I can check the condition of the project with:

git status
Enter fullscreen mode Exit fullscreen mode

Git may display something similar to:

Changes not staged for commit:
  modified:   index.html
Enter fullscreen mode Exit fullscreen mode

This means that index.html has been changed, but it is not yet in the staging area.

The Staging Area

The staging area is where I select the changes that I want to include in my next commit.
To stage the modified file, I run:

git add index.html
Enter fullscreen mode Exit fullscreen mode

Then I check the status again:

git status
Enter fullscreen mode Exit fullscreen mode

The output may now look like this:

Changes to be committed:
  modified:   index.html
Enter fullscreen mode Exit fullscreen mode

The file is now ready to be committed, but it has not been permanently saved in the project history yet.

I can stage more than one file by listing the filenames:

git add index.html style.css
Enter fullscreen mode Exit fullscreen mode

I can also stage all changed files with:

git add .
Enter fullscreen mode Exit fullscreen mode

Although git add . is convenient, I should check the files before committing. It may stage files that I did not intend to include.

Why the Staging Area Matters

The staging area gives me control over what goes into a commit.

For example, suppose I make changes to two files:

  • I add a completed navigation bar to index.html.
  • I experiment with unfinished styles in style.css.

If I want to commit only the navigation bar, I can run:

git add index.html
git commit -m "Add navigation bar"
Enter fullscreen mode Exit fullscreen mode

The changes in style.css will remain in the working directory and will not be included in the commit.

This makes it possible to create focused commits. Each commit can describe one meaningful change instead of containing a mixture of unrelated work.

Creating a Commit

A commit is a saved record of staged changes. It represents a particular version of the project.

After staging index.html, I can create a commit with:

git commit -m "Update homepage heading"
Enter fullscreen mode Exit fullscreen mode

The message after -m explains what the commit contains.

Good commit messages include:

git commit -m "Add contact form"
git commit -m "Fix mobile navigation"
git commit -m "Update project documentation"
Enter fullscreen mode Exit fullscreen mode

Messages such as these are less useful:

git commit -m "Changes"
git commit -m "Update"
git commit -m "Work"
Enter fullscreen mode Exit fullscreen mode

A good commit message should be short, clear, and specific.

When I commit changes, they are saved in my local Git repository. They are not yet available on GitHub.

To view the project history, I can run:

git log
Enter fullscreen mode Exit fullscreen mode

For a shorter version of the history, I can use:

git log --oneline
Enter fullscreen mode Exit fullscreen mode

A short log may look like this:

a31f9c2 Add contact form
e72b410 Update homepage heading
Enter fullscreen mode Exit fullscreen mode

Each commit has a unique identifier that Git uses to distinguish it from other commits.

Pushing to GitHub

A remote repository is the online version of a Git repository. For many projects, the remote repository is hosted on GitHub.

After creating a commit locally, I can upload it with:

git push origin main
Enter fullscreen mode Exit fullscreen mode

In this command:

  • origin is the name of the remote repository.
  • main is the branch I am pushing.

The difference between committing and pushing is important:

git commit = Save changes in the local repository
git push   = Upload local commits to the remote repository
Enter fullscreen mode Exit fullscreen mode

Running git commit does not automatically update GitHub. I must run git push to send the commit to the remote repository.

A Complete Example

Suppose I want to add a welcome message to my website.

First, I check the current status:

git status
Enter fullscreen mode Exit fullscreen mode

Next, I edit index.html:

<h1>Welcome to My Website</h1>
Enter fullscreen mode Exit fullscreen mode

I can review the changes before staging them:

git diff
Enter fullscreen mode Exit fullscreen mode

The git diff command shows changes that have not been staged.

Next, I stage the file:

git add index.html
Enter fullscreen mode Exit fullscreen mode

I check the status again:

git status
Enter fullscreen mode Exit fullscreen mode

Now I create a commit:

git commit -m "Add welcome message"
Enter fullscreen mode Exit fullscreen mode

Finally, I push the commit to GitHub:

git push origin main
Enter fullscreen mode Exit fullscreen mode

The complete workflow is:

git status
git diff
git add index.html
git commit -m "Add welcome message"
git push origin main
Enter fullscreen mode Exit fullscreen mode

Each command has a separate purpose:

  1. git status shows the current state of the project.
  2. git diff shows the changes made to files.
  3. git add selects changes for the next commit.
  4. git commit saves the staged changes locally.
  5. git push uploads the commit to GitHub.

Starting Git in a Project

If I am working on a new project, I first move into the project folder:

cd my-website
Enter fullscreen mode Exit fullscreen mode

Then I initialize Git:

git init
Enter fullscreen mode Exit fullscreen mode

This creates a hidden .git folder that stores the project's Git information and history.
I can check the project status with:

git status
Enter fullscreen mode Exit fullscreen mode

If the project contains files that Git has not tracked before, they will appear as untracked files.

I can add all the files:

git add .
Enter fullscreen mode Exit fullscreen mode

Then I create the first commit:

git commit -m "Initial project setup"
Enter fullscreen mode Exit fullscreen mode

If I have already created an empty repository on GitHub, I can connect the local repository to it:

git remote add origin https://github.com/your-username/my-website.git
Enter fullscreen mode Exit fullscreen mode

I can make sure the branch is called main:

git branch -M main
Enter fullscreen mode Exit fullscreen mode

Then I push the project to GitHub:

git push -u origin main
Enter fullscreen mode Exit fullscreen mode

The -u option links the local branch to the remote branch. After this first push, I can usually use:

git push
Enter fullscreen mode Exit fullscreen mode

Reviewing Staged Changes

It is useful to review changes before committing them.

The following command shows changes that have not been staged:

git diff
Enter fullscreen mode Exit fullscreen mode

After using git add, I can review the changes that are ready to be committed:

git diff --staged
Enter fullscreen mode Exit fullscreen mode

The difference is:

git diff          = Shows unstaged changes
git diff --staged = Shows staged changes
Enter fullscreen mode Exit fullscreen mode

This extra check can help me catch mistakes before they become part of the project history.

Removing a File from the Staging Area

Sometimes I may stage a file by mistake. I can remove it from the staging area without deleting it from my computer:

git restore --staged style.css
Enter fullscreen mode Exit fullscreen mode

The changes in style.css will remain in the working directory, but they will not be included in the next commit.

This command only unstages the file. It does not delete the file or remove the changes I made.

Discarding Changes

If I decide that I do not want to keep changes in a file, I can restore it to the version from the latest commit:

git restore index.html
Enter fullscreen mode Exit fullscreen mode

This removes the unstaged changes in index.html.

I should use this command carefully because the discarded changes may not be easy to recover. Before running it, I can check what will be removed with:

git diff
Enter fullscreen mode Exit fullscreen mode

Common Beginner Mistakes

Forgetting to Stage Changes

If I run git commit before staging a file, Git may tell me that there is nothing to commit.

The correct sequence is:

git add index.html
git commit -m "Describe the change"
Enter fullscreen mode Exit fullscreen mode

Thinking a Commit Is the Same as a Push

A commit saves changes locally. A push uploads those local commits to GitHub.

The commands are separate:

git commit -m "Save my changes"
git push
Enter fullscreen mode Exit fullscreen mode

Using Unclear Commit Messages

A message such as "Update" does not provide enough information about the change.

A clearer message would be:

git commit -m "Fix incorrect signup link"
Enter fullscreen mode Exit fullscreen mode

Committing Without Checking

Before committing, I should inspect the staged files:

git status
git diff --staged
Enter fullscreen mode Exit fullscreen mode

This helps prevent accidental commits containing unfinished work, temporary files, or sensitive information.

A Simple Way to Remember the Workflow

I think of the Git workflow as preparing and sending a parcel.

The working directory is my desk, where I work on the contents. The staging area is where I choose what should go into the parcel. The commit is like sealing and labeling the parcel, while pushing is like sending it to the online destination.

The commands follow the same idea:

git add       Choose what to include
git commit    Save the selected changes locally
git push      Share the saved changes online
Enter fullscreen mode Exit fullscreen mode

Final Workflow

For everyday Git work, I can use:

git status
git add .
git commit -m "Describe what changed"
git push
Enter fullscreen mode Exit fullscreen mode

When I am unsure about the state of my project, I start with:

git status
Enter fullscreen mode Exit fullscreen mode

The most important lesson is that changes move through separate stages:

Edit files
   ↓
Working Directory
   ↓ git add
Staging Area
   ↓ git commit
Local Repository
   ↓ git push
Remote Repository
Enter fullscreen mode Exit fullscreen mode

Once I understand this process, Git commands become easier to remember. I am not just running commands randomly; I am deliberately moving my work from one stage to the next.

Top comments (0)