Skip to main content

Git Methodology

Project: Open Source Languages · Team Size: 6 · Repository: Gitea · Versioning: Sprint-based major releases

1. Purpose

This document defines the Git workflow that every team member must follow throughout the project.

Objectives
  • Maintain a stable and functional codebase
  • Minimise merge conflicts
  • Ensure code is reviewed before integration
  • Keep Git history clean and easy to understand
  • Make changes traceable and accountable
  • Standardise the team's development workflow

All members are expected to follow this methodology consistently from kickoff until final submission.


2. Repository Structure

The repository contains two long-lived branches.

BranchPurpose
mainContains only stable, tested releases. Tagged with version numbers. Never used for day-to-day development.
developPrimary development branch where completed features are integrated. Deployed to staging.
Rules
  • Never commit directly to main.
  • Never commit directly to develop.
  • All work must be completed on feature branches.
  • All merges into develop must be done through Pull Requests.
  • Only the lead merges developmain at release time.

3. Branching Strategy

Every task should have its own branch, created from the latest version of develop.

Branch from develop, never from main. Merge back to develop via Pull Request. Only the lead promotes developmain at release time.


4. Branch Naming Convention

PrefixWhen to UseExample
feature/Developing a new featurefeature/login-page
bugfix/Fixing a bugbugfix/login-validation
refactor/Improving code without changing behaviourrefactor/auth-service
docs/Documentation onlydocs/setup-guide
test/Writing or updating teststest/login-api
hotfix/Urgent fix to main (rare)hotfix/security-patch
chore/Configuration, tooling, or maintenancechore/update-eslint

Rules: lowercase only · hyphens between words · short but descriptive · no spaces · one branch = one task/story.

feature/user-profile
feature/course-crud
bugfix/navbar-overflow
test/assessment-marking
docs/api-reference
refactor/database-layer

5. Creating a Branch

# Always start from the latest develop
git checkout develop
git pull origin develop

# Create your branch
git checkout -b feature/your-feature-name

Never create branches from main or old commits. Always pull the latest develop first.


6. Commit Guidelines

Each commit should represent one logical change — e.g. complete login form, add API endpoint, fix validation bug, update documentation. Avoid combining unrelated work into a single commit.

Good commit size

A commit should be small enough to understand in 30 seconds by reading the title and message, but large enough that the project still builds and tests pass.


7. Commit Message Convention

Use Conventional Commits — a simple format that makes history readable and lets tooling (changelog generation, version bumping) work automatically.

PrefixWhen to UseExample
feature:New featurefeature: implement login page
fix:Bug fixfix: prevent duplicate bookings
refactor:Internal improvements (no behavior change)refactor: simplify auth logic
docs:Documentation changesdocs: update api reference
test:Add or update teststest: add login integration tests
chore:Maintenance, config, toolingchore: update eslint config
perf:Performance improvementsperf: optimize course search query

Rules:

  • Present tense ("add" not "added")
  • Lowercase after the colon
  • Under 72 characters
  • Describe what, not how long it took
feature: add clinic search page
fix: prevent duplicate bookings
docs: update api documentation
refactor: split booking service
test: add login integration tests
chore: update prettier config

7a. AI Usage Attribution

Per the course's AI policy, any commit that used AI assistance for code generation, editing, debugging, or tests must include an Assisted-by: trailer — a separate line at the end of the commit message, not folded into the subject line.

feat: add lesson CRUD and reorder endpoints

Assisted-by: Claude-Code[Claude Sonnet 5]

If multiple tools/models were used on the same commit, list them all:

Assisted-by: Claude-Code[Claude Sonnet 5], GitHub-Copilot[GPT-5.6-Sol]

Rules:

  • The trailer goes on its own line, formatted exactly as Assisted-by: <tool>[<model>] — not appended to the subject line with a hyphen or in parentheses.
  • Every repository must also declare, in its own README.md, whether it uses AI code generation, AI inline editing, and AI code review — even if the answer is "no" for one of them. See the course's AI policy document for the exact required wording.
  • This applies regardless of how small the AI-assisted change was. If a commit had no AI involvement at all, no trailer is needed — don't add one speculatively.
  • Commits missing this trailer, where AI assistance was actually used, are a violation of the course's academic integrity policy — this isn't optional stylistic guidance.
Non-negotiable

Every commit made with AI assistance across every service must include this trailer. Reviewers should check for it as part of PR review (Section 13), the same way they check for tests and lint.


8. When to Commit

Commit whenever a logical piece of work is complete:

  • Feature implemented
  • Bug fixed
  • Tests written
  • Component finished
  • API endpoint completed
  • Documentation updated

