Git Submodules Explained: Add, Clone, Update and Remove Submodules

Submodules let one repository include another at an exact commit, for example shared test data or utilities. In this lesson you will add, clone, update, edit and remove submodules, use them in CI, and decide when an alternative is better.

๐Ÿ“– What You’ll Learn: what submodules are and when to use them, adding a submodule and .gitmodules, cloning with submodules, updating to newer commits, committing inside a submodule and detached HEAD, useful commands, removing a submodule, submodules in GitHub Actions, and alternatives.


๐Ÿงฉ What Is a Git Submodule?

A submodule is a Git repository nested inside another Git repository at a specific folder. The parent repository does not store the submodule’s files; it stores a pointer to one exact commit of the submodule repository.

Typical uses:

  • Sharing common test data, page objects or utilities between several test projects.
  • Including a third-party library at a fixed version.
  • Keeping a documentation or design-system repository inside an app repository.
qa-platform/                      (parent repository)
โ”œโ”€โ”€ tests/
โ”œโ”€โ”€ shared-test-data/   โ”€โ”€โ–ถ submodule: github.com/acme/shared-test-data @ commit 9f8e7d6
โ””โ”€โ”€ .gitmodules

๐Ÿ“ Note: Submodules are powerful but add complexity. For many teams, publishing shared code as a package (npm, PyPI) or using a monorepo is simpler. Use submodules when you truly need another repository’s exact source at a fixed commit.


โž• Add a Submodule

git submodule add https://github.com/acme/shared-test-data.git shared-test-data
git status
new file:   .gitmodules
new file:   shared-test-data

.gitmodules records the mapping and is committed like any file:

[submodule "shared-test-data"]
	path = shared-test-data
	url = https://github.com/acme/shared-test-data.git
git commit -m "Add shared-test-data as a submodule"
git push

๐Ÿ“ฅ Clone a Repository That Has Submodules

A normal clone leaves submodule folders empty. Use one of these:

git clone --recurse-submodules https://github.com/acme/qa-platform.git

# Already cloned without it?
git submodule update --init --recursive

๐Ÿ’ก Tip: Set git config --global submodule.recurse true so commands such as git pull and git switch also update submodules automatically.


๐Ÿ”„ Update a Submodule to a Newer Commit

The parent repository pins a specific commit. To move to the latest commit of the submodule’s branch:

git submodule update --remote shared-test-data
git status                        # modified: shared-test-data (new commits)
git add shared-test-data
git commit -m "Update shared-test-data to latest"
git push

Or manually:

cd shared-test-data
git fetch
git switch main
git pull
cd ..
git add shared-test-data
git commit -m "Update shared-test-data"

After teammates pull your change, they run git submodule update --init --recursive (or have submodule.recurse enabled) to check out the new pinned commit.


โœ๏ธ Change Code Inside a Submodule

A submodule is a full repository. To change it, commit and push inside it first, then commit the new pointer in the parent:

cd shared-test-data
git switch -c feature/new-users
# edit files
git commit -am "Add premium test users"
git push -u origin feature/new-users       # then merge via PR in that repository
cd ..
git add shared-test-data
git commit -m "Point to shared-test-data with premium users"

โš ๏ธ Common mistake: After git submodule update, the submodule is in detached HEAD state. Switch to a branch before committing inside it, or your commits may be hard to find later (see git reflog).


๐Ÿงฐ Useful Commands

CommandPurpose
git submodule statusShow each submodule’s pinned commit
git submodule foreach 'git pull'Run a command in every submodule
git submodule syncUpdate submodule URLs after they changed in .gitmodules
git diff --submoduleShow submodule commit changes as logs instead of hashes

๐Ÿ—‘๏ธ Remove a Submodule

git submodule deinit -f shared-test-data
git rm -f shared-test-data
rm -rf .git/modules/shared-test-data
git commit -m "Remove shared-test-data submodule"

๐Ÿค– Submodules in CI

In GitHub Actions, ask the checkout action to fetch submodules:

- uses: actions/checkout@v4
  with:
    submodules: recursive

Private submodules need a token or deploy key with access; see secrets and personal access tokens.


โš–๏ธ Submodules vs Alternatives

OptionBest whenDrawback
SubmoduleYou need another repo’s source at an exact commitExtra commands; easy to forget updates
Package (npm, PyPI, Maven)Sharing versioned code between projectsRequires publishing releases
MonorepoMany related projects evolving togetherOne big repository to manage
git subtreeCopying another repo’s history into a folderHarder to push changes back

๐Ÿ“ Assignment

  1. Create two repositories on GitHub: shared-test-data (with a users.json) and qa-platform.
  2. Add shared-test-data as a submodule of qa-platform and push.
  3. Clone qa-platform into a new folder without --recurse-submodules, observe the empty folder, then fix it.
  4. Change users.json in shared-test-data, push it, and update the pointer in qa-platform.
  5. Remove the submodule cleanly.

โ“ FAQ

๐Ÿค” What is a Git submodule?

A Git repository embedded in a folder of another repository, pinned to a specific commit.

๐Ÿค” How do I clone a repository with submodules?

git clone --recurse-submodules <url>, or after a normal clone run git submodule update --init --recursive.

๐Ÿค” How do I update a submodule to the latest commit?

git submodule update --remote <path>, then commit the changed submodule pointer in the parent repository.

๐Ÿค” Why is my submodule folder empty?

The repository was cloned without initializing submodules. Run git submodule update --init --recursive.

๐Ÿค” How do I remove a Git submodule?

git submodule deinit -f <path>, git rm -f <path>, delete .git/modules/<path>, and commit.


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

Git Hooks and Husky: Automate Checks with pre-commit, commit-msg and pre-push

Git hooks run your checks automatically at the right moment, before a commit or before a push. In this lesson you will write your first hook, share hooks with your team using Husky, run linters on staged files and validate commit messages.

๐Ÿ“– What You’ll Learn: what hooks are, the main client-side hooks, writing a pre-commit hook, bypassing hooks and why CI still matters, sharing hooks with core.hooksPath and Husky, lint-staged, commitlint, the Python pre-commit framework, and server-side alternatives on GitHub.


๐Ÿช What Are Git Hooks?

Git hooks are scripts that Git runs automatically at certain moments: before a commit, after a checkout, before a push and more. Teams use them to catch problems before they reach the repository:

  • Run the linter and formatter on staged files before each commit.
  • Reject commit messages that do not follow Conventional Commits.
  • Run fast tests before pushing.
  • Block commits that contain test.only or secrets.

๐Ÿ“‚ Where Hooks Live

Every repository has a .git/hooks folder with sample files such as pre-commit.sample. To enable a hook, create a file with the exact hook name (no extension) and make it executable.

