Git Tutorial for Testers

Every automation framework lives in Git: your test code, feature files, page objects, test data and CI configuration.

Git lets you:

  • Track every change.
  • Work on branches without breaking the main suite.
  • Review changes through pull requests.
  • Collaborate with other developers and testers.
  • Trigger Jenkins or other CI pipelines on every push.

This tutorial covers the Git a tester actually uses — the daily workflow, key commands, branching, merging, undoing changes and fixing common mistakes — and then links to the in-depth Git tutorials on the site.

Advertisement

Git in 60 Seconds

Before learning commands, understand these core Git concepts.

  • Repository (repo) — a project folder whose history Git tracks.
  • Commit — a saved snapshot of changes, together with a commit message.
  • Branch — an independent line of work, such as feature/login-tests.
  • Remote — the shared copy of a repository hosted on GitHub, GitLab or Bitbucket, usually called origin.
  • Pull request (PR) / merge request — a request to merge your branch into another branch after review.

Git vs GitHub

Git is the version-control tool installed and used on your machine.

GitHub, GitLab and Bitbucket are platforms that host Git repositories online and provide additional collaboration features such as:

  • Pull requests.
  • Code reviews.
  • Branch protection.
  • CI/CD integration.
  • Repository management.

More: Git Basics.

The Three Areas

Git changes move through three primary areas:

Working Directory
       ↓
    git add
       ↓
Staging Area
       ↓
   git commit
       ↓
Repository
       ↓
    git push
       ↓
Remote

Working Directory

This contains the files you are currently editing.

For example:

LoginTest.java
LoginPage.java
config.properties

Staging Area

When you run:

git add LoginTest.java

Git stages the changes so they can become part of the next commit.

Repository

When you run:

git commit -m "Add login test"

the staged changes are saved as a commit in your local Git history.

Remote

When you run:

git push

your local commits are sent to the remote repository.

Essential Commands

Command What it does
git clone <url> Copies a remote repository to your machine
git status Shows changed, staged and untracked files
git add <file> / git add . Stages changes
git commit -m "message" Saves staged changes as a commit
git push Sends commits to the remote repository
git pull Fetches remote changes and integrates them into your branch
git fetch Downloads remote changes without merging them
git switch -c <branch> Creates and switches to a new branch
git log --oneline --graph Displays compact commit history with branches
git diff Shows unstaged changes
git diff --staged Shows staged changes

For the complete command list, see Git Commands & Usage and the Git Commands Cheat Sheet.

The Daily Workflow for Automation Testers

A common feature-branch workflow looks like this.

Step 1 — Start from the Latest Main Branch

git switch main
git pull

This ensures you are starting from the latest version of the main branch.

Step 2 — Create a Feature Branch

git switch -c feature/login-tests

Your new branch isolates your work from main.

Step 3 — Write and Commit Your Tests

After implementing your automation:

git add src/test/java/com/example/tests/LoginTest.java

Then create a meaningful commit:

git commit -m "Add login tests for valid and locked-out users"

Small, focused commits make code review and troubleshooting easier.

Step 4 — Push the Branch

git push -u origin feature/login-tests

You can then create a pull request on GitHub, GitLab or your organization's source-control platform.

Step 5 — Merge After Review and CI

After the pull request has been reviewed and the CI build is successful:

git switch main
git pull
git branch -d feature/login-tests

The branch can then be removed locally if it is no longer needed.

Git and CI/CD

Pushing a branch commonly triggers Jenkins or GitHub Actions to execute automated tests.

A typical flow is:

Developer
    ↓
Git Push
    ↓
Pull Request
    ↓
CI Pipeline
    ↓
Automation Tests
    ↓
Report
    ↓
Code Review
    ↓
Merge

See GitHub & GitLab: Pull Requests & CI/CD and Jenkins & Git Integration.

Branching and Merging

Branches keep unfinished work away from the main automation suite.

For example:

main
 │
 ├── feature/login-tests
 │
 ├── feature/payment-tests
 │
 └── fix/checkout-validation

