Last updated: 2026-05-17

The Git Workflow

The Git workflow is the cycle every developer follows when working with Git — from making changes to recording them permanently in the project history. Understanding this cycle is the bridge between knowing what Git is and actually using it day to day.

The workflow maps directly onto the three sections covered in How Git Works: the working directory, the staging area, and the Git directory. Every action you take in Git moves work between these three places.


The Core Cycle

At its most fundamental, the Git workflow repeats the same cycle for every piece of work:

Modify → Stage → Commit
  1. Modify — make changes to files in your working directory.
  2. Stage — select which changes to include in the next snapshot using git add.
  3. Commit — permanently record the staged snapshot into the Git directory using git commit.

This cycle then repeats. Each iteration produces a new commit — a permanent, recoverable snapshot of your project at that moment.


Checking Status

Before doing anything, it helps to know the current state of your working directory and staging area. The git status command shows you exactly that:

git status

A clean working directory — nothing modified, nothing staged — looks like this:

On branch main
nothing to commit, working tree clean

When you add a new file, Git immediately flags it as untracked:

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

Git does not track files automatically. Every file starts untracked. You must explicitly tell Git to start tracking it.


Staging Changes — git add

git add is the command that moves changes from the working directory into the staging area. It is more accurately described as "add this content to the next commit" rather than "add this file to the project."

git add README.md          # Stage a specific file
git add src/               # Stage all files in a directory
git add .                  # Stage all changes in the current directory

After running git add, the file moves from untracked (or modified) to staged:

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

An Important Subtlety

git add stages the file as it exists at the moment you run the command. If you stage a file and then edit it again before committing, the new edits are not staged — only the version from when you ran git add will go into the commit. You would need to run git add again to stage the latest version.

This is not a bug — it is intentional design. The staging area gives you precise control over exactly what snapshot gets committed.


Tracked vs. Untracked Files

Every file in your working directory is in one of two states:

StateWhat It Means
TrackedGit knows about this file. It was in the last snapshot. It can be unmodified, modified, or staged.
UntrackedGit sees the file but has never been told to include it. It won't appear in commits until you git add it.

When you first clone a repository, all files are tracked and unmodified. As you edit them, they become modified. As you stage them, they become staged. As you commit, they become committed and unmodified again — and the cycle starts over.


Committing — git commit

Once your staging area contains exactly what you want to record, you commit it:

git commit -m "Add README with project description"

The -m flag lets you write the commit message inline. Without it, Git opens your configured text editor for you to write the message there.

A commit records:

  • The snapshot of everything currently in the staging area.
  • The author name and email from your git config.
  • The timestamp.
  • The commit message.
  • A SHA-1 hash that uniquely identifies this commit.

After committing, Git reports a summary:

[main 463dc4f] Add README with project description
 1 file changed, 3 insertions(+)
 create mode 100644 README.md

Anything that was not staged stays in the working directory as modified — it is not lost, just not included in this commit. You can commit it separately.

Writing Good Commit Messages

A commit message is a record for your future self and your collaborators. The widely accepted convention is:

  • Subject line: 50 characters or fewer, written in the imperative mood — "Fix bug" not "Fixed bug" or "Fixes bug."
  • Body (optional): A blank line followed by a detailed explanation of why the change was made, not just what changed. The diff already shows what changed.
Add user authentication to login route

Previously, the login route had no authentication check, allowing
any request to proceed. This adds JWT verification middleware to
ensure only valid tokens can access the endpoint.

Good commit messages make git log readable and make debugging much easier when you need to understand why a decision was made months later.


Skipping the Staging Area

For simple, routine commits where you want to stage and commit all tracked changes in one step, Git provides a shortcut:

git commit -a -m "Update project dependencies"

The -a flag automatically stages every tracked file that has been modified before committing. Note that it only works on files Git already tracks — untracked files are still ignored and must be git add-ed first.

Use this shortcut carefully. The staging area exists precisely so you can be deliberate about what goes into each commit. Bypassing it entirely can lead to commits that include unintended changes.


The .gitignore File

Not every file in your project should be tracked by Git. Build artifacts, log files, dependency folders, and environment files containing secrets should never be committed. The .gitignore file tells Git which files and patterns to completely ignore.

Create a .gitignore file in the root of your repository:

# Dependencies
node_modules/

# Build output
dist/
build/

# Environment variables
.env
.env.local

# Logs
*.log

# OS files
.DS_Store

.gitignore Rules

PatternWhat It Ignores
*.logAll files ending in .log
build/The entire build directory
/TODOOnly the TODO file in the root, not in subdirectories
!lib.aTrack lib.a even if other .a files are ignored
doc/**/*.pdfAll .pdf files inside doc/ and any subdirectory within it

Setting up .gitignore before your first commit is good practice. If you accidentally track a file that should be ignored, removing it from tracking requires extra steps.

GitHub maintains a comprehensive collection of .gitignore templates for most languages and frameworks at https://github.com/github/gitignore.


Viewing Differences — git diff

git status tells you which files have changed. git diff tells you what changed — the exact lines added and removed.

git diff                  # Changes in working directory not yet staged
git diff --staged         # Changes staged and ready to commit

The output uses a standard diff format:

  • Lines prefixed with + are additions.
  • Lines prefixed with - are removals.
  • Unchanged lines provide context.
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

git diff is particularly useful before staging to review exactly what you are about to add to a commit.


A Complete Workflow Example

Here is the full cycle from start to a committed change:

# 1. Check the current state
git status

# 2. Make changes to your files (in your editor)

# 3. Review what changed
git diff

# 4. Stage the changes you want
git add src/app.js
git add README.md

# 5. Confirm what is staged
git status

# 6. Commit with a descriptive message
git commit -m "Add homepage route and update documentation"

# 7. Back to a clean state — the cycle repeats
git status
# nothing to commit, working tree clean

Summary

CommandWhat It Does
git statusShows the current state of the working directory and staging area
git add <file>Stages a file for the next commit
git add .Stages all changes in the current directory
git diffShows unstaged changes line by line
git diff --stagedShows staged changes that are about to be committed
git commit -m "msg"Creates a commit with the staged snapshot
git commit -a -m "msg"Stages all tracked changes and commits in one step