HookRunsCan block the actionTypical use
pre-commitBefore the commit is createdโœ…Lint, format, quick checks
prepare-commit-msgBefore the message editor opensโœ…Add a ticket number from the branch name
commit-msgAfter the message is writtenโœ…Validate the message format
post-commitAfter the commitโŒNotifications
pre-pushBefore pushingโœ…Run tests
post-checkout, post-mergeAfter switching branches or mergingโŒReinstall dependencies

A hook blocks the action when it exits with a non-zero code.


โœ๏ธ Write Your First Hook

Block commits that contain test.only (a Playwright focus left in by mistake):

#!/bin/sh
# .git/hooks/pre-commit
if git diff --cached --name-only | grep -E '\.(ts|js)$' | xargs -r grep -n "test\.only" 2>/dev/null; then
  echo "โŒ Remove test.only before committing."
  exit 1
fi
exit 0
chmod +x .git/hooks/pre-commit

Now git commit fails if a staged TypeScript or JavaScript file contains test.only. On Windows, hooks run in Git Bash, so shell scripts work.

๐Ÿ“ Note: Anyone can skip client-side hooks with git commit --no-verify (or -n). Hooks are a convenience and safety net; the real enforcement belongs in CI and branch protection.


๐Ÿค Sharing Hooks with the Team

Files in .git/hooks are not committed, so teammates do not get them. Two ways to share hooks:

Option 1: core.hooksPath

Commit a folder such as .githooks/ and point Git at it:

git config core.hooksPath .githooks

Each developer runs this once (or a setup script does it).

Option 2: Husky (JavaScript and TypeScript projects)

Husky installs hooks automatically when teammates run npm install:

npm install -D husky
npx husky init

husky init creates a .husky/ folder with a pre-commit hook (initially running npm test) and adds a prepare script to package.json so hooks are set up on every install. Edit the hook files as plain shell commands:

# .husky/pre-commit
npx lint-staged
# .husky/pre-push
npx playwright test --grep @smoke

๐ŸŽฏ lint-staged: Check Only What You Changed

Running the linter on the whole project before every commit is slow. lint-staged runs commands only on staged files:

npm install -D lint-staged
{
  "lint-staged": {
    "*.{ts,js}": ["eslint --fix", "prettier --write"],
    "*.{json,md,yml}": "prettier --write"
  }
}

Put this in package.json. With npx lint-staged in the pre-commit hook, every commit is automatically linted and formatted.


โœ… Validate Commit Messages

Combine Husky with commitlint:

npm install -D @commitlint/cli @commitlint/config-conventional
echo "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.mjs
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

Now git commit -m "stuff" is rejected with a clear explanation.


๐Ÿ Python Projects: pre-commit Framework

Python teams often use the pre-commit framework instead of Husky:

pip install pre-commit
pre-commit install          # installs the hook defined in .pre-commit-config.yaml
pre-commit run --all-files

It manages hooks such as Black, Ruff, trailing whitespace and secret detection from a YAML config committed to the repository.


๐Ÿ–ฅ๏ธ Server-Side Hooks

Hooks like pre-receive run on the server when someone pushes. GitHub.com does not let you install custom server-side hooks; use rulesets and branch protection, required status checks in GitHub Actions, and push protection for secrets (security) instead.


๐Ÿ“ Assignment

  1. Write a pre-commit hook in .git/hooks that blocks commits containing the word console.log, and test it.
  2. Bypass it once with --no-verify and explain why CI is still needed.
  3. Move the hook to a committed .githooks folder and use core.hooksPath.
  4. In a Node or Playwright project, install Husky and lint-staged and run Prettier on staged files.
  5. Add commitlint and try to commit a badly formatted message.
  6. Add a pre-push hook that runs your @smoke tests.

โ“ FAQ

๐Ÿค” What are Git hooks?

Scripts that Git runs automatically at points such as before a commit, after a commit or before a push, used to automate checks.

๐Ÿค” What is a pre-commit hook?

A hook that runs before a commit is created; if it exits with a non-zero code, the commit is cancelled. It is commonly used for linting and formatting.

๐Ÿค” What is Husky?

A tool for JavaScript and TypeScript projects that stores Git hooks in the repository and installs them automatically for every developer via npm.

๐Ÿค” How do I skip Git hooks?

git commit --no-verify (or -n) skips pre-commit and commit-msg hooks; git push --no-verify skips pre-push.

๐Ÿค” Are Git hooks shared when I push?

Not automatically. Share them with core.hooksPath, Husky or the pre-commit framework.


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

git bisect: Find the Commit That Broke Your Code (Manual and Automatic)

When something that used to work is broken, git bisect finds the exact commit responsible in a handful of steps. In this lesson you will bisect manually, automate it with a test command, and learn how testers use it to pinpoint regressions.

๐Ÿ“– What You’ll Learn: how bisect uses binary search, a manual bisect step by step, automatic bisect with git bisect run and exit codes, a script that skips unbuildable commits, other bisect commands, and what makes bisect work well.


๐Ÿ” What Is git bisect?

A test passed last week and fails today. Fifty commits were made in between. Which one broke it? git bisect finds out with a binary search: it checks out a commit halfway between a known good and a known bad commit, you say whether it is good or bad, and Git halves the range again.

Commits to searchMaximum steps
164
1007
1,00010

For testers this is a superpower: you can hand developers the exact commit that introduced a regression.


๐Ÿงญ Manual Bisect Step by Step

git bisect start
git bisect bad                    # the current commit is broken
git bisect good v2.3.0            # this tag (or commit hash) was fine
Bisecting: 24 revisions left to test after this (roughly 5 steps)
[7c8d9e0] Add discount code field to cart

Git checks out a commit in the middle. Test it (run the app or the failing test), then tell Git the result:

npx playwright test tests/checkout.spec.ts
git bisect good                   # if it works on this commit
# or
git bisect bad                    # if it is broken on this commit

Repeat until Git reports:

3e4f5a6b is the first bad commit
commit 3e4f5a6b...
Author: Ravi Kumar <ravi@example.com>
    Change tax calculation to use rounded subtotal

Finish and go back to where you started:

git bisect reset

โš ๏ธ Common mistake: During bisect you are in detached HEAD state on old commits. Do not commit there. Always finish with git bisect reset.


๐Ÿค– Automatic Bisect with a Script

If a command can tell good from bad by its exit code, Git can do all the steps for you:

git bisect start HEAD v2.3.0                  # bad first, then good
git bisect run npx playwright test tests/checkout.spec.ts
git bisect reset
Exit code of the commandMeaning for bisect
0Good commit
1 to 127 (except 125)Bad commit
125Cannot test this commit: skip it

Any test runner works: npm test, pytest tests/test_login.py, mvn test or a custom script.

Example script that skips commits which do not build

#!/bin/sh
# bisect-check.sh
npm ci || exit 125                              # cannot install: skip this commit
npx playwright test tests/checkout.spec.ts      # 0 = good, non-zero = bad
chmod +x bisect-check.sh
git bisect start HEAD v2.3.0
git bisect run ./bisect-check.sh