A teammate should always be able to pull your commit and successfully build the project.

Never commit
  • Broken code
  • Unfinished features
  • Temporary debugging code (console.logs, commented-out code)
  • Large unrelated changes
  • .env files or secrets

9. Pushing Changes

git push origin feature/your-feature-name

Push regularly — don't wait several days before sharing your work. Pushing frequently reduces merge conflict risk.


10. Keeping Your Branch Updated

Before starting work each day or before opening a PR:

git checkout develop
git pull origin develop
git checkout feature/your-feature-name
git merge develop

Resolve any merge conflicts before continuing development. If conflicts are complex, ask a teammate for help — don't struggle alone.


11. Pull Request Workflow

Every completed feature must be merged using a Pull Request. No direct merges are permitted.

Opening a PR

  1. Push your branch: git push origin feature/your-feature-name
  2. Go to Gitea → Pull RequestsNew Pull Request
  3. Set:
    • Base branch: develop
    • Compare branch: feature/your-feature-name
  4. Verify only intended changes appear
  5. Give the PR a descriptive title (should match your commit message)
  6. Write a short description using the template below
  7. Assign at least one reviewer
  8. Submit

PR Description Template

## Summary
Brief explanation of what this PR does.

## Changes
- Added login page
- Added auth middleware
- Added validation schemas

## Testing
- Tested locally with Vitest
- No known issues
- [Optional] Link to test results

## Related Issues
Closes #123

12. Pull Request Requirements

Before requesting a review, ensure:

  • Project builds successfully (npm run build)
  • All tests pass locally (npm run test)
  • Linter passes (npm run lint)
  • No merge conflicts exist
  • Code is formatted (npm run format)
  • No commented-out code remains
  • No debugging statements remain
  • Documentation updated (if needed)
  • .env files not committed

Husky will catch many of these automatically on commit, but check manually too.


13. Code Review

Every Pull Request requires at least one approval before merging.

Reviewers check:

  • Code correctness and logic
  • Readability and naming
  • Adherence to coding standards
  • Test coverage and quality
  • No duplicate code
  • No obvious performance issues
  • Compliance with API conventions

As an author:

  • Respond to comments respectfully
  • Explain your reasoning if you disagree
  • Push fixes and re-request review
  • Don't merge until approved
Schema and shared-config changes

Per the Project Plan, a PR touching schema.prisma or backend/shared (used by every service) should get review from whoever owns that file/service specifically, not just any available teammate — a mistake here affects everyone, not just one feature.


14. Merging Strategy

The team uses Squash and Merge — combining all commits into a single clean commit when merging into develop.

c3a9f2: Added button
e1b4d8: Oops typo
f2c6a1: Fixed CSS
a7d9e2: Another fix
b8e3c4: Final fix

Why squash merge?

  • Cleaner Git history — easier to read and understand
  • Easier to bisect bugs (git bisect finds the commit that broke something)
  • Cleaner release notes — one logical change = one line in the changelog
  • Easier to revert — reverting one commit vs. reverting five
Setting up squash merge

Most platforms default to allowing all merge types. Set branch protection rules to require squash merge and prevent direct pushes.


15. Deleting Branches

Once merged, delete the branch immediately:

# Delete locally
git branch -d feature/your-feature-name

# Delete on Gitea
git push origin --delete feature/your-feature-name

Stale branches clutter the repository and confuse new team members.


16. Versioning — Sprint-based Major Releases

Format: MAJOR.MINOR.PATCH, but simplified for this project: MAJOR is tied directly to sprint number, not to "breaking changes" in the traditional SemVer sense. This is a deliberate deviation from strict SemVer, chosen because it maps cleanly onto the brief's own milestone structure and is easy for the whole team (and a marking tutor) to reason about at a glance.

VersionMeaning
1.0.0Tagged at the end of Sprint 1 (Basic tier submission)
2.0.0Tagged at the end of Sprint 2 (Intermediate tier, part 1)
3.0.0Tagged at the end of Sprint 3 (Intermediate tier, part 2)
4.0.0Tagged at the end of Sprint 4 (Advanced tier, final submission)

MINOR and PATCH still follow standard SemVer meaning within a sprint, if tagging becomes useful at a finer grain than once-per-sprint:

  • MINOR — a new backwards-compatible feature landing mid-sprint (e.g. 1.1.0)
  • PATCH — a bug fix landing mid-sprint (e.g. 1.0.1)

In practice, the team has only tagged at sprint boundaries so far — MINOR/PATCH tags are optional, not required.