Each tester or developer can work independently and later merge completed work into the appropriate branch.

What Is a Merge Conflict?

A merge conflict occurs when Git cannot automatically determine which changes should be retained.

For example:

<<<<<<< HEAD
String baseUrl = "https://qa.example.com";
=======
String baseUrl = "https://staging.example.com";
>>>>>>> feature/staging-config

The conflict indicates that different versions of the same section exist.

How to Resolve a Merge Conflict

The general process is:

  1. Open the conflicted file.
  2. Understand both versions.
  3. Decide what the correct final code should be.
  4. Remove the conflict markers.
  5. Save the file.
  6. Run the affected tests.
  7. Stage the resolved file.
  8. Commit the resolution.

For example:

git add LoginTest.java
git commit -m "Resolve login test merge conflict"

More: Branching & Merging.

Merge vs Rebase

Merge and rebase are two different ways of integrating changes.

  Merge Rebase
What it does Combines branches with a merge commit Replays your commits on top of another branch
History Preserves the branch structure Produces a more linear history
Safe on shared branches? Yes No — avoid rebasing commits that others have already pulled
Typical use Merging a PR into main Updating your own feature branch
Example git merge feature/login-tests git rebase main

Example: Updating Your Feature Branch with Rebase

Suppose you are working on:

feature/login-tests

and main has received new changes.

You can update your branch with:

git switch feature/login-tests
git fetch origin
git rebase origin/main

Your commits are replayed on top of the latest main.

Important Rebase Rule

Do not casually rebase commits that other team members have already pulled and based their work on.

Rebase rewrites commit history, which can create unnecessary problems on shared branches.

More, including cherry-pick and bisect: Rebase, Cherry-Pick & Bisect.

Stash, Reset and Revert — Undoing Safely

Git provides several mechanisms for dealing with unfinished work and mistakes.

Git Stash

Use git stash when you have unfinished local changes but need to temporarily switch branches or perform another Git operation.

git stash push -m "wip login tests"
git stash list
git stash pop

The first command stores your unfinished changes.

git stash list shows available stashes.

git stash pop restores the most recent stash.

Restore a Local File

If you want to discard local changes to a file:

git restore LoginTest.java

Be careful because this removes the uncommitted changes in that file.

Reset the Last Local Commit

If your last commit has not been pushed and you want to undo the commit while keeping the changes staged:

git reset --soft HEAD~1

The commit is removed from the branch history, but the changes remain staged.

Revert a Pushed Commit

If a commit has already been pushed to a shared branch, use git revert rather than rewriting shared history.

git revert <commit-hash>

This creates a new commit that reverses the changes introduced by the earlier commit.

Reset vs Revert

  git reset git revert
How it undoes changes Moves the branch pointer and can rewrite history Creates a new commit that reverses an earlier commit
Typical use Local, unpushed commits Shared or already-pushed commits
Rewrites history? Yes, depending on mode No
Safe for shared branches? Generally no Yes
--hard risk Can discard uncommitted work Does not have the same --hard behaviour

Recovering After a Bad Reset

If you accidentally lose track of a commit after a reset, git reflog can show previous positions of HEAD.

git reflog

This can help identify the commit or previous state you need to recover.

More: Stash, Reset & Revert and Git Troubleshooting.

What Not to Commit: .gitignore for Test Projects

Automation projects often generate files that should not be committed to source control.

A .gitignore file can exclude them.

# Build output and reports
target/
test-output/
allure-results/
allure-report/
playwright-report/
test-results/
screenshots/

# Dependencies and IDE files
node_modules/
.idea/
*.iml
.vscode/

# Secrets and local config
.env
*.local.properties
*.log

Never Commit Secrets

Do not commit:

  • Passwords.
  • API keys.
  • Access tokens.
  • Private credentials.
  • Environment-specific secrets.

Instead, use:

  • Environment variables.
  • Jenkins credentials.
  • CI/CD secret stores.
  • Secure configuration management.