๐Ÿ’ก Tip: Keep the bisect script outside the repository (or untracked), otherwise it disappears when Git checks out older commits.


๐Ÿงฐ Other Bisect Commands

CommandUse
git bisect skipThe current commit cannot be tested (for example it does not build)
git bisect logShow the decisions so far
git bisect visualize (or view)Show the remaining commits in git log or gitk
git bisect terms --term-old fast --term-new slowUse other words, e.g. to find a performance change

๐Ÿ’ก Bisect Works Best When…

  • Commits are small and each one builds: large, broken intermediate commits make bisect skip a lot (commit messages and practices).
  • You have a reliable automated test that reproduces the problem; flaky tests give wrong answers (flaky tests).
  • You know a good tag or commit: tag releases so you can say “it worked in v2.3.0” (tags).

๐Ÿ“ Assignment

  1. In git-practice, create 10 commits where the 7th commit changes app.txt to contain the word BROKEN.
  2. Find that commit with a manual bisect, testing with grep -q BROKEN app.txt && echo bad || echo good.
  3. Repeat with git bisect run sh -c "! grep -q BROKEN app.txt" and compare the result.
  4. Use git bisect skip on one commit and check git bisect log.
  5. Bonus: use bisect on a real project to find which commit made a test fail.

โ“ FAQ

๐Ÿค” What does git bisect do?

It finds the commit that introduced a bug by binary search between a known good and a known bad commit.

๐Ÿค” How do I use git bisect?

git bisect start, git bisect bad, git bisect good <commit>, then test each commit Git checks out and mark it good or bad until it reports the first bad commit; finish with git bisect reset.

๐Ÿค” How do I automate git bisect?

git bisect run <command>: the command’s exit code marks each commit (0 good, 125 skip, other non-zero bad).

๐Ÿค” How do I exit git bisect?

git bisect reset returns to the branch and commit where you started.

๐Ÿค” Can testers use git bisect?

Yes. With an automated test that reproduces a bug, bisect pinpoints the exact commit that caused a regression.


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

git reflog: Recover Lost Commits, Deleted Branches and Bad Rebases

Lost commits after a reset, deleted a branch or broke a rebase? Git almost never forgets. In this lesson you will read the reflog and use step-by-step recovery recipes to get your work back.

๐Ÿ“– What You’ll Learn: what the reflog is and how long it keeps entries, reading reflog entries and HEAD@{n} references, recovering from reset –hard, deleted branches, bad rebases and amends, recovering dropped stashes, and safe habits before risky operations.


๐Ÿ›Ÿ What Is the Reflog?

The reflog (reference log) is Git’s private diary of where HEAD and your branch tips have been. Every commit, checkout, reset, rebase, merge and amend adds an entry. Even when a commit disappears from git log (after a reset, a bad rebase or a deleted branch), it is usually still listed in the reflog, so you can get it back.

Key facts:

  • The reflog is local to your repository; it is not pushed or shared.
  • Entries are kept for a while: by default about 90 days for reachable entries and 30 days for unreachable ones, after which git gc may remove them.
  • It only knows about commits. Changes that were never committed (for example discarded with git restore) cannot be recovered with it.

๐Ÿ“œ Read the Reflog

git reflog
8b1d4e2 (HEAD -> main) HEAD@{0}: reset: moving to HEAD~2
f6a7b8c HEAD@{1}: commit: Add API tests for orders
e5f6a7b HEAD@{2}: commit: Add checkout tests
8b1d4e2 HEAD@{3}: checkout: moving from feature/login to main
PartMeaning
8b1d4e2The commit HEAD pointed to
HEAD@{2}“Where HEAD was two moves ago”
reset: moving to HEAD~2The action that caused the move

More views:

git reflog show feature/login         # history of one branch's tip
git reflog --date=iso                 # with timestamps
git log -g --oneline                  # reflog in git log format
git show HEAD@{2}                     # inspect an entry
git diff HEAD@{1} HEAD                # what changed since the previous position

You can also use time: git show main@{yesterday} or HEAD@{2.hours.ago}.


๐Ÿš‘ Recovery Recipes

1. Undo an accidental git reset –hard

git reflog
# f6a7b8c HEAD@{1}: commit: Add API tests for orders   โ† the commit you lost
git reset --hard f6a7b8c                 # or: git reset --hard HEAD@{1}

2. Recover a deleted branch

git branch -D feature/api-tests
# Deleted branch feature/api-tests (was a9b8c7d).   โ† Git prints the branch's last commit
git switch -c feature/api-tests a9b8c7d             # recreate the branch at that commit

# Lost that message? Search the reflog for the branch name:
git reflog | grep "feature/api-tests"
# 1f2e3d4 HEAD@{4}: checkout: moving from feature/api-tests to main
# a9b8c7d HEAD@{5}: commit: Add API tests for orders   โ† one entry older = last commit on the branch

On Windows PowerShell use git reflog | Select-String "feature/api-tests".

3. Undo a rebase that went wrong

git reflog
# 1a2b3c4 HEAD@{6}: rebase (start): checkout main
# 7d8e9f0 HEAD@{7}: commit: Add cart tests       โ† the state before the rebase
git reset --hard HEAD@{7}

Tip: the entry just before “rebase (start)” is the branch as it was. Git also stores it in ORIG_HEAD right after a rebase or reset: git reset --hard ORIG_HEAD.

4. Get back an amended commit’s previous version

git reflog
# 3c4d5e6 HEAD@{0}: commit (amend): Add login tests
# 2b3c4d5 HEAD@{1}: commit: Add login tests
git show 2b3c4d5                          # the version before --amend
git switch -c before-amend 2b3c4d5        # keep it on a branch if you need it

5. Recover a dropped stash

Stashes are commits too. If you dropped one recently:

git fsck --no-reflog | grep "dangling commit"
git show <hash>                           # find the one that looks like your stash
git stash apply <hash>

๐Ÿงญ Safe Habits

  • Before anything risky (reset, rebase, history cleanup), create a backup branch: git branch backup-before-rebase.
  • When recovering, prefer creating a new branch at the found commit (git switch -c rescue <hash>) over resetting immediately; inspect, then decide.
  • Remember the reflog is per repository and per machine: a fresh clone has an empty reflog.

๐Ÿ“ Assignment

  1. Make three commits, then git reset --hard HEAD~3 and recover them with the reflog.
  2. Create and delete a branch with unmerged commits, then recover it.
  3. Rebase a branch, then undo the rebase using ORIG_HEAD or the reflog.
  4. Amend a commit and recover the original version on a new branch.
  5. Show the reflog with ISO dates and find what you did one hour ago.

โ“ FAQ

๐Ÿค” What is git reflog?

A local log of every position HEAD and your branches have pointed to, which lets you find and restore commits that no longer appear in git log.

๐Ÿค” How do I recover a commit after git reset –hard?

Run git reflog, find the commit hash from before the reset, then git reset --hard <hash> or create a branch at it.

๐Ÿค” How do I recover a deleted branch in Git?

