On this page12 sections
CommandsBeginner8-10 min reference

Git for QA

You don't need to be a Git expert to be a great QA engineer, but you do need a working set of commands you reach for daily — pulling latest, switching to a feature branch, resolving conflicts in test files, and finding the commit that broke a passing test. This sheet is that working set.

Setup & config

One-time setup on a new machine.

# Identity — used on every commit you author
git config --global user.name "Jane Tester"
git config --global user.email "jane@example.com"
 
# Editor for commit messages and rebases
git config --global core.editor "code --wait"
 
# Better diffs and merges
git config --global merge.conflictstyle diff3
 
# Show short hashes everywhere
git config --global log.abbrevCommit true
 
# View all settings
git config --list

Cloning a repo and creating one from scratch:

# Clone an existing project
git clone https://github.com/your-team/app.git
cd app
 
# Or initialise a new repo (e.g., for your test framework)
mkdir qa-automation && cd qa-automation
git init

Daily workflow

The four-command loop you'll run a hundred times a week.

# 1. See what's changed locally
git status
 
# 2. Stage specific files (or everything)
git add tests/login.spec.ts
git add .                       # everything in cwd
 
# 3. Commit with a message
git commit -m "Add login retry-on-flaky test"
 
# 4. Push to the remote branch
git push origin qa/login-retry

A safer commit pattern when you're unsure what you've staged:

git diff                # unstaged changes
git diff --staged       # what's about to be committed
git commit -v           # opens editor with the diff for review

Branching & switching

# Create and switch in one step
git switch -c qa/flaky-login-fix       # modern syntax (Git 2.23+)
git checkout -b qa/flaky-login-fix      # older syntax — still works
 
# List branches
git branch                              # local
git branch -r                           # remote-tracking
git branch -a                           # all
 
# Switch branches
git switch main
git switch -                            # back to previous branch (like cd -)
 
# Delete a merged branch
git branch -d qa/old-branch
 
# Force-delete an unmerged branch (careful)
git branch -D qa/abandoned-experiment
 
# Rename the current branch
git branch -m qa/better-name

Merge vs rebase

Both integrate changes from one branch into another. They produce different histories.

Merge preserves the actual history with a merge commit:

git switch main
git pull
git switch qa/my-feature
git merge main                          # main → my-feature, creates merge commit

Rebase replays your commits on top of the target branch — linear history, no merge commit:

git switch qa/my-feature
git rebase main                         # replay my commits on top of main

Rule of thumb:

SituationUse
Bringing your local feature branch up to daterebase (cleaner history)
Merging a PR into mainmerge (preserves the branch context)
Branch already pushed and reviewedmerge (don't rewrite shared history)
Branch is private (only you have it)rebase is safe

If a rebase goes wrong:

git rebase --abort         # back to where you started
git rebase --continue      # after fixing conflicts in the current step
git rebase --skip          # drop the conflicted commit and move on

Inspecting history

# Compact log — most useful daily view
git log --oneline --graph --decorate --all
 
# Last 10 commits with files changed
git log -10 --stat
 
# Search commit messages
git log --grep="login"
 
# Search code changes
git log -S "loginButton.click"          # commits that added/removed this string
 
# What did a commit change?
git show abc1234
 
# Who last touched each line of a file?
git blame tests/login.spec.ts
 
# Show the diff of a single commit
git show abc1234 --stat

A useful alias for the compact log — add to ~/.gitconfig:

[alias]
  lg = log --oneline --graph --decorate --all

Then git lg gives you the picture instantly.

Undoing changes

The right "undo" depends on what state the change is in.

# Discard unstaged changes in a file
git restore tests/login.spec.ts
 
# Unstage a file (keep the edit, just don't commit it yet)
git restore --staged tests/login.spec.ts
 
# Discard ALL unstaged changes (destructive — be sure)
git restore .
 
# Undo the last commit but keep the changes staged
git reset --soft HEAD~1
 
# Undo the last commit and unstage the changes
git reset HEAD~1                        # default is --mixed
 
# Undo the last commit AND discard the changes (very destructive)
git reset --hard HEAD~1
 
# Undo a commit on a shared branch by creating a new commit that reverses it
git revert abc1234

git stash — the "save my work for later" command:

# Stash uncommitted changes
git stash
 
# Stash with a description
git stash push -m "WIP: login flaky retry"
 
# List stashes
git stash list
 
# Re-apply the most recent stash
git stash pop                           # apply + drop from stash list
git stash apply                         # apply but keep in stash list
 
# Apply a specific stash by index
git stash apply stash@{2}
 
# Discard the top stash
git stash drop
 
# Stash only specific files
git stash push tests/login.spec.ts

Working with remotes

# View configured remotes
git remote -v
 
# Fetch from origin without merging — updates remote-tracking branches only
git fetch origin
 
# Pull = fetch + merge into current branch
git pull origin main
 
# Pull with rebase instead of merge (cleaner history)
git pull --rebase origin main
 
# Make rebase the default for `git pull`
git config --global pull.rebase true
 
# Push to a remote branch (set upstream on first push)
git push -u origin qa/login-retry
 
# Delete a remote branch
git push origin --delete qa/old-feature
 
# Prune deleted remote branches from your local view
git fetch --prune

QA scenario: check out a feature branch to test it

# Make sure you have the latest list of remote branches
git fetch origin
 
# Switch to it (Git auto-tracks the remote branch)
git switch feature/login-fix
 
# Or with the older syntax
git checkout feature/login-fix
 
# Pull any updates the developer pushed since
git pull

QA scenario: pull latest changes before testing

# On your current branch
git pull --rebase origin main
 
# Or if you specifically want main's latest
git switch main
git pull

QA scenario: branch for your test automation code

# Branch off main
git switch main
git pull
git switch -c qa/login-retry-suite
 
# Make changes
git add tests/login-retry/
git commit -m "Add retry-on-flake suite for login flow"
 
# Push for review
git push -u origin qa/login-retry-suite

QA scenario: resolve merge conflicts in test files

git pull origin main
# CONFLICT (content): Merge conflict in tests/checkout.spec.ts
 
# 1. Open the conflicted file. You'll see markers:
#    <<<<<<< HEAD
#    your changes
#    =======
#    incoming changes
#    >>>>>>> origin/main
#
# 2. Edit to keep what you want. Remove all <<<<, ====, >>>> markers.
#
# 3. Mark the file resolved
git add tests/checkout.spec.ts
 
# 4. Continue the merge or rebase
git commit                              # if merging
git rebase --continue                   # if rebasing
 
# Bail out if you got in over your head
git merge --abort
git rebase --abort

For test files specifically: when in doubt, keep both test cases. A test removed in the conflict is one less safety net.

QA scenario: bisect to find the commit that broke a test

When a test was passing last week and now it isn't, git bisect finds the breaking commit in log₂(N) steps.

# Start the bisect
git bisect start
 
# Tell Git the current commit is broken
git bisect bad
 
# Tell Git the last known good version (a tag, hash, or branch)
git bisect good v1.4.0
 
# Git now checks out a commit halfway between them.
# Run your test against this commit:
npm test -- tests/checkout.spec.ts
 
# Mark the result and Git will narrow further
git bisect good             # if the test passed
git bisect bad              # if the test failed
 
# Keep marking. After ~log2(N) iterations, Git prints:
#   abc1234 is the first bad commit
 
# Reset back to your branch
git bisect reset

You can fully automate it if you have a script that returns 0 for "good" and non-zero for "bad":

git bisect start HEAD v1.4.0
git bisect run npm test -- tests/checkout.spec.ts

Walk away — Git will hand you the offending commit.