Git — Workflows

Git
Terminal
Published

July 10, 2026

Modified

August 5, 2026

Git workflows are conventions for how a team uses Git to develop software. They define how branches are created, when code is merged, and how releases are managed. The “best” workflow depends on your team size, release frequency, and project complexity.

This is the simplest workflow and resembles traditional version control systems.

main
 |
 +-- Commit
 |
 +-- Commit
 |
 +-- Commit

Everyone commits directly to a single “main” branch. Very easy to learn, no branching, good for solo projects and Git beginners. Collaboration with others on small projects will increase merge conflicts.

Commands

A branch is just a label pointing to a commit. A worktree is an additional checkout directory linked to the same repo. You always need a branch (or commit) inside a worktree — but the worktree is what lets you see it on disk simultaneously with other branches.

Comparison of Branch & Worktree
Branch Worktree
Working directories 1 at a time Many
.git directory One per clone Shared across all worktrees
Uncommitted changes Must stash/commit before switching Each worktree has its own state
Disk usage Extra working tree files
Typical use Linear workflow Parallel, multi-branch work

branch

Managing branches locally

Used to create, list, rename, and delete local branches (references to commits). It doesn’t switch branches itself—that’s git checkout or git switch. Commits made on branch currently “checked out”, git status shows checked out branch

List branches…

# list branches in repository (* marks the current branch)
git branch

# list available emote branches
git branch -r

# list available local and remote branches
git branch -a

Create and check out a branch…

# create a new branch
git branch $name

# create new branch at commit (defaults to HEAD), and switch to it
git checkout -b $branch [$commit]

# switch to branch (update HEAD, index, and working tree)
git checkout $branch

# checkout remote branch
git checkout -b $branch $remote/$branch

Deleting a branch…

Option Description
-d Only deletes the branch if fully merged in its upstream branch
-D Deletes the branch irrespective of its merged status
# delete branch
git branch -d $branch

# delete local copy of a remote branch
git branch -dr $remote/$branch

# delete remote branch...
git push $remote -d $branch

worktree

Checking out multiple branches simultaneously

Link additional directories (worktrees) to the same repository, each checked out at a different branch.

Important constraints:

  • A branch can only be checked out in one worktree at a time
  • The <path> must be outside the original repo’s tree
  • All worktrees share commit history, refs, stash, hooks, etc. (only the working files differ)
# Create a new branch "hotfix" and open it in a sibling directory
git worktree add ../site-hotfix -b hotfix

# Open an existing branch in a new directory
git worktree add ~/tmp/debug debug-branch

Feature Branch

Branch-based workflows1 are widely used. Every new feature or bug fix gets its own branch.

  1. Branch — Create a dedicated branch to keeps work isolated from main.
  2. Commit — Small, logical commits… represent a complete, reversible change.
  3. Push — Share your branch with the remote for backup and visibility.
  4. Review — Open a merge request. Collaborators leave feedback.
  5. Integrate — Once approved, merge or rebase into the main branch.
  6. Clean up — Delete merged branches locally and remotely.
# create and switch to a new branch
git checkout -b $branch

# stage and commit changes
git add $files
git commit -m 'describe the change'

# push branch to remote
git push -u origin $branch

Open a pull request or merge request through the platform’s web interface. The review, approval, and merge steps happen there — no command-line interaction needed.

Rebase

If you have an open merge request (MR) from your branch into main, rebasing your branch onto the updated main is a common way to keep the MR current. In a personal feature branch rebasing is usually fine because you own the branch history. When you rebase, Git rewrites the commits on your branch, but nobody else is depending on those exact commit IDs.

git fetch origin          # in the main branch
git checkout your-branch
git rebase origin/main

A normal push fails because Git sees that the histories are different.

git push --force-with-lease origin your-branch

Existing MR should update automatically because it points to the same branch. The diff will be recalculated against the newer main.

Many teams use this workflow because the MR stays clean:

  • No unnecessary merge commits
  • Conflicts are handled by the author
  • Reviewers see a focused change set
  • The final history is easier to read

Merge

If you want to avoid rewriting history:

git checkout your-branch
git fetch origin
git merge origin/main
git push origin your-branch

This creates a merge commit but does not require a force push.