Find the branch’s last commit in git reflog and recreate it with git switch -c <branch> <hash>.

๐Ÿค” How long does Git keep the reflog?

By default about 90 days for reachable entries and 30 days for unreachable ones, configurable with gc.reflogExpire settings.

๐Ÿค” Is the reflog shared when I push?

No. The reflog exists only in your local repository.


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

Interactive Rebase in Git: Squash, Reword, Reorder, Edit and Drop Commits

Interactive rebase turns a messy branch into a clean, reviewable story before you open a pull request. In this lesson you will squash, reword, reorder, drop, edit and split commits, and use the fixup and autosquash workflow.

๐Ÿ“– What You’ll Learn: what interactive rebase is, starting it and reading the todo list, squash vs fixup, reword, reorder and drop, editing and splitting older commits, the fixup and autosquash workflow, conflicts, aborting and recovering, and when rewriting is safe.


๐Ÿงฌ What Is Interactive Rebase?

Before you share a branch, its history is often messy: “WIP”, “fix typo”, “really fix test”, commits in the wrong order. Interactive rebase (git rebase -i) lets you edit your own commits before others see them:

  • Squash several small commits into one.
  • Reword commit messages.
  • Reorder, drop or split commits.
  • Edit the content of an older commit.

It is one of the most useful tools for producing clean pull requests. It builds on git rebase.

โš ๏ธ Common mistake: Only rewrite commits that are not yet shared, or that are on your own branch. Rewriting commits on main or other shared branches breaks your teammates’ history.


โ–ถ๏ธ Start an Interactive Rebase

git log --oneline -5
# e5f6a7b Fix typo in test name
# d4e5f6a WIP
# c3d4e5f Add checkout tests
# b2c3d4e Add cart tests
# a1b2c3d Add login tests

git rebase -i HEAD~4          # edit the last 4 commits
# or: git rebase -i main      # edit every commit on this branch since it left main

Git opens your editor with a todo list, oldest commit first:

pick b2c3d4e Add cart tests
pick c3d4e5f Add checkout tests
pick d4e5f6a WIP
pick e5f6a7b Fix typo in test name

# Commands:
# p, pick   = use commit
# r, reword = use commit, but edit the commit message
# e, edit   = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup  = like "squash" but keep only the previous commit's message
# d, drop   = remove commit
# x, exec   = run command (the rest of the line) using shell

Change the words at the start of lines, reorder lines if needed, then save and close the editor. Git replays the commits following your instructions.

๐Ÿ’ก Tip: The order in the todo list is the reverse of git log: the top line is the oldest commit.


๐Ÿ—œ๏ธ Squash and Fixup: Combine Commits

Fold “WIP” and “Fix typo” into “Add checkout tests”:

pick b2c3d4e Add cart tests
pick c3d4e5f Add checkout tests
fixup d4e5f6a WIP
fixup e5f6a7b Fix typo in test name
CommandKeeps the commit’s changesKeeps its message
squash (s)โœ… Merged into the previous commitโœ… Git asks you to edit the combined message
fixup (f)โœ… Merged into the previous commitโŒ Discarded silently

Result:

f1a2b3c Add checkout tests
b2c3d4e Add cart tests
a1b2c3d Add login tests

โœ๏ธ Reword: Fix Old Commit Messages

reword b2c3d4e Add cart tests
pick   c3d4e5f Add checkout tests

Git stops at that commit and opens the editor for the new message. Great for applying Conventional Commits before opening a PR.


๐Ÿ”€ Reorder and Drop

Move lines up or down to reorder commits, or replace pick with drop (or delete the line) to remove a commit entirely.


๐Ÿ› ๏ธ Edit an Older Commit

edit b2c3d4e Add cart tests
pick c3d4e5f Add checkout tests

Git stops after applying that commit:

# change files, then:
git add tests/cart.spec.ts
git commit --amend --no-edit
git rebase --continue

Split one commit into two

At an edit stop:

git reset HEAD~                       # undo the commit, keep its changes unstaged
git add tests/cart.spec.ts
git commit -m "Add cart tests"
git add src/pages/CartPage.ts
git commit -m "Add CartPage page object"
git rebase --continue

โšก The Fixup Workflow (Autosquash)

Found a mistake in a commit from earlier on your branch? Create a fixup commit that targets it, then let Git place and squash it automatically:

git commit --fixup c3d4e5f            # creates "fixup! Add checkout tests"
git rebase -i --autosquash main       # the fixup line is already moved and marked

Set git config --global rebase.autoSquash true to make --autosquash the default.


๐Ÿงฏ Conflicts, Aborting and Recovering

  • Conflicts are resolved as usual: fix files, git add, git rebase --continue (merge conflicts).
  • git rebase --abort cancels the whole interactive rebase.
  • Finished but unhappy? Find the old position in git reflog and git reset --hard HEAD@{n}.
  • Already pushed your branch? Update it with git push --force-with-lease (push).

๐Ÿ“ Assignment

  1. On a new branch in git-practice, make five commits including “WIP” and “fix typo”.
  2. Use git rebase -i to fixup the two noisy commits into the right ones.
  3. Reword one message to Conventional Commits style.
  4. Reorder two commits and drop one.
  5. Use edit to split one commit into two.
  6. Create a fixup commit with --fixup and squash it with --autosquash.
  7. Undo the whole exercise with git reflog and git reset --hard.

โ“ FAQ

๐Ÿค” How do I squash commits in Git?

Run git rebase -i HEAD~N, keep the first commit as pick, change the following ones to squash (or fixup), save and close the editor.

๐Ÿค” What is the difference between squash and fixup?

Both merge a commit into the previous one. Squash lets you combine and edit the messages; fixup discards the fixup commit’s message.

๐Ÿค” How do I change an old commit message?

git rebase -i HEAD~N, change pick to reword for that commit, save, then enter the new message.

๐Ÿค” How do I cancel an interactive rebase?

git rebase --abort while it is in progress, or reset to the previous position from git reflog after it finished.

๐Ÿค” Is it safe to rebase -i a pushed branch?

Only if it is your own branch and nobody else builds on it; then push with --force-with-lease. Never rewrite shared branches like main.


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

Git Workflow Best Practices for Teams (Checklist and Anti-Patterns)

This lesson brings Modules 2 to 6 together into a practical set of team best practices for Git and GitHub: daily habits, branch and pull request rules, security, history hygiene, what belongs in a repository, automation, common anti-patterns and a checklist.

๐Ÿ“– What You’ll Learn: daily Git habits, branch and pull request practices, protecting main, security practices, history hygiene, what to commit and what not to, automating quality, common anti-patterns, and a team checklist.


โœ… Why Best Practices?

Git gives teams enormous flexibility, which also means many ways to create a mess: giant commits, broken main, lost work, leaked secrets and endless conflicts. These best practices, collected from the earlier lessons, keep a team’s repository clean, safe and fast to work with.