If a secret has already been committed, simply deleting it in a later commit is not enough because the secret may remain in Git history.

The credential should be rotated and the exposed secret should be treated as compromised.

Best Practices for Testers

A few Git habits make automation collaboration much easier.

Pull Before Starting Work

Start from the latest version of the branch:

git switch main
git pull

Then create your feature branch.

Keep Branches Short-Lived

Avoid keeping feature branches open for unnecessarily long periods.

Short-lived branches reduce:

  • Merge conflicts.
  • Divergence from main.
  • Difficult integrations.

Make Small, Meaningful Commits

Prefer:

git commit -m "Add checkout negative tests"

over:

git commit -m "changes"

A good commit message should describe what changed.

Use Consistent Branch Names

Examples:

feature/login-tests
feature/payment-tests
fix/checkout-validation
test/search-regression

Run Tests Before Pushing

Before creating a pull request, run the relevant automation tests locally.

For example:

mvn clean test

This reduces the chance of sending an obvious failure to CI.

Protect Main

A shared main branch should generally be protected so that changes go through:

  • Pull requests.
  • Code review.
  • Automated CI checks.
  • Successful builds.

More: Git Best Practices.

The Learning Path

Part 1 — Basics

Part 2 — Advanced & Collaboration

Part 3 — Problem Solving & Interviews

Pair this with The Complete Jenkins Tutorial to understand how your automation tests can run automatically on every push.

From Real Projects

In my automation roles I maintained test scripts that several people reviewed and extended — POM classes, the business library and data files all changing at once. That's exactly the situation version control is built for: every change reviewed, traceable and easy to undo. On Canolog, the many forms and screens across sales, inventory, finance and service are where keeping page details in POM classes and reusable steps in a business library paid off. Learn add, commit, pull and push first; everything else builds on those four.

📚 Official documentation: Git documentation

Frequently Asked Questions

Why do software testers need Git?

Testers use Git to version and share automation code, feature files, test data and CI configuration.

Git also allows testers to:

  • Create feature branches.
  • Work without affecting the main suite.
  • Review changes through pull requests.
  • Collaborate with developers and other testers.
  • Trigger automated CI runs after code changes.

What's the difference between git pull and git fetch?

git fetch downloads changes from the remote repository without integrating them into your current branch.

git fetch

git pull performs a fetch and then integrates the remote changes into the current branch.

git pull

In simple terms:

git fetch → Download changes
git pull  → Download + integrate changes

What is the difference between merge and rebase?

Merge combines branches and can create a merge commit while preserving the existing branch history.

Rebase replays your commits on top of another branch, producing a more linear history.

Use rebase carefully and avoid rebasing commits that other people have already pulled.

What is the difference between reset and revert?

git reset moves the branch pointer and can rewrite history. It is generally appropriate for local, unpushed commits.

git revert creates a new commit that reverses the effect of an earlier commit, making it suitable for shared branches and already-pushed changes.

How do you resolve merge conflicts?

Open the conflicted files and identify the sections surrounded by:

<<<<<<<
=======
>>>>>>>

Decide what the correct final version should be, remove the conflict markers, save the file and run the affected tests.

Then stage and commit the resolution:

git add <file>
git commit -m "Resolve merge conflict"

What is git stash used for?

git stash temporarily saves uncommitted changes so that you can switch branches or perform another Git operation without committing unfinished work.

For example:

git stash push -m "wip login tests"

Later, restore the changes with:

git stash pop

I committed to the wrong branch. How do I fix it?

If the commit has not been pushed, one approach is to create the correct branch while the commit is still present:

git switch -c feature/right-branch

Then switch back to the incorrect branch and remove the unwanted commit:

git switch wrong-branch
git reset --hard HEAD~1

Use --hard carefully because it can discard working-tree changes.

If the commit has already been pushed or the branch is shared, the appropriate recovery strategy depends on the repository state. Avoid rewriting shared history without coordinating with the team.

More: Real-Time Git Scenarios.