Examples

  • 1.0.0 — Sprint 1 submission: auth, course/lesson CRUD, publish/unpublish, corrections, Browse
  • 2.0.0 — Sprint 2 submission: assessments, forking, reputation, moderation basics
  • 3.0.0 — Sprint 3 submission: full moderation workflow, discovery/notifications
  • 4.0.0 — Final submission: selected Advanced-tier features, hardening
Why not strict SemVer?

Traditional SemVer ties MAJOR to breaking API changes, which doesn't map naturally onto a course project graded by sprint milestone. Tying MAJOR to sprint number instead gives an immediate, unambiguous answer to "what state was the project in at each graded checkpoint" — which is what actually matters here.


17. Git Tags

Each official release receives a Git tag, created only for stable milestone releases (roughly at sprint ends).

# Create and push a tag
git tag -a v1.0.0 -m "Basic tier complete"
git push origin v1.0.0

Tags should match your version numbers. The lead creates tags at release time.


18. Daily Workflow

  1. Start your day: Pull the latest develop
  2. Pick a task: Choose a story from the sprint board
  3. Create a branch: git checkout -b feature/story-id-description
  4. Implement: Write code, tests, docs
  5. Commit regularly: Small, logical commits
  6. Push: git push origin feature/your-branch
  7. Open a PR: Describe the changes, request review
  8. Address feedback: Respond to review comments, push fixes
  9. Merge: Once approved and CI passes, merge via squash
  10. Delete branch: Clean up after yourself

19. Team Responsibilities

  • Follow this Git methodology strictly
  • Work only on assigned tasks
  • Keep commits small and meaningful
  • Push changes at least daily
  • Review teammates' PRs when requested
  • Resolve merge conflicts promptly
  • Delete branches after merging
  • Write descriptive commit messages

20. Summary of Rules

RulePolicy
Direct commits to main❌ Never
Direct commits to develop❌ Never
Feature branches required✅ Yes
Pull Requests required✅ Yes, even for small fixes
Code review required✅ Minimum one approval
Squash merge✅ Always
Delete merged branches✅ Immediately
Sprint-based major releases✅ Yes
Tag official releases✅ Yes
Keep main stable✅ Always

21. Troubleshooting common Git situations

Real issues this team has actually hit — worth knowing before you hit them too.

"Your local changes would be overwritten by checkout" when switching branches If the file is modified and tracked, git stash alone works. If the file is new/untracked (e.g. a work-in-progress file you haven't committed yet), plain git stash won't touch it and the checkout will still fail or silently carry the file onto the wrong branch. Use:

git stash -u

to stash untracked files too. Restore with git stash pop once you're back on the right branch.

package-lock.json merge conflicts Don't try to hand-resolve this file — it's generated, not authored. Accept either side, then regenerate it properly:

git checkout --theirs package-lock.json
npm install
git add package-lock.json

A branch was created before develop moved on, and now has conflicts Pull develop into your branch before opening (or before finishing) a PR that's been open a while:

git checkout your-branch
git pull origin develop

Resolve any conflicts that come up, same as any merge.

A folder won't delete ("EPERM: operation not permitted") Usually means something still has a file open inside it — another terminal, an editor, or (on Windows) antivirus real-time scanning. Close other processes, add a Windows Defender exclusion for the repo folder if this keeps happening, and retry. As a last resort, restart your machine to clear lingering file handles.

"Cannot checkout, would overwrite..." after git checkout <branch> with no local branch of that name git checkout <branch-name> only works if a local branch by that name already exists. If it doesn't, create one tracking the remote explicitly:

git checkout -b <branch-name> origin/<branch-name>

Using the plain form on a branch that only exists remotely can silently do something other than what you expect (e.g. run the next command against whatever branch you were already on).


22. Appendix — Example Workflow

# Start the day
git checkout develop
git pull origin develop

# Create a feature branch
git checkout -b feature/write-1-create-course

# Implement, commit
git add src/course.model.ts src/course.controller.ts
git commit -m "feat: implement course creation endpoint" -m "Assisted-by: Claude-Code[Claude Sonnet 5]"

git add tests/course.test.ts
git commit -m "test: add course creation tests"

# Push
git push origin feature/write-1-create-course

# [Open PR on Gitea]
# [Wait for CI to pass and review]
# [Address feedback if needed]

# [Merge via Gitea UI — select "Squash and merge"]

# Clean up
git checkout develop
git pull origin develop
git branch -d feature/write-1-create-course
git push origin --delete feature/write-1-create-course

Following this methodology ensures the repository stays organised, development is predictable, and collaboration across 6 people stays efficient.