๐Ÿ” Daily Habits

PracticeWhyLesson
Pull (or fetch) before you start and before you pushFewer and smaller conflictsfetch vs pull
Commit small, focused changes oftenEasy to review, revert and bisectfirst repository
Check git diff --staged before committingCatch debug code and secretsstaging area
Write meaningful commit messagesHistory becomes documentationcommit messages
Push at least dailyBackup, visibility and early CI feedbackpush and pull

๐ŸŒฟ Branches and Pull Requests

  • One branch per task, named consistently (feature/QA-123-login-tests) (branches).
  • Keep branches short-lived: merge within days, not weeks.
  • Never commit directly to main on a team project; use pull requests.
  • Small pull requests with a clear description and testing notes.
  • Update your branch with the latest main before merging (rebase your own branch, or merge).
  • Delete branches after merging, locally and on GitHub.

๐Ÿ›ก๏ธ Protect the Main Branch

Configure on GitHub (branch protection):

  • Require pull requests and at least one approval.
  • Require status checks (tests, lint) to pass.
  • Block force pushes and deletions.
  • Use CODEOWNERS to request the right reviewers automatically.

๐Ÿ” Security Practices

  • Never commit secrets: use .env files listed in .gitignore and CI secrets.
  • If a secret leaks, revoke and rotate it first, then clean history.
  • Use SSH keys or tokens with minimal scopes and expiry dates (SSH, tokens).
  • Enable 2FA, Dependabot and secret scanning (security).

๐Ÿงฌ History Hygiene

DoDo not
Rewrite your own local commits (amend, interactive rebase) before sharingRewrite commits on shared branches
Use git revert to undo pushed commitsUse git reset + force push on main
Use --force-with-lease on your own branchesUse plain --force
Squash “WIP” and “fix typo” commits before mergingMerge noisy history into main
Tag releases with semantic versionsMove or reuse release tags

See undo changes, interactive rebase and tags.


๐Ÿ“ฆ What Belongs in the Repository

โœ… CommitโŒ Do not commit
Source code and testsDependencies (node_modules/, venv/)
Configuration templates (.env.example)Real secrets (.env, keys, tokens)
Lock files (package-lock.json)Build output and test reports
Documentation (README, CONTRIBUTING)Personal editor settings (unless shared on purpose)
CI workflows (.github/workflows/)Large binaries (use Git LFS or artifact storage)

๐Ÿค– Automate Quality

  • Run tests and linting on every PR with GitHub Actions.
  • Use pre-commit hooks for formatting, linting and commit message checks (hooks and Husky).
  • Keep dependencies updated with Dependabot.

๐Ÿšซ Common Anti-Patterns

Anti-patternBetter approach
“Mega commits” with 50 files and the message “updates”Small, focused commits with clear messages
Long-lived feature branches (weeks)Short branches, feature flags, frequent integration
Working directly on mainBranch + pull request
Ignoring failing CIFix or revert immediately; red builds block everyone
Committing generated reports or node_modulesA proper .gitignore
Force-pushing shared branchesRevert, or coordinate with the team

๐Ÿ“‹ Team Checklist

  • [ ] Branching strategy chosen and documented (strategies)
  • [ ] Branch naming and commit message conventions agreed
  • [ ] main protected; reviews and CI required
  • [ ] PR template and CODEOWNERS in place
  • [ ] .gitignore covers dependencies, reports and secrets
  • [ ] CI runs tests on every pull request
  • [ ] Releases tagged with semantic versions

๐Ÿ“ Assignment

  1. Audit one of your repositories against the “What belongs in the repository” table and fix what you find.
  2. Write a CONTRIBUTING.md for git-practice covering branch names, commit messages and the PR process.
  3. Review your last 20 commits with git log --oneline and rewrite three messages (on a local branch) using interactive rebase later in Module 7.
  4. Complete the team checklist for a real or imaginary team of five.

โ“ FAQ

๐Ÿค” What are Git best practices for teams?

Commit small and often with clear messages, use short-lived branches and pull requests, protect main with reviews and CI, never commit secrets, and avoid rewriting shared history.

๐Ÿค” How often should I commit?

Whenever you complete a small, logical step that leaves the code working, often several times a day.

๐Ÿค” Should I commit directly to main?

Not in a team. Use a branch and a pull request so changes are reviewed and tested before reaching main.

๐Ÿค” What files should not be committed to Git?

Secrets, dependencies, build output, test reports, logs and large binaries. List them in .gitignore.

๐Ÿค” How do I keep a clean Git history?

Write focused commits, squash fixup commits before merging, use squash or rebase merges for PRs, and revert instead of rewriting shared branches.


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

Git and GitHub in VS Code: Stage, Commit, Branch, Merge and Pull Requests

VS Code puts Git a click away. In this lesson you will use the Source Control view for daily work, manage branches from the status bar, resolve conflicts in the merge editor and handle pull requests with the GitHub extension.

๐Ÿ“– What You’ll Learn: the Source Control view and its command equivalents, initializing, cloning and publishing repositories, branches in the status bar, resolving conflicts in the merge editor, timeline and history, stash, recommended extensions, and useful Git settings.


๐Ÿง‘โ€๐Ÿ’ป Why Use Git in VS Code?

Visual Studio Code has Git built in. You can stage, commit, branch, merge, resolve conflicts and push without leaving the editor, and see changes right next to your code. Knowing the commands first (Modules 2 to 4) makes the buttons easy to understand; VS Code then makes daily work faster.

Requirements: Git installed and configured.


๐Ÿ—‚๏ธ The Source Control View

Open it with Ctrl + Shift + G (macOS: Cmd + Shift + G) or the branch icon in the Activity Bar.

AreaEquivalent command
Changes listgit status (unstaged and untracked files)
+ next to a filegit add file
Staged Changes listStaged files
โˆ’ next to a staged filegit restore --staged file
Curved arrow (Discard Changes)git restore file
Message box + Commitgit commit -m "..."
Sync Changes buttongit pull then git push
… menuPull, push, fetch, branch, stash, tags and more

Click a changed file to open a side-by-side diff. In the editor, coloured bars in the gutter show added (green), modified (blue) and deleted (red) lines; click a bar to see or revert that change.


๐Ÿš€ Start a Repository

  • New repository: open a folder, then click Initialize Repository in Source Control (git init).
  • Clone: Command Palette (Ctrl + Shift + P), run Git: Clone, paste the URL or choose Clone from GitHub after signing in.
  • Publish to GitHub: for a local repository without a remote, click Publish Branch (or Publish to GitHub) to create the GitHub repository and push in one step (push an existing project).

๐ŸŒฟ Branches in VS Code

  • The current branch is shown in the bottom-left status bar. Click it to switch branches, create a new branch or check out a remote branch.
  • Publish Branch pushes a new branch with upstream tracking (git push -u).
  • Merge or rebase from the Command Palette: Git: Merge Branch…, Git: Rebase Branch….

๐Ÿงฏ Resolving Conflicts in VS Code

When a merge or rebase stops with conflicts, conflicted files appear under Merge Changes. In the file you can click Accept Current Change, Accept Incoming Change or Accept Both Changes, or open Resolve in Merge Editor for a 3-way view. Then stage the file and commit (or continue the rebase). Full details: Resolve Merge Conflicts.


๐Ÿ•ฐ๏ธ History and Stash

  • Timeline view (Explorer, bottom): commit history of the current file; click an entry to see that version’s diff.
  • Source Control Graph (in recent VS Code versions): a visual history of branches and commits in the Source Control view.
  • Stash: in the … menu, choose Stash to save, apply or pop changes (git stash).

๐Ÿ”Œ Recommended Extensions

ExtensionWhat it adds
GitHub Pull Requests (by GitHub)Create, review, comment on and check out pull requests and issues inside VS Code
GitLensInline blame, rich history, commit search and comparisons
Git GraphA detailed, clickable branch graph
GitHub CopilotAI suggestions, commit message generation and PR summaries (Copilot)

๐Ÿ’ก Tip: With the GitHub Pull Requests extension, testers can check out a developer’s PR in one click, run the tests locally and leave review comments without opening the browser (code review).


โŒจ๏ธ Handy Settings

SettingEffect
git.autofetchFetch in the background so the status bar shows incoming commits
git.confirmSyncAsk before syncing (turn off once confident)
git.enableSmartCommitCommit all changes when nothing is staged
git.postCommitCommandPush or sync automatically after committing

Open Settings (Ctrl + ,) and search “git” to see all options. The integrated terminal (Ctrl + `) is always available for commands the UI does not cover.


๐Ÿ“ Assignment

  1. Open git-practice in VS Code and make a change; stage, commit and sync it using only the Source Control view.
  2. Create a branch from the status bar, commit on it, and publish it.
  3. Create a conflict between two branches and resolve it with the Merge Editor.
  4. Use the Timeline view to compare an old version of README.md.
  5. Install the GitHub Pull Requests extension, sign in, and open or review a PR from VS Code.

โ“ FAQ

๐Ÿค” How do I use Git in VS Code?

Open a folder with a Git repository and use the Source Control view (Ctrl + Shift + G) to stage, commit, push, pull and manage branches.

๐Ÿค” How do I connect VS Code to GitHub?

Sign in with your GitHub account (Accounts icon or when cloning or publishing). VS Code then uses it for cloning, publishing and pushing.

๐Ÿค” How do I resolve merge conflicts in VS Code?

Open the conflicted file and choose Accept Current, Accept Incoming or Accept Both, or use Resolve in Merge Editor, then stage the file and commit.

๐Ÿค” Why does VS Code say Git is not found?

Git is not installed or not in your PATH. Install Git, restart VS Code, or set the git.path setting.

๐Ÿค” Which VS Code extensions help with GitHub?

GitHub Pull Requests for PRs and issues, GitLens or Git Graph for history, and GitHub Copilot for AI assistance.


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

How to Write Good Git Commit Messages (and Use Conventional Commits)

Good commit messages turn Git history into documentation. In this lesson you will learn the anatomy of a great commit message, the Conventional Commits standard used by many teams, and how to enforce it automatically.

๐Ÿ“– What You’ll Learn: why commit messages matter, the subject, body and footer rules, bad vs good examples, Conventional Commits types and scopes, breaking changes, benefits like automated changelogs, enforcing the format with commitlint and Husky, and examples for test projects.


โœ๏ธ Why Commit Messages Matter

Six months from now, someone (probably you) will run git log or git blame to understand why a line of code exists. A message like “fix” or “update” tells them nothing. A good message saves hours of investigation, makes code review easier and can even generate release notes automatically.


๐Ÿ“ The Anatomy of a Good Commit Message

Fix flaky checkout test by waiting for the order API

The test clicked "Finish" before the cart total was recalculated,
so it failed about 1 in 20 runs in CI. Wait for the /api/order
response instead of using a fixed 2-second timeout.

Closes #87
PartRules
Subject lineAbout 50 characters (hard limit around 72); imperative mood (“Fix”, not “Fixed” or “Fixes”); capitalised; no full stop
Blank lineSeparates subject and body (tools rely on it)
Body (optional)Wrap at about 72 characters; explain what and why, not how (the diff shows how)
Footer (optional)Issue references (Closes #87), BREAKING CHANGE:, co-authors

๐Ÿ’ก Tip: A simple test for the subject line: it should complete the sentence “If applied, this commit will ___”. “If applied, this commit will fix flaky checkout test by waiting for the order API.”

Write multi-line messages by running git commit without -m; Git opens your configured editor.


โŒ Bad vs โœ… Good Examples

โŒ Badโœ… Good
fixFix tax rounding on the checkout summary page
update testsAdd negative login tests for locked-out users
changes as per reviewUse getByRole for the login button
WIPSquash WIP commits before merging (interactive rebase)
Fixed the bug where the thing didn't work on Safari when the user...Fix date picker on Safari (details in the body)

๐Ÿงฉ Conventional Commits

Conventional Commits is a widely used specification that adds a type (and optional scope) to the subject:

<type>(<optional scope>): <description>

[optional body]

[optional footer(s)]
TypeUse forExample
featA new featurefeat(cart): add discount code field
fixA bug fixfix(checkout): round tax to two decimals
testAdding or fixing teststest(login): add locked-out user scenario
docsDocumentation onlydocs: add setup steps to README
refactorCode change that neither fixes a bug nor adds a featurerefactor(pages): extract BasePage
styleFormatting, whitespace (no code meaning change)style: apply Prettier formatting
perfPerformance improvementperf(api): cache product list
buildBuild system or dependenciesbuild: upgrade @playwright/test
ciCI configurationci: shard Playwright tests across 4 jobs
choreMaintenance that does not fit elsewherechore: update .gitignore
revertReverting a commitrevert: undo feat(cart) discount field

Breaking changes

Mark changes that break compatibility with ! or a footer:

feat(api)!: rename /users endpoint to /accounts

BREAKING CHANGE: clients must call /accounts instead of /users.

Why teams adopt Conventional Commits

  • History is easy to scan and filter (git log --oneline --grep="^fix").
  • Tools can generate changelogs and choose the next version automatically (fix โ†’ patch, feat โ†’ minor, breaking โ†’ major; see semantic versioning).
  • PR titles in the same format become clean commit messages when using Squash and merge (pull requests).

๐Ÿค– Enforce the Format Automatically

Teams usually enforce the format with commitlint running in a Git hook managed by Husky:

npm install -D @commitlint/cli @commitlint/config-conventional husky
echo "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.mjs
npx husky init
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

Now a commit message like update stuff is rejected before the commit is created. Hooks are covered in Git Hooks and Husky.


๐Ÿงช Commit Messages for Test Automation Projects

test(checkout): add data-driven tests for invalid postcodes
fix(tests): replace waitForTimeout with web-first assertion in search spec
refactor(pages): move cart locators into CartPage
ci: upload Playwright traces on failure
build: bump @playwright/test to the latest version

๐Ÿ“ Assignment

  1. Rewrite these messages properly: “fix”, “tests”, “updated readme”, “final changes”.
  2. Make three commits in git-practice using Conventional Commits with different types and scopes.
  3. Write one commit with a subject, a body explaining why, and a Closes #<n> footer, using your editor instead of -m.
  4. Run git log --oneline --grep="^test" to list only test commits.
  5. Bonus: set up commitlint with Husky and try to commit a bad message.

โ“ FAQ

๐Ÿค” How do I write a good Git commit message?

Use a short imperative subject (about 50 characters), a blank line, and an optional body explaining what changed and why, with issue references in the footer.

๐Ÿค” What are Conventional Commits?

A specification for commit messages in the form type(scope): description, such as fix(login): handle locked users, that enables readable history and automated changelogs and versioning.

๐Ÿค” Should commit messages be in past or present tense?

The common convention is the imperative mood: “Add test”, “Fix bug”, as if giving a command.

๐Ÿค” What does feat! mean in a commit message?

The ! marks a breaking change, which usually triggers a major version increase.

๐Ÿค” How do I write a multi-line commit message?

Run git commit without -m to open your editor, or use -m twice: git commit -m "Subject" -m "Body".


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

Git Branching Strategies: Git Flow vs GitHub Flow vs Trunk-Based Development

Every team needs agreed rules for branches. This lesson explains the three most popular Git branching strategies, GitHub Flow, Git Flow and trunk-based development, with diagrams, pros and cons, a comparison table and guidance on choosing.

๐Ÿ“– What You’ll Learn: why teams need a branching strategy, GitHub Flow, Git Flow and its branch types, trunk-based development and feature flags, a side-by-side comparison, how to choose, environments, and how each strategy affects testing.


๐ŸŒณ Why You Need a Branching Strategy

When one person uses Git, almost anything works. When ten people commit every day, the team needs agreed rules: Which branches exist? Where do new features start? What gets deployed? How are urgent fixes released? That set of rules is a branching strategy (or Git workflow).

This lesson compares the three most popular strategies and shows how to choose. You should be comfortable with branches, merging and pull requests.


๐Ÿš€ GitHub Flow

The simplest strategy, created by GitHub:

main โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€ (always deployable)
         \     /             \        /
          โ—โ”€โ”€โ”€โ—  feature/a    โ—โ”€โ”€โ—โ”€โ”€โ”€โ—  feature/b
              PR + review         PR + review

Rules:

  1. main is always deployable.
  2. For any change, create a descriptive branch from main.
  3. Commit and push regularly; open a pull request early.
  4. Review, discuss and let CI run.
  5. Merge to main and deploy (often automatically).
ProsCons
Very simple; few branchesNeeds strong CI and automated tests
Fast feedback, continuous deliveryNot ideal for supporting several released versions at once

Best for: web apps and SaaS with continuous deployment.


๐Ÿ—๏ธ Git Flow

A structured model with long-lived branches, introduced by Vincent Driessen in 2010:

BranchLifetimePurpose
mainPermanentProduction releases only, each tagged (v2.4.0)
developPermanentIntegration branch for the next release
feature/*TemporaryNew features, branched from and merged back into develop
release/*TemporaryStabilise a release (bug fixes, versioning); merged into main and develop
hotfix/*TemporaryUrgent production fixes from main; merged into main and develop
main     โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—   (v2.4.0)   (v2.4.1)
          \                    / \      /
release    \        โ—โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ—   \    /
            \      /               hotfix
develop      โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ”€โ—โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ—
              \   /     \  /
feature        โ—โ”€โ—       โ—โ—
ProsCons
Clear separation of development and productionMany branches and merges; more overhead
Supports scheduled releases and multiple versionsSlower feedback; long-lived branches cause bigger conflicts
Natural fit for QA phases on release branchesConsidered heavy for continuous delivery

Best for: products with versioned, scheduled releases (mobile apps, installed software, regulated environments).


โšก Trunk-Based Development

Everyone integrates into one main branch (the trunk) at least daily:

  • Very short-lived branches (hours, at most a day or two), or direct commits to main for small teams.
  • Unfinished features are hidden behind feature flags instead of long branches.
  • Heavy reliance on automated tests that run on every change.
  • Releases are cut from main (sometimes via short-lived release branches).
ProsCons
Minimal merge conflicts; continuous integration in the truest senseRequires excellent test automation and discipline
Fastest deliveryFeature flags add complexity
Used by many high-performing engineering organisationsHarder for beginners and teams with weak CI

Best for: experienced teams with mature CI/CD and strong automated test suites.


โš–๏ธ Side-by-Side Comparison

GitHub FlowGit FlowTrunk-Based
Long-lived branchesmainmain + developmain (trunk)
Feature branch lifetimeDaysDays to weeksHours to a day
Release styleContinuousScheduled versionsContinuous
ComplexityLowHighLow process, high engineering discipline
HotfixesNormal PR to mainhotfix/* branchFix on trunk, cherry-pick if needed
Dependence on test automationHighMediumVery high

๐Ÿงญ How to Choose

  • Small team, web app, deploys often: GitHub Flow.
  • Versioned product, multiple supported releases, formal QA phase: Git Flow (or a lighter variant).
  • Mature DevOps team, strong CI, feature flags: trunk-based development.
  • Several environments (dev, QA, staging, prod): many teams add environment branches or, better, promote the same build through environments with a deployment pipeline (deploy with GitHub Actions).

๐Ÿ’ก Tip: Whatever you choose, write it down in CONTRIBUTING.md, enforce it with branch protection, and keep branches short-lived. Long-running branches are the main source of painful merge conflicts.


๐Ÿงช What It Means for Testers

StrategyWhere testers test
GitHub FlowOn each PR (preview environments, CI tests) and continuously on main
Git FlowFeature testing on develop; regression on release/* before merging to main
Trunk-basedMostly automated on every commit; exploratory testing behind feature flags

Automated tests running on every pull request (for example Playwright in GitHub Actions) are essential for all three.


๐Ÿ“ Assignment

  1. In git-practice, simulate GitHub Flow: two feature branches, two PRs, merge both to main.
  2. Simulate Git Flow: create develop, a feature/* branch merged into develop, a release/0.3.0 branch merged into main and develop, and a tag v0.3.0.
  3. Simulate a hotfix in Git Flow and merge it into both main and develop.
  4. Write a one-page branching guide for a team of five testers and developers who deploy weekly. Which strategy would you choose and why?

โ“ FAQ

๐Ÿค” What is a Git branching strategy?

An agreed set of rules for how a team creates, names, merges and releases branches, such as GitHub Flow, Git Flow or trunk-based development.

๐Ÿค” What is the difference between Git Flow and GitHub Flow?

Git Flow uses long-lived main and develop branches plus feature, release and hotfix branches for scheduled releases. GitHub Flow uses only main plus short-lived feature branches merged through pull requests and deployed continuously.

๐Ÿค” What is trunk-based development?

A strategy where everyone integrates small changes into one main branch at least daily, using very short-lived branches and feature flags.

๐Ÿค” Which branching strategy is best?

It depends on your release style and test automation. GitHub Flow suits most web teams; Git Flow suits versioned releases; trunk-based suits mature teams with strong CI.

๐Ÿค” Is Git Flow still used?

Yes, especially for versioned products, but many teams doing continuous delivery have moved to GitHub Flow or trunk-based development.


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

GitHub Markdown and How to Write a Great README (with Template)

Your README is the front page of your project, and Markdown is the language of GitHub. In this lesson you will learn Markdown from scratch, the GitHub-specific extras, and how to write a professional README using a ready-made template for test automation projects.

๐Ÿ“– What You’ll Learn: Markdown basics, code blocks and tables, GitHub extras like mentions, alerts, collapsible sections and diagrams, what a great README contains, a README template for a Playwright project, CI badges, your profile README, and other Markdown files.


๐Ÿ“ Why Markdown and README Matter

Markdown is a simple text format that GitHub turns into nicely formatted pages. You use it everywhere on GitHub: README files, issues, pull request descriptions, comments, wikis and release notes.

The README.md file in the root of a repository is shown on the repository’s front page. It is the first thing visitors, teammates and recruiters read. A clear README makes a project easy to use and makes your work look professional.


โœ๏ธ Markdown Basics

You writeYou get
# Heading 1 to ###### Heading 6Headings
**bold** and *italic*bold and italic
~~strikethrough~~Strikethrough
inline code wrapped in single backticksInline code
[link text](https://sqatools.in)A link
![alt text](images/report.png)An image
- item or 1. itemBullet or numbered lists
- [ ] task and - [x] doneTask list checkboxes
> quoteBlock quote
--- on its own lineHorizontal rule

Code blocks

Wrap code in a fence of three backticks (or three tildes) and add the language for syntax highlighting:

~~~bash
npm install
npx playwright test
~~~

Tables

| Command          | What it does         |
|------------------|----------------------|
| npm test         | Run all tests        |
| npm run report   | Open the HTML report |

GitHub extras

FeatureSyntax
Mention a user@username
Link an issue or PR#42
Emoji:rocket: :white_check_mark:
Collapsible section<details><summary>Logs</summary> ... </details>
Alert boxes> [!NOTE], > [!TIP], > [!WARNING] on the first line of a quote
DiagramsA code block with the language mermaid renders flowcharts and sequence diagrams

Preview Markdown on GitHub with the Preview tab, or in VS Code with Ctrl + Shift + V.


๐Ÿ“„ What a Great README Contains

SectionAnswers
Title and one-line descriptionWhat is this?
BadgesIs CI green? Which version or licence?
Features or scopeWhat does it cover?
Tech stackWhich tools and versions?
PrerequisitesWhat do I need installed?
InstallationHow do I set it up?
UsageHow do I run it?
Project structureWhere is everything?
ConfigurationWhich environment variables or settings exist?
Reports and CIWhere are results? How does CI run?
ContributingHow can others help?
Licence and contactCan I reuse it? Who maintains it?

๐Ÿงช README Template for a Test Automation Project

# Swag Labs Playwright Framework

![Playwright Tests](https://github.com/your-username/swaglabs-playwright/actions/workflows/playwright.yml/badge.svg)

End-to-end and API tests for Swag Labs, built with Playwright and TypeScript.

## Features
- Page Object Model with custom fixtures
- Login once with storageState
- Data-driven tests from JSON
- Chromium, Firefox and mobile projects
- HTML report and traces on retry
- GitHub Actions CI with sharding

## Tech stack
Playwright 1.x, TypeScript, Node.js LTS, GitHub Actions

## Getting started
~~~bash
git clone https://github.com/your-username/swaglabs-playwright.git
cd swaglabs-playwright
npm ci
npx playwright install --with-deps
cp .env.example .env
~~~

## Running tests
| Command                | Description              |
|------------------------|--------------------------|
| npm test               | Run all tests            |
| npm run test:smoke     | Run @smoke tests         |
| npx playwright test --ui | Open UI mode           |
| npm run report         | Open the HTML report     |

## Project structure
~~~text
src/pages      Page objects
src/fixtures   Custom fixtures
src/data       Test data
tests/         Test specs
~~~

## Contributing
Create a branch, follow Conventional Commits and open a pull request.

## License
MIT

The CI badge URL follows the pattern https://github.com/OWNER/REPO/actions/workflows/WORKFLOW_FILE/badge.svg. Learn to build that workflow in Playwright in GitHub Actions and use this template for the framework project.

๐Ÿ’ก Tip: Add a short animated GIF or a screenshot of the HTML report: one picture explains a test framework faster than a page of text.


๐Ÿ‘ค Your GitHub Profile README

Create a public repository with exactly the same name as your username (for example asha-verma-qa/asha-verma-qa) and add a README. GitHub shows it at the top of your profile. Include who you are, the tools you use, links to your best projects, and how to contact you.


๐Ÿ“š Other Markdown Files in a Repository

FilePurpose
CONTRIBUTING.mdHow to contribute (open source contributions)
CHANGELOG.mdNotable changes per version (tags and releases)
CODE_OF_CONDUCT.mdCommunity rules
SECURITY.mdHow to report vulnerabilities
docs/*.mdLonger documentation

๐Ÿ“ Assignment

  1. Write a README for your git-practice repository using at least: headings, a list, a table, a code block, a link and a task list.
  2. Add a “Getting started” section with commands and a “Project structure” section.
  3. Add a collapsible <details> section and a > [!TIP] alert, and check the preview on GitHub.
  4. Create your GitHub profile README.
  5. Bonus: after you add a GitHub Actions workflow, add its status badge to your README.

โ“ FAQ

๐Ÿค” What is a README file on GitHub?

A Markdown file (README.md) in a repository’s root that GitHub displays on the repository’s main page to explain what the project is and how to use it.

๐Ÿค” How do I write a good README?

Explain what the project does, how to install and run it, show the structure and configuration, add badges and screenshots, and explain how to contribute.

๐Ÿค” How do I add a code block in Markdown?

Surround the code with three backticks (or three tildes) on separate lines, adding the language after the opening fence for highlighting.

๐Ÿค” How do I create a GitHub profile README?

Create a public repository with the same name as your username and add a README.md file to it.

๐Ÿค” How do I add a CI badge to a README?

Use ![name](https://github.com/OWNER/REPO/actions/workflows/FILE.yml/badge.svg), or copy it from the workflow’s “Create status badge” menu on the Actions tab.


๐ŸŽฏ Next Steps

๐ŸŽฌ Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in